From 225013934954e763531a638375310df8e2186841 Mon Sep 17 00:00:00 2001 From: Justin Aquadro Date: Fri, 31 Aug 2012 01:29:32 -0400 Subject: [PATCH] Most of the 2.0 work. --- DataNode.cs | 27 +- Form1.cs | 44 +- IconRegistry.cs | 30 + MainForm.Designer.cs | 698 ++++++++++++++++++ MainForm.cs | 523 ++++++++++++++ MainForm.resx | 1146 ++++++++++++++++++++++++++++++ Model/CompoundTagContainer.cs | 65 ++ Model/DataNode.cs | 181 +++++ Model/DataNodeCollection.cs | 121 ++++ Model/DirectoryDataNode.cs | 65 ++ Model/ListTagContainer.cs | 38 + Model/NbtFileDataNode.cs | 124 ++++ Model/NodeCapabilities.cs | 18 + Model/RegionChunkDataNode.cs | 96 +++ Model/RegionFileDataNode.cs | 65 ++ Model/TagCompoundDataNode.cs | 129 ++++ Model/TagContainerInterface.cs | 36 + Model/TagDataNode.cs | 433 +++++++++++ Model/TagListDataNode.cs | 111 +++ NBTExplorer.csproj | 29 +- Program.cs | 2 +- Properties/Resources.Designer.cs | 2 +- Resources/question-white.png | Bin 0 -> 761 bytes app.config | 6 +- forms/CreateNode.Designer.cs | 2 +- forms/CreateNode.cs | 6 +- forms/EditName.cs | 9 +- 27 files changed, 3961 insertions(+), 45 deletions(-) create mode 100644 IconRegistry.cs create mode 100644 MainForm.Designer.cs create mode 100644 MainForm.cs create mode 100644 MainForm.resx create mode 100644 Model/CompoundTagContainer.cs create mode 100644 Model/DataNode.cs create mode 100644 Model/DataNodeCollection.cs create mode 100644 Model/DirectoryDataNode.cs create mode 100644 Model/ListTagContainer.cs create mode 100644 Model/NbtFileDataNode.cs create mode 100644 Model/NodeCapabilities.cs create mode 100644 Model/RegionChunkDataNode.cs create mode 100644 Model/RegionFileDataNode.cs create mode 100644 Model/TagCompoundDataNode.cs create mode 100644 Model/TagContainerInterface.cs create mode 100644 Model/TagDataNode.cs create mode 100644 Model/TagListDataNode.cs create mode 100644 Resources/question-white.png diff --git a/DataNode.cs b/DataNode.cs index e4a9451..ef3248d 100644 --- a/DataNode.cs +++ b/DataNode.cs @@ -1,20 +1,23 @@ using Substrate.Core; using Substrate.Nbt; +using System.Collections.Generic; +using System; +using System.Windows.Forms; namespace NBTExplorer { - public class DataNode + public class DataNodeOld { - public DataNode () + public DataNodeOld () { } - public DataNode (DataNode parent) + public DataNodeOld (DataNodeOld parent) { Parent = parent; } - public DataNode Parent { get; set; } + public DataNodeOld Parent { get; set; } private bool _modified; public bool Modified @@ -32,13 +35,13 @@ namespace NBTExplorer public bool Expanded { get; set; } } - public class NbtDataNode : DataNode + public class NbtDataNode : DataNodeOld { public NbtDataNode () { } - public NbtDataNode (DataNode parent) + public NbtDataNode (DataNodeOld parent) : base(parent) { } @@ -53,7 +56,7 @@ namespace NBTExplorer { } - public RegionChunkData (DataNode parent, RegionFile file, int x, int z) + public RegionChunkData (DataNodeOld parent, RegionFile file, int x, int z) : base(parent) { Region = file; @@ -66,14 +69,14 @@ namespace NBTExplorer public int Z { get; private set; } } - public class RegionData : DataNode + public class RegionData : DataNodeOld { public RegionData (string path) : this(null, path) { } - public RegionData (DataNode parent, string path) + public RegionData (DataNodeOld parent, string path) : base(parent) { Path = path; @@ -89,7 +92,7 @@ namespace NBTExplorer { } - public NbtFileData (DataNode parent, string path, CompressionType cztype) + public NbtFileData (DataNodeOld parent, string path, CompressionType cztype) : base(parent) { Path = path; @@ -100,14 +103,14 @@ namespace NBTExplorer public CompressionType CompressionType { get; private set; } } - public class DirectoryData : DataNode + public class DirectoryData : DataNodeOld { public DirectoryData (string path) : this(null, path) { } - public DirectoryData (DataNode parent, string path) + public DirectoryData (DataNodeOld parent, string path) : base(parent) { Path = path; diff --git a/Form1.cs b/Form1.cs index 395a24d..38b2a76 100644 --- a/Form1.cs +++ b/Form1.cs @@ -264,8 +264,8 @@ namespace NBTExplorer private void LinkDataNodeParent (TreeNode node, TreeNode parent) { if (node != null && parent != null && node.Tag != null && parent.Tag != null) { - DataNode nodeDn = node.Tag as DataNode; - DataNode parentDn = parent.Tag as DataNode; + DataNodeOld nodeDn = node.Tag as DataNodeOld; + DataNodeOld parentDn = parent.Tag as DataNodeOld; if (nodeDn != null && parentDn != null) { nodeDn.Parent = parentDn; @@ -332,7 +332,7 @@ namespace NBTExplorer public void UnloadLazyDataNode (TreeNode node) { - DataNode data = node.Tag as DataNode; + DataNodeOld data = node.Tag as DataNodeOld; if (data == null || data.Modified) return; @@ -347,8 +347,8 @@ namespace NBTExplorer if (node.Tag == null) return; - if (node.Tag is DataNode) { - if ((node.Tag as DataNode).Expanded) + if (node.Tag is DataNodeOld) { + if ((node.Tag as DataNodeOld).Expanded) return; } @@ -371,7 +371,7 @@ namespace NBTExplorer if (node.Tag == null) return; - if (node.Tag is DataNode) { + if (node.Tag is DataNodeOld) { UnloadLazyDataNode(node); } } @@ -664,7 +664,7 @@ namespace NBTExplorer private void SaveNode (TreeNode node) { foreach (TreeNode sub in node.Nodes) { - if (sub.Tag != null && sub.Tag is DataNode) { + if (sub.Tag != null && sub.Tag is DataNodeOld) { SaveNode(sub); } } @@ -728,7 +728,7 @@ namespace NBTExplorer return null; TreeNode baseNode = node; - while (baseNode.Tag == null || !(baseNode.Tag is DataNode)) { + while (baseNode.Tag == null || !(baseNode.Tag is DataNodeOld)) { baseNode = baseNode.Parent; } @@ -745,7 +745,7 @@ namespace NBTExplorer if (baseNode == null || baseNode == node) return; - (baseNode.Tag as DataNode).Modified = true; + (baseNode.Tag as DataNodeOld).Modified = true; DeleteNodeNbtTag(node); @@ -912,7 +912,7 @@ namespace NBTExplorer if (form.ShowDialog() == DialogResult.OK) { TreeNode baseNode = BaseNode(node); if (baseNode != null) { - (baseNode.Tag as DataNode).Modified = true; + (baseNode.Tag as DataNodeOld).Modified = true; } tag.ToTagString().Data = form.StringValue; @@ -924,7 +924,7 @@ namespace NBTExplorer if (form.ShowDialog() == DialogResult.OK && form.Modified) { TreeNode baseNode = BaseNode(node); if (baseNode != null) { - (baseNode.Tag as DataNode).Modified = true; + (baseNode.Tag as DataNodeOld).Modified = true; } Array.Copy(form.Data, tag.ToTagByteArray().Data, tag.ToTagByteArray().Length); @@ -942,7 +942,7 @@ namespace NBTExplorer if (form.ShowDialog() == DialogResult.OK && form.Modified) { TreeNode baseNode = BaseNode(node); if (baseNode != null) { - (baseNode.Tag as DataNode).Modified = true; + (baseNode.Tag as DataNodeOld).Modified = true; } for (int i = 0; i < iatag.Length; i++) { @@ -955,7 +955,7 @@ namespace NBTExplorer if (form.ShowDialog() == DialogResult.OK) { TreeNode baseNode = BaseNode(node); if (baseNode != null) { - (baseNode.Tag as DataNode).Modified = true; + (baseNode.Tag as DataNodeOld).Modified = true; } node.Text = GetNodeText(node); @@ -997,7 +997,7 @@ namespace NBTExplorer if (form.ShowDialog() == DialogResult.OK) { TreeNode baseNode = BaseNode(node); if (baseNode != null) { - (baseNode.Tag as DataNode).Modified = true; + (baseNode.Tag as DataNodeOld).Modified = true; } SetTagNodeName(node, form.TagName); @@ -1033,7 +1033,7 @@ namespace NBTExplorer if (tag is TagNodeCompound) { TagNodeCompound ctag = tag as TagNodeCompound; - CreateNode form = new CreateNode(type); + CreateNodeForm form = new CreateNodeForm(type); foreach (string key in ctag.Keys) { form.InvalidNames.Add(key); } @@ -1052,7 +1052,7 @@ namespace NBTExplorer else if (tag is TagNodeList) { TagNode newNode; if (TagIsSizedType(type)) { - CreateNode form = new CreateNode(type, false); + CreateNodeForm form = new CreateNodeForm(type, false); if (form.ShowDialog() != DialogResult.OK) return; @@ -1079,7 +1079,7 @@ namespace NBTExplorer TreeNode baseNode = BaseNode(node); if (baseNode != null) { - (baseNode.Tag as DataNode).Modified = true; + (baseNode.Tag as DataNodeOld).Modified = true; } } @@ -1219,8 +1219,8 @@ namespace NBTExplorer if (!_search.MoveNext()) { _nodeTree.SelectedNode = _rootSearchNode; - if (_rootSearchNode != null && _rootSearchNode.Tag is DataNode) { - if (_rootSearchNode.IsExpanded && !(_rootSearchNode.Tag as DataNode).Expanded) { + if (_rootSearchNode != null && _rootSearchNode.Tag is DataNodeOld) { + if (_rootSearchNode.IsExpanded && !(_rootSearchNode.Tag as DataNodeOld).Expanded) { _rootSearchNode.Collapse(); } } @@ -1241,8 +1241,8 @@ namespace NBTExplorer bool expand = false; - if (node.Tag is DataNode) { - DataNode data = node.Tag as DataNode; + if (node.Tag is DataNodeOld) { + DataNodeOld data = node.Tag as DataNodeOld; if (!data.Expanded) { ExpandNode(node); expand = true; @@ -1277,7 +1277,7 @@ namespace NBTExplorer } if (expand) { - DataNode data = node.Tag as DataNode; + DataNodeOld data = node.Tag as DataNodeOld; if (!data.Modified) CollapseNode(node); } diff --git a/IconRegistry.cs b/IconRegistry.cs new file mode 100644 index 0000000..fad1765 --- /dev/null +++ b/IconRegistry.cs @@ -0,0 +1,30 @@ +using System; +using System.Collections.Generic; + +namespace NBTExplorer +{ + public class IconRegistry + { + private static Dictionary _iconRegistry; + + public IconRegistry () + { + _iconRegistry = new Dictionary(); + } + + public int DefaultIcon { get; set; } + + public int Lookup (Type type) + { + if (_iconRegistry.ContainsKey(type)) + return _iconRegistry[type]; + else + return DefaultIcon; + } + + public void Register (Type type, int iconIndex) + { + _iconRegistry[type] = iconIndex; + } + } +} diff --git a/MainForm.Designer.cs b/MainForm.Designer.cs new file mode 100644 index 0000000..b2bd556 --- /dev/null +++ b/MainForm.Designer.cs @@ -0,0 +1,698 @@ +namespace NBTExplorer +{ + partial class MainForm + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose (bool disposing) + { + if (disposing && (components != null)) { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent () + { + this.components = new System.ComponentModel.Container(); + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(MainForm)); + this.menuStrip1 = new System.Windows.Forms.MenuStrip(); + this.fileToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.openToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.openFolderToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.openMinecraftSaveFolderToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.toolStripSeparator3 = new System.Windows.Forms.ToolStripSeparator(); + this.saveToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.toolStripSeparator4 = new System.Windows.Forms.ToolStripSeparator(); + this._menuItemExit = new System.Windows.Forms.ToolStripMenuItem(); + this.editToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this._menuItemCut = new System.Windows.Forms.ToolStripMenuItem(); + this._menuItemCopy = new System.Windows.Forms.ToolStripMenuItem(); + this._menuItemPaste = new System.Windows.Forms.ToolStripMenuItem(); + this.toolStripSeparator7 = new System.Windows.Forms.ToolStripSeparator(); + this._menuItemRename = new System.Windows.Forms.ToolStripMenuItem(); + this._menuItemEditValue = new System.Windows.Forms.ToolStripMenuItem(); + this._menuItemDelete = new System.Windows.Forms.ToolStripMenuItem(); + this.searchToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this._menuItemFind = new System.Windows.Forms.ToolStripMenuItem(); + this.findNextToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.helpToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this._menuItemAbout = new System.Windows.Forms.ToolStripMenuItem(); + this._nodeTree = new System.Windows.Forms.TreeView(); + this.imageList1 = new System.Windows.Forms.ImageList(this.components); + this.toolStrip1 = new System.Windows.Forms.ToolStrip(); + this._buttonOpen = new System.Windows.Forms.ToolStripButton(); + this._buttonOpenFolder = new System.Windows.Forms.ToolStripButton(); + this._buttonSave = new System.Windows.Forms.ToolStripButton(); + this.toolStripSeparator1 = new System.Windows.Forms.ToolStripSeparator(); + this._buttonCut = new System.Windows.Forms.ToolStripButton(); + this._buttonCopy = new System.Windows.Forms.ToolStripButton(); + this._buttonPaste = new System.Windows.Forms.ToolStripButton(); + this.toolStripSeparator6 = new System.Windows.Forms.ToolStripSeparator(); + this._buttonRename = new System.Windows.Forms.ToolStripButton(); + this._buttonEdit = new System.Windows.Forms.ToolStripButton(); + this._buttonDelete = new System.Windows.Forms.ToolStripButton(); + this.toolStripSeparator2 = new System.Windows.Forms.ToolStripSeparator(); + this._buttonAddTagByte = new System.Windows.Forms.ToolStripButton(); + this._buttonAddTagShort = new System.Windows.Forms.ToolStripButton(); + this._buttonAddTagInt = new System.Windows.Forms.ToolStripButton(); + this._buttonAddTagLong = new System.Windows.Forms.ToolStripButton(); + this._buttonAddTagFloat = new System.Windows.Forms.ToolStripButton(); + this._buttonAddTagDouble = new System.Windows.Forms.ToolStripButton(); + this._buttonAddTagByteArray = new System.Windows.Forms.ToolStripButton(); + this._buttonAddTagIntArray = new System.Windows.Forms.ToolStripButton(); + this._buttonAddTagString = new System.Windows.Forms.ToolStripButton(); + this._buttonAddTagList = new System.Windows.Forms.ToolStripButton(); + this._buttonAddTagCompound = new System.Windows.Forms.ToolStripButton(); + this.toolStripSeparator5 = new System.Windows.Forms.ToolStripSeparator(); + this._buttonFindNext = new System.Windows.Forms.ToolStripButton(); + this.BottomToolStripPanel = new System.Windows.Forms.ToolStripPanel(); + this.TopToolStripPanel = new System.Windows.Forms.ToolStripPanel(); + this.RightToolStripPanel = new System.Windows.Forms.ToolStripPanel(); + this.LeftToolStripPanel = new System.Windows.Forms.ToolStripPanel(); + this.ContentPanel = new System.Windows.Forms.ToolStripContentPanel(); + this.statusStrip1 = new System.Windows.Forms.StatusStrip(); + this.toolStripStatusLabel1 = new System.Windows.Forms.ToolStripStatusLabel(); + this.menuStrip1.SuspendLayout(); + this.toolStrip1.SuspendLayout(); + this.statusStrip1.SuspendLayout(); + this.SuspendLayout(); + // + // menuStrip1 + // + this.menuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.fileToolStripMenuItem, + this.editToolStripMenuItem, + this.searchToolStripMenuItem, + this.helpToolStripMenuItem}); + this.menuStrip1.Location = new System.Drawing.Point(0, 0); + this.menuStrip1.Name = "menuStrip1"; + this.menuStrip1.Size = new System.Drawing.Size(619, 24); + this.menuStrip1.TabIndex = 0; + this.menuStrip1.Text = "menuStrip1"; + // + // fileToolStripMenuItem + // + this.fileToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.openToolStripMenuItem, + this.openFolderToolStripMenuItem, + this.openMinecraftSaveFolderToolStripMenuItem, + this.toolStripSeparator3, + this.saveToolStripMenuItem, + this.toolStripSeparator4, + this._menuItemExit}); + this.fileToolStripMenuItem.Name = "fileToolStripMenuItem"; + this.fileToolStripMenuItem.Size = new System.Drawing.Size(37, 20); + this.fileToolStripMenuItem.Text = "&File"; + // + // openToolStripMenuItem + // + this.openToolStripMenuItem.Image = ((System.Drawing.Image)(resources.GetObject("openToolStripMenuItem.Image"))); + this.openToolStripMenuItem.Name = "openToolStripMenuItem"; + this.openToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.O))); + this.openToolStripMenuItem.Size = new System.Drawing.Size(223, 22); + this.openToolStripMenuItem.Text = "&Open..."; + // + // openFolderToolStripMenuItem + // + this.openFolderToolStripMenuItem.Image = ((System.Drawing.Image)(resources.GetObject("openFolderToolStripMenuItem.Image"))); + this.openFolderToolStripMenuItem.Name = "openFolderToolStripMenuItem"; + this.openFolderToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)(((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.Shift) + | System.Windows.Forms.Keys.O))); + this.openFolderToolStripMenuItem.Size = new System.Drawing.Size(223, 22); + this.openFolderToolStripMenuItem.Text = "Open &Folder..."; + // + // openMinecraftSaveFolderToolStripMenuItem + // + this.openMinecraftSaveFolderToolStripMenuItem.Name = "openMinecraftSaveFolderToolStripMenuItem"; + this.openMinecraftSaveFolderToolStripMenuItem.Size = new System.Drawing.Size(223, 22); + this.openMinecraftSaveFolderToolStripMenuItem.Text = "Open &Minecraft Save Folder"; + // + // toolStripSeparator3 + // + this.toolStripSeparator3.Name = "toolStripSeparator3"; + this.toolStripSeparator3.Size = new System.Drawing.Size(220, 6); + // + // saveToolStripMenuItem + // + this.saveToolStripMenuItem.Image = ((System.Drawing.Image)(resources.GetObject("saveToolStripMenuItem.Image"))); + this.saveToolStripMenuItem.Name = "saveToolStripMenuItem"; + this.saveToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.S))); + this.saveToolStripMenuItem.Size = new System.Drawing.Size(223, 22); + this.saveToolStripMenuItem.Text = "&Save"; + // + // toolStripSeparator4 + // + this.toolStripSeparator4.Name = "toolStripSeparator4"; + this.toolStripSeparator4.Size = new System.Drawing.Size(220, 6); + // + // exitToolStripMenuItem + // + this._menuItemExit.Image = ((System.Drawing.Image)(resources.GetObject("exitToolStripMenuItem.Image"))); + this._menuItemExit.Name = "exitToolStripMenuItem"; + this._menuItemExit.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Alt | System.Windows.Forms.Keys.F4))); + this._menuItemExit.Size = new System.Drawing.Size(223, 22); + this._menuItemExit.Text = "E&xit"; + // + // editToolStripMenuItem + // + this.editToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { + this._menuItemCut, + this._menuItemCopy, + this._menuItemPaste, + this.toolStripSeparator7, + this._menuItemRename, + this._menuItemEditValue, + this._menuItemDelete}); + this.editToolStripMenuItem.Name = "editToolStripMenuItem"; + this.editToolStripMenuItem.Size = new System.Drawing.Size(39, 20); + this.editToolStripMenuItem.Text = "&Edit"; + // + // cutToolStripMenuItem + // + this._menuItemCut.Image = ((System.Drawing.Image)(resources.GetObject("cutToolStripMenuItem.Image"))); + this._menuItemCut.Name = "cutToolStripMenuItem"; + this._menuItemCut.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.X))); + this._menuItemCut.Size = new System.Drawing.Size(166, 22); + this._menuItemCut.Text = "Cu&t"; + // + // copyToolStripMenuItem + // + this._menuItemCopy.Image = ((System.Drawing.Image)(resources.GetObject("copyToolStripMenuItem.Image"))); + this._menuItemCopy.Name = "copyToolStripMenuItem"; + this._menuItemCopy.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.C))); + this._menuItemCopy.Size = new System.Drawing.Size(166, 22); + this._menuItemCopy.Text = "&Copy"; + // + // pasteToolStripMenuItem + // + this._menuItemPaste.Image = ((System.Drawing.Image)(resources.GetObject("pasteToolStripMenuItem.Image"))); + this._menuItemPaste.Name = "pasteToolStripMenuItem"; + this._menuItemPaste.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.V))); + this._menuItemPaste.Size = new System.Drawing.Size(166, 22); + this._menuItemPaste.Text = "&Paste"; + // + // toolStripSeparator7 + // + this.toolStripSeparator7.Name = "toolStripSeparator7"; + this.toolStripSeparator7.Size = new System.Drawing.Size(163, 6); + // + // renameToolStripMenuItem + // + this._menuItemRename.Image = ((System.Drawing.Image)(resources.GetObject("renameToolStripMenuItem.Image"))); + this._menuItemRename.Name = "renameToolStripMenuItem"; + this._menuItemRename.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.R))); + this._menuItemRename.Size = new System.Drawing.Size(166, 22); + this._menuItemRename.Text = "&Rename"; + // + // editValueToolStripMenuItem + // + this._menuItemEditValue.Image = ((System.Drawing.Image)(resources.GetObject("editValueToolStripMenuItem.Image"))); + this._menuItemEditValue.Name = "editValueToolStripMenuItem"; + this._menuItemEditValue.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.E))); + this._menuItemEditValue.Size = new System.Drawing.Size(166, 22); + this._menuItemEditValue.Text = "&Edit Value"; + // + // deleteToolStripMenuItem + // + this._menuItemDelete.Image = ((System.Drawing.Image)(resources.GetObject("deleteToolStripMenuItem.Image"))); + this._menuItemDelete.Name = "deleteToolStripMenuItem"; + this._menuItemDelete.ShortcutKeys = System.Windows.Forms.Keys.Delete; + this._menuItemDelete.Size = new System.Drawing.Size(166, 22); + this._menuItemDelete.Text = "&Delete"; + // + // searchToolStripMenuItem + // + this.searchToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { + this._menuItemFind, + this.findNextToolStripMenuItem}); + this.searchToolStripMenuItem.Name = "searchToolStripMenuItem"; + this.searchToolStripMenuItem.Size = new System.Drawing.Size(54, 20); + this.searchToolStripMenuItem.Text = "&Search"; + // + // findToolStripMenuItem + // + this._menuItemFind.Image = ((System.Drawing.Image)(resources.GetObject("findToolStripMenuItem.Image"))); + this._menuItemFind.Name = "findToolStripMenuItem"; + this._menuItemFind.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.F))); + this._menuItemFind.Size = new System.Drawing.Size(146, 22); + this._menuItemFind.Text = "Find..."; + // + // findNextToolStripMenuItem + // + this.findNextToolStripMenuItem.Image = ((System.Drawing.Image)(resources.GetObject("findNextToolStripMenuItem.Image"))); + this.findNextToolStripMenuItem.Name = "findNextToolStripMenuItem"; + this.findNextToolStripMenuItem.ShortcutKeys = System.Windows.Forms.Keys.F3; + this.findNextToolStripMenuItem.Size = new System.Drawing.Size(146, 22); + this.findNextToolStripMenuItem.Text = "Find Next"; + // + // helpToolStripMenuItem + // + this.helpToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { + this._menuItemAbout}); + this.helpToolStripMenuItem.Name = "helpToolStripMenuItem"; + this.helpToolStripMenuItem.Size = new System.Drawing.Size(44, 20); + this.helpToolStripMenuItem.Text = "&Help"; + // + // aboutToolStripMenuItem + // + this._menuItemAbout.Image = ((System.Drawing.Image)(resources.GetObject("aboutToolStripMenuItem.Image"))); + this._menuItemAbout.Name = "aboutToolStripMenuItem"; + this._menuItemAbout.ShortcutKeys = System.Windows.Forms.Keys.F1; + this._menuItemAbout.Size = new System.Drawing.Size(126, 22); + this._menuItemAbout.Text = "&About"; + // + // _nodeTree + // + this._nodeTree.AllowDrop = true; + this._nodeTree.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this._nodeTree.ImageIndex = 0; + this._nodeTree.ImageList = this.imageList1; + this._nodeTree.ItemHeight = 18; + this._nodeTree.Location = new System.Drawing.Point(0, 49); + this._nodeTree.Margin = new System.Windows.Forms.Padding(0); + this._nodeTree.Name = "_nodeTree"; + this._nodeTree.SelectedImageIndex = 0; + this._nodeTree.Size = new System.Drawing.Size(619, 350); + this._nodeTree.TabIndex = 0; + // + // imageList1 + // + this.imageList1.ImageStream = ((System.Windows.Forms.ImageListStreamer)(resources.GetObject("imageList1.ImageStream"))); + this.imageList1.TransparentColor = System.Drawing.Color.Transparent; + this.imageList1.Images.SetKeyName(0, "document-attribute-b.png"); + this.imageList1.Images.SetKeyName(1, "document-attribute-s.png"); + this.imageList1.Images.SetKeyName(2, "document-attribute-i.png"); + this.imageList1.Images.SetKeyName(3, "document-attribute-l.png"); + this.imageList1.Images.SetKeyName(4, "document-attribute-f.png"); + this.imageList1.Images.SetKeyName(5, "document-attribute-d.png"); + this.imageList1.Images.SetKeyName(6, "edit-code.png"); + this.imageList1.Images.SetKeyName(7, "edit-small-caps.png"); + this.imageList1.Images.SetKeyName(8, "edit-list.png"); + this.imageList1.Images.SetKeyName(9, "box.png"); + this.imageList1.Images.SetKeyName(10, "folder.png"); + this.imageList1.Images.SetKeyName(11, "block.png"); + this.imageList1.Images.SetKeyName(12, "wooden-box.png"); + this.imageList1.Images.SetKeyName(13, "map.png"); + this.imageList1.Images.SetKeyName(14, "edit-code-i.png"); + this.imageList1.Images.SetKeyName(15, "question-white.png"); + // + // toolStrip1 + // + this.toolStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this._buttonOpen, + this._buttonOpenFolder, + this._buttonSave, + this.toolStripSeparator1, + this._buttonCut, + this._buttonCopy, + this._buttonPaste, + this.toolStripSeparator6, + this._buttonRename, + this._buttonEdit, + this._buttonDelete, + this.toolStripSeparator2, + this._buttonAddTagByte, + this._buttonAddTagShort, + this._buttonAddTagInt, + this._buttonAddTagLong, + this._buttonAddTagFloat, + this._buttonAddTagDouble, + this._buttonAddTagByteArray, + this._buttonAddTagIntArray, + this._buttonAddTagString, + this._buttonAddTagList, + this._buttonAddTagCompound, + this.toolStripSeparator5, + this._buttonFindNext}); + this.toolStrip1.Location = new System.Drawing.Point(0, 24); + this.toolStrip1.Name = "toolStrip1"; + this.toolStrip1.Size = new System.Drawing.Size(619, 25); + this.toolStrip1.Stretch = true; + this.toolStrip1.TabIndex = 0; + // + // _buttonOpen + // + this._buttonOpen.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; + this._buttonOpen.Image = ((System.Drawing.Image)(resources.GetObject("_buttonOpen.Image"))); + this._buttonOpen.ImageTransparentColor = System.Drawing.Color.Magenta; + this._buttonOpen.Name = "_buttonOpen"; + this._buttonOpen.Size = new System.Drawing.Size(23, 22); + this._buttonOpen.Text = "Open NBT Data Source"; + // + // _buttonOpenFolder + // + this._buttonOpenFolder.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; + this._buttonOpenFolder.Image = ((System.Drawing.Image)(resources.GetObject("_buttonOpenFolder.Image"))); + this._buttonOpenFolder.ImageTransparentColor = System.Drawing.Color.Magenta; + this._buttonOpenFolder.Name = "_buttonOpenFolder"; + this._buttonOpenFolder.Size = new System.Drawing.Size(23, 22); + this._buttonOpenFolder.Text = "Open Folder"; + // + // _buttonSave + // + this._buttonSave.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; + this._buttonSave.Image = ((System.Drawing.Image)(resources.GetObject("_buttonSave.Image"))); + this._buttonSave.ImageTransparentColor = System.Drawing.Color.Magenta; + this._buttonSave.Name = "_buttonSave"; + this._buttonSave.Size = new System.Drawing.Size(23, 22); + this._buttonSave.Text = "Save All Modified Tags"; + // + // toolStripSeparator1 + // + this.toolStripSeparator1.Name = "toolStripSeparator1"; + this.toolStripSeparator1.Size = new System.Drawing.Size(6, 25); + // + // _buttonCut + // + this._buttonCut.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; + this._buttonCut.Image = ((System.Drawing.Image)(resources.GetObject("_buttonCut.Image"))); + this._buttonCut.ImageTransparentColor = System.Drawing.Color.Magenta; + this._buttonCut.Name = "_buttonCut"; + this._buttonCut.Size = new System.Drawing.Size(23, 22); + this._buttonCut.Text = "Cut"; + // + // _buttonCopy + // + this._buttonCopy.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; + this._buttonCopy.Image = ((System.Drawing.Image)(resources.GetObject("_buttonCopy.Image"))); + this._buttonCopy.ImageTransparentColor = System.Drawing.Color.Magenta; + this._buttonCopy.Name = "_buttonCopy"; + this._buttonCopy.Size = new System.Drawing.Size(23, 22); + this._buttonCopy.Text = "Copy"; + // + // _buttonPaste + // + this._buttonPaste.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; + this._buttonPaste.Image = ((System.Drawing.Image)(resources.GetObject("_buttonPaste.Image"))); + this._buttonPaste.ImageTransparentColor = System.Drawing.Color.Magenta; + this._buttonPaste.Name = "_buttonPaste"; + this._buttonPaste.Size = new System.Drawing.Size(23, 22); + this._buttonPaste.Text = "Paste"; + // + // toolStripSeparator6 + // + this.toolStripSeparator6.Name = "toolStripSeparator6"; + this.toolStripSeparator6.Size = new System.Drawing.Size(6, 25); + // + // _buttonRename + // + this._buttonRename.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; + this._buttonRename.Image = ((System.Drawing.Image)(resources.GetObject("_buttonRename.Image"))); + this._buttonRename.ImageTransparentColor = System.Drawing.Color.Magenta; + this._buttonRename.Name = "_buttonRename"; + this._buttonRename.Size = new System.Drawing.Size(23, 22); + this._buttonRename.Text = "Rename Tag"; + // + // _buttonEdit + // + this._buttonEdit.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; + this._buttonEdit.Image = ((System.Drawing.Image)(resources.GetObject("_buttonEdit.Image"))); + this._buttonEdit.ImageTransparentColor = System.Drawing.Color.Magenta; + this._buttonEdit.Name = "_buttonEdit"; + this._buttonEdit.Size = new System.Drawing.Size(23, 22); + this._buttonEdit.Text = "Edit Tag Value"; + // + // _buttonDelete + // + this._buttonDelete.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; + this._buttonDelete.Image = ((System.Drawing.Image)(resources.GetObject("_buttonDelete.Image"))); + this._buttonDelete.ImageTransparentColor = System.Drawing.Color.Magenta; + this._buttonDelete.Name = "_buttonDelete"; + this._buttonDelete.Size = new System.Drawing.Size(23, 22); + this._buttonDelete.Text = "Delete Tag"; + // + // toolStripSeparator2 + // + this.toolStripSeparator2.Name = "toolStripSeparator2"; + this.toolStripSeparator2.Size = new System.Drawing.Size(6, 25); + // + // _buttonAddTagByte + // + this._buttonAddTagByte.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; + this._buttonAddTagByte.Image = ((System.Drawing.Image)(resources.GetObject("_buttonAddTagByte.Image"))); + this._buttonAddTagByte.ImageTransparentColor = System.Drawing.Color.Magenta; + this._buttonAddTagByte.Name = "_buttonAddTagByte"; + this._buttonAddTagByte.Size = new System.Drawing.Size(23, 22); + this._buttonAddTagByte.Text = "Add Byte Tag"; + // + // _buttonAddTagShort + // + this._buttonAddTagShort.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; + this._buttonAddTagShort.Image = ((System.Drawing.Image)(resources.GetObject("_buttonAddTagShort.Image"))); + this._buttonAddTagShort.ImageTransparentColor = System.Drawing.Color.Magenta; + this._buttonAddTagShort.Name = "_buttonAddTagShort"; + this._buttonAddTagShort.Size = new System.Drawing.Size(23, 22); + this._buttonAddTagShort.Text = "Add Short Tag"; + // + // _buttonAddTagInt + // + this._buttonAddTagInt.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; + this._buttonAddTagInt.Image = ((System.Drawing.Image)(resources.GetObject("_buttonAddTagInt.Image"))); + this._buttonAddTagInt.ImageTransparentColor = System.Drawing.Color.Magenta; + this._buttonAddTagInt.Name = "_buttonAddTagInt"; + this._buttonAddTagInt.Size = new System.Drawing.Size(23, 22); + this._buttonAddTagInt.Text = "Add Int Tag"; + // + // _buttonAddTagLong + // + this._buttonAddTagLong.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; + this._buttonAddTagLong.Image = ((System.Drawing.Image)(resources.GetObject("_buttonAddTagLong.Image"))); + this._buttonAddTagLong.ImageTransparentColor = System.Drawing.Color.Magenta; + this._buttonAddTagLong.Name = "_buttonAddTagLong"; + this._buttonAddTagLong.Size = new System.Drawing.Size(23, 22); + this._buttonAddTagLong.Text = "Add Long Tag"; + // + // _buttonAddTagFloat + // + this._buttonAddTagFloat.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; + this._buttonAddTagFloat.Image = ((System.Drawing.Image)(resources.GetObject("_buttonAddTagFloat.Image"))); + this._buttonAddTagFloat.ImageTransparentColor = System.Drawing.Color.Magenta; + this._buttonAddTagFloat.Name = "_buttonAddTagFloat"; + this._buttonAddTagFloat.Size = new System.Drawing.Size(23, 22); + this._buttonAddTagFloat.Text = "Add Float Tag"; + // + // _buttonAddTagDouble + // + this._buttonAddTagDouble.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; + this._buttonAddTagDouble.Image = ((System.Drawing.Image)(resources.GetObject("_buttonAddTagDouble.Image"))); + this._buttonAddTagDouble.ImageTransparentColor = System.Drawing.Color.Magenta; + this._buttonAddTagDouble.Name = "_buttonAddTagDouble"; + this._buttonAddTagDouble.Size = new System.Drawing.Size(23, 22); + this._buttonAddTagDouble.Text = "Add Double Tag"; + // + // _buttonAddTagByteArray + // + this._buttonAddTagByteArray.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; + this._buttonAddTagByteArray.Image = ((System.Drawing.Image)(resources.GetObject("_buttonAddTagByteArray.Image"))); + this._buttonAddTagByteArray.ImageTransparentColor = System.Drawing.Color.Magenta; + this._buttonAddTagByteArray.Name = "_buttonAddTagByteArray"; + this._buttonAddTagByteArray.Size = new System.Drawing.Size(23, 22); + this._buttonAddTagByteArray.Text = "Add Byte Array Tag"; + // + // _buttonAddTagIntArray + // + this._buttonAddTagIntArray.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; + this._buttonAddTagIntArray.Image = ((System.Drawing.Image)(resources.GetObject("_buttonAddTagIntArray.Image"))); + this._buttonAddTagIntArray.ImageScaling = System.Windows.Forms.ToolStripItemImageScaling.None; + this._buttonAddTagIntArray.ImageTransparentColor = System.Drawing.Color.Magenta; + this._buttonAddTagIntArray.Name = "_buttonAddTagIntArray"; + this._buttonAddTagIntArray.Size = new System.Drawing.Size(23, 22); + this._buttonAddTagIntArray.Text = "Add Int Array Tag"; + // + // _buttonAddTagString + // + this._buttonAddTagString.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; + this._buttonAddTagString.Image = ((System.Drawing.Image)(resources.GetObject("_buttonAddTagString.Image"))); + this._buttonAddTagString.ImageTransparentColor = System.Drawing.Color.Magenta; + this._buttonAddTagString.Name = "_buttonAddTagString"; + this._buttonAddTagString.Size = new System.Drawing.Size(23, 22); + this._buttonAddTagString.Text = "Add String Tag"; + // + // _buttonAddTagList + // + this._buttonAddTagList.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; + this._buttonAddTagList.Image = ((System.Drawing.Image)(resources.GetObject("_buttonAddTagList.Image"))); + this._buttonAddTagList.ImageTransparentColor = System.Drawing.Color.Magenta; + this._buttonAddTagList.Name = "_buttonAddTagList"; + this._buttonAddTagList.Size = new System.Drawing.Size(23, 22); + this._buttonAddTagList.Text = "Add List Tag"; + // + // _buttonAddTagCompound + // + this._buttonAddTagCompound.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; + this._buttonAddTagCompound.Image = ((System.Drawing.Image)(resources.GetObject("_buttonAddTagCompound.Image"))); + this._buttonAddTagCompound.ImageTransparentColor = System.Drawing.Color.Magenta; + this._buttonAddTagCompound.Name = "_buttonAddTagCompound"; + this._buttonAddTagCompound.Size = new System.Drawing.Size(23, 22); + this._buttonAddTagCompound.Text = "Add Compound Tag"; + // + // toolStripSeparator5 + // + this.toolStripSeparator5.Name = "toolStripSeparator5"; + this.toolStripSeparator5.Size = new System.Drawing.Size(6, 25); + // + // _buttonFindNext + // + this._buttonFindNext.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; + this._buttonFindNext.Image = ((System.Drawing.Image)(resources.GetObject("_buttonFindNext.Image"))); + this._buttonFindNext.ImageTransparentColor = System.Drawing.Color.Magenta; + this._buttonFindNext.Name = "_buttonFindNext"; + this._buttonFindNext.Size = new System.Drawing.Size(23, 22); + this._buttonFindNext.Text = "Find / Find Next"; + // + // BottomToolStripPanel + // + this.BottomToolStripPanel.Location = new System.Drawing.Point(0, 0); + this.BottomToolStripPanel.Name = "BottomToolStripPanel"; + this.BottomToolStripPanel.Orientation = System.Windows.Forms.Orientation.Horizontal; + this.BottomToolStripPanel.RowMargin = new System.Windows.Forms.Padding(3, 0, 0, 0); + this.BottomToolStripPanel.Size = new System.Drawing.Size(0, 0); + // + // TopToolStripPanel + // + this.TopToolStripPanel.Location = new System.Drawing.Point(0, 0); + this.TopToolStripPanel.Name = "TopToolStripPanel"; + this.TopToolStripPanel.Orientation = System.Windows.Forms.Orientation.Horizontal; + this.TopToolStripPanel.RowMargin = new System.Windows.Forms.Padding(3, 0, 0, 0); + this.TopToolStripPanel.Size = new System.Drawing.Size(0, 0); + // + // RightToolStripPanel + // + this.RightToolStripPanel.Location = new System.Drawing.Point(0, 0); + this.RightToolStripPanel.Name = "RightToolStripPanel"; + this.RightToolStripPanel.Orientation = System.Windows.Forms.Orientation.Horizontal; + this.RightToolStripPanel.RowMargin = new System.Windows.Forms.Padding(3, 0, 0, 0); + this.RightToolStripPanel.Size = new System.Drawing.Size(0, 0); + // + // LeftToolStripPanel + // + this.LeftToolStripPanel.Location = new System.Drawing.Point(0, 0); + this.LeftToolStripPanel.Name = "LeftToolStripPanel"; + this.LeftToolStripPanel.Orientation = System.Windows.Forms.Orientation.Horizontal; + this.LeftToolStripPanel.RowMargin = new System.Windows.Forms.Padding(3, 0, 0, 0); + this.LeftToolStripPanel.Size = new System.Drawing.Size(0, 0); + // + // ContentPanel + // + this.ContentPanel.Size = new System.Drawing.Size(562, 376); + // + // statusStrip1 + // + this.statusStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.toolStripStatusLabel1}); + this.statusStrip1.Location = new System.Drawing.Point(0, 401); + this.statusStrip1.Margin = new System.Windows.Forms.Padding(0, 2, 0, 0); + this.statusStrip1.Name = "statusStrip1"; + this.statusStrip1.Size = new System.Drawing.Size(619, 22); + this.statusStrip1.TabIndex = 1; + this.statusStrip1.Text = "statusStrip1"; + // + // toolStripStatusLabel1 + // + this.toolStripStatusLabel1.Name = "toolStripStatusLabel1"; + this.toolStripStatusLabel1.Size = new System.Drawing.Size(604, 17); + this.toolStripStatusLabel1.Spring = true; + // + // MainForm + // + this.AllowDrop = true; + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(619, 423); + this.Controls.Add(this.statusStrip1); + this.Controls.Add(this.toolStrip1); + this.Controls.Add(this._nodeTree); + this.Controls.Add(this.menuStrip1); + this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); + this.MainMenuStrip = this.menuStrip1; + this.Name = "MainForm"; + this.Text = "NBTExplorer"; + this.menuStrip1.ResumeLayout(false); + this.menuStrip1.PerformLayout(); + this.toolStrip1.ResumeLayout(false); + this.toolStrip1.PerformLayout(); + this.statusStrip1.ResumeLayout(false); + this.statusStrip1.PerformLayout(); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.MenuStrip menuStrip1; + private System.Windows.Forms.ToolStripMenuItem fileToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem searchToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem helpToolStripMenuItem; + private System.Windows.Forms.TreeView _nodeTree; + private System.Windows.Forms.ToolStrip toolStrip1; + private System.Windows.Forms.ToolStripButton _buttonOpen; + private System.Windows.Forms.ToolStripButton _buttonSave; + private System.Windows.Forms.ToolStripSeparator toolStripSeparator1; + private System.Windows.Forms.ToolStripButton _buttonRename; + private System.Windows.Forms.ToolStripButton _buttonEdit; + private System.Windows.Forms.ToolStripButton _buttonDelete; + private System.Windows.Forms.ToolStripSeparator toolStripSeparator2; + private System.Windows.Forms.ToolStripButton _buttonAddTagByte; + private System.Windows.Forms.ToolStripButton _buttonAddTagShort; + private System.Windows.Forms.ToolStripButton _buttonAddTagInt; + private System.Windows.Forms.ToolStripButton _buttonAddTagLong; + private System.Windows.Forms.ToolStripButton _buttonAddTagFloat; + private System.Windows.Forms.ToolStripButton _buttonAddTagDouble; + private System.Windows.Forms.ToolStripButton _buttonAddTagByteArray; + private System.Windows.Forms.ToolStripButton _buttonAddTagList; + private System.Windows.Forms.ToolStripButton _buttonAddTagCompound; + private System.Windows.Forms.ImageList imageList1; + private System.Windows.Forms.ToolStripButton _buttonAddTagString; + private System.Windows.Forms.ToolStripMenuItem _menuItemAbout; + private System.Windows.Forms.ToolStripMenuItem openToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem openFolderToolStripMenuItem; + private System.Windows.Forms.ToolStripSeparator toolStripSeparator3; + private System.Windows.Forms.ToolStripMenuItem saveToolStripMenuItem; + private System.Windows.Forms.ToolStripSeparator toolStripSeparator4; + private System.Windows.Forms.ToolStripMenuItem _menuItemExit; + private System.Windows.Forms.ToolStripMenuItem _menuItemFind; + private System.Windows.Forms.ToolStripMenuItem findNextToolStripMenuItem; + private System.Windows.Forms.ToolStripSeparator toolStripSeparator5; + private System.Windows.Forms.ToolStripButton _buttonFindNext; + private System.Windows.Forms.ToolStripButton _buttonOpenFolder; + private System.Windows.Forms.ToolStripMenuItem openMinecraftSaveFolderToolStripMenuItem; + private System.Windows.Forms.ToolStripPanel BottomToolStripPanel; + private System.Windows.Forms.ToolStripPanel TopToolStripPanel; + private System.Windows.Forms.ToolStripPanel RightToolStripPanel; + private System.Windows.Forms.ToolStripPanel LeftToolStripPanel; + private System.Windows.Forms.ToolStripContentPanel ContentPanel; + private System.Windows.Forms.StatusStrip statusStrip1; + private System.Windows.Forms.ToolStripStatusLabel toolStripStatusLabel1; + private System.Windows.Forms.ToolStripButton _buttonAddTagIntArray; + private System.Windows.Forms.ToolStripMenuItem editToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem _menuItemCut; + private System.Windows.Forms.ToolStripMenuItem _menuItemCopy; + private System.Windows.Forms.ToolStripMenuItem _menuItemPaste; + private System.Windows.Forms.ToolStripSeparator toolStripSeparator7; + private System.Windows.Forms.ToolStripMenuItem _menuItemRename; + private System.Windows.Forms.ToolStripMenuItem _menuItemEditValue; + private System.Windows.Forms.ToolStripMenuItem _menuItemDelete; + private System.Windows.Forms.ToolStripButton _buttonCut; + private System.Windows.Forms.ToolStripButton _buttonCopy; + private System.Windows.Forms.ToolStripButton _buttonPaste; + private System.Windows.Forms.ToolStripSeparator toolStripSeparator6; + } +} + diff --git a/MainForm.cs b/MainForm.cs new file mode 100644 index 0000000..6953fb4 --- /dev/null +++ b/MainForm.cs @@ -0,0 +1,523 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Windows.Forms; +using Substrate; +using Substrate.Core; +using Substrate.Nbt; +using NBTExplorer.Model; + +namespace NBTExplorer +{ + public partial class MainForm : Form + { + private static Dictionary _tagIconIndex; + + private IconRegistry _iconRegistry; + + static MainForm () + { + _tagIconIndex = new Dictionary(); + _tagIconIndex[TagType.TAG_BYTE] = 0; + _tagIconIndex[TagType.TAG_SHORT] = 1; + _tagIconIndex[TagType.TAG_INT] = 2; + _tagIconIndex[TagType.TAG_LONG] = 3; + _tagIconIndex[TagType.TAG_FLOAT] = 4; + _tagIconIndex[TagType.TAG_DOUBLE] = 5; + _tagIconIndex[TagType.TAG_BYTE_ARRAY] = 6; + _tagIconIndex[TagType.TAG_STRING] = 7; + _tagIconIndex[TagType.TAG_LIST] = 8; + _tagIconIndex[TagType.TAG_COMPOUND] = 9; + _tagIconIndex[TagType.TAG_INT_ARRAY] = 14; + } + + public MainForm () + { + InitializeComponent(); + InitializeIconRegistry(); + + _nodeTree.BeforeExpand += _nodeTree_BeforeExpand; + _nodeTree.AfterSelect += _nodeTree_AfterSelect; + _nodeTree.NodeMouseDoubleClick += _nodeTree_NodeMouseDoubleClick; + + _buttonEdit.Click += _buttonEdit_Click; + _buttonRename.Click += _buttonRename_Click; + _buttonDelete.Click += _buttonDelete_Click; + _buttonCopy.Click += _buttonCopy_Click; + _buttonCut.Click += _buttonCut_Click; + _buttonPaste.Click += _buttonPaste_Click; + _buttonAddTagByte.Click += _buttonAddTagByte_Click; + _buttonAddTagByteArray.Click += _buttonAddTagByteArray_Click; + _buttonAddTagCompound.Click += _buttonAddTagCompound_Click; + _buttonAddTagDouble.Click += _buttonAddTagDouble_Click; + _buttonAddTagFloat.Click += _buttonAddTagFloat_Click; + _buttonAddTagInt.Click += _buttonAddTagInt_Click; + _buttonAddTagIntArray.Click += _buttonAddTagIntArray_Click; + _buttonAddTagList.Click += _buttonAddTagList_Click; + _buttonAddTagLong.Click += _buttonAddTagLong_Click; + _buttonAddTagShort.Click += _buttonAddTagShort_Click; + _buttonAddTagString.Click += _buttonAddTagString_Click; + + _menuItemExit.Click += _menuItemExit_Click; + _menuItemEditValue.Click += _menuItemEditValue_Click; + _menuItemRename.Click += _menuItemRename_Click; + _menuItemDelete.Click += _menuItemDelete_Click; + _menuItemCopy.Click += _menuItemCopy_Click; + _menuItemCut.Click += _menuItemCut_Click; + _menuItemPaste.Click += _menuItemPaste_Click; + _menuItemAbout.Click += _menuItemAbout_Click; + + /*_nodeTree.BeforeExpand += NodeExpand; + _nodeTree.AfterCollapse += NodeCollapse; + _nodeTree.AfterSelect += NodeSelected; + _nodeTree.NodeMouseClick += NodeClicked; + _nodeTree.NodeMouseDoubleClick += NodeDoubleClicked; + + string[] args = Environment.GetCommandLineArgs(); + if (args.Length > 1) { + OpenFile(args[1]); + } + else { + OpenMinecraftDir(); + }*/ + + //OpenDirectory(@"F:\Minecraft\tps"); + + string[] args = Environment.GetCommandLineArgs(); + if (args.Length > 1) { + OpenFile(args[1]); + } + else { + OpenMinecraftDirectory(); + } + } + + private void InitializeIconRegistry () + { + _iconRegistry = new IconRegistry(); + _iconRegistry.DefaultIcon = 15; + + _iconRegistry.Register(typeof(TagByteDataNode), 0); + _iconRegistry.Register(typeof(TagShortDataNode), 1); + _iconRegistry.Register(typeof(TagIntDataNode), 2); + _iconRegistry.Register(typeof(TagLongDataNode), 3); + _iconRegistry.Register(typeof(TagFloatDataNode), 4); + _iconRegistry.Register(typeof(TagDoubleDataNode), 5); + _iconRegistry.Register(typeof(TagByteArrayDataNode), 6); + _iconRegistry.Register(typeof(TagStringDataNode), 7); + _iconRegistry.Register(typeof(TagListDataNode), 8); + _iconRegistry.Register(typeof(TagCompoundDataNode), 9); + _iconRegistry.Register(typeof(RegionChunkDataNode), 9); + _iconRegistry.Register(typeof(DirectoryDataNode), 10); + _iconRegistry.Register(typeof(RegionFileDataNode), 11); + _iconRegistry.Register(typeof(NbtFileDataNode), 12); + _iconRegistry.Register(typeof(TagIntArrayDataNode), 14); + } + + private void OpenFile (string path) + { + _nodeTree.Nodes.Clear(); + + NbtFileDataNode node = NbtFileDataNode.TryCreateFrom(path); + + _nodeTree.Nodes.Add(CreateUnexpandedNode(node)); + } + + private void OpenDirectory (string path) + { + _nodeTree.Nodes.Clear(); + + DirectoryDataNode node = new DirectoryDataNode(path); + + TreeNode frontNode = CreateUnexpandedNode(node); + _nodeTree.Nodes.Add(frontNode); + + ExpandNode(frontNode); + frontNode.Expand(); + } + + private void OpenMinecraftDirectory () + { + try { + string path = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData); + path = Path.Combine(path, ".minecraft"); + path = Path.Combine(path, "saves"); + + if (!Directory.Exists(path)) { + path = Environment.GetFolderPath(Environment.SpecialFolder.MyComputer); + } + + OpenDirectory(path); + } + catch (Exception) { + MessageBox.Show("Could not open default Minecraft save directory"); + try { + OpenDirectory(Directory.GetCurrentDirectory()); + } + catch (Exception) { + MessageBox.Show("Could not open current directory, this tool is probably not compatible with your platform."); + Application.Exit(); + } + } + } + + private TreeNode CreateUnexpandedNode (DataNode node) + { + TreeNode frontNode = new TreeNode(node.NodeDisplay); + frontNode.ImageIndex = _iconRegistry.Lookup(node.GetType()); + frontNode.SelectedImageIndex = frontNode.ImageIndex; + frontNode.Tag = node; + + if (node.HasUnexpandedChildren) + frontNode.Nodes.Add(new TreeNode()); + + return frontNode; + } + + private void ExpandNode (TreeNode node) + { + if (node == null || !(node.Tag is DataNode)) + return; + + DataNode backNode = node.Tag as DataNode; + if (!backNode.HasUnexpandedChildren) + return; + + node.Nodes.Clear(); + + if (!backNode.IsExpanded) + backNode.Expand(); + + foreach (DataNode child in backNode.Nodes) + node.Nodes.Add(CreateUnexpandedNode(child)); + } + + private void CreateNode (TreeNode node, TagType type) + { + if (node == null || !(node.Tag is DataNode)) + return; + + DataNode dataNode = node.Tag as DataNode; + if (!dataNode.CanCreateTag(type)) + return; + + if (dataNode.CreateNode(type)) { + node.Text = dataNode.NodeDisplay; + RefreshChildNodes(node, dataNode); + UpdateUI(dataNode); + } + } + + private void RefreshChildNodes (TreeNode node, DataNode dataNode) + { + Dictionary currentNodes = new Dictionary(); + foreach (TreeNode child in node.Nodes) { + if (child.Tag is DataNode) + currentNodes.Add(child.Tag as DataNode, child); + } + + foreach (DataNode child in dataNode.Nodes) { + if (!currentNodes.ContainsKey(child)) + node.Nodes.Add(CreateUnexpandedNode(child)); + else + currentNodes.Remove(child); + } + + foreach (TreeNode child in currentNodes.Values) { + node.Nodes.Remove(child); + } + + if (node.Nodes.Count == 0 && dataNode.HasUnexpandedChildren) { + ExpandNode(node); + node.Expand(); + } + } + + private void EditNode (TreeNode node) + { + if (node == null || !(node.Tag is DataNode)) + return; + + DataNode dataNode = node.Tag as DataNode; + if (!dataNode.CanEditNode) + return; + + if (dataNode.EditNode()) { + node.Text = dataNode.NodeDisplay; + } + } + + private void RenameNode (TreeNode node) + { + if (node == null || !(node.Tag is DataNode)) + return; + + DataNode dataNode = node.Tag as DataNode; + if (!dataNode.CanRenameNode) + return; + + if (dataNode.RenameNode()) { + node.Text = dataNode.NodeDisplay; + } + } + + private void DeleteNode (TreeNode node) + { + if (node == null || !(node.Tag is DataNode)) + return; + + DataNode dataNode = node.Tag as DataNode; + if (!dataNode.CanDeleteNode) + return; + + if (dataNode.DeleteNode()) { + UpdateUI(node.Parent.Tag as DataNode); + UpdateNodeText(node.Parent); + node.Remove(); + } + } + + private void CopyNode (TreeNode node) + { + if (node == null || !(node.Tag is DataNode)) + return; + + DataNode dataNode = node.Tag as DataNode; + if (!dataNode.CanCopyNode) + return; + + dataNode.CopyNode(); + } + + private void CutNode (TreeNode node) + { + if (node == null || !(node.Tag is DataNode)) + return; + + DataNode dataNode = node.Tag as DataNode; + if (!dataNode.CanCutNode) + return; + + if (dataNode.CutNode()) { + UpdateUI(node.Parent.Tag as DataNode); + UpdateNodeText(node.Parent); + node.Remove(); + } + } + + private void PasteNode (TreeNode node) + { + if (node == null || !(node.Tag is DataNode)) + return; + + DataNode dataNode = node.Tag as DataNode; + if (!dataNode.CanPasteIntoNode) + return; + + if (dataNode.PasteNode()) { + node.Text = dataNode.NodeDisplay; + RefreshChildNodes(node, dataNode); + UpdateUI(dataNode); + } + } + + private void UpdateNodeText (TreeNode node) + { + if (node == null || !(node.Tag is DataNode)) + return; + + DataNode dataNode = node.Tag as DataNode; + node.Text = dataNode.NodeDisplay; + } + + private void UpdateUI (DataNode node) + { + if (node == null) + return; + + _buttonAddTagByte.Enabled = node.CanCreateTag(TagType.TAG_BYTE); + _buttonAddTagByteArray.Enabled = node.CanCreateTag(TagType.TAG_BYTE_ARRAY); + _buttonAddTagCompound.Enabled = node.CanCreateTag(TagType.TAG_COMPOUND); + _buttonAddTagDouble.Enabled = node.CanCreateTag(TagType.TAG_DOUBLE); + _buttonAddTagFloat.Enabled = node.CanCreateTag(TagType.TAG_FLOAT); + _buttonAddTagInt.Enabled = node.CanCreateTag(TagType.TAG_INT); + _buttonAddTagIntArray.Enabled = node.CanCreateTag(TagType.TAG_INT_ARRAY); + _buttonAddTagList.Enabled = node.CanCreateTag(TagType.TAG_LIST); + _buttonAddTagLong.Enabled = node.CanCreateTag(TagType.TAG_LONG); + _buttonAddTagShort.Enabled = node.CanCreateTag(TagType.TAG_SHORT); + _buttonAddTagString.Enabled = node.CanCreateTag(TagType.TAG_STRING); + + _buttonCopy.Enabled = node.CanCopyNode; + _buttonCut.Enabled = node.CanCutNode; + _buttonDelete.Enabled = node.CanDeleteNode; + _buttonEdit.Enabled = node.CanEditNode; + _buttonFindNext.Enabled = node.CanSearchNode; // Not entirely + _buttonPaste.Enabled = node.CanPasteIntoNode; // Not entirely + _buttonRename.Enabled = node.CanRenameNode; + + _menuItemCopy.Enabled = node.CanCopyNode; + _menuItemCut.Enabled = node.CanCutNode; + _menuItemDelete.Enabled = node.CanDeleteNode; + _menuItemEditValue.Enabled = node.CanEditNode; + _menuItemFind.Enabled = node.CanSearchNode; + _menuItemPaste.Enabled = node.CanPasteIntoNode; // Not entirely + _menuItemRename.Enabled = node.CanRenameNode; + } + + #region Event Handlers + + #region TreeView Event Handlers + + private void _nodeTree_BeforeExpand (object sender, TreeViewCancelEventArgs e) + { + ExpandNode(e.Node); + } + + private void _nodeTree_AfterSelect (object sender, TreeViewEventArgs e) + { + UpdateUI(e.Node.Tag as DataNode); + } + + private void _nodeTree_NodeMouseDoubleClick (object sender, TreeNodeMouseClickEventArgs e) + { + EditNode(e.Node); + } + + #endregion + + #region Toolstrip Event Handlers + + private void _buttonEdit_Click (object sender, EventArgs e) + { + EditNode(_nodeTree.SelectedNode); + } + + private void _buttonRename_Click (object sender, EventArgs e) + { + RenameNode(_nodeTree.SelectedNode); + } + + private void _buttonDelete_Click (object sender, EventArgs e) + { + DeleteNode(_nodeTree.SelectedNode); + } + + private void _buttonCopy_Click (object sernder, EventArgs e) + { + CopyNode(_nodeTree.SelectedNode); + } + + private void _buttonCut_Click (object sernder, EventArgs e) + { + CutNode(_nodeTree.SelectedNode); + } + + private void _buttonPaste_Click (object sernder, EventArgs e) + { + PasteNode(_nodeTree.SelectedNode); + } + + private void _buttonAddTagByteArray_Click (object sender, EventArgs e) + { + CreateNode(_nodeTree.SelectedNode, TagType.TAG_BYTE_ARRAY); + } + + private void _buttonAddTagByte_Click (object sender, EventArgs e) + { + CreateNode(_nodeTree.SelectedNode, TagType.TAG_BYTE); + } + + private void _buttonAddTagCompound_Click (object sender, EventArgs e) + { + CreateNode(_nodeTree.SelectedNode, TagType.TAG_COMPOUND); + } + + private void _buttonAddTagDouble_Click (object sender, EventArgs e) + { + CreateNode(_nodeTree.SelectedNode, TagType.TAG_DOUBLE); + } + + private void _buttonAddTagFloat_Click (object sender, EventArgs e) + { + CreateNode(_nodeTree.SelectedNode, TagType.TAG_FLOAT); + } + + private void _buttonAddTagInt_Click (object sender, EventArgs e) + { + CreateNode(_nodeTree.SelectedNode, TagType.TAG_INT); + } + + private void _buttonAddTagIntArray_Click (object sender, EventArgs e) + { + CreateNode(_nodeTree.SelectedNode, TagType.TAG_INT_ARRAY); + } + + private void _buttonAddTagList_Click (object sender, EventArgs e) + { + CreateNode(_nodeTree.SelectedNode, TagType.TAG_LIST); + } + + private void _buttonAddTagLong_Click (object sender, EventArgs e) + { + CreateNode(_nodeTree.SelectedNode, TagType.TAG_LONG); + } + + private void _buttonAddTagShort_Click (object sender, EventArgs e) + { + CreateNode(_nodeTree.SelectedNode, TagType.TAG_SHORT); + } + + private void _buttonAddTagString_Click (object sender, EventArgs e) + { + CreateNode(_nodeTree.SelectedNode, TagType.TAG_STRING); + } + + #endregion + + #region Menu Event Handlers + + private void _menuItemExit_Click (object sender, EventArgs e) + { + Close(); + } + + private void _menuItemEditValue_Click (object sender, EventArgs e) + { + EditNode(_nodeTree.SelectedNode); + } + + private void _menuItemRename_Click (object sender, EventArgs e) + { + RenameNode(_nodeTree.SelectedNode); + } + + private void _menuItemDelete_Click (object sender, EventArgs e) + { + DeleteNode(_nodeTree.SelectedNode); + } + + private void _menuItemCopy_Click (object sender, EventArgs e) + { + CopyNode(_nodeTree.SelectedNode); + } + + private void _menuItemCut_Click (object sender, EventArgs e) + { + CutNode(_nodeTree.SelectedNode); + } + + private void _menuItemPaste_Click (object sender, EventArgs e) + { + PasteNode(_nodeTree.SelectedNode); + } + + private void _menuItemAbout_Click (object sender, EventArgs e) + { + new About().ShowDialog(); + } + + #endregion + + #endregion + } +} diff --git a/MainForm.resx b/MainForm.resx new file mode 100644 index 0000000..5097d62 --- /dev/null +++ b/MainForm.resx @@ -0,0 +1,1146 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 17, 17 + + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 + YQUAAAAZdEVYdFNvZnR3YXJlAEFkb2JlIEltYWdlUmVhZHlxyWU8AAACkklEQVQ4T43SX0hTURzA8d9b + 9O/BHjPowfZkRgTRgxVFJgrBRKT2kJWjEsUsKyprtZyumdoSZ86hGdU0LUOTsJXGahCYthIUs6au/fPf + nJvzOvfXX+ccusINgg584Hfhni/ncC8MqACoL+WQQ5T8pxx+H/STzX+UcpZynPl4CmeNJ5Ebuo0xRyPi + 5BOh2RYk75fy+6BPCTwlLrzEFe8LDNpr0dNXiG+1h/DdG7VAT68GO8vi69Ql+6FKvg/gU9kqVWy+DaMz + eibmfY7mjnPo9HhwiuPQQdj8fnxlMqFSnmrIlMlEGcXFACbFqoqouwUjk48ZOn9uleKwxYLfRkdx3O3G + kakpbO7uRrrI5jxCBEY58O5Fpp9iyPGQobPpkQS/j42xyKTPxyIavX6VKD1dBj03gVcdcjVhwFrP0NnY + eBR/TEywyBy5Ah+hJ6HXSSsqKgDDDeDVLtsakLPUMnTu1WWixWplEe/SkiDiWFzElIKCQnh9DXjawIQW + /aPVDJ0NdWIct9lYZGF5WRCZDgTwQG7uBei8ArwG7mcN+oYrGTp31xxBKwnQCBcMCiLz5HmvVHoRFMcA + 2i8xTf4RNXoGVQydu+6noc1uZ5FAOCyI+Mnznuzsy0DXrSyAZ+dB7xuqQLdZwdC5ozIV7Q4HiwQjEUGE + I4FdEgk5P8BaYpPuLHR5B8mv3C9nvOQU7XdT0Ol0skgkGhVElkhwu1hMviFAHLEtPxXq31fv9o8b8sJz + Awqc/6rE1jsH0eVyoZOIraxglAjHYhgisRCZ45OTy9kV6Dq8A0B3BjK0p0HXdn3LB3Nz5q+rWWvs60Qi + zYbExIqNSUmqv61PSMgXBMhm0EgB1CdgZ9VxkJVJ4AF5YSux+R/ifgP/44T3ShVnvwAAAABJRU5ErkJg + gg== + + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 + YQUAAAAJcEhZcwAADrwAAA68AZW8ckkAAAI/SURBVDhPjdJPSJNxGAfw5xYd6+hZJIhCkm5d8hBeIq/9 + AftDgRcPHQzEqVPn5sRcNptjuVjZYlkUFZZpusQIFf+h2Zwuc0NJl5vatub+fXufB1e8DKTBhz1s3+f7 + vr+Xl2jvM2GgK+MG0v4Pzmb3/n6PNVFDZMmAdfdlbAyVITJbh3TgPrD2UG3DCc7mFHxuJB22nyMT7kHc + 34HN0QosuEqQWepUwaoDnM0pGGkkfTrkQmq9W6TDTzHjKMb2jAlJ7z2kFy0iE3gAzuYUDGvJmAo6kVxz + CJ6nuk7BP6IXKaWEpf12cDanYKiGWpM/HmE30CV4/mQ+iZVhnUh4zCK1bANncwr6NWTaXbUjttwpeHab + TmDZ3SDi8+0i4bOCs30aKlKVvKsi8+8VGyKLZsHzQGshfINaEZsziV1+FpkMOK8qeFNJltg3C3Y8JsHz + 2+ZjWPpQJ6KzbSK+0IFQNArOqwpeVpIt4m3H1lyL4Pm17ii8A7Xi10yriH29C18wCM6rCp7dJPvO/G1s + TusFzy/qj8DzXiO2p1pE9MsdnB7NgPOqAmcFdW/NGhGcqBc899QUwNNXLbYmjSKiHON4bwSczxYcVIbD + 1uv0KjytvMpjtSKs3IVLU4BF5fZZ9ghR5UFy9loxnVX2eJcOKfLLz1Bnv6lox9dbnvg5Xo/QpA7NFyh8 + 6xyNsJZLNJjFWd7Z2/13EusNKrVcJeuTqjz3+OPS780X6aPyb15JPh3IeXH2+6GtjAqVq1U3nad2Jbfv + 8h/ayQIkRwIF8QAAAABJRU5ErkJggg== + + + + + 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 + gsnRJ2HiAAAAAElFTkSuQmCC + + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 + YQUAAAAZdEVYdFNvZnR3YXJlAEFkb2JlIEltYWdlUmVhZHlxyWU8AAACc0lEQVQ4T43SW0hUURQG4PWS + 0JsIFUQ9lWMTFo63RqXRLKoRDMbMcbyMWtqY5qBOjsEEFmlRJAaTlJRdTLtn+ZBBL4EE9rBDu0AlIURZ + D4VQjo3j7W+v0+xT+tSBj7M5Z6+ftdc5dC6diLVn/HXIaozIzc3NkVxhOfzs3z2qTisOB3TIDYKdMNFw + 12H3l5GRD2C85mfqvbx36AF+GRAm3rfvRV9NKgYHX2Fo6B1GRz9reM3P+N1bfynkfqHq6OxmUsTrtiJc + L4nFRftaXCtej5v74nC7Ih7dpRtwuSAGPWUb8bK1ALJGqDpqTSVFDJ9x4NnRbDz2ZGguNNjQ1ujQnW8q + Q2eLC83bl72pLbSQ25FGdNqsEy9O5eGpb6fO7yvGr7k5/JyexvepKYwFAugbGECtPeWjzeeLzvZ6iU4m + 6cTzZhueeLfqWr35mJyZwfjkJL5NTODT+Dh6+vvBlyyukgx0PIEUwe0/qrNoeGDHqrIRnJ3Fj2BQD/F3 + d0OJtlqPUFMcKYLbv38gWRvkpfxoNJRkIiSPEAiFFoRwJ2Oyq23V1W7yxZIi+uvTcaVwHTodBo3HmYkZ + GRCUM1gcwjOxVFTUUaORFPGg2oyrRUZdXfEWzM3PIySPsTiEB2t2Oj1UbyBF9MqALtm+4i7MwLwc2Kzs + YnFIQAbE2+1e2r2SyL1GI3qrNmk/i1KZl6ZNnEO4Ez4Oz4QHOyXvMVlZPuJr1woi1+o/AbfKTboaWzzy + raYFHFkmJBlXfY00mVqiEhPLuX6ptHxPJImHB1O0r3CvMgl3XYm6O/sTwPi3ZryXa8K1FCUXsclL6MaO + CBL/g/dyjRT1G7y5F+bDPK+HAAAAAElFTkSuQmCC + + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 + YQUAAAAZdEVYdFNvZnR3YXJlAEFkb2JlIEltYWdlUmVhZHlxyWU8AAAAt0lEQVQ4T6VSSwoCMQxNTzBL + wYX3cu9F5j7iQhAFQXAxC8/gATxGzQuNhEdHM1h4NOn7tBlGaq3yD6SUAoyKfauxZ2p4xAMOzex9ZjdP + RvhV4+QxvAD1VhHPeiHGO3GiEbjvBZhm7nmX7DfxgCsZuO9dZBonbhTAfS/ANHMj3JeOMJGB+95FpnHi + EQJQ7xTxTLDoEuN//kjmDItHc+rJwkT/8WxUfFa8mgl7poYHXhkUK8V6IeAZ3llKVtf+E8JOAAAAAElF + TkSuQmCC + + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 + YQUAAAAZdEVYdFNvZnR3YXJlAEFkb2JlIEltYWdlUmVhZHlxyWU8AAADaWlUWHRYTUw6Y29tLmFkb2Jl + LnhtcAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQi + Pz4gPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENv + cmUgNS4wLWMwNjAgNjEuMTM0Nzc3LCAyMDEwLzAyLzEyLTE3OjMyOjAwICAgICAgICAiPiA8cmRmOlJE + RiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPiA8 + cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIiB4bWxuczp4bXBSaWdodHM9Imh0dHA6Ly9ucy5hZG9i + ZS5jb20veGFwLzEuMC9yaWdodHMvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAv + MS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNv + dXJjZVJlZiMiIHhtbG5zOnhtcD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLyIgeG1wUmlnaHRz + Ok1hcmtlZD0iRmFsc2UiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6NzA0RUI0NjQwMzg3MTFFMUFE + RTJDQkMzMDBBQjU2MjYiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6NzA0RUI0NjMwMzg3MTFFMUFE + RTJDQkMzMDBBQjU2MjYiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTMyBXaW5kb3dz + Ij4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InV1aWQ6QUMxRjJFODMzMjRBREYx + MUFBQjhDNTM5MEQ4NUI1QjMiIHN0UmVmOmRvY3VtZW50SUQ9InV1aWQ6QzlEMzQ5NjY0QTNDREQxMUIw + OEFCQkJDRkYxNzIxNTYiLz4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+ + IDw/eHBhY2tldCBlbmQ9InIiPz4xPsWJAAACIElEQVQ4T4WSXUhTYRiA3/dbG7omFjZGFyFBJBkW9nMR + SD/o2kUF5+aElZo0LyYG9oOh5aIakxlpKAxrQ1jUZEWRRT/EvBiKFLEslW6CmeWwCyFJangRvL3fwcmx + OnrguTgcnuf7zve9ACs8JUUIbU0IqqpqpBG3TiL2jiHue4FobGfFp2EEyUKgcMBu76VAgIYRXz1DLP+n + 8LeoC2xSFKU+k8nQvMdDc1VVFAN4shgwErVACPcHffa7Uk4mk5RKpchnsTyPAOyA4kIAbw1o2/wvLD8K + 4kv6HqD4g52a7HA4fKW5uVtUsxkg2grQ5zUI6OTfMz6aeHeUblzM6bfZbNutVitIjAM6ef7bZZp8f5we + Bk2J/pCpPCsbB3Tyz6lmmhqrpnsdYvB+t6h4fNukrWy8A508O3GW0uO1FPaLoTvXhTPWJWD5gE6e+VSv + yd2tYvjWNeGMtAvQB8zyAOWzeIg6efqjm+WT1H4eX99sQWfPVQHZQOURsXR2ZIApinVgn7yqr6PV9OXD + CbrSgG/azuDBzmYEGVCcBmMbbgJLzzk4/SOdmE3GK+jzSCW1uPGt14MufyOCq2yZeZd76WzAPfHoqcTc + 9CClRiK/Go/h0IVacO3dtYKY/ZFLNeiXcrRLHa07jKEDpajwNztTwKxl8pk8hqcGchgLs4oxMdoqVHcI + Q2Xb0J1nxd38XsIUM5uZjcwGZj2zjlnDrF4IyWsQfwCLISjKZ5nx7AAAAABJRU5ErkJggg== + + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 + YQUAAAAZdEVYdFNvZnR3YXJlAEFkb2JlIEltYWdlUmVhZHlxyWU8AAABfUlEQVQ4T6WTu0vDUBTGz1+g + VBtB1KBgdSsUNFvHQoZChw4upWoRupYO7a6giw66KCj4wgciuAiKg5M4XcFBUHAVBxdXcfD4fTGJqaZT + hx+353yPezNUVFU6oaMwL/YKDkXkCJyIuMDw5LzvE6cx87eAIaPNpvIEbqTA0z5qtVBrKfCN5qvR0Id8 + Xj/rdcXOAJYQ81apeNpLqRRovy/YxXOAuwPje7Wq146jr+WyciaPhYK3u8vlvB29zISfwAGCbEHYhOG5 + WNSLdFpvs1m9ymR027L02LaVGj30xhbAIBswrMN4nkrpXiLhcZBMKnfU6PlXsIjlElgBqzCtwXyGW08R + DuCOGj30MhN+QlCw/GMwlwjGQY2edgUUzA3CAZzb7NyWF8zjOcDcIxzAeQG3kTiNmfATbAxTMNYRekIJ + T87D2JM4jZmwAL8HwdiEyNw0wpMis5hHwRAYACOOyAw1ejCPMxMt6MKiF/T79OHsAd2AWgJYET3JfVjQ + yd/5G8s+qAWdGU8YAAAAAElFTkSuQmCC + + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 + YQUAAAAZdEVYdFNvZnR3YXJlAEFkb2JlIEltYWdlUmVhZHlxyWU8AAACDElEQVQ4T42SzWoaURTHRxER + QUVBCqVv4aZxIX7MBNMQJn7G6ERNFRTRGT8riCAluMob5BmSTQjNRkogkEWg4LJQUgiE0NCH+PecYabc + BhcVftzjPef8Zu49IzkcDkngM8XnBK/iPscbc6+LLqbTKXw+3yoQCEihUMiEY97jHIkuRLkoOAmHw99k + WQavxBkhWXD8N0eCE1siCi6XyyVGoxEMY8SStQjnptNP0PU+v8XlJsHVYrHA0ZGGXK6CSCSCfr9vwjHn + Go0GstkiC642Ca7n8znK5UNEo1GzSURRFNTrdahqjgXXrwWnwWDwO5/fblJVFZ1Ox4Rj3pfllLlyLQlO + WWLfwWo2m9HZdeTzeWxtRUE3/0OkUCig1+uh2WwSbX6LlSi4GY/HqFY1eoqM3d0Cj/Kn3+9/z3A8mUzo + Dj5iZyeNdHqfBTei4HYwGKBSOUQikaCCLLxe7yMhWTwOh0O6gxq2txUoyh4LbkXBna7rKJWKiMViVKDC + 4/E8EZLFk2EY5oRSqSSSyQ8suBMF991uF8fHdfMODg40uN3uZ0KyeOY8j7FYLBJlFtyLgnU8Hjft9hRc + LtcLIVm88NF4lHaemtemwPo9tFotaJpGI9unD6kEp9P52541x+12G7ValT6kDDKZAqjvwW5+R8EX4pcI + NX+l/xHGiv/JWz3cK/mJEPGGePufcC33+P8AbaoESlToQpYAAAAASUVORK5CYII= + + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 + YQUAAAAZdEVYdFNvZnR3YXJlAEFkb2JlIEltYWdlUmVhZHlxyWU8AAACZElEQVQ4T4WSXWhSYRjHj8Ns + GDrmJutjd0LrJroQYjoQzWO4BiluTt3OlkvXlqhH50xaizWWrNhdEWNdBEFBFxvBGI3AaiR1EQV2EQxG + weiDotsuol38e56D2mEMEn68f9/nfX6e87wKGo1GUDFLeZngVb3Pec/a7kMrhUIBBoOh1NTUJJhMJgXO + vMc1Eq2o5WrBnNlsfieKIngl7hJCFc71GgnmahK1YLVYLCKXy0GWcyypqOFaoXAJ6XSGn2J1L8HazMwM + hoYk9PYOwmq1IpPJKHDmWiwWQyDQz4K1vQTr09PTGBiIwG63K01qPB4PotEofL5eFqzvFiw0Nzdv8vvX + mnw+HxKJhAJn3hdFt7LyWRIssKQ2g9LU1BS9exp9fX2w2eygyW+pCQaDSKVSiMfjxDg/RUkt2JicnMTw + sES/IqKnJ8hX+cloNHYynPP5PM3gPLq7vfB6/SzYUAvK2WwWg4MRuFwuOhCAXq/fJoQq2xMTEzSDc3Bf + eQT36DwLymrB63Q6jXC4Hw6HAx6PD42NjV8I4Yg3JXCWZVm5Ifv1DeIl2roiWwfFRH0Gb5LJJEZGosoM + QiEJOp3u2yFPQjherCx1yMt/umafwXathJNXn2LxK9CRffyLalJtiBWn0wm3+1T9FrRa7Y9WR1ywXC6/ + vfUZSHwAht7/I7cJcE2ofj6OjY1BkiS6Mj/9kcJoaGj4ub/9hNDiv7nU0n9759jFhzg6/gCW0fvofAW0 + hu78pprE/e3EE+K7GhrQc/puZapZqR84c2OH0VmcL6q9gpGCiWgjDv8P3dnFe/tOz1+o9hj/AtmlLdLj + WupUAAAAAElFTkSuQmCC + + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 + YQUAAAAZdEVYdFNvZnR3YXJlAEFkb2JlIEltYWdlUmVhZHlxyWU8AAAC5klEQVQ4T12OX0iTURjGD4kM + 8y4JCYqQbJZkLhWElStG08lybm5q/k/TajCM/ANOlmmBaEQEqeGFDBd4ITNNIRC0LaXc0vmp6edQYzrN + C0WvvH/63tOM6MDv4/ne9/kdDsvNzWUGg4Hl5eUxk8nEzGbz6fz8fJUEnfthKKtoRx3qkkMu/4QvkEnL + jPr6+iav17u0t7eH3d1dDuWZmZmlurq6JupIF8j+v0BmNBpzHA5HPwnvR1bR+GoBOqufQ9k5LGJnZxt9 + fX391JUukPEX6PV64qa0cAaDQZTbZnG3eR21bw7R0HOE+u4jWF8foKBpje82NtbR29vrJIdcptPpYq1W + q31zM4jiRi8qX4Tw6OU+ch6v4PhQftCxh9KWP51AIACLxWInl2m1WrXb/Xm52+lDXsMKKtpCMNQFoHno + /3sBZZoV24O4U7uIrv4ZjI2NLpPLNBpNKT2rxu5BeWsQWRaBo67+Drn2Ay5oXEjIHkF85hBHdW+ad+fm + ZkEuU6vVVkEQcL1kAiVPf+JWlQ8K0yQuZo9KpTn4/X7Eaz9K/2OclPxJ3p2enga5TKVS1VIxvXAcOU9W + kGhwI0E/CblunMuiKPJMM+Kq+QvvejwekMuUSmWlICygrGEcqmoBiWYf55JhisuhUIjn4/kV81fe9Xim + QC5LT0/PGhx0rXa+8+BagRupFQEkFUsvMc9y+eDggGeaEZdzJ9DR7YbD4Vwll6WlpZ0xGk3t8/PLuF0x + huRCH1Iqt5BU9IPLh4eHPCsqtpBo8vKOz7cAg8HYTi5TKBQsOTlZ29Ly3LW4uI4bhS6cz/yExCIRiqpf + HMo0o50grMFub3ORQy6LjY1lcXFxUXK5vNRmax0WxR109nyDvnoIp1K7OJRpJorbsNmeDVOXHHLpnJA4 + KZPJzsbExJQplRlvBwZGN9bW9vEvNKMddaTuOXLCLouQQoyEXCIlMjJSHRUVVRMdHd0s0RGmmWa0o45E + QtiJ+A2+oxJO8d3MEAAAAABJRU5ErkJggg== + + + + 237, 17 + + + + AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj00LjAuMC4w + LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAACZTeXN0 + ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAADQ + MwAAAk1TRnQBSQFMAgEBEAEAAQgBAQEIAQEBEAEAARABAAT/ARkBAAj/AUIBTQE2BwABNgMAASgDAAFA + AwABUAMAAQEBAAEYBgABPP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AB4AA/wD+SH4A/kD/AMAA/0D+SH4 + A/kD/TkAA/8D/AP5EvgD+QP7A/4GAAGWAakBvAFcAYQBrgFcAYQBrgFcAYQBrgFcAYQBrgFcAYQBrgFc + AYQBrgFcAYQBrgFcAYQBrgFcAYQBrgFcAYQBrgFcAYQBrgFcAYQBrgFcAYQBrgGWAakBvAMAAs8BywK5 + AbACuQGwArkBsAK5AbACuQGwArkBsAK5AbACuQGwArkBsAK5AbACuQGwArkBsAK5AbACzwHLOQAD/gP4 + AegC5QHZAbQBqwHqAY4BdwHuAXABUAHuAXABUAHqAY4BdwHZAbQBqwHoAeUB5AP2A/4GAAFsAZMBugFV + AYgBuwFwAaMB1gFnAZoBzQFnAZoBzQFnAZoBzQFnAZoBzQFnAZoBzQFnAZoBzQFnAZoBzQFnAZoBzQFn + AZoBzQFwAaMB1gFVAYgBuwFsAZMBugMAAsEBuQL5AekC8wHiAvMB4gLzAeIC8wHiAvMB4gLzAeIC8wHi + AvMB4gLzAeIC8wHiAvMB4gL5AekCwQG5PAAB6gHcAdgB7gGCAWcB9QGiAY8B+gHRAcoB/AHnAeUB/AHm + AeUB+QHRAckB9AGhAY4B7gGBAWYB6gHcAdgJAAF+AaIBxwFxAaQB1wFVAYgBuwFxAaQB1wFxAaQB1wFx + AaQB1wFxAaQB1wFxAaQB1wFxAaQB1wFxAaQB1wFxAaQB1wFxAaQB1wFVAYgBuwFxAaQB1wF+AaIBxwMA + AssBwwL0AeQBegGnAZsBhwG3AacBhwG1AaMBiQGzAaIBaAGgAYYBVwGXAXgBWAGTAXkBaAGQAX4BkgGk + AZMBhgGXAYACqAGOAvQB5ALLAcMJAAP+A/wG+QP6BvwD+wb5A/wD/gwAAfMB3wHaAe4BewFgAfcB1AHO + AfcC6QH3AugB/AL0AfwC9AH3AugB9wLpAfYB0QHKAe4BewFfAfMB3wHaBgABhgGqAc0BcwGmAdkBagGd + AdABSAF7Aa4BXwGSAcUBTAF/AbIBXwGSAcUBTAF/AbIBXwGSAcUBTAF/AbIBXwGSAcUBSAF7Aa4BagGd + AdABcwGmAdkBhgGqAc0DAALPAccC9QHmAYQBtQGrAZgB1wHHAZAB0QG+AXMBsAGZAZcBywG2AacBzgG9 + AZcBvQGsAZQBugGoAakBvwGvAY4BrQGhAbcBrQGLAvUB5gLPAccJAAP+A/wD+QOzA1wG/ANcA7QD+QP8 + A/4JAAH6AfgB9wHnAX4BYgHzAdMBzQHwAuUB7wLkAe8C5AHlAWEBPwHlAWEBPwHvAuQB7wLkAe8C5AHv + Ac0BxwHnAX4BYgH6AfgB9wMAAYsBrQHPAXUBqAHbAWwBnwHSAUoBfQGwAWwBnwHSAVIBhQG4AWwBnwHS + AVIBhQG4AWwBnwHSAVIBhQG4AWwBnwHSAUoBfQGwAWwBnwHSAXUBqAHbAYsBrQHPAwAC0QHJAvYB6QGQ + AbwBtQG5AeUB2wGmAd0B0AGIAcABsgGHAckBtQF+Ab4BpAGIAbkBowGuAdABvwGpAccBtQGUAboBqAG2 + AbUBkQL2AekC0QHJDwADywN1A/gGAAP4A3UDyw8AAegBxQG8AeUBnQGKAeoC4gHnAt8B5wLfAecC3wHW + AVkBNwHWAVkBNwHnAt8B5wLfAecC3wHoAuAB4QGXAYQB6AHFAbwDAAGPAbEB0gF3AaoB3QFuAaEB1AFH + AXoBrQFuAaEB1AFPAYIBtQFuAaEB1AFPAYIBtQFuAaEB1AFPAYIBtQFuAaEB1AFHAXoBrQFuAaEB1AF3 + AaoB3QGPAbEB0gMAAtMBzAL3AesBxQG4AYcB/wHeAYwB+AHnAa0B1QHRAbABygHrAeIBvQHlAdkBoAHK + AbsBqgHOAa8BggHBAaQBfgG2ApgBrAGEAvcB6wLTAcwMAAPOA38D+QHdAbMBuQHAAUkBWgHAAUkBWgHd + AbMBuQP5A38DzgwAAdIBhAFuAeoB0AHIAeEC2gHgAtkB4ALZAeAC2QHxAu0B8QLtAeAC2QHgAtkB4ALZ + AeAC2QHhAcQBvQHSAYQBbgMAAZMBtAHUAXgBqwHeAW8BogHVAUQBdwGqAW8BogHVAUwBfwGyAW8BogHV + AUwBfwGyAW8BogHVAUwBfwGyAW8BogHVAUQBdwGqAW8BogHVAXgBqwHeAZMBtAHUAwAC1QHNAvgB7gHR + Aa4BaQHbAboBcQHeAb4BdAHpAckBfAG/Ac0BqAGVAcwBwgGhAc8BvgGRAcQBrwF/Ab0BpgF3AbcBnQGo + AaoBdwL4Ae4C1QHNCQAD0AOGA/kGAAHgAbYBvAHRAXsBhwYAA/kDhgPQCQABuwFUATUB9AHuAe0B5wLl + AdoC1gHYAtQB2ALUAbcBSAEmAbcBSAEmAeMC3wHYAtQB2ALUAdgC1AHhAdgB1gG7AVQBNQMAAZgBuAHX + AXoBrQHgAXEBpAHXAUEBdAGnAXEBpAHXAUkBfAGvAXEBpAHXAUkBfAGvAXEBpAHXAUkBfAGvAXEBpAHX + AUEBdAGnAXEBpAHXAXoBrQHgAZgBuAHXAwAC1wHPAvkB8QHTAawBZgH/AdMBfgH/AdYBggHgAb4BdAH2 + AeEBmQGwAe0B5AGvAdEBvwGiAeAB0wGYAdgBxgGOAdABugG4AbIBgAL5AfEC1wHPBgAD7wNsA+8JAAHj + AbgBvwHXAYEBjQkAA+8DbAPvBgABsQFQATEB9AHvAe0D7gPqAdwC2wHTAtEBxwGmAZwBrgFHASUBwQFz + AVoB3gLcAdIC0AHSAtAB3wHYAdcBsQFQATEDAAGbAboB2QF8Aa8B4gFzAaYB2QE/AXIBpQFzAaYB2QFH + AXoBrQFzAaYB2QFHAXoBrQFzAaYB2QFHAXoBrQFzAaYB2QE/AXIBpQFzAaYB2QF8Aa8B4gGbAboB2QMA + AtkB0QL7AfQB1QGpAWIB/wHOAXkB/wHSAX0B3wG6AW8B/wHYAYMB5gHqAb0BpgHYAc0BswHsAeIBuQHk + AdABtgHcAcQBqwG+AZcC+wH0AtkB0QkAA9QDkQP5BgAB5gG7AcEB3QGHAZMGAAP5A5ED1AkAAcABfQFm + AeoB1QHNCfAD6wPgAcgBnAGNAasBRgEkAb0BigF5A84B0gLRAdwBxwLAAX0BZgMAAZ0BvQHbAX4BsQHk + AXUBqAHbATgBawGeAVEBhAG3ATgBawGeAVEBhAG3ATgBawGeAVEBhAG3ATgBawGeAVEBhAG3ATgBawGe + AXUBqAHbAX4BsQHkAZ0BvQHbAwAC2gHTAvwB9wHXAacBXwHaAawBZAHcAbABZwHnAbwBcAHgAboBbwHj + Ab4BcwHfAdEBmAHbAc8BlgHVAdEBnAHEAc0BpAGdAdEBwwL8AfcC2gHTDAAD1QOWA/kB6AG9AcMB3QFm + AXcB3QFmAXcB6AG9AcMD+QOWA9UMAAHfAcMBuQHUAZ0BigP1BvMB2gGpAZgB2gGpAZgBzwGOAXgBswFP + AS0B0wGhAZAD8wP1AdQBnAGJAd8BwwG5AwABoAG+AdwBfwGyAeUBZgGZAcwBdgGpAdwBdgGpAdwBdgGp + AdwBdgGpAdwBdgGpAdwBdgGpAdwBdgGpAdwBdgGpAdwBdgGpAdwBZgGZAcwBfwGyAeUBoAG+AdwDAALb + AdQC/QH5AdkBpAFcAf8BxAFvAf8ByAFzAd4BsAFnAf8BzgF5Af8B0gF9AeQBvgFyAf8B2AGDAe0B5AGo + AeIB5gG2AdAB1wGtAv0B+QLbAdQPAAPXA5kD+gYAA/oDmQPXDwAB+QH4AfcBywF7AWAB8gHfAdkD+AP3 + AcEBXQE7AcEBXQE7AcEBXQE7AcEBXQE7AekB0AHIA/gB8gHfAdkBywF7AWAB+QH4AfcDAAGjAcAB3gFr + AZ4B0QF3AaoB3QF3AaoB3QF3AaoB3QF3AaoB3QF3AaoB3QF3AaoB3QF3AaoB3QF3AaoB3QF3AaoB3QF3 + AaoB3QF3AaoB3QFrAZ4B0QGjAcAB3gMAAt0B1QL+AfwB2gGjAVoB/wG/AWsB/wHCAW4B3gGsAWIB/wHJ + AXQB/wHNAXgB4wG5AW4B/wHTAX4B/wHXAYMB/AHeAZUB7AHKAXwC/gH8At0B1RIAA9gDnQYAA50D2BUA + Ae4B4AHbAdgBhAFoAfYB4wHcA/wM+wP8AfYB4wHcAdgBhAFoAe4B4AHbBgABpgHDAeABoAHTAfoBmAHL + AfUBkwHGAfMBkwHGAfMBkwHGAfMBkwHGAfMBkwHGAfMBkwHGAfMBkwHGAfMBkwHGAfMBkwHGAfMBmAHL + AfUBoAHTAfoBpgHDAeADAALeAdcC/wH+AdsBoQFYAdsBogFZAdsBpAFbAdsBpQFdAdsBqQFgAdsBrAFj + AdsBrwFmAdsBsQFoAdsBtAFrAdsBtwFuAdsBuQFxAv8B/gLeAdc8AAHwAeIB3QHkAZQBeAHvAbcBpAH6 + AeQB3QH+AfkB9wH+AfkB9wH6AeQB3QHvAbcBpAHkAZQBeAHwAeIB3QkAAegB7QHzAagBxAHhAZcBygH1 + AZIBxQHzAZIBxQHzAZIBxQHzAZIBxQHzAZIBxQHzAZIBxQHzAZIBxQHzAZIBxQHzAZIBxQHzAZcBygH1 + AagBxAHhAegB7QHzAwAC3wHZJ/8C3wHZPwAB+gL4Ae8B0gHIAewBqAGSAewBjgFuAewBjgFuAewBqAGS + Ae8B0gHIAfoC+A8AAegB7QHzAakBxQHiAakBxQHiAakBxQHiAakBxQHiAakBxQHiAakBxQHiAakBxQHi + AakBxQHiAakBxQHiAakBxQHiAakBxQHiAegB7QHzBgAC6gHmAuAB2QLgAdkC4AHZAuAB2QLgAdkC4AHZ + AuAB2QLgAdkC4AHZAuAB2QLgAdkC4AHZAuAB2QLqAebDAAP7A/EBlQGvAbwBaAGbAbYBaAGbAbYBaAGb + AbYBaAGbAbYBaAGbAbYBaAGbAbYBaAGbAbYBaAGbAbYBaAGbAbYBaAGbAbYBlQGvAbwD8QP7FQAS+AP5 + A/0zAAP8A/kk+AP5A/wD/QP6AXcBqAHBAYYBzwHwAYEBywHtAYEBywHtAYEBywHtAYEBywHtAYEBywHt + AYEBywHtAYYBzwHwAUsBjwGxAYYBzwHwAXcBqAHBAdwB4gHlBv0D+Qz4A/MBiQGlAY8BVQGLAV8BVQGL + AV8BVQGLAV8BVQGLAV8BVQGLAV8BVQGLAV8BlAGtAZkGAAPAAywDwAMAA/sb+AP7A/cBkwGmAboBYAGI + Aa8BYAGIAa8BYAGIAa8BYAGIAa8BYAGIAa8BYAGIAa8BYAGIAa8BYAGIAa8BYAGIAa8BYAGIAa8BYAGI + Aa8BYAGIAa8BkwGmAboD9wYAAYYBtQHNAYQBzgHuAXwBxwHoAXwBxwHoAXwBxwHoAXwBxwHoAXwBxwHo + AXwBxwHoAYQBzgHuAVcBmwG9AYQBzgHuAfQBtgEuAYYBtQHNAwAClAG4AlUBowJVAaMCVQGjAlUBowJV + AaMCVQGjAVUBegGJATUBvQF5AUMBywGHAT4BxgGCAT4BxgGCAT4BxgGCAUMBywGHAVUBoAFwBgADQAFn + AlYDQAMAA/sDYQNeA1wDWQNUA0kDPAMvA2wD+wMAAXIBmAG/AXsBrgHgAXoBrQHfAXoBrQHfAXoBrQHf + AXoBrQHfAXoBrQHfAXoBrQHfAXoBrQHfAXoBrQHfAXoBrQHfAXoBrQHfAXsBrgHgAXIBmAG/CQABkQG+ + AdQBhwHQAe8BfwHKAekBfwHKAekBfwHKAekBfwHKAekBfwHKAekBfwHKAekBhwHQAe8BXwGjAcUBhwHQ + Ae8B/gHJAUEBkQG+AdQDAAJVAbQBLwEeAdwBJQETAdgBJQETAdgBJQETAdgBJQETAdgBJQETAdgBVQF+ + AZUBNwG/AXsBQgHKAYYBNwG/AXsBNwG/AXsBNwG/AXsBQgHKAYYBVQGnAXYGAAPLA1UDyycAAYQBpwHL + AYEBtAHkAX0BsAHhAX0BsAHhAX0BsAHhAX0BsAHhAX0BsAHhAX0BsAHhAX0BsAHhAX0BsAHhAX0BsAHh + AX0BsAHhAYEBtAHkAYQBpwHLCQABlAHAAdYBigHTAfABggHNAesBggHNAesBggHNAesBggHNAesBggHN + AesBggHNAesBigHTAfABYgGmAcgBigHTAfAC6QHbAZQBwAHWAwACVQG5AS0BHAHeARUBAAHVARUBAAHV + ARUBAAHVARUBAAHVARUBAAHVAVUBgQGaATsBwwF/AUgBzwGMATsBwwF/ATsBwwF/ATsBwwF/AUgBzwGM + AVUBrQF7NgABigGtAc8BiAG7AeoBggG1AeUBggG1AeUBggG1AeUBggG1AeUBggG1AeUBggG1AeUBggG1 + AeUBggG1AeUBggG1AeUBggG1AeUBiAG7AeoBigGtAc8JAAGYAcMB2AGOAdYB8gGHAdAB7QGHAdAB7QGH + AdAB7QGHAdAB7QGHAdAB7QGHAdAB7QGOAdYB8gFmAaoBzAGOAdYB8gLwAeYBmAHDAdgDAAJVAb8BNgEl + AeQBGQEAAdsBGQEAAdsBGQEAAdsBGQEAAdsBGQEAAdsBVQGEAaABPgHGAYIBTQHVAZEBPgHGAYIBPgHG + AYIBPgHGAYIBTQHVAZEBVQGzAYA2AAGOAbAB0QGPAcIB7gGHAboB6QGHAboB6QGHAboB6QGHAboB6QGH + AboB6QGHAboB6QGHAboB6QGHAboB6QGHAboB6QGHAboB6QGPAcIB7gGOAbAB0QkAAZsBxgHaAZIB2gH0 + AYsB1AHwAYsB1AHwAYsB1AHwAYsB1AHwAYsB1AHwAYsB1AHwAZIB2gH0AWkBrQHPAZIB2gH0AvgB8wGb + AcYB2gMAAlUBxAE+AS0B7AEcAQAB4wEcAQAB4wEcAQAB4wEcAQAB4wEcAQAB4wFVAYYBpAFCAcoBhgFR + AdkBlQFCAcoBhgFCAcoBhgFCAcoBhgFRAdkBlQFVAbkBhAYAA9ADZwPQJwABkwG0AdQBlgHJAfIBjAG/ + AewBjAG/AewBjAG/AewBRAF3AaoBjAG/AewBRAF3AaoBjAG/AewBjAG/AewBjAG/AewBjAG/AewBlgHJ + AfIBkwG0AdQJAAGfAcgB3QGXAd4B9gGQAdgB8gGQAdgB8gGQAdgB8gGQAdgB8gGQAdgB8gGQAdgB8gGX + Ad4B9gF5Ab0B3AF4Ab0B3AL+Af0BnwHIAd0DAAJVAcgBRgE1AfIBIAEAAekBIAEAAekBIAEAAekBIAEA + AekBIAEAAekBVQGJAagBRAHMAYgBZQHtAakBZQHtAakBZQHtAakBZQHtAakBWAHWAZYBfwHLAaQGAANs + AW8CaQNsBgADdQN0A3EDbgNsA2gDZQNjA2AGAAGYAbgB1wGbAc4B9gGRAcQB8AGRAcQB8AGRAcQB8AFV + AYgBuwFEAXcBqgFVAYgBuwFAAXMBpgGRAcQB8AGRAcQB8AGRAcQB8AGbAc4B9gGYAbgB1wkAAaIBygHe + AZsB4QH3AZQB2wH0AZQB2wH0AZQB2wH0AZQB2wH0AZQB2wH0AZQB2wH0AZQB2wH0AZ4B5AH5AXwBwAHe + AaIBygHeAe4B8wH1AwACfwHVAWIBYQHnAXYBdQH+AXYBdQH+AXkBYgGjAXsBUAFVAXsBUAFVAWoBWQE/ + AWoBbgEyAWoBbgEyAWEBiwFRAVUBwQGKAVUBwQGKAVUBwQGKAeIB7wHoBgAD0wNxA9MnAAGbAboB2QGf + AdIB+QGVAcgB8wGVAcgB8wGVAcgB8wFVAYgBuwFVAYgBuwFVAYgBuwFNAYABswGVAcgB8wGVAcgB8wGV + AcgB8wGfAdIB+QGbAboB2QkAAaUBzQHgAZ4B5QH5AZgB3wH2AZgB3wH2AZgB3wH2AZgB3wH2AZgB3wH2 + AZgB3wH2AZgB3wH2AZgB3wH2AaEB6AH6AaUBzQHgBgAC4gHxAlUBzgJVAc4CVQHOAW0BUwF1AdwBqQEy + AdcBpAEtAdcBpAEtAdcBpAEtAdwBqQEyAbABhgFIQgABnwG9AdsBqQHbAf4BqgHdAf8BqgHdAf8BqgHd + Af8BdwGqAd0BdwGqAd0BdwGqAd0BZgGZAcwBqgHdAf8BqgHdAf8BqgHdAf8BqQHbAf4BnwG9AdsJAAGo + Ac4B4gGjAegB+wGdAeMB+QGdAeMB+QGdAeMB+QGdAeMB+QGdAeMB+QGdAeMB+QGdAeMB+QGdAeMB+QGj + AegB+wGoAc4B4hIAAbYBiwFFAdwBqQEyAdEBngEnAdEBngEnAdEBngEnAdwBqQEyAbYBiwFFQgABxwHX + AecBiAG2AeIBgAGzAeYBgAGzAeYBgAGzAeYBTgGBAbQBTgGBAbQBTgGBAbQBSAF7Aa4BgAGzAeYBgAGz + AeYBgAGzAeYBiAG2AeIBxwHXAecJAAGrAdAB4wGmAesB/AGhAeYB+wGhAeYB+wGhAeYB+wGhAeYB+wGh + AeYB+wGhAeYB+wGhAeYB+wGhAeYB+wGmAesB/AGrAdAB4xIAAbsBkAFBAeEBrgE4AdYBowEsAdYBowEs + AdYBowEsAeEBrgE4AbsBkAFBEgAD1wN9A9cnAAHjAeoB8QGOAbgB4QGJAbwB7wGIAbsB7gGIAbsB7gFB + AXQBpwFBAXQBpwFBAXQBpwE+AXEBpAGIAbsB7gGIAbsB7gGJAbwB7wGOAbgB4QHjAeoB8QkAAa4B0gHk + AakB7gH9AaQB6QH8AaQB6QH8AaQB6QH8AaQB6QH8AaQB6QH8AaQB6QH8AaQB6QH8AaQB6QH8AakB7gH9 + Aa4B0gHkEgABwAGVAT8B5wG0AT0B2gGnATAB2gGnATAB2gGnATAB5wG0AT0BwAGVAT8SAAN/A3cDfwYA + A4IDgQN/A34DfAN6A3kDdgOrBgAB9QH3AfkBmwG+Ad8BiQG8Ae8BiAG7Ae4BiAG7Ae4BNQFoAZsBNQFo + AZsBNQFoAZsBNQFoAZsBiAG7Ae4BiAG7Ae4BiQG8Ae8BmwG+Ad8B9QH3AfkJAAGwAdQB5gGsAfEB/wGn + AewB/gGnAewB/gGnAewB/gGnAewB/gGnAewB/gGnAewB/gGnAewB/gGnAewB/gGsAfEB/wGwAdQB5hIA + AcYBmgE9AesBuAFBAd0BqgEzAd0BqgEzAd0BqgEzAesBuAFBAcYBmgE9EgAD2AOCA9gnAAP+AcsB2gHq + AakBxQHiAakBxQHiAakBxQHiAVUBfQGmAVUBfQGmAVUBfQGmAVUBfQGmAakBxQHiAakBxQHiAakBxQHi + AcsB2gHqA/4JAAGyAdUB5gGxAfUB/wGuAfIB/wGuAfIB/wGuAfIB/wGuAfIB/wGuAfIB/wGuAfIB/wGu + AfIB/wGuAfIB/wGxAfUB/wGyAdUB5hIAAdQBswFsAecBuAFGAf4BywFUAf4BywFUAf4BywFUAecBuAFG + AdQBswFsdQAB0AHkAe4BswHWAecBswHWAecBswHWAecBswHWAecBswHWAecBswHWAecBswHWAecBswHW + AecBswHWAecBswHWAecB0AHkAe4SAAHwAesB3gHNAaABOQHNAaABOQHNAaABOQHNAaABOQHNAaABOQHw + AesB3g8AA/sD8QLIAcMCuAGwArgBsAK4AbACuAGwArgBsAK4AbACuAGwArgBsAK4AbACuAGwAsgBwwPx + BvsD8QLIAcMCuAGwArgBsAK4AbACuAGwArgBsAK4AbACuAGwArgBsAK4AbACuAGwAsgBwwPxA/tgAAP9 + A/oCwAG4C/8D/gH9Av4B/AL9AfsC/QH6AvwB+AL+AfkCwAG4A/oG/QP6AsABuAv/A/4B/QL+AfwC/QH7 + Av0B+gL8AfgC/gH5AsABuAP6A/1mAALJAcEG/wP+Av0B/AL9AfsC/AH5AvsB+AL6AfYC+AH0AvsB9gLJ + AcEMAALJAcEG/wP+Av0B/AL9AfsC/AH5AvsB+AL6AfYC+AH0AvsB9gLJAcFsAALPAccD/wP+Av0B/AL9 + AfsC/AH5AvsB+AL6AfYC+AH0AvcB8gL7AfUCzwHHDAACzwHHA/8D/gL9AfwC/QH7AvwB+QL7AfgC+gH2 + AvgB9AL3AfIC+wH1As8BxwwAA/4D/Ab5A/oG/AP7BvkD/AP+BgAD/QP8A/oe+AP6A/wD/QYAAtAByAL/ + Af4C/QH8Av0B+wG/AUgBrgHsAc4B5QL6AfYC+AH0AvcB8gL2AfAC+gHzAtAByAwAAtAByAL/Af4C/QH8 + AekBzwHrAa4BSAG/Aa4BSAG/Aa4BSAG/AdMBoQHaAvcB8gL2AfAC+gHzAtAByAwAA/4D/AP5A7MDXAb8 + A1wDtAP5A/wD/gYAA/0DhAM0A4QD+APiBjQDhAPiA3UDpAP4A4QDNAPpBgAC0gHLAv4D/QH7AvwB+QHG + AU8BtQHsAc8B5QL4AfQC9wHyAvYB8AL1Ae4C+gHyAtIBywwAAtIBywL+A/0B+wHqAdEB7QG1AU8BxgL6 + AfYB5wHOAegBtQFPAcYB7gHhAesC9QHuAvoB8gLSAcsSAAPLA3UD+AYAA/gDdQPLEgADeQP1BgADqgN5 + BgADywO+A+4DqgPCCQAC1QHNAv4D/AH5AvsB+AHOAVcBvQHOAVcBvQHOAVcBvQHiAaYB1gL1Ae4C9AHs + AvkB7wLVAc0MAALVAc0C/gP8AfkB6wHSAe0BvQFXAc4C+AH0AvcB8gG9AVcBzgHnAc0B5QL0AewC+QHv + AtUBzQ8AA84DfwP5DAAD+QN/A84PAAPGDGADxgYAA/UJYAPpCQAC1gHOAv0D+wH4AvoB9gHWAV8BxQHv + AdEB5gL2AfAC9QHuAvQB7ALxAecC9wHqAtYBzgwAAtYBzgL9A/sB+AHsAdMB7gHFAV8B1gL3AfIB6gHR + AeoBxQFfAdYB7QHhAekC8QHnAvcB6gLWAc4MAAPQA4YD+RIAA/kDhgPQDAAD9QOUA+8D0QNoA/UJAAOT + A+8DaAwAAtgB0AL9A/oB9gL4AfQB3AFlAcsB3AFlAcsB3AFlAcsB4gGJAdMC8QHnAuwB3wL0AeUC2AHQ + DAAC2AHQAv0D+gH2Ae0B0wHuAcsBZQHcAcsBZQHcAcsBZQHcAd8BrAHjAvEB5wLsAd8C9AHlAtgB0AkA + A+8DbAPvGAAD7wNsA+8MAAOPA/YDtwOPDAADzAN9A8wMAALaAdIC/AP4AfQC9wHyAvYB8AL1Ae4C9AHs + AvEB5wLsAd8C6AHZAvMB4gLaAdIMAALaAdIC/AP4AfQC9wHyAvYB8AL1Ae4C9AHsAvEB5wLsAd8C6AHZ + AvMB4gLaAdIMAAPUA5ED+RIAA/kDkQPUDwADzgPVA3cDzgwAA+wDdwPsDAAC2wHTAvwD9wHyAvYB8AL1 + Ae4C9AHsAvEB5wLsAd8C6AHZAuYB1QLyAeEC2wHTDAAC2wHTAvwD9wHyAvYB8AL1Ae4C9AHsAvEB5wLs + Ad8C6AHZAuYB1QLyAeEC2wHTDwAD1QOWA/kMAAP5A5YD1RIAA/YDogN+A/YhAALcAdUC+wP2AfAC9QHu + AvQB7ALxAecC7AHfAugB2QLmAdUC5QHUAvIB4QLcAdUMAALcAdUC+wP2AfAC9QHuAvQB7ALxAecC7AHf + AugB2QLmAdUC5QHUAvIB4QLcAdUSAAPXA5kD+gYAA/oDmQPXGAAGnCQAAt0B1gL6AfQC9QHuAvQB7ALx + AecC7AHfAugB2QLmAdUCpAGTAqQBkwKkAZMCyQHADAAC3QHWAvoB9AL1Ae4C9AHsAvEB5wLsAd8C6AHZ + AuYB1QKkAZMCpAGTAqQBkwLJAcAVAAPYA50GAAOdA9hFAALeAdcC+gHzAvQB7ALxAecC7AHfAugB2QLm + AdUC5QHUArYBpQP/At4B1wL3AfYMAALeAdcC+gHzAvQB7ALxAecC7AHfAugB2QLmAdUC5QHUArYBpQP/ + At4B1wL3AfZsAALfAdkC/AH1AvkB7wL2AeoC9AHlAvMB4gLyAeEC8gHhAsIBsQLfAdkC9wH2DwAC3wHZ + AvwB9QL5Ae8C9gHqAvQB5QLzAeIC8gHhAvIB4QLCAbEC3wHZAvcB9m8AAuoB5gLgAdkC4AHZAuAB2QLg + AdkC4AHZAuAB2QLgAdkC4AHZAvcB9hIAAuoB5gLgAdkC4AHZAuAB2QLgAdkC4AHZAuAB2QLgAdkC4AHZ + AvcB9mwAA/sD8QLIAcMCuAGwArgBsAK4AbACuAGwArgBsAK4AbACuAGwArgBsAK4AbACuAGwAsgBwwPx + BvsD8QLIAcMCuAGwArgBsAK4AbACuAGwArgBsAK4AbACuAGwArgBsAK4AbACuAGwAsgBwwPxBvsD8QLI + AcMCuAGwArgBsAK4AbACuAGwArgBsAK4AbACuAGwArgBsAK4AbACuAGwAsgBwwPxBvsD8QLIAcMCuAGw + ArgBsAK4AbACuAGwArgBsAK4AbACuAGwArgBsAK4AbACuAGwAsgBwwPxA/sD/QP6AsABuAv/A/4B/QL+ + AfwC/QH7Av0B+gL8AfgC/gH5AsABuAP6Bv0D+gLAAbgL/wP+Af0C/gH8Av0B+wL9AfoC/AH4Av4B+QLA + AbgD+gb9A/oCwAG4C/8D/gH9Av4B/AL9AfsC/QH6AvwB+AL+AfkCwAG4A/oG/QP6AsABuAv/A/4B/QL+ + AfwC/QH7Av0B+gL8AfgC/gH5AsABuAP6A/0GAALJAcEG/wP+Av0B/AL9AfsC/AH5AvsB+AL6AfYC+AH0 + AvsB9gLJAcEMAALJAcEG/wP+Av0B/AL9AfsC/AH5AvsB+AL6AfYC+AH0AvsB9gLJAcEMAALJAcEG/wP+ + Av0B/AL9AfsC/AH5AvsB+AL6AfYC+AH0AvsB9gLJAcEMAALJAcEG/wP+Av0B/AL9AfsC/AH5AvsB+AL6 + AfYC+AH0AvsB9gLJAcEMAALPAccD/wP+Av0B/AL9AfsC/AH5AvsB+AL6AfYC+AH0AvcB8gL7AfUCzwHH + DAACzwHHA/8D/gL9AfwC/QH7AvwB+QL7AfgC+gH2AvgB9AL3AfIC+wH1As8BxwwAAs8BxwP/A/4C/QH8 + Av0B+wL8AfkC+wH4AvoB9gL4AfQC9wHyAvsB9QLPAccMAALPAccD/wP+Av0B/AL9AfsC/AH5AvsB+AL6 + AfYC+AH0AvcB8gL7AfUCzwHHDAAC0AHIAv8B/gL9AfwB3AHPAesBewFIAb8BewFIAb8BewFIAb8BiwFe + AcYB6AHhAesC9gHwAvoB8wLQAcgMAALQAcgC/wH+Av0B/AL9AfsBggHCAbQBWQGuAZ0BWQGuAZ0BqQHT + AcgC9wHyAvYB8AL6AfMC0AHIDAAC0AHIAv8B/gL9AfwC/QH7Ad4BogGpAb8BSAFZAb8BSAFZAdwBoAGm + AvcB8gL2AfAC+gHzAtAByAwAAtAByAL/Af4C/QH8Av0B+wG/AXsBSAG/AXsBSAG/AXsBSAHcAboBngL3 + AfIC9gHwAvoB8wLQAcgMAALSAcsC/gP9AfsB3QHRAe0BggFPAcYC+gH2AvgB9AGCAU8BxgHZAcwB5QL1 + Ae4C+gHyAtIBywwAAtIBywL+A/0B+wL8AfkC+wH4AvoB9gHSAegB4AFgAbUBpAL2AfAC9QHuAvoB8gLS + AcsMAALSAcsC/gP9AfsC/AH5AvsB+AHgAaUBqwHTAXoBhQL3AfIC9gHwAvUB7gL6AfIC0gHLDAAC0gHL + Av4D/QH7AvwB+QHGAYIBTwHsAdsBzAL4AfQC9wHyAvYB8AL1Ae4C+gHyAtIBywwAAtUBzQL+A/wB+QHf + AdIB7QGKAVcBzgGYAWwB0wGKAVcBzgGlAX8B1wHnAeEB6QL0AewC+QHvAtUBzQwAAtUBzQL+A/wB+QL7 + AfgBsgHcAdIBaAG9AawBaAG9AawBrgHZAc0C9QHuAvQB7AL5Ae8C1QHNDAAC1QHNAv4D/AH5AvsB+AL6 + AfYB4wGoAa4B2QF/AYsC9gHwAvUB7gL0AewC+QHvAtUBzQwAAtUBzQL+A/wB+QL7AfgBzgGKAVcB7gHd + AcwC9wHyAvYB8AL1Ae4C9AHsAvkB7wLVAc0MAALWAc4C/QP7AfgB4AHTAe4BkgFfAdYC9wHyAd0B0AHp + AZIBXwHWAvQB7ALxAecC9wHqAtYBzgwAAtYBzgL9A/sB+AL6AfYBcAHFAbQB1QHrAeIC9gHwAvUB7gL0 + AewC8QHnAvcB6gLWAc4MAALWAc4C/QP7AfgC+gH2AvgB9AHnAasBsQHeAYUBkAL1Ae4C9AHsAvEB5wL3 + AeoC1gHODAAC1gHOAv0D+wH4AvoB9gHWAZIBXwHvAd4BzQL2AfAC9QHuAvQB7ALxAecC9wHqAtYBzgwA + AtgB0AL9A/oB9gHgAdMB7gGYAWUB3AGYAWUB3AGYAWUB3AHFAawB4wLxAecC7AHfAvQB5QLYAdAMAALY + AdAC/QP6AfYC+AH0AbcB4QHVAXYBywG6AXYBywG6AZUB1QHGAvEB5wLsAd8C9AHlAtgB0AwAAtgB0AL9 + A/oB9gL4AfQB6gGvAbQB3AFlAXYB3AFlAXYB6AGsAbEC8QHnAuwB3wL0AeUC2AHQDAAC2AHQAv0D+gH2 + AvgB9AHcAZgBZQHvAd4BzQL1Ae4C9AHsAvEB5wLsAd8C9AHlAtgB0AwAAtoB0gL8A/gB9AL3AfIC9gHw + AvUB7gL0AewC8QHnAuwB3wLoAdkC8wHiAtoB0gwAAtoB0gL8A/gB9AL3AfIC9gHwAvUB7gL0AewC8QHn + AuwB3wLoAdkC8wHiAtoB0gwAAtoB0gL8A/gB9AL3AfIC9gHwAvUB7gL0AewC8QHnAuwB3wLoAdkC8wHi + AtoB0gwAAtoB0gL8A/gB9AL3AfIC9gHwAvUB7gL0AewC8QHnAuwB3wLoAdkC8wHiAtoB0gwAAtsB0wL8 + A/cB8gL2AfAC9QHuAvQB7ALxAecC7AHfAugB2QLmAdUC8gHhAtsB0wwAAtsB0wL8A/cB8gL2AfAC9QHu + AvQB7ALxAecC7AHfAugB2QLmAdUC8gHhAtsB0wwAAtsB0wL8A/cB8gL2AfAC9QHuAvQB7ALxAecC7AHf + AugB2QLmAdUC8gHhAtsB0wwAAtsB0wL8A/cB8gL2AfAC9QHuAvQB7ALxAecC7AHfAugB2QLmAdUC8gHh + AtsB0wwAAtwB1QL7A/YB8AL1Ae4C9AHsAvEB5wLsAd8C6AHZAuYB1QLlAdQC8gHhAtwB1QwAAtwB1QL7 + A/YB8AL1Ae4C9AHsAvEB5wLsAd8C6AHZAuYB1QLlAdQC8gHhAtwB1QwAAtwB1QL7A/YB8AL1Ae4C9AHs + AvEB5wLsAd8C6AHZAuYB1QLlAdQC8gHhAtwB1QwAAtwB1QL7A/YB8AL1Ae4C9AHsAvEB5wLsAd8C6AHZ + AuYB1QLlAdQC8gHhAtwB1QwAAt0B1gL6AfQC9QHuAvQB7ALxAecC7AHfAugB2QLmAdUCpAGTAqQBkwKk + AZMCyQHADAAC3QHWAvoB9AL1Ae4C9AHsAvEB5wLsAd8C6AHZAuYB1QKkAZMCpAGTAqQBkwLJAcAMAALd + AdYC+gH0AvUB7gL0AewC8QHnAuwB3wLoAdkC5gHVAqQBkwKkAZMCpAGTAskBwAwAAt0B1gL6AfQC9QHu + AvQB7ALxAecC7AHfAugB2QLmAdUCpAGTAqQBkwKkAZMCyQHADAAC3gHXAvoB8wL0AewC8QHnAuwB3wLo + AdkC5gHVAuUB1AK2AaUD/wLeAdcC9wH2DAAC3gHXAvoB8wL0AewC8QHnAuwB3wLoAdkC5gHVAuUB1AK2 + AaUD/wLeAdcC9wH2DAAC3gHXAvoB8wL0AewC8QHnAuwB3wLoAdkC5gHVAuUB1AK2AaUD/wLeAdcC9wH2 + DAAC3gHXAvoB8wL0AewC8QHnAuwB3wLoAdkC5gHVAuUB1AK2AaUD/wLeAdcC9wH2DAAC3wHZAvwB9QL5 + Ae8C9gHqAvQB5QLzAeIC8gHhAvIB4QLCAbEC3wHZAvcB9g8AAt8B2QL8AfUC+QHvAvYB6gL0AeUC8wHi + AvIB4QLyAeECwgGxAt8B2QL3AfYPAALfAdkC/AH1AvkB7wL2AeoC9AHlAvMB4gLyAeEC8gHhAsIBsQLf + AdkC9wH2DwAC3wHZAvwB9QL5Ae8C9gHqAvQB5QLzAeIC8gHhAvIB4QLCAbEC3wHZAvcB9g8AAuoB5gLg + AdkC4AHZAuAB2QLgAdkC4AHZAuAB2QLgAdkC4AHZAvcB9hIAAuoB5gLgAdkC4AHZAuAB2QLgAdkC4AHZ + AuAB2QLgAdkC4AHZAvcB9hIAAuoB5gLgAdkC4AHZAuAB2QLgAdkC4AHZAuAB2QLgAdkC4AHZAvcB9hIA + AuoB5gLgAdkC4AHZAuAB2QLgAdkC4AHZAuAB2QLgAdkC4AHZAvcB9gwAAUIBTQE+BwABPgMAASgDAAFA + AwABUAMAAQEBAAEBBQABgAECFgAD/4IAAQEBAAEBAv8BwAEDAQABAQEAAQEC/wHAAQMBAAEBAQABAQL/ + AeABBwEAAQEBAAEBAcABAwHAAQMBAAEBAQABAQHAAQMBgAEBAQABAQEAAQEB8QGPAYABAQEAAQEBAAEB + AeABBwGAAQEBAAEBAQABAQHGAWMBgAEBAQABAQEAAQEBjgFxAYABAQEAAQEBAAEBAcYBYwGAAQEBAAEB + AQABAQHgAQcBgAEBAQABAQEAAQEB8QGPAYABAQEAAQEBAAEBAfkBnwHAAQMBAAEBAQABAQL/AeABBwEA + AQEBAAEBAv8B8AEPAYABAwEAAQEI/wIAAf4BAQL/BQABAQGIAwABwAEBAQABAQGIAQABgAEBAcABAQEA + AQEBjwH/AYABAQHAAQEBAAEBAv8BgAEBAcABAQEAAQEC/wGAAQEBwAEBAQABAQGPAf8BgAEBAcABAQEA + AQEBjAEBAYABAQHAAQEBAAEBAY8B/wGAAQEBwAEDAQABHwL/AYABAQHAAQMB8AEfAv8BgAEBAcABAwHw + AR8BjwH/AYABAQHAAQMB8AEfAYwBAQGAAQEBwAEDAfABHwGPAf8BgAEBAcABAwHwAR8E/wHAAQMB8AEf + BAAE/wQABP8BwAEDAcABAwT/AcABAwHAAQMBwAEDAgABwAEDAcABAwHAAQMCAAHAAQMBwAEDAfEBjwHM + AcEBwAEDAcABAwHjAccBwAHBAcABAwHAAQMBxwHjAcAB4wHAAQMBwAEDAY8B8QHhAeMBwAEDAcABAwHH + AeMB4QHjAcABAwHAAQMB4wHHAeEB/wHAAQMBwAEDAfEBjwHzAf8BwAEDAcABAwH5AZ8C/wHAAQMBwAED + BP8BwAEHAcABBwT/AcABDwHAAQ8E/xAAAcABAwHAAQMBwAEDAcABAwHAAQMBwAEDAcABAwHAAQMBwAED + AcABAwHAAQMBwAEDAcABAwHAAQMBwAEDAcABAwHAAQMBwAEDAcABAwHAAQMBwAEDAcABAwHAAQMBwAED + AcABAwHAAQMBwAEDAcABAwHAAQMBwAEDAcABAwHAAQMBwAEDAcABAwHAAQMBwAEDAcABAwHAAQMBwAED + AcABAwHAAQMBwAEDAcABAwHAAQMBwAEDAcABAwHAAQMBwAEDAcABBwHAAQcBwAEHAcABBwHAAQ8BwAEP + AcABDwHAAQ8L + + + + 132, 17 + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 + YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAJ5SURBVDhPjdNdSFNhHMfx56Kb3i7scl10M28kIW+6kCDC + mF1EikF5IViDBMMkJQbKzHyZLiUVXc6hGdU0K0OTMFPBGkGpWIJiqznX3nybc3Oezb3663ke8sBJgg58 + Of/ncM6H58A5hPw5ZrTk+rSWVP1P7N6958TzVB2pESxarH28hvWJfAhz95BwdgHLT6Wt94Lduw/4XEs0 + 2HqNXd8rhB06eL8U470+A6PvmiSNjbdhsPZ4+z7gUy2pT2y+QHzNyEv4XmJm4BZcXi9WBAFOmj0QwBuT + CZpKxUiOWp0sQUxVpCHu6UVs+QmPzZN9SsxbLPhmNsPq8WBhZQU9w8NgR3ZZWaEEmbhLHsRWnyHifMRj + s+lxLr4vLnJk2e/nSJvRKJacmakWdzFWQVoi7m6EbB08Nk90XcGPpSWObNBX2EPYTtjrKEpKikRgpJzo + duydECw6HpvHDTmw2Gwc8QWDEsS5vY2MoqJiEXirIvrQkh4BcwuPzSPtWbDa7RzZ2tmRIKuhEM4WFNwW + gUEV6RR+tsI/38hj83DrRdgowBAhHJYgm3R9RqksFYH+UtIdWGiCd7aex+ah5guwOxwcCUWjEiRA16fz + 8u6IQG8xMfrnGuCZqeaxeaBRAYfTyZFwLCZBBAqk5eaqGHCQdsxwgwz5ZumnPFXJ89Fd9N8/D5fLxZFY + PC5BghQ8mZVVwYAkmrxQQTpGW9IC1qHC6MZ0NTa/atBXdw5utxsuWmJ3F3FaNJFAhGIROsvS07WSr9FQ + QLL1SmJ4Xi77MNlz6Zfq8gHHIbm87XBKSsPR1NT6vzsil9/c90+wC8355FRjHlHXXCUP6fIETfaPkn4D + qvVdCMceSq0AAAAASUVORK5CYII= + + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 + YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAJASURBVDhPjdJPSJNxGAfw5xYd6+hZJIjCim5d8hBe+nOL + KLA/FHjx0GEHcf6f04m51mwb5mJlhlkUFpVmusSIKf5Dszk3zYmSLjdn29rmtm/v8+CKl4E0+LCH7ft8 + 3/f38hLtfsYb6dpYI9X8D85m9/5+jzZQXcTbiHXnVWwMlSAyU430ygNg7ZHaRhc4m1PwpZ50CL9AJtSD + uL8Nm64yzHcXI+O1qmDVAc7mFIzUkz4d7EZqvVOkQ88w7ShCeNqIHc99pBcsIrPyEJzNKRiuIUMq0IWd + NYfgebLjFPwjepFSSljabwdncwqGKqll58djJFY6BM+fzSexPKwTSbdZpJbawdmcgg9aMiZW7YgtWQXP + TuNxLDnrRHzOJJI+Gzjbp6UTqpL35WT+vdyOyIJZ8DzQUgjfYI2IzRpFgp9FJgPOqwreaMgSW7Rg220U + PL9rOgLvx2oRnWkV8fk2BKNRcF5V8EpD7RGPCVuzzYLn17rD8AxUiV/TLSL27R58gQA4ryp4fpvs23N3 + sDmlFzy/rD0Ed79WhCebRfTrXZx2ZcB5VUFXGXVuzRgQGK8VPPdUFsDdVyG2Jgwiohzj6NsIOJ8t2K8M + B203qTc0pbzKo1UipNxFt7YAC8rts+wRosqD5OyNIjqr7PEuHVDkl54ha7/x2LavtzT5c6wWwQkd9Bcp + pDlPI6z5Cg1mcZZ3dnf/ncR2iy5YrpPtaXme0/Xk3Pemy/RJ+TevOJ/25bw4e/3QWkKFytUqGi6RScnt + ufwHz8wCEl4W+tkAAAAASUVORK5CYII= + + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 + YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAGqSURBVDhPrY3dK0NxHIfPcf4Al8qFK9du1K65kt0oGi0v + GSMX3Kml1NTENntT06TMCBtSthI2MptMygVDyLxERCsvodVqX+dzar8oHZRTT+f0+32e53DcfzxNOY42 + jWAfUOn1rb8BWzjs3xrBZj2ZfiE8mR/ABls4LNAoWOxxT5LSmQyl0mlZsMEWDgvUC5bBPfcDvYny0/u7 + LNhgC4cFGgSTc3fklh5TKbp7fpYFG2zhsEAt3+/acV3Tvfj3i2RSFmywhcMCar53JOa8pPPEE928vsqC + DbZwPgUMo1HHGQX7478CWzVvGGWBGl7vCVtPyFQ9QUbV+LfgLsv20BXBYQEV3z25ajoki3qKYrFtikSi + X8AZ7mZ1UbLX+WhzMEFwWKCK7/Kt9O2To36GQqEwdZcPSQQCSxI4wx0CLu0CbdhOCQ4LVPC6+ZDxgJya + efL7g9Ib+Hx+iewZAmPty7RuOSY4LKDgKkuVfEewp8z1ODe3QsMtfgmvd1Eie4aAtzNMa+Yjwj4bKBA/ + igo5RXMJp90SBMH8Hbj7TDGndIseXC5XJE8k/4/Ayf0AQu4lRh6dpg8AAAAASUVORK5CYII= + + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 + YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAHBSURBVDhPrVI9SAJhGH5vlygi+jFIBJEb4pwECQTBRaRB + aQmbrFmkwOQmMQLnGowiaIsapJaIhHAQghAu4pakRSgkbomgqCC/3ufDCxWThoSH93ufv/tOJfqPTzwe + n4/FYtpfuuCDv8ubTCZ1IBqNDiyBbnu7Cjwej24YhkgkEnooFOpbAh46fPD33lYDaZqm4CvqPp+vqwQ7 + eOjtcN+HaF6vV6/X6yISiehslCZM7OChMzXwNWVJo9EQwWBQdzqdC5jY/xKWrzXHT1BVVW82myIcDl9U + KhWBHfyvv9ITkeORaPFBUbYYxyVFKW+4XKZlWaLqcJg3vIOHDh/8P2UmL/eKsmkFArW3VOr5PZdriUJB + 3KbT4pLoFWcAPHT44EdOlhhESw2/34DpxO2+2yaqfeXz4oznOVEREzt46PDBj5wsqCrKfmf4I5MRp2xm + SAMmdvCdJcjJghJR+SWTaUH8zGbFIc8ju739otjBQ4cPfuSkvEO0e61pTdzigMX1nrD9ZYGHDh/8yEnN + SxQqEu0xcbVMtMbULP4/jBmGkzHNcDPUFaJV+OBHzi6f4oONST6PM0YZw4yhNkZ4jjEmOrzI0DcBiOxD + XRtgPgAAAABJRU5ErkJggg== + + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 + YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAG4SURBVDhPlZNNS0JREIbdR2DLIghCF0Eu2rQKI4IuSIFE + hQtXLsRCIiMjQ7m7+gHhL+iTEKmFIoj5tXfZrkUIGRhpeq/fOs0IczmYCR4YOHDOfZjnnXN1Olx7gcDW + riw7h9WOLBvozshlDQRcaqcD340GfNZqkK9W4b1SgedMBuhs2+83jgb4fPtKqwVfigIf5TK8FYvwWijA + bTQKtKx4PhKy6fUeqO02lFS1D4nncnCfSsF5MKjVmsv1RIpDlTY8HncdFX7q9T4knM3CWErrbvdhEwEK + ZkCQMLqPpbTqdB61ul2oYQ4ECaXTICpxLlc3N8BllCS/FuyKw3Hc6fWggTkQJJRMgqg0GC5NiLQ1wLLd + ftJFQBs1CPKYSICoxOFyJ3kMmrQ1wJLNdtrDcXVQgyAP8TiIShwud0JvhbQ1wKLVekbz7mEXBLmLxUBU + 4nC5k1KzCaStAWbNZrn/YgiCdR2JgKjE4XInFcyJtBkwN2EweCZNpksugyS9iEocLndCIyZtBuhxM401 + w7VgsVyIShwud1LDoEn7v/9DP6hEOpQJBUvTaeKe7iBgahjkj5Kox3vSxo/nfwHKBlL+USi6VgAAAABJ + RU5ErkJggg== + + + + + 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 + RpkLgwRoAAAAAElFTkSuQmCC + + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 + YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAG9SURBVDhPjZLNSwJRFMVdFu1a1DrIhRC0CCKiVUG5KIi0 + KGjRxkpKwpAJ1BgIpEWboH8gwqIoCiHaBv4L1UIQ+8ISkcpxZvz2ds/QRPLMenB4PDj3x73nXYvl68xs + bk5My/JiMzlludv0C7czEFjSKhV6LxYpreuUVFV6yuXoUVEMRaJRgmcqGLQ2hEz6/cu5UokyXPiazdJ9 + JkOxVIruXl7oNpmkw6srwoGvIWRCktwqA940rSFkLxwmU9axsaDQxbjPt6KXy/TB7f8GQScYB14BMOr1 + ruY5AyWfbwoBAF4BMOLxeAoMUAuFphAEC68AGHa710rVKumcAyCXF2mSXHFDkbPUd7D4HXgFwJDL5S0z + oMA5mJDI6SvthhJ1maR5RHgFwODCwnqlVqMij2FCzo+faUeO1WWCPYFXAPTPz/uqDEAXJuT08IFC/pu6 + TBQeEV4B0Dc7K9V4USoMAOTkIEFz9mtDR/vxbwiWDV4B0OtwbGDTatyFCfk5jvk7GmcErwCw2u0BY1f/ + gGDZ4P0JaOVHR+fAwJYJMCAsZIJgMRK+GHtS5De8qGGh1tLO6mnp6lpvs9m2/yN4UYPaT6iBRnEAJMyK + AAAAAElFTkSuQmCC + + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 + YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAGzSURBVDhPjZK9S4JRFMYdi7aGmoUchKAhCImmgnRIiuzD + QcjFSkpCEQM/EFyCxlqamuwPaHFoCRyarKmCyIoCTUQ0X/X1+z2dR3olumZdeLhceM6Pc557NJqvsxYK + mVfD4c1+WgmHx1S/cK8EAluVVosK9TplZZlS5TK9lUr0KkkdncfjBM9yMKjrCVny+7dLjQbluPC9WKSX + XI4eMhm6S6fpNpWis1iMcODrCTH7fM4yA/KVSk/IcTRKqnRGY1DoYsHr3ZGbTfrg9n+DoBOMA68AmHe7 + d6ucgVSt9oUAAK8AmHO5XDUGlGu1vhAEC68AmHU69xrtNsmcAyCOkyRdPxeEcfA78AqAGYfD3WRAjXMA + ZOPovgP4mUmWR4RXAEzb7Z6WolCdxwBk/fCGEk95YRzsCbwCYMpm87YZgC4AWYxcUeIxJ2QicXfwCoBJ + q9Wn8KK0GACIKXDZ1elFstsJlg1eATBhsexj0xTuQoWo46jB4osrPB68AkBnMgU6u/oHBMsG73fAID9G + Rg2GiAroQFjIBMFiJHwx9qTOb3hRw0KtZpg1PqDVeob0+oP/CF7UoPYTXb5IoCRPHYoAAAAASUVORK5C + YII= + + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 + YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAG1SURBVDhPjZK9S4JRFMYdi7aGmoUchKAhCImmgnRIirRy + EHKxkpJQxMAPhJZo7l+oxqAhtwiEWgIjKiEIIuE1kZfM1+/P03mk9yW4Zl14uFx4zo9znnt0uu+zGo1a + V2KxjX6yx2Jjql+47eHwZrnVony9TrlKhaRSidLFIr0pSlfniQTBsxyJGHpClkKhrWKjQTIXvhcK9CrL + 9JzN0lMmQ4+SRCfxOOHA1xNiDQY9JQZ8lMs9IUfHx6TKYDZHhC4WAoHtSrNJn9z+bxB0gnHgFQDzPt9O + lTNQqtW+EADgFQBzXq+3xoBSrdYXgmDhFQCzHs9uo92mCucAyK37RdPDYVoLFr8DrwCYcbt9TQbUOAdA + rtdTlLnPC+PkeER4BcC0y+VvdTpU5zEAuVxLakqdprVgsSfwCoAppzPQZgC6AORi8YakO1nIROHu4BUA + kw5HsMOL0mIAIGeWK5KSspaJ+jtYNngFwITNtodN63AXKkQdRw0WkDKPB68AMFgs4e6u/gHBssH7EzDI + j5FRk2lfBXQhLGSCYDESvhh7Uuc3vKhhoVY3zBof0Ov9Q0bjwX8EL2pQ+wUVkUjMVKxfkgAAAABJRU5E + rkJggg== + + + + + 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 + + + + 527, 17 + + + + AAABAAQAMDAAAAEAIACoJQAARgAAACAgAAABACAAqBAAAO4lAAAYGAAAAQAgAIgJAACWNgAAEBAAAAEA + IABoBAAAHkAAACgAAAAwAAAAYAAAAAEAIAAAAAAAgCUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAABjRbAAY0WwsGNFvIBTNa/wo5Yf8jXo3/KGSU/yZhkf8NPmf/BTNa/wY0W+AGNFscBjRbAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAABTNaAAUzWgsFM1rIBDJZ/wk4YP8iXYz/KGSU/yZhkf8NPmf/BTNa/wY0 + W+AGNFscBjRbAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABzVdAAc1XQsHNV3IBjRc/ws6Yv8jXo3/KGSU/yZh + kf8NPmf/BTNa/wY0W+AGNFscBjRbAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIFiGACBYhgsgWIbIH1iG/yFa + iP8mYpL/KGSU/yZhkf8NPmf/BTNa/wY0W+AGNFscBjRbAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKGSUAChk + lAsoZJTIKGSU/yhklP8oZJT/KGSU/yZhkf8NPmf/BTNa/wY0W+AGNFscBjRbAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAKGSUAChklAsoZJTIKGSU/yhklP8oZJT/KGSU/yZhkf8NPmf/BTNa/wY0W+AGNFscBjRbAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAKGSUAChklAsoZJTIKGSU/yhklP8oZJT/KGSU/yZhkf8NPmf/BTNa/wY0 + W+AGNFscBjRbAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAChk + lAAoZJQAKGSUAChklAAoZJQAKGSUAAAAAAAAAAAAKGSUAChklAsoZJTIKGSU/yhklP8oZJT/KGSU/yZh + kf8NPmf/BTNa/wY0W+AGNFscBjRbAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAChklAAoZJQGKGSUCihklAkoZJQCKGSUAAAAAAAAAAAAJmKRACZikQsmYpHIJmKR/yZi + kv8nY5P/KGSU/yZhkf8NPmf/BTNa/wY0W+AGNFscBjRbAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + 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 + lAAoZJQAKGSUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAKGSUAChklAgoZJSuKGSU4CNejeAjXo30I16N/yRejf8nYpL/KGSU/yNe + jf8KOWH/BTNa/wY0W/QGNFtOBjRbHgY0WxoGNFsDBjRbAAY0WwoGNFuxBjRb4AY0W8QGNFsYBjRbAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKGSUAChklAEoZJQXKGSUHgo5YR4KOWGxCThg/wo7 + Y/8gWoj/KGSU/yNejf8KOWH/BTNa/wY0W/0GNFvmBjRb4AY0W8UGNFsYBjRbAAY0WwEGNFsYBjRbHgY0 + WxoGNFsDBjRbAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEURuABFEbgARRG4AEURuAAUz + WgAFM1mkBDFY/wY0W/8gWYf/KGWV/yNejf8JOGD/BDJZ/wUzWv8FM1r/BjRb/wY0W+EGNFsYBjRbAAY0 + WwAGNFsABjRbAAY0WwAGNFsABjRbAAY0WwAGNFsABjRbAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABjRbAAY0 + WwIGNFsqBjRbNgY0WzYKOmK5DD1m/w0/aP8bU4D/IFqI/x1Wg/8PQGr/DD1m/ww9Zv8HNl3/BTNa/wY0 + W+YGNFtMBjRbNgY0WzMGNFsLBjRbAAY0WwYGNFswBjRbNgY0WyoGNFsCBjRbAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAABjRbAAY0WwkGNFu9BjRb9AY0W/QbUX77JmKS/yRfjv8NP2j/BjRb/ws6Yv8hXIv/JmGR/yRf + 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 + AAAAAAAAAAAAAAAAAAAAAAAAKGSUAChklBMoZJSRKGSUpChklH4oZJQGKGSUAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKGSUAChklAAoZJQAKGSUACdjkx4nY5PgJ2OT/ydj + k/MnY5M2J2OTAAAAAAAAAAAAAAAAAAAAAAAAAAAAKGSUAChklAAoZJQAKGSUAChklAAoZJQAKGSUAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKGSUAChk + lB4oZJTgKGSU/yhklPMoZJQ2KGSUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAKGSUAChklB4oZJTgKGSU/yhklPMoZJQ2KGSUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAKGSUAChklB4oZJTgKGSU/yhklPMoZJQ2KGSUAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + 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 + AADmBwAA/nMAAP53AAD/fwAA/38AAA== + + + \ No newline at end of file diff --git a/Model/CompoundTagContainer.cs b/Model/CompoundTagContainer.cs new file mode 100644 index 0000000..7df9f75 --- /dev/null +++ b/Model/CompoundTagContainer.cs @@ -0,0 +1,65 @@ +using System; +using System.Collections.Generic; +using Substrate.Nbt; + +namespace NBTExplorer.Model +{ + public class CompoundTagContainer : INamedTagContainer + { + private TagNodeCompound _tag; + + public CompoundTagContainer (TagNodeCompound tag) + { + _tag = tag; + } + + public int TagCount + { + get { return _tag.Count; } + } + + public IEnumerable TagNamesInUse + { + get { return _tag.Keys; } + } + + public string GetTagName (TagNode tag) + { + foreach (String name in _tag.Keys) + if (_tag[name] == tag) + return name; + + return null; + } + + public bool AddTag (TagNode tag, string name) + { + if (_tag.ContainsKey(name)) + return false; + + _tag.Add(name, tag); + return true; + } + + public bool RenameTag (TagNode tag, string name) + { + if (_tag.ContainsKey(name)) + return false; + + string oldName = GetTagName(tag); + _tag.Remove(oldName); + _tag.Add(name, tag); + + return true; + } + + public bool DeleteTag (TagNode tag) + { + foreach (String name in _tag.Keys) + if (_tag[name] == tag) + return _tag.Remove(name); + + return false; + } + } +} diff --git a/Model/DataNode.cs b/Model/DataNode.cs new file mode 100644 index 0000000..0495047 --- /dev/null +++ b/Model/DataNode.cs @@ -0,0 +1,181 @@ +using Substrate.Nbt; + +namespace NBTExplorer.Model +{ + public class DataNode + { + private DataNode _parent; + private DataNodeCollection _children; + + private bool _expanded; + private bool _modified; + + public DataNode () + { + _children = new DataNodeCollection(this); + } + + public DataNode Parent + { + get { return _parent; } + internal set { _parent = value; } + } + + public DataNodeCollection Nodes + { + get { return _children; } + } + + public bool IsModified + { + get { return _modified; } + set + { + if (value && Parent != null) + Parent.IsModified = value; + _modified = value; + } + } + + public bool IsExpanded + { + get { return _expanded; } + private set { _expanded = value; } + } + + public void Expand () + { + if (!IsExpanded) { + ExpandCore(); + IsExpanded = true; + } + } + + protected virtual void ExpandCore () { } + + public void Collapse () + { + if (IsExpanded && !IsModified) { + Release(); + IsExpanded = false; + } + } + + public void Release () + { + foreach (DataNode node in Nodes) + node.Release(); + + ReleaseCore(); + IsExpanded = false; + } + + protected virtual void ReleaseCore () + { + Nodes.Clear(); + } + + public virtual string NodeName + { + get { return ""; } + } + + public virtual string NodeDisplay + { + get { return ""; } + } + + public virtual bool HasUnexpandedChildren + { + get { return false; } + } + + #region Capabilities + + protected virtual NodeCapabilities Capabilities + { + get { return NodeCapabilities.None; } + } + + public virtual bool CanRenameNode + { + get { return (Capabilities & NodeCapabilities.Rename) != NodeCapabilities.None; } + } + + public virtual bool CanEditNode + { + get { return (Capabilities & NodeCapabilities.Edit) != NodeCapabilities.None; } + } + + public virtual bool CanDeleteNode + { + get { return (Capabilities & NodeCapabilities.Delete) != NodeCapabilities.None; } + } + + public virtual bool CanCopyNode + { + get { return (Capabilities & NodeCapabilities.Copy) != NodeCapabilities.None; } + } + + public virtual bool CanCutNode + { + get { return (Capabilities & NodeCapabilities.Cut) != NodeCapabilities.None; } + } + + public virtual bool CanPasteIntoNode + { + get { return (Capabilities & NodeCapabilities.PasteInto) != NodeCapabilities.None; } + } + + public virtual bool CanSearchNode + { + get { return (Capabilities & NodeCapabilities.Search) != NodeCapabilities.None; } + } + + public virtual bool CanCreateTag (TagType type) + { + return false; + } + + #endregion + + #region Operations + + public virtual bool CreateNode (TagType type) + { + return false; + } + + public virtual bool RenameNode () + { + return false; + } + + public virtual bool EditNode () + { + return false; + } + + public virtual bool DeleteNode () + { + return false; + } + + public virtual bool CopyNode () + { + return false; + } + + public virtual bool CutNode () + { + return false; + } + + public virtual bool PasteNode () + { + return false; + } + + #endregion + } +} diff --git a/Model/DataNodeCollection.cs b/Model/DataNodeCollection.cs new file mode 100644 index 0000000..52ffbcf --- /dev/null +++ b/Model/DataNodeCollection.cs @@ -0,0 +1,121 @@ +using System; +using System.Collections.Generic; + +namespace NBTExplorer.Model +{ + public class DataNodeCollection : IList + { + private List _nodes; + private DataNode _parent; + + internal DataNodeCollection (DataNode parent) + { + _parent = parent; + _nodes = new List(); + } + + public int IndexOf (DataNode item) + { + return _nodes.IndexOf(item); + } + + public void Insert (int index, DataNode item) + { + if (item == null) + throw new ArgumentNullException("item"); + if (item.Parent != null) + throw new ArgumentException("The item is already assigned to another DataNode."); + + item.Parent = _parent; + + _nodes.Insert(index, item); + } + + public void RemoveAt (int index) + { + if (index < 0 || index >= _nodes.Count) + throw new ArgumentOutOfRangeException("index"); + + DataNode node = _nodes[index]; + node.Parent = null; + + _nodes.RemoveAt(index); + } + + DataNode IList.this[int index] + { + get { return _nodes[index]; } + set + { + if (index < 0 || index > _nodes.Count) + throw new ArgumentOutOfRangeException("index"); + if (value == null) + throw new ArgumentNullException("item"); + if (value.Parent != null) + throw new ArgumentException("The item is already assigned to another DataNode."); + + _nodes[index].Parent = null; + _nodes[index] = value; + _nodes[index].Parent = _parent; + } + } + + public void Add (DataNode item) + { + if (item == null) + throw new ArgumentNullException("item"); + if (item.Parent != null) + throw new ArgumentException("The item is already assigned to another DataNode."); + + item.Parent = _parent; + + _nodes.Add(item); + } + + public void Clear () + { + foreach (DataNode node in _nodes) + node.Parent = null; + + _nodes.Clear(); + } + + public bool Contains (DataNode item) + { + return _nodes.Contains(item); + } + + public void CopyTo (DataNode[] array, int arrayIndex) + { + _nodes.CopyTo(array, arrayIndex); + } + + public int Count + { + get { return _nodes.Count; } + } + + bool ICollection.IsReadOnly + { + get { return (_nodes as IList).IsReadOnly; } + } + + public bool Remove (DataNode item) + { + if (_nodes.Contains(item)) + item.Parent = null; + + return _nodes.Remove(item); + } + + public IEnumerator GetEnumerator () + { + return _nodes.GetEnumerator(); + } + + System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator () + { + return _nodes.GetEnumerator(); + } + } +} diff --git a/Model/DirectoryDataNode.cs b/Model/DirectoryDataNode.cs new file mode 100644 index 0000000..f385c0b --- /dev/null +++ b/Model/DirectoryDataNode.cs @@ -0,0 +1,65 @@ +using System.IO; + +namespace NBTExplorer.Model +{ + public class DirectoryDataNode : DataNode + { + private string _path; + + public DirectoryDataNode (string path) + { + _path = path; + } + + protected override NodeCapabilities Capabilities + { + get + { + return NodeCapabilities.Search; + } + } + + public override string NodeDisplay + { + get { return Path.GetFileName(_path); } + } + + public override bool HasUnexpandedChildren + { + get { return !IsExpanded; } + } + + protected override void ExpandCore () + { + foreach (string dirpath in Directory.GetDirectories(_path)) { + Nodes.Add(new DirectoryDataNode(dirpath)); + } + + foreach (string filepath in Directory.GetFiles(_path)) { + string ext = Path.GetExtension(filepath); + DataNode node = null; + + switch (ext) { + case ".mcr": + case ".mca": + node = RegionFileDataNode.TryCreateFrom(filepath); + break; + + case ".dat": + case ".nbt": + case ".schematic": + node = NbtFileDataNode.TryCreateFrom(filepath); + break; + } + + if (node != null) + Nodes.Add(node); + } + } + + protected override void ReleaseCore () + { + Nodes.Clear(); + } + } +} diff --git a/Model/ListTagContainer.cs b/Model/ListTagContainer.cs new file mode 100644 index 0000000..1f4f3cd --- /dev/null +++ b/Model/ListTagContainer.cs @@ -0,0 +1,38 @@ +using Substrate.Nbt; + +namespace NBTExplorer.Model +{ + public class ListTagContainer : IOrderedTagContainer + { + private TagNodeList _tag; + + public ListTagContainer (TagNodeList tag) + { + _tag = tag; + } + + public int TagCount + { + get { return _tag.Count; } + } + + public bool DeleteTag (TagNode tag) + { + return _tag.Remove(tag); + } + + public int GetTagIndex (TagNode tag) + { + return _tag.IndexOf(tag); + } + + public bool InsertTag (TagNode tag, int index) + { + if (index < 0 || index > _tag.Count) + return false; + + _tag.Insert(index, tag); + return true; + } + } +} diff --git a/Model/NbtFileDataNode.cs b/Model/NbtFileDataNode.cs new file mode 100644 index 0000000..3fe0e9e --- /dev/null +++ b/Model/NbtFileDataNode.cs @@ -0,0 +1,124 @@ +using System.IO; +using Substrate.Core; +using Substrate.Nbt; + +namespace NBTExplorer.Model +{ + public class NbtFileDataNode : DataNode, IMetaTagContainer + { + private NbtTree _tree; + private string _path; + private CompressionType _compressionType; + + private CompoundTagContainer _container; + + private NbtFileDataNode (string path, CompressionType compressionType) + { + _path = path; + _compressionType = compressionType; + _container = new CompoundTagContainer(new TagNodeCompound()); + } + + public static NbtFileDataNode TryCreateFrom (string path) + { + return TryCreateFrom(path, CompressionType.GZip) + ?? TryCreateFrom(path, CompressionType.None); + } + + private static NbtFileDataNode TryCreateFrom (string path, CompressionType compressionType) + { + try { + NBTFile file = new NBTFile(path); + NbtTree tree = new NbtTree(); + tree.ReadFrom(file.GetDataInputStream(compressionType)); + + if (tree.Root == null) + return null; + + return new NbtFileDataNode(path, compressionType); + } + catch { + return null; + } + } + + protected override NodeCapabilities Capabilities + { + get + { + return NodeCapabilities.CreateTag + | NodeCapabilities.PasteInto + | NodeCapabilities.Search; + } + } + + public override string NodeName + { + get { return Path.GetFileName(_path); } + } + + public override string NodeDisplay + { + get { return NodeName; } + } + + public override bool HasUnexpandedChildren + { + get { return !IsExpanded; } + } + + protected override void ExpandCore () + { + if (_tree == null) { + NBTFile file = new NBTFile(_path); + _tree = new NbtTree(); + _tree.ReadFrom(file.GetDataInputStream(_compressionType)); + + if (_tree.Root != null) + _container = new CompoundTagContainer(_tree.Root); + } + + foreach (TagNode tag in _tree.Root.Values) { + TagDataNode node = TagDataNode.CreateFromTag(tag); + if (node != null) + Nodes.Add(node); + } + } + + protected override void ReleaseCore () + { + _tree = null; + Nodes.Clear(); + } + + public bool IsNamedContainer + { + get { return true; } + } + + public bool IsOrderedContainer + { + get { return false; } + } + + public INamedTagContainer NamedTagContainer + { + get { return _container; } + } + + public IOrderedTagContainer OrderedTagContainer + { + get { return null; } + } + + public int TagCount + { + get { return _container.TagCount; } + } + + public bool DeleteTag (TagNode tag) + { + return _container.DeleteTag(tag); + } + } +} diff --git a/Model/NodeCapabilities.cs b/Model/NodeCapabilities.cs new file mode 100644 index 0000000..e5f08a3 --- /dev/null +++ b/Model/NodeCapabilities.cs @@ -0,0 +1,18 @@ +using System; + +namespace NBTExplorer.Model +{ + [Flags] + public enum NodeCapabilities + { + None = 0, + Cut = 0x1, + Copy = 0x2, + PasteInto = 0x4, + Rename = 0x8, + Edit = 0x10, + Delete = 0x20, + CreateTag = 0x40, + Search = 0x80, + } +} diff --git a/Model/RegionChunkDataNode.cs b/Model/RegionChunkDataNode.cs new file mode 100644 index 0000000..da56b7c --- /dev/null +++ b/Model/RegionChunkDataNode.cs @@ -0,0 +1,96 @@ +using Substrate.Core; +using Substrate.Nbt; + +namespace NBTExplorer.Model +{ + public class RegionChunkDataNode : DataNode, IMetaTagContainer + { + private RegionFile _regionFile; + private NbtTree _tree; + private int _x; + private int _z; + + private CompoundTagContainer _container; + + public RegionChunkDataNode (RegionFile regionFile, int x, int z) + { + _regionFile = regionFile; + _x = x; + _z = z; + _container = new CompoundTagContainer(new TagNodeCompound()); + } + + protected override NodeCapabilities Capabilities + { + get + { + return NodeCapabilities.CreateTag + | NodeCapabilities.PasteInto + | NodeCapabilities.Search; + } + } + + public override bool HasUnexpandedChildren + { + get { return !IsExpanded; } + } + + public override string NodeDisplay + { + get { return "Chunk [" + _x + ", " + _z + "]"; } + } + + protected override void ExpandCore () + { + if (_tree == null) { + _tree = new NbtTree(); + _tree.ReadFrom(_regionFile.GetChunkDataInputStream(_x, _z)); + + if (_tree.Root != null) + _container = new CompoundTagContainer(_tree.Root); + } + + foreach (TagNode tag in _tree.Root.Values) { + TagDataNode node = TagDataNode.CreateFromTag(tag); + if (node != null) + Nodes.Add(node); + } + } + + protected override void ReleaseCore () + { + _tree = null; + Nodes.Clear(); + } + + public bool IsNamedContainer + { + get { return true; } + } + + public bool IsOrderedContainer + { + get { return false; } + } + + public INamedTagContainer NamedTagContainer + { + get { return _container; } + } + + public IOrderedTagContainer OrderedTagContainer + { + get { return null; } + } + + public int TagCount + { + get { return _container.TagCount; } + } + + public bool DeleteTag (TagNode tag) + { + return _container.DeleteTag(tag); + } + } +} diff --git a/Model/RegionFileDataNode.cs b/Model/RegionFileDataNode.cs new file mode 100644 index 0000000..b22562a --- /dev/null +++ b/Model/RegionFileDataNode.cs @@ -0,0 +1,65 @@ +using System.IO; +using System.Windows.Forms; +using Substrate.Core; + +namespace NBTExplorer.Model +{ + public class RegionFileDataNode : DataNode + { + private string _path; + private RegionFile _region; + + private RegionFileDataNode (string path) + { + _path = path; + } + + public static RegionFileDataNode TryCreateFrom (string path) + { + return new RegionFileDataNode(path); + } + + protected override NodeCapabilities Capabilities + { + get + { + return NodeCapabilities.Search; + } + } + + public override bool HasUnexpandedChildren + { + get { return !IsExpanded; } + } + + public override string NodeDisplay + { + get { return Path.GetFileName(_path); } + } + + protected override void ExpandCore () + { + try { + if (_region == null) + _region = new RegionFile(_path); + + for (int x = 0; x < 32; x++) { + for (int z = 0; z < 32; z++) { + if (_region.HasChunk(x, z)) { + Nodes.Add(new RegionChunkDataNode(_region, x, z)); + } + } + } + } + catch { + MessageBox.Show("Not a valid region file.", "Read Error", MessageBoxButtons.OK, MessageBoxIcon.Warning); + } + } + + protected override void ReleaseCore () + { + _region = null; + Nodes.Clear(); + } + } +} diff --git a/Model/TagCompoundDataNode.cs b/Model/TagCompoundDataNode.cs new file mode 100644 index 0000000..569a9e1 --- /dev/null +++ b/Model/TagCompoundDataNode.cs @@ -0,0 +1,129 @@ +using System; +using System.Collections.Generic; +using System.Windows.Forms; +using Substrate.Nbt; + +namespace NBTExplorer.Model +{ + public class TagCompoundDataNode : TagDataNode.Container + { + private CompoundTagContainer _container; + + public TagCompoundDataNode (TagNodeCompound tag) + : base(tag) + { + _container = new CompoundTagContainer(tag); + } + + protected new TagNodeCompound Tag + { + get { return base.Tag as TagNodeCompound; } + } + + protected override void ExpandCore () + { + var list = new SortedList(); + foreach (var item in Tag) { + list.Add(new TagKey(item.Key, item.Value.GetTagType()), item.Value); + } + + foreach (var item in list) { + TagDataNode node = TagDataNode.CreateFromTag(item.Value); + if (node != null) + Nodes.Add(node); + } + } + + public override bool CanCreateTag (TagType type) + { + return Enum.IsDefined(typeof(TagType), type) && type != TagType.TAG_END; + } + + public override bool CanPasteIntoNode + { + get { return NbtClipboardData.ContainsData; } + } + + public override bool CreateNode (TagType type) + { + if (!CanCreateTag(type)) + return false; + + CreateNodeForm form = new CreateNodeForm(type, true); + form.InvalidNames.AddRange(_container.TagNamesInUse); + + if (form.ShowDialog() == DialogResult.OK) { + AddTag(form.TagNode, form.TagName); + return true; + } + + return false; + } + + public override bool PasteNode () + { + if (!CanPasteIntoNode) + return false; + + NbtClipboardData clipboard = NbtClipboardData.CopyFromClipboard(); + if (clipboard.Node == null) + return false; + + string name = clipboard.Name; + if (String.IsNullOrEmpty(name)) + name = "UNNAMED"; + + AddTag(clipboard.Node, MakeUniqueName(name)); + return true; + } + + public override bool IsNamedContainer + { + get { return true; } + } + + public override INamedTagContainer NamedTagContainer + { + get { return _container; } + } + + public override int TagCount + { + get { return _container.TagCount; } + } + + public override bool DeleteTag (TagNode tag) + { + return _container.DeleteTag(tag); + } + + private void AddTag (TagNode tag, string name) + { + _container.AddTag(tag, name); + + if (IsExpanded) { + TagDataNode node = TagDataNode.CreateFromTag(tag); + if (node != null) + Nodes.Add(node); + } + } + + private string MakeUniqueName (string name) + { + List names = new List(_container.TagNamesInUse); + if (!names.Contains(name)) + return name; + + int index = 1; + while (names.Contains(MakeCandidateName(name, index))) + index++; + + return MakeCandidateName(name, index); + } + + private string MakeCandidateName (string name, int index) + { + return name + " (Copy " + index + ")"; + } + } +} diff --git a/Model/TagContainerInterface.cs b/Model/TagContainerInterface.cs new file mode 100644 index 0000000..35c56b2 --- /dev/null +++ b/Model/TagContainerInterface.cs @@ -0,0 +1,36 @@ +using System.Collections.Generic; +using Substrate.Nbt; + +namespace NBTExplorer.Model +{ + public interface ITagContainer + { + int TagCount { get; } + + bool DeleteTag (TagNode tag); + } + + public interface IMetaTagContainer : ITagContainer + { + bool IsNamedContainer { get; } + bool IsOrderedContainer { get; } + + INamedTagContainer NamedTagContainer { get; } + IOrderedTagContainer OrderedTagContainer { get; } + } + + public interface INamedTagContainer : ITagContainer + { + IEnumerable TagNamesInUse { get; } + + string GetTagName (TagNode tag); + bool AddTag (TagNode tag, string name); + bool RenameTag (TagNode tag, string name); + } + + public interface IOrderedTagContainer : ITagContainer + { + int GetTagIndex (TagNode tag); + bool InsertTag (TagNode tag, int index); + } +} diff --git a/Model/TagDataNode.cs b/Model/TagDataNode.cs new file mode 100644 index 0000000..c4e8799 --- /dev/null +++ b/Model/TagDataNode.cs @@ -0,0 +1,433 @@ +using System; +using System.Collections.Generic; +using System.Windows.Forms; +using Substrate.Nbt; + +namespace NBTExplorer.Model +{ + public abstract class TagDataNode : DataNode + { + public abstract class Container : TagDataNode, IMetaTagContainer + { + protected Container (TagNode tag) + : base(tag) + { } + + #region ITagContainer + + public virtual int TagCount + { + get { return 0; } + } + + public virtual bool IsNamedContainer + { + get { return false; } + } + + public virtual bool IsOrderedContainer + { + get { return false; } + } + + public virtual INamedTagContainer NamedTagContainer + { + get { return null; } + } + + public virtual IOrderedTagContainer OrderedTagContainer + { + get { return null; } + } + + public virtual bool DeleteTag (TagNode tag) + { + return false; + } + + #endregion + + protected override NodeCapabilities Capabilities + { + get + { + return NodeCapabilities.Copy + | NodeCapabilities.CreateTag + | NodeCapabilities.Cut + | NodeCapabilities.Delete + | NodeCapabilities.PasteInto + | (TagParent.IsNamedContainer ? NodeCapabilities.Rename : NodeCapabilities.None) + | NodeCapabilities.Search; + } + } + + public override bool HasUnexpandedChildren + { + get { return !IsExpanded && TagCount > 0; } + } + + public override string NodeDisplay + { + get { return NodeDisplayPrefix + TagCount + ((TagCount == 1) ? " entry" : " entries"); } + } + } + + private static Dictionary _tagRegistry; + + static TagDataNode () + { + _tagRegistry = new Dictionary(); + _tagRegistry[TagType.TAG_BYTE] = typeof(TagByteDataNode); + _tagRegistry[TagType.TAG_BYTE_ARRAY] = typeof(TagByteArrayDataNode); + _tagRegistry[TagType.TAG_COMPOUND] = typeof(TagCompoundDataNode); + _tagRegistry[TagType.TAG_DOUBLE] = typeof(TagDoubleDataNode); + _tagRegistry[TagType.TAG_FLOAT] = typeof(TagFloatDataNode); + _tagRegistry[TagType.TAG_INT] = typeof(TagIntDataNode); + _tagRegistry[TagType.TAG_INT_ARRAY] = typeof(TagIntArrayDataNode); + _tagRegistry[TagType.TAG_LIST] = typeof(TagListDataNode); + _tagRegistry[TagType.TAG_LONG] = typeof(TagLongDataNode); + _tagRegistry[TagType.TAG_SHORT] = typeof(TagShortDataNode); + _tagRegistry[TagType.TAG_STRING] = typeof(TagStringDataNode); + } + + static public TagDataNode CreateFromTag (TagNode tag) + { + if (tag == null || !_tagRegistry.ContainsKey(tag.GetTagType())) + return null; + + return Activator.CreateInstance(_tagRegistry[tag.GetTagType()], tag) as TagDataNode; + } + + static public TagNode DefaultTag (TagType type) + { + switch (type) { + case TagType.TAG_BYTE: + return new TagNodeByte(0); + case TagType.TAG_BYTE_ARRAY: + return new TagNodeByteArray(new byte[0]); + case TagType.TAG_COMPOUND: + return new TagNodeCompound(); + case TagType.TAG_DOUBLE: + return new TagNodeDouble(0); + case TagType.TAG_FLOAT: + return new TagNodeFloat(0); + case TagType.TAG_INT: + return new TagNodeInt(0); + case TagType.TAG_INT_ARRAY: + return new TagNodeIntArray(new int[0]); + case TagType.TAG_LIST: + return new TagNodeList(TagType.TAG_BYTE); + case TagType.TAG_LONG: + return new TagNodeLong(0); + case TagType.TAG_SHORT: + return new TagNodeShort(0); + case TagType.TAG_STRING: + return new TagNodeString(""); + default: + return new TagNodeByte(0); + } + } + + private TagNode _tag; + + protected TagDataNode (TagNode tag) + { + _tag = tag; + } + + protected IMetaTagContainer TagParent + { + get { return base.Parent as IMetaTagContainer; } + } + + protected TagNode Tag + { + get { return _tag; } + set + { + if (_tag.GetTagType() == value.GetTagType()) + _tag = value; + } + } + + protected override NodeCapabilities Capabilities + { + get + { + return NodeCapabilities.Copy + | NodeCapabilities.Cut + | NodeCapabilities.Delete + | NodeCapabilities.Edit + | (TagParent.IsNamedContainer ? NodeCapabilities.Rename : NodeCapabilities.None); + } + } + + public override string NodeName + { + get + { + if (TagParent == null || !TagParent.IsNamedContainer) + return null; + + return TagParent.NamedTagContainer.GetTagName(Tag); + } + } + + protected string NodeDisplayPrefix + { + get + { + string name = NodeName; + return String.IsNullOrEmpty(name) ? "" : name + ": "; + } + } + + public override string NodeDisplay + { + get { return NodeDisplayPrefix + Tag.ToString(); } + } + + public override bool DeleteNode () + { + if (CanDeleteNode) { + TagParent.DeleteTag(Tag); + return Parent.Nodes.Remove(this); + } + + return false; + } + + public override bool RenameNode () + { + if (CanRenameNode && TagParent.IsNamedContainer) { + EditName form = new EditName(TagParent.NamedTagContainer.GetTagName(Tag)); + form.InvalidNames.AddRange(TagParent.NamedTagContainer.TagNamesInUse); + if (form.ShowDialog() == DialogResult.OK && form.IsModified) { + if (TagParent.NamedTagContainer.RenameTag(Tag, form.TagName)) { + IsModified = true; + return true; + } + } + } + + return false; + } + + public override bool CopyNode () + { + if (CanCopyNode) { + NbtClipboardData clip = new NbtClipboardData(NodeName, Tag); + clip.CopyToClipboard(); + return true; + } + + return false; + } + + public override bool CutNode () + { + if (CanCutNode) { + NbtClipboardData clip = new NbtClipboardData(NodeName, Tag); + clip.CopyToClipboard(); + + TagParent.DeleteTag(Tag); + Parent.Nodes.Remove(this); + return true; + } + + return false; + } + + protected bool EditScalarValue (TagNode tag) + { + EditValue form = new EditValue(tag); + if (form.ShowDialog() == DialogResult.OK) { + IsModified = true; + return true; + } + else + return false; + } + + protected bool EditStringValue (TagNode tag) + { + EditString form = new EditString(tag.ToTagString().Data); + if (form.ShowDialog() == DialogResult.OK) { + tag.ToTagString().Data = form.StringValue; + + IsModified = true; + return true; + } + else + return false; + } + + protected bool EditByteHexValue (TagNode tag) + { + HexEditor form = new HexEditor(NodeName, tag.ToTagByteArray().Data, 1); + if (form.ShowDialog() == DialogResult.OK && form.Modified) { + Array.Copy(form.Data, tag.ToTagByteArray().Data, tag.ToTagByteArray().Length); + + IsModified = true; + return true; + } + else + return false; + } + + protected bool EditIntHexValue (TagNode tag) + { + TagNodeIntArray iatag = tag.ToTagIntArray(); + byte[] data = new byte[iatag.Length * 4]; + for (int i = 0; i < iatag.Length; i++) { + byte[] buf = BitConverter.GetBytes(iatag.Data[i]); + Array.Copy(buf, 0, data, 4 * i, 4); + } + + HexEditor form = new HexEditor(NodeName, data, 4); + if (form.ShowDialog() == DialogResult.OK && form.Modified) { + for (int i = 0; i < iatag.Length; i++) { + iatag.Data[i] = BitConverter.ToInt32(form.Data, i * 4); + } + + IsModified = true; + return true; + } + else + return false; + } + } + + public class TagByteDataNode : TagDataNode + { + public TagByteDataNode (TagNodeByte tag) + : base(tag) + { } + + public override bool EditNode () + { + return EditScalarValue(Tag); + } + } + + public class TagShortDataNode : TagDataNode + { + public TagShortDataNode (TagNodeShort tag) + : base(tag) + { } + + public override bool EditNode () + { + return EditScalarValue(Tag); + } + } + + public class TagIntDataNode : TagDataNode + { + public TagIntDataNode (TagNodeInt tag) + : base(tag) + { } + + public override bool EditNode () + { + return EditScalarValue(Tag); + } + } + + public class TagLongDataNode : TagDataNode + { + public TagLongDataNode (TagNodeLong tag) + : base(tag) + { } + + public override bool EditNode () + { + return EditScalarValue(Tag); + } + } + + public class TagFloatDataNode : TagDataNode + { + public TagFloatDataNode (TagNodeFloat tag) + : base(tag) + { } + + public override bool EditNode () + { + return EditScalarValue(Tag); + } + } + + public class TagDoubleDataNode : TagDataNode + { + public TagDoubleDataNode (TagNodeDouble tag) + : base(tag) + { } + + public override bool EditNode () + { + return EditScalarValue(Tag); + } + } + + public class TagStringDataNode : TagDataNode + { + public TagStringDataNode (TagNodeString tag) + : base(tag) + { } + + public override bool EditNode () + { + return EditStringValue(Tag); + } + + public override string NodeDisplay + { + get { return NodeDisplayPrefix + Tag.ToString().Replace('\n', (char)0x00B6); } + } + } + + public class TagByteArrayDataNode : TagDataNode + { + public TagByteArrayDataNode (TagNodeByteArray tag) + : base(tag) + { } + + protected new TagNodeByteArray Tag + { + get { return base.Tag as TagNodeByteArray; } + } + + public override bool EditNode () + { + return EditByteHexValue(Tag); + } + + public override string NodeDisplay + { + get { return NodeDisplayPrefix + Tag.Data.Length + " bytes"; } + } + } + + public class TagIntArrayDataNode : TagDataNode + { + public TagIntArrayDataNode (TagNodeIntArray tag) + : base(tag) + { } + + protected new TagNodeIntArray Tag + { + get { return base.Tag as TagNodeIntArray; } + } + + public override bool EditNode () + { + return EditIntHexValue(Tag); + } + + public override string NodeDisplay + { + get { return NodeDisplayPrefix + Tag.Data.Length + " integers"; } + } + } +} diff --git a/Model/TagListDataNode.cs b/Model/TagListDataNode.cs new file mode 100644 index 0000000..42ad81f --- /dev/null +++ b/Model/TagListDataNode.cs @@ -0,0 +1,111 @@ +using System; +using Substrate.Nbt; + +namespace NBTExplorer.Model +{ + public class TagListDataNode : TagDataNode.Container + { + private ListTagContainer _container; + + public TagListDataNode (TagNodeList tag) + : base(tag) + { + _container = new ListTagContainer(tag); + } + + protected new TagNodeList Tag + { + get { return base.Tag as TagNodeList; } + set { base.Tag = value; } + } + + protected override void ExpandCore () + { + foreach (TagNode tag in Tag) { + TagDataNode node = TagDataNode.CreateFromTag(tag); + if (node != null) + Nodes.Add(node); + } + } + + public override bool CanCreateTag (TagType type) + { + if (Tag.Count > 0) + return Tag.ValueType == type; + else + return Enum.IsDefined(typeof(TagType), type) && type != TagType.TAG_END; + } + + public override bool CanPasteIntoNode + { + get + { + if (NbtClipboardData.ContainsData) { + TagNode node = NbtClipboardData.CopyFromClipboard().Node; + if (node != null && node.GetTagType() == Tag.ValueType) + return true; + } + + return false; + } + } + + public override bool CreateNode (TagType type) + { + if (!CanCreateTag(type)) + return false; + + if (Tag.Count == 0) { + Tag = new TagNodeList(type); + _container = new ListTagContainer(Tag); + } + + AppendTag(TagDataNode.DefaultTag(type)); + return true; + } + + public override bool PasteNode () + { + if (!CanPasteIntoNode) + return false; + + NbtClipboardData clipboard = NbtClipboardData.CopyFromClipboard(); + if (clipboard.Node == null) + return false; + + AppendTag(clipboard.Node); + return true; + } + + public override bool IsOrderedContainer + { + get { return true; } + } + + public override IOrderedTagContainer OrderedTagContainer + { + get { return _container; } + } + + public override int TagCount + { + get { return _container.TagCount; } + } + + public override bool DeleteTag (TagNode tag) + { + return _container.DeleteTag(tag); + } + + private void AppendTag (TagNode tag) + { + _container.InsertTag(tag, _container.TagCount); + + if (IsExpanded) { + TagDataNode node = TagDataNode.CreateFromTag(tag); + if (node != null) + Nodes.Add(node); + } + } + } +} diff --git a/NBTExplorer.csproj b/NBTExplorer.csproj index e42dba2..d122582 100644 --- a/NBTExplorer.csproj +++ b/NBTExplorer.csproj @@ -10,9 +10,8 @@ Properties NBTExplorer NBTExplorer - v2.0 - - + v4.0 + Client 512 @@ -49,6 +48,13 @@ + + + Form + + + MainForm.cs + Form @@ -98,6 +104,19 @@ EditHex.cs + + + + + + + + + + + + + @@ -122,6 +141,10 @@ + + MainForm.cs + Designer + About.cs diff --git a/Program.cs b/Program.cs index c9908a1..41b41d1 100644 --- a/Program.cs +++ b/Program.cs @@ -14,7 +14,7 @@ namespace NBTExplorer { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); - Application.Run(new Form1()); + Application.Run(new MainForm()); } } } diff --git a/Properties/Resources.Designer.cs b/Properties/Resources.Designer.cs index 28adddb..bdc9983 100644 --- a/Properties/Resources.Designer.cs +++ b/Properties/Resources.Designer.cs @@ -1,7 +1,7 @@ //------------------------------------------------------------------------------ // // This code was generated by a tool. -// Runtime Version:4.0.30319.239 +// Runtime Version:4.0.30319.269 // // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. diff --git a/Resources/question-white.png b/Resources/question-white.png new file mode 100644 index 0000000000000000000000000000000000000000..f806468719539405a3f76885123e4ecb09cf3d1b GIT binary patch literal 761 zcmV?7A3KEJ$%9f&PJl8eND821JVDLIihG+y!Z@4+2UMgjAcB zHZe`4oxGcwOuXNXGgxuwg)@)uJLk;(4tJPFqXGZ3jCdKp6a|Z=1#Grf5Ji)hW!X7W zo+jx1%}Wq0tEw8VRx3$K+Jj=T0FlT3rh&EyA;7|ZXnfG(I5ltxI-JdRDy#Tb<0W4t zR=GkrK~h>eumeqO;;P|=iyq$F&O>vwI_-748Su2V!02(ovG`~sEU7AJCe%QdWv{A~ zLkodpe3z5OcQ||X!+}}v-spo9eKuGKbn@44#zTY?A>|~C%|f9#H#ux`bh!*vtSAc1 zo^Pi(GiZf;J`e9c@6aA{CQjNMs6j0?s8p)clcO$5sMqThGZS{08sWid-N!y;GCPn+ zBw%gr8;taeRHKies%)>f!%Xfq`gKXlL%Cdmk6()L@I@Mi2V8LZ!V!{u5ilCJ-9R?}1XOM0h;Sqd_)KHJX7aS`&%QvhT3DMua>; zGq}}fr|CVH+Xapj^+30>O^u#`$z)%C6O-`}0nZCM&dqOA{8%pFww6eMA1f}y(7{;1$Z0ha;VV_$h^s#A_ng~Rce`Cff9{I5nkPQQ{Xe!Qbc_3 zInQHlanR{vX}DY2Iz&Io5Q)jT?e&%5_t>qa z-P8&_t<->F7%fn@(=*lIJ#cNNwQa=Du-s9ax+<^l{dgbUj6Zmp-FW?#l+pyXzYTC4 r3xQc1?H>z&kP04N{83Q*OMn3Yq{|~z654 - + + + + + diff --git a/forms/CreateNode.Designer.cs b/forms/CreateNode.Designer.cs index 3d0e3cf..4435b37 100644 --- a/forms/CreateNode.Designer.cs +++ b/forms/CreateNode.Designer.cs @@ -1,6 +1,6 @@ namespace NBTExplorer { - partial class CreateNode + partial class CreateNodeForm { /// /// Required designer variable. diff --git a/forms/CreateNode.cs b/forms/CreateNode.cs index c5b03f3..e4418c0 100644 --- a/forms/CreateNode.cs +++ b/forms/CreateNode.cs @@ -9,7 +9,7 @@ using Substrate.Nbt; namespace NBTExplorer { - public partial class CreateNode : Form + public partial class CreateNodeForm : Form { private string _name; private int _size; @@ -20,11 +20,11 @@ namespace NBTExplorer private List _invalidNames = new List(); - public CreateNode (TagType tagType) + public CreateNodeForm (TagType tagType) : this(tagType, true) { } - public CreateNode (TagType tagType, bool hasName) + public CreateNodeForm (TagType tagType, bool hasName) { InitializeComponent(); diff --git a/forms/EditName.cs b/forms/EditName.cs index 6c5c485..1525661 100644 --- a/forms/EditName.cs +++ b/forms/EditName.cs @@ -10,6 +10,7 @@ namespace NBTExplorer { public partial class EditName : Form { + private string _originalName; private string _name; private List _invalidNames = new List(); @@ -18,6 +19,7 @@ namespace NBTExplorer { InitializeComponent(); + _originalName = name; _name = name; _nameField.Text = _name; @@ -33,6 +35,11 @@ namespace NBTExplorer get { return _invalidNames; } } + public bool IsModified + { + get { return _name != _originalName; } + } + private void Apply () { if (ValidateInput()) { @@ -54,7 +61,7 @@ namespace NBTExplorer return false; } - if (_invalidNames.Contains(text)) { + if (text != _originalName && _invalidNames.Contains(text)) { MessageBox.Show("Duplicate name provided."); return false; }