diff --git a/samples/LineCounter/Article/LineCounterSharpDevelopAddIn.html b/samples/LineCounter/Article/LineCounterSharpDevelopAddIn.html new file mode 100644 index 0000000000..e01d449a0c --- /dev/null +++ b/samples/LineCounter/Article/LineCounterSharpDevelopAddIn.html @@ -0,0 +1,609 @@ + + + + + + + + +
+

+ +

+

+ Introduction
+

+When seeing the article +Line +Counter - Writing a Visual Studio 2005 Add-In +[^], +I wanted to show you how to write that AddIn for SharpDevelop.
+In this article I will show you how to create an AddIn, but I will not discuss +the concepts of the SharpDevelop's AddIn architecture here - you can read more +about that in my article +Building +Applications with the SharpDevelop Core +[^]. +The line counter code is taken from the VS 2005 AddIn written by Jon Rista; the +counting algorithm itself is from Oz Solomon.
+
+

+ Creating a new AddIn +

+Our AddIn will be a menu entry in the "Tools" menu that opens a document window +displaying the line counter UI. SharpDevelop already comes with a project +template for an AddIn extending the "Tools" menu: "Tools menu entry"
+
+
+We create a SharpDevelop Macro with the name "LineCounter". The "SharpDevelop +AddIn" template could also be used, but it starts with an AddIn defining a pad +(a docked tool window like "Projects", "Properties"); the "Tool menu entry" +AddIn starts with a menu command.
+Now let's look at what SharpDevelop has generated for us:
+We have a project with a few files:
+
+First look at the .addin file:
+The template already defines a menu item in the tools menu, we'll just modify +the label. And we'll add a new section to the .addin file: the <Manifest> +section. Our AddIn needs a unique identity - use something like a namespace +name. Because we don't want lots of AddIns with the identity "AddIn1" around, +the template does not contain the manifest section by default. The identity is +not strictly required, but it allows us to use SharpDevelop's AddIn manager for +our AddIn - and it is also required when other AddIns want to reference your +AddIn. Because the API between SharpDevelop 2.0.x.y and SharpDevelop 2.1.a.b +will change a bit, we use the dependency to ensure that our AddIn can only be +installed into SharpDevelop 2.0.*.*.
+Since our LineCounter will only work when a solution is opened, we put the menu +item inside a <Condition name="SolutionOpen" action="disable">
+Here is how the content of LineCounter.addin should look like after these steps:
+
<AddIn name        = "LineCounter"
+       author      = "Daniel Grunwald"
+       url         = "http://www.codeproject.com/useritems/LineCounterSharpDevelopAddIn.asp"
+       description = "Advanced line counter AddIn">
+   
+    <Manifest>
+        <Identity>Grunwald.LineCounter</Identity>
+        <Dependency addin="SharpDevelop" version="2.0"/>
+    </Manifest>
+   
+    <Runtime>
+        <Import assembly = "LineCounter.dll"/>
+    </Runtime>
+   
+    <Path name = "/Workspace/Tools">
+        <!-- disable our menu item if condition "SolutionOpen" is not met -->
+        <Condition name="SolutionOpen" action = "disable">
+            <MenuItem id = "LineCounterCommand1"
+                      label = "Show Line Counter"
+                      class = "Grunwald.LineCounter.ToolCommand1"/>
+        </Condition>
+    </Path>
+</AddIn>
+
Our menu item uses the "class" attribute. When the menu item is +clicked, SharpDevelop will create an instance of this class and call its Run() +method. This class is defined the file Command.cs. The example code from the +template accesses the currently opened text editor and reverses the letters in +the currently selected text. We are not interested in accessing the text editor, +so we can delete the content of the Run() method and start writing our own.
+

+ Testing +

+However, first we want to get our AddIn running. For testing, we'll display a +MessageBox inside Run(). If you now try to compile the AddIn, you'll get errors +about missing references. This is because the template is missing the assembly +references to the SharpDevelop libraries - these have to hard-coded paths in +most cases, so you should add them manually. Add references to +ICSharpCode.Core.dll and ICSharpCode.SharpDevelop.dll from the bin directory of +your SharpDevelop installation. ICSharpCode.Core contains the AddIn system, we +need the base class of our menu command from it. ICSharpCode.SharpDevelop is the +largest part of SharpDevelop, we'll use the project system from it.
+Make sure you set "Local copy" for the references to +False.
+
+
+You should now be able to successfully compile the project. If you look into the +bin/Debug directory, you will see a copy of LineCounter.addin, the compiled +LineCounter.dll and the debug symbols.
+If you want to test your AddIn, you need to register it with SharpDevelop. The +best way for testing is to copy these files to the AddIns directory of your +SharpDevelop installation. Restart SharpDevelop to let it load the AddIn. You +should see the "Line Counter" command in the Tools menu, disabled until you open +a solution. If you click the menu item, the message box should show up.
+If you want to update your AddIn, you'll need to shutdown SharpDevelop, copy the +files and restart it. If you do this a few times, you'll probably want to use a +separate installation of SharpDevelop to develop your AddIn, so you can leave +your development environment opened. Alternatively, you could use +Visual Studio to write your AddIn...
+

+ Creating the line counter +

+Now to the real work: Implementing the line counter. We want to display the line +counter user interface as a document, like the start page. Document views in +SharpDevelop are called ViewContents. +There are two types of view contents: primary and secondary. A primary view +content is capable of displaying something on its own; a secondary view content +extends another view content by displaying multiple tabs in the document - +SharpDevelop's Windows.Forms designer is a secondary view content. We want to +display a simple document view, so we'll use a normal (primary) view +content.
+
+
Showing such a view content is easy:
+
public override void Run()
+{
+    WorkbenchSingleton.Workbench.ShowView(new LineCounterViewContent());
+}
+
+Now create the new class named LineCounterViewContent. Let it derive from +ICSharpCode.SharpDevelop.Gui.AbstractViewContent to get default implementations +for most of the IViewContent members.
+We will need to implement the abstract property Control - here we have to return +the control to display.
+
+public class LineCounterViewContent : AbstractViewContent
+{
+    LineCounterBrowser browser = new LineCounterBrowser();
+    public override Control Control {
+        get { return browser; }
+    }
+    public LineCounterViewContent() {
+        this.TitleName = "Line Counter";
+    }
+}
+

+This control is a UserControl copied from the +Visual +Studio Line Counter article +[^] — +copy LineCounterBrowser.* into the "Src" directory and use "Add existing file" +to add LineCounterBrowser.cs to the project. SharpDevelop should add +LineCounterBrowser.Designer.cs and LineCounterBrowser.resx automatically.
+Now we still have to change the parts where the line counter references Visual +Studio's EnvDTE class and replace them with the appropriate calls to the +SharpDevelop API.
+

+ Accessing the project in SharpDevelop +

+First fix the using-Statements: remove those importing Visual Studio namespaces. +Instead we will use:
+
using ICSharpCode.SharpDevelop.Project;
+Then remove the variable and property referencing the EnvDTE +object.
+Now move on to the methods. The first method requiring a rewrite is +"ScanSolution". We can simply get the solution instance from a static class: +ProjectService.
+
    Solution solution = ProjectService.OpenSolution;
