diff --git a/.gitignore b/.gitignore
index bff1e36e5..f377c2268 100644
--- a/.gitignore
+++ b/.gitignore
@@ -19,3 +19,4 @@ paket-files/
\.paket/
*.nupkg
+*.user
diff --git a/Src/SwqlStudio/DocumentationContent.Designer.cs b/Src/SwqlStudio/DocumentationContent.Designer.cs
new file mode 100644
index 000000000..c5928ec26
--- /dev/null
+++ b/Src/SwqlStudio/DocumentationContent.Designer.cs
@@ -0,0 +1,77 @@
+namespace SwqlStudio
+{
+ partial class DocumentationContent
+ {
+ ///
+ /// 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 Component Designer generated code
+
+ ///
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ ///
+ private void InitializeComponent()
+ {
+ this.itemTypeLabel = new System.Windows.Forms.Label();
+ this.docTextBox = new System.Windows.Forms.RichTextBox();
+ this.SuspendLayout();
+ //
+ // itemTypeLabel
+ //
+ this.itemTypeLabel.AutoSize = true;
+ this.itemTypeLabel.Dock = System.Windows.Forms.DockStyle.Top;
+ this.itemTypeLabel.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.itemTypeLabel.Location = new System.Drawing.Point(5, 5);
+ this.itemTypeLabel.Name = "itemTypeLabel";
+ this.itemTypeLabel.Padding = new System.Windows.Forms.Padding(3);
+ this.itemTypeLabel.Size = new System.Drawing.Size(6, 19);
+ this.itemTypeLabel.TabIndex = 2;
+ //
+ // docTextBox
+ //
+ this.docTextBox.BorderStyle = System.Windows.Forms.BorderStyle.None;
+ this.docTextBox.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.docTextBox.Location = new System.Drawing.Point(5, 24);
+ this.docTextBox.Name = "docTextBox";
+ this.docTextBox.ReadOnly = true;
+ this.docTextBox.Size = new System.Drawing.Size(274, 232);
+ this.docTextBox.TabIndex = 3;
+ this.docTextBox.Text = "";
+ //
+ // DocumentationContent
+ //
+ this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+ this.ClientSize = new System.Drawing.Size(284, 261);
+ this.Controls.Add(this.docTextBox);
+ this.Controls.Add(this.itemTypeLabel);
+ this.Name = "DocumentationContent";
+ this.Padding = new System.Windows.Forms.Padding(5);
+ this.Text = "Documentation";
+ this.ResumeLayout(false);
+ this.PerformLayout();
+
+ }
+
+ #endregion
+
+ private System.Windows.Forms.Label itemTypeLabel;
+ private System.Windows.Forms.RichTextBox docTextBox;
+ }
+}
diff --git a/Src/SwqlStudio/DocumentationContent.cs b/Src/SwqlStudio/DocumentationContent.cs
new file mode 100644
index 000000000..2f7d9f978
--- /dev/null
+++ b/Src/SwqlStudio/DocumentationContent.cs
@@ -0,0 +1,24 @@
+using System.Drawing.Design;
+using System.Windows.Forms;
+using WeifenLuo.WinFormsUI.Docking;
+
+namespace SwqlStudio
+{
+ public partial class DocumentationContent : DockContent
+ {
+ public DocumentationContent()
+ {
+ InitializeComponent();
+ }
+
+ public void UpdateDocumentation(TreeNode newNode)
+ {
+ if (newNode != null)
+ {
+ var doc = DocumentationBuilder.Build(newNode);
+ this.itemTypeLabel.Text = doc.ItemType;
+ this.docTextBox.Text = doc.Documents;
+ }
+ }
+ }
+}
diff --git a/Src/SwqlStudio/DocumentationContent.resx b/Src/SwqlStudio/DocumentationContent.resx
new file mode 100644
index 000000000..1af7de150
--- /dev/null
+++ b/Src/SwqlStudio/DocumentationContent.resx
@@ -0,0 +1,120 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
\ No newline at end of file
diff --git a/Src/SwqlStudio/LexerService.cs b/Src/SwqlStudio/LexerService.cs
index e973f6f50..d89b7e6b2 100644
--- a/Src/SwqlStudio/LexerService.cs
+++ b/Src/SwqlStudio/LexerService.cs
@@ -3,6 +3,7 @@
using System.Collections.Generic;
using System.Linq;
using SwqlStudio.Autocomplete;
+using SwqlStudio.Metadata;
using SwqlStudio.Properties;
namespace SwqlStudio
diff --git a/Src/SwqlStudio/MainForm.Designer.cs b/Src/SwqlStudio/MainForm.Designer.cs
index eb08faad1..d11de49a4 100644
--- a/Src/SwqlStudio/MainForm.Designer.cs
+++ b/Src/SwqlStudio/MainForm.Designer.cs
@@ -49,6 +49,7 @@ private void InitializeComponent()
this.redoToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripSeparator5 = new System.Windows.Forms.ToolStripSeparator();
this.findToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+ this.replaceToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripSeparator6 = new System.Windows.Forms.ToolStripSeparator();
this.menuEditCut = new System.Windows.Forms.ToolStripMenuItem();
this.menuEditCopy = new System.Windows.Forms.ToolStripMenuItem();
@@ -77,7 +78,6 @@ private void InitializeComponent()
this.saveFileDialog = new System.Windows.Forms.SaveFileDialog();
this.fontDialog = new System.Windows.Forms.FontDialog();
this.filesDock = new SwqlStudio.QueriesDockPanel();
- this.ObjectExplorerImageList = new System.Windows.Forms.ImageList(this.components);
this.startTimer = new System.Windows.Forms.Timer(this.components);
this.mainToolbar = new System.Windows.Forms.ToolStrip();
this.connectionsCombobox = new System.Windows.Forms.ToolStripComboBox();
@@ -93,7 +93,6 @@ private void InitializeComponent()
this.newFileToolButton = new System.Windows.Forms.ToolStripButton();
this.openFileButton = new System.Windows.Forms.ToolStripButton();
this.saveToolButton = new System.Windows.Forms.ToolStripButton();
- this.replaceToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
toolStripSeparator1 = new System.Windows.Forms.ToolStripSeparator();
this.menu.SuspendLayout();
this.mainToolbar.SuspendLayout();
@@ -254,7 +253,7 @@ private void InitializeComponent()
this.undoToolStripMenuItem.Image = global::SwqlStudio.Properties.Resources.Undo_16x;
this.undoToolStripMenuItem.Name = "undoToolStripMenuItem";
this.undoToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.Z)));
- this.undoToolStripMenuItem.Size = new System.Drawing.Size(180, 22);
+ this.undoToolStripMenuItem.Size = new System.Drawing.Size(158, 22);
this.undoToolStripMenuItem.Text = "Undo";
this.undoToolStripMenuItem.Click += new System.EventHandler(this.undoToolStripMenuItem_Click);
//
@@ -263,34 +262,42 @@ private void InitializeComponent()
this.redoToolStripMenuItem.Image = global::SwqlStudio.Properties.Resources.Redo_16x;
this.redoToolStripMenuItem.Name = "redoToolStripMenuItem";
this.redoToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.Y)));
- this.redoToolStripMenuItem.Size = new System.Drawing.Size(180, 22);
+ this.redoToolStripMenuItem.Size = new System.Drawing.Size(158, 22);
this.redoToolStripMenuItem.Text = "Redo";
this.redoToolStripMenuItem.Click += new System.EventHandler(this.redoToolStripMenuItem_Click);
//
// toolStripSeparator5
//
this.toolStripSeparator5.Name = "toolStripSeparator5";
- this.toolStripSeparator5.Size = new System.Drawing.Size(177, 6);
+ this.toolStripSeparator5.Size = new System.Drawing.Size(155, 6);
//
// findToolStripMenuItem
//
this.findToolStripMenuItem.Name = "findToolStripMenuItem";
this.findToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.F)));
- this.findToolStripMenuItem.Size = new System.Drawing.Size(180, 22);
+ this.findToolStripMenuItem.Size = new System.Drawing.Size(158, 22);
this.findToolStripMenuItem.Text = "&Find";
this.findToolStripMenuItem.Click += new System.EventHandler(this.findToolStripMenuItem_Click);
//
+ // replaceToolStripMenuItem
+ //
+ this.replaceToolStripMenuItem.Name = "replaceToolStripMenuItem";
+ this.replaceToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.H)));
+ this.replaceToolStripMenuItem.Size = new System.Drawing.Size(158, 22);
+ this.replaceToolStripMenuItem.Text = "Replace";
+ this.replaceToolStripMenuItem.Click += new System.EventHandler(this.replaceToolStripMenuItem_Click);
+ //
// toolStripSeparator6
//
this.toolStripSeparator6.Name = "toolStripSeparator6";
- this.toolStripSeparator6.Size = new System.Drawing.Size(177, 6);
+ this.toolStripSeparator6.Size = new System.Drawing.Size(155, 6);
//
// menuEditCut
//
this.menuEditCut.Image = ((System.Drawing.Image)(resources.GetObject("menuEditCut.Image")));
this.menuEditCut.Name = "menuEditCut";
this.menuEditCut.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.X)));
- this.menuEditCut.Size = new System.Drawing.Size(180, 22);
+ this.menuEditCut.Size = new System.Drawing.Size(158, 22);
this.menuEditCut.Text = "Cu&t";
this.menuEditCut.Click += new System.EventHandler(this.menuEditCut_Click);
//
@@ -299,7 +306,7 @@ private void InitializeComponent()
this.menuEditCopy.Image = global::SwqlStudio.Properties.Resources.ASX_Copy_blue_16x;
this.menuEditCopy.Name = "menuEditCopy";
this.menuEditCopy.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.C)));
- this.menuEditCopy.Size = new System.Drawing.Size(180, 22);
+ this.menuEditCopy.Size = new System.Drawing.Size(158, 22);
this.menuEditCopy.Text = "&Copy";
this.menuEditCopy.Click += new System.EventHandler(this.menuEditCopy_Click);
//
@@ -308,7 +315,7 @@ private void InitializeComponent()
this.menuEditPaste.Image = global::SwqlStudio.Properties.Resources.ASX_Paste_blue_16x;
this.menuEditPaste.Name = "menuEditPaste";
this.menuEditPaste.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.V)));
- this.menuEditPaste.Size = new System.Drawing.Size(180, 22);
+ this.menuEditPaste.Size = new System.Drawing.Size(158, 22);
this.menuEditPaste.Text = "&Paste";
this.menuEditPaste.Click += new System.EventHandler(this.menuEditPaste_Click);
//
@@ -319,7 +326,7 @@ private void InitializeComponent()
this.curlBashToolStripMenuItem,
this.getSwisDataPowerShellToolStripMenuItem});
this.copyQueryAsToolStripMenuItem.Name = "copyQueryAsToolStripMenuItem";
- this.copyQueryAsToolStripMenuItem.Size = new System.Drawing.Size(180, 22);
+ this.copyQueryAsToolStripMenuItem.Size = new System.Drawing.Size(158, 22);
this.copyQueryAsToolStripMenuItem.Text = "Copy &Query As";
//
// curlCmdToolStripMenuItem
@@ -494,25 +501,6 @@ private void InitializeComponent()
this.filesDock.Size = new System.Drawing.Size(827, 571);
this.filesDock.TabIndex = 2;
//
- // ObjectExplorerImageList
- //
- this.ObjectExplorerImageList.ImageStream = ((System.Windows.Forms.ImageListStreamer)(resources.GetObject("ObjectExplorerImageList.ImageStream")));
- this.ObjectExplorerImageList.TransparentColor = System.Drawing.Color.Transparent;
- this.ObjectExplorerImageList.Images.SetKeyName(0, "Column");
- this.ObjectExplorerImageList.Images.SetKeyName(1, "Database");
- this.ObjectExplorerImageList.Images.SetKeyName(2, "Link");
- this.ObjectExplorerImageList.Images.SetKeyName(3, "Table");
- this.ObjectExplorerImageList.Images.SetKeyName(4, "InheritedColumn");
- this.ObjectExplorerImageList.Images.SetKeyName(5, "KeyColumn");
- this.ObjectExplorerImageList.Images.SetKeyName(6, "Verb");
- this.ObjectExplorerImageList.Images.SetKeyName(7, "Argument");
- this.ObjectExplorerImageList.Images.SetKeyName(8, "Indication");
- this.ObjectExplorerImageList.Images.SetKeyName(9, "Namespace");
- this.ObjectExplorerImageList.Images.SetKeyName(10, "BaseType");
- this.ObjectExplorerImageList.Images.SetKeyName(11, "BaseTypeAbstract");
- this.ObjectExplorerImageList.Images.SetKeyName(12, "TableAbstract");
- this.ObjectExplorerImageList.Images.SetKeyName(13, "TableCrud");
- //
// startTimer
//
this.startTimer.Tick += new System.EventHandler(this.startTimer_Tick);
@@ -652,14 +640,6 @@ private void InitializeComponent()
this.saveToolButton.ToolTipText = "Save (Ctrl+S)";
this.saveToolButton.Click += new System.EventHandler(this.menuFileSave_Click);
//
- // replaceToolStripMenuItem
- //
- this.replaceToolStripMenuItem.Name = "replaceToolStripMenuItem";
- this.replaceToolStripMenuItem.Size = new System.Drawing.Size(180, 22);
- this.replaceToolStripMenuItem.Text = "Replace";
- this.replaceToolStripMenuItem.Click += new System.EventHandler(this.replaceToolStripMenuItem_Click);
- this.replaceToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.H)));
- //
// MainForm
//
this.AllowDrop = true;
@@ -705,7 +685,6 @@ private void InitializeComponent()
private System.Windows.Forms.ToolStripMenuItem menuEditPaste;
private System.Windows.Forms.ToolStripMenuItem queryToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem menuQueryExecute;
- private System.Windows.Forms.ImageList ObjectExplorerImageList;
private System.Windows.Forms.Timer startTimer;
private System.Windows.Forms.ToolStripMenuItem parametersToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem enumEntitiesToolStripMenuItem;
diff --git a/Src/SwqlStudio/MainForm.cs b/Src/SwqlStudio/MainForm.cs
index 3b832e903..2fcdc3a41 100644
--- a/Src/SwqlStudio/MainForm.cs
+++ b/Src/SwqlStudio/MainForm.cs
@@ -7,6 +7,7 @@
using System.Windows.Forms;
using SolarWinds.InformationService.Contract2;
using SolarWinds.InformationService.InformationServiceClient;
+using SwqlStudio.Metadata;
using SwqlStudio.Properties;
using SwqlStudio.Subscriptions;
using SwqlStudio.Utils;
@@ -53,7 +54,6 @@ public MainForm()
private void InitializeDockPanel()
{
- this.filesDock.SetObjectExplorerImageList(this.ObjectExplorerImageList);
this.serverList = new ServerList();
this.serverList.ConnectionAdded += ServerListOnConnectionAdded;
this.serverList.ConnectionRemoved += ServerListOnConnectionRemoved;
diff --git a/Src/SwqlStudio/MainForm.resx b/Src/SwqlStudio/MainForm.resx
index a6189d612..d0b7f431f 100644
--- a/Src/SwqlStudio/MainForm.resx
+++ b/Src/SwqlStudio/MainForm.resx
@@ -151,221 +151,6 @@
ZHMuSW5mb3JtYXRpb25TZXJ2aWNlLkNvbnRyYWN0Mi5Qcm9wZXJ0eUJhZwMAAAAHVmVyc2lvbghDb21w
YXJlcghIYXNoU2l6ZQADAAgWU3lzdGVtLk9yZGluYWxDb21wYXJlcggCAAAAAAAAAAkDAAAAAAAAAAQD
AAAAFlN5c3RlbS5PcmRpbmFsQ29tcGFyZXIBAAAAC19pZ25vcmVDYXNlAAEBCw==
-
-
-
- 467, 17
-
-
-
- AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj00LjAuMC4w
- LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAACZTeXN0
- ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAAAG
- MAAAAk1TRnQBSQFMAgEBDgEAAYwBAgGMAQIBEAEAARABAAT/ASEBAAj/AUIBTQE2BwABNgMAASgDAAFA
- AwABQAMAAQEBAAEgBgABQBIAgP+AAAT/A0AB/wPAAf8D9AH/A9YB/wMrTf8DAAH/AwAB/wE5AVwBuRH/
- gAAE/wO0Af8DCQH/AwkB/wMJAf8Dok3/AwAB/wMAAf8BOQFcAbkB/wMADf+AAAT/A/IB/wMiAf8D6AH/
- AyQB/wPoAf8BBgIAAf8BBgIAAf8BBgIAAf8BBgIAAf8BBgIAAf8BBgIAAf8BBgIAAf8BBgIAEf8BtwGi
- AZMB/wFFASsBFwH/AUUBKwEXAf8BRQErARcB/wFFASsBFwn/AwAB/wE5AVwBuQH/ATkBXAG5Af8BRQEr
- ARcB/wMACf+AAAT/A/kB/wONAf8DSQH/A1MB/wP3Af8B3wHOAcMB/wHdAcgBuwH/AdsBvwGtAf8B2wG7
- AacB/wHbAbsBpwH/AdsBuwGnAf8BzwG0AaMB/wEGAgAR/wG3AaIBkwH/Af0B+wH5Af8B4QHcAdgB/wHg
- AdcB0gH/Ad8BzgHDAf8B3QHIAbsJ/wMAAf8DYQH/AUUBKwEXAf8BRQErARcB/wMABf+AAAT/A/0B/wPb
- Af8DCQH/A8kB/wP7Af8B+wHsAeMB/wGkAY0BIQH/AZoBgwEVAf8B9gHWAcIB/wGIARQBAQH/AYMBDgEA
- Af8BzwG0AaMB/wEGAgAR/wG3AaIBkwH/A/4B/wG6AaYBmAH/AbUBoAGRAf8B+wHsAeMB/wGkAY0BYAH/
- AZoBgwFUCf8DAAH/A2EB/wFFASsBFwH/AUUBKwEXAf8DAAH/gAAI/wG6AaUBlgH/A/4B/wP+Af8D/gH/
- Af0B+wH5Af8B/QH3AfMB/wH7AewB4wH/AfoB5wHbAf8B+AHhAdIB/wH3AdsByQH/AdABuQGrAf8BBgIA
- Ef8BugGlAZYB/wP+Af8D/gH/A/4B/wH9AfsB+QH/Af0B9wHzAf8B+wHsAeMB/wH6AecB2wn/AwAB/wNh
- Af8BRQErARcB/wFFASsBFwH/gAAI/wG+AakBmgH/A/4B/wG6AaYBmAH/AbQBoAGRAf8D/gH/AaMBjgEh
- Af8BmgGDARUB/wH7AewB4wH/AYkBFAECAf8BgwEOAQAB/wHRAcEBtgH/AQYCABH/Ab4BqQGaAf8D/gH/
- AboBpgGYAf8BtAGgAZEB/wP+Af8BowGOAWAB/wGaAYMBVAH/AfsB7AHjAf8BiQFTAUEJ/wMAAf8DYQH/
- AUUBKwEXAf+AAAj/AcMBrgGeAf8D/gH/A/4B/wP+Af8D/gH/A/4B/wH9AfcB8wH/AfwB8gHsAf8B+wHs
- AeMB/wH6AecB2wH/AdEBwQG2Af8BBgIAEf8BwwGuAZ4B/wP+Af8D/gH/A/4B/wP+Af8D/gH/Af0B9wHz
- Af8B/AHyAewB/wH7AewB4wH/AfoB5wHbCf8DAAH/A2EB/4AACP8ByAGyAaMB/wP+Af8BugGmAZgB/wG0
- AaABkQH/A/4B/wGkAY4BIQH/AZkBhAEVAf8B/QH3AfMB/wGIARQBAQH/AYMBDgEAAf8B0QHBAbYB/wEG
- AgAR/wHIAbIBowH/A/4B/wG6AaYBmAH/AbQBoAGRAf8D/gH/AaQBjgFgAf8BmQGEAVQB/wH9AfcB8wH/
- AYgBUwFAAf8BgwFNAToB/wHRAcEBtgn/AUUBKwEXAf+AAAj/AcwBtgGnAf8D/gH/A/4B/wP+Af8D/gH/
- A/4B/wP+Af8B/QH7AfkB/wH9AfcB8wH/AfwB8gHsAf8B+wHsAeMB/wEGAgAR/wHMAbYBpwH/A/4B/wP+
- Af8D/gH/A/4B/wP+Af8D/gH/Af0B+wH5Af8B/QH3AfMB/wH8AfIB7AH/AfsB7AHjAf8BRQErARcJ/4AA
- CP8B6gGqAYsB/wHqAaoBiwH/AeoBqgGLAf8B6QGlAYQB/wHnAZcBEQH/AeYBjgEFAf8B4wEgAQAB/wHj
- ARkBAAH/AeIBFQEAAf8B4gEVAQAB/wHiARUBAAH/AcgBBQEAEf8B6gGqAYsB/wHqAaoBiwH/AeoBqgGL
- Af8B6QGlAYQB/wHnAZcBUAH/AeYBjgFEAf8B4wFfASwB/wHjAVgBIgH/AeIBVAEbAf8B4gFUARsB/wHi
- AVQBGwH/AcgBRAERCf+AAAj/AeoBqgGLAv8BwgGiAf8B/gHAAZ8B/wH9Ab0BmgH/AfsBtQGQAf8B+gGw
- AYsB/wH4AacBIAH/AfYBogEaAf8B9QGdARQB/wH1AZkBDQH/AfMBlQEIAf8BzQEIAQAR/wHqAaoBiwL/
- AcIBogH/Af4BwAGfAf8B/QG9AZoB/wH7AbUBkAH/AfoBsAGLAf8B+AGnAV8B/wH2AaIBWQH/AfUBnQFT
- Af8B9QGZAUwB/wHzAZUBRwH/Ac0BRwETCf+AAAj/AeoBqgGLAf8B6gGqAYsB/wHqAaoBiwH/AeoBqgGL
- Af8B6QGhASIB/wHoAZsBGQH/AeYBjgEFAf8B5QGHAQAB/wHkAYEBAAH/AeQBHgEAAf8B4wEZAQAB/wHi
- ARUBABH/AeoBqgGLAf8B6gGqAYsB/wHqAaoBiwH/AeoBqgGLAf8B6QGhAWEB/wHoAZsBWAH/AeYBjgFE
- Af8B5QGHAToB/wHkAYEBMAH/AeQBXQEoAf8B4wFYASAB/wHiAVQBGwn/gACA/4AAgP//ACkAAdMB3wHr
- Af8B6AH0Av8B6AH0Av8B0wHfAesB/wgAA/QB/wP0Af8D9QX/A/YB/wP0Af8D9A3/A/4B/wP2Af8D9QH/
- A/0J/xAAAe8B5gHcAf8BzgG1AZMB/wG4AZMBIQH/AbIBiAEPAf8BuAGSASAB/wHOAbQBkAH/Ae4B5gHb
- Af94AAPfAf8B6AH0Av8BmAGkAbAB/wGYAaQBsAH/AegB9AL/A98B/wQAA/YB/wM/Af8DwAH/A/QB/wPW
- Af8DKgH/A/UJ/wP+Af8D9gH/AVABrgHbAf8BUAGuAdsB/wP1Af8D/QX/CAAB/QH7AfoB/wHIAawBhAH/
- AaEBMAEAAf8BnQEqAQAB/wGcASgBAAH/AaQBNgEAAf8BnQEpAQAB/wGdASkBAAH/AZ8BLwEAAf8BxwGq
- AYEB/wH8AfsB+QH/HAADhgH/AwAB/w8AAf8DhgH/NAAD3wH/A/QB/wEtAagB5gH/AQABSwG2Af8BAAFL
- Ab4B/wElAagB7gH/AegB9AL/AdMB3wHrAf8D+gH/A7QB/wMIAf8DCAH/AwgB/wOiAf8D+gX/A/4B/wP2
- Af8BUAGuAdsB/wEAAU4BxwH/AQABTgHHAf8BUAGuAdsB/wP1Af8D/QH/BAAB/AH7AfkB/wG8AZYBJgH/
- AaABLQEAAf8BoQEuAQAB/wGeASkBAAH/AcoBqgE3Af8B9gHxAegB/wHNAa8BQQH/AZ4BKQEAAf8BoQEu
- AQAB/wGhAS0BAAH/AboBlAEiAf8B/AH6AfgB/xQAA4YB/wMAAf8XAAH/A4YB/zgAAS0BqAHmAf8BAAFL
- AbYB/wEAAUsBvgH/AQABSwG+Af8BmAGkAbAB/wHoAfQC/wP+Af8D8gH/AyEB/wPoAf8DIwH/A+gB/wP+
- Af8D9AH/A/QB/wP0Af8BlAG9AeAB/wEAAU4BxwH/AQABTgHHAf8BAAFOAccB/wFQAa4B2wH/A/UB/wQA
- AcwBrwGIAf8BpQEyAQAB/wGlATIBAAH/AaUBMwEAAf8BogEtAQAB/wHmAdYBuwX/AesB3gHIAf8BowEv
- AQAB/wGlATIBAAH/AaUBMgEAAf8BpQEyAQAB/wHKAa0BhAH/FAADFwH/AwAB/xcAAf8DFwH/MAABBgFL
- Aa4B/wEGAUsBrgH/AR4BRwGdAf8BHgFHAZ0B/wEAAUsBtgH/AQABSwG2Af8BmAGkAbAB/wHoAfQG/wP5
- Af8DjQH/A0gB/wNSAf8D9wX/A/QB/wEAAU4BxwH/AQABTgHHAf8BAAFOAccB/wGUAb0B4AH/AQABTgHH
- Af8BAAFOAccB/wGUAb0B4AH/A/YB/wHyAeoB4QH/AakBOQEAAf8BqgE3AQAB/wGqATcBAAH/AaoBNwEA
- Af8BpwEyAQAB/wHlAdMBtgX/AeoB3AHDAf8BqAE0AQAB/wGqATYBAAH/AaoBNwEAAf8BqgE3AQAB/wGp
- ATgBAAH/AfAB6QHeAf8QAAMXAf8DAAH/FwAB/wMXAf8cAAPfAf8D3wH/DAABBgFLAa4B/wG1AfoC/wHN
- AfYC/wHNAfYC/wEtAagB5gH/AS0BqAHmAf8B6AH0Av8B0wHfAesF/wP9Af8D2wH/AwgB/wPJAf8D+wX/
- A/QB/wEAAU4BxwH/A/QB/wP0Af8D9AH/AZQBvQHgAf8BlAG9AeAB/wP2Af8D/gH/AdYBvgGdAf8BsAE+
- AQAB/wGuATsBAAH/Aa8BPAEAAf8BrwE8AQAB/wGsATcBAAH/AeYB1QG2Bf8B6wHcAcQB/wGtATkBAAH/
- Aa8BOwEAAf8BrwE8AQAB/wGuATwBAAH/Aa8BOwEAAf8B0wG5AZYB/xMAAf8DwAH/FAADwAH/AwAB/xgA
- AdMB3wHrAf8B6AH0Av8B6AH0Av8B0wHfAesB/wgAAR4BRwGdAf8BzQH2Av8ByQH2Av8BSgGkAdEB/wFK
- AaQB0QH/AckB9gL/A+UB/wQACP8D9gH/A/QB/wP0Af8D/QX/A/QB/wEAAU4BxwH/A/QB/wP2Af8BUAGu
- AdsB/wFQAa4B2wH/A/QB/wP8Bf8BygGpAT4B/wHAAY4BAAH/AbUBQwEAAf8BswE/AQAB/wG0AUEBAAH/
- AbIBPQEAAf8B6AHWAbgF/wHsAd4BxQH/AbIBPgEAAf8BtAFAAQAB/wG0AUEBAAH/AbQBQQEAAf8BtQFB
- AQAB/wHEAZ8BKwH/DwAB/wMwAf8cAAMwAf8DAAH/EAAD3wH/AegB9AL/AZgBpAGwAf8BmAGkAbAB/wHo
- AfQC/wPfAf8EAAEeAUcBnQH/Ac0B9gL/AUoBpAHRAf8BGgFHAaEB/wEaAUcBoQH/AUoBpAHRAf8D9AH/
- A98F/wP+Af8D9gH/AVABrgHbAf8BUAGuAdsB/wP1Af8D/QH/A/QB/wEAAU4BxwH/A/QB/wFQAa4B2wH/
- AQABTgHHAf8BAAFOAccB/wFQAa4B2wH/A/UB/wP9Af8ByQGmATUB/wHJAZsBDAH/AcUBlAEFAf8BvgGJ
- AQAB/wG6AYABAAH/AbcBQQEAAf8B6wHZAbsF/wHvAeEByAH/AbcBQwEAAf8BuQFFAQAB/wG5AUUBAAH/
- AbkBRQEAAf8BugFFAQAB/wHDAZoBHwH/EwAB/wPAAf8UAAPAAf8DAAH/EAAB0wHfAesB/wHoAfQC/wEl
- AagB7gH/AQABSwG+Af8BAAFLAb4B/wElAagB7gH/Ac0B9gL/Ac0B9gL/AQYBSwGuAf8BtQH6Av8BJQGo
- Ae4B/wEAAUsBvgH/AQABSwHHAf8BAAFLAccB/wGMAaQBvQH/AdwB9AL/A/4B/wP2Af8BUAGuAdsB/wEA
- AU4BxwH/AQABTgHHAf8BUAGuAdsB/wP0Af8D9AH/AQABTgHHAf8D9AH/AZQBvQHgAf8BAAFOAccB/wEA
- AU4BxwH/AQABTgHHAf8BUAGuAdsB/wP1Af8B0AGvAYEB/wHOAaABEQH/AcsBnAEQAf8BzAGcARAB/wHK
- AZkBCAH/AcMBjQEAAf8B5QHUAbUF/wHnAdgBvAH/Ab4BgwEAAf8BwAGHAQAB/wHBAYgBAAH/AcIBigEA
- Af8BxgGQAQAB/wHMAagBOAH/EAADFwH/AwAB/xcAAf8DFwH/EAAB6AH0Av8BmAGkAbAB/wEAAUsBvgH/
- AQABSwG+Af8BAAFLAb4B/wEAAUsBvgH/AR4BRwGdAf8BHgFHAZ0B/wEGAUsBrgH/AQYBSwGuAf8BAAFL
- Ab4B/wEAAUsBvgH/AQABSwHHAf8BAAFLAccB/wGMAaQBvQH/AdwB9AL/A/YB/wFQAa4B2wH/AQABTgHH
- Af8BAAFOAccB/wEAAU4BxwH/AQABTgHHAf8BUAGuAdsB/wEAAU4BxwH/AQABTgHHAf8BAAFOAccB/wEA
- AU4BxwH/AZQBvQHgAf8BAAFOAccB/wEAAU4BxwH/AZQBvQHgAf8D9gH/Ad0BxwGrAf8B0wGmARoB/wHQ
- AaIBEwH/AdABoQEUAf8B0AGhARQB/wHQAZ8BDwH/AcsBpAEkAf8B1AHDAaUB/wHKAaQBJAH/Ac0BmwEH
- Af8BzgGcAQoB/wHOAZwBCgH/Ac4BnAEJAf8BzwGdAQkB/wHaAcMBogH/EAADFwH/AwAB/xcAAf8DFwH/
- EAAB6AH0Av8BmAGkAbAB/wEAAUsBvgH/AQABSwG+Af8BAAFLAccB/wEAAUsBxwH/AQABSwG+Af8BJQGo
- Ae4B/wHqAfYC/wHqAfYC/wP2Af8D9gH/AYwBpAG9Af8BjAGkAb0B/wP0Af8D3wH/A/cB/wGUAb0B4AH/
- AQABTgHHAf8BAAFOAccB/wEAAU4BxwH/AQABTgHHAf8BAAFOAccB/wFQAa4B2wH/A/QB/wP0Af8D9AH/
- A/QB/wGUAb0B4AH/AZQBvQHgAf8D9gH/A/4B/wH1Ae8B5wH/AdEBqAEoAf8B2AGpARoB/wHVAaYBGgH/
- AdUBpgEYAf8B1AGjARMB/wHlAccBkQH/AfMB6gHYAf8B5wHLAZkB/wHTAaEBDwH/AdMBogESAf8B0wGh
- ARAB/wHVAaMBDwH/Ac0BnQETAf8B9AHtAeQB/xAAA4YB/wMAAf8XAAH/A4YB/xAAAdMB3wHrAf8B6AH0
- Av8BJQGoAe4B/wEAAUsBvgH/AQABSwHHAf8BAAFLAccB/wEAAUsBvgH/AQABSwG+Af8BmAGkAbAB/wHo
- AfQC/wPfAf8D3wH/AdwB9AL/AdwB9AL/A98B/wQAA/4B/wP3Af8BlAG9AeAB/wEAAU4BxwH/AQABTgHH
- Af8BAAFOAccB/wEAAU4BxwH/AQABTgHHAf8BUAGuAdsB/wP1Af8D/QH/A/4B/wP3Af8D9gH/A/4F/wQA
- Ad0ByAGqAf8B3QGyASkB/wHaAasBHQH/AdkBqwEeAf8B1wGnARcB/wHxAeYB0wX/AfUB7gHhAf8B1wGm
- ARcB/wHXAacBFwH/AdgBpwEVAf8B2QGqARoB/wHbAcEBngH/GAADhgH/AwAB/w8AAf8DhgH/GAAD3wH/
- AegB9AL/AZgBpAGwAf8BAAFLAb4B/wEAAUsBvgH/AQABSwG+Af8BAAFLAb4B/wGYAaQBsAH/AegB9AL/
- A98B/wQAA98B/wPfAf8IAAT/A/4B/wP3Af8BlAG9AeAB/wEAAU4BxwH/AQABTgHHAf8BAAFOAccB/wEA
- AU4BxwH/AZQBvQHgAf8D9gH/A/4F/wP+Af8D/gn/BAAB/gL9Af8B2QG/AZoB/wHgAbYBLwH/Ad8BsQEi
- Af8B3AGtAR0B/wHXAbUBQAH/AeIB1QG+Af8B1wG3AYAB/wHbAaoBGQH/Ad4BrgEcAf8B3gGxASQB/wHW
- AbgBjQH/Af4B/QH8Af9QAAHTAd8B6wH/AegB9AL/ASUBqAHuAf8BAAFLAb4B/wEAAUsBvgH/ASUBqAHu
- Af8B6AH0Av8B0wHfAesB/xgACP8D/gH/A/cB/wGUAb0B4AH/AQABTgHHAf8BAAFOAccB/wGUAb0B4AH/
- A/YB/wP+Gf8MAAHfAcsBsQH/AdwBuAFAAf8B4wG4ATEB/wHjAbQBJQH/Ad0BrgEdAf8B4QGyASEB/wHi
- AbYBKwH/AdsBswE3Af8B3gHIAaoB/wL+Af0B/1gAA98B/wHoAfQC/wGYAaQBsAH/AZgBpAGwAf8B6AH0
- Av8D3wH/HAAM/wP+Af8D9wH/AZQBvQHgAf8BlAG9AeAB/wP2Af8D/h3/EAAB9gHxAesB/wHkAdQBvwH/
- Ad4BxQGjAf8B3gHEAZwB/wHeAcQBoQH/AeQB0wG8Af8B9QHvAekB/2QAAdMB3wHrAf8B6AH0Av8B6AH0
- Av8B0wHfAesB/yAAEP8D/gH/A/cB/wP2Af8D/iH/WQABDQG5Af8CAAEuAf8CAAEQAf/1AAEuAccB/wEA
- Ac0B/AH/AQABDwGHAf+0AAM7AWUBAAEEAQAB/wM6AWA1AAEuAccB/wEAAaAB0gH/AQABBQElAf8cAAMB
- AQIDAAEBGwABAQwAASIBIQEiATEDAAEBXAADPgFqAQABpwEAAf8BAAEIAQAB/wEAAQQBAAH/AzYBWDEA
- AS4BxwH/AQAB0QH8Af8BAAEPAYcB/zMAAQEDAAEBEAAB7AHSAewB/wElAQABJAH/AeYBzAHmAf8DAgED
- AxIBGRAAASIBLAEuAf8BGAEgASMB/wEPARQBFwH/AQUBCAELAf8DAAH/AwAB/wMAAf8DAAH/AwAB/xwA
- Az4BagEAAacBAAH/ARwBuwEQAf8BAAEMAQAB/wEAAQkBAAH/AQABBAEAAf8DNQFXLQABLgHHAf8BAAGh
- AdEB/wEAAQUBJQH/PwABAQQAAe0B2AHtAf8BqQEDAagB/wGAAQABMgH/ASgBAAEoAf8B6wHRAesB/xQA
- ASsBggGDAf8BlwHbAfUB/wEOAakBygH/AQ4BqQHKAf8BDQGnAckB/wEFAZ8BwgH/AQABlgG5Af8BAAGN
- AbAB/wMAAf8dAAGkAQAB/wEcAbsBEAH/ARwBuwEQAf8BAAELAQAB/wEAAQwBAAH/AQABCQEAAf8BAAEE
- AQAB/wMwAUwpAAEuAccB/wEEAeIB/QH/AQABCwGAAf8jAAEBAwABAQMAAQEDAAEBAwABAQMAAQEDAAEB
- BAAB6AHRAegB/wGqAQMBqQH/AcwBGgHLAf8BMQEAATEB/wGWAQABlQH/AS4BAAEtAf8B8AHVAfAB/xAA
- ATMCjAH/AaAB4AH3Af8BJAHNAfEB/wEXAccB7gH/AQsBwQHrAf8BAAG8AegB/wEAAbcB5gH/AQABkgG2
- Af8DAAH/HQABpwEAAf8BHAG7ARAB/wEcAbsBEAH/AaoB1AGiAf8BAAGgAQAB/wEAAQwBAAH/AQABCQEA
- Af8BAAEDAQAB/ykAAS4BxwH/AQsB1wH8Af8BAAELAYAB/yQAAasB8AH3Af8BqwHiAeUB/wGsAc4BzAH/
- Aa0BuwG1Af8BrgGnAZwB/wQAAeQBygHkAf8BqQEDAagB/wHTAR4B0gH/AdQBIQHTAf8BMgEAATEB/wGf
- AQABnwH/AY4BAAGNAf8BMAEAAS8B/xAAAYUClAH/AacB4wH4Af8BLwHTAfQB/wEkAc4B8QH/ARgByAHu
- Af8BCwHCAesB/wEAAbwB6AH/AQABmQG8Af8DAAH/GAADAgEDAQEBqwEAAf8BHAG7ARAB/wGqAdQBogH/
- AbcB2gGwAf8BqgHUAaIB/wEAAZMBAAH/AQABDAEAAf8BAAEEAQAB/yUAARMBkAH/AQABLgHHAf8BIQHe
- AfwB/wEAAQsBgAH/AQABAQEtAf84AAGqAQUBqQH/AdIBHQHRAf8B1QEiAdUB/wG9ASMBvAH/Ad4BmAHd
- Af8BjwEAAY4B/wGdAQABnAH/ATEBAAExAf8QAAGMApsB/wGuAeYB+gH/AYYB2AH2Af8BLwHUAfQB/wEk
- Ac0B8QH/ARgBxwHuAf8BCwHCAesB/wEGAaABwQH/AwAB/xgAAwQBBQEWAbgBCQH/AbQB2QGtAf8BxQHi
- AcAB/wG3AdoBsAH/AbcB2gGwAf8BqgHUAaIB/wEAAYgBAAH/AQABBAEAAf8hAAEiAaAB/wEAAYcBxwH/
- AQ4BwAHwAf8BAwHLAf4B/wEEAbMB3QH/AgABGQH/AQABAQEtAf8YAAGrAfAB9wH/AasB5QHpAf8BrALV
- Af8BrAHEAcEB/wGtAbUBrAH/Aa4BpAGYAf8EAAGoAQIBpwH/AdIBIAHRAf8BvAEiAbsB/wHvAaUB7gH/
- AfsBnwH6Af8B7wGdAe4B/wGXAQUBlgH/AS8BAAEvAf8QAAGRAaIBoQH/AbIB6AH8Af8BoAHiAfoB/wGG
- AdgB9gH/ATAB0wHzAf8BJAHOAfEB/wEXAcgB7gH/AQoBpQHHAf8CAAEFAf8YAAMCAQMDRAF6AY4BxgGE
- Af8BuQHcAbMB/wHDAeEBvgH/AcMB4QG+Af8BtwHaAbAB/wGqAdQBogH/AQABGgEAAf8dAAGAAbEB/wEA
- AYcByAH/AQUBugH3Af8BBwHCAfkB/wEAAbcB+QH/ARsB1gH7Af8BAAGmAegB/wIAARcB/wEAAQQBgwH/
- MAABpwEDAaYB/wG8ASIBuwH/Ae8BpQHuAf8B+wGbAfoB/wH7AZgB+gH/AfsBmQH6Af8B5wGYAeYB/wGR
- AQEBkAH/EAABlAGmAaUB/wG9AewB/AH/AaUB5QH7Af8BnwHiAfoB/wGGAdgB9gH/ATAB1AH0Af8BJAHN
- AfEB/wEOAakBygH/AQcBCwEOAf8gAANGAX4BkAHHAYYB/wG+Ad4BuAH/AcMB4QG+Af8BswHZAawB/wGQ
- AccBhgH/Az0BaR0AAS4BuAH/AQcBwQH5Af8BAwG3AfkB/wGTAe4B/gH/AY8B7AH+Af8BBQG0AfMB/wGN
- AeMB/gH/AQIBugHiAf8BAAEBAR4B/xwAAasB8AH3Af8BrALVAf8BrgG0AawB/wGuAZkBigH/A/0B/wHP
- AYgBzwH/AeIBrwHiAf8B+wGrAfoB/wH7AZgB+gH/AfsBmAH6Af8B6gGQAekB/wHPAYgBzwH/AfQB5gH0
- Af8QAAGUAaYBpQH/Ab0B7AH8Af8BvQHsAfwB/wGyAegB/AH/Aa4B5gH6Af8BpwHkAfkB/wGgAeAB9wH/
- AZcB2wH1Af8BEAEVARkB/yQAA0cBgQGUAckBigH/Ab0B3gG3Af8BjgHGAYQB/wMwAUshAAGDAbsB/wEM
- AcYB+QH/ARwBigGsAf8BHAGKAawB/wEcAYoBrAH/ARwBigGsAf8BHAGKAawB/wEVAdUB+gH/AgABGwH/
- MAAB8AHUAfAB/wHPAYgBzwH/Ae4BvgHuAf8B+wGuAfoB/wHsAZEB6wH/Ac8BiAHPAf8B8wHgAfIB/xQA
- AZQBpgGlAf8BlAGmAaUB/wGTAqUB/wGPAZ8BngH/AYgClwH/AYECjgH/ASwChAH/ASIBLAEuAf8BGQEg
- ASIB/ygAAzwBZgGUAckBigH/AyUBNyUAAYMBvAH/AQ8B0gH6Af8BAAEXAYQB/w0AAZABwQH/AQYBuwHh
- Af8CAAEYAf80AAHyAdsB8gH/Ac8BiAHPAf8B4wGsAeMB/wHPAYgBzwH/AfMB4wHzAf9gAAMBAQIEAAMB
- AQIpAAGIAcEB/wEAAZ0B0AH/AS0B4wH6Af8BAAGFAZ4B/wEEARcBhwH/AQQBKQGcAf8BBQG/AfQB/wEA
- AYwBqgH/AQABCwEtAf84AAHyAdsB8gH/Ac8BiAHPAf8B8AHjAfAB/5kAAZQBxgH/AQABigHBAf8BAAGa
- Ac0B/wEhAdUB9QH/ASQB6QH+Af8BIAHUAfMB/wEAAZIBsgH/AQABFwGMAf8BAAEjAaIB/zwAAf4B+wH+
- Af+hAAGUAcYB/wEAAY0BwwH/AQABiwG6Af8BAAGLAboB/wEAAYgBtwH/AQABJgGgAf8BAAGCAbIB//8A
- qQADNgFYAZkCAAH/AzMBU/AAAzgBXQHXAZoBAAH/AZkCAAH/AZkCAAH/Ay8BSiwAAx4BKwNUAa4BWQJk
- AewBAAGDAZYB/wEAARkBjQH/AQABEAGMAf8BTgJdAfADVgGzAyUBN5gAAzoBYQHXAZoBAAH/AdgBmwEA
- Af8BmQIAAf8BmQIAAf8BmQIAAf8DLwFKKAABWwJeAdABAAGwAdEB/wGEAdUB6AH/AaEB6wH2Af8BFgHk
- Av8BAAG+AfMB/wEAAZ8B3gH/AQABiwG+Af8BWwJeAdlUAAG3AaIBkwH/AQYCAAH/AQYCAAH/AQYCAAH/
- AQYCAAH/AQYCAAH/AQYCAAH/AQYCAAH/AQYCAAH/AQYCAAH/AQYCAAH/AQYCAAH/FAAB2AGbAQAB/wHY
- AZsBAAH/AdgBmwEAAf8BmQIAAf8BmQIAAf8BmQIAAf8BmQIAAf8DLwFKJQABjwGqAf8BAAHXAv8BkAHq
- AfoB/wGhAesB9gH/ARQB2QH0Af8BAAG8AfIB/wEAAacB6AH/AQABnAHaAf8BAAEGAYQB/xQAAzEBTQJS
- AVEBoQFfAlgB4wFfAlgB4wFSAlEBoQExAjABTQQAAzEBTQJSAVEBoQFfAlgB4wFfAlgB4wFSAlEBoQEx
- AjABTQwAAbcBogGTAf8B/QH7AfkB/wHhAdwB2AH/AeAB1wHSAf8B3wHOAcMB/wHdAcgBuwH/AdsBvwGt
- Af8B2wG7AacB/wHbAbsBpwH/AdsBuwGnAf8BzwG0AaMB/wEGAgAB/xQAAdgBmwEAAf8B2AGbAQAB/wHp
- AbQBHwH/AfwB1gGvAf8BtQEGAQAB/wGZAgAB/wGZAgAB/wGZAgAB/wMvAUohAAGRAa4B/wEAAdIB+gH/
- AY0B5AH2Af8BoQHrAfYB/wETAdcB8wH/AQABuQHvAf8BAAGnAegB/wEAAZwB2gH/AQABCAGGAf8QAAM1
- AVUDZAHnAc8BuAGpAf8B6wHWAcgB/wHlAcsBuwH/AbMBlQEiAf8BZAJcAecDSwGOA2QB5wHPAbgBqQH/
- AesB1gHIAf8B5QHLAbsB/wGzAZUBIgH/AWQCXAHnATUCNAFVCAABtwGiAZMB/wP+Af8BugGmAZgB/wG1
- AaABkQH/AfsB7AHjAf8BpAGNASEB/wGaAYMBFQH/AfYB1gHCAf8BiAEUAQEB/wGDAQ4BAAH/Ac8BtAGj
- Af8BBgIAAf8UAAHYAZsBAAH/AeoBtwGCAf8B+wHYAbIB/wH+AdEBowH/AfsB2AGyAf8BrwIAAf8BmQIA
- Af8BmQIAAf8BmQIAAf8DKgFBHQABlQGwAf8BAAHSAfoB/wGNAeQB9AH/AaEB6wH2Af8BEwHXAfIB/wEA
- AbkB7gH/AQABpwHoAf8BAAGcAdoB/wEAAQsBiAH/EAADVQGyAeYB1gHLAf8DWQHCAmABXAHUA2AB1AFM
- ASoBIQH7AwAB/wMAAf8DAAH/AWECWAHmAmABXAHUA2AB1ANZAcIBuQGcAYgB/wNVAbIIAAG6AaUBlgH/
- A/4B/wP+Af8D/gH/Af0B+wH5Af8B/QH3AfMB/wH7AewB4wH/AfoB5wHbAf8B+AHhAdIB/wH3AdsByQH/
- AdABuQGrAf8BBgIAAf8UAAHnAbMBHwH/AfEBwwGRAf8B/gHPAZ0C/wHNAZkB/wH+AdABnwH/AfsB2AGy
- Af8BqQIAAf8BmQIAAf8BmQIAAf8BmQIAAf8DBAEFGQABmQG1Af8BAAHRAfsB/wGOAeQB9QH/AaEB6wH2
- Af8BEwHXAfIB/wEAAbkB7gH/AQABpwHoAf8BAAGcAdoB/wEAAQ4BigH/EAADZQH0BP8DVwHfAx0BKgNc
- Ac0F/wH+AfcC/wHxAeYB/wH6AeMB1AH/AfMB1wHHAf8DSgGNAx0BKgNcAd8B7wHWAccB/wFkAlIB9AgA
- Ab4BqQGaAf8D/gH/AboBpgGYAf8BtAGgAZEB/wP+Af8BowGOASEB/wGaAYMBFQH/AfsB7AHjAf8BiQEU
- AQIB/wGDAQ4BAAH/AdEBwQG2Af8BBgIAAf8UAANFAXwB5QGyAR4B/wH0AcABiwL/Ac0BmQL/Ac0BmQH/
- Af4B0AGhAf8B+wHYAbIB/wGpAgAB/wGZAgAB/wGZAgAB/x0AAZsBtwH/AQAB0AH5Af8BjQHjAfUB/wGh
- AesB9gH/ARUB2QHyAf8BAAG5Ae4B/wEAAacB6AH/AQABnAHaAf8BAAEQAY0B/xAAA1UBsgHyAeYB3gH/
- A1kBwgNcAdQBYAJcAdQDYQHiAdMBtQGiAf8DTQH6AdoBwAGvAf8DXwHzA1sB1gFgAlwB1ANZAcIBywGx
- AaEB/wNVAbIIAAHDAa4BngH/A/4B/wP+Af8D/gH/A/4B/wP+Af8B/QH3AfMB/wH8AfIB7AH/AfsB7AHj
- Af8B+gHnAdsB/wHRAcEBtgH/AQYCAAH/GAADRgF/AeQBsAEcAf8B9gHEAZAC/wHNAZkC/wHNAZkB/wH+
- AdABoQH/AfsB2AGyAf8BqQIAAf8BmQIAAf8cAAEBAZ4BugH/AQAB0AH5Af8BjQHjAfQB/wGhAesB9gH/
- ARIB1wHyAf8BAAG3Ae4B/wEAAacB6AH/AQABnAHaAf8BAAESAY8B/xAAAzUBVQNkAecB7QHhAdcD/wH9
- Av8B9wHxAf8B2AHEAbcB/wNkAecDSwGOA2QB5wHtAeEB1wP/Af0C/wH3AfEB/wHYAcQBtwH/A2QB5wM1
- AVUIAAHIAbIBowH/A/4B/wG6AaYBmAH/AbQBoAGRAf8D/gH/AaQBjgEhAf8BmQGEARUB/wH9AfcB8wH/
- AYgBFAEBAf8BgwEOAQAB/wHRAcEBtgH/AQYCAAH/HAADSQGHAeMBrwEbAf8B9gHEAZAC/wHNAZkC/wHN
- AZkB/wH+AdABoQH/AfIByQGdAf8BsAIAAf8cAAECAaIBvAH/AQABzgH3Af8BiwHjAfQB/wGhAesB9gH/
- AREB1gHyAf8BAAG3Ae4B/wEAAacB6AH/AQABnAHaAf8BAAETAZIB/xQAAzEBTQNSAaEDXwHjA18B4wNS
- AaEDMQFNBAADMQFNA1IBoQNfAeMDXwHjA1IBoQMxAU0MAAHMAbYBpwH/A/4B/wP+Af8D/gH/A/4B/wP+
- Af8D/gH/Af0B+wH5Af8B/QH3AfMB/wH8AfIB7AH/AfsB7AHjAf8BBgIAAf8gAANJAYcB4wGvARsB/wH2
- AcQBkAL/Ac0BmQH/AfMBwgGOAf8B4wGwARwB/wNDAXgcAAEOAakBwAH/AQAB1AH6Af8BnAHsAfoB/wGr
- Ae8B+gH/AaYB7QH4Af8BlAHnAfgB/wEUAdkB9gH/AQABvQHpAf8BAAEfAZcB/1QAAeoBqgGLAf8B6gGq
- AYsB/wHqAaoBiwH/AekBpQGEAf8B5wGXAREB/wHmAY4BBQH/AeMBIAEAAf8B4wEZAQAB/wHiARUBAAH/
- AeIBFQEAAf8B4gEVAQAB/wHIAQUBAAH/JAADSQGHAeMBrwEbAf8B7gG9AYoB/wHjAbABHAH/AzQBVCAA
- AYABswHFAf8BmwHeAesB/wHFAfkB/QH/AcUB+QH9Af8BxQH5Af0B/wHFAfkB/QH/AcUB+QH9Af8BoAHf
- AeoB/wEJAZEBogH/VAAB6gGqAYsC/wHCAaIB/wH+AcABnwH/Af0BvQGaAf8B+wG1AZAB/wH6AbABiwH/
- AfgBpwEgAf8B9gGiARoB/wH1AZ0BFAH/AfUBmQENAf8B8wGVAQgB/wHNAQgBAAH/KAADQAFuAeUBsgEg
- Af8DJgE4JAADOwFjA2AB1gEZAasBugH/ARMBowGzAf8BDwGdAa8B/wEOAZsBrgH/ARIBogG0Af8DXgHZ
- A0ABb1QAAeoBqgGLAf8B6gGqAYsB/wHqAaoBiwH/AeoBqgGLAf8B6QGhASIB/wHoAZsBGQH/AeYBjgEF
- Af8B5QGHAQAB/wHkAYEBAAH/AeQBHgEAAf8B4wEZAQAB/wHiARUBAAH//wD/AAoAAUIBTQE+BwABPgMA
- ASgDAAFAAwABQAMAAQEBAAEBBgABAhYAA/+BAAX/AcMCAAHwAR8D/wGBAgABwAEHAfMBnwH/AwABgAED
- AecBzwH/AcACAAGAAQMB5wHPAf8EAAEBAecBzwHnBAABAQHnAc8BwwEBAwABAQHPAecBgQQAAQEB5wHP
- BQABAQHnAc8FAAEBAecBzwUAAQEB5wHPAQABAQIAAYABAwHzAZ8BgAETAgABgAEDAv8BwAE/AgAB4AEH
- Av8B4AF/AgAB8AEfAv8B8AH/AgAC/wH8AX8G/wH8AX8E/wH8AX8B/AF/AT8BcwL/AfgBPwH8AX8B+QHg
- AfABBwHwAR8B/AF/Af8BQQHwAQcB8AEPAfwBfwKAAfABBwHwAQ8B/AF/AcEBAAHwAQcB4AEPAfgBPwH/
- AQAB8AEHAeABDwHwAR8BgQEAAfABBwHgAQ8B4AEPAf8BAAHwAQcB+AEPAeABDwHgAQAB8AEHAfwBHwHg
- AQ8B/wEBAfABBwH+AT8B4wGPAf8BgwL/Af0BfwHgAQ8B/wHHBP8B4AEPAf8B7wT/AfABHwz/AfgH/wHw
- AX8B8AEHBP8B4AE/AfABBwL/AcABAwHgAR8B8AEHAcABgQHAAQMB4AEPAfABBwGAAQABwAEDAeABBwHw
- AQcBgAEAAcABAwHgAQMB8AEHAYABAAHAAQMB4AEHAfABBwGAAQABwAEDAfABBwHwAQcBgAEAAcABAwH4
- AQcB8AEHAcABgQHAAQMB/AEHAfABBwL/AcABAwH+AQ8B8AEHAv8BwAEDAf8BHwHwAQcC/wHAAQMQ/ws=
diff --git a/Src/SwqlStudio/ObjectExplorer/IMetadataProvider.cs b/Src/SwqlStudio/Metadata/IMetadataProvider.cs
similarity index 88%
rename from Src/SwqlStudio/ObjectExplorer/IMetadataProvider.cs
rename to Src/SwqlStudio/Metadata/IMetadataProvider.cs
index 1bbe11b9b..a65538de1 100644
--- a/Src/SwqlStudio/ObjectExplorer/IMetadataProvider.cs
+++ b/Src/SwqlStudio/Metadata/IMetadataProvider.cs
@@ -1,8 +1,7 @@
using System;
using System.Collections.Generic;
-using SwqlStudio.Metadata;
-namespace SwqlStudio
+namespace SwqlStudio.Metadata
{
interface IMetadataProvider
{
diff --git a/Src/SwqlStudio/Metadata/ITypedMetadata.cs b/Src/SwqlStudio/Metadata/ITypedMetadata.cs
new file mode 100644
index 000000000..9b52685bb
--- /dev/null
+++ b/Src/SwqlStudio/Metadata/ITypedMetadata.cs
@@ -0,0 +1,9 @@
+namespace SwqlStudio.Metadata
+{
+ public interface ITypedMetadata
+ {
+ string Name { get; set; }
+ string Type { get; set; }
+ string Summary { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/Src/SwqlStudio/Metadata/Property.cs b/Src/SwqlStudio/Metadata/Property.cs
index ab4aac946..2c9d7d7eb 100644
--- a/Src/SwqlStudio/Metadata/Property.cs
+++ b/Src/SwqlStudio/Metadata/Property.cs
@@ -1,7 +1,7 @@
namespace SwqlStudio.Metadata
{
- public class Property
+ public class Property : ITypedMetadata
{
public string Name { get; set; }
public string Type { get; set; }
diff --git a/Src/SwqlStudio/ObjectExplorer/SwisMetaDataProvider.cs b/Src/SwqlStudio/Metadata/SwisMetaDataProvider.cs
similarity index 98%
rename from Src/SwqlStudio/ObjectExplorer/SwisMetaDataProvider.cs
rename to Src/SwqlStudio/Metadata/SwisMetaDataProvider.cs
index fa4988b1e..c3eae838f 100644
--- a/Src/SwqlStudio/ObjectExplorer/SwisMetaDataProvider.cs
+++ b/Src/SwqlStudio/Metadata/SwisMetaDataProvider.cs
@@ -2,9 +2,8 @@
using System.Collections.Generic;
using System.Data;
using System.Linq;
-using SwqlStudio.Metadata;
-namespace SwqlStudio
+namespace SwqlStudio.Metadata
{
class SwisMetaDataProvider : IMetadataProvider
{
diff --git a/Src/SwqlStudio/Metadata/VerbArgument.cs b/Src/SwqlStudio/Metadata/VerbArgument.cs
index 1fe7f2b29..25e9498a7 100644
--- a/Src/SwqlStudio/Metadata/VerbArgument.cs
+++ b/Src/SwqlStudio/Metadata/VerbArgument.cs
@@ -1,6 +1,6 @@
namespace SwqlStudio.Metadata
{
- public class VerbArgument
+ public class VerbArgument : ITypedMetadata
{
public string Name { get; set; }
diff --git a/Src/SwqlStudio/ObjectExplorer/ArgumentsPlaceholderTreeNode.cs b/Src/SwqlStudio/ObjectExplorer/ArgumentsPlaceholderTreeNode.cs
new file mode 100644
index 000000000..99ffc8915
--- /dev/null
+++ b/Src/SwqlStudio/ObjectExplorer/ArgumentsPlaceholderTreeNode.cs
@@ -0,0 +1,17 @@
+using System.Windows.Forms;
+using SwqlStudio.Metadata;
+
+namespace SwqlStudio
+{
+ internal class ArgumentsPlaceholderTreeNode : TreeNode
+ {
+ public Verb Verb { get; set; }
+ public IMetadataProvider Provider { get; set; }
+
+ public ArgumentsPlaceholderTreeNode(Verb verb, IMetadataProvider provider)
+ {
+ Verb = verb;
+ Provider = provider;
+ }
+ }
+}
\ No newline at end of file
diff --git a/Src/SwqlStudio/ObjectExplorer/Documentation.cs b/Src/SwqlStudio/ObjectExplorer/Documentation.cs
new file mode 100644
index 000000000..fe1bd3e6e
--- /dev/null
+++ b/Src/SwqlStudio/ObjectExplorer/Documentation.cs
@@ -0,0 +1,16 @@
+namespace SwqlStudio
+{
+ internal class Documentation
+ {
+ public string ItemType { get; set; }
+ public string Documents { get; set; }
+
+ public static readonly Documentation Empty = new Documentation(string.Empty, string.Empty);
+
+ public Documentation(string itemType, string documents)
+ {
+ this.ItemType = itemType;
+ this.Documents = documents;
+ }
+ }
+}
\ No newline at end of file
diff --git a/Src/SwqlStudio/ObjectExplorer/DocumentationBuilder.cs b/Src/SwqlStudio/ObjectExplorer/DocumentationBuilder.cs
new file mode 100644
index 000000000..b45efaa8c
--- /dev/null
+++ b/Src/SwqlStudio/ObjectExplorer/DocumentationBuilder.cs
@@ -0,0 +1,141 @@
+using System;
+using System.Text;
+using System.Windows.Forms;
+using SwqlStudio.Metadata;
+
+namespace SwqlStudio
+{
+ internal class DocumentationBuilder
+ {
+ public static Documentation Build(TreeNode node)
+ {
+ var data = node.Tag;
+ var connectedNode = node as TreeNodeWithConnectionInfo;
+ var provider = connectedNode?.Provider;
+
+ if (provider == null)
+ return Documentation.Empty;
+
+ if (data is SwisMetaDataProvider)
+ return ProviderDocumentation(provider);
+
+ if (data is string nameSpace)
+ return NamespaceDocumentation(nameSpace, node.Nodes.Count);
+
+ if (data is Entity entity)
+ return EntityDocumentation(provider, entity);
+
+ if (data is Property property)
+ return PropertyDocumentation(property);
+
+ if (data is Verb verb)
+ return VerbDocumentation(verb);
+
+ if (data is VerbArgument verbArg)
+ return VerbArgumentDocumentation(verbArg);
+
+ return Documentation.Empty;
+ }
+
+ private static Documentation VerbArgumentDocumentation(VerbArgument verbArg)
+ {
+ var docs = MetadataDocumentation(verbArg);
+ return new Documentation("Verb argument", docs);
+ }
+
+ private static Documentation VerbDocumentation(Verb verb)
+ {
+ var builder = new StringBuilder();
+ builder.AppendName(verb.Name);
+ builder.AppendSummaryParagraph(verb.Summary);
+ var docs = builder.ToString();
+ return new Documentation("Verb", docs);
+ }
+
+ private static Documentation EntityDocumentation(IMetadataProvider provider, Entity entity)
+ {
+ var builder = new StringBuilder();
+ builder.AppendName(entity.FullName);
+ builder.Append($"Base type: {entity.BaseType}\r\n");
+ builder.AppendAccessControl(provider.ConnectionInfo, entity);
+ builder.AppendSummaryParagraph(entity.Summary);
+ var docs = builder.ToString();
+ return new Documentation("Entity", docs);
+ }
+
+ private static Documentation NamespaceDocumentation(string nameSpace, int childrenCount)
+ {
+ var builder = new StringBuilder();
+ builder.AppendName(nameSpace);
+ var children = ChildrenText(childrenCount);
+ builder.Append(children);
+ var docs = builder.ToString();
+ return new Documentation("Namespace", docs);
+ }
+
+ private static Documentation PropertyDocumentation(Property property)
+ {
+ var docs = MetadataDocumentation(property);
+ return new Documentation("Property", docs);
+ }
+
+ private static Documentation ProviderDocumentation(IMetadataProvider provider)
+ {
+ var documents = $@"Connection: {provider.Name}";
+ return new Documentation("Database", documents);
+ }
+
+ private static string MetadataDocumentation(ITypedMetadata metadata)
+ {
+ var builder = new StringBuilder();
+ builder.AppendName(metadata.Name);
+ builder.AppendType(metadata.Type);
+ builder.AppendSummaryParagraph(metadata.Summary);
+ return builder.ToString();
+ }
+
+ public static string ToToolTip(ITypedMetadata metadata)
+ {
+ var builder = new StringBuilder();
+ builder.AppendSummary(metadata.Summary);
+ return builder.ToString();
+ }
+
+ public static string ToToolTip(ConnectionInfo connection, Entity entity)
+ {
+ var builder = new StringBuilder();
+ builder.AppendSummary(entity.Summary);
+ return builder.ToString();
+ }
+
+ public static string ToToolTip(Verb verb)
+ {
+ var builder = new StringBuilder();
+ builder.AppendSummary(verb.Summary);
+ return builder.ToString();
+ }
+
+ public static string ToNodeText(string name, int childrenCount)
+ {
+ var children = ChildrenText(childrenCount);
+ return $"{name} ({children})";
+ }
+
+ private static string ChildrenText(int childrenCount)
+ {
+ var countSuffix = childrenCount > 1 ? "s" : String.Empty;
+ return $"{childrenCount} item{countSuffix}";
+ }
+
+ public static string ToNodeText(ITypedMetadata metadata)
+ {
+ return $"{metadata.Name} ({metadata.Type})";
+ }
+
+ public static string ToBaseNodeText(TreeNode baseNode, int childrenCount)
+ {
+ var entitiesSuffix = childrenCount > 1 ? "ies" : "y";
+ return $"{baseNode.Text} ({childrenCount} derived entit{entitiesSuffix})";
+ }
+ }
+}
\ No newline at end of file
diff --git a/Src/SwqlStudio/ObjectExplorer/EntityGroupingMode.cs b/Src/SwqlStudio/ObjectExplorer/EntityGroupingMode.cs
new file mode 100644
index 000000000..5270b3103
--- /dev/null
+++ b/Src/SwqlStudio/ObjectExplorer/EntityGroupingMode.cs
@@ -0,0 +1,10 @@
+namespace SwqlStudio
+{
+ internal enum EntityGroupingMode
+ {
+ Flat = 1,
+ ByNamespace = 2,
+ ByBaseType = 3,
+ ByHierarchy = 4
+ }
+}
\ No newline at end of file
diff --git a/Src/SwqlStudio/ObjectExplorer/ImageKeys.cs b/Src/SwqlStudio/ObjectExplorer/ImageKeys.cs
new file mode 100644
index 000000000..def13677d
--- /dev/null
+++ b/Src/SwqlStudio/ObjectExplorer/ImageKeys.cs
@@ -0,0 +1,53 @@
+using SwqlStudio.Metadata;
+
+namespace SwqlStudio
+{
+ internal class ImageKeys
+ {
+ internal const string Database = "Database";
+ internal const string Namespace = "Namespace";
+ internal const string Verb = "Verb";
+ internal const string Argument = "Argument";
+
+ internal const string BaseTypeAbstract = "BaseTypeAbstract";
+ internal const string BaseType = "BaseType";
+
+ internal const string Indication = "Indication";
+ internal const string TableAbstract = "TableAbstract";
+ internal const string TableCrud = "TableCrud";
+ internal const string Table = "Table";
+
+ internal const string Column = "Column";
+ internal const string Link = "Link";
+ internal const string KeyColumn = "KeyColumn";
+ internal const string InheritedColumn = "InheritedColumn";
+
+ public static string GetImageKey(Entity entity)
+ {
+ if (entity.IsIndication)
+ return Indication;
+
+ if (entity.IsAbstract)
+ return TableAbstract;
+
+ if (entity.CanCreate || entity.CanDelete || entity.CanUpdate)
+ {
+ return TableCrud;
+ }
+
+ return Table;
+ }
+
+ public static string GetImageKey(Property property)
+ {
+ if (property.IsNavigable)
+ return Link;
+ if (property.IsKey)
+ return KeyColumn;
+ if (property.IsInherited)
+ return InheritedColumn;
+
+ return Column;
+ }
+ }
+}
\ No newline at end of file
diff --git a/Src/SwqlStudio/ObjectExplorer/ObjectExplorer.cs b/Src/SwqlStudio/ObjectExplorer/ObjectExplorer.cs
index d7cc3feb2..9b66e815e 100644
--- a/Src/SwqlStudio/ObjectExplorer/ObjectExplorer.cs
+++ b/Src/SwqlStudio/ObjectExplorer/ObjectExplorer.cs
@@ -17,21 +17,13 @@
namespace SwqlStudio
{
- enum EntityGroupingMode
- {
- Flat = 1,
- ByNamespace = 2,
- ByBaseType = 3,
- ByHierarchy = 4
- }
-
- class ObjectExplorer : Control
+ internal class ObjectExplorer : Control
{
private static readonly Log log = new Log();
private readonly SearchTextBox _treeSearch;
private readonly TreeView _tree;
- private readonly TreeView _treeData;
+ private TreeView _treeData;
private TreeNodeUtils.TreeNodeBindings _treeBindings = new TreeNodeUtils.TreeNodeBindings(); // default value, so this field is never null
private TreeNode _contextMenuNode;
private readonly Dictionary _tableContextMenuItems;
@@ -42,15 +34,18 @@ class ObjectExplorer : Control
private string _filter;
private bool _treeIsUnderUpdate;
private Point _lastLocation;
+ private ImageList objectExplorerImageList;
+ private System.ComponentModel.IContainer components;
private TreeNode _dragNode;
-
+ private readonly TreeNodesBuilder treeNodesBuilder = new TreeNodesBuilder();
+ public event TreeViewEventHandler SelectionChanged;
public ITabsFactory TabsFactory { get; set; }
- public EntityGroupingMode EntityGroupingMode { get; set; }
-
public ObjectExplorer()
{
+ InitializeComponent();
+
_treeSearch = new SearchTextBox
{
Dock = DockStyle.Top
@@ -63,18 +58,41 @@ public ObjectExplorer()
ShowNodeToolTips = true
};
+ InitializeTreeview();
+
+ _treeSearch.TextChangedWithDebounce += (sender, e) => { SetFilter(((TextBox) sender).Text); };
+ _treeSearch.CueText = "Search (Ctrl + \\)";
+ _treeSearch.DebounceLimit = TimeSpan.FromMilliseconds(400);
+
+ _tableContextMenuItems = new Dictionary();
+ _serverContextMenuItems = new Dictionary();
+ _tableCrudContextMenuItems = new Dictionary();
+
+ _verbContextMenu = new ContextMenu();
+ _verbContextMenu.MenuItems.Add("Invoke...", (s, e) => OpenInvokeTab());
+
+ Controls.Add(_tree);
+ Controls.Add(_treeSearch);
+ }
+
+ private void InitializeTreeview()
+ {
_treeData = new TreeView();
_tree.MouseDown += TreeMouseDown;
_tree.MouseMove += TreeMouseMove;
_tree.MouseUp += _tree_MouseUp;
- _tree.BeforeExpand += (sender, e) => { e.Cancel = !AllowExpandCollapse; if (!e.Cancel) _tree_BeforeExpand(sender, e); };
+ _tree.BeforeExpand += (sender, e) =>
+ {
+ e.Cancel = !AllowExpandCollapse;
+ if (!e.Cancel) _tree_BeforeExpand(sender, e);
+ };
_tree.BeforeCollapse += (sender, e) => { e.Cancel = !AllowExpandCollapse; };
// copy expanded / not expanded state to data, so it is persisted
_tree.AfterExpand += (sender, e) =>
{
if (_treeIsUnderUpdate) // we are calling expand on the display tree when cloning from data.
- // we do not want to update data with such information, as we dont have proper _treeBindings at the moment
+ // we do not want to update data with such information, as we dont have proper _treeBindings at the moment
return;
var dataNode = _treeBindings.FindDataNode(e.Node);
@@ -91,19 +109,13 @@ public ObjectExplorer()
};
_tree.NodeMouseDoubleClick += _tree_NodeMouseDoubleClick;
- _treeSearch.TextChangedWithDebounce += (sender, e) => { SetFilter(((TextBox) sender).Text); };
- _treeSearch.CueText = "Search (Ctrl + \\)";
- _treeSearch.DebounceLimit = TimeSpan.FromMilliseconds(400);
-
- _tableContextMenuItems = new Dictionary();
- _serverContextMenuItems = new Dictionary();
- _tableCrudContextMenuItems = new Dictionary();
-
- _verbContextMenu = new ContextMenu();
- _verbContextMenu.MenuItems.Add("Invoke...", (s, e) => OpenInvokeTab());
+ _tree.AfterSelect += OnTreeOnAfterSelect;
+ _tree.ImageList = this.objectExplorerImageList;
+ }
- Controls.Add(_tree);
- Controls.Add(_treeSearch);
+ private void OnTreeOnAfterSelect(object sender, TreeViewEventArgs args)
+ {
+ this.SelectionChanged?.Invoke(this, args);
}
public void FocusSearch()
@@ -293,23 +305,15 @@ private void TreeMouseMove(object sender, MouseEventArgs e)
void _tree_BeforeExpand(object sender, TreeViewCancelEventArgs e)
{
- if (e.Node.Tag is Verb verb)
+ var verbNode = e.Node;
+ if (verbNode.Tag is Verb)
{
- e.Node.Nodes.Clear();
-
- foreach (var arg in FindProvider(e.Node).GetVerbArguments(verb))
- {
- string text = $"{arg.Name} ({arg.Type})";
- var argNode = new TreeNode(text) { SelectedImageKey = "Argument" };
- argNode.ImageKey = argNode.SelectedImageKey;
- argNode.Tag = arg;
- if (!string.IsNullOrEmpty(arg.Summary))
- argNode.ToolTipText = arg.Summary;
- e.Node.Nodes.Add(argNode);
- }
+ var provider = FindProvider(verbNode);
+ TreeNodesBuilder.RebuildVerbArguments(verbNode, provider);
}
}
+
void _tree_NodeMouseDoubleClick(object sender, TreeNodeMouseClickEventArgs e)
{
if (e.Node.Tag != null)
@@ -334,14 +338,11 @@ void _tree_NodeMouseDoubleClick(object sender, TreeNodeMouseClickEventArgs e)
private IMetadataProvider FindProvider(TreeNode node)
{
- var provider = node.Tag as IMetadataProvider;
- if (provider != null)
- return provider;
+ var providerNode = node as TreeNodeWithConnectionInfo;
+ if (providerNode?.Provider != null)
+ return providerNode.Provider;
- if (node.Parent == null)
- throw new InvalidOperationException("No IMetadataProvider found in tree.");
-
- return FindProvider(node.Parent);
+ throw new InvalidOperationException("No IMetadataProvider found in tree.");
}
public void RefreshAllServers()
@@ -377,12 +378,11 @@ private void RefreshServer(TreeNode node)
provider.Refresh();
BeginInvoke(new Action(() =>
{
- node.Nodes.Clear();
var treeNodeWithConnectionInfo = node as TreeNodeWithConnectionInfo;
if (treeNodeWithConnectionInfo != null)
- AddTablesToNode(node, provider, treeNodeWithConnectionInfo.Connection);
+ this.treeNodesBuilder.RebuildDatabaseNode(node, provider);
else
- AddTablesToNode(node, provider, null);
+ node.Nodes.Clear();
UpdateDrawnNodes();
}));
@@ -497,12 +497,6 @@ private string GenerateSwql(Entity table, bool includeInheritedProperties)
return sb.ToString();
}
- public ImageList ImageList
- {
- get { return _tree.ImageList; }
- set { _tree.ImageList = value; }
- }
-
public void AddServer(IMetadataProvider provider, ConnectionInfo connection)
{
//Check if the current connection can create subscription
@@ -558,16 +552,11 @@ public void AddServer(IMetadataProvider provider, ConnectionInfo connection)
_serverContextMenuItems.Add(connection.Title, serverContextMenu);
-
- TreeNode node = CreateDatabaseNode(provider, connection);
-
- TreeNode[] existingNodes = _treeData.Nodes.Find(node.Name, false);
+ TreeNode[] existingNodes = _treeData.Nodes.Find(provider.Name, false);
if (existingNodes.Length == 0)
{
- // Node doesn't already exist. Add it
- _treeData.Nodes.Add(node);
- _treeData.SelectedNode = node;
- RefreshServer(node);
+ TreeNode databaseNode = TreeNodesBuilder.CreateDatabaseNode(_treeData, provider, connection);
+ RefreshServer(databaseNode);
}
else
{
@@ -617,215 +606,6 @@ private void RemoveFromMenus(ConnectionInfo connection)
serverContextMenu.Dispose();
}
- private static TreeNode CreateDatabaseNode(IMetadataProvider provider, ConnectionInfo connection)
- {
- TreeNode node = new TreeNodeWithConnectionInfo(provider.Name, connection);
- node.SelectedImageKey = "Database";
- node.ImageKey = "Database";
- node.Tag = provider;
- node.Name = node.Text;
-
- return node;
- }
-
- private void AddTablesToNode(TreeNode parent, IMetadataProvider provider, ConnectionInfo connection)
- {
- switch (EntityGroupingMode)
- {
- case EntityGroupingMode.Flat:
- parent.Nodes.AddRange(MakeEntityTreeNodes(provider, connection, provider.Tables.OrderBy(e => e.FullName)));
- break;
- case EntityGroupingMode.ByNamespace:
- foreach (var group in provider.Tables.GroupBy(e => e.Namespace).OrderBy(g => g.Key))
- {
- TreeNode[] childNodes = MakeEntityTreeNodes(provider, connection, group.OrderBy(e => e.FullName));
-
- int countChilds = childNodes.Length;
- var namespaceNode = new TreeNode(string.Format("{0} ({1} item{2})", group.Key, countChilds, countChilds > 1 ? "s" : string.Empty))
- {
- Tag = group.Key,
- ImageKey = "Namespace"
- };
- namespaceNode.SelectedImageKey = namespaceNode.ImageKey;
-
- namespaceNode.Nodes.AddRange(childNodes);
- parent.Nodes.Add(namespaceNode);
- }
- break;
- case SwqlStudio.EntityGroupingMode.ByBaseType:
- foreach (var group in provider.Tables.Where(e => e.BaseEntity != null).GroupBy(
- e => e.BaseEntity,
- (key, group) => new { Key = key, Entities = group }).OrderBy(item => item.Key.FullName))
- {
- TreeNode[] childNodes = MakeEntityTreeNodes(provider, connection, group.Entities.OrderBy(e => e.FullName));
-
- int countChilds = childNodes.Length;
- var baseTypeNode = new TreeNodeWithConnectionInfo(
- string.Format("{0} ({1} item{2})", group.Key.FullName, countChilds, countChilds > 1 ? "s" : string.Empty),
- connection)
- {
- Tag = group.Key
- };
- baseTypeNode.ImageKey = !group.Key.IsAbstract ? "BaseType" : "BaseTypeAbstract";
- baseTypeNode.SelectedImageKey = baseTypeNode.ImageKey;
-
- baseTypeNode.Nodes.AddRange(childNodes);
- parent.Nodes.Add(baseTypeNode);
- }
- break;
- case SwqlStudio.EntityGroupingMode.ByHierarchy:
- GroupByHierarchy(provider, connection, parent);
- break;
- default:
- throw new ArgumentOutOfRangeException();
- }
- }
-
- private static void GroupByHierarchy(IMetadataProvider provider, ConnectionInfo connection, TreeNode baseNode)
- {
- Entity baseEntity = baseNode != null ? baseNode.Tag as Entity : null;
-
- var entities = provider.Tables.Where(e => baseEntity == null ? e.BaseEntity == null : e.BaseEntity == baseEntity);
-
- if (entities.Any())
- {
- TreeNode[] childNodes = MakeEntityTreeNodes(provider, connection, entities.OrderBy(e => e.FullName));
-
- baseNode.Nodes.AddRange(childNodes);
-
- if (baseEntity != null)
- {
- int countChilds = childNodes.Length;
- baseNode.Text = string.Format("{0} ({1} derived entit{2})", baseNode.Text, countChilds, countChilds > 1 ? "ies" : "y");
- }
-
- foreach (var node in childNodes)
- {
- GroupByHierarchy(provider, connection, node);
- }
-
- if (baseEntity == null)
- {
- foreach (var node in childNodes)
- {
- node.Expand();
- }
- baseNode.Expand();
- }
- }
- }
-
- private static TreeNode[] MakeEntityTreeNodes(IMetadataProvider provider, ConnectionInfo connection, IEnumerable entities)
- {
- return entities.Select(e => MakeEntityTreeNode(provider, connection, e)).ToArray();
- }
-
- private static TreeNodeWithConnectionInfo MakeEntityTreeNode(IMetadataProvider provider, ConnectionInfo connection, Entity table)
- {
- var node = new TreeNodeWithConnectionInfo(table.FullName, connection);
- node.ImageKey = GetImageKey(table);
- node.SelectedImageKey = node.ImageKey;
- node.Tag = table;
- if (table.IsIndication)
- {
- node.ToolTipText += $@"{table.FullName}
-{(string.IsNullOrEmpty(table.Summary) ? string.Empty : table.Summary + Environment.NewLine)}Base type: {table.BaseType}
-CanSubscribe: {connection.CanCreateSubscription}";
- }
- else
- {
-
- node.ToolTipText = $@"{table.FullName}
-{(string.IsNullOrEmpty(table.Summary) ? string.Empty : table.Summary + Environment.NewLine)}Base type: {table.BaseType}
-CanCreate: {table.CanCreate}
-CanUpdate: {table.CanUpdate}
-CanDelete: {table.CanDelete}";
- }
-
- // Add keys
- AddPropertiesToNode(node, table.Properties.Where(c => c.IsKey));
-
- // Add the simple Properties
- AddPropertiesToNode(node, table.Properties.Where(c => !c.IsInherited && !c.IsNavigable && !c.IsKey));
-
- // Add the inherited Properties
- AddPropertiesToNode(node, table.Properties.Where(c => c.IsInherited && !c.IsNavigable && !c.IsKey));
-
- // Add the Navigation Properties
- AddPropertiesToNode(node, table.Properties.Where(c => c.IsNavigable));
-
- AddVerbsToNode(node, table, provider);
- return node;
- }
-
- private static string GetImageKey(Entity table)
- {
- if (table.IsIndication)
- return "Indication";
- else if (table.IsAbstract)
- return "TableAbstract";
- else if (table.CanCreate || table.CanDelete || table.CanUpdate)
- return "TableCrud";
-
- return "Table";
- }
-
- private static void AddVerbsToNode(TreeNode parent, Entity table, IMetadataProvider provider)
- {
- foreach (var verb in table.Verbs.OrderBy(v => v.Name))
- {
- TreeNode verbNode = new TreeNode(verb.Name);
- verbNode.SelectedImageKey = "Verb";
- verbNode.ImageKey = verbNode.SelectedImageKey;
- verbNode.Tag = verb;
- verbNode.ToolTipText = verb.Name + Environment.NewLine + verb.Summary;
-
- parent.Nodes.Add(verbNode);
-
- verbNode.Nodes.Add(new ObjectExplorer.ArgumentsPlaceholderTreeNode(verb, provider));
- }
- }
-
- private class ArgumentsPlaceholderTreeNode : TreeNode
- {
- public Verb Verb { get; set; }
- public IMetadataProvider Provider { get; set; }
-
- public ArgumentsPlaceholderTreeNode(Verb verb, IMetadataProvider provider)
- {
- Verb = verb;
- Provider = provider;
- }
- }
-
- private static void AddPropertiesToNode(TreeNode parent, IEnumerable properties)
- {
- foreach (Property column in properties.OrderBy(c => c.Name))
- {
- string text = $"{column.Name} ({column.Type})";
- TreeNode node = new TreeNode(text);
- node.SelectedImageKey = GetColumnIcon(column);
- node.ImageKey = node.SelectedImageKey;
- node.Tag = column;
- if (!string.IsNullOrEmpty(column.Summary))
- node.ToolTipText = text + Environment.NewLine + column.Summary;
-
- parent.Nodes.Add(node);
- }
- }
-
- private static string GetColumnIcon(Property column)
- {
- if (column.IsNavigable)
- return "Link";
- if (column.IsKey)
- return "KeyColumn";
- if (column.IsInherited)
- return "InheritedColumn";
-
- return "Column";
- }
-
private void Crud(Entity entity, CrudOperation operation)
{
var provider = FindProvider(_contextMenuNode);
@@ -850,5 +630,39 @@ private void AddTextEditor(string query)
TabsFactory.OpenQueryTab(query, node.Connection);
}
}
+
+ private void InitializeComponent()
+ {
+ this.components = new System.ComponentModel.Container();
+ System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(ObjectExplorer));
+ this.objectExplorerImageList = new System.Windows.Forms.ImageList(this.components);
+ this.SuspendLayout();
+ //
+ // objectExplorerImageList
+ //
+ this.objectExplorerImageList.ImageStream = ((System.Windows.Forms.ImageListStreamer)(resources.GetObject("objectExplorerImageList.ImageStream")));
+ this.objectExplorerImageList.TransparentColor = System.Drawing.Color.Transparent;
+ this.objectExplorerImageList.Images.SetKeyName(0, ImageKeys.Column);
+ this.objectExplorerImageList.Images.SetKeyName(1, ImageKeys.Database);
+ this.objectExplorerImageList.Images.SetKeyName(2, ImageKeys.Link);
+ this.objectExplorerImageList.Images.SetKeyName(3, ImageKeys.Table);
+ this.objectExplorerImageList.Images.SetKeyName(4, ImageKeys.InheritedColumn);
+ this.objectExplorerImageList.Images.SetKeyName(5, ImageKeys.KeyColumn);
+ this.objectExplorerImageList.Images.SetKeyName(6, ImageKeys.Verb);
+ this.objectExplorerImageList.Images.SetKeyName(7, ImageKeys.Argument);
+ this.objectExplorerImageList.Images.SetKeyName(8, ImageKeys.Indication);
+ this.objectExplorerImageList.Images.SetKeyName(9, ImageKeys.Namespace);
+ this.objectExplorerImageList.Images.SetKeyName(10, ImageKeys.BaseType);
+ this.objectExplorerImageList.Images.SetKeyName(11, ImageKeys.BaseTypeAbstract);
+ this.objectExplorerImageList.Images.SetKeyName(12, ImageKeys.TableAbstract);
+ this.objectExplorerImageList.Images.SetKeyName(13, ImageKeys.TableCrud);
+ this.ResumeLayout(false);
+
+ }
+
+ public void SetGroupingMode(EntityGroupingMode mode)
+ {
+ this.treeNodesBuilder.EntityGroupingMode = mode;
+ }
}
}
diff --git a/Src/SwqlStudio/ObjectExplorer/ObjectExplorer.resx b/Src/SwqlStudio/ObjectExplorer/ObjectExplorer.resx
new file mode 100644
index 000000000..be952d99c
--- /dev/null
+++ b/Src/SwqlStudio/ObjectExplorer/ObjectExplorer.resx
@@ -0,0 +1,338 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ 17, 17
+
+
+
+ AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj00LjAuMC4w
+ LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAACZTeXN0
+ ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAAD8
+ LwAAAk1TRnQBSQFMAgEBDgEAAZwBAgGcAQIBEAEAARABAAT/ASEBAAj/AUIBTQE2BwABNgMAASgDAAFA
+ AwABQAMAAQEBAAEgBgABQBIAgP+AAAT/Az4B/wPAAf8D9AH/A9YB/wMpTf8DAAH/AwAB/wE3AVoBuRH/
+ gAAE/wO0Af8DBwH/AwcB/wMHAf8Dok3/AwAB/wMAAf8BNwFaAbkB/wMADf+AAAT/A/IB/wMgAf8D6AH/
+ AyIB/wPoAf8BBAIAAf8BBAIAAf8BBAIAAf8BBAIAAf8BBAIAAf8BBAIAAf8BBAIAAf8BBAIAEf8BtwGi
+ AZMB/wFDASkBFQH/AUMBKQEVAf8BQwEpARUB/wFDASkBFQn/AwAB/wE3AVoBuQH/ATcBWgG5Af8BQwEp
+ ARUB/wMACf+AAAT/A/kB/wONAf8DRwH/A1EB/wP3Af8B3wHOAcMB/wHdAcgBuwH/AdsBvwGtAf8B2wG7
+ AacB/wHbAbsBpwH/AdsBuwGnAf8BzwG0AaMB/wEEAgAR/wG3AaIBkwH/Af0B+wH5Af8B4QHcAdgB/wHg
+ AdcB0gH/Ad8BzgHDAf8B3QHIAbsJ/wMAAf8DXwH/AUMBKQEVAf8BQwEpARUB/wMABf+AAAT/A/0B/wPb
+ Af8DBwH/A8kB/wP7Af8B+wHsAeMB/wGkAY0BHwH/AZoBgwETAf8B9gHWAcIB/wGIARIBAAH/AYMBDAEA
+ Af8BzwG0AaMB/wEEAgAR/wG3AaIBkwH/A/4B/wG6AaYBmAH/AbUBoAGRAf8B+wHsAeMB/wGkAY0BXgH/
+ AZoBgwFSCf8DAAH/A18B/wFDASkBFQH/AUMBKQEVAf8DAAH/gAAI/wG6AaUBlgH/A/4B/wP+Af8D/gH/
+ Af0B+wH5Af8B/QH3AfMB/wH7AewB4wH/AfoB5wHbAf8B+AHhAdIB/wH3AdsByQH/AdABuQGrAf8BBAIA
+ Ef8BugGlAZYB/wP+Af8D/gH/A/4B/wH9AfsB+QH/Af0B9wHzAf8B+wHsAeMB/wH6AecB2wn/AwAB/wNf
+ Af8BQwEpARUB/wFDASkBFQH/gAAI/wG+AakBmgH/A/4B/wG6AaYBmAH/AbQBoAGRAf8D/gH/AaMBjgEf
+ Af8BmgGDARMB/wH7AewB4wH/AYkBEgEAAf8BgwEMAQAB/wHRAcEBtgH/AQQCABH/Ab4BqQGaAf8D/gH/
+ AboBpgGYAf8BtAGgAZEB/wP+Af8BowGOAV4B/wGaAYMBUgH/AfsB7AHjAf8BiQFRAT8J/wMAAf8DXwH/
+ AUMBKQEVAf+AAAj/AcMBrgGeAf8D/gH/A/4B/wP+Af8D/gH/A/4B/wH9AfcB8wH/AfwB8gHsAf8B+wHs
+ AeMB/wH6AecB2wH/AdEBwQG2Af8BBAIAEf8BwwGuAZ4B/wP+Af8D/gH/A/4B/wP+Af8D/gH/Af0B9wHz
+ Af8B/AHyAewB/wH7AewB4wH/AfoB5wHbCf8DAAH/A18B/4AACP8ByAGyAaMB/wP+Af8BugGmAZgB/wG0
+ AaABkQH/A/4B/wGkAY4BHwH/AZkBhAETAf8B/QH3AfMB/wGIARIBAAH/AYMBDAEAAf8B0QHBAbYB/wEE
+ AgAR/wHIAbIBowH/A/4B/wG6AaYBmAH/AbQBoAGRAf8D/gH/AaQBjgFeAf8BmQGEAVIB/wH9AfcB8wH/
+ AYgBUQE+Af8BgwFLATgB/wHRAcEBtgn/AUMBKQEVAf+AAAj/AcwBtgGnAf8D/gH/A/4B/wP+Af8D/gH/
+ A/4B/wP+Af8B/QH7AfkB/wH9AfcB8wH/AfwB8gHsAf8B+wHsAeMB/wEEAgAR/wHMAbYBpwH/A/4B/wP+
+ Af8D/gH/A/4B/wP+Af8D/gH/Af0B+wH5Af8B/QH3AfMB/wH8AfIB7AH/AfsB7AHjAf8BQwEpARUJ/4AA
+ CP8B6gGqAYsB/wHqAaoBiwH/AeoBqgGLAf8B6QGlAYQB/wHnAZcBDwH/AeYBjgEDAf8B4wEeAQAB/wHj
+ ARcBAAH/AeIBEwEAAf8B4gETAQAB/wHiARMBAAH/AcgBAwEAEf8B6gGqAYsB/wHqAaoBiwH/AeoBqgGL
+ Af8B6QGlAYQB/wHnAZcBTgH/AeYBjgFCAf8B4wFdASoB/wHjAVYBIAH/AeIBUgEZAf8B4gFSARkB/wHi
+ AVIBGQH/AcgBQgEPCf+AAAj/AeoBqgGLAv8BwgGiAf8B/gHAAZ8B/wH9Ab0BmgH/AfsBtQGQAf8B+gGw
+ AYsB/wH4AacBHgH/AfYBogEYAf8B9QGdARIB/wH1AZkBCwH/AfMBlQEGAf8BzQEGAQAR/wHqAaoBiwL/
+ AcIBogH/Af4BwAGfAf8B/QG9AZoB/wH7AbUBkAH/AfoBsAGLAf8B+AGnAV0B/wH2AaIBVwH/AfUBnQFR
+ Af8B9QGZAUoB/wHzAZUBRQH/Ac0BRQERCf+AAAj/AeoBqgGLAf8B6gGqAYsB/wHqAaoBiwH/AeoBqgGL
+ Af8B6QGhASAB/wHoAZsBFwH/AeYBjgEDAf8B5QGHAQAB/wHkAYEBAAH/AeQBHAEAAf8B4wEXAQAB/wHi
+ ARMBABH/AeoBqgGLAf8B6gGqAYsB/wHqAaoBiwH/AeoBqgGLAf8B6QGhAV8B/wHoAZsBVgH/AeYBjgFC
+ Af8B5QGHATgB/wHkAYEBLgH/AeQBWwEmAf8B4wFWAR4B/wHiAVIBGQn/gACA/4AAgP//ACkAAdMB3wHr
+ Af8B6AH0Av8B6AH0Av8B0wHfAesB/wgAA/QB/wP0Af8D9QX/A/YB/wP0Af8D9A3/A/4B/wP2Af8D9QH/
+ A/0J/xAAAe8B5gHcAf8BzgG1AZMB/wG4AZMBHwH/AbIBiAENAf8BuAGSAR4B/wHOAbQBkAH/Ae4B5gHb
+ Af94AAPfAf8B6AH0Av8BmAGkAbAB/wGYAaQBsAH/AegB9AL/A98B/wQAA/YB/wM9Af8DwAH/A/QB/wPW
+ Af8DKAH/A/UJ/wP+Af8D9gH/AU4BrgHbAf8BTgGuAdsB/wP1Af8D/QX/CAAB/QH7AfoB/wHIAawBhAH/
+ AaEBLgEAAf8BnQEoAQAB/wGcASYBAAH/AaQBNAEAAf8BnQEnAQAB/wGdAScBAAH/AZ8BLQEAAf8BxwGq
+ AYEB/wH8AfsB+QH/HAADhgH/AwAB/w8AAf8DhgH/NAAD3wH/A/QB/wErAagB5gH/AQABSQG2Af8BAAFJ
+ Ab4B/wEjAagB7gH/AegB9AL/AdMB3wHrAf8D+gH/A7QB/wMGAf8DBgH/AwYB/wOiAf8D+gX/A/4B/wP2
+ Af8BTgGuAdsB/wEAAUwBxwH/AQABTAHHAf8BTgGuAdsB/wP1Af8D/QH/BAAB/AH7AfkB/wG8AZYBJAH/
+ AaABKwEAAf8BoQEsAQAB/wGeAScBAAH/AcoBqgE1Af8B9gHxAegB/wHNAa8BPwH/AZ4BJwEAAf8BoQEs
+ AQAB/wGhASsBAAH/AboBlAEgAf8B/AH6AfgB/xQAA4YB/wMAAf8XAAH/A4YB/zgAASsBqAHmAf8BAAFJ
+ AbYB/wEAAUkBvgH/AQABSQG+Af8BmAGkAbAB/wHoAfQC/wP+Af8D8gH/Ax8B/wPoAf8DIQH/A+gB/wP+
+ Af8D9AH/A/QB/wP0Af8BlAG9AeAB/wEAAUwBxwH/AQABTAHHAf8BAAFMAccB/wFOAa4B2wH/A/UB/wQA
+ AcwBrwGIAf8BpQEwAQAB/wGlATABAAH/AaUBMQEAAf8BogErAQAB/wHmAdYBuwX/AesB3gHIAf8BowEt
+ AQAB/wGlATABAAH/AaUBMAEAAf8BpQEwAQAB/wHKAa0BhAH/FAADFQH/AwAB/xcAAf8DFQH/MAABBAFJ
+ Aa4B/wEEAUkBrgH/ARwBRQGdAf8BHAFFAZ0B/wEAAUkBtgH/AQABSQG2Af8BmAGkAbAB/wHoAfQG/wP5
+ Af8DjQH/A0YB/wNQAf8D9wX/A/QB/wEAAUwBxwH/AQABTAHHAf8BAAFMAccB/wGUAb0B4AH/AQABTAHH
+ Af8BAAFMAccB/wGUAb0B4AH/A/YB/wHyAeoB4QH/AakBNwEAAf8BqgE1AQAB/wGqATUBAAH/AaoBNQEA
+ Af8BpwEwAQAB/wHlAdMBtgX/AeoB3AHDAf8BqAEyAQAB/wGqATQBAAH/AaoBNQEAAf8BqgE1AQAB/wGp
+ ATYBAAH/AfAB6QHeAf8QAAMVAf8DAAH/FwAB/wMVAf8cAAPfAf8D3wH/DAABBAFJAa4B/wG1AfoC/wHN
+ AfYC/wHNAfYC/wErAagB5gH/ASsBqAHmAf8B6AH0Av8B0wHfAesF/wP9Af8D2wH/AwYB/wPJAf8D+wX/
+ A/QB/wEAAUwBxwH/A/QB/wP0Af8D9AH/AZQBvQHgAf8BlAG9AeAB/wP2Af8D/gH/AdYBvgGdAf8BsAE8
+ AQAB/wGuATkBAAH/Aa8BOgEAAf8BrwE6AQAB/wGsATUBAAH/AeYB1QG2Bf8B6wHcAcQB/wGtATcBAAH/
+ Aa8BOQEAAf8BrwE6AQAB/wGuAToBAAH/Aa8BOQEAAf8B0wG5AZYB/xMAAf8DwAH/FAADwAH/AwAB/xgA
+ AdMB3wHrAf8B6AH0Av8B6AH0Av8B0wHfAesB/wgAARwBRQGdAf8BzQH2Av8ByQH2Av8BSAGkAdEB/wFI
+ AaQB0QH/AckB9gL/A+UB/wQACP8D9gH/A/QB/wP0Af8D/QX/A/QB/wEAAUwBxwH/A/QB/wP2Af8BTgGu
+ AdsB/wFOAa4B2wH/A/QB/wP8Bf8BygGpATwB/wHAAY4BAAH/AbUBQQEAAf8BswE9AQAB/wG0AT8BAAH/
+ AbIBOwEAAf8B6AHWAbgF/wHsAd4BxQH/AbIBPAEAAf8BtAE+AQAB/wG0AT8BAAH/AbQBPwEAAf8BtQE/
+ AQAB/wHEAZ8BKQH/DwAB/wMuAf8cAAMuAf8DAAH/EAAD3wH/AegB9AL/AZgBpAGwAf8BmAGkAbAB/wHo
+ AfQC/wPfAf8EAAEcAUUBnQH/Ac0B9gL/AUgBpAHRAf8BGAFFAaEB/wEYAUUBoQH/AUgBpAHRAf8D9AH/
+ A98F/wP+Af8D9gH/AU4BrgHbAf8BTgGuAdsB/wP1Af8D/QH/A/QB/wEAAUwBxwH/A/QB/wFOAa4B2wH/
+ AQABTAHHAf8BAAFMAccB/wFOAa4B2wH/A/UB/wP9Af8ByQGmATMB/wHJAZsBCgH/AcUBlAEDAf8BvgGJ
+ AQAB/wG6AYABAAH/AbcBPwEAAf8B6wHZAbsF/wHvAeEByAH/AbcBQQEAAf8BuQFDAQAB/wG5AUMBAAH/
+ AbkBQwEAAf8BugFDAQAB/wHDAZoBHQH/EwAB/wPAAf8UAAPAAf8DAAH/EAAB0wHfAesB/wHoAfQC/wEj
+ AagB7gH/AQABSQG+Af8BAAFJAb4B/wEjAagB7gH/Ac0B9gL/Ac0B9gL/AQQBSQGuAf8BtQH6Av8BIwGo
+ Ae4B/wEAAUkBvgH/AQABSQHHAf8BAAFJAccB/wGMAaQBvQH/AdwB9AL/A/4B/wP2Af8BTgGuAdsB/wEA
+ AUwBxwH/AQABTAHHAf8BTgGuAdsB/wP0Af8D9AH/AQABTAHHAf8D9AH/AZQBvQHgAf8BAAFMAccB/wEA
+ AUwBxwH/AQABTAHHAf8BTgGuAdsB/wP1Af8B0AGvAYEB/wHOAaABDwH/AcsBnAEOAf8BzAGcAQ4B/wHK
+ AZkBBgH/AcMBjQEAAf8B5QHUAbUF/wHnAdgBvAH/Ab4BgwEAAf8BwAGHAQAB/wHBAYgBAAH/AcIBigEA
+ Af8BxgGQAQAB/wHMAagBNgH/EAADFQH/AwAB/xcAAf8DFQH/EAAB6AH0Av8BmAGkAbAB/wEAAUkBvgH/
+ AQABSQG+Af8BAAFJAb4B/wEAAUkBvgH/ARwBRQGdAf8BHAFFAZ0B/wEEAUkBrgH/AQQBSQGuAf8BAAFJ
+ Ab4B/wEAAUkBvgH/AQABSQHHAf8BAAFJAccB/wGMAaQBvQH/AdwB9AL/A/YB/wFOAa4B2wH/AQABTAHH
+ Af8BAAFMAccB/wEAAUwBxwH/AQABTAHHAf8BTgGuAdsB/wEAAUwBxwH/AQABTAHHAf8BAAFMAccB/wEA
+ AUwBxwH/AZQBvQHgAf8BAAFMAccB/wEAAUwBxwH/AZQBvQHgAf8D9gH/Ad0BxwGrAf8B0wGmARgB/wHQ
+ AaIBEQH/AdABoQESAf8B0AGhARIB/wHQAZ8BDQH/AcsBpAEiAf8B1AHDAaUB/wHKAaQBIgH/Ac0BmwEF
+ Af8BzgGcAQgB/wHOAZwBCAH/Ac4BnAEHAf8BzwGdAQcB/wHaAcMBogH/EAADFQH/AwAB/xcAAf8DFQH/
+ EAAB6AH0Av8BmAGkAbAB/wEAAUkBvgH/AQABSQG+Af8BAAFJAccB/wEAAUkBxwH/AQABSQG+Af8BIwGo
+ Ae4B/wHqAfYC/wHqAfYC/wP2Af8D9gH/AYwBpAG9Af8BjAGkAb0B/wP0Af8D3wH/A/cB/wGUAb0B4AH/
+ AQABTAHHAf8BAAFMAccB/wEAAUwBxwH/AQABTAHHAf8BAAFMAccB/wFOAa4B2wH/A/QB/wP0Af8D9AH/
+ A/QB/wGUAb0B4AH/AZQBvQHgAf8D9gH/A/4B/wH1Ae8B5wH/AdEBqAEmAf8B2AGpARgB/wHVAaYBGAH/
+ AdUBpgEWAf8B1AGjAREB/wHlAccBkQH/AfMB6gHYAf8B5wHLAZkB/wHTAaEBDQH/AdMBogEQAf8B0wGh
+ AQ4B/wHVAaMBDQH/Ac0BnQERAf8B9AHtAeQB/xAAA4YB/wMAAf8XAAH/A4YB/xAAAdMB3wHrAf8B6AH0
+ Av8BIwGoAe4B/wEAAUkBvgH/AQABSQHHAf8BAAFJAccB/wEAAUkBvgH/AQABSQG+Af8BmAGkAbAB/wHo
+ AfQC/wPfAf8D3wH/AdwB9AL/AdwB9AL/A98B/wQAA/4B/wP3Af8BlAG9AeAB/wEAAUwBxwH/AQABTAHH
+ Af8BAAFMAccB/wEAAUwBxwH/AQABTAHHAf8BTgGuAdsB/wP1Af8D/QH/A/4B/wP3Af8D9gH/A/4F/wQA
+ Ad0ByAGqAf8B3QGyAScB/wHaAasBGwH/AdkBqwEcAf8B1wGnARUB/wHxAeYB0wX/AfUB7gHhAf8B1wGm
+ ARUB/wHXAacBFQH/AdgBpwETAf8B2QGqARgB/wHbAcEBngH/GAADhgH/AwAB/w8AAf8DhgH/GAAD3wH/
+ AegB9AL/AZgBpAGwAf8BAAFJAb4B/wEAAUkBvgH/AQABSQG+Af8BAAFJAb4B/wGYAaQBsAH/AegB9AL/
+ A98B/wQAA98B/wPfAf8IAAT/A/4B/wP3Af8BlAG9AeAB/wEAAUwBxwH/AQABTAHHAf8BAAFMAccB/wEA
+ AUwBxwH/AZQBvQHgAf8D9gH/A/4F/wP+Af8D/gn/BAAB/gL9Af8B2QG/AZoB/wHgAbYBLQH/Ad8BsQEg
+ Af8B3AGtARsB/wHXAbUBPgH/AeIB1QG+Af8B1wG3AYAB/wHbAaoBFwH/Ad4BrgEaAf8B3gGxASIB/wHW
+ AbgBjQH/Af4B/QH8Af9QAAHTAd8B6wH/AegB9AL/ASMBqAHuAf8BAAFJAb4B/wEAAUkBvgH/ASMBqAHu
+ Af8B6AH0Av8B0wHfAesB/xgACP8D/gH/A/cB/wGUAb0B4AH/AQABTAHHAf8BAAFMAccB/wGUAb0B4AH/
+ A/YB/wP+Gf8MAAHfAcsBsQH/AdwBuAE+Af8B4wG4AS8B/wHjAbQBIwH/Ad0BrgEbAf8B4QGyAR8B/wHi
+ AbYBKQH/AdsBswE1Af8B3gHIAaoB/wL+Af0B/1gAA98B/wHoAfQC/wGYAaQBsAH/AZgBpAGwAf8B6AH0
+ Av8D3wH/HAAM/wP+Af8D9wH/AZQBvQHgAf8BlAG9AeAB/wP2Af8D/h3/EAAB9gHxAesB/wHkAdQBvwH/
+ Ad4BxQGjAf8B3gHEAZwB/wHeAcQBoQH/AeQB0wG8Af8B9QHvAekB/2QAAdMB3wHrAf8B6AH0Av8B6AH0
+ Av8B0wHfAesB/yAAEP8D/gH/A/cB/wP2Af8D/iH/WQABCwG5Af8CAAEsAf8CAAEOAf/1AAEsAccB/wEA
+ Ac0B/AH/AQABDQGHAf+0AAM7AWUBAAECAQAB/wM6AWA1AAEsAccB/wEAAaAB0gH/AQABAwEjAf8cAAMB
+ AQIDAAEBGwABAQwAASIBIQEiATEDAAEBXAADPgFqAQABpwEAAf8BAAEGAQAB/wEAAQIBAAH/AzYBWDEA
+ ASwBxwH/AQAB0QH8Af8BAAENAYcB/zMAAQEDAAEBEAAB7AHSAewB/wEjAQABIgH/AeYBzAHmAf8DAgED
+ AxIBGRAAASABKgEsAf8BFgEeASEB/wENARIBFQH/AQMBBgEJAf8DAAH/AwAB/wMAAf8DAAH/AwAB/xwA
+ Az4BagEAAacBAAH/ARoBuwEOAf8BAAEKAQAB/wEAAQcBAAH/AQABAgEAAf8DNQFXLQABLAHHAf8BAAGh
+ AdEB/wEAAQMBIwH/PwABAQQAAe0B2AHtAf8BqQEBAagB/wGAAQABMAH/ASYBAAEmAf8B6wHRAesB/xQA
+ ASkBggGDAf8BlwHbAfUB/wEMAakBygH/AQwBqQHKAf8BCwGnAckB/wEDAZ8BwgH/AQABlgG5Af8BAAGN
+ AbAB/wMAAf8dAAGkAQAB/wEaAbsBDgH/ARoBuwEOAf8BAAEJAQAB/wEAAQoBAAH/AQABBwEAAf8BAAEC
+ AQAB/wMwAUwpAAEsAccB/wECAeIB/QH/AQABCQGAAf8jAAEBAwABAQMAAQEDAAEBAwABAQMAAQEDAAEB
+ BAAB6AHRAegB/wGqAQEBqQH/AcwBGAHLAf8BLwEAAS8B/wGWAQABlQH/ASwBAAErAf8B8AHVAfAB/xAA
+ ATECjAH/AaAB4AH3Af8BIgHNAfEB/wEVAccB7gH/AQkBwQHrAf8BAAG8AegB/wEAAbcB5gH/AQABkgG2
+ Af8DAAH/HQABpwEAAf8BGgG7AQ4B/wEaAbsBDgH/AaoB1AGiAf8BAAGgAQAB/wEAAQoBAAH/AQABBwEA
+ Af8BAAEBAQAB/ykAASwBxwH/AQkB1wH8Af8BAAEJAYAB/yQAAasB8AH3Af8BqwHiAeUB/wGsAc4BzAH/
+ Aa0BuwG1Af8BrgGnAZwB/wQAAeQBygHkAf8BqQEBAagB/wHTARwB0gH/AdQBHwHTAf8BMAEAAS8B/wGf
+ AQABnwH/AY4BAAGNAf8BLgEAAS0B/xAAAYUClAH/AacB4wH4Af8BLQHTAfQB/wEiAc4B8QH/ARYByAHu
+ Af8BCQHCAesB/wEAAbwB6AH/AQABmQG8Af8DAAH/GAADAgEDAQABqwEAAf8BGgG7AQ4B/wGqAdQBogH/
+ AbcB2gGwAf8BqgHUAaIB/wEAAZMBAAH/AQABCgEAAf8BAAECAQAB/yUAAREBkAH/AQABLAHHAf8BHwHe
+ AfwB/wEAAQkBgAH/AgABKwH/OAABqgEDAakB/wHSARsB0QH/AdUBIAHVAf8BvQEhAbwB/wHeAZgB3QH/
+ AY8BAAGOAf8BnQEAAZwB/wEvAQABLwH/EAABjAKbAf8BrgHmAfoB/wGGAdgB9gH/AS0B1AH0Af8BIgHN
+ AfEB/wEWAccB7gH/AQkBwgHrAf8BBAGgAcEB/wMAAf8YAAMEAQUBFAG4AQcB/wG0AdkBrQH/AcUB4gHA
+ Af8BtwHaAbAB/wG3AdoBsAH/AaoB1AGiAf8BAAGIAQAB/wEAAQIBAAH/IQABIAGgAf8BAAGHAccB/wEM
+ AcAB8AH/AQEBywH+Af8BAgGzAd0B/wIAARcB/wIAASsB/xgAAasB8AH3Af8BqwHlAekB/wGsAtUB/wGs
+ AcQBwQH/Aa0BtQGsAf8BrgGkAZgB/wQAAagBAAGnAf8B0gEeAdEB/wG8ASABuwH/Ae8BpQHuAf8B+wGf
+ AfoB/wHvAZ0B7gH/AZcBAwGWAf8BLQEAAS0B/xAAAZEBogGhAf8BsgHoAfwB/wGgAeIB+gH/AYYB2AH2
+ Af8BLgHTAfMB/wEiAc4B8QH/ARUByAHuAf8BCAGlAccB/wIAAQMB/xgAAwIBAwNEAXoBjgHGAYQB/wG5
+ AdwBswH/AcMB4QG+Af8BwwHhAb4B/wG3AdoBsAH/AaoB1AGiAf8BAAEYAQAB/x0AAYABsQH/AQABhwHI
+ Af8BAwG6AfcB/wEFAcIB+QH/AQABtwH5Af8BGQHWAfsB/wEAAaYB6AH/AgABFQH/AQABAgGDAf8wAAGn
+ AQEBpgH/AbwBIAG7Af8B7wGlAe4B/wH7AZsB+gH/AfsBmAH6Af8B+wGZAfoB/wHnAZgB5gH/AZEBAAGQ
+ Af8QAAGUAaYBpQH/Ab0B7AH8Af8BpQHlAfsB/wGfAeIB+gH/AYYB2AH2Af8BLgHUAfQB/wEiAc0B8QH/
+ AQwBqQHKAf8BBQEJAQwB/yAAA0YBfgGQAccBhgH/Ab4B3gG4Af8BwwHhAb4B/wGzAdkBrAH/AZABxwGG
+ Af8DPQFpHQABLAG4Af8BBQHBAfkB/wEBAbcB+QH/AZMB7gH+Af8BjwHsAf4B/wEDAbQB8wH/AY0B4wH+
+ Af8BAAG6AeIB/wIAARwB/xwAAasB8AH3Af8BrALVAf8BrgG0AawB/wGuAZkBigH/A/0B/wHPAYgBzwH/
+ AeIBrwHiAf8B+wGrAfoB/wH7AZgB+gH/AfsBmAH6Af8B6gGQAekB/wHPAYgBzwH/AfQB5gH0Af8QAAGU
+ AaYBpQH/Ab0B7AH8Af8BvQHsAfwB/wGyAegB/AH/Aa4B5gH6Af8BpwHkAfkB/wGgAeAB9wH/AZcB2wH1
+ Af8BDgETARcB/yQAA0cBgQGUAckBigH/Ab0B3gG3Af8BjgHGAYQB/wMwAUshAAGDAbsB/wEKAcYB+QH/
+ ARoBigGsAf8BGgGKAawB/wEaAYoBrAH/ARoBigGsAf8BGgGKAawB/wETAdUB+gH/AgABGQH/MAAB8AHU
+ AfAB/wHPAYgBzwH/Ae4BvgHuAf8B+wGuAfoB/wHsAZEB6wH/Ac8BiAHPAf8B8wHgAfIB/xQAAZQBpgGl
+ Af8BlAGmAaUB/wGTAqUB/wGPAZ8BngH/AYgClwH/AYECjgH/ASoChAH/ASABKgEsAf8BFwEeASAB/ygA
+ AzwBZgGUAckBigH/AyUBNyUAAYMBvAH/AQ0B0gH6Af8BAAEVAYQB/w0AAZABwQH/AQQBuwHhAf8CAAEW
+ Af80AAHyAdsB8gH/Ac8BiAHPAf8B4wGsAeMB/wHPAYgBzwH/AfMB4wHzAf9gAAMBAQIEAAMBAQIpAAGI
+ AcEB/wEAAZ0B0AH/ASsB4wH6Af8BAAGFAZ4B/wECARUBhwH/AQIBJwGcAf8BAwG/AfQB/wEAAYwBqgH/
+ AQABCQErAf84AAHyAdsB8gH/Ac8BiAHPAf8B8AHjAfAB/5kAAZQBxgH/AQABigHBAf8BAAGaAc0B/wEf
+ AdUB9QH/ASIB6QH+Af8BHgHUAfMB/wEAAZIBsgH/AQABFQGMAf8BAAEhAaIB/zwAAf4B+wH+Af+hAAGU
+ AcYB/wEAAY0BwwH/AQABiwG6Af8BAAGLAboB/wEAAYgBtwH/AQABJAGgAf8BAAGCAbIB//8AqQADNgFY
+ AZkCAAH/AzMBU/AAAzgBXQHXAZoBAAH/AZkCAAH/AZkCAAH/Ay8BSiwAAx4BKwNUAa4BWQJkAewBAAGD
+ AZYB/wEAARcBjQH/AQABDgGMAf8BTgJdAfADVgGzAyUBN5gAAzoBYQHXAZoBAAH/AdgBmwEAAf8BmQIA
+ Af8BmQIAAf8BmQIAAf8DLwFKKAABWwJeAdABAAGwAdEB/wGEAdUB6AH/AaEB6wH2Af8BFAHkAv8BAAG+
+ AfMB/wEAAZ8B3gH/AQABiwG+Af8BWwJeAdlUAAG3AaIBkwH/AQQCAAH/AQQCAAH/AQQCAAH/AQQCAAH/
+ AQQCAAH/AQQCAAH/AQQCAAH/AQQCAAH/AQQCAAH/AQQCAAH/AQQCAAH/FAAB2AGbAQAB/wHYAZsBAAH/
+ AdgBmwEAAf8BmQIAAf8BmQIAAf8BmQIAAf8BmQIAAf8DLwFKJQABjwGqAf8BAAHXAv8BkAHqAfoB/wGh
+ AesB9gH/ARIB2QH0Af8BAAG8AfIB/wEAAacB6AH/AQABnAHaAf8BAAEEAYQB/xQAAzEBTQJSAVEBoQFf
+ AlgB4wFfAlgB4wFSAlEBoQExAjABTQQAAzEBTQJSAVEBoQFfAlgB4wFfAlgB4wFSAlEBoQExAjABTQwA
+ AbcBogGTAf8B/QH7AfkB/wHhAdwB2AH/AeAB1wHSAf8B3wHOAcMB/wHdAcgBuwH/AdsBvwGtAf8B2wG7
+ AacB/wHbAbsBpwH/AdsBuwGnAf8BzwG0AaMB/wEEAgAB/xQAAdgBmwEAAf8B2AGbAQAB/wHpAbQBHQH/
+ AfwB1gGvAf8BtQEEAQAB/wGZAgAB/wGZAgAB/wGZAgAB/wMvAUohAAGRAa4B/wEAAdIB+gH/AY0B5AH2
+ Af8BoQHrAfYB/wERAdcB8wH/AQABuQHvAf8BAAGnAegB/wEAAZwB2gH/AQABBgGGAf8QAAM1AVUDZAHn
+ Ac8BuAGpAf8B6wHWAcgB/wHlAcsBuwH/AbMBlQEgAf8BZAJcAecDSwGOA2QB5wHPAbgBqQH/AesB1gHI
+ Af8B5QHLAbsB/wGzAZUBIAH/AWQCXAHnATUCNAFVCAABtwGiAZMB/wP+Af8BugGmAZgB/wG1AaABkQH/
+ AfsB7AHjAf8BpAGNAR8B/wGaAYMBEwH/AfYB1gHCAf8BiAESAQAB/wGDAQwBAAH/Ac8BtAGjAf8BBAIA
+ Af8UAAHYAZsBAAH/AeoBtwGCAf8B+wHYAbIB/wH+AdEBowH/AfsB2AGyAf8BrwIAAf8BmQIAAf8BmQIA
+ Af8BmQIAAf8DKgFBHQABlQGwAf8BAAHSAfoB/wGNAeQB9AH/AaEB6wH2Af8BEQHXAfIB/wEAAbkB7gH/
+ AQABpwHoAf8BAAGcAdoB/wEAAQkBiAH/EAADVQGyAeYB1gHLAf8DWQHCAmABXAHUA2AB1AFMASoBIQH7
+ AwAB/wMAAf8DAAH/AWECWAHmAmABXAHUA2AB1ANZAcIBuQGcAYgB/wNVAbIIAAG6AaUBlgH/A/4B/wP+
+ Af8D/gH/Af0B+wH5Af8B/QH3AfMB/wH7AewB4wH/AfoB5wHbAf8B+AHhAdIB/wH3AdsByQH/AdABuQGr
+ Af8BBAIAAf8UAAHnAbMBHQH/AfEBwwGRAf8B/gHPAZ0C/wHNAZkB/wH+AdABnwH/AfsB2AGyAf8BqQIA
+ Af8BmQIAAf8BmQIAAf8BmQIAAf8DBAEFGQABmQG1Af8BAAHRAfsB/wGOAeQB9QH/AaEB6wH2Af8BEQHX
+ AfIB/wEAAbkB7gH/AQABpwHoAf8BAAGcAdoB/wEAAQwBigH/EAADZQH0BP8DVwHfAx0BKgNcAc0F/wH+
+ AfcC/wHxAeYB/wH6AeMB1AH/AfMB1wHHAf8DSgGNAx0BKgNcAd8B7wHWAccB/wFkAlIB9AgAAb4BqQGa
+ Af8D/gH/AboBpgGYAf8BtAGgAZEB/wP+Af8BowGOAR8B/wGaAYMBEwH/AfsB7AHjAf8BiQESAQAB/wGD
+ AQwBAAH/AdEBwQG2Af8BBAIAAf8UAANFAXwB5QGyARwB/wH0AcABiwL/Ac0BmQL/Ac0BmQH/Af4B0AGh
+ Af8B+wHYAbIB/wGpAgAB/wGZAgAB/wGZAgAB/x0AAZsBtwH/AQAB0AH5Af8BjQHjAfUB/wGhAesB9gH/
+ ARMB2QHyAf8BAAG5Ae4B/wEAAacB6AH/AQABnAHaAf8BAAEOAY0B/xAAA1UBsgHyAeYB3gH/A1kBwgNc
+ AdQBYAJcAdQDYQHiAdMBtQGiAf8DTQH6AdoBwAGvAf8DXwHzA1sB1gFgAlwB1ANZAcIBywGxAaEB/wNV
+ AbIIAAHDAa4BngH/A/4B/wP+Af8D/gH/A/4B/wP+Af8B/QH3AfMB/wH8AfIB7AH/AfsB7AHjAf8B+gHn
+ AdsB/wHRAcEBtgH/AQQCAAH/GAADRgF/AeQBsAEaAf8B9gHEAZAC/wHNAZkC/wHNAZkB/wH+AdABoQH/
+ AfsB2AGyAf8BqQIAAf8BmQIAAf8dAAGeAboB/wEAAdAB+QH/AY0B4wH0Af8BoQHrAfYB/wEQAdcB8gH/
+ AQABtwHuAf8BAAGnAegB/wEAAZwB2gH/AQABEAGPAf8QAAM1AVUDZAHnAe0B4QHXA/8B/QL/AfcB8QH/
+ AdgBxAG3Af8DZAHnA0sBjgNkAecB7QHhAdcD/wH9Av8B9wHxAf8B2AHEAbcB/wNkAecDNQFVCAAByAGy
+ AaMB/wP+Af8BugGmAZgB/wG0AaABkQH/A/4B/wGkAY4BHwH/AZkBhAETAf8B/QH3AfMB/wGIARIBAAH/
+ AYMBDAEAAf8B0QHBAbYB/wEEAgAB/xwAA0kBhwHjAa8BGQH/AfYBxAGQAv8BzQGZAv8BzQGZAf8B/gHQ
+ AaEB/wHyAckBnQH/AbACAAH/HQABogG8Af8BAAHOAfcB/wGLAeMB9AH/AaEB6wH2Af8BDwHWAfIB/wEA
+ AbcB7gH/AQABpwHoAf8BAAGcAdoB/wEAAREBkgH/FAADMQFNA1IBoQNfAeMDXwHjA1IBoQMxAU0EAAMx
+ AU0DUgGhA18B4wNfAeMDUgGhAzEBTQwAAcwBtgGnAf8D/gH/A/4B/wP+Af8D/gH/A/4B/wP+Af8B/QH7
+ AfkB/wH9AfcB8wH/AfwB8gHsAf8B+wHsAeMB/wEEAgAB/yAAA0kBhwHjAa8BGQH/AfYBxAGQAv8BzQGZ
+ Af8B8wHCAY4B/wHjAbABGgH/A0MBeBwAAQwBqQHAAf8BAAHUAfoB/wGcAewB+gH/AasB7wH6Af8BpgHt
+ AfgB/wGUAecB+AH/ARIB2QH2Af8BAAG9AekB/wEAAR0BlwH/VAAB6gGqAYsB/wHqAaoBiwH/AeoBqgGL
+ Af8B6QGlAYQB/wHnAZcBDwH/AeYBjgEDAf8B4wEeAQAB/wHjARcBAAH/AeIBEwEAAf8B4gETAQAB/wHi
+ ARMBAAH/AcgBAwEAAf8kAANJAYcB4wGvARkB/wHuAb0BigH/AeMBsAEaAf8DNAFUIAABgAGzAcUB/wGb
+ Ad4B6wH/AcUB+QH9Af8BxQH5Af0B/wHFAfkB/QH/AcUB+QH9Af8BxQH5Af0B/wGgAd8B6gH/AQcBkQGi
+ Af9UAAHqAaoBiwL/AcIBogH/Af4BwAGfAf8B/QG9AZoB/wH7AbUBkAH/AfoBsAGLAf8B+AGnAR4B/wH2
+ AaIBGAH/AfUBnQESAf8B9QGZAQsB/wHzAZUBBgH/Ac0BBgEAAf8oAANAAW4B5QGyAR4B/wMmATgkAAM7
+ AWMDYAHWARcBqwG6Af8BEQGjAbMB/wENAZ0BrwH/AQwBmwGuAf8BEAGiAbQB/wNeAdkDQAFvVAAB6gGq
+ AYsB/wHqAaoBiwH/AeoBqgGLAf8B6gGqAYsB/wHpAaEBIAH/AegBmwEXAf8B5gGOAQMB/wHlAYcBAAH/
+ AeQBgQEAAf8B5AEcAQAB/wHjARcBAAH/AeIBEwEAAf//AP8ACgABQgFNAT4HAAE+AwABKAMAAUADAAFA
+ AwABAQEAAQEGAAECFgAD/4EABf8BwwIAAfABHwP/AYECAAHAAQcB8wGfAf8DAAGAAQMB5wHPAf8BwAIA
+ AYABAwHnAc8B/wQAAQEB5wHPAecEAAEBAecBzwHDAQEDAAEBAc8B5wGBBAABAQHnAc8FAAEBAecBzwUA
+ AQEB5wHPBQABAQHnAc8BAAEBAgABgAEDAfMBnwGAARMCAAGAAQMC/wHAAT8CAAHgAQcC/wHgAX8CAAHw
+ AR8C/wHwAf8CAAL/AfwBfwb/AfwBfwT/AfwBfwH8AX8BPwFzAv8B+AE/AfwBfwH5AeAB8AEHAfABHwH8
+ AX8B/wFBAfABBwHwAQ8B/AF/AoAB8AEHAfABDwH8AX8BwQEAAfABBwHgAQ8B+AE/Af8BAAHwAQcB4AEP
+ AfABHwGBAQAB8AEHAeABDwHgAQ8B/wEAAfABBwH4AQ8B4AEPAeABAAHwAQcB/AEfAeABDwH/AQEB8AEH
+ Af4BPwHjAY8B/wGDAv8B/QF/AeABDwH/AccE/wHgAQ8B/wHvBP8B8AEfDP8B+Af/AfABfwHwAQcE/wHg
+ AT8B8AEHAv8BwAEDAeABHwHwAQcBwAGBAcABAwHgAQ8B8AEHAYABAAHAAQMB4AEHAfABBwGAAQABwAED
+ AeABAwHwAQcBgAEAAcABAwHgAQcB8AEHAYABAAHAAQMB8AEHAfABBwGAAQABwAEDAfgBBwHwAQcBwAGB
+ AcABAwH8AQcB8AEHAv8BwAEDAf4BDwHwAQcC/wHAAQMB/wEfAfABBwL/AcABAxD/Cw==
+
+
+
+ False
+
+
\ No newline at end of file
diff --git a/Src/SwqlStudio/ObjectExplorer/StringBuilderExtensions.cs b/Src/SwqlStudio/ObjectExplorer/StringBuilderExtensions.cs
new file mode 100644
index 000000000..aa23abfe8
--- /dev/null
+++ b/Src/SwqlStudio/ObjectExplorer/StringBuilderExtensions.cs
@@ -0,0 +1,49 @@
+using System;
+using System.Text;
+using SwqlStudio.Metadata;
+
+namespace SwqlStudio
+{
+ internal static class StringBuilderExtensions
+ {
+ public static void AppendName(this StringBuilder builder, string name)
+ {
+ builder.AppendFormat("Name: {0}\r\n", name);
+ }
+
+ public static void AppendType(this StringBuilder builder, string metadataType)
+ {
+ builder.AppendFormat("Type: {0}\r\n", metadataType);
+ }
+
+ public static void AppendSummaryParagraph(this StringBuilder builder,string summary)
+ {
+ builder.Append("\r\n\r\n");
+ builder.AppendSummary(summary);
+ }
+
+ public static void AppendSummary(this StringBuilder builder,string summary)
+ {
+ if (String.IsNullOrEmpty(summary))
+ return;
+
+ var trimmed = summary.Trim();
+ builder.AppendFormat(trimmed);
+ }
+
+ public static void AppendAccessControl(this StringBuilder builder, ConnectionInfo connection, Entity entity)
+ {
+ if (entity.IsIndication)
+ {
+ builder.Append($@"Can Subscribe: {connection.CanCreateSubscription}");
+ }
+ else
+ {
+ builder.Append($"Can Read: {entity.CanRead}\r\n");
+ builder.Append($"Can Create: {entity.CanCreate}\r\n");
+ builder.Append($"Can Update: {entity.CanUpdate}\r\n");
+ builder.Append($"Can Delete: {entity.CanDelete}\r\n");
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Src/SwqlStudio/ObjectExplorer/TreeNodeUtils.cs b/Src/SwqlStudio/ObjectExplorer/TreeNodeUtils.cs
index 4c1610259..122752ef2 100644
--- a/Src/SwqlStudio/ObjectExplorer/TreeNodeUtils.cs
+++ b/Src/SwqlStudio/ObjectExplorer/TreeNodeUtils.cs
@@ -60,23 +60,28 @@ private static void CopyTree(TreeNodeCollection source, TreeNodeCollection targe
private static TreeNode CloneShallow(TreeNode node)
{
var treeNode = new TreeNode();
- treeNode.Text = node.Text;
- treeNode.Name = node.Name;
- treeNode.ImageIndex = node.ImageIndex;
- treeNode.SelectedImageIndex = node.SelectedImageIndex;
- treeNode.StateImageIndex = node.StateImageIndex;
-
- treeNode.SelectedImageKey = node.SelectedImageKey;
- treeNode.ImageKey = node.ImageKey;
- treeNode.Tag = node.Tag;
-
- treeNode.ToolTipText = node.ToolTipText;
- treeNode.ContextMenu = node.ContextMenu;
- treeNode.ContextMenuStrip = node.ContextMenuStrip;
- treeNode.Checked = node.Checked;
+ CopyContent(node, treeNode);
return treeNode;
}
+ internal static void CopyContent(TreeNode source, TreeNode target)
+ {
+ target.Text = source.Text;
+ target.Name = source.Name;
+ target.ImageIndex = source.ImageIndex;
+ target.SelectedImageIndex = source.SelectedImageIndex;
+ target.StateImageIndex = source.StateImageIndex;
+
+ target.SelectedImageKey = source.SelectedImageKey;
+ target.ImageKey = source.ImageKey;
+ target.Tag = source.Tag;
+
+ target.ToolTipText = source.ToolTipText;
+ target.ContextMenu = source.ContextMenu;
+ target.ContextMenuStrip = source.ContextMenuStrip;
+ target.Checked = source.Checked;
+ }
+
///
/// Used in filtering of the nodes.
///
diff --git a/Src/SwqlStudio/ObjectExplorer/TreeNodeWithConnectionInfo.cs b/Src/SwqlStudio/ObjectExplorer/TreeNodeWithConnectionInfo.cs
index 6554102d3..1b03d001b 100644
--- a/Src/SwqlStudio/ObjectExplorer/TreeNodeWithConnectionInfo.cs
+++ b/Src/SwqlStudio/ObjectExplorer/TreeNodeWithConnectionInfo.cs
@@ -1,35 +1,26 @@
using System;
using System.Windows.Forms;
+using SwqlStudio.Metadata;
namespace SwqlStudio
{
- public class TreeNodeWithConnectionInfo : TreeNode, ICloneable
+ internal class TreeNodeWithConnectionInfo : TreeNode
{
- public TreeNodeWithConnectionInfo(string text, ConnectionInfo connection) : base(text)
+ public IMetadataProvider Provider { get; }
+
+ public ConnectionInfo Connection => this.Provider.ConnectionInfo;
+
+
+ public TreeNodeWithConnectionInfo(string text, IMetadataProvider provider) : base(text)
{
- Connection = connection;
+ Provider = provider;
}
public TreeNode CloneShallow()
{
- var treeNode = new TreeNodeWithConnectionInfo(Text, Connection);
- treeNode.Text = Text;
- treeNode.Name = Name;
- treeNode.ImageIndex = ImageIndex;
- treeNode.SelectedImageIndex = SelectedImageIndex;
- treeNode.StateImageIndex = StateImageIndex;
-
- treeNode.SelectedImageKey = SelectedImageKey;
- treeNode.ImageKey = ImageKey;
- treeNode.Tag = Tag;
-
- treeNode.ToolTipText = ToolTipText;
- treeNode.ContextMenu = ContextMenu;
- treeNode.ContextMenuStrip = ContextMenuStrip;
- treeNode.Checked = Checked;
+ var treeNode = new TreeNodeWithConnectionInfo(this.Text, this.Provider);
+ TreeNodeUtils.CopyContent(this, treeNode);
return treeNode;
}
-
- public ConnectionInfo Connection { get; private set; }
}
}
diff --git a/Src/SwqlStudio/ObjectExplorer/TreeNodesBuilder.cs b/Src/SwqlStudio/ObjectExplorer/TreeNodesBuilder.cs
new file mode 100644
index 000000000..02ddde71c
--- /dev/null
+++ b/Src/SwqlStudio/ObjectExplorer/TreeNodesBuilder.cs
@@ -0,0 +1,197 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Windows.Forms;
+using SwqlStudio.Metadata;
+
+namespace SwqlStudio
+{
+ internal class TreeNodesBuilder
+ {
+ public EntityGroupingMode EntityGroupingMode { get; set; }
+
+ private static TreeNodeWithConnectionInfo MakeEntityTreeNode(IMetadataProvider provider, Entity entity)
+ {
+ var entityNode = CreateEntityNode(provider, entity);
+
+ // Add keys
+ AddPropertiesToNode(provider, entityNode, entity.Properties.Where(c => c.IsKey));
+
+ // Add the simple Properties
+ AddPropertiesToNode(provider, entityNode, entity.Properties.Where(c => !c.IsInherited && !c.IsNavigable && !c.IsKey));
+
+ // Add the inherited Properties
+ AddPropertiesToNode(provider, entityNode, entity.Properties.Where(c => c.IsInherited && !c.IsNavigable && !c.IsKey));
+
+ // Add the Navigation Properties
+ AddPropertiesToNode(provider, entityNode, entity.Properties.Where(c => c.IsNavigable));
+
+ AddVerbsToNode(entityNode, entity, provider);
+ return entityNode;
+ }
+
+ private static void AddVerbsToNode(TreeNode entityNode, Entity entity, IMetadataProvider provider)
+ {
+ foreach (var verb in entity.Verbs.OrderBy(v => v.Name))
+ {
+ TreeNode verbNode = CreateNode(provider, verb.Name, ImageKeys.Verb, verb);
+ verbNode.ToolTipText = DocumentationBuilder.ToToolTip(verb);
+
+ var argumentsPlaceholder = new ArgumentsPlaceholderTreeNode(verb, provider);
+ verbNode.Nodes.Add(argumentsPlaceholder);
+
+ entityNode.Nodes.Add(verbNode);
+ }
+ }
+
+ private static void AddPropertiesToNode(IMetadataProvider provider, TreeNode entityNode, IEnumerable properties)
+ {
+ foreach (Property property in properties.OrderBy(c => c.Name))
+ {
+ string name = DocumentationBuilder.ToNodeText(property);
+ var imageKey = ImageKeys.GetImageKey(property);
+ TreeNode node = CreateNode(provider, name, imageKey, property);
+ node.ToolTipText = DocumentationBuilder.ToToolTip(property);
+ entityNode.Nodes.Add(node);
+ }
+ }
+
+ public static void RebuildVerbArguments(TreeNode verbNode, IMetadataProvider provider)
+ {
+ verbNode.Nodes.Clear();
+ var verb = verbNode.Tag as Verb;
+
+ foreach (var argument in provider.GetVerbArguments(verb))
+ {
+ var argNode = CreateVerbArgumentNode(provider, argument);
+ verbNode.Nodes.Add(argNode);
+ }
+ }
+
+ private static TreeNodeWithConnectionInfo[] MakeEntityTreeNodes(IMetadataProvider provider, IEnumerable entities)
+ {
+ return entities.Select(e => MakeEntityTreeNode(provider, e)).ToArray();
+ }
+
+ public void RebuildDatabaseNode(TreeNode databaseNode, IMetadataProvider provider)
+ {
+ databaseNode.Nodes.Clear();
+
+ switch (this.EntityGroupingMode)
+ {
+ case EntityGroupingMode.Flat:
+ databaseNode.Nodes.AddRange(MakeEntityTreeNodes(provider, provider.Tables.OrderBy(e => e.FullName)));
+ break;
+ case EntityGroupingMode.ByNamespace:
+ foreach (var group in provider.Tables.GroupBy(e => e.Namespace).OrderBy(g => g.Key))
+ {
+ TreeNode[] entityNodes = MakeEntityTreeNodes(provider, group.OrderBy(e => e.FullName));
+ var namespaceNode = CreateNamespaceNode(provider, entityNodes, group.Key);
+ databaseNode.Nodes.Add(namespaceNode);
+ }
+ break;
+ case EntityGroupingMode.ByBaseType:
+ foreach (var group in provider.Tables.Where(e => e.BaseEntity != null).GroupBy(
+ e => e.BaseEntity,
+ (key, group) => new { Key = key, Entities = group }).OrderBy(item => item.Key.FullName))
+ {
+ TreeNode[] childNodes = MakeEntityTreeNodes(provider, group.Entities.OrderBy(e => e.FullName));
+ var entityNode = CreateEntityNode(provider, group.Key, childNodes);
+ databaseNode.Nodes.Add(entityNode);
+ }
+ break;
+ case EntityGroupingMode.ByHierarchy:
+ GroupByHierarchy(provider, databaseNode);
+ break;
+ default:
+ throw new ArgumentOutOfRangeException();
+ }
+ }
+
+ private static void GroupByHierarchy(IMetadataProvider provider, TreeNode baseNode)
+ {
+ Entity baseEntity = baseNode != null ? baseNode.Tag as Entity : null;
+
+ var entities = provider.Tables.Where(e => baseEntity == null ? e.BaseEntity == null : e.BaseEntity == baseEntity);
+
+ if (entities.Any())
+ {
+ TreeNode[] childNodes = MakeEntityTreeNodes(provider, entities.OrderBy(e => e.FullName));
+
+ baseNode.Nodes.AddRange(childNodes);
+
+ if (baseEntity != null)
+ {
+ baseNode.Text = DocumentationBuilder.ToBaseNodeText(baseNode, childNodes.Length);
+ }
+
+ foreach (var node in childNodes)
+ {
+ GroupByHierarchy(provider, node);
+ }
+
+ if (baseEntity == null)
+ {
+ foreach (var node in childNodes)
+ {
+ node.Expand();
+ }
+ baseNode.Expand();
+ }
+ }
+ }
+
+ public static TreeNodeWithConnectionInfo CreateDatabaseNode(TreeView treeView, IMetadataProvider provider,
+ ConnectionInfo connection)
+ {
+ TreeNodeWithConnectionInfo node = CreateNode(provider, provider.Name, ImageKeys.Database, provider);
+ node.Name = node.Text;
+ treeView.Nodes.Add(node);
+ treeView.SelectedNode = node;
+ return node;
+ }
+
+ public static TreeNodeWithConnectionInfo CreateNamespaceNode(IMetadataProvider provider, TreeNode[] entityNodes, string namespaceName)
+ {
+ var name = DocumentationBuilder.ToNodeText(namespaceName, entityNodes.Length);
+ var namespaceNode = CreateNode(provider, name, ImageKeys.Namespace, namespaceName);
+ namespaceNode.Nodes.AddRange(entityNodes);
+ return namespaceNode;
+ }
+
+ private static TreeNodeWithConnectionInfo CreateEntityNode(IMetadataProvider provider, Entity entity, TreeNode[] childNodes)
+ {
+ var imageKey = !entity.IsAbstract ? ImageKeys.BaseType : ImageKeys.BaseTypeAbstract;
+ var name = DocumentationBuilder.ToNodeText(entity.FullName, childNodes.Length);
+ var entityNode = CreateNode(provider, name, imageKey, entity);
+
+ entityNode.Nodes.AddRange(childNodes);
+ return entityNode;
+ }
+
+ private static TreeNodeWithConnectionInfo CreateEntityNode(IMetadataProvider provider, Entity entity)
+ {
+ var imageKey = ImageKeys.GetImageKey(entity);
+ var node = CreateNode(provider, entity.FullName, imageKey, entity);
+ node.ToolTipText = DocumentationBuilder.ToToolTip(provider.ConnectionInfo, entity);
+ return node;
+ }
+
+ private static TreeNodeWithConnectionInfo CreateVerbArgumentNode(IMetadataProvider provider, VerbArgument argument)
+ {
+ string text = DocumentationBuilder.ToNodeText(argument);
+ var argNode = CreateNode(provider, text, ImageKeys.Argument, argument);
+ argNode.ToolTipText = DocumentationBuilder.ToToolTip(argument);
+ return argNode;
+ }
+
+ private static TreeNodeWithConnectionInfo CreateNode(IMetadataProvider provider, string name, string imageKey, object data)
+ {
+ var node = new TreeNodeWithConnectionInfo(name, provider);
+ node.ImageKey = imageKey;
+ node.SelectedImageKey = imageKey;
+ node.Tag = data;
+ return node;
+ }
+ }
+}
\ No newline at end of file
diff --git a/Src/SwqlStudio/QueriesDockPanel.cs b/Src/SwqlStudio/QueriesDockPanel.cs
index 023380080..342531d47 100644
--- a/Src/SwqlStudio/QueriesDockPanel.cs
+++ b/Src/SwqlStudio/QueriesDockPanel.cs
@@ -4,6 +4,7 @@
using System.Windows.Forms;
using ScintillaNET;
using SolarWinds.InformationService.Contract2;
+using SwqlStudio.Metadata;
using WeifenLuo.WinFormsUI.Docking;
namespace SwqlStudio
@@ -15,6 +16,7 @@ public partial class QueriesDockPanel : DockPanel
private ObjectExplorer objectExplorer;
private DockContent objectExplorerContent;
private QueryParameters queryParametersContent;
+ private DocumentationContent documentationContent;
public PropertyBag QueryParameters
{
@@ -55,6 +57,7 @@ public QueriesDockPanel()
InitializeDockPanel();
InitializeObjectExplorer();
InitializeQueryParameters();
+ InitializeDocumentation();
}
public void CreateTabFromPrevious()
@@ -83,11 +86,6 @@ private bool HasActiveContent()
return this.lastActiveContent != null;
}
- internal void SetObjectExplorerImageList(ImageList imageList)
- {
- this.objectExplorer.ImageList = imageList;
- }
-
private void InitializeDockPanel()
{
// Workaround for crash, when form is MDI
@@ -103,7 +101,7 @@ private void InitializeObjectExplorer()
{
this.objectExplorer = new ObjectExplorer();
this.objectExplorer.Dock = DockStyle.Fill;
- this.objectExplorer.EntityGroupingMode = EntityGroupingMode.Flat;
+ this.objectExplorer.SetGroupingMode(EntityGroupingMode.Flat);
this.objectExplorer.Location = new System.Drawing.Point(0, 0);
this.objectExplorer.Name = "objectExplorer";
this.objectExplorer.Size = new System.Drawing.Size(191, 571);
@@ -123,6 +121,19 @@ private void InitializeQueryParameters()
this.queryParametersContent.Show(this, DockState.DockRightAutoHide);
}
+ private void InitializeDocumentation()
+ {
+ this.documentationContent = new DocumentationContent();
+ ConfigureBuildInToolbox(this.documentationContent);
+ this.objectExplorer.SelectionChanged += ObjectExplorer_SelectionChanged;
+ this.documentationContent.Show(this.objectExplorerContent.Pane, DockAlignment.Bottom, 0.25);
+ }
+
+ private void ObjectExplorer_SelectionChanged(object sender, TreeViewEventArgs e)
+ {
+ this.documentationContent.UpdateDocumentation(e.Node);
+ }
+
private void ConfigureBuildInToolbox(DockContent content)
{
content.CloseButton = false;
@@ -141,6 +152,7 @@ private void FilesDock_ActiveContentChanged(object sender, EventArgs e)
if (newContent != null &&
newContent != this.objectExplorerContent &&
newContent != this.queryParametersContent &&
+ newContent != this.documentationContent &&
newContent != this.lastActiveContent)
{
this.ActiveQueryTab?.PutParameters();
@@ -168,7 +180,7 @@ internal void ShowParametersToolbox()
internal void SetEntityGroupingMode(EntityGroupingMode mode)
{
- objectExplorer.EntityGroupingMode = mode;
+ objectExplorer.SetGroupingMode(mode);
objectExplorer.RefreshAllServers();
}
diff --git a/Src/SwqlStudio/QueryTab.cs b/Src/SwqlStudio/QueryTab.cs
index 397f637f1..7fa26347d 100644
--- a/Src/SwqlStudio/QueryTab.cs
+++ b/Src/SwqlStudio/QueryTab.cs
@@ -11,6 +11,7 @@
using System.Xml;
using System.Xml.Linq;
using SolarWinds.InformationService.Contract2;
+using SwqlStudio.Metadata;
using SwqlStudio.Playback;
using SwqlStudio.Properties;
using SwqlStudio.Subscriptions;
diff --git a/Src/SwqlStudio/SciTextEditorControl.cs b/Src/SwqlStudio/SciTextEditorControl.cs
index 4eeefa97d..987fd3021 100644
--- a/Src/SwqlStudio/SciTextEditorControl.cs
+++ b/Src/SwqlStudio/SciTextEditorControl.cs
@@ -3,6 +3,7 @@
using System.Windows.Forms;
using ScintillaNET;
using System.Linq;
+using SwqlStudio.Metadata;
using SwqlStudio.Properties;
namespace SwqlStudio
diff --git a/Src/SwqlStudio/ServerList.cs b/Src/SwqlStudio/ServerList.cs
index 34cc416cf..af907f0f7 100644
--- a/Src/SwqlStudio/ServerList.cs
+++ b/Src/SwqlStudio/ServerList.cs
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
+using SwqlStudio.Metadata;
namespace SwqlStudio
{
diff --git a/Src/SwqlStudio/SwqlStudio.csproj b/Src/SwqlStudio/SwqlStudio.csproj
index bffc57968..505d4ee82 100644
--- a/Src/SwqlStudio/SwqlStudio.csproj
+++ b/Src/SwqlStudio/SwqlStudio.csproj
@@ -181,6 +181,12 @@
+
+ Form
+
+
+ DocumentationContent.cs
+
Form
@@ -205,13 +211,21 @@
+
+
+
+
+
Component
+
+
+
@@ -249,11 +263,11 @@
NewConnection.cs
-
+
Component
-
+
@@ -324,6 +338,9 @@
CrudTab.cs
Designer
+
+ DocumentationContent.cs
+
EntityClassGraphForm.cs
Designer
@@ -334,6 +351,9 @@
MainForm.cs
+
+ ObjectExplorer.cs
+
ResXFileCodeGenerator
Designer