+    if (solution != null)  // OpenSolution is null when no solution is opened
+    {
+        FileInfo fiSolution = new FileInfo(solution.FileName);
+
+SharpDevelop doesn't need "plural" classes like "Projects", but +uses the standard .NET collection classes. Unlike Visual Studio, +solution.Projects returns all projects; including those in solution folders. +It's implemented as iterator (with yield return), that's why you don't have +something simple as solution.Projects.Count. As I cannot really imagine +solutions with thousands of projects, we can just copy the values returned by +the iterator into a list to have a normal collection to work with.
+
        List<IProject> projects = new List<IProject>(solution.Projects);
+        tsprgTotal.Maximum = projects.Count;
+        tsprgTask.Value = 0;
+        foreach (IProject fiProject in projects) {
+
+As you might guess, IProject is the interface all projects +implement. The actual object type depends on the project type - every language +binding comes with its own project class (but SharpDevelop contains the classes +AbstractProject and MSBuildProject they can inherit most functionality from).
+The loop body can be simplified quite a bit: SharpDevelop will display its usual +error handling dialog box for unhandled exceptions, so we don't need to use +try-catch to redirect them to the debug view (where nobody really reads +them...). The language ID is a straightforward property of the IProject +interface, no need to query the CodeModel.
+
        foreach (IProject fiProject in projects) {
+            tsprgTotal.PerformStep();
+            string projName, lang;
+            if (fiProject.FileName.IndexOf("://") != -1)
+            {
+                projName = fiProject.FileName; // this is a web project
+                lang = "{00000001-0000-0000-0000-000000000000}";
+            } else {
+                projName = fiProject.Name;
+                lang = fiProject.TypeGuid;
+            }
+
+            int iconIndex;
+            m_projIconMappings.TryGetValue(lang, out iconIndex); // default icon 0
+            summary = new LineCountSummary(projName, iconIndex);
+            m_summaryList.Add(summary);
+
+            tsprgTask.Maximum = 0;
+            tsprgTotal.Value = 0;
+            ScanProjectItems(fiProject.Items, summary);
+        }
+
+ScanProjectItems is the next method we'll look at. ProjectItems becomes +List<ProjectItem>. You'll also need to change the summary since +SharpDevelop stores all project items in this collection - no need to use +recursion to get Designer.cs files. In the SharpDevelop model, every project +item is exactly one file. This simplifies the method greatly:
+
private void ScanProjectItems(List<ProjectItem> projectItems, LineCountSummary summary)
+{
+    tsprgTask.Maximum += projectItems.Count;
+    foreach (ProjectItem projectItem in projectItems)
+    {
+        tsprgTask.PerformStep();
+        if (!(projectItem is FileProjectItem)) {
+            // Skip references and other special MSBuild things
+            continue;
+        }
+        string projectFile = projectItem.FileName;
+        if (!Directory.Exists(projectFile))
+        {
+            int iconIndex = 0;
+            m_fileIconMappings.TryGetValue(Path.GetExtension(projectFile), out iconIndex);
+            summary.FileLineCountInfo.Add(new LineCountInfo(projectFile, iconIndex, summary));
+        }
+    }
+}
+Now try to compile again. The only thing missing is +"CodeModelLanguageConstants", a class containing the GUIDs for C#, VB and +(M)C++. SharpDevelop supports C#, VB, Boo and MSIL projects; this is not +matching the icons we imported from the Visual Studio AddIn. We'll look for a +way to get icons directly from SharpDevelop soon; for now just hard-code the +values for C# and VB:
+
// Map project types to icons for use in the projects list
+m_projIconMappings = new Dictionary<string, int>();
+m_projIconMappings.Add("{00000000-0000-0000-0000-000000000000}", 0);
+m_projIconMappings.Add("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}", 1); // C#
+m_projIconMappings.Add("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}", 2); // VB
+m_projIconMappings.Add("{00000001-0000-0000-0000-000000000000}", 5);
+
+

+ This fixes all compile errors. And if you test it, you'll find that it even + runs correctly! :-) +

+

+ Although the extension process is very different in SharpDevelop and Visual + Studio; the API is quite similar - after all, both are modelling MSBuild + solutions and after a similar feature set. I hope this shows you that porting + AddIns from Visual Studio to SharpDevelop isn't very hard and we would like to + see more SharpDevelop AddIns in the future. +

+

+ Here an image showing the AddIn counting itself: +

+

+ +

+

+ Possible improvements +

+While this is a basic port of the AddIn to SharpDevelop, there are lots of +possibilities for improvement.
+

+ Getting Icons from SharpDevelop +

+First, we to replace some bad code in AddFileListItem: Remove the code from the +"TODO: Add image index setting" command to the "lvi.ImageIndex = iconIndex;" +line and replace it with "lvi.ImageIndex = info.IconIndex;". Now only one +read-access on the m_fileIconMappings hashtable is left - the one in +ScanProjectItems.
+Before we can continue, we need to be aware how SharpDevelop deals with icons:
+Menu items are defined in XML and can be shown before the AddIn library is +loaded. Because of that, resource files can be registered in XML which makes the +icons inside it available to the ICSharpCode.Core.ResourceService. AddIns like +language bindings can register such file extensions and project types with such +icons. SharpDevelop's class IconService provides convenience methods for +accessing these icons: GetImageForFile or GetImageForProjectType get the icon's +name by looking up the project type or file extension. If you have an icon name, +you can use GetBitmap or GetIcon to access it. The ResourceService converts +between Bitmap and Icon on demand, but it is suggested to use .png bitmaps in +the resource files and the GetBitmap method to load them.
+This means with these simple IconService methods we can load the bitmap for the +correct project/file type, just like SharpDevelop's project browser does.
+The line counter code uses image lists with a few predefined images. Because I +do not want to change it, I will just introduce a new class ImageListHelper that +can add SharpDevelop icons to an existing image list.
+
public class ImageListHelper
+{
+    ImageList imageList;
+    Dictionary<string, int> dict = new Dictionary<string, int>();
+    
+    public ImageListHelper(ImageList imageList)
+    {
+        if (imageList == null)
+            throw new ArgumentNullException("imageList");
+        this.imageList = imageList;
+    }
+    
+    public int GetIndex(string imageName)
+    {
+        int index;
+        if (!dict.TryGetValue(imageName, out index)) {
+            index = imageList.Images.Count;
+            imageList.Images.Add(IconService.GetBitmap(imageName));
+            dict[imageName] = index;
+        }
+        return index;
+    }
+}
+
+We +will use two instances of this class to control the two image lists +imgProjectTypes and imgFileTypes.
+ScanSolution() is getting the icon index from m_projIconMappings - we will +change this line to use our ImageListHelper instead.
+Replace "m_projIconMappings.TryGetValue(lang, out iconIndex);" with
+
iconIndex = projectImageListHelper.GetIndex(IconService.GetImageForProjectType(fiProject.Language));
+
Do the same for the file icons in ScanProjectItems():
+
iconIndex = fileImageListHelper.GetIndex(IconService.GetImageForFile(projectFile));
+
+

+ Now the AddIn is using the icons shipping with SharpDevelop and will + automatically use the icons of other languages added to SharpDevelop.
+

+

+ Adding new counting algorithms +

+The great thing about the SharpDevelop AddIn infrastructure is that it allows +one AddIn to extend another. We will modify the Line Counter in such a way that +it is possible for other AddIns to introduce new counting algorithms. We want to +lazy-load our counting algorithms only when a file of the specified type is +encountered.
+This leads to the doozer-descriptor-implementation pattern you will often see +for extendable SharpDevelop features.
+
+In the AddInTree, one can register classes - we already did this with the +command for our menu item. We will add a new path to the AddInTree containing +counting algorithm implementations. We will have to use classes instead of +methods to be able to register them in the AddInTree, so let's create an +interface and the classes:
+
public interface ICountingAlgorithm
+{
+    void CountLines(LineCountInfo info);
+}
+
+public class CountingAlgorithmGeneric : ICountingAlgorithm {
+    public void CountLines(LineCountInfo info) {
+        LineCounterBrowser.CountLinesGeneric(info);
+    }
+}
+public class CountingAlgorithmCStyle : ICountingAlgorithm {
+    public void CountLines(LineCountInfo info) {
+        LineCounterBrowser.CountLinesCStyle(info);
+    }
+}
+public class CountingAlgorithmVBStyle : ICountingAlgorithm {
+    public void CountLines(LineCountInfo info) {
+        LineCounterBrowser.CountLinesVBStyle(info);
+    }
+}
+public class CountingAlgorithmXmlStyle : ICountingAlgorithm {
+    public void CountLines(LineCountInfo info) {
+        LineCounterBrowser.CountLinesXMLStyle(info);
+    }
+}
+
The Count* methods in LineCounterBrowser have been changed from +"private" to "internal static".
+We still need a way to associate the algorithms with file extensions. This is +done directly in the XML code defining the AddInTree:
+
<Path name = "/AddIns/LineCounter/CountingAlgorithms">
+    <LineCountingAlgorithm
+        id = "Generic"
+        extensions = ".txt;.res;.sql;.cd"
+        class = "LineCounterAddin.CountingAlgorithmGeneric" />
+    <LineCountingAlgorithm
+        id = "CStyle"
+        extensions = ".cs;.vj;.js;.cpp;.cc;.cxx;.c;.hpp;.hh;.hxx;.h;.idl;.odl;.css"
+        class = "LineCounterAddin.CountingAlgorithmCStyle" />
+    <LineCountingAlgorithm
+        id = "VBStyle"
+        extensions = ".vb;.vbs"
+        class = "LineCounterAddin.CountingAlgorithmVBStyle" />
+    <LineCountingAlgorithm
+        id = "XmlStyle"
+        extensions = ".xml;.xsl;.xslt;.xsd;.config;.resx;.aspx;.ascx;.ashx;.asmx;.asax;.html;.html"
+        class = "LineCounterAddin.CountingAlgorithmXmlStyle" />
+</Path>
+
Because we are using custom attributes, we are using a new codon +name "LineCountingAlgorithm". Don't be irritated that it's not defined in the +XML schema for .addin files - we are creating a new possible codon name here; +the XML schema is just for code completion when editing the .addin file.
+Now how can we define this codon type? Constructing objects from the AddInTree +is done by the doozers (the name comes +from +these +guys +[^]). +This means you have to register a new doozer for line counting algorithms.
+This is done by editing the <Runtime> section of your .addin file:
+
<Import assembly = "LineCounter.dll">
+    <Doozer name="LineCountingAlgorithm" class="LineCounterAddin.CountingAlgorithmDoozer"/>
+</Import>
+
The CountingAlgorithmDoozer class has to implement the +ICSharpCode.Core.IDoozer interface:
+
public class CountingAlgorithmDoozer : IDoozer
+{
+    public bool HandleConditions {
+        get {
+            // our doozer cannot handle conditions, let SharpDevelop
+            // do that for us
+            return false;
+        }
+    }
+   
+    public object BuildItem(object caller, Codon codon, System.Collections.ArrayList subItems)
+    {
+        return new CountingAlgorithmDescriptor(codon.AddIn,
+                                               codon.Properties["extensions"],
+                                               codon.Properties["class"]);
+    }
+}
+
This means our doozer will always build objects of the type +CountingAlgorithmDescriptor. Let's define that class:
+
public class CountingAlgorithmDescriptor
+{
+    AddIn addIn;
+    string[] extensions;
+    string className;
+   
+    public CountingAlgorithmDescriptor(AddIn addIn, string extensions, string className)
+    {
+        this.addIn = addIn;
+        this.extensions = extensions.ToLowerInvariant().Split(';');
+        this.className = className;
+    }
+   
+    public bool CanCountLines(LineCountInfo info)
+    {
+        return (Array.IndexOf(extensions, info.FileType.ToLowerInvariant()) >= 0);
+    }
+   
+    ICountingAlgorithm cachedAlgorithm;
+   
+    public ICountingAlgorithm GetAlgorithm()
+    {
+        if (cachedAlgorithm == null) {
+            cachedAlgorithm = (ICountingAlgorithm)addIn.CreateObject(className);
+        }
+        return cachedAlgorithm;
+    }
+}
+

+

+ Now only the change to LineCounterBrowser to actually use this code is + missing. +

+We will need a member variable storing the list of existing counting algorithms:
+
List<CountingAlgorithmDescriptor> countingAlgorithms;
+
Initialising this list in the constructor is easy:
+
+countingAlgorithms = AddInTree.BuildItems<CountingAlgorithmDescriptor>
+                        ("/AddIns/LineCounter/CountingAlgorithms", this);
+// Iterate through algorithms to fill list of known countable types
+foreach (CountingAlgorithmDescriptor desc in countingAlgorithms) {
+    m_countableTypes.AddRange(desc.extensions);
+}
+
+

+ And finally, replace the usage of m_countAlgorithms in the inner try-catch + block in SumSolution() with this code: +

+
+    foreach (CountingAlgorithmDescriptor desc in countingAlgorithms) {
+        if (desc.CanCountLines(info)) {
+            desc.GetAlgorithm().CountLines(info);
+            break;
+        }
+    }
+
+

+
+

+

+ So, let's reiterate how this extension model works: +

+

+ When SharpDevelop starts, SharpDevelop only loads your .addin file, but this + bit of XML parsing is quite fast. Your .dll is not loaded, but SharpDevelop + remembers where it has to look when the CountingAlgorithmDoozer is needed. Now + the user opens a solution and clicks on "Tools > Show Line Counter". + Launching the menu command will load you AddIn assembly and create an instance + of the ToolCommand1 class and call Run() on it. The LineCounterBrowser + constructor now calls AddInTree.BuildItems for + /AddIns/LineCounter/CountingAlgorithms. To build the items in that path, the + doozer is required, so SharpDevelop creates the doozer instance here and uses + it to build all items. The doozer does not create instances of the algorithm + classes; it only creates a descriptor instance. +

+

+ Only when counting the lines in a file of any matching extension, the + descriptor creates an instance of the class. The "AddIn" stored is the context + in which the class name occured - it knows which runtime assemblies were + specified in that XML file.
+

+

+ If there were additional algorithms in other assemblies (for example a Boo + line counter), those assemblies would be loaded only if you count files in + those languages. +

+

+ This means unused SharpDevelop AddIns use very little memory and startup time + (if their extension points are coded properly) - it only takes parsing the + XML, storing the resulting codons in a compact object tree where they are + mixed with the other AddIns' codons.
+

+

+ Creating an AddIn installation package +

+Now to move to a completely different and much easier topic at the end: we want +to have an easy way for users to install, update and uninstall our AddIn.
+
+Creating a SharpDevelop AddIn installation package (.sdaddin file) is easy. Just +create a zip file containing LineCounter.addin and LineCounter.dll and rename +the zip file to "LineCounter.sdaddin". That really was everything you had to do +- double-clicking this .sdaddin file will open SharpDevelop's AddIn manager +where you can install the AddIn with just one click. AddIns installed this way +will be extracted to %Application Data%\.ICSharpCode\SharpDevelop2\AddIns.
+
+
+

+ More AddIn-writing help +

+ +
+

+ License +

+

+ SharpDevelop 2.0 is released under the terms of the GNU Lesser General Public + License. In plain English, that means you can use any license you want for + your own AddIns and do not have to open-source them. You only have to release + modifications to the SharpDevelop libraries.
+

+

+ Summary +

+

+ This article shows you how to start writing SharpDevelop AddIns. It is a + complete walkthrough from creating a new project to creating the installation + package. +

+

+ History +

+ +
+
+
+
+
+ \ No newline at end of file diff --git a/samples/LineCounter/Article/LineCounterSharpDevelopAddIn/addinmanager.png b/samples/LineCounter/Article/LineCounterSharpDevelopAddIn/addinmanager.png new file mode 100644 index 0000000000..390fff1ad3 Binary files /dev/null and b/samples/LineCounter/Article/LineCounterSharpDevelopAddIn/addinmanager.png differ diff --git a/samples/LineCounter/Article/LineCounterSharpDevelopAddIn/projectbrowser.png b/samples/LineCounter/Article/LineCounterSharpDevelopAddIn/projectbrowser.png new file mode 100644 index 0000000000..2ed27ef6b3 Binary files /dev/null and b/samples/LineCounter/Article/LineCounterSharpDevelopAddIn/projectbrowser.png differ diff --git a/samples/LineCounter/Article/LineCounterSharpDevelopAddIn/properties.png b/samples/LineCounter/Article/LineCounterSharpDevelopAddIn/properties.png new file mode 100644 index 0000000000..0b226ff166 Binary files /dev/null and b/samples/LineCounter/Article/LineCounterSharpDevelopAddIn/properties.png differ diff --git a/samples/LineCounter/Article/LineCounterSharpDevelopAddIn/screenshot.png b/samples/LineCounter/Article/LineCounterSharpDevelopAddIn/screenshot.png new file mode 100644 index 0000000000..87add37854 Binary files /dev/null and b/samples/LineCounter/Article/LineCounterSharpDevelopAddIn/screenshot.png differ diff --git a/samples/LineCounter/Article/LineCounterSharpDevelopAddIn/screenshot2.png b/samples/LineCounter/Article/LineCounterSharpDevelopAddIn/screenshot2.png new file mode 100644 index 0000000000..732d8d0cf8 Binary files /dev/null and b/samples/LineCounter/Article/LineCounterSharpDevelopAddIn/screenshot2.png differ diff --git a/samples/LineCounter/Article/LineCounterSharpDevelopAddIn/templatetype.png b/samples/LineCounter/Article/LineCounterSharpDevelopAddIn/templatetype.png new file mode 100644 index 0000000000..861f2b993a Binary files /dev/null and b/samples/LineCounter/Article/LineCounterSharpDevelopAddIn/templatetype.png differ diff --git a/samples/LineCounter/Configuration/AssemblyInfo.cs b/samples/LineCounter/Configuration/AssemblyInfo.cs new file mode 100644 index 0000000000..82045e9df2 --- /dev/null +++ b/samples/LineCounter/Configuration/AssemblyInfo.cs @@ -0,0 +1,27 @@ +/* + * Created by SharpDevelop. + * User: Daniel Grunwald + * Date: 09.05.2006 + * Time: 17:22 + */ + +using System.Reflection; + +[assembly: AssemblyTitle("LineCounter")] +[assembly: AssemblyDescription("Macro AddIn for SharpDevelop 2.0")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("SharpDevelop")] +[assembly: AssemblyCopyright("")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// The assembly version has following format : +// +// Major.Minor.Build.Revision +// +// You can specify all values by your own or you can build default build and revision +// numbers with the '*' character (the default): + +[assembly: AssemblyVersion("1.0.*")] + diff --git a/samples/LineCounter/LineCounter.addin b/samples/LineCounter/LineCounter.addin new file mode 100644 index 0000000000..d2091518fd --- /dev/null +++ b/samples/LineCounter/LineCounter.addin @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/samples/LineCounter/LineCounter.csproj b/samples/LineCounter/LineCounter.csproj new file mode 100644 index 0000000000..3cd9bb19b5 --- /dev/null +++ b/samples/LineCounter/LineCounter.csproj @@ -0,0 +1,73 @@ + + + Library + LineCounterAddin + LineCounter + Debug + AnyCPU + {880A7EAF-D0B4-46AC-A9B6-B6156512037A} + ..\..\AddIns\ + False + False + False + Auto + 4194304 + AnyCPU + 4096 + 4 + false + + + obj\ + obj\Debug\ + False + DEBUG,TRACE,IMPR1,IMPR2,IMPR3 + true + Full + True + + + obj\ + obj\Release\ + True + TRACE,IMPR1,IMPR2,IMPR3 + false + None + False + + + + + + + + + ..\..\bin\ICSharpCode.SharpDevelop.dll + False + False + + + ..\..\bin\ICSharpCode.Core.dll + False + False + + + + + Always + + + + + + + LineCounterBrowser.cs + + + LineCounterBrowser.cs + + + + + + \ No newline at end of file diff --git a/samples/LineCounter/LineCounter.sln b/samples/LineCounter/LineCounter.sln new file mode 100644 index 0000000000..1b940f8e29 --- /dev/null +++ b/samples/LineCounter/LineCounter.sln @@ -0,0 +1,16 @@ +Microsoft Visual Studio Solution File, Format Version 9.00 +# SharpDevelop 2.1.0.1394 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LineCounter", "LineCounter.csproj", "{880A7EAF-D0B4-46AC-A9B6-B6156512037A}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {880A7EAF-D0B4-46AC-A9B6-B6156512037A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {880A7EAF-D0B4-46AC-A9B6-B6156512037A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {880A7EAF-D0B4-46AC-A9B6-B6156512037A}.Release|Any CPU.Build.0 = Release|Any CPU + {880A7EAF-D0B4-46AC-A9B6-B6156512037A}.Release|Any CPU.ActiveCfg = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/samples/LineCounter/Src/Command.cs b/samples/LineCounter/Src/Command.cs new file mode 100644 index 0000000000..73d0ed8304 --- /dev/null +++ b/samples/LineCounter/Src/Command.cs @@ -0,0 +1,24 @@ +/* + * Created by SharpDevelop. + * User: Daniel Grunwald + * Date: 09.05.2006 + * Time: 17:22 + */ + +using System; +using System.Text; +using System.Windows.Forms; +using ICSharpCode.Core; +using ICSharpCode.SharpDevelop; +using ICSharpCode.SharpDevelop.Gui; + +namespace LineCounterAddin +{ + public class ToolCommand1 : AbstractMenuCommand + { + public override void Run() + { + WorkbenchSingleton.Workbench.ShowView(new LineCounterViewContent()); + } + } +} diff --git a/samples/LineCounter/Src/Extensibility.cs b/samples/LineCounter/Src/Extensibility.cs new file mode 100644 index 0000000000..228a254830 --- /dev/null +++ b/samples/LineCounter/Src/Extensibility.cs @@ -0,0 +1,87 @@ +/* + * Created by SharpDevelop. + * User: Daniel Grunwald + * Date: 18.07.2006 + * Time: 17:08 + */ + +using System; +using ICSharpCode.Core; + +namespace LineCounterAddin +{ + // Improvement 2 + + public interface ICountingAlgorithm + { + void CountLines(LineCountInfo info); + } + + public class CountingAlgorithmGeneric : ICountingAlgorithm { + public void CountLines(LineCountInfo info) { + LineCounterBrowser.CountLinesGeneric(info); + } + } + public class CountingAlgorithmCStyle : ICountingAlgorithm { + public void CountLines(LineCountInfo info) { + LineCounterBrowser.CountLinesCStyle(info); + } + } + public class CountingAlgorithmVBStyle : ICountingAlgorithm { + public void CountLines(LineCountInfo info) { + LineCounterBrowser.CountLinesVBStyle(info); + } + } + public class CountingAlgorithmXmlStyle : ICountingAlgorithm { + public void CountLines(LineCountInfo info) { + LineCounterBrowser.CountLinesXMLStyle(info); + } + } + + public class CountingAlgorithmDoozer : IDoozer + { + public bool HandleConditions { + get { + // our doozer cannot handle conditions, let SharpDevelop + // do that for us + return false; + } + } + + public object BuildItem(object caller, Codon codon, System.Collections.ArrayList subItems) + { + return new CountingAlgorithmDescriptor(codon.AddIn, + codon.Properties["extensions"], + codon.Properties["class"]); + } + } + + public class CountingAlgorithmDescriptor + { + AddIn addIn; + internal string[] extensions; + string className; + + public CountingAlgorithmDescriptor(AddIn addIn, string extensions, string className) + { + this.addIn = addIn; + this.extensions = extensions.ToLowerInvariant().Split(';'); + this.className = className; + } + + public bool CanCountLines(LineCountInfo info) + { + return (Array.IndexOf(extensions, info.FileType.ToLowerInvariant()) >= 0); + } + + ICountingAlgorithm cachedAlgorithm; + + public ICountingAlgorithm GetAlgorithm() + { + if (cachedAlgorithm == null) { + cachedAlgorithm = (ICountingAlgorithm)addIn.CreateObject(className); + } + return cachedAlgorithm; + } + } +} diff --git a/samples/LineCounter/Src/ImageListHelper.cs b/samples/LineCounter/Src/ImageListHelper.cs new file mode 100644 index 0000000000..f2f46597ba --- /dev/null +++ b/samples/LineCounter/Src/ImageListHelper.cs @@ -0,0 +1,45 @@ +/* + * Created by SharpDevelop. + * User: Daniel Grunwald + * Date: 18.07.2006 + * Time: 15:53 + */ + +using System; +using System.Collections.Generic; +using System.Windows.Forms; +using ICSharpCode.Core; + +namespace LineCounterAddin +{ + // Helper class for improvement 1 + + /// + /// To minimize changes to LineCounterBrowser, we are + /// using this helper class to load images from SharpDevelop's + /// IconService into our image list on demand. + /// + public class ImageListHelper + { + ImageList imageList; + Dictionary dict = new Dictionary(); + + public ImageListHelper(ImageList imageList) + { + if (imageList == null) + throw new ArgumentNullException("imageList"); + this.imageList = imageList; + } + + public int GetIndex(string imageName) + { + int index; + if (!dict.TryGetValue(imageName, out index)) { + index = imageList.Images.Count; + imageList.Images.Add(IconService.GetBitmap(imageName)); + dict[imageName] = index; + } + return index; + } + } +} diff --git a/samples/LineCounter/Src/LineCounterBrowser.Designer.cs b/samples/LineCounter/Src/LineCounterBrowser.Designer.cs new file mode 100644 index 0000000000..7879d80647 --- /dev/null +++ b/samples/LineCounter/Src/LineCounterBrowser.Designer.cs @@ -0,0 +1,469 @@ +namespace LineCounterAddin +{ + partial class LineCounterBrowser + { + /// + /// 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.components = new System.ComponentModel.Container(); + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(LineCounterBrowser)); + System.Windows.Forms.ListViewGroup listViewGroup1 = new System.Windows.Forms.ListViewGroup("Grand Totals", System.Windows.Forms.HorizontalAlignment.Left); + System.Windows.Forms.ListViewGroup listViewGroup2 = new System.Windows.Forms.ListViewGroup("Project Totals", System.Windows.Forms.HorizontalAlignment.Left); + this.tscMain = new System.Windows.Forms.ToolStripContainer(); + this.toolStrip1 = new System.Windows.Forms.ToolStrip(); + this.toolStripLabel1 = new System.Windows.Forms.ToolStripLabel(); + this.tsprgTotal = new System.Windows.Forms.ToolStripProgressBar(); + this.toolStripLabel2 = new System.Windows.Forms.ToolStripLabel(); + this.tsprgTask = new System.Windows.Forms.ToolStripProgressBar(); + this.tstxtLinesCounted = new System.Windows.Forms.ToolStripTextBox(); + this.splitContainer1 = new System.Windows.Forms.SplitContainer(); + this.lvFileList = new System.Windows.Forms.ListView(); + this.chFilename = new System.Windows.Forms.ColumnHeader(); + this.chFileTotalLines = new System.Windows.Forms.ColumnHeader(); + this.chFileTotalCode = new System.Windows.Forms.ColumnHeader(); + this.chFileTotalComment = new System.Windows.Forms.ColumnHeader(); + this.chFileExt = new System.Windows.Forms.ColumnHeader(); + this.chMode = new System.Windows.Forms.ColumnHeader(); + this.cmsFileList = new System.Windows.Forms.ContextMenuStrip(this.components); + this.tsmiArrange = new System.Windows.Forms.ToolStripMenuItem(); + this.tsmiGroupByType = new System.Windows.Forms.ToolStripMenuItem(); + this.tsmiGroupByProj = new System.Windows.Forms.ToolStripMenuItem(); + this.toolStripMenuItem1 = new System.Windows.Forms.ToolStripSeparator(); + this.tsmiNoGrouping = new System.Windows.Forms.ToolStripMenuItem(); + this.tsmiRecalculate_FileList = new System.Windows.Forms.ToolStripMenuItem(); + this.imgFileTypes = new System.Windows.Forms.ImageList(this.components); + this.lvSummary = new System.Windows.Forms.ListView(); + this.chProject = new System.Windows.Forms.ColumnHeader(); + this.chTotalLines = new System.Windows.Forms.ColumnHeader(); + this.chCodeLines = new System.Windows.Forms.ColumnHeader(); + this.chComments = new System.Windows.Forms.ColumnHeader(); + this.chBlankLines = new System.Windows.Forms.ColumnHeader(); + this.chNetLines = new System.Windows.Forms.ColumnHeader(); + this.imgProjectTypes = new System.Windows.Forms.ImageList(this.components); + this.menuStrip1 = new System.Windows.Forms.MenuStrip(); + this.tsmiLineCounter = new System.Windows.Forms.ToolStripMenuItem(); + this.tsmiOptions = new System.Windows.Forms.ToolStripMenuItem(); + this.tsmiRecalculate = new System.Windows.Forms.ToolStripMenuItem(); + this.tscMain.BottomToolStripPanel.SuspendLayout(); + this.tscMain.ContentPanel.SuspendLayout(); + this.tscMain.TopToolStripPanel.SuspendLayout(); + this.tscMain.SuspendLayout(); + this.toolStrip1.SuspendLayout(); + this.splitContainer1.Panel1.SuspendLayout(); + this.splitContainer1.Panel2.SuspendLayout(); + this.splitContainer1.SuspendLayout(); + this.cmsFileList.SuspendLayout(); + this.menuStrip1.SuspendLayout(); + this.SuspendLayout(); + // + // tscMain + // + // + // tscMain.BottomToolStripPanel + // + this.tscMain.BottomToolStripPanel.Controls.Add(this.toolStrip1); + // + // tscMain.ContentPanel + // + this.tscMain.ContentPanel.Controls.Add(this.splitContainer1); + this.tscMain.ContentPanel.Size = new System.Drawing.Size(600, 351); + this.tscMain.Dock = System.Windows.Forms.DockStyle.Fill; + this.tscMain.Location = new System.Drawing.Point(0, 0); + this.tscMain.Name = "tscMain"; + this.tscMain.Size = new System.Drawing.Size(600, 400); + this.tscMain.TabIndex = 0; + this.tscMain.Text = "toolStripContainer1"; + // + // tscMain.TopToolStripPanel + // + this.tscMain.TopToolStripPanel.Controls.Add(this.menuStrip1); + // + // toolStrip1 + // + this.toolStrip1.Dock = System.Windows.Forms.DockStyle.None; + this.toolStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.toolStripLabel1, + this.tsprgTotal, + this.toolStripLabel2, + this.tsprgTask, + this.tstxtLinesCounted}); + this.toolStrip1.Location = new System.Drawing.Point(0, 0); + this.toolStrip1.Name = "toolStrip1"; + this.toolStrip1.Size = new System.Drawing.Size(600, 25); + this.toolStrip1.Stretch = true; + this.toolStrip1.TabIndex = 1; + // + // toolStripLabel1 + // + this.toolStripLabel1.Name = "toolStripLabel1"; + this.toolStripLabel1.Size = new System.Drawing.Size(80, 22); + this.toolStripLabel1.Text = "Total Progress:"; + // + // tsprgTotal + // + this.tsprgTotal.Name = "tsprgTotal"; + this.tsprgTotal.Size = new System.Drawing.Size(150, 22); + // + // toolStripLabel2 + // + this.toolStripLabel2.Name = "toolStripLabel2"; + this.toolStripLabel2.Size = new System.Drawing.Size(78, 22); + this.toolStripLabel2.Text = "Task Progress:"; + // + // tsprgTask + // + this.tsprgTask.Name = "tsprgTask"; + this.tsprgTask.Size = new System.Drawing.Size(150, 22); + // + // tstxtLinesCounted + // + this.tstxtLinesCounted.Name = "tstxtLinesCounted"; + this.tstxtLinesCounted.Size = new System.Drawing.Size(100, 25); + this.tstxtLinesCounted.ToolTipText = "Lines counted so far"; + // + // splitContainer1 + // + this.splitContainer1.Dock = System.Windows.Forms.DockStyle.Fill; + this.splitContainer1.Location = new System.Drawing.Point(0, 0); + this.splitContainer1.Name = "splitContainer1"; + this.splitContainer1.Orientation = System.Windows.Forms.Orientation.Horizontal; + // + // splitContainer1.Panel1 + // + this.splitContainer1.Panel1.Controls.Add(this.lvFileList); + // + // splitContainer1.Panel2 + // + this.splitContainer1.Panel2.Controls.Add(this.lvSummary); + this.splitContainer1.Size = new System.Drawing.Size(600, 351); + this.splitContainer1.SplitterDistance = 255; + this.splitContainer1.TabIndex = 0; + // + // lvFileList + // + this.lvFileList.AllowColumnReorder = true; + this.lvFileList.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] { + this.chFilename, + this.chFileTotalLines, + this.chFileTotalCode, + this.chFileTotalComment, + this.chFileExt, + this.chMode}); + this.lvFileList.ContextMenuStrip = this.cmsFileList; + this.lvFileList.Dock = System.Windows.Forms.DockStyle.Fill; + this.lvFileList.FullRowSelect = true; + this.lvFileList.GridLines = true; + this.lvFileList.HideSelection = false; + this.lvFileList.Location = new System.Drawing.Point(0, 0); + this.lvFileList.Name = "lvFileList"; + this.lvFileList.Size = new System.Drawing.Size(600, 255); + this.lvFileList.SmallImageList = this.imgFileTypes; + this.lvFileList.TabIndex = 0; + this.lvFileList.UseCompatibleStateImageBehavior = false; + this.lvFileList.View = System.Windows.Forms.View.Details; + this.lvFileList.ColumnClick += new System.Windows.Forms.ColumnClickEventHandler(this.lvFileList_ColumnClick); + // + // chFilename + // + this.chFilename.Text = "File"; + this.chFilename.Width = 192; + // + // chFileTotalLines + // + this.chFileTotalLines.Text = "Total Lines"; + this.chFileTotalLines.Width = 90; + // + // chFileTotalCode + // + this.chFileTotalCode.Text = "Code Lines"; + this.chFileTotalCode.Width = 90; + // + // chFileTotalComment + // + this.chFileTotalComment.Text = "Comments"; + this.chFileTotalComment.Width = 90; + // + // chFileExt + // + this.chFileExt.Text = "Extension"; + this.chFileExt.Width = 64; + // + // chMode + // + this.chMode.Text = "Sum-Mode"; + this.chMode.Width = 70; + // + // cmsFileList + // + this.cmsFileList.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.tsmiArrange, + this.tsmiRecalculate_FileList}); + this.cmsFileList.Name = "cmsFileList"; + this.cmsFileList.Size = new System.Drawing.Size(130, 48); + // + // tsmiArrange + // + this.tsmiArrange.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.tsmiGroupByType, + this.tsmiGroupByProj, + this.toolStripMenuItem1, + this.tsmiNoGrouping}); + this.tsmiArrange.Name = "tsmiArrange"; + this.tsmiArrange.Size = new System.Drawing.Size(129, 22); + this.tsmiArrange.Text = "Arrange"; + // + // tsmiGroupByType + // + this.tsmiGroupByType.Checked = true; + this.tsmiGroupByType.CheckOnClick = true; + this.tsmiGroupByType.CheckState = System.Windows.Forms.CheckState.Checked; + this.tsmiGroupByType.Name = "tsmiGroupByType"; + this.tsmiGroupByType.ShortcutKeyDisplayString = "CTRL-G,T"; + this.tsmiGroupByType.Size = new System.Drawing.Size(208, 22); + this.tsmiGroupByType.Text = "Group by type"; + this.tsmiGroupByType.Click += new System.EventHandler(this.tsmiGroupByType_Click); + // + // tsmiGroupByProj + // + this.tsmiGroupByProj.CheckOnClick = true; + this.tsmiGroupByProj.Name = "tsmiGroupByProj"; + this.tsmiGroupByProj.ShortcutKeyDisplayString = "CTRL-G,P"; + this.tsmiGroupByProj.Size = new System.Drawing.Size(208, 22); + this.tsmiGroupByProj.Text = "Group by project"; + this.tsmiGroupByProj.Click += new System.EventHandler(this.tsmiGroupByProj_Click); + // + // toolStripMenuItem1 + // + this.toolStripMenuItem1.Name = "toolStripMenuItem1"; + this.toolStripMenuItem1.Size = new System.Drawing.Size(205, 6); + // + // tsmiNoGrouping + // + this.tsmiNoGrouping.CheckOnClick = true; + this.tsmiNoGrouping.Name = "tsmiNoGrouping"; + this.tsmiNoGrouping.ShortcutKeyDisplayString = "CTRL-G,0"; + this.tsmiNoGrouping.Size = new System.Drawing.Size(208, 22); + this.tsmiNoGrouping.Text = "Do not group"; + this.tsmiNoGrouping.Click += new System.EventHandler(this.tsmiNoGrouping_Click); + // + // tsmiRecalculate_FileList + // + this.tsmiRecalculate_FileList.Name = "tsmiRecalculate_FileList"; + this.tsmiRecalculate_FileList.Size = new System.Drawing.Size(129, 22); + this.tsmiRecalculate_FileList.Text = "Recalculate"; + this.tsmiRecalculate_FileList.Click += new System.EventHandler(this.tsmiRecalculate_FileList_Click); + // + // imgFileTypes + // + this.imgFileTypes.ImageStream = ((System.Windows.Forms.ImageListStreamer)(resources.GetObject("imgFileTypes.ImageStream"))); + this.imgFileTypes.TransparentColor = System.Drawing.Color.Transparent; + this.imgFileTypes.Images.SetKeyName(0, "Default.png"); + this.imgFileTypes.Images.SetKeyName(1, "FileCS.png"); + this.imgFileTypes.Images.SetKeyName(2, "FileVB.png"); + this.imgFileTypes.Images.SetKeyName(3, "FileVJ.png"); + this.imgFileTypes.Images.SetKeyName(4, "FileCPP.png"); + this.imgFileTypes.Images.SetKeyName(5, "FileC.png"); + this.imgFileTypes.Images.SetKeyName(6, "FileH.png"); + this.imgFileTypes.Images.SetKeyName(7, "JavaScript.png"); + this.imgFileTypes.Images.SetKeyName(8, "FileCD.png"); + this.imgFileTypes.Images.SetKeyName(9, "FileRESX.png"); + this.imgFileTypes.Images.SetKeyName(10, "FileCSS.png"); + this.imgFileTypes.Images.SetKeyName(11, "FileHTM.png"); + this.imgFileTypes.Images.SetKeyName(12, "FileXML.png"); + this.imgFileTypes.Images.SetKeyName(13, "FileXSL.png"); + this.imgFileTypes.Images.SetKeyName(14, "FileXSD.png"); + this.imgFileTypes.Images.SetKeyName(15, "FileCONFIG.png"); + this.imgFileTypes.Images.SetKeyName(16, "FileASAX.png"); + this.imgFileTypes.Images.SetKeyName(17, "FileASCX.png"); + this.imgFileTypes.Images.SetKeyName(18, "FileASMX.png"); + this.imgFileTypes.Images.SetKeyName(19, "fileASPX.png"); + // + // lvSummary + // + this.lvSummary.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] { + this.chProject, + this.chTotalLines, + this.chCodeLines, + this.chComments, + this.chBlankLines, + this.chNetLines}); + this.lvSummary.Dock = System.Windows.Forms.DockStyle.Fill; + this.lvSummary.FullRowSelect = true; + listViewGroup1.Header = "Grand Totals"; + listViewGroup1.Name = "lvgAllProj"; + listViewGroup2.Header = "Project Totals"; + listViewGroup2.Name = "lvgEachProj"; + this.lvSummary.Groups.AddRange(new System.Windows.Forms.ListViewGroup[] { + listViewGroup1, + listViewGroup2}); + this.lvSummary.HideSelection = false; + this.lvSummary.Location = new System.Drawing.Point(0, 0); + this.lvSummary.Name = "lvSummary"; + this.lvSummary.Size = new System.Drawing.Size(600, 92); + this.lvSummary.SmallImageList = this.imgProjectTypes; + this.lvSummary.TabIndex = 0; + this.lvSummary.UseCompatibleStateImageBehavior = false; + this.lvSummary.View = System.Windows.Forms.View.Details; + // + // chProject + // + this.chProject.Text = "Project"; + this.chProject.Width = 146; + // + // chTotalLines + // + this.chTotalLines.Text = "Total Lines"; + this.chTotalLines.Width = 90; + // + // chCodeLines + // + this.chCodeLines.Text = "Code Lines"; + this.chCodeLines.Width = 90; + // + // chComments + // + this.chComments.Text = "Comments"; + this.chComments.Width = 90; + // + // chBlankLines + // + this.chBlankLines.Text = "Blank Lines"; + this.chBlankLines.Width = 90; + // + // chNetLines + // + this.chNetLines.Text = "Net Lines"; + this.chNetLines.Width = 90; + // + // imgProjectTypes + // + this.imgProjectTypes.ImageStream = ((System.Windows.Forms.ImageListStreamer)(resources.GetObject("imgProjectTypes.ImageStream"))); + this.imgProjectTypes.TransparentColor = System.Drawing.Color.Transparent; + this.imgProjectTypes.Images.SetKeyName(0, "Solution.png"); + this.imgProjectTypes.Images.SetKeyName(1, "ProjectCS.png"); + this.imgProjectTypes.Images.SetKeyName(2, "ProjectVB.png"); + this.imgProjectTypes.Images.SetKeyName(3, "ProjectVC.png"); + this.imgProjectTypes.Images.SetKeyName(4, "ProjectVJ.png"); + this.imgProjectTypes.Images.SetKeyName(5, "ProjectWeb.png"); + // + // menuStrip1 + // + this.menuStrip1.Dock = System.Windows.Forms.DockStyle.None; + this.menuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.tsmiLineCounter}); + this.menuStrip1.Location = new System.Drawing.Point(0, 0); + this.menuStrip1.Name = "menuStrip1"; + this.menuStrip1.Size = new System.Drawing.Size(600, 24); + this.menuStrip1.TabIndex = 0; + this.menuStrip1.Text = "menuStrip1"; + // + // tsmiLineCounter + // + this.tsmiLineCounter.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.tsmiOptions, + this.tsmiRecalculate}); + this.tsmiLineCounter.Name = "tsmiLineCounter"; + this.tsmiLineCounter.Size = new System.Drawing.Size(80, 20); + this.tsmiLineCounter.Text = "Line Counter"; + // + // tsmiOptions + // + this.tsmiOptions.Name = "tsmiOptions"; + this.tsmiOptions.Size = new System.Drawing.Size(129, 22); + this.tsmiOptions.Text = "Options"; + // + // tsmiRecalculate + // + this.tsmiRecalculate.Name = "tsmiRecalculate"; + this.tsmiRecalculate.Size = new System.Drawing.Size(129, 22); + this.tsmiRecalculate.Text = "Recalculate"; + this.tsmiRecalculate.Click += new System.EventHandler(this.tsmiRecalculate_FileList_Click); + // + // LineCounterBrowser + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.Controls.Add(this.tscMain); + this.Name = "LineCounterBrowser"; + this.Size = new System.Drawing.Size(600, 400); + this.tscMain.BottomToolStripPanel.ResumeLayout(false); + this.tscMain.BottomToolStripPanel.PerformLayout(); + this.tscMain.ContentPanel.ResumeLayout(false); + this.tscMain.TopToolStripPanel.ResumeLayout(false); + this.tscMain.TopToolStripPanel.PerformLayout(); + this.tscMain.ResumeLayout(false); + this.tscMain.PerformLayout(); + this.toolStrip1.ResumeLayout(false); + this.toolStrip1.PerformLayout(); + this.splitContainer1.Panel1.ResumeLayout(false); + this.splitContainer1.Panel2.ResumeLayout(false); + this.splitContainer1.ResumeLayout(false); + this.cmsFileList.ResumeLayout(false); + this.menuStrip1.ResumeLayout(false); + this.menuStrip1.PerformLayout(); + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.ToolStripContainer tscMain; + private System.Windows.Forms.MenuStrip menuStrip1; + private System.Windows.Forms.ToolStripMenuItem tsmiLineCounter; + private System.Windows.Forms.ToolStripMenuItem tsmiOptions; + private System.Windows.Forms.SplitContainer splitContainer1; + private System.Windows.Forms.ToolStripMenuItem tsmiRecalculate; + private System.Windows.Forms.ListView lvSummary; + private System.Windows.Forms.ColumnHeader chProject; + private System.Windows.Forms.ListView lvFileList; + private System.Windows.Forms.ColumnHeader chTotalLines; + private System.Windows.Forms.ColumnHeader chCodeLines; + private System.Windows.Forms.ColumnHeader chComments; + private System.Windows.Forms.ColumnHeader chBlankLines; + private System.Windows.Forms.ColumnHeader chNetLines; + private System.Windows.Forms.ColumnHeader chFilename; + private System.Windows.Forms.ColumnHeader chFileTotalLines; + private System.Windows.Forms.ColumnHeader chFileTotalCode; + private System.Windows.Forms.ColumnHeader chFileTotalComment; + private System.Windows.Forms.ColumnHeader chFileExt; + private System.Windows.Forms.ContextMenuStrip cmsFileList; + private System.Windows.Forms.ToolStripMenuItem tsmiArrange; + private System.Windows.Forms.ToolStripMenuItem tsmiGroupByType; + private System.Windows.Forms.ToolStripMenuItem tsmiGroupByProj; + private System.Windows.Forms.ToolStripSeparator toolStripMenuItem1; + private System.Windows.Forms.ToolStripMenuItem tsmiNoGrouping; + private System.Windows.Forms.ToolStripMenuItem tsmiRecalculate_FileList; + private System.Windows.Forms.ImageList imgProjectTypes; + private System.Windows.Forms.ToolStrip toolStrip1; + private System.Windows.Forms.ToolStripLabel toolStripLabel1; + private System.Windows.Forms.ToolStripProgressBar tsprgTotal; + private System.Windows.Forms.ToolStripLabel toolStripLabel2; + private System.Windows.Forms.ToolStripProgressBar tsprgTask; + private System.Windows.Forms.ToolStripTextBox tstxtLinesCounted; + private System.Windows.Forms.ImageList imgFileTypes; + private System.Windows.Forms.ColumnHeader chMode; + } +} diff --git a/samples/LineCounter/Src/LineCounterBrowser.cs b/samples/LineCounter/Src/LineCounterBrowser.cs new file mode 100644 index 0000000000..7b60d1a321 --- /dev/null +++ b/samples/LineCounter/Src/LineCounterBrowser.cs @@ -0,0 +1,1255 @@ +// LineCounterBrowser is from the CodeProject article +// "Line Counter - Writing a Visual Studio 2005 Add-In" by Jon Rista +// http://www.codeproject.com/useritems/LineCounterAddin.asp + +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Diagnostics; +using System.Drawing; +using System.IO; +using System.Text; +using System.Windows.Forms; + +using ICSharpCode.Core; +using ICSharpCode.SharpDevelop.Project; + +namespace LineCounterAddin +{ + /// + /// Line Counter add-in user interface. + /// + public partial class LineCounterBrowser : UserControl + { + #region Nested Classes + abstract class ListViewItemComparer : System.Collections.IComparer + { + public abstract int Compare(ListViewItem item1, ListViewItem item2); + + public ListView SortingList; + public int Column; + + #region IComparer Members + int System.Collections.IComparer.Compare(object x, object y) + { + if (x is ListViewItem && y is ListViewItem) + { + int diff = Compare((ListViewItem)x, (ListViewItem)y); + if (SortingList.Sorting == SortOrder.Descending) + diff *= -1; + + return diff; + } + else + { + throw new ArgumentException("One or both of the arguments are not ListViewItem objects."); + } + } + #endregion + } + + /// + /// Compares items based on file name. + /// + class FileNameComparer : ListViewItemComparer + { + + public override int Compare(ListViewItem item1, ListViewItem item2) + { + return String.Compare(item1.Text, item2.Text, false); + } + } + + /// + /// Compares items based on total lines primarily, and + /// the filename secondarily. + /// + class FileLinesComparer : ListViewItemComparer + { + + public override int Compare(ListViewItem item1, ListViewItem item2) + { + string string1 = item1.SubItems[Column].Text; + string string2 = item2.SubItems[Column].Text; + + if (string1 != null && string2 != null) + { + int total1 = int.Parse(string1); + int total2 = int.Parse(string2); + + // Compare the totals... + int diff = total1 - total2; + + // If totals are equal... + if (diff == 0) + { + // Compare the filenames + diff = String.Compare(item1.Text, item2.Text, false); + } + + return diff; + } + + return 0; + } + } + + /// + /// Compares items based on file extension. + /// + class FileExtensionComparer : ListViewItemComparer + { + + public override int Compare(ListViewItem item1, ListViewItem item2) + { + string string1 = item1.SubItems[4].Text; + string string2 = item2.SubItems[4].Text; + + return String.Compare(string1, string2, true); + } + } + #endregion + + #region Constructor + /// + /// Construct the line counter user interface and + /// the countable file type mappings (to icons and + /// counting algorithms). + /// + public LineCounterBrowser() + { + InitializeComponent(); + + #if IMPR1 + projectImageListHelper = new ImageListHelper(imgProjectTypes); + fileImageListHelper = new ImageListHelper(imgFileTypes); + #endif + + // Map project types to icons for use in the projects list + m_projIconMappings = new Dictionary(); + m_projIconMappings.Add("{00000000-0000-0000-0000-000000000000}", 0); + m_projIconMappings.Add("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}", 1); // C# + m_projIconMappings.Add("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}", 2); // VB + m_projIconMappings.Add("{00000001-0000-0000-0000-000000000000}", 5); + + // List all the countable file types (so we don't try to count .dll's, + // images, executables, etc. + + m_countableTypes = new System.Collections.Specialized.StringCollection(); + #if IMPR2 + countingAlgorithms = AddInTree.BuildItems + ("/AddIns/LineCounter/CountingAlgorithms", this); + // Iterate through algorithms to fill list of known countable types + foreach (CountingAlgorithmDescriptor desc in countingAlgorithms) { + m_countableTypes.AddRange(desc.extensions); + } + #else + m_countableTypes.Add("*"); + m_countableTypes.Add(".cs"); + m_countableTypes.Add(".vb"); + m_countableTypes.Add(".vj"); + m_countableTypes.Add(".cpp"); + m_countableTypes.Add(".cc"); + m_countableTypes.Add(".cxx"); + m_countableTypes.Add(".c"); + m_countableTypes.Add(".hpp"); + m_countableTypes.Add(".hh"); + m_countableTypes.Add(".hxx"); + m_countableTypes.Add(".h"); + m_countableTypes.Add(".js"); + m_countableTypes.Add(".cd"); + m_countableTypes.Add(".resx"); + m_countableTypes.Add(".res"); + m_countableTypes.Add(".css"); + m_countableTypes.Add(".htm"); + m_countableTypes.Add(".html"); + m_countableTypes.Add(".xml"); + m_countableTypes.Add(".xsl"); + m_countableTypes.Add(".xslt"); + m_countableTypes.Add(".xsd"); + m_countableTypes.Add(".config"); + m_countableTypes.Add(".asax"); + m_countableTypes.Add(".ascx"); + m_countableTypes.Add(".asmx"); + m_countableTypes.Add(".aspx"); + m_countableTypes.Add(".ashx"); + m_countableTypes.Add(".idl"); + m_countableTypes.Add(".odl"); + m_countableTypes.Add(".txt"); + m_countableTypes.Add(".sql"); + #endif + + // Map file extensions to icons for use in the file list + m_fileIconMappings = new Dictionary(33); + m_fileIconMappings.Add("*", 0); + m_fileIconMappings.Add(".cs", 1); + m_fileIconMappings.Add(".vb", 2); + m_fileIconMappings.Add(".vj", 3); + m_fileIconMappings.Add(".cpp", 4); + m_fileIconMappings.Add(".cc", 4); + m_fileIconMappings.Add(".cxx", 4); + m_fileIconMappings.Add(".c", 5); + m_fileIconMappings.Add(".hpp", 6); + m_fileIconMappings.Add(".hh", 6); + m_fileIconMappings.Add(".hxx", 6); + m_fileIconMappings.Add(".h", 6); + m_fileIconMappings.Add(".js", 7); + m_fileIconMappings.Add(".cd", 8); + m_fileIconMappings.Add(".resx", 9); + m_fileIconMappings.Add(".res", 9); + m_fileIconMappings.Add(".css", 10); + m_fileIconMappings.Add(".htm", 11); + m_fileIconMappings.Add(".html", 11); + m_fileIconMappings.Add(".xml", 12); + m_fileIconMappings.Add(".xsl", 13); + m_fileIconMappings.Add(".xslt", 13); + m_fileIconMappings.Add(".xsd", 14); + m_fileIconMappings.Add(".config", 15); + m_fileIconMappings.Add(".asax", 16); + m_fileIconMappings.Add(".ascx", 17); + m_fileIconMappings.Add(".asmx", 18); + m_fileIconMappings.Add(".aspx", 19); + m_fileIconMappings.Add(".ashx", 0); + m_fileIconMappings.Add(".idl", 0); + m_fileIconMappings.Add(".odl", 0); + m_fileIconMappings.Add(".txt", 0); + m_fileIconMappings.Add(".sql", 0); + + // Prepare counting algorithm mappings + CountLines countLinesGeneric = new CountLines(CountLinesGeneric); + CountLines countLinesCStyle = new CountLines(CountLinesCStyle); + CountLines countLinesVBStyle = new CountLines(CountLinesVBStyle); + CountLines countLinesXMLStyle = new CountLines(CountLinesXMLStyle); + + m_countAlgorithms = new Dictionary(33); + m_countAlgorithms.Add("*", countLinesGeneric); + m_countAlgorithms.Add(".cs", countLinesCStyle); + m_countAlgorithms.Add(".vb", countLinesVBStyle); + m_countAlgorithms.Add(".vj", countLinesCStyle); + m_countAlgorithms.Add(".js", countLinesCStyle); + m_countAlgorithms.Add(".cpp", countLinesCStyle); + m_countAlgorithms.Add(".cc", countLinesCStyle); + m_countAlgorithms.Add(".cxx", countLinesCStyle); + m_countAlgorithms.Add(".c", countLinesCStyle); + m_countAlgorithms.Add(".hpp", countLinesCStyle); + m_countAlgorithms.Add(".hh", countLinesCStyle); + m_countAlgorithms.Add(".hxx", countLinesCStyle); + m_countAlgorithms.Add(".h", countLinesCStyle); + m_countAlgorithms.Add(".idl", countLinesCStyle); + m_countAlgorithms.Add(".odl", countLinesCStyle); + m_countAlgorithms.Add(".txt", countLinesGeneric); + m_countAlgorithms.Add(".xml", countLinesXMLStyle); + m_countAlgorithms.Add(".xsl", countLinesXMLStyle); + m_countAlgorithms.Add(".xslt", countLinesXMLStyle); + m_countAlgorithms.Add(".xsd", countLinesXMLStyle); + m_countAlgorithms.Add(".config", countLinesXMLStyle); + m_countAlgorithms.Add(".res", countLinesGeneric); + m_countAlgorithms.Add(".resx", countLinesXMLStyle); + m_countAlgorithms.Add(".aspx", countLinesXMLStyle); + m_countAlgorithms.Add(".ascx", countLinesXMLStyle); + m_countAlgorithms.Add(".ashx", countLinesXMLStyle); + m_countAlgorithms.Add(".asmx", countLinesXMLStyle); + m_countAlgorithms.Add(".asax", countLinesXMLStyle); + m_countAlgorithms.Add(".htm", countLinesXMLStyle); + m_countAlgorithms.Add(".html", countLinesXMLStyle); + m_countAlgorithms.Add(".css", countLinesCStyle); + m_countAlgorithms.Add(".sql", countLinesGeneric); + m_countAlgorithms.Add(".cd", countLinesGeneric); + } + #endregion + + #region Variables + private List m_summaryList; + private Dictionary m_projIconMappings; + private Dictionary m_fileIconMappings; + private Dictionary m_countAlgorithms; + private System.Collections.Specialized.StringCollection m_countableTypes; + + #if IMPR1 + ImageListHelper fileImageListHelper; + ImageListHelper projectImageListHelper; + #endif + #if IMPR2 + List countingAlgorithms; + #endif + #endregion + + #region Handlers + private int lastSortColumn = -1; // Track the last clicked column + + /// + /// Sorts the ListView by the clicked column, automatically + /// reversing the sort order on subsequent clicks of the + /// same column. + /// + /// + /// Provides the index of the clicked column. + private void lvFileList_ColumnClick(object sender, ColumnClickEventArgs e) + { + // Define a variable of the abstract (generic) comparer + ListViewItemComparer comparer = null; + + // Create an instance of the specific comparer in the 'comparer' + // variable. Since each of the explicit comparer classes is + // derived from the abstract case class, polymorphism applies. + switch (e.Column) + { + // Line count columns + case 1: + case 2: + case 3: + comparer = new FileLinesComparer(); + break; + // The file extension column + case 4: + comparer = new FileExtensionComparer(); + break; + // All other columns sort by file name + default: + comparer = new FileNameComparer(); + break; + } + + // Set the sorting order + if (lastSortColumn == e.Column) + { + if (lvFileList.Sorting == SortOrder.Ascending) + { + lvFileList.Sorting = SortOrder.Descending; + } + else + { + lvFileList.Sorting = SortOrder.Ascending; + } + } + else + { + lvFileList.Sorting = SortOrder.Ascending; + } + lastSortColumn = e.Column; + + // Send the comparer the list view and column being sorted + comparer.SortingList = lvFileList; + comparer.Column = e.Column; + + // Attach the comparer to the list view and sort + lvFileList.ListViewItemSorter = comparer; + lvFileList.Sort(); + } + + /// + /// Sets the file listing mode to No Grouping, + /// and recounts. + /// + /// + /// + /// FIX THIS: Add a helper to simply repopulate + /// the list view with existing count data if it exists!!! + private void tsmiNoGrouping_Click(object sender, EventArgs e) + { + tsmiGroupByProj.Checked = false; + tsmiGroupByType.Checked = false; + + SumSolution(); + } + + /// + /// Sets the file listing mode to Group by Project, + /// and recounts. + /// + /// + /// + /// FIX THIS: Add a helper to simply repopulate + /// the list view with existing count data if it exists!!! + private void tsmiGroupByProj_Click(object sender, EventArgs e) + { + tsmiGroupByType.Checked = false; + tsmiNoGrouping.Checked = false; + + SumSolution(); + } + + /// + /// Sets the file listing mode to Group by Type, + /// and recounts. + /// + /// + /// + /// FIX THIS: Add a helper to simply repopulate + /// the list view with existing count data if it exists!!! + private void tsmiGroupByType_Click(object sender, EventArgs e) + { + tsmiGroupByProj.Checked = false; + tsmiNoGrouping.Checked = false; + + SumSolution(); + } + + /// + /// Forces a recount of all files in all projects, and + /// updates the view. + /// + /// + /// + private void tsmiRecalculate_FileList_Click(object sender, EventArgs e) + { + ScanSolution(); + SumSolution(); + } + #endregion + + #region Helpers + #region Line Counting Methods + /// + /// Count each line in a text file, logging + /// blank lines. + /// + /// The file information data to use. + internal static void CountLinesGeneric(LineCountInfo info) + { + StreamReader sr = new StreamReader(info.FileName); + + string line; + while ((line = sr.ReadLine()) != null) + { + info.LineCountInfoDetails.Add("TotalLines", 1); + if (line.Trim() == string.Empty) + { + info.LineCountInfoDetails.Add("BlankLines", 1); + } + + info.SumMode = "Generic"; + } + + sr.Close(); + } + + /// + /// Count each line in a c-style source file, scanning + /// for single and multi-line comments, code, and blank lines. + /// + /// The file information data to use. + /// This algorithm was originally created by Oz Solomon, + /// for his PLC line counter add-in for Visual Studio 2002/2003. + internal static void CountLinesCStyle(LineCountInfo info) + { + try + { + StreamReader reader = new StreamReader(info.FileName); + + string line; + bool multiLineComment = false; + bool hasCode = false; + bool hasComments = false; + while ((line = reader.ReadLine()) != null) + { + ParseCLine(line, ref multiLineComment, ref hasCode, ref hasComments); + + if (hasComments) + { + info.LineCountInfoDetails.Add("normcmtlines", 1); + } + + if (hasCode) + { + info.LineCountInfoDetails.Add("codelines", 1); + } + + if (!hasCode && !hasComments) + { + info.LineCountInfoDetails.Add("blanklines", 1); + } + + info.LineCountInfoDetails.Add("totallines", 1); + } + + reader.Close(); + + info.SumMode = "C-Style"; + } + catch + { + } + } + + /// + /// Count each line in a vb-style source file, scanning + /// for comments, code, and blank lines. + /// + /// The file information data to use. + /// This algorithm was originally created by Oz Solomon, + /// for his PLC line counter add-in for Visual Studio 2002/2003. + internal static void CountLinesVBStyle(LineCountInfo info) + { + try + { + StreamReader reader = new StreamReader(info.FileName); + + string line; + bool multiLineComment = false; + bool hasCode = false; + bool hasComments = false; + while ((line = reader.ReadLine()) != null) + { + ParseVBLine(line, ref multiLineComment, ref hasCode, ref hasComments); + + if (hasComments) + { + info.LineCountInfoDetails.Add("normcmtlines", 1); + } + + if (hasCode) + { + info.LineCountInfoDetails.Add("codelines", 1); + } + + if (!hasCode && !hasComments) + { + info.LineCountInfoDetails.Add("blanklines", 1); + } + + info.LineCountInfoDetails.Add("totallines", 1); + } + + reader.Close(); + + info.SumMode = "Visual Basic"; + } + catch + { + } + } + + /// + /// Count each line in an xml source file, scanning + /// for comments, code, and blank lines. + /// + /// The file information data to use. + /// This algorithm is based on one created by Oz Solomon, + /// for his PLC line counter add-in for Visual Studio 2002/2003. + internal static void CountLinesXMLStyle(LineCountInfo info) + { + try + { + StreamReader reader = new StreamReader(info.FileName); + + string line; + bool multiLineComment = false; + bool hasCode = false; + bool hasComments = false; + while ((line = reader.ReadLine()) != null) + { + ParseXMLLine(line, ref multiLineComment, ref hasCode, ref hasComments); + + if (hasComments) + { + info.LineCountInfoDetails.Add("normcmtlines", 1); + } + + if (hasCode) + { + info.LineCountInfoDetails.Add("codelines", 1); + } + + if (!hasCode && !hasComments) + { + info.LineCountInfoDetails.Add("blanklines", 1); + } + + info.LineCountInfoDetails.Add("totallines", 1); + } + + reader.Close(); + + info.SumMode = "XML"; + } + catch + { + } + } + + /// + /// Determines if the two input characters ch and chNext + /// match the given pair of characters a and b. + /// + /// First char requirement. + /// Second char requirement. + /// First char to test. + /// Second char to test. + /// + private static bool IsPair(char a, char b, char ch, char chNext) + { + return (ch == a && chNext == b); + } + + /// + /// Parses a c-style code line for comments, code, and blanks. + /// + /// + /// + /// + /// + /// This algorithm was originally created by Oz Solomon, + /// for his PLC line counter add-in for Visual Studio 2002/2003. + private static void ParseCLine(string line, ref bool multiLineComment, ref bool hasCode, ref bool hasComments) + { + bool inString = false; + bool inTwoPairSequence = false; + + hasComments = multiLineComment; + hasCode = false; + + for (int i = 0; i < line.Length; i++) + { + char ch = line[i]; + char chNext = (i < line.Length - 1 ? line[i + 1] : '\0'); + + // Process a single-line comment + if (IsPair('/', '/', ch, chNext) && !multiLineComment && !inString) + { + hasComments = true; + return; + } + + // Process start of a multiline comment + else if (IsPair('/', '*', ch, chNext) && !multiLineComment && !inString) + { + multiLineComment = true; + hasComments = true; + ++i; + } + + // Process end of a multiline comment + else if (IsPair('*', '/', ch, chNext) && !inString) + { + multiLineComment = false; + ++i; + } + + // Process escaped character + else if (ch == '\\' && !multiLineComment) + { + ++i; + hasCode = true; + } + + // Process string + else if (ch == '"' && !multiLineComment) + { + inString = !inString; + hasCode = true; + } + + else if (!multiLineComment) + { + if (!Char.IsWhiteSpace(ch)) + { + hasCode = true; + } + } + } + } + + /// + /// Parses a vb-style code line for comments, code and blanks. + /// + /// + /// + /// + /// + /// This algorithm was originally created by Oz Solomon, + /// for his PLC line counter add-in for Visual Studio 2002/2003. + private static void ParseVBLine(string line, ref bool multiLineComment, ref bool hasCode, ref bool hasComments) + { + bool inString = false; + bool inTwoPairSequence = false; + + multiLineComment = false; + + line = line.Trim(); + + if (line.Length == 0) + { + hasCode = false; + hasComments = false; + return; + } + + if (line[0] == '\'') + { + hasCode = false; + hasComments = true; + return; + } + + if (line.IndexOf('\'') != -1) + { + hasCode = true; + hasComments = true; + return; + } + + hasCode = true; + hasComments = true; + } + + /// + /// Parses an xml-style code line for comments, markup, and blanks. + /// + /// + /// + /// + /// + /// This algorithm is based on one created by Oz Solomon, + /// for his PLC line counter add-in for Visual Studio 2002/2003. + private static void ParseXMLLine(string line, ref bool multiLineComment, ref bool hasCode, ref bool hasComments) + { + bool inString = false; + bool inTwoPairSequence = false; + + hasComments = multiLineComment; + hasCode = false; + + for (int i = 0; i < line.Length; i++) + { + char ch1 = line[i]; + char ch2 = (i < line.Length-1 ? line[i + 1] : '\0'); + char ch3 = (i+1 < line.Length-1 ? line[i + 2] : '\0'); + char ch4 = (i+2 < line.Length-1 ? line[i + 3] : '\0'); + + // Process start of XML comment + if (IsPair('<', '!', ch1, ch2) && IsPair('-', '-', ch3, ch4) && !multiLineComment && !inString) + { + multiLineComment = true; + hasComments = true; + i += 3; + } + + // Process end of XML comment + else if (IsPair('-', '-', ch1, ch2) && ch3 == '>' && !inString) + { + multiLineComment = false; + i += 2; + } + + // Process string + else if (ch3 == '"' && !multiLineComment) + { + inString = !inString; + hasCode = true; + } + + else if (!multiLineComment) + { + if (!Char.IsWhiteSpace(ch1)) + { + hasCode = true; + } + } + } + } + #endregion + + #region Scanning and Summation Methods + /// + /// Scans the solution and creates a hierarchy of + /// support objects for each project and file + /// within each project. + /// + private void ScanSolution() + { + if (m_summaryList == null) + m_summaryList = new List(); + + m_summaryList.Clear(); + + Solution solution = ProjectService.OpenSolution; + if (solution != null) // OpenSolution is null when no solution is opened + { + FileInfo fiSolution = new FileInfo(solution.FileName); + LineCountSummary summary = new LineCountSummary("All Projects", m_projIconMappings["{00000000-0000-0000-0000-000000000000}"]); + m_summaryList.Add(summary); + + // Configure progress bars + tsprgTotal.Minimum = 0; + tsprgTotal.Step = 1; + tsprgTask.Minimum = 0; + tsprgTask.Step = 1; + + List projects = new List(solution.Projects); + tsprgTotal.Maximum = projects.Count; + tsprgTask.Value = 0; + foreach (IProject fiProject in projects) { + tsprgTotal.PerformStep(); + string projName, lang; + if (fiProject.FileName.IndexOf("://") != -1) + { + projName = fiProject.FileName; // this is a web project + lang = "{00000001-0000-0000-0000-000000000000}"; + } else { + projName = fiProject.Name; + lang = fiProject.TypeGuid; + } + + int iconIndex; + #if IMPR1 + iconIndex = projectImageListHelper.GetIndex(IconService.GetImageForProjectType(fiProject.Language ?? "defaultLanguageName")); + #else + m_projIconMappings.TryGetValue(lang, out iconIndex); // default icon 0 + #endif + summary = new LineCountSummary(projName, iconIndex); + m_summaryList.Add(summary); + + tsprgTask.Maximum = 0; + tsprgTotal.Value = 0; + ScanProjectItems(fiProject.Items, summary); + } + + tsprgTask.Value = tsprgTask.Maximum; + tsprgTotal.Value = tsprgTotal.Maximum; + } + else + { + MessageBox.Show("There is no solution open in SharpDevelop.", "Line Counter"); + } + } + + /// + /// Scans the project items (files, usually) of + /// a project's ProjectItems collection. + /// + /// The ProjectItems collection to scan. + /// The root summary data object that these + /// files belong to. + private void ScanProjectItems(List projectItems, LineCountSummary summary) + { + tsprgTask.Maximum += projectItems.Count; + foreach (ProjectItem projectItem in projectItems) + { + tsprgTask.PerformStep(); + if (!(projectItem is FileProjectItem)) { + // Skip references and other special MSBuild things + continue; + } + string projectFile = projectItem.FileName; + if (!Directory.Exists(projectFile)) + { + int iconIndex = 0; + #if IMPR1 + iconIndex = fileImageListHelper.GetIndex(IconService.GetImageForFile(projectFile)); + #else + m_fileIconMappings.TryGetValue(Path.GetExtension(projectFile), out iconIndex); + #endif + summary.FileLineCountInfo.Add(new LineCountInfo(projectFile, iconIndex, summary)); + } + } + } + + /// + /// Performs a complete counting and summation of all lines + /// in all projects and files. + /// + private void SumSolution() + { + try + { + // Clean the list + lvSummary.Items.Clear(); + lvFileList.Items.Clear(); + lvFileList.Groups.Clear(); + + // Configure progress bars + tsprgTotal.Minimum = 0; + tsprgTotal.Step = 1; + tsprgTask.Minimum = 0; + tsprgTask.Step = 1; + + // Skip if there are no projects + if (m_summaryList == null || (m_summaryList != null && m_summaryList.Count == 1)) + { + MessageBox.Show("There are no projects loaded to summarize.", "Line Counter"); + return; + } + + // Get all projects summary + LineCountSummary allProjects = m_summaryList[0]; + allProjects.LineCountSummaryDetails.Reset(); + AddSummaryListItem(allProjects, lvSummary.Groups["lvgAllProj"]); + + tsprgTotal.Maximum = m_summaryList.Count; + tsprgTotal.Value = 0; + for (int s = 1; s < m_summaryList.Count; s++) + { + tsprgTotal.PerformStep(); + + LineCountSummary summary = m_summaryList[s]; + summary.LineCountSummaryDetails.Reset(); + AddSummaryListItem(summary, lvSummary.Groups["lvgEachProj"]); + + tsprgTask.Maximum = summary.FileLineCountInfo.Count; + tsprgTask.Value = 0; + for (int i = 0; i < summary.FileLineCountInfo.Count; i++) + { + tsprgTask.PerformStep(); + + LineCountInfo info = summary.FileLineCountInfo[i]; + if (m_countableTypes.Contains(info.FileType)) + { + info.LineCountInfoDetails.Reset(); + #if IMPR2 + foreach (CountingAlgorithmDescriptor desc in countingAlgorithms) { + if (desc.CanCountLines(info)) { + desc.GetAlgorithm().CountLines(info); + break; + } + } + #else + try + { + CountLines counter = m_countAlgorithms[info.FileType]; + counter(info); + } + catch (Exception ex) + { + Console.WriteLine(ex.Message); + Console.WriteLine(ex.StackTrace); + } + #endif + info.LineCountInfoDetails.Summarize(); + + allProjects.LineCountSummaryDetails.Add(info.LineCountInfoDetails); + summary.LineCountSummaryDetails.Add(info.LineCountInfoDetails); + + tstxtLinesCounted.Text = allProjects.LineCountSummaryDetails.TotalLines.ToString(); + + AddFileListItem(info); + } + } + + summary.LineCountSummaryDetails.Summarize(); + LineCountDetails details = summary.LineCountSummaryDetails; + summary.LinkedListViewItem.SubItems[1].Text = details.TotalLines.ToString(); + summary.LinkedListViewItem.SubItems[2].Text = details.CodeLines.ToString(); + summary.LinkedListViewItem.SubItems[3].Text = details.CommentLines.ToString(); + summary.LinkedListViewItem.SubItems[4].Text = details.BlankLines.ToString(); + summary.LinkedListViewItem.SubItems[5].Text = details.NetLines.ToString(); + details = null; + } + + allProjects.LineCountSummaryDetails.Summarize(); + LineCountDetails totals = allProjects.LineCountSummaryDetails; + allProjects.LinkedListViewItem.SubItems[1].Text = totals.TotalLines.ToString(); + allProjects.LinkedListViewItem.SubItems[2].Text = totals.CodeLines.ToString(); + allProjects.LinkedListViewItem.SubItems[3].Text = totals.CommentLines.ToString(); + allProjects.LinkedListViewItem.SubItems[4].Text = totals.BlankLines.ToString(); + allProjects.LinkedListViewItem.SubItems[5].Text = totals.NetLines.ToString(); + + } + catch (Exception ex) + { + Debug.WriteLine(ex.Message); + Debug.WriteLine(ex.StackTrace); + } + + tsprgTotal.Value = tsprgTotal.Maximum; + } + + /// + /// Obsolete. Useless. Dissapeared. + /// + private void PrepareFileListGroups() + { + lvFileList.Groups.Clear(); + if (tsmiGroupByType.Checked) + { + + } + else if (tsmiGroupByProj.Checked) + { + } + } + + /// + /// Adds a summary item to the projects list view. + /// + /// The summary data object to reference. + /// The summary list view group this item + /// should be listed under. + private void AddSummaryListItem(LineCountSummary summary, ListViewGroup group) + { + ListViewItem lvi = new ListViewItem(); + lvi.Text = summary.ProjectName; + lvi.SubItems.Add("0"); + lvi.SubItems.Add("0"); + lvi.SubItems.Add("0"); + lvi.SubItems.Add("0"); + lvi.SubItems.Add("0"); + + lvi.Tag = summary; + lvi.ImageIndex = summary.IconIndex; + //lvi.StateImageIndex = summary.IconIndex; + lvi.Group = group; + + summary.LinkedListViewItem = lvi; + + lvSummary.Items.Add(lvi); + } + + /// + /// Adds a file information item to the file list view. + /// + /// The file information data object. + private void AddFileListItem(LineCountInfo info) + { + FileInfo fileInfo = new FileInfo(info.FileName); + + ListViewItem lvi = new ListViewItem(); + lvi.Text = fileInfo.Name; + lvi.SubItems.Add(info.LineCountInfoDetails.TotalLines.ToString()); + lvi.SubItems.Add(info.LineCountInfoDetails.CodeLines.ToString()); + lvi.SubItems.Add(info.LineCountInfoDetails.CommentLines.ToString()); + lvi.SubItems.Add(info.FileType); + lvi.SubItems.Add(info.SumMode); + + lvi.Tag = info; + + lvi.ImageIndex = info.IconIndex; + //lvi.StateImageIndex = iconIndex; + + + if (tsmiGroupByType.Checked) + { + ListViewGroup group = lvFileList.Groups["groupType" + info.FileType.Substring(1)]; + if (group == null) + { + group = new ListViewGroup("groupType" + info.FileType.Substring(1), info.FileType.Substring(1).ToUpper() + " Files"); + lvFileList.Groups.Add(group); + } + + lvi.Group = group; + } + else if (tsmiGroupByProj.Checked) + { + ListViewGroup group = lvFileList.Groups["groupProj" + info.ProjectSummary.ProjectName]; + if (group == null) + { + group = new ListViewGroup("groupProj" + info.ProjectSummary.ProjectName, info.ProjectSummary.ProjectName + " Files"); + lvFileList.Groups.Add(group); + } + + lvi.Group = group; + } + + lvFileList.Items.Add(lvi); + } + #endregion + #endregion + } + + #region Support Structures + // Delegate for pluggable line counting methods + delegate void CountLines(LineCountInfo info); + + /// + /// Encapsulates line count sum details. + /// + public class LineCountDetails + { + public LineCountDetails() + { + Reset(); + } + + private int m_totalLines; + private int m_codeLines; + private int m_commentLines; + private int m_doccmtLines; + private int m_normcmtLines; + private int m_blankLines; + private int m_netLines; + + public int TotalLines + { + get { return m_totalLines; } + } + + public int CodeLines + { + get { return m_codeLines; } + } + + public int CommentLines + { + get { return m_commentLines; } + } + + public int DocCommentLines + { + get { return m_doccmtLines; } + } + + public int NormalCommentLines + { + get { return m_normcmtLines; } + } + + public int BlankLines + { + get { return m_blankLines; } + } + + public int NetLines + { + get { return m_netLines; } + } + + public void Reset() + { + m_totalLines = 0; + m_codeLines = 0; + m_commentLines = 0; + m_doccmtLines = 0; + m_normcmtLines = 0; + m_blankLines = 0; + m_netLines = 0; + } + + public void Summarize() + { + m_commentLines = m_doccmtLines + m_normcmtLines; + m_netLines = m_totalLines - m_blankLines; + } + + public void Add(string toWhat, int amount) + { + if (toWhat == null) + toWhat = "totallines"; + + toWhat = toWhat.ToLower(); + switch (toWhat) + { + case "totallines": m_totalLines += amount; break; + case "codelines": m_codeLines += amount; break; + case "doccmtlines": m_doccmtLines += amount; break; + case "normcmtlines": m_normcmtLines += amount; break; + case "blanklines": m_blankLines += amount; break; + } + } + + public void Add(LineCountDetails details) + { + m_totalLines += details.m_totalLines; + m_codeLines += details.m_codeLines; + m_doccmtLines += details.m_doccmtLines; + m_normcmtLines += details.m_normcmtLines; + m_blankLines += details.m_blankLines; + } + } + + /// + /// Wraps a project and the line count total detail + /// for that project. Enumerates all of the files + /// within that project. + /// + public class LineCountSummary + { + public LineCountSummary(string projName, int iconIndex) + { + m_fileLineCountInfo = new List(); + m_lineCountSummaryDetails = new LineCountDetails(); + m_projectName = projName; + m_iconIndex = iconIndex; + } + + private List m_fileLineCountInfo; + private LineCountDetails m_lineCountSummaryDetails; + private string m_projectName; + private int m_iconIndex; + + internal ListViewItem LinkedListViewItem; + + public string ProjectName + { + get { return m_projectName; } + } + + public int IconIndex + { + get { return m_iconIndex; } + } + + public LineCountDetails LineCountSummaryDetails + { + get { return m_lineCountSummaryDetails; } + } + + public List FileLineCountInfo + { + get { return m_fileLineCountInfo; } + } + } + + /// + /// Wraps a project source code file and the line + /// count info for that file. Also provides details + /// about the file type and what icon should be shown + /// for the file in the UI. + /// + public class LineCountInfo + { + public LineCountInfo(string fileName, int iconIndex) + { + m_fileName = fileName; + m_fileType = Path.GetExtension(fileName); + m_iconIndex = iconIndex; + m_sumMode = "Generic"; + + m_lineCountInfoDetails = new LineCountDetails(); + } + + public LineCountInfo(string fileName, int iconIndex, LineCountSummary projectSummary) : this(fileName, iconIndex) + { + m_projectSummary = projectSummary; + } + + private LineCountDetails m_lineCountInfoDetails; + private string m_fileName; + private string m_fileType; + private int m_iconIndex; + private LineCountSummary m_projectSummary; + private string m_sumMode; + + public string FileName + { + get { return m_fileName; } + } + + public string FileType + { + get { return m_fileType; } + } + + public int IconIndex + { + get { return m_iconIndex; } + } + + public string SumMode + { + get { return m_sumMode; } + set { m_sumMode = value; } + } + + public LineCountDetails LineCountInfoDetails + { + get { return m_lineCountInfoDetails; } + } + + public LineCountSummary ProjectSummary + { + get { return m_projectSummary; } + } + } + #endregion +} diff --git a/samples/LineCounter/Src/LineCounterBrowser.resx b/samples/LineCounter/Src/LineCounterBrowser.resx new file mode 100644 index 0000000000..8357e1a487 --- /dev/null +++ b/samples/LineCounter/Src/LineCounterBrowser.resx @@ -0,0 +1,780 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 + + + 365, 17 + + + 126, 17 + + + 464, 17 + + + + AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj0yLjAuMC4w + LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAACZTeXN0 + ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAAAI + cAAAAk1TRnQBSQFMAgEBFAEAARgBAAEEAQABEAEAARABAAT/ASEBAAj/AUIBTQE2BwABNgMAASgDAAFA + AwABYAMAAQEBAAEgBgABYP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8AKgABdQIhAeABgAEy + ATAB7QQAAVUCBQGaAZUBVQFWAf9wAAG3AaIBkwH/AWYBTAE4Af8BZgFMATgB/wFmAUwBOAH/AWYBTAE4 + Af8BZgFMATgB/wFmAUwBOAH/AWYBTAE4Af8BZgFMATgB/wFmAUwBOAH/AWYBTAE4Af8BZgFMATgB/0wA + AYABNAEzAfIBsQFlAWkB/wFzAj8B/wGVAVUBVgH/AXMCPwH/AWYBTAE4Af8BZgFMATgB/wFmAUwBOAH/ + AWYBTAE4Af8BZgFMATgB/wFmAUwBOAH/AWYBTAE4Af8BZgFMATgB/wgAAQMBngHeAf8BAwGeAd4B/wED + AZ4B3gH/AQMBngHeAf8BAwGeAd4B/wEDAZ4B3gH/AQMBngHeAf8BAwGeAd4B/wEDAZ4B3gH/AQMBngHe + Af8BAwGeAd4B/wEDAZ4B3gH/AQMBngHeAf8BAwGeAd4B/xAAATwCAgFiAfcB5QHcAf8BtwGiAZMB/wG3 + AaIBkwH/AbcBogGTAf8BtwGiAZMB/wG3AaIBkwH/AbcBogGTAf8BtwGiAZMB/wG3AaIBkwH/AbcBogGT + Af8BZgFMATgB/wgAAaQBigF7Af8BegFhAU0B/wF4AV4BSwH/AXYBXAFIAf8BdAFaAUUB/wFyAVcBQwH/ + AXABVQFBAf8BbgFTAT8B/wFrAVEBPQH/AWoBTwE7Af8BaQFOATkB/wFnAU0BOAH/AWcBTQE4Af8BZgFL + ATYB/wQAAZgBWgFYAf8BfAI7AfkBwAFxAW0B/wG7AWQBYQH/Ab0BZgFdAf8B2gFzAXIB/wHEAmYB/wGW + AVwBVQH/AXABOAE5Af8BtwGiAZMB/wG3AaIBkwH/AbcBogGTAf8BtwGiAZMB/wG3AaIBkwH/AWYBTAE4 + Af8IAAEDAZ4B3gH/AdgD/wHTAf8B/gH/Ac4D/wHJA/8BxQP/AcAB/wH+Af8BvAH/Af4B/wG3A/8BswH/ + Af4B/wGwAf8B/gH/Aa0B/wH+Af8BqgH/Af4B/wEDAZ4B3gH/CAABrALVAf8BrgG0AawB/wGuAZkBigH/ + AfkB6QHiAf8B+AHmAd0B/wH3AeIB2AH/AfUB3gHTAf8B9AHbAc4B/wHzAdcBygH/AfIB1AHFAf8B8QHQ + AcEB/wHwAc0BvAH/AbcBogGTAf8BZgFMATgB/wgAAaQBigF7Af8BxwP/AYoB4wH1Af8BggHgAfQB/wF8 + AdwB9AH/AXMB2QH0Af8BagHVAfMB/wFhAdEB8wH/AVgBzgHzAf8BTgHJAfEB/wFFAcYB8AH/AT0BwgHx + Af8BPQHCAfEB/wFoAU4BOAH/BAAB3AGHAYYB/wHAAXgBegH/AdwBhwGGAf8BigFUAVUB/wG+AZkBlwH/ + AcUBhAGCAf8BxAJmAf8BsQFZAVoB/wGxAVkBWgH/AfMB1wHKAf8B8gHUAcUB/wHxAdABwQH/AfABzQG8 + Af8BtwGiAZMB/wFmAUwBOAH/CAABAwGeAd4B/wHUA/8BPQGfAVkB/wFCAYABSgH/AToBcAFBAf8BMgFh + ATkB/wEqAVMBMgH/AbQB/wH+Af8BsAH/Af4B/wGrAf8B/gH/AacB/wH+Af8BpwH/Af4B/wGsAf8B/gH/ + AQMBngHeAf8QAAE8AgIBYgH5Ae4B6AH/AUIBgAFKAf8BOgFwAUEB/wEyAWEBOQH/ASsBUwEzAf8BkgFX + AVkB/wGAAUYBRwH/AXEBOQE6Af8B8QHRAcIB/wG3AaIBkwH/AWYBTAE4Af8IAAGsAZEBggH/AdQD/wHO + A/8ByAH/Af4B/wHEAf8B/gH/Ab4D/wG5A/8BtAH/Af4B/wGwAf8B/gH/AasB/wH+Af8BpwH/Af4B/wGn + Af8B/gH/AVUBzAHyAf8BbQFTAT4B/wQAAQ0CAQEQAdMBhwGGAf8B4AGPAY0B/wF1AkEB/wHZAcQBwAH/ + AdUBtAGxAf8BzQJxAf8BsQFZAVoB/wHyAdUBywH/AfUB2wHQAf8B8wHYAcsB/wHyAdUBxgH/AfEB0QHC + Af8BtwGiAZMB/wFmAUwBOAH/CAABAwGeAd4B/wHZAf8B/gH/AU0BqQFmAf8B4QHVAc4B/wHWAcYBvgH/ + AcwBuAGtAf8BMQFgAToB/wG6Af8B/gH/AbYB/wH+Af8BsQH/Af4B/wGsAf8B/gH/AawB/wH+Af8BsAH/ + Af4B/wEDAZ4B3gH/CAABrALVAf8BrgG0AawB/wGuAZkBigH/AfsB8gHtAf8BRAGkAV8C/wH4A/8B+AL/ + ATIBYQE6Av8B+AP/AfgC/wGAAUUBRgH/AfMB1QHHAf8BtwGiAZMB/wFmAUwBOAH/CAABsAGXAYcB/wHZ + Af8B/gH/AdUD/wHPAf8B/gH/AcoB/wH+Af8BxwGyAaUB/wG/Af8B/gH/AboB/wH+Af8BtgH/Af4B/wGx + Af8B/gH/AawB/wH+Af8BrAH/Af4B/wFiAdEB8wH/AXEBVgFCAf8EAAHdAZABjgH/AeUBpAGmAf8B8AKo + Af8BqgFuAXEB/wGDAVgBVwH/AZMCYQH/AcIBbwFwAf8BsQFZAVoB/wFwATgBOQH/AfYB4QHVAf8B9QHc + AdEB/wH0AdgBzAH/AfMB1QHHAf8BtwGiAZMB/wFmAUwBOAH/CAABAwGeAd4B/wHfA/8BXQG0AXMB/wHq + AeEB3AH/AZkBNgEDAf8B1AHEAbsB/wE6AXABQQH/AcEB/wH+Af8B/AGSAWAB/wHPAXUBRwH/AaYBWwE2 + Af8BsgH/Af4B/wG0Af8B/gH/AQMBngHeAf8QAAE8AgIBYgH8AfYB8wH/AU8BqgFoAv8B+AP/AfgC/wE6 + AXEBQQL/AfgD/wH4Av8BkgJYAf8B8wHaAc0B/wG3AaIBkwH/AWYBTAE4Af8IAAG1AZsBjAH/Ad8D/wGz + AZkBiwH/AbMBmgGKAf8B0AH/Af4B/wHGAbEBpgH/AcYB/wH+Af8BwAGqAZ0B/wGzAZkBiwH/AaYBiwF9 + Af8BmwGBAXIB/wGyAf8B/gH/AW4B1wHzAf8BdAFbAUcB/wQAAXgCIwHDAb0CagHzAbQCYgHnAe0BqQGo + Af8B3QGJAYYB/wHWAYABegH/AcIBbwFwAf8BwAJ1Af8BvQF1AXYB/wH3AeUB2wH/AfYB4QHXAf8B9AHe + AdMB/wHzAdoBzQH/AbcBogGTAf8BZgFMATgB/wgAAQMBngHeAf8B5QP/AW0BvgGBAf8B8gHtAesB/wHo + Ad8B2gH/Ad4B0AHKAf8BQgGBAUoB/wHHAf8B/gH/AcEB/wH+Af8BvAH/Af4B/wG4Af8B/gH/AbgB/wH+ + Af8BuQH/Af4B/wEDAZ4B3gH/CAABrALVAf8BrgG0AawB/wGuAZkBigH/AdABtgGYAf8BfwF+AVEB/wGu + AXgBWAH/AbwBmAGEAf8BYQFRAYAB/wEwAScBcAH/ASYBHAFlAf8BHwETAV0B/wH1Ad8B0wH/AbcBogGT + Af8BZgFMATgB/wgAAboBoQGTAf8B5QP/AeED/wHcA/8B1wH/Af4B/wHHAbIBpgH/AcwB/wH+Af8B9wHz + AfEB/wHqAeEB3QH/AdsBzgHGAf8BnAGBAXIB/wG4Af8B/gH/AXoB2wH0Af8BeAFeAUsB/wwAAbQBYgFl + AesB2wGfAZ4B/wHQAYIBgQH/Ac4BgQF9Af8BuQFyAXMB/wH6AfAB6wH/AfoB7QHnAf8B+AHpAeEB/wH3 + AeUB3QH/AfYB4gHYAf8B9QHfAdMB/wG3AaIBkwH/AWYBTAE4Af8IAAEDAZ4B3gH/AesB/wH+Af8BfQHH + AYsB/wFwAcABgQH/AWIBtwF5Af8BVQGvAWwB/wFHAaYBYQH/Ac0B/wH+Af8ByAH/Af4B/wHDA/8BvQH/ + Af4B/wG9Af8B/gH/Ab4B/wH+Af8BAwGeAd4B/xAAAfMBwgGrAf8B1QGBAU8B/wE0AZoBDAH/AWUBgQEl + Af8BwAFeASwB/wGlAZcBhQL/AfgD/wH4Av8BKAEfAWcB/wH2AeIB2gH/AbcBogGTAf8BZgFMATgB/wgA + Ab4BpwGZAf8B6wH/Af4B/wGzAZkBiwH/AbMBmQGKAf8B3AH/Af4B/wHHAbEBpgH/AdID/wHNAf8B/gH/ + AcgB/wH+Af8BwwP/Ab0B/wH+Af8BvQH/Af4B/wGCAeAB9QH/AXwBYgFQAf8MAAHdAZwBmwH/AdMBlAGO + Af8B/QH2AfUB/wHOAYEBfQH/Ab0BdQF2Af8B/AH0AfAB/wH7AfEB7QH/AfoB7gHoAf8B+AHqAeQB/wH3 + AecB3wH/AfYB4gHaAf8BtwGiAZMB/wFmAUwBOAH/CAABAwGeAd4B/wHwA/8BPQGfAVkB/wFCAYABSgH/ + AToBcAFBAf8BMgFhATkB/wEqAVMBMgH/AdMD/wHOAf8B/gH/AcgD/wHDAf8B/gH/AcMB/wH+Af8BwwH/ + Af4B/wEDAZ4B3gH/EAAB9AGbAXYB/wGBAYYBNAH/AVwBrwEOAf8ByAGCAScB/wFWAX8BLQH/AUYBmwEo + Av8B+AP/AfgC/wE3AS4BdgH/AfgB6AHfAf8BtwGiAZMB/wFmAUwBOAH/CAABwgGrAZ8B/wHwA/8B7AP/ + AecD/wHjA/8BxwGxAaUB/wHYAf8B/gH/AcABqgGdAf8BswGZAYsB/wGmAYsBfQH/AZsBgQFyAf8BwwH/ + Af4B/wGNAeQB9gH/AYABZwFUAf8QAAHDAa4BngH/A/4B/wH+Af0B/AH/Af0B+gH4Af8B/QH4AfUB/wH8 + AfQB8QH/AfsB8gHtAf8B+gHuAekB/wH5AesB5QH/AfgB6AHfAf8BtwGiAZMB/wFmAUwBOAH/CAABAwGe + Ad4B/wH0A/8BTQGpAWYB/wHhAdUBzgH/AdYBxgG+Af8BzAG4Aa0B/wExAWABOgH/AdkD/wHVA/8BzwP/ + AcoB/wH+Af8BygH/Af4B/wHIA/8BAwGeAd4B/xAAAacBlQFiAf8BAwG0ASoB/wKdATwC/wF5AToB/wFl + Aa8BEQH/AT0BugEbAf8BZAFpAd0B/wFWAVwB2QH/AUgBQgGFAf8B+QHsAeYB/wG3AaIBkwH/AWYBTAE4 + Af8IAAHGAbABpAH/AfQD/wGzAZkBiwH/AbMBmQGLAf8B6AP/AccBsQGmAf8B3wP/AfcB8wHxAf8B6gHh + Ad0B/wHbAc4BxgH/AZwBgQFyAf8BygH/Af4B/wGYAegB9gH/AYIBbAFZAf8QAAHIAbIBowr/Af0B/AH/ + Af0B+wH5Af8B/QH5AfYB/wH8AfUB8gH/AfsB8gHuAf8B+wHvAeoB/wH5AewB5gH/AbcBogGTAf8BZgFM + ATgB/wgAAQMBngHeAf8B+AP/AV0BtAFzAf8B6gHhAdwB/wGZATYBAwH/AdQBxAG7Af8BOgFwAUEB/wHf + A/8B/AGSAWAB/wHPAXUBRwH/AaYBWwE2Af8B0AH/Af4B/wHNA/8BAwGeAd4B/xAAAaYB0AGfAf8BOwH4 + AXIB/wGXAekBjwH/AcEBpwFVAf8BvAGZARsB/wGWAdUBdwH/Af0B+QH3Af8B/AH2AfMB/wH7AfQB7wH/ + AbcBogGTAf8BtwGiAZMB/wFnAU0BOQH/CAABygG1AasB/wH4A/8B9QP/AfED/wHuA/8B6QP/AeQD/wHf + A/8B2wH/Af4B/wHVAf8B/gH/AdAB/wH+Af8B0AH/Af4B/wGfAesB9wH/AYYBcQFfAf8QAAHMAbYBpw7/ + Av0B/wH+AfsB+gH/Af0B+QH3Af8B/AH2AfMB/wH7AfQB7wH/AbcBogGTAf8BtwGiAZMB/wFnAU0BOQH/ + CAABAwGeAd4B/wH8A/8BbQG+AYEB/wHyAe0B6wH/AegB3wHaAf8B3gHQAcoB/wFCAYEBSgH/AeYD/wHg + A/8B2wP/AdcD/wHXA/8B0gP/AQMBngHeAf8QAAHQAcgBsQH/Ac0B6QHAAf8BowHwAZkB/wE9AdwBZwH/ + AdwBvgGMAf8B8AH2AesB/wH+AvsB/wH9AfkB+AH/AbcBogGTAf8BZwFNATkB/wFnAU0BOQH/AWcBTQE5 + Af8IAAHOAbwBsQH/AfwD/wEDATYC/wHqAZ0BeQH/AeoBkwFrAf8B6gGKAVsB/wHqAYEBTQH/AeYBegFC + Af8B3gFyATkB/wHUAWoBMwH/AccBYgEvAf8B1wP/AacB7gH3Af8BiwF2AWQB/xAAAdEBuwGrEv8B/gH9 + Af8B/gL7Af8B/QH5AfgB/wG3AaIBkwH/AWcBTQE5Af8BZwFNATkB/wFnAU0BOQH/CAABAwGeAd4F/wF9 + AccBiwH/AXABwAGBAf8BYgG3AXkB/wFVAa8BbAH/AUcBpgFhAf8B6wH/Af4B/wHmA/8B4gP/Ad0D/wHd + A/8B2AP/AQMBngHeAf8QAAHVAb8Brxb/Av4B/wH+AfwB+wH/AbkBpAGVAf8B1AHFAboB/wFmAUwBOAH/ + AVsBDQEMAakIAAHUAcIBuQX/AccBsQGmAf8BtAGZAYoB/wGhAYYBdwH/AfMD/wHvA/8B6wH/Af4B/wHm + A/8B4gP/Ad0D/wHdA/8BqwHwAfcB/wGQAXsBaQH/EAAB1QG/Aa8W/wL+Af8B/gH8AfsB/wG5AaQBlQH/ + AdQBxQG6Af8BZgFMATgB/wFbAQ0BDAGpCAABAwGeAd4J/wH+A/8B+gP/AfcD/wHzA/8B8AP/AewD/wHn + Af8B/gH/AeID/wHeA/8B3gP/AQMBngHeAf8QAAHYAcIBshv/Af4B/wHAAasBnAH/AWYBTAE4Af8BWwEN + AQwBqAwAAdgByQHACf8B/gP/AfoD/wH3A/8B8wP/AfAD/wHsA/8B5wH/Af4B/wHiA/8B3gP/Ad4D/wGU + AYABbwH/EAAB2AHCAbIb/wH+Af8BwAGrAZwB/wFmAUwBOAH/AVsBDQEMAagMAAEDAZ4B3gH/AQMBngHe + Af8BAwGeAd4B/wEDAZ4B3gH/AQMBngHeAf8BAwGeAd4B/wEDAZ4B3gH/AQMBngHeAf8BAwGeAd4B/wED + AZ4B3gH/AQMBngHeAf8BAwGeAd4B/wEDAZ4B3gH/AQMBngHeAf8QAAHYAcIBsgH/AdgBwgGyAf8B2AHC + AbIB/wHYAcIBsgH/AdgBwgGyAf8B2AHCAbIB/wHUAb4BrgH/Ac8BuQGpAf8ByQGzAaQB/wFPAgYBixAA + Ad0BzwHIAf8B2gHLAcIB/wHWAcYBvQH/AdIBwQG3Af8B0AG8AbIB/wHMAbgBrQH/AckBswGpAf8BxgGw + AaQB/wHDAawBoAH/AcABqQGcAf8BvQGlAZcB/wG6AaEBkwH/AboBoQGTAf8BmQGCAXQB/xAAAdgBwgGy + Af8B2AHCAbIB/wHYAcIBsgH/AdgBwgGyAf8B2AHCAbIB/wHYAcIBsgH/AdQBvgGuAf8BzwG5AakB/wHJ + AbMBpAH/AU8CBgGL0AABtwGiAZMB/wFmAUwBOAH/AWYBTAE4Af8BZgFMATgB/wFmAUwBOAH/AWYBTAE4 + Af8BZgFMATgB/wFmAUwBOAH/AWYBTAE4Af8BZgFMATgB/wFmAUwBOAH/AWYBTAE4Af8BZgFMATgB/wFm + AUwBOAH/CAABtwGiAZMB/wFmAUwBOAH/AWYBTAE4Af8BZgFMATgB/wFmAUwBOAH/AWYBTAE4Af8BZgFM + ATgB/yQAAaQBigF7Af8BegFhAU0B/wF4AV4BSwH/AXYBXAFIAf8BdAFaAUUB/wFyAVcBQwH/AXABVQFB + Af8BbgFTAT8B/wFrAVEBPQH/AWoBTwE7Af8BaQFOATkB/wFnAU0BOAH/AWYBSwE2Af8MAAG3AaIBkwH/ + AWYBTAE4Af8BZgFMATgB/wFmAUwBOAH/AWYBTAE4Af8BZgFMATgB/wFmAUwBOAH/AWYBTAE4Af8BZgFM + ATgB/wFmAUwBOAH/AWYBTAE4Af8BZgFMATgB/xAAAbcBogGTAf8B9wHlAdwB/wHdAc8ByAH/AdgByQHB + Af8B0wHCAbkB/wHPAbwBsgH/AcoBtgGqAf8BxgGwAaQB/wHCAasBngH/Ab4BpgGYAf8BugGgAZIB/wG0 + AZoBjAH/AbABlQGGAf8BZgFMATgB/wgAAbcBogGTAf8B+QHtAecB/wHnAd4B2QH/AeQB2AHSAf8B3wHR + AcsB/wHZAcsBwwH/AWYBTAE4Af8kAAGkAYoBewH/AccD/wGKAeMB9QH/AYIB4AH0Af8BfAHcAfQB/wFz + AdkB9AH/AWoB1QHzAf8BYQHRAfMB/wFYAc4B8wH/AU4ByQHxAf8BRQHGAfAB/wE9AcIB8QH/AWgBTgE4 + Af8MAAG3AaIBkwH/AfcB5QHcAf8BtwGiAZMB/wG3AaIBkwH/AbcBogGTAf8BtwGiAZMB/wG3AaIBkwH/ + AbcBogGTAf8BtwGiAZMB/wG3AaIBkwH/AbcBogGTAf8BZgFMATgB/xAAAbcBogGTAf8B+QHpAeIB/wH5 + AekB4gH/AfkB6QHiAf8B+AHmAd0B/wH3AeIB2AH/AfUB3gHTAf8B9AHbAc4B/wHzAdcBygH/AfIB1AHF + Af8B8QHQAcEB/wHwAc0BvAH/AbYBnAGOAf8BZgFMATgB/wgAAbcBogGTAf8B+wHzAe8B/wH6Ae0B5wH/ + AfgB5wHfAf8B0QG7Aa4B/wHAAbABpgH/AWYBTAE4Af8BKwIBAUABKwIBAUABKwIBAUABKwIBAUABKwIB + AUAQAAGoAY0BfwH/Ac0D/wHIA/8BwgH/Af4B/wG9Af8B/gH/AbgD/wGzAf8B/gH/Aa8D/wGrA/8BpwH/ + Af4B/wGjAf8B/gH/AUgBxwHxAf8BawFQATsB/wwAAbcBogGTAf8B+QHpAeIB/wH4AeYB3QH/AfcB4gHY + Af8B9QHeAdMB/wH0AdsBzgH/AfMB1wHKAf8B8gHUAcUB/wHvAcwBuwH/AdsBnQF9Af8BewF6AS8B/wFg + AWsBNwH/AZ8BZQFBAf8BeQEhARQB1QEOAgEBEQQAAbcBogGTAf8B+QHuAegB/wH5Ae4B6AH/AfkB7gHo + Af8B6gGPAWMB/wHqAYQBUgH/AeYBewFCAf8B3wFyATkB/wHSAWkBMwH/AcEBYAEtAf8B8gHVAcYB/wHx + AdEBwgH/AbwBowGVAf8BZgFMATgB/wgAAboBpQGWAf8B/QH4AfUB/wH8AfMB7wH/AbcBogGTAf8BZgFM + ATgB/wFmAUwBOAH/AWYBTAE4Af8BZgFMATgB/wFmAUwBOAH/AWYBTAE4Af8BZgFMATgB/wErAgEBQBAA + AawBkQGCAf8B1AP/Ac8BZwExAf8BugFdASsB/wGlAVMBKAH/AZMBSgElAf8BuQP/Ac8BZwExAf8BugFd + ASsB/wGlAVMBKAH/AZMBSgElAf8BVQHMAfIB/wFtAVMBPgH/DAABtwGiAZMB/wH5Ae4B6AH/AfgB6gHj + Af8B+AHmAd4B/wH3AeMB2QH/AfUB3wHVAf8B9QHbAdAB/wHzAdgBywH/AesBsgGUAf8B9QGJAV0B/wGG + AYEBPAH/ASoBiwEfAf8BaAFxATcB/wGtAWgBQwH/AZABWgFQAecEAAG3AaIBkwH/AfsB8gHtAf8B+wHy + Ae0B/wH7AfIB7QH/AfoB7gHpAf8B+QHqAeQB/wH4AecB4AH/AfcB5AHaAf8B9gHhAdUB/wH1AdwB0QH/ + AfQB2AHMAf8B8wHVAccB/wHCAaoBngH/AWYBTAE4Af8IAAG+AakBmgH/Af4B/AH6Af8B/QH3AfUB/wG3 + AaIBkwH/AfgB5wHgAf8B2gHMAcQB/wHUAcMBuwH/Ac4BvAGxAf8ByQG1AakB/wHEAa0BoQH/AWYBTAE4 + Af8BKwIBAUAQAAGwAZcBhwH/AdkB/wH+Av8BrAGBAf8B8wHYAcwB/wHwAc4BvgH/AaUBUgEoAf8BvwH/ + Af4C/wGsAYEB/wHzAdgBzAH/AfABzgG+Af8BpQFSASgB/wFiAdEB8wH/AXEBVgFCAf8MAAG3AaIBkwH/ + AfsB8gHtAf8B5gF7AUMB/wHeAXEBOQH/AfgB5wHgAf8BxAGuAaIB/wHAAakBnAH/AbsBogGVAf8B8wGa + AXQB/wG9AYMBYQH/AVkBkQFAAf8BawGhAS8B/wGwAX8BRAH/AWIBagFBAf8BNwF7ASUB/wQAAbcBogGT + Af8B/AH2AfMB/wH8AfYB8wH/AfwB9gHzAf8B6gGPAWMB/wHqAYQBUgH/AeYBewFCAf8B3wFyATkB/wHS + AWkBMwH/AcEBYAEtAf8B9AHeAdMB/wHzAdoBzQH/AccBsQGlAf8BZgFMATgB/wgAAcMBrgGeBf8B/gH8 + AfsB/wG3AaIBkwH/AfoB7QHnAf8B+gHtAecB/wH6Ae0B5wH/AfoB7QHnAf8B+gHtAecB/wHJAbUBqgH/ + AWYBTAE4Af8BKwIBAUAQAAG1AZsBjAH/Ad8E/wG0AYsC/wGoAXwC/wGbAWkB/wH3AY4BXAH/AcYB/wH+ + Av8BtAGLAv8BqAF8Av8BmwFpAf8B9wGOAVwB/wFuAdcB8wH/AXQBWwFHAf8MAAG3AaIBkwH/AfwB9gHz + Af8B+wHyAe4B/wH7Ae8B6gH/AfkB6wHmAf8B+QHoAeEB/wH3AeUB2wH/AfYB4QHXAf8B3gGcAXkB/wFL + AZYBTQH/AWABpAFMAf8B0gGRAWEB/wHeAYYBXAH/AVYBkQEtAf8BNQGUARoB/wQAAboBpQGWAf8B/QH5 + AfYB/wH9AfkB9gH/Af0B+QH2Af8B/AH2AfMB/wH8AfMB7wH/AfoB8AHrAf8B+gHtAecB/wH4AekB4QH/ + AfcB5QHdAf8B9gHiAdgB/wH1Ad8B0wH/AcwBuAGuAf8BZgFMATgB/wgAAdkByQHAAf8B0wHCAbkB/wHN + AbsBsQH/AbsBpgGXAf8B+wHyAe4B/wEYARYBgAH/Aa4BogG+Af8B9gHiAdgB/wHHAbUBwQH/AdABvQG0 + Af8BZgFMATgB/wErAgEBQBAAAboBoQGTAf8B5QP/AeED/wHcA/8BlwGBAXIB/wHRA/8BzAH/Af4B/wHH + Af8B/gH/AW0BUgE+Af8BvAH/Af4B/wG4Af8B/gH/AXoB2wH0Af8BeAFeAUsB/wwAAboBpQGWAf8B/QH5 + AfYB/wHmAXsBQwH/Ad4BcQE5Af8B+gHwAesB/wHEAa4BogH/AcABqAGcAf8BuwGiAZQB/wGdAZwBbQH/ + AUkByQFuAf8BdQHNAYcB/wGwAbEBgQH/AeYBkQFkAf8BmAGaATsB/wFtAbABWQH8BAABvgGpAZoB/wH+ + AfwB+wH/Af4B/AH7Af8BpQFSASgB/wH9AfkB+AH/AasBuAGRAf8BVwF7ATAB/wGKAXMBSwH/Ac4BsQGe + Af8B+AHqAeQB/wGlAVIBKAH/AfYB4gHaAf8B0gHAAbgB/wFmAUwBOAH/FAABwQGrAZwB/wH9AfcB9QH/ + AcUBvAHRAf8BGAEWAYAB/wGsAaEBvwH/AgMBdwH/AdYBxgG9Af8BZgFMATgB/wErAgEBQBAAAb4BpwGZ + Af8B6wH/Af4B/wHmA/8B4QP/AaQBjgGBAf8BlwGBAXIB/wGKAXUBYwH/AYEBaAFVAf8BdQFcAUkB/wHD + A/8BvQH/Af4B/wGCAeAB9QH/AXwBYgFQAf8MAAG+AakBmgH/Af4B/AH7Af8B/QH5AfgB/wH9AfcB9AH/ + AfwB9AHwAf8B+wHxAe0B/wH6Ae4B6AH/AfgB6gHkAf8B1gHaAcAB/wF6AdwBkQH/AcoB9AHFAf8BugHk + AbEB/wGUAa0BcgH/AboBigFBAf8BWgEQAQoBqQQAAcMBrgGeAf8D/gH/AaUBUgEoAf8D/gH/Af4B/QH8 + Af8BgQGCAT4B/wGQAZMBRQH/AXMBegE0Af8BeQGnAWoB/wH6Ae4B6QH/AfkB6wHlAf8BpQFSASgB/wHZ + AckBwQH/AWYBTAE4Af8UAAHHAbIBowH/Af4B+wH5Af8B+wH0AfEB/wHGAb4B0wH/ARgBFwGBAf8BMgEv + AYkB/wHWAcYBvQH/AWYBTAE4Af8BKwIBAUAQAAHCAasBnwH/AfAD/wHsA/8B5wP/AeMD/wHeA/8BlwGB + AXIB/wHTA/8BzgH/Af4B/wHIA/8BwwH/Af4B/wGNAeQB9gH/AYABZwFUAf8MAAHDAa4BngH/A/4B/wHm + AXsBQwH/Ad4BcQE5Af8B/QH4AfUB/wHEAa4BogH/AcABqAGbAf8BuwGiAZQB/wG2AZwBjQH/AeEB4AHG + Af8BwAHWAakB/wGGAcoBiwH/AVQBPgEfAdMBSgEEAQMBggEOAgEBEQQAAcgBsgGjCf8BpQFSASgF/wFm + AbYBZQH/AcMByAGdAf8BogGRAT0B/wGcAcYBigH/AfsB8gHuAf8BpQFSASgB/wH5AewB5gH/Ad8B0gHM + Af8BZgFMATgB/xQAAc8BuQGpA/8B/gH/AcoBxwHdAf8CAwF3Af8BOAE2AY4B/wIDAXcB/wHdAc8ByAH/ + AWcBTQE5Af8BZgFMATgB/wFmAUwBOAH/AWYBTAE4Af8IAAHGAbABpAH/AfQD/wHwA/8B7QP/Ad4BcQE5 + Af8BzwFnATEB/wG6AV0BKwH/AaUBUwEoAf8BkwFKASUB/wHPA/8BygH/Af4B/wGYAegB9gH/AYIBbAFZ + Af8MAAHIAbIBowr/Af0B/AH/Af0B+wH5Af8B/QH5AfYB/wH8AfUB8gH/AfsB8gHuAf8B+wHvAeoB/wH5 + AewB5gH/AbcBogGTAf8BZgFMATgB/xAAAcwBtgGnEf8B1gHyAdIB/wGZAcoBiwH/AawBrwF/Af8B7wHx + AeYB/wH8AfYB8wH/AfsB9AHvAf8B6gHiAd0B/wHlAdsB1QH/AWcBTQE5Af8UAAHUAb4Brwr/Av0C/wL9 + Af8IAAFnAU0BOQH/AYEBvAHFAf8BfwHdAfQB/wFmAUwBOAH/CAABygG1AasB/wH4A/8B9QP/AfEE/wGk + AXYB/wH3AeMB2wH/AfMB2AHMAf8B8AHOAb4B/wGlAVIBKAH/AdUB/wH+Af8B0AH/Af4B/wGfAesB9wH/ + AYYBcQFfAf8MAAHMAbYBpwX/AeYBewFDAf8B3gFxATkC/wL9Af8BxQGuAaIB/wHAAakBmwH/AfwB9gHz + Af8B+wH0Ae8B/wG3AaIBkwH/AbcBogGTAf8BZwFNATkB/xAAAdEBuwGrGv8B/gH9Af8B/gL7Af8B/QH5 + AfgB/wG3AaIBkwH/AWcBTQE5Af8BZwFNATkB/wFnAU0BOQH/FAAB2AHCAbIR/wgAAWcBTQE5Af8BwAH/ + Af4B/wGGAeEB9QH/AWYBTAE4Af8IAAHOAbwBsQH/AfwD/wH5A/8B9QT/AawBgQH/AfwB9AHwAf8B+QHq + AeMB/wH1Ad4B0wH/AboBXAErAf8B2wP/AdcD/wGnAe4B9wH/AYsBdgFkAf8MAAHRAbsBqxL/Af4B/QH/ + Af4C+wH/Af0B+QH4Af8BtwGiAZMB/wFnAU0BOQH/AWcBTQE5Af8BZwFNATkB/xAAAdUBvwGvHv8C/gH/ + Af4B/AH7Af8BuQGkAZUB/wHUAcUBugH/AWYBTAE4Af8BWwENAQwBqRQAAdgBwgGyAf8B2AHCAbIB/wHU + Ab8BrgH/AdQBvwGuAf8BzgG4AakB/wHIAbIBowH/Ac4BuAGpAf8ByAGyAaMB/wHMAf8B/gH/AZAB5QH1 + Af8BZgFMATgB/wgAAdQBwgG5Bf8B/QP/AfoE/wG0AYsC/wGoAXwC/wGbAWkB/wH3AY4BXAH/Ac4BZwEx + Af8B4gP/Ad0D/wGrAfAB9wH/AZABewFpAf8MAAHVAb8Brxb/Av4B/wH+AfwB+wH/AbkBpAGVAf8B1AHF + AboB/wFmAUwBOAH/AVsBDQEMAakQAAHYAcIBsiP/Af4B/wHAAasBnAH/AWYBTAE4Af8BWwENAQwBqCgA + Ab4BqQGaAf8B+QP/Ae8D/wHlA/8B2AH/Af4B/wGYAegB9QH/AWYBTAE4Af8IAAHYAckBwAn/Af4D/wH6 + A/8B9wP/AfMD/wHwA/8B7AP/AecB/wH+Af8B4gP/Ad4D/wGUAYABbwH/DAAB2AHCAbIb/wH+Af8BwAGr + AZwB/wFmAUwBOAH/AVsBDQEMAagUAAHYAcIBsgH/AdgBwgGyAf8B2AHCAbIB/wHYAcIBsgH/AdgBwgGy + Af8B2AHCAbIB/wHYAcIBsgH/AdgBwgGyAf8B1AG+Aa4B/wHPAbkBqQH/AckBswGkAf8BTwIGAYssAAHD + Aa4BngX/AfgD/wHwA/8B5QP/AdkD/wFmAUwBOAH/CAAB3QHPAcgB/wHaAcsBwgH/AdYBxgG9Af8B0gHB + AbcB/wHQAbwBsgH/AcwBuAGtAf8ByQGzAakB/wHGAbABpAH/AcMBrAGgAf8BwAGpAZwB/wG9AaUBlwH/ + AboBoQGTAf8BmQGCAXQB/wwAAdgBwgGyAf8B2AHCAbIB/wHYAcIBsgH/AdgBwgGyAf8B2AHCAbIB/wHY + AcIBsgH/AdQBvgGuAf8BzwG5AakB/wHJAbMBpAH/AU8CBgGLdAAB2QHJAcAB/wHTAcIBuQH/Ac0BuwGx + Af8ByQG0AakB/wHFAa8BogH/AcEBqQGcAf8BrQGSAYMB/4QAAS4CAQFGAZMBZQFMAf8BjgFgAUcB/wGI + AVsBQgH/AYEBVAE6Af8BLgIBAUYIAAEuAgEBRgGTAWUBTAH/AY4BYAFHAf8BiAFbAUIB/wGBAVQBOgH/ + AS4CAQFGVAABtwGiAZMB/wFmAUwBOAH/AWYBTAE4Af8BZgFMATgB/wFmAUwBOAH/AWYBTAE4Af8BZgFM + ATgB/wFmAUwBOAH/AWYBTAE4Af8BZgFMATgB/wFmAUwBOAH/AWYBTAE4Af8MAAG3AaIBkwH/AWYBTAE4 + Af8BZgFMATgB/wFmAUwBOAH/AWYBTAE4Af8BZgFMATgB/wFmAUwBOAH/AWYBTAE4Af8BZgFMATgB/wFm + AUwBOAH/AWYBTAE4Af8BZgFMATgB/wgAAaUBeAFdAf8B/QH4AfYB/wH8AfQB8AH/AfoB7wHpAf8B+QHp + AeMB/wGGAVoBQAH/AWYBTAE4Af8BZgFMATgB/wGlAXgBXQH/Af0B+AH2Af8B/AH0AfAB/wH6Ae8B6QH/ + AfkB6QHjAf8BhgFaAUAB/wwAAbcBogGTAf8BZgFMATgB/wFmAUwBOAH/AWYBTAE4Af8BZgFMATgB/wFm + AUwBOAH/AWYBTAE4Af8BZgFMATgB/wFmAUwBOAH/AWYBTAE4Af8gAAG3AaIBkwH/AfcB5QHcAf8BtwGi + AZMB/wHaAcwBxQH/AdcBxwG+Af8B0wHCAbkB/wHPAb0BswH/AcwBtwGtAf8ByAGzAagB/wHFAa8BowH/ + AcIBqwGeAf8BZgFMATgB/wwAAbcBogGTAf8BtAH/Af4B/wFwAdcB8wH/AWcB0wHzAf8BXgHQAfIB/wFV + AcwB8gH/AUwByQHyAf8BQgHFAfEB/wE6AcEB8AH/ATIBvQHvAf8BKgG6Ae4B/wFmAUwBOAH/CAABsgGC + AWkB/wHdAaUBhQH/AeABrgGRAf8B5gG6AaIB/wHrAccBtQH/AZIBZQFLAf8BtwGiAZMB/wG3AaIBkwH/ + AbIBggFpAf8B3QGlAYUB/wHgAa4BkQH/AeYBugGiAf8B6wHHAbUB/wGSAWUBSwH/DAABtwGiAZMB/wH8 + AfQB8gH/AeEB3AHYAf8B4AHXAdIB/wHfAdIBygH/Ad8BzgHDAf8B3QHIAbsB/wHcAcMBswH/AcUBrwGj + Af8BZgFMATgB/yAAAbcBogGTAf8B+QHpAeIB/wH4AeYB3QH/AfcB4gHYAf8B9QHeAdMB/wH0AdsBzgH/ + AfMB1wHKAf8B8gHUAcUB/wHhAYEBTwH/Ab4BawFBAf8BxQGvAaMB/wFmAUwBOAH/DAABtwGiAZMB/wG8 + Af8B/gH/AbYB/wH+Af8BsgH/Af4B/wGuAf8B/gH/AakB/wH+Af8BpgH/Af4B/wGiAf8B/gH/AZ8B/wH+ + Af8BnAH/Af4B/wE0Ab4B7wH/AWYBTAE4Af8IAAG7AYsBcQH/Ad0BpQGFAf8B4QGtAZEB/wHmAboBogH/ + AeoByAG1Af8BoAFzAVgB/wH1Ad4B0wH/AfQB2wHOAf8BuwGLAXEB/wHdAaUBhQH/AeEBrQGRAf8B5gG6 + AaIB/wHqAcgBtQH/AaABcwFYAf8MAAG3AaIBkwH/Af0B+AH1Af8B/AH0AfEB/wH7AfEB7QH/AfoB7gHn + Af8B+AHpAeIB/wH3AeUB3QH/AVYBfgGTAf8BTQFaAWkB/wFHAVQBYwH/AUIBTgFeAf8BPgFKAVgB/wE7 + AUYBVQH/ATkBQwFRAf8BNwFBAU4B/wwAAbcBogGTAf8B+QHuAegB/wG3AaIBkwH/AfgB5gHeAf8B9wHj + AdkB/wH1Ad8B1QH/AfUB2wHQAf8B8wHYAcsB/wH8AZIBYQH/AeEBgAFPAf8ByQG0AagB/wFmAUwBOAH/ + DAABtwGiAZMB/wHCA/8BvQH/Af4B/wG4Af8B/gH/AbQB/wH+Af8BsAH/Af4B/wGrAf8B/gH/AagB/wH+ + Af8BpAH/Af4B/wGhAf8B/gH/AT8BwwHxAf8BZgFMATgB/wgAASMCAQExAbwBjAFzAf8BvAGMAXMB/wG6 + AYkBcAH/AbIBggFpAf8B4gHIAcIB/wH3AeMB2QH/AfUB3wHVAf8B4AG/AbYB/wG8AYwBcwH/AbwBjAFz + Af8BugGJAXAB/wGyAYIBaQH/AcsBrQGiAf8MAAG+AakBmgH/Av4B/QH/AWYBTAE4Af8B/QH4AfUB/wFm + AUwBOAH/AfsB8QHtAf8BZgFMATgB/wFeAYUBnAH/AcQB+QHHAf8BmgHfAaYB/wFyAcYBgQH/AUMBrgFg + Af8BPQGBAUQB/wGBAXYBXQH/ATkBRAFSAf8BFgIBARwBTwECAQwBqgEqAQQBTAHsAaQBnQG4Af8B+wHy + Ae0B/wH6Ae4B6QH/AYgBgAGwAf8BDwENAXwB/wIEAXcB/wFNAUUBkQH/AfUB3AHRAf8B9AHYAcwB/wHz + AdUBxwH/AcwBuAGuAf8BZgFMATgB/wwAAbcBogGTAf8ByQH/Af4B/wHFAf8B/gH/AcIB9AHvAf8B0AG2 + AZgB/wF/AX4BUQH/Aa4BeAFYAf8BvAGYAYQB/wGuAeMB3QH/AaYB/wH+Af8BSQHIAfEB/wFmAUwBOAH/ + EAABtwGiAZMB/wFmAUwBOAH/AfoB7gHpAf8B+QHqAeQB/wH4AecB4AH/AfcB5AHaAf8B9gHhAdUB/wH1 + AdwB0QH/AfQB2AHMAf8BZgFMATgB/wHNAbcBqgH/AbgBnwGQAf8MAAHDAa4BngX/Af4C/QH/Af4B+wH5 + Af8B/QH4AfUB/wH8AfQB8QH/AfsB8QHtAf8BZQGOAaQB/wFDAa4BYAH/AbwB7AHGAf8BiwHXAZ4B/wE9 + AYEBRAH/AagBmgGPAf8BeAFjAVgB/wE8AUcBVQH/BAABIQIBAS0CAwF3Af8BzwHGAckB/wH5AfMB8gH/ + AeAB1wHQAf8B0gHHAdYB/wEbARgBgQH/ARIBEAF9Af8B9wHlAdsB/wH2AeEB1wH/AVABVgHXAf8BOwFB + AdEB/wHQAb0BtAH/AWYBTAE4Af8MAAG3AaIBkwH/AdAD/wHMA/8B8wHCAasB/wHVAYEBTwH/AT4BhQEi + Af8BYAF1ATMB/wGqAWYBQwH/AaUBlwGFAf8BqwH/Af4B/wFVAcwB8gH/AWYBTAE4Af8QAAG3AaIBkwH/ + AWYBTAE4Af8BZgFMATgB/wFmAUwBOAH/AWYBTAE4Af8BZgFMATgB/wFmAUwBOAH/AWYBTAE4Af8BZgFM + ATgB/wFmAUwBOAH/Ac0BtwGqAf8BgQFpAVYB/wwAAcgBsgGjBf8BZgFMATgC/wH9AfwB/wFmAUwBOAH/ + Af0B9wH2Af8BZgFMATgB/wFtAZcBrQH/AfUB4wHeAf8BQwGuAWAB/wE9AYEBRAH/AbgBngGIAf8BrQGL + AXYB/wHYAawBjQH/AUABSwFaAf8EAAEIAgEBCQFPAQIBCgGkASgBIgF+Af8BZgFhAaUB/wFlAV8BpAH/ + AUIBPAGRAf8CAwF3Af8BgwF9Aa8B/wH1AeYB4AH/AfcB5QHdAf8BbwF2AeAB/wFYAV4B2QH/AdUBwwG7 + Af8BZgFMATgB/wwAAboBpQGWAf8B2AP/AdMB/wH+Af8B9AGbAXYB/wF4AX0BQQH/AV4BlwEnAf8BsAGB + AUAB/wFWAXMBOQH/AU8BigE6Af8BsgH/Af4B/wFhAdAB8gH/AWYBTAE4Af8QAAG6AaUBlgH/Af0B+QH2 + Af8B/AH2AfMB/wH8AfMB7wH/AfoB8AHrAf8BZgFMATgB/wH4AekB4QH/AfcB5QHdAf8B9gHiAdgB/wH1 + Ad8B0wH/Ac0BtwGqAf8BZgFMATgB/wwAAcwBtgGnDf8B/gH9AfwB/wH+AfoB+QH/Af0B+AH2Af8BcwGf + AbMB/wH5Ae8B7AH/AfUB4wHeAf8B8AHUAcwB/wHTAcgB2QH/AXcBhgHFAf8B6QHEAbkB/wFFAVEBYAH/ + CAABOwEBAQIBYQIDAXcB/wHNAcsB4QH/AZwBlgG1Af8CAwF3Af8BFQETAYAB/wHaAdEB3QH/AfoB7gHo + Af8B+AHqAeQB/wH3AecB3wH/AfYB4gHaAf8B2AHJAcEB/wFmAUwBOAH/DAABvgGpAZoB/wHfA/8B2gP/ + AacBlQFiAf8BFAGjATQB/wKOAUsB/wHnAYEBUgH/AWQBlwEpAf8BSwGiATMB/wG5A/8BbAHVAfMB/wFm + AUwBOAH/EAABvgGpAZoB/wH+AfwB+wH/AdwCyQH/AZMBZQFMAf8BjgFgAUcB/wGIAVsBQgH/AYQBVwE+ + Af8BgQFUAToB/wHYAbwBtgH/AfYB4gHaAf8BzQG3AaoB/wFmAUwBOAH/DAAB2QHJAcAB/wHTAcIBuQH/ + Ac0BuwGxAf8ByQG0AakB/wHFAa8BogH/AcEBqQGcAf8BvAGjAZUB/wF5AacBuwH/AfwB9gH1Af8B+QHv + AewB/wH3AekB4QH/AXIBlQHjAf8BRAGVAekB/wF6AYkBxwH/AUoBWAFmAf8IAAETAgEBGAIDAXcB/wHf + Ad0B7QH/AacBogHMAf8CAwF3Af8BcQFrAaoB/wH7AfMB8QH/AfsB8gHtAf8B+gHuAekB/wE8AZ8BWAH/ + ASYBkQFFAf8B3AHOAcgB/wFmAUwBOAH/DAABwwGuAZ4B/wHmA/8B4gP/AaYB0AGfAf8BWAHcAX8B/wGj + AdwBnQH/AbEBnwFmAf8BpAGMATQB/wGbAccBgwH/AcAD/wF3AdoB9AH/AWYBTAE4Af8QAAHDAa4BngH/ + A/4B/wGlAXgBXQH/Af0B+AH2Af8B/AH0AfAB/wH6Ae8B6QH/AfkB6QHjAf8B9wHkAdoB/wGGAVoBQAH/ + AfgB6AHfAf8BzQG3AaoB/wFmAUwBOAH/FAABwwGuAZ4B/wHYAekB7AH/AdgB6QHsAf8B2AHpAewB/wHY + AekB7AH/AX4BrQG/Bf8B/AH2AfUB/wH8AfYB9QH/AckB1AH0Af8BfAGfAekB/wHcAdQB3gH/AVIBYAFu + Af8MAAFeAVMBiwH/AZ8BmwHJAf8BHAEYAXwB/wERARABfgH/AcIBvgHZAf8B/QH5AfYB/wH8AfUB8gH/ + AfsB8gHuAf8BUAGrAWgB/wE2AZsBUwH/AeEB1AHOAf8BZgFMATgB/wwAAcgBsgGjAf8B7QP/AegD/wHe + AfkB7gH/Ac0B6QHAAf8BrQHjAaYB/wFVAcQBcwH/AdABuwGYAf8BxQH3Ae0B/wHHAf8B/gH/AYEB3gH1 + Af8BZgFMATgB/xAAAcgBsgGjBf8BsgGCAWkB/wHdAaUBhQH/AeABrgGRAf8B5gG6AaIB/wHrAccBtQH/ + Ae8B1QHGAf8BkgFlAUsB/wH5AewB5gH/Ac0BtwGqAf8BZgFMATgB/xQAAcgBsgGjAf8B2AHpAewB/wHY + AekB7AH/AdgB6QHsAf8B2AHpAewB/wGBAbIBxAH/AX4BrQHAAf8BeQGnAbsB/wF0AZ8BtAH/AWwBlwGt + Af8BZQGOAaUB/wFeAYQBnAH/AVYBfgGTAf8MAAHPAcUBzgH/AgMBdwH/AgMBdwH/AU8BTAGcAf8B/gL8 + Af8B/gH7AfoB/wH9AfkB9wH/AfwB9gHzAf8B+wH0Ae8B/wHoAd8B2gH/AeQB2QHUAf8BZwFNATkB/wwA + AcwBtgGnAf8B8wP/Ae8B/wH+Af8B6wH/Af4B/wHmA/8B4gH/Af4B/wHdA/8B2QP/AdQD/wGRAeUB9QH/ + AYkB4gH1Af8BZwFNATkB/xAAAcwBtgGnBf8BuwGLAXEB/wHdAaUBhQH/AeEBrQGRAf8B5gG6AaIB/wHq + AcgBtQH/Ae8B1AHGAf8BoAFzAVgB/wHdAdQBzAH/Ac0BtwGqAf8BZwFNATkB/xQAAcwBtgGnAf8B2AHp + AewB/wHYAekB7AH/AdgB6QHsAf8B2AHpAewB/wHYAekB7AH/AdgB6QHsAf8B2AHpAewB/wHYAekB7AH/ + AWYBTAE4Af8YAAHRAbsBqwH/AS8BLQGMAf8BCwEJAXoB/wHDAcAB3wb/Af4B/QH/Af4C+wH/Af0B+QH4 + Af8BtwGiAZMB/wFnAU0BOQH/AWcBTQE5Af8BZwFNATkB/wwAAdEBuwGrAf8B9wP/AfQD/wHwA/8B7QP/ + AegD/wHkA/8B3wP/AbcBogGTAf8BZwFNATkB/wFnAU0BOQH/AWcBTQE5Af8QAAHRAbsBqwX/AegC3AH/ + AbwBjAFzAf8BvAGMAXMB/wG6AYkBcAH/AbYBhgFtAf8BsgGCAWkB/wHdAc8BzAH/AbUBqgGgAf8BZwFN + ATkB/wFnAU0BOQH/FAAB/wHCAaIC/wG8AZgC/wGzAYoC/wGoAXwC/wGeAW0B/wH9AZIBYAH/Ae4BhwFV + Af8B2gF8AUwB/wHGAW8BQwH/AbIBYwE8Af8YAAHVAb8BrwH/AcQBwQHeAf8BcAFtAbAB/wHgAdcB0AX/ + AbcBogGTAv8C/gH/AbcBogGTAf8BuQGkAZUB/wHUAcUBugH/AWYBTAE4Af8BWwENAQwBqQwAAdUBvwGv + Af8B/AP/AfkD/wH2A/8B8gP/Ae4B/wH+Af8B6gP/AeYB/wH+Af8BuQGkAZUB/wHUAcUBugH/AWYBTAE4 + Af8BWwENAQwBqRAAAdUBvwGvFv8C/gH/Af4B/AH7Af8BzAG9AbMB/wGuAZoBjAH/AWYBTAE4Af8BWwEN + AQwBqRQAAf8BvgGbAv8BwgGiAf8B/gHAAZ8B/wH9Ab0BmgH/AfwBuQGWAf8B+wG1AZAB/wH6AbABiwH/ + AfkBqwGEAf8B8wGVAWgB/wHNAWgBNAH/GAAB2AHCAbIb/wH+Af8BwAGrAZwB/wFmAUwBOAH/AVsBDQEM + AagQAAHYAcIBsgX/AfwD/wH6A/8B9wP/AfQD/wHxA/8B7AP/AcABqwGcAf8BZgFMATgB/wFbAQ0BDAGo + FAAB2AHCAbIb/wH+Af8BwAGrAZwB/wFmAUwBOAH/AVsBDQEMAagYAAH/Ab4BmwL/AbcBkQL/AbABhQL/ + AagBewL/AZ8BbwL/AZcBZQH/AfcBjgFcAf8B6wGEAVQB/wHcAX0BTQH/AcsBcwFGAf8YAAHYAcIBsgH/ + AdgBwgGyAf8B2AHCAbIB/wHYAcIBsgH/AdgBwgGyAf8B2AHCAbIB/wHUAb4BrgH/Ac8BuQGpAf8ByQGz + AaQB/wFPAgYBixQAAdgBwgGyAf8B2AHCAbIB/wHYAcIBsgH/AdgBwgGyAf8B2AHCAbIB/wHYAcIBsgH/ + AdQBvgGuAf8BzwG5AakB/wHJAbMBpAH/AU8CBgGLGAAB2AHCAbIB/wHYAcIBsgH/AdgBwgGyAf8B2AHC + AbIB/wHYAcIBsgH/AdgBwgGyAf8B1AG+Aa4B/wHPAbkBqQH/AckBswGkAf8BTwIGAYv/AKEAAbcBogGT + Af8BagFQATwB/wFqAVABPAH/AWoBUAE8Af8BagFQATwB/wFqAVABPAH/AWoBUAE8Af8BagFQATwB/wFq + AVABPAH/AWoBUAE8Af8BagFQATwB/wFqAVABPAH/EAABtwGiAZMB/wFrAVEBPQH/AWsBUQE9Af8BawFR + AT0B/wFrAVEBPQH/AWsBUQE9Af8BawFRAT0B/wFrAVEBPQH/AWsBUQE9Af8BawFRAT0B/wFrAVEBPQH/ + AWsBUQE9Af8IAAG3AaIBkwH/AWsBUQE9Af8BawFRAT0B/wFrAVEBPQH/AWsBUQE9Af8BawFRAT0B/wFr + AVEBPQH/AWsBUQE9Af8BawFRAT0B/wFrAVEBPQH/AWsBUQE9Af8BawFRAT0B/xAAAbcBogGTAf8BawFR + AT0B/wFrAVEBPQH/AWsBUQE9Af8BawFRAT0B/wFrAVEBPQH/AWsBUQE9Af8BawFRAT0B/wFrAVEBPQH/ + AWsBUQE9Af8BawFRAT0B/wFrAVEBPQH/GAABtwGiAZMF/wG3AaIBkwH/AbcBogGTAf8BtwGiAZMB/wG3 + AaIBkwH/AbcBogGTAf8BtwGiAZMB/wG3AaIBkwH/AbcBogGTAf8BtwGiAZMB/wFqAVABPAH/EAABtwGi + AZMB/wH3AeUB3AH/AdgBxwG/Af8B1QHEAbwB/wHSAcABtwH/Ac8BvQGzAf8BzQG5Aa8B/wHLAbYBqwH/ + AcgBswGoAf8BxgGvAaMB/wHDAawBoAH/AWsBUQE9Af8IAAG3AaIBkwH/AfcB5QHcAf8BtwGiAZMB/wG3 + AaIBkwH/AbcBogGTAf8BtwGiAZMB/wG3AaIBkwH/AbcBogGTAf8BtwGiAZMB/wG3AaIBkwH/AbcBogGT + Af8BawFRAT0B/xAAAbcBogGTAf8B8wHWAckB/wHxAdEBwgH/AfABzQG8Af8B7wHJAbcB/wHuAcYBswH/ + Ae0BwwGvAf8B7QHDAa8B/wHtAcMBrwH/Ae0BwwGvAf8B7QHDAa8B/wFrAVEBPQH/GAABtwGiAZMJ/wH8 + AfoB+QH/AfwB+gH5Af8B9wHxAe4B/wHxAecB4QH/AewB3QHVAf8B5gHTAckB/wHhAcoBvQH/AbcBogGT + Af8BagFQATwB/wQAAQIDAQEEAgEBBAEHAgEBCAG5AaUBlgH/AfkB6gHjAf8B+AHmAd0B/wH3AeIB2AH/ + AfUB3gHTAf8B9AHbAc4B/wHzAdcBygH/AfIB1AHFAf8B8QHQAcEB/wHwAc0BvAH/AccBsQGlAf8BawFR + AT0B/wgAAbcBogGTAf8B+QHpAeIB/wH4AecB3gH/AfgB5AHbAf8B9gHiAdkB/wH2AeEB1gH/AfUB3QHS + Af8B8wHYAcoB/wHyAdIBwwH/AfABzQG9Af8BtwGiAZMB/wFrAVEBPQH/EAABtwGiAZMB/wH5AekB4gH/ + AfgB5wHeAf8B9wHkAdoB/wH2AeEB1wH/AfUB3gHSAf8B9AHbAc8B/wHzAdgBygH/AfIB0wHFAf8B8QHP + Ab4B/wHtAcMBrwH/AWsBUQE9Af8IAAErAgEBPwFIAX8BjwH/ATwBaQF9Af8BMAFcAXEB/wEwAVwBcQH/ + ATABXAFxAf8BLQFZAW4B/wE8AWMBewH/ATEBXQFzAf8B+gH3AfUB/wH1Ae0B6QH/Ae8B4wHcAf8B6gHZ + AdEB/wHkAc8BxAH/AbcBogGTAf8BagFQATwB/wEFAgEBBQEQAgEBEwEfAgECKgIBAT4BzwHBAbgB/wH6 + AfIB7QH/AfkB7QHmAf8B+AHnAeAB/wH3AeMB2QH/AfUB3wHVAf8B9QHbAdAB/wHzAdgBywH/AfIB1QHG + Af8B8QHRAcIB/wHKAbUBqgH/AWsBUQE9Af8IAAG3AaIBkwH/AfkB7gHpAf8B+QHsAeYB/wH6AewB5gH/ + AfoB7QHmAf8B+QHsAecB/wH5AekB4gH/AfYB4wHaAf8B9AHbAc4B/wHyAdMBxQH/AbcBogGTAf8BawFR + AT0B/xAAAbcBogGTAf8B+QHuAegB/wH4AesB5QH/AfkB6gHjAf8B+QHqAeMB/wH4AegB4QH/AfgB5QHd + Af8B9gHjAdkB/wH1Ad0B0QH/AfMB1gHJAf8B7QHEAbEB/wFrAVEBPQH/CAABQQF7AYwB/wGpAdYB3wH/ + AbgB6AHzAf8BrwHlAfIB/wGvAeUB8gH/Aa8B5QHyAf8BpQHcAesB/wFIAYEBkQH/AUkBpAHRAf8BPwF/ + AZEB/wH4AfMB8AH/AfIB6QHjAf8B7QHfAdgB/wHnAdUBywH/AbcBogGTAf8BagFQATwB/wESAgEBFwEp + AgEBPAFAAgEBbAFUAgIBpQHmAcwBtQH/AfgB7gHmAf8B/AH0AfEB/wH6Ae4B6QH/AfgB6AHiAf8B9wHk + AdoB/wH2AeEB1QH/AfUB3AHSAf8B9AHZAc0B/wHzAdUByAH/Ac0BuwGwAf8BawFRAT0B/wgAAbcBogGT + Af8B+wHzAe8B/wH7AfIB7wH/AeMBzwHBAf8BoAF0AUsB/wGBAUIBCgH/AY8BWwEqAf8ByAGlAYsB/wH3 + AeIB2QH/AfQB2QHMAf8BtwGiAZMB/wFrAVEBPQH/EAABtwGiAZMB/wH7AfIB7QH/AfsB8AHsAf8B+wHx + Ae0B/wGuAVcBCAH/AeYBxwGvAf8B+wHxAewB/wGuAVcBCAH/AeQBvwGlAf8B9gHeAdMB/wHuAcUBsgH/ + AWsBUQE9Af8IAAFnAZQBqgH/AVUBhAGaAf8BTQGBAZMB/wFeAYkBoAH/AV4BiQGgAf8BXgGJAaAB/wFa + AYMBmgH/AWIBhAGcAf8BTQGrAdkB/wFDAYEBnQH/AfsB+AH3Af8B9gHvAesB/wHwAeUB3wH/AesB2wHT + Af8BtwGiAZMB/wFqAVABPAH/ASYCAQE3AUkCAgKEASoBFQHuAa4BVwEIAf8BrgFXAQgB/wGuAVcBCAH/ + Ad0BtgGVAf8B/AH0AfEB/wH6Ae8B6wH/AfkB6gHjAf8B+AHnAd4B/wH3AeMB2gH/AfUB4gHYAf8B9AHd + AdEB/wHSAcEBtwH/AWsBUQE9Af8IAAG4AaMBlQH/Af0B+AH1Af8B/QH3AfUB/wGPAVwBKwH/AcIBoAGF + Af8B/QH4AfUB/wHKAaoBkQH/AYEBQgEKAf8B7wHbAdAB/wH0Ad4B0gH/AbcBogGTAf8BawFRAT0B/xAA + AbcBogGTAf8B/AH2AfMB/wH8AfQB8QH/Af0B9gHzAf8BrgFXAQgB/wHpAcwBtgH/Af0B+QH2Af8BrgFX + AQgB/wHmAcUBrAH/AfcB5QHcAf8B7gHGAbMB/wFrAVEBPQH/EAABVgICAa0BhwHUAewB/wFlAcEB6gH/ + AWUBwQHqAf8BWgG5AecB/wFUAbQB4wH/AUYBhAGiAf8BZwGLAZ0B/wH+Af0B/AH/AfkB9QHyAf8B9AHr + AeYB/wHuAeEB2gH/AbcBogGTAf8BagFQATwB/wE4AgEBWQFnAQsBCAHUAa4BVwEIAf8BhAE3ATAB6gH2 + Ae8B6QH/Ab4BegE7Af8BuQFuASkB/wH+AfoB+AH/AecBygGzAf8B/AHzAe8B/wH6Ae8B6gH/AfoB7QHo + Af8B5QHDAakB/wH4AegB4AH/AdsBzAHGAf8BcQFXAUQB/wgAAbwBpwGZAf8B/gH7AfgB/wHkAdQByAH/ + AYEBQgEKAf8B9QHtAegB/wH9AfcB9AH/AfsB8QHsAf8B8gHiAdoB/wH4AegB4AH/AfYB4gHXAf8BtwGi + AZMB/wFrAVEBPQH/EAABugGlAZYB/wH9AfkB9gH/Af0B+AH2Af8B/gH5AfcB/wGuAVcBCAH/AekBzwG6 + Af8B/gL9Af8BrgFXAQgB/wHmAcgBsAH/AfgB6QHhAf8B7wHIAbYB/wFrAVEBPQH/DAABJAIBATIBRwF+ + AY4B/wGFAdkB8wH/AXgBzQHvAf8BbAHEAesB/wFhAb4B6QH/AUIBgQGWAf8BewGhAbQJ/wH8AfoB+QH/ + AfcB8QHuAf8B8QHnAeEB/wG3AaIBkwH/AWoBUAE8Af8BQQIBAXEBjgEyARkB8QGjAVcBIQH7AV0CBQHC + AfEB7AHpAf8B9AHnAdsB/wH+Av0B/wH+Af0B/AH/Aa4BVwEIAf8B/QH5AfcB/wH9AfcB9AH/AfwB9gH0 + Af8BrgFXAQgB/wH7AfIB7gH/AeMB2AHSAf8BdQFdAUoB/wgAAcABrAGdAf8B/gH9AfwB/wHcAcgBuQH/ + AYEBQgEKAf8B/gH7AfoB/wH9AfcB9QH/AfwB8wHvAf8B+gHwAewB/wH4AesB5QH/AfcB5AHdAf8BtwGi + AZMB/wFrAVEBPQH/EAABvgGpAZoB/wH+AfwB+wH/Af0C+gH/Af4B+wH6Af8BrgFXAQgB/wHZAa0BiAH/ + AfoB8gHtAf8BrgFXAQgB/wHmAcgBsAH/AfgB6QHjAf8B8AHLAboB/wFrAVEBPQH/DAABYwGQAaIB/wF8 + AaABrQH/AZYB5AH3Af8BiQHcAfUB/wGBAdQB8QH/AXIBxQHoAf8BQgGBAZYB/wHwAfUB9wn/A/4B/wH6 + AfcB9QH/AfUB7QHpAf8BtwGiAZMB/wFqAVABPAH/AUMCAQFzAY4BNgEbAfIBqgFdATgB+gFaAgQBuQHw + AesB5wH/A/4B/wH0AeUB2gH/Aa4BVwEIAf8BrgFXAQgB/wGuAVcBCAH/AfQB5QHaAf8BrgFXAQgB/wGu + AVcBCAH/Aa4BVwEIAf8B3QHEAbEB/wF7AWQBUgH/CAABxAGwAaAB/wP+Af8B9QHxAewB/wGBAUIBCgH/ + AeQB1gHKAf8B/gH6AfkB/wH1AesB5QH/AcEBnQGBAf8B8gHjAdsB/wH5AeoB4gH/AbcBogGTAf8BawFR + AT0B/xAAAcMBrgGeAf8D/gH/Af4C/QH/Af4B/AH7Af8BrgFXAQgB/wHOAZUBbgH/Aa4BVwEIAf8BwwGB + AUoB/wH7AfMB7wH/AfkB7AHkAf8B8AHOAb0B/wFrAVEBPQH/DAABcQGOAZ0B/gGvAfMB/QH/AakB8AH9 + Af8BoQHrAfoB/wGWAeQB+AH/ATsBfQGUAf8BWgGkAcUB/wE/AXYBhAH/AT8BcgGBDf8B+gH3AfUB/wG3 + AaIBkwH/AWoBUAE8Af8BOwIBAWABbAEQAQsB3QGuAVcBCAH/AWsCFAHZAfoB+AH3Af8B2QGtAYgB/wHj + AcIBpgL/Av4B/wGuAVcBCAH/Af4B/AH7Af8B/gH6AfkB/wH9AfkB+AH/Aa4BVwEIAf8B/AH2AfMB/wHo + Ad8B2gH/AXUBXQFKAf8IAAHIAbMBpAn/AboBlQGAAf8BjwFcASsB/wHCAaIBhwH/AaABdQFMAf8BlwFo + ATsB/wH7Ae8B6gH/AfkB7AHmAf8BtwGiAZMB/wFrAVEBPQH/EAAByAGyAaMK/wH+Af0B/wGuAVcBCAH/ + AekBzwG5Af8B/gH7AfkB/wH8AfcB9AH/AfwB8gHuAf8B+QHtAegB/wHxAdEBwgH/AWsBUQE9Af8MAAE0 + AV8BcwH8Aa0B8QH7Af8BsAH0Af4B/wGvAfMB/gH/AaYB7gH7Af8BLgFoAYEB/wFaAaQBxQH/AWYBsgHT + Af8BIwFQAWQJ/wH9AfwB+wH/AbcBogGTAf8BtwGiAZMB/wFrAVEBPQH/ASsCAQE/AU8CAgGZAZ8BTQEW + AfwBswFKARcB/QG9AXgBOQH/Aa4BVwEIAf8B3AGzAZEF/wHtAdgBxgH/Af4C/AH/Af4B+wH5Af8B/QH5 + AfcB/wHuAdoBygH/Ae0B5gHiAf8B5wHdAdkB/wFxAVgBRQH/CAABzAG2AacN/wHdAcoBuwH/AcMBogGI + Af8BwgGhAYcB/wH1AewB5wH/AfsB9AHvAf8BtwGiAZMB/wG3AaIBkwH/AWwBUgE+Af8QAAHMAbYBpw3/ + AdkBrAGHAf8B8wHmAdoB/wH+AfsB+QH/AfwB9wH1Af8B+wH1AfAB/wH0Ad0B0QH/AfMB1wHJAf8BbAFS + AT4B/wwAARkCAQEgAYEBrQHAAf8BfQGnAboB/wF4AZ8BtAH/AXABlwGtAf8BaQGOAaQB/wE3AWkBfQH/ + ATkBagF+Df8BtwGiAZMB/wFrAVEBPQH/AWsBUQE9Af8BawFRAT0B/wEXAgEBHQEwAgECSgICAYgBZAIH + AdAB1AGmAYEB/wHfAbkBmQ7/Af4B/QH/Af4C+wH/Af0B+QH4Af8BvgGrAZ4B/wF2AV4BSwH/AXEBWAFE + Af8BbAFSAT4B/wgAAdEBuwGrEv8C/gH/Af4C/AH/Af0B+gH5Af8BtwGiAZMB/wFsAVIBPgH/AWwBUgE+ + Af8BbAFSAT4B/xAAAdEBuwGrEv8B/gH9Af8B/gL7Af8B/QH5AfgB/wG3AaIBkwH/AWwBUgE+Af8BbAFS + AT4B/wFsAVIBPgH/GAAB1QG/Aa8d/wG5AaQBlQH/AdQBxQG6Af8BawFRAT0B/wFMAgIBjAEHAgEBCAEW + AgEBHAEnAgEBOAE0AgEBUgHvAecB4Bb/Av4B/wH+AfwB+wH/AboBpQGWAf8B1AHFAbsB/wFsAVIBPgH/ + AVYCAgGpCAAB1QG/Aa8W/wL+Af8B/gH8AfsB/wG5AaQBlQH/AdQBxQG6Af8BawFRAT0B/wFWAgIBqRAA + AdUBvwGvFv8C/gH/Af4B/AH7Af8BuQGkAZUB/wHUAcUBugH/AWsBUQE9Af8BVgICAakYAAHYAcIBsh3/ + AcABqwGcAf8BawFRAT0B/wFLAgIBiwgAAQQCAQEEAQkCAQEKAQ8CAQESAdsBxwG4G/8B/gH/AcABqwGc + Af8BawFRAT0B/wFWAgIBqAwAAdgBwgGyG/8B/gH/AcABqwGcAf8BawFRAT0B/wFWAgIBqBQAAdgBwgGy + G/8B/gH/AcABqwGcAf8BawFRAT0B/wFWAgIBqBwAAdgBwgGyAf8B2AHCAbIB/wHYAcIBsgH/AdgBwgGy + Af8B2AHCAbIB/wHYAcIBsgH/AdQBvgGuAf8BzwG5AakB/wHJAbMBpAH/AUsCAgGLGAAB2AHCAbIB/wHY + AcIBsgH/AdgBwgGyAf8B2AHCAbIB/wHYAcIBsgH/AdgBwgGyAf8B1AG+Aa4B/wHPAbkBqQH/AckBswGk + Af8BSwICAYsQAAHYAcIBsgH/AdgBwgGyAf8B2AHCAbIB/wHYAcIBsgH/AdgBwgGyAf8B2AHCAbIB/wHU + Ab4BrgH/Ac8BuQGpAf8ByQGzAaQB/wFLAgIBixgAAdgBwgGyAf8B2AHCAbIB/wHYAcIBsgH/AdgBwgGy + Af8B2AHCAbIB/wHYAcIBsgH/AdQBvgGuAf8BzwG5AakB/wHJAbMBpAH/AUsCAgGLWAABtwGiAZMB/wFr + AVEBPQH/AWsBUQE9Af8BawFRAT0B/wFrAVEBPQH/AWsBUQE9Af8BawFRAT0B/wFrAVEBPQH/AWsBUQE9 + Af8BawFRAT0B/wFrAVEBPQH/AWsBUQE9Af8UAAG3AaIBkwH/AWsBUQE9Af8BawFRAT0B/wFrAVEBPQH/ + AWsBUQE9Af8BawFRAT0B/wFrAVEBPQH/AWsBUQE9Af8BawFRAT0B/wFrAVEBPQH/AWsBUQE9Af8BawFR + AT0B/xAAAbcBogGTAf8BawFRAT0B/wFrAVEBPQH/AWsBUQE9Af8BawFRAT0B/wFrAVEBPQH/AWsBUQE9 + Af8BawFRAT0B/wFrAVEBPQH/AWsBUQE9Af8BawFRAT0B/wFrAVEBPQH/FAABtwGiAZMB/wFrAVEBPQH/ + AWsBUQE9Af8BawFRAT0B/wFrAVEBPQH/AWsBUQE9Af8BawFRAT0B/wFrAVEBPQH/AWsBUQE9Af8BawFR + AT0B/wFrAVEBPQH/AWsBUQE9Af8IAAG3AaIBkwH/AfcB5QHcAf8BtwGiAZMB/wG3AaIBkwH/AbcBogGT + Af8BtwGiAZMB/wG3AaIBkwH/AbcBogGTAf8BtwGiAZMB/wG3AaIBkwH/AbcBogGTAf8BawFRAT0B/xQA + AbcBogGTAf8B9wHlAdwB/wG3AaIBkwH/AbcBogGTAf8BtwGiAZMB/wG3AaIBkwH/AbcBogGTAf8BtwGi + AZMB/wG3AaIBkwH/AbcBogGTAf8BtwGiAZMB/wFrAVEBPQH/EAABtwGiAZMB/wH3AeUB3AH/AbcBogGT + Af8BtwGiAZMB/wG3AaIBkwH/AbcBogGTAf8BtwGiAZMB/wG3AaIBkwH/AbcBogGTAf8BtwGiAZMB/wG3 + AaIBkwH/AWsBUQE9Af8UAAG3AaIBkwH/AfcB5QHcAf8BtwGiAZMB/wG3AaIBkwH/AbcBogGTAf8BtwGi + AZMB/wG3AaIBkwH/AbcBogGTAf8BtwGiAZMB/wG3AaIBkwH/AbcBogGTAf8BawFRAT0B/wgAAbcBogGT + Af8B+QHpAeIB/wH4AeYB3QH/AfcB4gHYAf8B9QHeAdMB/wH0AdsBzgH/AfMB1wHKAf8B8gHUAcUB/wHx + AdABwQH/AfABzQG8Af8BtwGiAZMB/wFrAVEBPQH/FAABtwGiAZMB/wH5AekB4gH/AfgB5gHdAf8B9wHi + AdgB/wH1Ad4B0wH/AfQB2wHOAf8B8wHXAcoB/wHyAdQBxQH/AfEB0AHBAf8B8AHNAbwB/wG3AaIBkwH/ + AWsBUQE9Af8QAAG3AaIBkwH/AfkB6QHiAf8B+AHmAd0B/wH3AeIB2AH/AfUB3gHTAf8B9AHbAc4B/wHz + AdcBygH/AfIB1AHFAf8B8QHQAcEB/wHwAc0BvAH/AbcBogGTAf8BawFRAT0B/xQAAbcBogGTAf8B+QHp + AeIB/wH4AeYB3QH/AfcB4gHYAf8B9QHeAdMB/wH0AdsBzgH/AfMB1wHKAf8B8gHUAcUB/wHxAdABwQH/ + AfABzQG8Af8BtwGiAZMB/wFrAVEBPQH/CAABtwGiAZMB/wH5Ae4B6AH/AfgB6gHjAf8B+AHmAd4B/wH3 + AeMB2QH/AfUB3wHVAf8B9QHbAdAB/wHzAdgBywH/AfIB1QHGAf8B8QHRAcIB/wG3AaIBkwH/AWsBUQE9 + Af8UAAG3AaIBkwH/AfkB7gHoAf8BvgGqAZwB/wG1AaEBkwH/AawBlwGIAf8BogGNAYEB/wGaAYMBegH/ + AZEBgQFxAf8BigF7AWkB/wHxAdEBwgH/AbcBogGTAf8BawFRAT0B/xAAAbcBogGTAf8B+QHuAegB/wH4 + AeoB4wH/AfgB5gHeAf8B9wHjAdkB/wH1Ad8B1QH/AfUB2wHQAf8B8wHYAcsB/wHyAdUBxgH/AfEB0QHC + Af8BtwGiAZMB/wFrAVEBPQH/FAABtwGiAZMB/wH5Ae4B6AH/AcsBuAGrAf8BxAGwAaMB/wG5AaQBlgH/ + AawBlwGHAf8BngGIAX8B/wGQAYABbwH/AYIBcQFfAf8B8QHRAcIB/wG3AaIBkwH/AWsBUQE9Af8IAAG3 + AaIBkwH/AfsB8gHtAf8B2AFyAToB/wHQAW0BOQH/AcQBaAE1Af8BtwFhATMB/wGnAVkBMAH/AZoBUwEt + Af8BjgFNASoB/wHzAdUBxwH/AbcBogGTAf8BawFRAT0B/xQAAbcBogGTAf8B+wHyAe0B/wH6Ae4B6QH/ + AfkB6gHkAf8B+AHnAeAB/wH3AeQB2gH/AfYB4QHVAf8B9QHcAdEB/wH0AdgBzAH/AfMB1QHHAf8BtwGi + AZMB/wFrAVEBPQH/EAABtwGiAZMB/wH7AfIB7QH/AdQBxAG6Af8BzwG8AbEB/wHJAbQBqQH/AcQBrgGi + Af8BwAGpAZwB/wG7AaIBlQH/AbUBnAGNAf8B8wHVAccB/wG3AaIBkwH/AWsBUQE9Af8UAAG3AaIBkwH/ + AfsB8gHtAf8B+gHuAekB/wH5AeoB5AH/AfgB5wHgAf8B9wHkAdoB/wH2AeEB1QH/AfUB3AHRAf8B9AHY + AcwB/wHzAdUBxwH/AbcBogGTAf8BawFRAT0B/wgAAbcBogGTAf8B/AH2AfMB/wH7AfIB7gH/AfsB7wHq + Af8B+QHrAeYB/wH5AegB4QH/AfcB5QHbAf8B9gHhAdcB/wH0Ad4B0wH/AfMB2gHNAf8BtwGiAZMB/wFr + AVEBPQH/CAABGgIBASMBRQIBAXkBWgIEAboB7AHmAeIB/wH+AfsB+gH/AeQB2wHVAf8B3QHUAc4B/wHC + AbIBpwH/AaUBkQGCAf8BmgGDAXoB/wGRAYEBcQH/AYoBewFpAf8B8wHaAc0B/wG3AaIBkwH/AWsBUQE9 + Af8QAAG3AaIBkwH/AfwB9gHzAf8B/AH2AfMB/wH+Af0B/AH/Af4C/QH/Af4B/QH8Af8B+wHzAe4B/wH3 + AeUB3AH/AfQB3gHTAf8B8wHaAc0B/wG3AaIBkwH/AWsBUQE9Af8IAAEXAgEBHgE4AgEBWwE4AgEBWwHF + AbQBqAH/Af0B+gH4Af8B8QHsAegB/wHeAdMBywH/AcIBrwGjAf8BywG+AbQB/wHZAdABygH/Aa8BngGR + Af8BggFxAV8B/wHzAdoBzQH/AbcBogGTAf8BawFRAT0B/wgAAboBpQGWAf8B/QH5AfYB/wHYAXIBOgH/ + AdABbgE4Af8BxAFoATUB/wG3AWEBMwH/AagBWgEwAf8BmgFTASwB/wGOAU0BKgH/AfUB3wHTAf8BtwGi + AZMB/wFrAVEBPQH/CAABRQIBAXkBqQGGAX4B9gEIAZkBCAH/AQgBmQEIAf8B4gHuAeIB/wH7Af0B+wH/ + AQ0BlwENAf8B0AHiAc8B/wH9AfcB9AH/AfoB7gHoAf8B9wHlAd4B/wH2AeIB2AH/AfUB3wHTAf8BtwGi + AZMB/wFrAVEBPQH/EAABugGlAZYB/wH9AfkB9gH/AfwB+wH6Af8BywFuAQgB/wHLAW4BCAH/AcsBbgEI + Af8B6AG9AZ0B/wHpAeAB3AH/AbUBmwGNAf8B9QHfAdMB/wG3AaIBkwH/AWsBUQE9Af8IAAFKAgIBhQGV + AaoC/wGVAaoC/wH8AvsB/wG5AccC/wEIATsC/wG5AccD/wL+Af8B1AHdAv8BDQE/Bv8B+wH0AfAB/wH4 + AegB3wH/AbcBogGTAf8BawFRAT0B/wgAAb4BqQGaAf8B/gH8AfsB/wH9AfkB+AH/Af0B9wH0Af8B/AH0 + AfAB/wH7AfEB7QH/AfoB7gHoAf8B+AHqAeQB/wH3AecB3wH/AfYB4gHaAf8BtwGiAZMB/wFrAVEBPQH/ + CAABWgIEAboBIgGjASIB/wGpAYYBfgH2AfcB9QHzAf8BngHYAZ4B/wEQAZkBEAH/AQkBlQEJAf8BrwHO + Aa4B/wEKAZUBCgH/AecB7QHiAf8B+AHrAeYB/wH3AecB3wH/AfYB4gHaAf8BtwGiAZMB/wFrAVEBPQH/ + DAABWAIDAbMB9gHzAfED/wH+Av8C/gH/AcsBbgEIAv8C/gL/Af4B/QH/AcsBbgEIAf8B/QH6AfgB/wH3 + AecB3wH/AfYB4gHaAf8BtwGiAZMB/wFrAVEBPQH/BAABDAIBAQ4E/wEIATsC/wEIATsG/wEIATsC/wHO + AdgC/wEIATsC/wHOAdgC/wEIATsC/wEJATwC/wHZAeEC/wEKAT0C/wH+Av0B/wG6AaYBmAH/AWsBUQE9 + Af8IAAHDAa4BngH/A/4B/wHYAXIBOgH/AdABbgE4Af8BxAFoATYB/wG3AWEBMwH/AacBWgEvAf8BmQFT + AS0B/wGOAU0BKgH/AfgB6AHfAf8BtwGiAZMB/wFrAVEBPQH/CAABYgIHAcgBCAGZAQgB/wF8AigB4wH4 + AfUB8wn/AQsBlgELAf8BCgGVAQoB/wEJAZQBCQH/AeAB6wHeAf8B+wHyAe8B/wH5AesB5QH/AfgB6AHf + Af8BtwGiAZMB/wFrAVEBPQH/DAABegIlAeIB2QGQAWIB/wHZAZEBYgH/Af0C/AH/AcsBbgEIAf8BywFu + AQgB/wHLAW4BCAH/AfIB2QHGAf8B8QHsAekB/wG2AZwBjQH/AfgB6AHfAf8BtwGiAZMB/wFrAVEBPQH/ + BAABPAIBAWQBzgHYAv8BCAE7Av8BCAE7Av8BzgHYCv8BCAE7Av8BzgHYAv8B2AHgAv8BCwE9Av8BCgE9 + Av8BCQE8Av8B2QHhAv8B0QHEAboB/wFrAVEBPQH/CAAByAGyAaMK/wH9AfwB/wH9AfsB+QH/Af0B+QH2 + Af8B/AH1AfIB/wH7AfIB7gH/AfsB7wHqAf8B+QHsAeYB/wG3AaIBkwH/AWsBUQE9Af8IAAFaAgQBugEI + AZkBCAH/AakBhgF+AfYB+AH2AfQB/wGBAckBgQH/ARABmQEQAf8BCwGWAQsB/wHrAfMB6gH/AQkBlAEJ + Af8BCwGWAQsB/wH9AfgB9gH/AfsB7wHqAf8B+QHsAeYB/wG3AaIBkwH/AWsBUQE9Af8IAAEPAgEBEgG3 + Ao8B9gHLAW4BCAH/AcsBbgEIAv8C/gH/AcsBbgEIA/8B/gL/Av4B/wHLAW4BCAH/Af4B/AH7Af8B+wHv + AeoB/wH5AewB5gH/AbcBogGTAf8BawFRAT0B/wQAAYUCOQHoAQgBOwL/AaYBuAL/AaYBuAL/AQgBOwr/ + AQgBOwL/Ac4B2AL/AQgBOwL/AQsBPQb/AQkBPAL/AQsBPQL/AeUB3gHYAf8BawFRAT0B/wgAAcwBtgGn + Bf8B2AFyAToB/wHQAW4BOAH/AcQBaAE1Af8BtwFhATIB/wGoAVoBMAH/AfwB9gHzAf8B+wH0Ae8B/wG3 + AaIBkwH/AbcBogGTAf8BbAFSAT4B/wgAAUcCAQF+AakBhgF+AfYBIgGjASIB/wEIAZkBCAH/AeIB7gHi + Af8B4gHuAeIB/wEJAZQBCQH/AQ0BlwENAf8BCAGZAQgB/wHLAd8BygH/Af0B+gH5Af8B+wH0Ae8B/wG3 + AaIBkwH/AbcBogGTAf8BbAFSAT4B/wgAAWACBQHHAdABpQGXAfsBywFuAQgB/wHLAW4BCAH/AfEB2AHG + Af8BywFuAQgB/wHLAW4BCAH/AcsBbgEIAf8B6AG9AZ0B/wH+AfsB+QH/AfsB9AHvAf8BtwGiAZMB/wG3 + AaIBkwH/AWwBUgE+Af8EAAFvAhUB2gEIATsK/wEIATsK/wEIATsC/wHOAdgC/wHIAdMC/wEJATwC/wEN + AT8C/wEIATsC/wHdAeQC/wHlAd4B2AH/AWwBUgE+Af8IAAHRAbsBqxL/Af4B/QH/Af4C+wH/Af0B+QH4 + Af8BtwGiAZMB/wFsAVIBPgH/AWwBUgE+Af8BbAFSAT4B/wgAASECAQEuAU8CAgGZAWACBQHEAfQB7wHs + Cf8BEQGZAREB/wHfAewB3wH/AQgBlAEIAf8BEQGZAREB/wH+AvwB/wG3AaIBkwH/AWwBUgE+Af8BbAFS + AT4B/wFsAVIBPgH/CAABtQKFAfUBywFuAQgB/wHbAZcBbAH/AdsBlwFsAf8BywFuAQgO/wL+Af8B/QH6 + AfkB/wG3AaIBkwH/AWwBUgE+Af8BbAFSAT4B/wFsAVIBPgH/BAABMAIBAUkBTQICAZEBMAIBAUkBMAIB + AUkB6wHiAdsR/wHlAeoC/wEIATsC/wHPAdkC/wEIATsC/wEIATsC/wHGAbwBtQH/AWwBUgE+Af8IAAHV + Ab8Brxb/Av4B/wH+AfwB+wH/AbkBpAGVAf8B1AHFAboB/wFrAVEBPQH/AVYCAgGpCAABBAIBAQQBCQIB + AQoBBAIBAQQB1gHAAbAR/wEPAZgBDwH/Ad8B7AHfAf8B/gL9Af8BuQGkAZUB/wHUAcUBugH/AWsBUQE9 + Af8BbAIUAeIIAAGwAXwBewH0AcsBbgEIAf8C/QH8Af8C/gH9Af8BywFuAQgO/wL+Af8B/gH8AfsB/wG5 + AaQBlQH/AdQBxQG6Af8BawFRAT0B/wFsAhQB4hQAAdUBvwGvGf8B5wHsAv8BCAE7Av8B6QHtAv8BlwGG + AYAB/wFWAgIBqQgAAdgBwgGyG/8B/gH/AcABqwGcAf8BawFRAT0B/wFWAgIBqBgAAdgBwgGyG/8B/gH/ + AcABqwGcAf8BawFRAT0B/wFuAhMB4QwAAVoCBAG5AWoCDwHUAfQB7gHqG/8B/gH/AcABqwGcAf8BawFR + AT0B/wFuAhMB4RgAAdgBwgGyG/8B/gH/AecB3wHZAf8BlwGGAYAB/wFVAgIBqgwAAdgBwgGyAf8B2AHC + AbIB/wHYAcIBsgH/AdgBwgGyAf8B2AHCAbIB/wHYAcIBsgH/AdQBvgGuAf8BzwG5AakB/wHJAbMBpAH/ + AUsCAgGLHAAB2AHCAbIB/wHYAcIBsgH/AdgBwgGyAf8B2AHCAbIB/wHYAcIBsgH/AdgBwgGyAf8B1AG+ + Aa4B/wHPAbkBqQH/AckBswGkAf8BYQIGAcoYAAHYAcIBsgH/AdgBwgGyAf8B2AHCAbIB/wHYAcIBsgH/ + AdgBwgGyAf8B2AHCAbIB/wHUAb4BrgH/Ac8BuQGpAf8ByQGzAaQB/wFhAgYByhwAAdgBwgGyAf8B2AHC + AbIB/wHYAcIBsgH/AdgBwgGyAf8B2AHCAbIB/wHYAcIBsgH/AdQBvgGuAf8BzwG5AakB/wHJAbMBpAH/ + AUsCAgGL/wAJAAFCAU0BPgcAAT4DAAEoAwABQAMAAWADAAEBAQABAQYAAQMWAAP/gQAByQP/AeABAQL/ + AcABAQGAAQEB4AEBAYABAQEAAQEBgAEBAYABAQGAAQEBAAEBAYABAQHgAQEBgAEBAQABAQGAAQEBgAEB + AYABAQEAAQEBgAEBAeABAQGAAQEBAAEBAYABAQGAAQEBgAEBAcABAQGAAQEB4AEBAYABAQHAAQEBgAEB + AeABAQGAAQEB4AEBAYABAQHgAQEBgAEBAeABAQGAAQEB4AEBAYABAQHgAQEBgAEBAeABAQGAAQEB4AEB + AYABAQHgAQEBgAEBAeABAQGAAQEB4AEDAYABAQHgAQMBgAEBAeABBwGAAQEB4AEHBv8BgAEBAYAB/wGA + AQMBgAEHAYABAQGAAf8BgAEDAYABBwGAAQEBgAEHAYABAwGAAQABgAEBAYABBwGAAQMBgAEAAYABAQGA + AQcBgAEDAYABAAGAAQEBgAEHAYABAwGAAQABgAEBAYABBwGAAQMBgAEAAYABAQHwAQcBgAEDAYABAAGA + AQEB8AEHAYABAwGAAQABgAEBAfABAQGAAQMBgAEHAYABAQHwAWEBgAEDAYABBwGAAQEB8AFhAYABAwGA + AQcBgAEBAfABAQGAAQMBgAEHAYABAwH/AQEBgAEDAYABDwGAAQcB/wEBAYABAwGAAR8D/wEBBP8CAwL/ + AeABAQHAAQMBAAEDAYABHwHgAQEBwAEDAQABAwGAAR8B4AEBAcABAwEAAQMBgAEAAeABAQHAAQMBAAED + AYACAAEBAcABAwHAAQMBgAEAAYABAQHAAQMBwAEDAYABAAGAAQEBwAEDAcABAwGAAQABwAEBAcABAwHA + AQMBgAEAAcABAQHAAQMBwAEDAeABAAHgAQEBwAEDAcABAwHgAQAB4AEBAcABAwHAAQMB4AEHAeABAQHA + AQMBwAEDAeABBwHgAQEBwAEDAcABAwHgAQcB4AEDAcABBwHAAQcB4AEHAeABBwHAAQ8BwAEPDP8B8AEA + AfABAAHAAQMBwAEDAfABAAHwAQABwAEDAcABAwHwAQABgAEAAcABAwHAAQMEAAHAAQMBwAEDBAABwAED + AcABAwQAAcABAwHAAQMBwAMAAcABAwHAAQMBgAMAAcABAwHAAQMBgAMAAcABAwHAAQMBgAMAAcABAwHA + AQMBgAMAAcABAwHAAQMBgAMAAcABAwHAAQMB8AMAAcABAwHAAQMB8AEBAYABAQHAAQcBwAEHAfABAwHw + AQMBwAEPAcABDwL/AcABAwHgAQEB4AEBAfABAAHAAQMB4AEBAeABAQHwAQABwAEDAeABAQHgAQEB8AEA + AcABAwHgAQEB4AEBAfABAAHAAQMB4AEBAeABAQHwAQABwAEDAQABAQHgAQEBgAEAAcABAwEAAQEB4AEB + AYABAAHAAQMBAAEBAcABAQIAAcABAwEAAQEBwAEBAgABwAEDAQABAQGAAQECAAHAAQMBAAEBAYABAQIA + AcABAwEAAQEBgAEBAgABwAEDAQABAQGAAQEB8AEAAcABBwHgAQMBgAEDAfABAQHAAQ8B4AEHAeABBwHw + AQMI/ws= + + + + 231, 17 + + + + AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj0yLjAuMC4w + LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAACZTeXN0 + ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAABm + IwAAAk1TRnQBSQFMAgEBBgEAAQkBAAEEAQABEAEAARABAAT/ASEBAAj/AUIBTQE2BwABNgMAASgDAAFA + AwABIAMAAQEBAAEgBgABIGoAAbcBogGTAf8BZwFNATkB/wFnAU0BOQH/AWcBTQE5Af8BZwFNATkB/wFn + AU0BOQH/AWcBTQE5Af8BZwFNATkB/wFnAU0BOQH/AWcBTQE5Af/YAAG3AaIBkwH/Aa0B5wH5Af8B4QHc + AdgB/wHgAdcB0gH/Ad8B0gHKAf8B3wHOAcMB/wHdAcgBuwH/AdwBwwGzAf8BxQGvAaMB/wFnAU0BOQH/ + gAABtwGiAZMB/wFwAVYBQgH/AXABVgFCAf8BcAFWAUIB/wFwAVYBQgH/AXABVgFCAf8BcAFWAUIB/wFw + AVYBQgH/AXABVgFCAf8BcAFWAUIB/wFwAVYBQgH/AXABVgFCAf8BcAFWAUIB/wFwAVYBQgH/IAABtwGi + AZMB/wG8AesB+gH/Aa4B6AH5Af8BnwHjAfgB/wGRAd8B9wH/AYMB2wH2Af8BewHYAfUB/wFwAdUB9AH/ + AcgBtAGpAf8BZwFNATkB/4AAAbcBogGTAf8B/QH4AfYB/wHhAdwB2AH/AeAB1wHSAf8B3wHSAcoB/wHf + Ac4BwwH/Ad0ByAG7Af8B3AHDAbMB/wHbAb8BrQH/AdsBuwGnAf8B2wG7AacB/wHbAbsBpwH/Ac8BtAGj + Af8BcAFWAUIB/xAAARACAQEUAUECAQFwAVoBCQEFAbcBewE2ASMB6gG3AaIBkwH/AcoB7wH7Af8BtwGi + AZMB/wGtAegB+QH/AbcBogGTAf8BkQHfAfcB/wG3AaIBkwH/AXsB1wH1Af8BzAG5Aa4B/wFnAU0BOQH/ + gAABtwGiAZMB/wH9AfsB+QH/Af0B+QH3Af8B/QH5AfcB/wH8AfcB8wH/AfsB8gHtAf8B/AHzAfAB/wH9 + AfkB9gH/AfsB8AHrAf8B9wHlAdwB/wH5AeoB5AH/AfsB8QHsAf8B3AHJAb0B/wFwAVYBQgH/DAABJAIB + ATMBXAEIAQcBsAGFAXYBLwH/AV4BdgElAf8BVgFkAUAB/wG6AaUBlgH/AdgB9AH8Af8BygHwAfsB/wG8 + AewB+gH/Aa0B6AH5Af8BnwHjAfgB/wGRAd8B9wH/AYMB3AH2Af8B0AG+AbQB/wFnAU0BOQH/gAABtwGi + AZMB/wH+AvwC/wH9AfwB/wGVAaoC/wGVAaoD/wL+Af8BuQHHAv8BDQFAAv8BuQHHAv8B/gH9AfwB/wHU + Ad0C/wESAUQG/wHCAbgBsAH/AS8CAQFIBAABEAIBARQBXgEJAQcBsAHnAYUBVwH/AckBgAFEAf8BXAGH + ARwB/wEzAYUBIQH/Ab4BqQGaAf8B4wH3Af0B/wG3AaIBkwH/AcoB8AH7Af8BtwGiAZMB/wGtAegB+QH/ + AbcBogGTAf8BkQHfAfcB/wHUAcQBuwH/AWcBTQE5Af+AAAG3AaIBkwL/Av4F/wENAUAC/wENAUAG/wEN + AUAC/wHOAdgC/wENAUAC/wHOAdgC/wENAUAC/wEOAUEC/wHZAeEC/wEPAUIC/wF+AiwB7gEKAgEBCwFC + AgEBcQH0AY8BYQH/Ae0BjAFfAf8BwwGBAVgB/wFSAX4BPQH/ATgBmAEhAf8BwwGuAZ4B/wHvAfsB/gH/ + AeQB9wH9Af8B2AH0AfwB/wHKAfAB+wH/AbwB7AH6Af8BrgHoAfkB/wGfAeMB+AH/AdkBygHCAf8BZwFN + ATkB/4AAAboBpQGWBf8BzgHYAv8BDQFAAv8BDQFAAv8BzgHYCv8BDQFAAv8BzgHYAv8B2AHgAv8BEAFC + Av8BDwFCAv8BDgFBAv8B2QHhAv8BOQIBAV0BZQENAQoBuQH5AZYBaQH/AdwBjQFlAf8BawF4AU8B/wFU + AaEBNQH/AU4BowEtAf8ByAGyAaMB/wH4Af0C/wG3AaIBkwH/AeQB9wH9Af8BtwGiAZMB/wHKAe8B+wH/ + AbcBogGTAf8BrQHoAfkB/wHdAdAByQH/AWcBTQE5Af+AAAG+AakBmgX/AQ0BQAL/AaYBuAL/AaYBuAL/ + AQ0BQAP/Av4F/wENAUAC/wHOAdgC/wENAUAC/wEQAUIG/wEOAUEC/wEQAUIC/wFTAgIBpAG2AVIBPAHr + AegBlwFtAf8BYAF0AVoB/wFgAZYBSAH/AV4BrAE8Af8BkwGgAT0B/wHMAbYBpwX/AfgB/QH+Af8B7wH6 + Af4B/wHkAfcB/QH/AdgB8wH8Af8BygHwAfsB/wG8AesB+gH/Aa4B6AH5Af8BZwFNATkB/4AAAcMBrgGe + Bf8BDQFACv8BDQFAA/8C/gL/Af4B/QH/AQ0BQAL/Ac4B2AL/AcgB0wL/AQ4BQQL/ARIBRAL/AQ0BQAL/ + Ad0B5AL/AVMCAgGkAbYBVwFAAewCgQFeAf8BPgGhAUUB/wFWAbMBRgH/AY0BkQFcAf8B5AGUAW4C/wHC + AaIC/wG8AZgC/wGzAYoC/wGoAX0C/wGeAW4B/wH9AZIBYQH/Ae4BhwFWAf8B2gF9AU0B/wHGAXABRAH/ + AbIBZAE9Af+AAAHIAbIBow3/A/4C/wL+Af8B/gH8AfsB/wH+AfoB+AH/Af4B+wH6Af8B/QH5AfcB/wHl + AeoC/wENAUAC/wHPAdkC/wENAUAC/wENAUAC/wFTAgIBoQFoAREBDQG9AWcBmAFWAf8BRAHFAWMB/wFI + AckBbgH/AXcBnQFxAf8BtgGfAW0C/wG+AZsC/wHCAaIB/wH+AcABnwH/Af0BvQGaAf8B/AG5AZYB/wH7 + AbUBkAH/AfoBsAGLAf8B+QGrAYQB/wHzAZUBaQH/Ac0BaQE1Af+AAAHMAbYBpxP/Af4B/wH+AvwB/wH+ + AfoB+QH/Af0B9wH1Af8B+wH0AfEB/wH8AfYB8wH/Af4B+gH4Af8B5wHsAv8BDQFAAv8B6QHtAv8BNgIB + AVUBRQIBAXkBVgG4AWoB/wFeAdYBgQH/AY0B4QGbAf8BggHjAZ4B/wGeAdABkwL/Ab4BmwL/AbcBkQL/ + AbABhQL/AagBfAL/AZ8BcAL/AZcBZgH/AfcBjgFdAf8B6wGEAVUB/wHcAX4BTgH/AcsBdAFHAf+AAAES + ATwB3AH/ARIBOwHaAf8BFAE5AdIB/wEVATcBygH/ARcBNQHAAf8BGAEzAbUB/wEbAS8BqQH/AR0BLQGd + Af8BHwEqAZEB/wEhAScBhgH/ASMBJQGBAf8BKwEoAYEB/wF0AXABmgH/AagBpAHDAf8BNgIBAVUBBgIB + AQYBEwIBARgBVwESAQoBuwF7Ad8BlgH/AcQB7AG3Af8B0wHzAcoB/wHrAfcB1QH/AbAB5AGmAf8BggGU + AWQB/wHVAZQBRAH/Aa0BjwE2Af8BVgELAQMBsAEQAgEBFJAAAREBPQHiAf8BiQGgAf0B/wGCAZsB/AH/ + AYEBkwH6Af8BegGJAfoB/wFtAYEB+AH/AWABgAH2Af8BUgF1AfQB/wFDAWkB8gH/ATYBXgHxAf8BKQFT + Ae8B/wEdAUoB7gH/ARQBQgHsAf8BKAEeAW0B/wwAASgCAQE7AV0BFAEMAbsBvwHsAbYB/wHeAfYBzAH/ + AYABqQFsAf8BeQHYAYkB/wFHAa0BZQH/AYYBgQE8Af8BXwEIAQcBsQEkAgEBM5QAARIBOwHcAf8BEgE7 + AdkB/wEUATkB0gH/ARUBOAHJAf8BFgE0AcAB/wEYATIBtQH/ARsBLwGpAf8BHQEtAZ0B/wEfASoBkQH/ + ASEBJwGGAf8BIwElAYEB/wElASIBfQH/ASYBIAF0Af8BKAEeAWwB/xAAARQCAQEZAUYBAgEBAXwBZQEZ + ARQBwAGCAX0BWQHtAVsBdQFKAewBVQESAQoBvAFDAgEBcwERAgEBFf8ArQABPAIBAWMBtQFrASoB/AFP + AWcB2wH/AWIBBQEPAeYIAAEVAb8C/wEVAb8C/wFBAXsBYAH8AToCAQFfxAABjgJ/Af4BWQFVAVMB/wFY + AVQBUgH/AVgBVAFRAf8BgQFwAV4B/wHXAYkBOQH/Ad4BmwFKAf8BRgF4AecB/wEwAVIB4wH/ASgBNQG0 + Af8BQwGKAdoB/wEiAccB/gH/AUQB0gH5Af8BZAHNAZUB/wFBAaYBeAH/AUkBWQFBAf6AAAG3AaIBkwH/ + AXABVgFCAf8BcAFWAUIB/wFwAVYBQgH/AXABVgFCAf8BcAFWAUIB/wFwAVYBQgH/AXABVgFCAf8BcAFW + AUIB/wFwAVYBQgH/AXABVgFCAf8BcAFWAUIB/wFwAVYBQgH/AXABVgFCAf8BcAFWAUIB/wFwAVYBQgH/ + AX4BNQEyAfQK/wH8Af8BhgGOAW4B/wHNAYEBPAH/AecBvwGcAf8BlAGtAfAB/wE9AXUB9gH/ATUBUwHg + Af8BJwE2AbkB/wFDAYoB2gH/AYEByQHhAf8BggHRAaQB/wFLAbwBgQH/ATwBmQFxAf8EAAG3AaIBkwH/ + AXABVgFCAf8BcAFWAUIB/wFwAVYBQgH/AXABVgFCAf8BcAFWAUIB/wFwAVYBQgH/AXABVgFCAf8BcAFW + AUIB/wFwAVYBQgH/AXABVgFCAf8BcAFWAUIB/wFwAVYBQgH/AXABVgFCAf8IAAG3AaIBkwH/AXABVgFC + Af8BcAFWAUIB/wFwAVYBQgH/AXABVgFCAf8BcAFWAUIB/wFwAVYBQgH/AXABVgFCAf8BcAFWAUIB/wFw + AVYBQgH/AXABVgFCAf8BcAFWAUIB/wFwAVYBQgH/AXABVgFCAf8EAAG3AaIBkwH/AeEB3AHYAf8B4QHc + AdgB/wHgAdcB0gH/Ad8B0gHKAf8B3wHOAcMB/wHdAcgBuwH/AdwBwwGzAf8B2wG/Aa0B/wHbAbsBpwH/ + AdsBuwGnAf8B2wG7AacB/wHbAbsBpwH/AdsBuwGnAf8BzwG0AaMB/wFwAVYBQgH/AXYCJAHwBv8B/gL/ + Af0B+wH/AUYBoQF0Af8BYwGcAXAB/wH8AfMB7AH/AfsB7wHnAf8BOAGRAfIB/wFDAXMB8gH/ATQBUAHd + Af8BJQE3Ab0B/wH3AdoBxwH/AfYB1gHCAf8BgwGbAWQB/wFMAX8BYQH+BAABtwGiAZMB/wH9AfgB9gH/ + AeEB3AHYAf8B4AHXAdIB/wHfAdIBygH/Ad8BzgHDAf8B3QHIAbsB/wHcAcMBswH/AdsBvwGtAf8B2wG7 + AacB/wHbAbsBpwH/AdsBuwGnAf8BzwG0AaMB/wFwAVYBQgH/CAABtwGiAZMB/wH9AfgB9gH/AeEB3AHY + Af8B4AHXAdIB/wHfAdIBygH/Ad8BzgHDAf8B5gHXAc4B/wH6AfYB8wH/AfsB+QH3Af8B+wH4AfYB/wHu + Ad8B1QH/AeABxAGyAf8BzwG0AaMB/wFwAVYBQgH/BAABtwGiAZMB/wH9AfkB9gH/Af0B9wH1Af8B/QH2 + AfMB/wH8AfQB8QH/AfwB8wHvAf8B+wHyAe0B/wH7AfAB6wH/AfoB8AHpAf8B+QHuAecB/wH5AewB5gH/ + AUMBdAGOAf8BQwF0AY4B/wH4AekB4AH/Ac8BtAGjAf8BcAFWAUIB/wF2AiQB8An/Av4B/wFpAbYBiAH/ + AVMBygGJAf8BRwGwAYEB/wEyAcMB4gH/AV8B1AH9Af8BUgGUAfoB/wE9AXIB7wH/ATABTQHhAf8BOQE4 + Aa8B/wHWAYQBRAH/Ad0BjAE7Af8BjQFfASoB/AQAAbcBogGTAf8B/QH7AfkB/wH9AfkB9wH/Af0B+gH4 + Af8B/gH7AfoB/wH+AfsB+QH/Af0B9wH0Af8B/AH1AfIB/wH7AfMB7wH/AfgB6QHiAf8B9QHeAdUB/wH0 + AdsBzgH/Ac8BtAGjAf8BcAFWAUIB/wgAAbcBogGTAf8B/QH7AfkB/wH9AfgB9gH/AfwB9QHyAf8B+gHy + Ae0B/wH6Ae8B6QH/Af4B/AH7Af8BywFzAQ0B/wHLAXMBDQH/AcsBcwENAf8B6QG+AZ0B/wH6Ae4B6AH/ + Ac8BtAGjAf8BcAFWAUIB/wQAAbcBogGTAf8B/gH6AfcB/wH9AfgB9gH/AfwB+AH1Af8B/QH2AfMB/wH7 + AfQB8QH/AfsB8wHwAf8B+wHyAe0B/wH6AfEB6wH/AfoB7wHqAf8B+QHtAecB/wFoAdsC/wFBAXwBkwH/ + AfgB6gHjAf8BzwG0AaMB/wFwAVYBQgH/AXYCJAHwDP8B2AHxAeIB/wF9Ac4BmgH/AWABzgGZAf8BSgHY + AfwB/wFJAdcC/wEVAb8C/wGEAaQB7QH/ATgBbwHzAf8BRgFjAdcB/wHiAZgBQgH/AeIBnwFbAf8BYAEU + AQsB8gQAAbcBogGTAf8B/gL8Af8B/gL8Af8B4gHuAeIB/wENAZkBDQH/AQ0BmQENAf8B4gHtAeEB/wH7 + AfwB+gH/ARIBlwESAf8B0AHhAc4B/wH7AfEB7AH/AfcB5gHcAf8B0AG1AaQB/wFwAVYBQgH/CAABtwGi + AZMB/wH+AvwB/wH+AfoB+QH/Af0B+QH2Af8B/gH7AfoB/wH+AfoB+AH/Af4C/QH/AcsBcwENAf8B/gH9 + AfwB/wH+AfwB+wH/AcsBcwENAf8B/QH3AfQB/wHPAbQBowH/AXABVgFCAf8EAAG3AaIBkwH/Af4B+wH5 + Af8B/QH6AfgB/wH9AfgB9gH/Af0B9wH1Af8B/QH2AfMB/wH7AfUB8QH/AfsB8wHvAf8B+wHyAe4B/wEw + AZUBpQH/ATMBjAGhAf8BbwHfAf4B/wE8AYEBlgH/AUABfAGSAf8BRAF1AY8B/wFwAVYBQgH/AXYCJAHw + EP8B2AHwAeIB/wF5AcoBoAH/ASQBxAL/ASQBxAL/AfwB7wHnAf8B+wHrAeEB/wGBAaIB7wH/AVoBgQHq + Af8B4gGzAYEB/wHpAcgBqgH/AVcBCgEJAfAEAAG3AaIBkwL/Av4C/wL+Af8BJwGjAScB/wHiAe4B4gL/ + Af4B/QH/AZ4B2AGeAf8BFQGZARUB/wEOAZUBDgH/Aa4BzQGsAf8BDwGVAQ8B/wHlAekB3QH/AdIBuAGo + Af8BcAFWAUIB/wgAAbcBogGTAv8C/gH/Af4B/QH7Af8C/gH9Af8B2gGSAWgB/wHaAZIBaAL/Af4B/QH/ + AcsBcwENAf8BywFzAQ0B/wHLAXMBDQH/AfIB2AHGAf8B/AH2AfMB/wHPAbQBowH/AXABVgFCAf8EAAG6 + AaUBlgH/Af4B/AH7Af8B/gH7AfoB/wH+AfoB+AH/Af0B+AH2Af8B/AH3AfQB/wH9AfYB8wH/AfwB9AHx + Af8B/AHzAe8B/wGIAfUC/wGBAe8B/gH/AX4B6AL/AXMB4gL/AWsB3QL/AUQBdQGPAf8BcAFWAUIB/wF2 + AiQB8BH/Af4C/wH+AfwB+gH/Af4B+QH1Af8B/QH2AfEB/wH8AfIB6wH/AfwB7gHlAf8B+gHqAd8B/wH6 + AeUB2AH/AfkB4AHSAf8B6gHUAcMB/wFXAQoBCQHwBAABugGlAZYJ/wENAZkBDQL/Av4C/wL+Bv8C/QH/ + ARABlgEQAf8BDwGVAQ8B/wEOAZQBDgH/Ad8B6QHcAf8B3AHLAcEB/wFwAVYBQgH/CAABugGlAZYG/wL+ + Bf8BywFzAQ0B/wHLAXMBDQL/Af4B/QH/AcsBcwENAv8C/QH/Af4B/QH8Af8BywFzAQ0B/wH9AfgB9gH/ + AdABuQGrAf8BcAFWAUIB/wQAAb4BqQGaAf8B/gH9AfwB/wH+AfwB+gH/Af4B+wH5Af8B/QH6AfgB/wH9 + AfgB9wH/AfwB9wH1Af8BQwF0AY4B/wFDAXQBjgH/AfsB9AHvAf8B+wHyAe4B/wGDAfIB/gH/ATQBjAGh + Af8B+gHtAegB/wHRAcEBtgH/AXABVgFCAf8BdgIkAfAV/wH+Af0B/wH+AfoB+QH/Af4B+AH1Af8B/QH0 + Ae8B/wH8AfEB6QH/AfsB7AHjAf8B+gHoAd0B/wH5AeQB1gH/AeoB1gHIAf8BVwEKAQkB8AQAAb4BqQGa + Cf8BDQGZAQ0B/wHiAe4B4gL/Av4B/wGBAckBgQH/ARUBmQEVAf8BEAGWARAB/wHqAfIB6gH/AQ4BlAEO + Af8BEAGWARAB/wHmAd0B1wH/AXABVgFCAf8IAAG+AakBmgn/AfMB2wHJAf8BywFzAQ0B/wHLAXMBDQH/ + AfMB2gHIAf8BywFzAQ0B/wHLAXMBDQH/AcsBcwENAf8B6QG+AZ4B/wH7AfMB7gH/AdEBwQG2Af8BcAFW + AUIB/wQAAcMBrgGeAv8C/gH/Af4B/QH8Af8B/gH8AfsB/wH9AfsB+gH/Af0B+QH4Af8B/AH4AfcB/wFo + AdsC/wFBAXwBkwH/AfwB9AHxAf8B+wH0Ae8B/wGSAfsB/gH/ATABlQGlAf8B+gHvAeoB/wHRAcEBtgH/ + AXABVgFCAf8BdgIkAfAZ/wH9AfwB/wH+AfoB+AH/Af0B9wHzAf8B/AHzAe0B/wH8Ae8B5wH/AfoB6wHh + Af8B+gHnAdsB/wHqAdkBywH/AVcBCgEJAfAEAAHDAa4Bngn/AeIB7gHiAf8BJwGjAScB/wENAZkBDQH/ + AeIB7gHiAf8B4gHuAeEB/wEOAZQBDgH/ARIBlwESAf8BDQGZAQ0B/wHKAd0ByAH/AecB3gHYAf8BcAFW + AUIB/wgAAcMBrgGeCf8BywFzAQ0B/wHdAZsBdgH/Ad0BmwF2Af8BywFzAQ0C/wL+Av8B/gH9Av8C/QH/ + AfwB9gHzAf8B+QHrAeUB/wHRAcEBtgH/AXABVgFCAf8EAAHIAbIBowL/Av4C/wH+Af0B/wH+Af0B/AH/ + Af4B/AH7Af8BMAGVAaUB/wEzAYwBoQH/AW8B3wH+Af8BPAGBAZYB/wFAAXwBkgH/AUQBdQGPAf8B+wHz + Ae8B/wH6AfIB7gH/AfsB8AHsAf8B0QHBAbYB/wFwAVYBQgH/AXICIQHwHf8C/gL/AfsB+gH/Af4B+AH1 + Af8B/QH1Ae8B/wH8AfEB6AH/AfsB7AHiAf8B6gHfAdQB/wFXAQoBCQHwBAAByAGyAaMT/wH+Af8C/gH9 + Av8C/gH/ARYBmQEWAf8B3wHsAd8B/wENAZQBDQH/ARYBmQEWAf8B6wHkAeAB/wFwAVYBQgH/CAAByAGy + AaMJ/wHLAXMBDQn/AcsBcwENAv8B/gH9Af8B/AH1AfEB/wH7AfIB7QH/AfoB7gHpAf8B+QHqAeQB/wHR + AcEBtgH/AXABVgFCAf8EAAG+AakBmgH/BAAB/gH/Af4C/wH+Af0B/wH+Af0B/AH/AYgB9QL/AYEB7wH+ + Af8BfgHoAv8BcwHiAv8BawHdAv8BRAF1AY8B/wH8AfQB8QH/AfsB8wHvAf8B+wHyAe0B/wHfAc4BwwH/ + AXABVgFCAf8BfAEyAS8B9AH3AfAB7AH/AfwB9gH0Af8B/AH2AfMB/wH7AfUB8gH/AfoB9AHxAf8B+gH0 + AfAB/wH6AfIB7gH/AfoB8gHuAf8B+gHwAeoB/wH5Ae0B5gH/AfkB6gHhAf8B+AHmAdwB/wH4AeMB1gH/ + AeYB1gHJAf8BXQIHAewEAAHMAbYBpxP/Af4B/wH+AvwB/wH+AvsC/wL9A/8B/gH/ARQBmAEUAf8B3wHr + Ad4B/wH8AfQB8AH/AXABVgFCAf8IAAHMAbYBpxP/Af4C/wL+Af8B/gL7Af8B/QH3AfUB/wH7AfQB8QH/ + AfsB8QHtAf8B+gHuAegB/wH5AeoB4wH/AXABVgFCAf8EAAHDAa4BngH/CAAB/gP/Af4C/QH/Af4C/AH/ + Af4B+wH6Af8BgwHyAf4B/wE0AYwBoQH/Af0B+AH2Af8B/AH3AfUB/wH8AfYB8wH/AfwB9AHxAf8B+wH0 + AfAB/wHfAc4BwwH/AXABVgFCAf8BiAE6ATQB9QHwAbEBkgH/AfQBsgGRAf8B6AGfAYEB/wHhAZABdQH/ + Ad0BiAFqAf8B3AGHAWgB/wHaAYMBZAH/AdgBgQFfAf8B1wGBAVsB/wHWAYEBWAH/AdUBgQFWAf8B1AGB + AVQB/wHUAYEBUwH/AcoBfQFOAf8BYAEOAQkB8QQAAW0BugFzAf8BagG1AXAB/wFmAa8BbQH/AWIBpgFp + Af8BXgGeAWQB/wFZAZUBYAH/AVQBjAFbAf8BTwGDAVYB/wFeAYcBZQH/AYgBqQGNAf8BtQHIAbgB/wGS + AaoBlQH/AVQBeAFaAf8BMwFaATsB/wgAAeoBqgGLAf8B6gGqAYsB/wHqAaoBiwH/AekBpQGEAf8B6QGf + AYEB/wHnAZcBewH/AeYBjgFvAf8B5QGGAWMB/wHjAYEBVwH/AeMBgQFNAf8B4gF/AUYB/wHiAX8BRgH/ + AeIBfwFGAf8ByAFvATwB/wQAAbwBYgExAf8BvAFiATEB/wG8AWIBMQH/AbwBYgExAf8BugFaASYB/wG6 + AVEBFQH/AbcBRAENAf8BkgH7Af4B/wEwAZUBpQH/AbEBGgENAf8BsQEPAQ0B/wGvAg0B/wGvAg0B/wGv + Ag0B/wGvAg0B/wGGAg0B/wHYAaoBkgH/AfwBwAGgAf8B/AG9AZsB/wH5AbYBlAH/AfUBsAGLAf8B8QGp + AYUB/wHuAaQBgQH/AewBoAGBAf8B6wGcAX8B/wHnAZUBeAH/AeQBjwFyAf8B4QGLAWsB/wHfAYYBZgH/ + Ad0BggFhAf8BzgGBAVkB/wFFATUBKwH/BAABbQG6AXMB/wFAAcsBdAH/AT0BxwFvAf8BOwHBAWoB/wE4 + AboBYwH/ATQBswFbAf8BMAGqAVIB/wErAaIBSgH/AScBmQFBAf8BIwGQATkB/wEgAYgBMQH/ARwBggEq + Af8BGQGBASQB/wEzAVoBOwH/CAAB6gGqAYsC/wHCAaIB/wH+AcABnwH/Af0BvQGaAf8B/AG5AZYB/wH7 + AbUBkAH/AfoBsAGLAf8B+QGrAYQB/wH4AacBgQH/AfYBogGBAf8B9QGdAX4B/wH1AZkBdwH/AfMBlQFy + Af8BzQFyAT4B/wQAAbwBYgExAf8B3gGBAVYB/wHeAYEBVgH/AdwBgQFRAf8B2wGBAUkB/wHZAXsBQgH/ + AdcBdAE5Af8B1gFsATEB/wHUAWQBJgH/AdMBXgEaAf8BzwFWAREB/wHOAU4BDQH/Ac4BRwENAf8BywFB + AQ0B/wHLAUEBDQH/AY4CDQH/AWACAwHTAV4CAwHKAWUCBQHcAWMCAwHQAWICAwHUAYEBIwEZAfEBegEd + ARcB8AFuAQ4BCwHoAWQCBAHaAWMCAwHSAWECAwHMAWECAwHMAWECAwHMAWECAwHMAWECAwHRAWQCBAHd + BAABbQG6AXMB/wFqAbUBcAH/AWYBrwFtAf8BYgGmAWkB/wFeAZ4BZAH/AVkBlQFgAf8BVAGMAVsB/wFP + AYMBVgH/AUoBgQFSAf8BRQF8AU0B/wFAAXMBRwH/ATwBagFDAf8BNwFhAT4B/wEzAVoBOwH/CAAB6gGq + AYsB/wHqAaoBiwH/AeoBqgGLAf8B6gGqAYsB/wHqAaYBhgH/AekBoQGBAf8B6AGbAYEB/wHnAZQBeQH/ + AeYBjgFvAf8B5QGHAWUB/wHkAYEBWwH/AeQBgQFTAf8B4wGBAUsB/wHiAX8BRgH/BAABvAFiATEB/wG8 + AWIBMQH/AbwBYgExAf8BvAFiATEB/wG8AWIBMQH/AbwBXAEpAf8BugFUAR0B/wG5AUoBDwH/AbcBPwEN + Af8BtgE2AQ0B/wG0ASoBDQH/AbIBIQENAf8BsgEXAQ0B/wGxAQ8BDQH/AbEBDwENAf8BrwINAf//AAEA + AUIBTQE+BwABPgMAASgDAAFAAwABIAMAAQEBAAEBBgABARYAA/8BAAL/AfwFAAL/AfwGAAEDAfwGAAED + AcAGAAEDAYAGAAEBOQABDwUAAQMBgAEfBQABAwHAAT8EAAT/BAAB+AFhBv8CAAT/BAABgAEBAYABAQQA + AYABAQGAAQEEAAGAAQEBgAEBBAABgAEBAYABAQQAAYABAQGAAQEEAAGAAQEBgAEBBAABgAEBAYABAQQA + AYABAQGAAQEEAAGAAQEBgAEBAUADAAGAAQEBgAEBAWADAAGAAQEBgAEBBAABgAEBAYABAQQAAYABAQGA + AQECAAj/Cw== + + + + 17, 17 + + \ No newline at end of file diff --git a/samples/LineCounter/Src/LineCounterViewContent.cs b/samples/LineCounter/Src/LineCounterViewContent.cs new file mode 100644 index 0000000000..27d504645c --- /dev/null +++ b/samples/LineCounter/Src/LineCounterViewContent.cs @@ -0,0 +1,35 @@ +/* + * Created by SharpDevelop. + * User: Daniel Grunwald + * Date: 09.05.2006 + * Time: 17:53 + */ + +using System; +using System.Windows.Forms; +using ICSharpCode.SharpDevelop.Gui; + +namespace LineCounterAddin +{ + /// + /// Description of the view content + /// + public class LineCounterViewContent : AbstractViewContent + { + LineCounterBrowser browser = new LineCounterBrowser(); + + /// + /// The representing the view. + /// + public override Control Control { + get { + return browser; + } + } + + public LineCounterViewContent() + { + this.TitleName = "Line Counter"; + } + } +}