├── Docs ├── media │ └── PayPal.gif ├── Content │ ├── VersionHistory │ │ ├── v2019.10.27.0.md │ │ ├── v2021.7.5.0.md │ │ ├── v2023.2.12.0.md │ │ ├── v2022.7.29.0.md │ │ ├── VersionHistory.md │ │ └── v2025.9.12.0.md │ ├── KnownIssues.md │ ├── Installation.md │ ├── SystemRequirements.md │ ├── Contributing.md │ └── Welcome.md ├── ContentLayout.content └── ExtendedDocCommentsProviderDocs.shfbproj ├── Source ├── VSIXPackage.png ├── VSIXPreview.png ├── ExtendedDocCommentsProvider.snk ├── GlobalSuppressions.cs ├── ElementUsage.cs ├── source.extension.vsixmanifest ├── Properties │ └── AssemblyInfo.cs ├── ElementAttribute.cs ├── SyntaxExtensions.cs ├── ExtendedDocCommentsProvider.csproj ├── CommentsElement.cs ├── CSharpXmlDocCommentsCompletionProvider.cs └── License.rtf ├── ExtendedDocCommentsProvider.slnx ├── .github └── FUNDING.yml ├── README.md ├── .gitignore ├── LICENSE └── .editorconfig /Docs/media/PayPal.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EWSoftware/ExtendedDocCommentsProvider/HEAD/Docs/media/PayPal.gif -------------------------------------------------------------------------------- /Source/VSIXPackage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EWSoftware/ExtendedDocCommentsProvider/HEAD/Source/VSIXPackage.png -------------------------------------------------------------------------------- /Source/VSIXPreview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EWSoftware/ExtendedDocCommentsProvider/HEAD/Source/VSIXPreview.png -------------------------------------------------------------------------------- /Source/ExtendedDocCommentsProvider.snk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EWSoftware/ExtendedDocCommentsProvider/HEAD/Source/ExtendedDocCommentsProvider.snk -------------------------------------------------------------------------------- /Docs/Content/VersionHistory/v2019.10.27.0.md: -------------------------------------------------------------------------------- 1 | --- 2 | uid: 34d99bb4-76e2-4f02-b2e4-1feaab4dbba8 3 | alt-uid: v2019-10-27-0 4 | title: Version 2019.10.27.0 5 | keywords: "versions, 2019.10.27.0" 6 | --- 7 | 8 | Initial release. 9 | 10 | 11 | 12 | ## See Also 13 | 14 | 15 | **Other Resources** 16 | [](@caa20db4-521f-4c4c-8399-aea8a81ae6a7) 17 | -------------------------------------------------------------------------------- /Docs/Content/VersionHistory/v2021.7.5.0.md: -------------------------------------------------------------------------------- 1 | --- 2 | uid: 16fd137b-699a-4260-906f-59d94818ff7a 3 | alt-uid: v2021-7-5-0 4 | title: Version 2021.7.5.0 5 | keywords: "versions, 2021.7.5.0" 6 | --- 7 | 8 | Changes made in this release: 9 | 10 | 11 | - Added support for Visual Studio 2022. 12 | 13 | 14 | 15 | ## See Also 16 | 17 | 18 | **Other Resources** 19 | [](@caa20db4-521f-4c4c-8399-aea8a81ae6a7) 20 | -------------------------------------------------------------------------------- /Docs/Content/VersionHistory/v2023.2.12.0.md: -------------------------------------------------------------------------------- 1 | --- 2 | uid: 6857ece7-59b8-4ad0-86bd-ae7453b97faf 3 | alt-uid: v2023-2-12-0 4 | title: Version 2023.2.12.0 5 | keywords: "versions, 2023.2.12.0" 6 | --- 7 | 8 | Changes made in this release: 9 | 10 | 11 | - Added the self-closing option to the `see` and `seealso` 12 | elements. 13 | 14 | 15 | 16 | ## See Also 17 | 18 | 19 | **Other Resources** 20 | [](@caa20db4-521f-4c4c-8399-aea8a81ae6a7) 21 | -------------------------------------------------------------------------------- /Docs/Content/VersionHistory/v2022.7.29.0.md: -------------------------------------------------------------------------------- 1 | --- 2 | uid: 23ea721a-0a75-48c7-8457-7614bf3c4926 3 | alt-uid: v2022-7-29-0 4 | title: Version 2022.7.29.0 5 | keywords: "versions, 2022.7.29.0" 6 | --- 7 | 8 | Changes made in this release: 9 | 10 | 11 | - Added support for the `title` attribute and the `todo` 12 | note type for the `note` XML comments element. 13 | 14 | 15 | 16 | ## See Also 17 | 18 | 19 | **Other Resources** 20 | [](@caa20db4-521f-4c4c-8399-aea8a81ae6a7) 21 | -------------------------------------------------------------------------------- /ExtendedDocCommentsProvider.slnx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /Docs/Content/VersionHistory/VersionHistory.md: -------------------------------------------------------------------------------- 1 | --- 2 | uid: caa20db4-521f-4c4c-8399-aea8a81ae6a7 3 | alt-uid: VersionHistory 4 | title: Version History 5 | keywords: "version, history" 6 | --- 7 | 8 | This topic describes the various changes made to the Extended XML Documentation Comments Provider 9 | over the life of the project. Select a version below to see a description of its changes. 10 | 11 | 12 | 13 | - [](@f05af659-63c9-439b-8e07-3105f10cfb4a) 14 | - [](@6857ece7-59b8-4ad0-86bd-ae7453b97faf) 15 | - [](@23ea721a-0a75-48c7-8457-7614bf3c4926) 16 | - [](@16fd137b-699a-4260-906f-59d94818ff7a) 17 | - [](@34d99bb4-76e2-4f02-b2e4-1feaab4dbba8) 18 | 19 | 20 | 21 | ## See Also 22 | 23 | 24 | **Other Resources** 25 | [](@141160ac-ba6a-4f6d-a802-1110aadea932) 26 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: [ewsoftware] 4 | patreon: # Replace with a single Patreon username 5 | open_collective: # Replace with a single Open Collective username 6 | ko_fi: # Replace with a single Ko-fi username 7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel 8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry 9 | liberapay: # Replace with a single Liberapay username 10 | issuehunt: # Replace with a single IssueHunt username 11 | lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry 12 | polar: # Replace with a single Polar username 13 | buy_me_a_coffee: # Replace with a single Buy Me a Coffee username 14 | thanks_dev: # Replace with a single thanks.dev username 15 | custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] 16 | -------------------------------------------------------------------------------- /Docs/Content/VersionHistory/v2025.9.12.0.md: -------------------------------------------------------------------------------- 1 | --- 2 | uid: f05af659-63c9-439b-8e07-3105f10cfb4a 3 | alt-uid: v2025-9-12-0 4 | title: Version 2025.9.12.0 5 | keywords: "versions, 2025.9.12.0" 6 | --- 7 | 8 | Changes made in this release: 9 | 10 | 11 | > [!IMPORTANT] 12 | > As of this release, only Visual Studio 2022 and later are supported. Support for Visual Studio 13 | > 2019 has been dropped. I do not use the older versions anymore, it will allow me to simplify the extension 14 | > projects and keep the package references more up to date without the risk of breaking the build, and implement 15 | > future features without regard to maintaining backward compatibility with the older versions. 16 | > 17 | > 18 | 19 | - Enabled installation on ARM64 PCs. 20 | - Enabled installation in Visual Studio 2026. 21 | 22 | 23 | 24 | ## See Also 25 | 26 | 27 | **Other Resources** 28 | [](@caa20db4-521f-4c4c-8399-aea8a81ae6a7) 29 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Welcome to the **Extended XML Documentation Comments Completion Provider** project. 2 | 3 | * [Get the current release](https://github.com/EWSoftware/ExtendedDocCommentsProvider/releases) 4 | * [Ask a question or open an issue](https://github.com/EWSoftware/ExtendedDocCommentsProvider/issues) 5 | * [Getting Started](https://ewsoftware.github.io/ExtendedDocCommentsProvider/html/141160ac-ba6a-4f6d-a802-1110aadea932.htm) 6 | * [System Requirements and Building the Code](https://ewsoftware.github.io/ExtendedDocCommentsProvider/html/3BBB6221-417C-4F5C-B89A-563A8052CE35.htm) 7 | * [Contributing](https://ewsoftware.github.io/ExtendedDocCommentsProvider/html/C60519F2-A2F7-4EB1-883F-96C51073CEB3.htm) 8 | 9 | This project is an editor extension that augments the standard C# XML documentation comments elements with 10 | custom elements, attributes, and attribute values supported by the Sandcastle Help File Builder and other 11 | documentation tools. 12 | -------------------------------------------------------------------------------- /Docs/ContentLayout.content: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /Source/GlobalSuppressions.cs: -------------------------------------------------------------------------------- 1 | // This file is used by Code Analysis to maintain SuppressMessage 2 | // attributes that are applied to this project. 3 | // Project-level suppressions either have no target or are given 4 | // a specific target and scoped to a namespace, type, member, etc. 5 | 6 | using System.Diagnostics.CodeAnalysis; 7 | 8 | [assembly: SuppressMessage("Design", "CA1031:Do not catch general exception types", Justification = "", Scope = "member", Target = "~M:EWSoftware.CompletionProviders.CSharpXmlDocCommentsCompletionProvider.TriggerOnTypingLetters(Microsoft.CodeAnalysis.Options.OptionSet)~System.Boolean")] 9 | [assembly: SuppressMessage("Design", "CA1031:Do not catch general exception types", Justification = "", Scope = "member", Target = "~M:EWSoftware.CompletionProviders.CSharpXmlDocCommentsCompletionProvider.GetItemsAsync(Microsoft.CodeAnalysis.Document,System.Int32,Microsoft.CodeAnalysis.Completion.CompletionTrigger,System.Threading.CancellationToken)~System.Threading.Tasks.Task{System.Collections.Generic.IEnumerable{Microsoft.CodeAnalysis.Completion.CompletionItem}}")] 10 | -------------------------------------------------------------------------------- /Docs/Content/KnownIssues.md: -------------------------------------------------------------------------------- 1 | --- 2 | uid: b146cb94-e594-4462-9262-d5cdba76c331 3 | alt-uid: KnownIssues 4 | title: Known Issues 5 | keywords: known issues 6 | --- 7 | The following are some known issues. 8 | 9 | - Completion providers are additive. Each one returns a set of items to add to the completion list based on the 10 | current editor context. The providers are unaware of other providers and the items added by them. They cannot 11 | remove items from other providers or make decisions about what to add based on other items that may appear. 12 | 13 | As such, you will see completion items from the built-in XML comments completion provider that may not be 14 | appropriate. For example, you will see the standard set of inline elements inside of the `revisionHistory` 15 | element. The same issue can be seen with standard elements such as `list`. This provider does allow the 16 | definition of valid parent elements so it will not present the custom child elements in inappropriate contexts. 17 | - Only C# is supported right now. A provider for Visual Basic is planned for a later release. 18 | - The current set of extended elements, attributes, and values is currently fixed and cannot be 19 | changed. A future release will allow the items to be customized and additional user-defined elements to be 20 | added. 21 | 22 | ## See Also 23 | **Other Resources** 24 | [](@141160ac-ba6a-4f6d-a802-1110aadea932) 25 | -------------------------------------------------------------------------------- /Docs/Content/Installation.md: -------------------------------------------------------------------------------- 1 | --- 2 | uid: 102EF998-5094-482A-B708-9DA64C04C859 3 | alt-uid: Installation 4 | title: Installation Instructions and Usage Notes 5 | keywords: installation, usage 6 | --- 7 | 8 | To install this package: 9 | 10 | 11 | - Download the latest release of the VSIX installer for your version of Visual Studio from the 12 | [Releases](https://GitHub.com/EWSoftware/ExtendedDocCommentsProvider/releases) page of the project site. The package can be installed in Visual Studio 2019 or Visual Studio 13 | 2022 or later. 14 | - Close all open instances of Visual Studio before installing the package. 15 | - Run the downloaded package and follow the prompts to install it. 16 | 17 | 18 | This package can also be installed from within Visual Studio from the Visual Studio Marketplace 19 | ([Visual Studio 2019](https://marketplace.visualstudio.com/items?itemName=EWoodruff.ExtendedDocCommentsProvider) or 20 | [Visual Studio 2022 or later](https://marketplace.visualstudio.com/items?itemName=EWoodruff.ExtendedDocCommentsProvider2022)) using the **Tools | Extension and Updates** option. Select the online marketplace and 21 | search for "doc comments provider". Include the quote marks for an exact match and find the one created by 22 | *EWSoftware*. Once found, you can click the **Download** button to download and 23 | install it. 24 | 25 | 26 | Once installed, the extended elements, attributes, and attribute values will be provided in the 27 | completion popup list in the source code editor when entering XML comments. 28 | 29 | 30 | 31 | ## See Also 32 | 33 | 34 | **Other Resources** 35 | [](@141160ac-ba6a-4f6d-a802-1110aadea932) 36 | -------------------------------------------------------------------------------- /Source/ElementUsage.cs: -------------------------------------------------------------------------------- 1 | //=============================================================================================================== 2 | // System : Extended Doc Comments Completion Provider Package 3 | // File : ElementUsage.cs 4 | // Author : Eric Woodruff (Eric@EWoodruff.us) 5 | // Updated : 10/21/2019 6 | // Note : Copyright 2019, Eric Woodruff, All rights reserved 7 | // 8 | // This file contains the enumerated type that defines comment element usage types 9 | // 10 | // This code is published under the Microsoft Public License (Ms-PL). A copy of the license should be 11 | // distributed with the code and can be found at the project website: 12 | // https://github.com/EWSoftware/ExtendedDocCommentsProvider. This notice, the author's name, and all copyright 13 | // notices must remain intact in all applications, documentation, and source files. 14 | // 15 | // Date Who Comments 16 | // ============================================================================================================== 17 | // 10/18/2019 EFW Created the code 18 | //=============================================================================================================== 19 | 20 | using System; 21 | 22 | namespace EWSoftware.CompletionProviders 23 | { 24 | /// 25 | /// This enumerated type defines comment element usage types 26 | /// 27 | [Serializable] 28 | public enum ElementUsage 29 | { 30 | /// 31 | /// Top-level only 32 | /// 33 | TopLevel = 0, 34 | /// 35 | /// Nested only 36 | /// 37 | Nested = 1, 38 | /// 39 | /// Can be top-level or nested 40 | /// 41 | Both = 2 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | 4 | # User-specific files 5 | *.suo 6 | *.user 7 | *.userosscache 8 | *.sln.docstates 9 | StyleCop.Cache 10 | _ReSharper*/ 11 | *.[Rr]e[Ss]harper 12 | *.DotSettings.user 13 | launchSettings.json 14 | 15 | # Build results 16 | [Dd]ebug/ 17 | [Dd]ebugPublic/ 18 | [Rr]elease/ 19 | [Rr]eleases/ 20 | x64/ 21 | x86/ 22 | build/ 23 | bld/ 24 | [Bb]in/ 25 | [Oo]bj/ 26 | 27 | # Roslyn cache directories 28 | *.vs/ 29 | 30 | # Visual Studio profiler 31 | *.psess 32 | *.vsp 33 | *.vspx 34 | 35 | # Sandcastle Help File Builder is a documentation generator add-in 36 | Documentation/**/Help/ 37 | Documentation/WebHelp/ 38 | **/Doc/Help/ 39 | **/Docs/Help/ 40 | *.shfbproj_* 41 | 42 | # Publish Web Output 43 | *.[Pp]ublish.xml 44 | *.pubxml 45 | *.publishproj 46 | **/PrecompiledWeb 47 | 48 | # NuGet Packages 49 | *.nupkg 50 | # The packages folder can be ignored because of Package Restore 51 | **/packages/* 52 | *.lock.json 53 | 54 | # Others 55 | ~$* 56 | *~ 57 | *.publishsettings 58 | *CodeAnalysisLog.xml 59 | WebProject.lastcodeanalysissucceeded 60 | 61 | # Backup & report files from converting an old project file 62 | # to a newer Visual Studio version. Backup files are not needed, 63 | # because we have git ;-) 64 | _UpgradeReport_Files/ 65 | Backup*/ 66 | UpgradeLog*.XML 67 | UpgradeLog*.htm 68 | 69 | # Non-distributable and private local stuff 70 | Deployment/ 71 | NonDist/ 72 | 73 | # ========================= 74 | # Operating System Files 75 | # ========================= 76 | 77 | # Windows 78 | # ========================= 79 | 80 | # Windows image file caches 81 | Thumbs.db 82 | ehthumbs.db 83 | 84 | # Folder config file 85 | Desktop.ini 86 | 87 | # Recycle Bin used on file shares 88 | $RECYCLE.BIN/ 89 | 90 | # Windows Installer files 91 | *.cab 92 | *.msi 93 | *.msm 94 | *.msp 95 | 96 | # Windows shortcuts 97 | *.lnk 98 | -------------------------------------------------------------------------------- /Docs/Content/SystemRequirements.md: -------------------------------------------------------------------------------- 1 | --- 2 | uid: 3BBB6221-417C-4F5C-B89A-563A8052CE35 3 | alt-uid: SystemRequirements 4 | title: System Requirements and Building the Code 5 | keywords: system requirements 6 | --- 7 | The master branch is for Visual Studio 2019 and later and is the default branch for all current and future 8 | development. In order to build the projects you will need Visual Studio 2019 or later. 9 | 10 | ## Folder Layout 11 | *.\Source* - This folder contains the source code for all of the projects. 12 | 13 | *.\Docs* - The [Sandcastle Help File Builder](https://GitHub.com/EWSoftware/SHFB) project used to manage the 14 | extended documentation comments provider project's documentation. 15 | 16 | *.\Deployment* - This folder contains the deployment resources (the installer and all related files) generated 17 | by building the projects. 18 | 19 | ## Building and Debugging the Projects 20 | To build the projects, open the solution file (*\*.sln*) for your version of Visual Studio (currently 2019 or 21 | 2022) found in the *Source\\* folder and build it. You can also run the *MasterBuild.bat* script from a command 22 | prompt to build the projects. 23 | 24 | In order to debug the projects: 25 | 26 | - Set the *ExtendedDocCommentsProvider* project as the default project and then open its project properties. 27 | - Go to the **Debug** category. 28 | - For the **Start Action** option, set it to **Start external program**, click the "..." button after the text 29 | box, navigate to the installation folder for your version of Visual Studio and select the *devenv.exe* file in 30 | that folder (i.e. *C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\Common7\IDE\devenv.exe*). 31 | - For the **Command line arguments** option, enter the value `/rootsuffix Exp`. 32 | - When you run the project, it should start a new instance of Visual Studio using the experimental instance 33 | settings. 34 | 35 | ## See Also 36 | **Other Resources** 37 | [](@141160ac-ba6a-4f6d-a802-1110aadea932) 38 | [License Agreement](https://github.com/EWSoftware/ExtendedDocCommentsProvider/blob/master/LICENSE) 39 | -------------------------------------------------------------------------------- /Source/source.extension.vsixmanifest: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Extended XML Doc Comments Provider (VS2022+) 6 | An editor extension that augments the standard C# XML documentation comments elements with custom elements, attributes, and attribute values supported by the Sandcastle Help File Builder and other documentation tools. 7 | https://github.com/EWSoftware/ExtendedDocCommentsProvider 8 | License.rtf 9 | https://ewsoftware.github.io/ExtendedDocCommentsProvider/html/102EF998-5094-482A-B708-9DA64C04C859.htm 10 | https://ewsoftware.github.io/ExtendedDocCommentsProvider/html/caa20db4-521f-4c4c-8399-aea8a81ae6a7.htm 11 | VSIXPackage.png 12 | VSIXPreview.png 13 | documentation;comments;completion provider;sandcastle;shfb;help file builder 14 | 15 | 16 | 17 | amd64 18 | 19 | 20 | arm64 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Microsoft Public License (Ms-PL) 2 | 3 | This license governs use of the accompanying software. If you use the 4 | software, you accept this license. If you do not accept the license, do not 5 | use the software. 6 | 7 | 1. Definitions 8 | 9 | The terms "reproduce," "reproduction," "derivative works," and "distribution" 10 | have the same meaning here as under U.S. copyright law. 11 | 12 | A "contribution" is the original software, or any additions or changes to the 13 | software. 14 | 15 | A "contributor" is any person that distributes its contribution under this 16 | license. 17 | 18 | "Licensed patents" are a contributor's patent claims that read directly on its 19 | contribution. 20 | 21 | 2. Grant of Rights 22 | 23 | (A) Copyright Grant- Subject to the terms of this license, including the 24 | license conditions and limitations in section 3, each contributor grants you a 25 | non-exclusive, worldwide, royalty-free copyright license to reproduce its 26 | contribution, prepare derivative works of its contribution, and distribute its 27 | contribution or any derivative works that you create. 28 | 29 | (B) Patent Grant- Subject to the terms of this license, including the license 30 | conditions and limitations in section 3, each contributor grants you a 31 | non-exclusive, worldwide, royalty-free license under its licensed patents to 32 | make, have made, use, sell, offer for sale, import, and/or otherwise dispose 33 | of its contribution in the software or derivative works of the contribution in 34 | the software. 35 | 36 | 3. Conditions and Limitations 37 | 38 | (A) No Trademark License- This license does not grant you rights to use any 39 | contributors' name, logo, or trademarks. 40 | 41 | (B) If you bring a patent claim against any contributor over patents that you 42 | claim are infringed by the software, your patent license from such contributor 43 | to the software ends automatically. 44 | 45 | (C) If you distribute any portion of the software, you must retain all 46 | copyright, patent, trademark, and attribution notices that are present in the 47 | software. 48 | 49 | (D) If you distribute any portion of the software in source code form, you may 50 | do so only under this license by including a complete copy of this license 51 | with your distribution. If you distribute any portion of the software in 52 | compiled or object code form, you may only do so under a license that complies 53 | with this license. 54 | 55 | (E) The software is licensed "as-is." You bear the risk of using it. The 56 | contributors give no express warranties, guarantees or conditions. You may 57 | have additional consumer rights under your local laws which this license 58 | cannot change. To the extent permitted under your local laws, the contributors 59 | exclude the implied warranties of merchantability, fitness for a particular 60 | purpose and non-infringement. 61 | -------------------------------------------------------------------------------- /Docs/Content/Contributing.md: -------------------------------------------------------------------------------- 1 | --- 2 | uid: C60519F2-A2F7-4EB1-883F-96C51073CEB3 3 | alt-uid: Contributing 4 | title: Contributing 5 | keywords: Contributing 6 | --- 7 | 8 | 9 | 10 | 11 | ## Issues 12 | If you don't feel like working on the code yourself, 13 | [filing an issue](https://github.com/EWSoftware/ExtendedDocCommentsProvider/issues "Extended Doc Comments Provider Issues") 14 | and letting me handle the change is fine. You don't need to file an issue for trivial changes (i.e. typos, minor 15 | fixes, etc.). Just send a pull request if it's small. 16 | 17 | If an issue is complex, adds or removes functionality, changes existing behavior, etc. consider filing an issue 18 | and giving me time to respond before sending a corresponding pull request. If you want to work on the issue, 19 | just let it be known on the issue thread. Giving me a chance to review the issue will help save time and 20 | prevents you from wasting time on something that cannot be implemented. For example, I might let you know why 21 | existing behavior cannot be changed or about particular implementation constraints you need to keep in mind, etc. 22 | 23 | ## Contributing to the Project 24 | 1. Unless it is a trivial change such as a typo or minor fix, make sure that there is a corresponding issue for 25 | your change first. If there isn't, create one. 26 | 2. Create a fork in GitHub 27 | 3. Create a branch off the master branch. Name it something that makes sense, such as *issue-123* or 28 | *githubUserID-issue*. This makes it easy for everyone to figure out what the branch is used for. It also 29 | makes it easier to isolate your changes from incoming changes from the origin. 30 | 4. Commit your changes and push your changes to GitHub. 31 | 5. Create a pull request against the origin's master branch. 32 | 33 | ## Coding Style 34 | In general, use the Visual Studio defaults. Take a look at the existing code to see the styles in use. The 35 | *.editorconfig* file defines the preferred style defaults. 36 | 37 | 1. In source code, use four spaces for indentation, no tabs. 38 | 2. For XML, XAML, HTML, and similar file types, use two spaces for indentation and do use tabs. 39 | 3. Namespace imports should be specified at the top of the file, outside of the `namespace` declaration, and 40 | should be sorted alphabetically. Place `System.` namespaces at the top and blank lines between different top 41 | level groups. Remove any unused namespaces to avoid unnecessary clutter. 42 | 4. Use Allman style braces where each brace begins on a new line. A single line statement block can go without 43 | braces but the block must be properly indented on its own line. 44 | 5. Do not insert spaces after keywords in control flow statements (use `if(a < b)` instead of `if (a < b)`). 45 | 6. Use `camelCase` private members without leading underscores or other such prefixes like `m_`. 46 | 7. Always specify the visibility even if it is the default (i.e. `private string foo` not `string foo`). 47 | 48 | ## See Also 49 | **Other Resources** 50 | [](@141160ac-ba6a-4f6d-a802-1110aadea932) 51 | [License Agreement](https://github.com/EWSoftware/ExtendedDocCommentsProvider/blob/master/LICENSE) 52 | -------------------------------------------------------------------------------- /Source/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | //=============================================================================================================== 2 | // System : Extended Doc Comments Completion Provider Package 3 | // File : AssemblyInfo.cs 4 | // Author : Eric Woodruff (Eric@EWoodruff.us) 5 | // Updated : 09/12/2025 6 | // Note : Copyright 2019-2025, Eric Woodruff, All rights reserved 7 | // 8 | // Extended documentation comments completion provider package attributes 9 | // 10 | // This code is published under the Microsoft Public License (Ms-PL). A copy of the license should be 11 | // distributed with the code and can be found at the project website: 12 | // https://github.com/EWSoftware/ExtendedDocCommentsProvider. This notice, the author's name, and all copyright 13 | // notices must remain intact in all applications, documentation, and source files. 14 | // 15 | // Date Who Comments 16 | // ============================================================================================================== 17 | // 10/22/2019 EFW Created the code 18 | //=============================================================================================================== 19 | 20 | using System; 21 | using System.Reflection; 22 | using System.Resources; 23 | using System.Runtime.InteropServices; 24 | 25 | // General assembly information 26 | [assembly: AssemblyProduct("Extended Doc Comments Completion Provider Package")] 27 | [assembly: AssemblyTitle("Extended Doc Comments Completion Provider Package")] 28 | [assembly: AssemblyDescription("An editor extension that augments the standard C# XML documentation comments " + 29 | "elements with custom elements, attributes, and attribute values supported by the Sandcastle Help File " + 30 | "Builder and other documentation tools")] 31 | [assembly: AssemblyCompany("Eric Woodruff")] 32 | [assembly: AssemblyCopyright("Copyright \xA9 2019-2025, Eric Woodruff, All Rights Reserved")] 33 | [assembly: AssemblyCulture("")] 34 | #if DEBUG 35 | [assembly: AssemblyConfiguration("Debug")] 36 | #else 37 | [assembly: AssemblyConfiguration("Release")] 38 | #endif 39 | 40 | // This assembly is not CLS compliant 41 | [assembly: CLSCompliant(false)] 42 | 43 | // Not visible to COM 44 | [assembly: ComVisible(false)] 45 | 46 | // Resources contained within the assembly are English 47 | [assembly: NeutralResourcesLanguage("en")] 48 | 49 | // Version numbers. All version numbers for an assembly consists of the following four values: 50 | // 51 | // Year of release 52 | // Month of release 53 | // Day of release 54 | // Revision (typically zero unless multiple releases are made on the same day) 55 | // 56 | 57 | // Common assembly strong name version - Typically not change unless necessary but doesn't apply to this project 58 | // as it is self-contained and is not referenced by anything else. Keep it in sync with the versions below. 59 | [assembly: AssemblyVersion("2025.9.12.0")] 60 | 61 | // Common assembly file version 62 | // 63 | // This is used to set the assembly file version. This will change with each new release. MSIs only support a 64 | // Major value between 0 and 255 so we drop the century from the year on this one. 65 | [assembly: AssemblyFileVersion("25.9.12.0")] 66 | 67 | // Common product version 68 | // 69 | // This may contain additional text to indicate Alpha or Beta states. The version number will always match the 70 | // file version above but includes the century on the year. 71 | [assembly: AssemblyInformationalVersion("2025.9.12.0")] 72 | -------------------------------------------------------------------------------- /Docs/Content/Welcome.md: -------------------------------------------------------------------------------- 1 | --- 2 | uid: 141160ac-ba6a-4f6d-a802-1110aadea932 3 | alt-uid: Welcome 4 | title: Welcome 5 | keywords: Welcome 6 | --- 7 | 8 | 9 | Welcome to the **Extended XML Documentation Comments Completion Provider** project. 10 | 11 | This project is a Visual Studio editor extension that augments the standard C# XML documentation comments 12 | elements with custom elements, attributes, and attribute values supported by the Sandcastle Help File Builder and 13 | other documentation tools. The following elements, attributes, and attribute values are provided: 14 | 15 | | Elements | Attributes | Attribute Values | 16 | | --- | --- | --- | 17 | | AttachedEventComments |   |   | 18 | | AttachedPropertyComments |   |   | 19 | | code | language | cs, cpp, c, fs, javascript, vb, vbnet, html, xml, xsl, xaml, sql, py, pshell, bat, none | 20 | |   | title |   | 21 | |   | source |   | 22 | |   | region |   | 23 | |   | removeRegionMarkers | true, false | 24 | |   | tabSize |   | 25 | |   | numberLines | true, false | 26 | |   | outlining | true, false | 27 | |   | keepSeeTags | true, false | 28 | | conceptualLink |   |   | 29 | | event |   |   | 30 | | list | type | definition | 31 | |   | start |   | 32 | | note | type | note, tip, implement, caller, inherit, caution, warning, important, security, cs, cpp, vb, todo | 33 | |   | title |   | 34 | | overloads |   |   | 35 | | preliminary |   |   | 36 | | revisionHistory | visible | true, false | 37 | | revision | date |   | 38 | |   | version |   | 39 | |   | author |   | 40 | |   | visible | true, false | 41 | | see/seealso | qualifyHint | true, false | 42 | |   | autoUpgrade | true, false | 43 | |   | href |   | 44 | |   | alt |   | 45 | |   | target | _blank, _self, _parent, _top | 46 | | threadsafety | static | true, false | 47 | |   | instance | true, false | 48 | | token |   |   | 49 | 50 | For information on the above elements and all other XML comments elements, see the 51 | [Sandcastle XML Comments Guide](https://EWSoftware.github.io/XMLCommentsGuide/index.html "Sandcastle XML Comments Guide"). 52 | 53 | ## Making a Donation 54 | If you would like to support this project, you can make a donation of any amount you like by clicking on the 55 | PayPal donation button below. Another option is to click the **Sponsor** button in the page footer to sponsor 56 | the project on GitHub with either a one-time or monthly amount. 57 | 58 | [![Make donations with PayPal - It's fast, free and secure!](@PayPal)](https://www.paypal.com/donate/?hosted_button_id=QK8P2B8B5WBJ2 "Make a donation") 59 | 60 | Thanks to those of you that have made a donation. It is much appreciated! 61 | 62 | ## See Also 63 | **Other Resources** 64 | [](@102EF998-5094-482A-B708-9DA64C04C859) 65 | [](@caa20db4-521f-4c4c-8399-aea8a81ae6a7) 66 | [License Agreement](https://github.com/EWSoftware/ExtendedDocCommentsProvider/blob/master/LICENSE) 67 | -------------------------------------------------------------------------------- /Source/ElementAttribute.cs: -------------------------------------------------------------------------------- 1 | //=============================================================================================================== 2 | // System : Extended Doc Comments Completion Provider Package 3 | // File : ElementAttribute.cs 4 | // Author : Eric Woodruff (Eric@EWoodruff.us) 5 | // Updated : 10/21/2019 6 | // Note : Copyright 2019, Eric Woodruff, All rights reserved 7 | // 8 | // This file contains the class used to define XML documentation comments element attributes and their values 9 | // 10 | // This code is published under the Microsoft Public License (Ms-PL). A copy of the license should be 11 | // distributed with the code and can be found at the project website: 12 | // https://github.com/EWSoftware/ExtendedDocCommentsProvider. This notice, the author's name, and all copyright 13 | // notices must remain intact in all applications, documentation, and source files. 14 | // 15 | // Date Who Comments 16 | // ============================================================================================================== 17 | // 10/18/2019 EFW Created the code 18 | //=============================================================================================================== 19 | 20 | using System; 21 | using System.Collections.Generic; 22 | using System.Linq; 23 | 24 | namespace EWSoftware.CompletionProviders 25 | { 26 | /// 27 | /// This is used to define element attributes and their values 28 | /// 29 | public class ElementAttribute 30 | { 31 | #region Properties 32 | //===================================================================== 33 | 34 | /// 35 | /// The attribute name 36 | /// 37 | public string Name { get; set; } 38 | 39 | /// 40 | /// An optional description to show when the completion item is selected in the completion popup list 41 | /// 42 | /// If not set, no description will be shown 43 | public string Description { get; set; } 44 | 45 | public IEnumerable Values { get; } 46 | 47 | #endregion 48 | 49 | #region Constructors 50 | //===================================================================== 51 | 52 | /// 53 | /// Constructor for an attribute with no provided attribute values 54 | /// 55 | /// There are two overloads for the constructor 56 | public ElementAttribute() : this(null) 57 | { 58 | } 59 | 60 | /// 61 | /// Constructor for an attribute with provided attribute values 62 | /// 63 | /// An enumerable list of values or null if there are none 64 | public ElementAttribute(IEnumerable values) 65 | { 66 | this.Values = values ?? Enumerable.Empty(); 67 | } 68 | #endregion 69 | 70 | #region Method overrides 71 | //===================================================================== 72 | 73 | /// 74 | /// This is overridden to compare element attributes by name 75 | /// 76 | /// The object to compare 77 | /// True if equal by attribute name, false if not 78 | public override bool Equals(object obj) 79 | { 80 | return (obj is ElementAttribute attr && attr.Name.Equals(this.Name, StringComparison.Ordinal)); 81 | } 82 | 83 | /// 84 | public override int GetHashCode() 85 | { 86 | return this.Name.GetHashCode(); 87 | } 88 | #endregion 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /Source/SyntaxExtensions.cs: -------------------------------------------------------------------------------- 1 | //=============================================================================================================== 2 | // System : Extended Doc Comments Completion Provider Package 3 | // File : SyntaxExtensions.cs 4 | // Author : Eric Woodruff (Eric@EWoodruff.us) 5 | // Updated : 10/21/2019 6 | // Note : Copyright 2019, Eric Woodruff, All rights reserved 7 | // 8 | // This file contains various syntax element extension methods 9 | // 10 | // This code is published under the Microsoft Public License (Ms-PL). A copy of the license should be 11 | // distributed with the code and can be found at the project website: 12 | // https://github.com/EWSoftware/ExtendedDocCommentsProvider. This notice, the author's name, and all copyright 13 | // notices must remain intact in all applications, documentation, and source files. 14 | // 15 | // Date Who Comments 16 | // ============================================================================================================== 17 | // 10/09/2019 EFW Created the code 18 | //=============================================================================================================== 19 | 20 | using System.Threading; 21 | 22 | using Microsoft.CodeAnalysis; 23 | 24 | namespace EWSoftware.CompletionProviders 25 | { 26 | /// 27 | /// This class contains various syntax element extension methods 28 | /// 29 | internal static class SyntaxExtensions 30 | { 31 | /// 32 | /// If the position is inside of a token, return that token. Otherwise, return the token to the left. 33 | /// 34 | /// The syntax tree to search 35 | /// The position to find 36 | /// A cancellation token used to cancel the operation 37 | public static SyntaxToken FindTokenOnLeftOfPosition(this SyntaxTree syntaxTree, int position, 38 | CancellationToken cancellationToken) 39 | { 40 | var root = syntaxTree.GetRoot(cancellationToken); 41 | var token = (position < root.FullSpan.End || !(root is ICompilationUnitSyntax)) ? root.FindToken(position, true) : 42 | root.GetLastToken(true, true, true, true).GetPreviousToken(false, true, false, false); 43 | 44 | if(position <= token.SpanStart) 45 | { 46 | do 47 | { 48 | var skippedToken = FindSkippedTokenBackward(token.LeadingTrivia, position); 49 | token = skippedToken.RawKind != 0 ? skippedToken : token.GetPreviousToken(false, true, false, false); 50 | 51 | } while(position <= token.SpanStart && root.FullSpan.Start < token.SpanStart); 52 | } 53 | else 54 | if(token.Span.End < position) 55 | { 56 | var skippedToken = FindSkippedTokenBackward(token.TrailingTrivia, position); 57 | token = skippedToken.RawKind != 0 ? skippedToken : token; 58 | } 59 | 60 | if(token.Span.Length == 0) 61 | token = token.GetPreviousToken(); 62 | 63 | return token; 64 | } 65 | 66 | /// 67 | /// Look inside a trivia list for a skipped token that contains the given position 68 | /// 69 | /// The syntax trivia list to search 70 | /// The position to find 71 | private static SyntaxToken FindSkippedTokenBackward(SyntaxTriviaList triviaList, int position) 72 | { 73 | foreach(var trivia in triviaList.Reverse()) 74 | { 75 | if(trivia.HasStructure && trivia.GetStructure() is ISkippedTokensTriviaSyntax skippedTokensTrivia) 76 | { 77 | foreach(var token in skippedTokensTrivia.Tokens) 78 | { 79 | if(token.Span.Length > 0 && token.SpanStart <= position) 80 | return token; 81 | } 82 | } 83 | } 84 | 85 | return default; 86 | } 87 | 88 | /// 89 | /// This is used to get the ancestor or a syntax node matching a specified type 90 | /// 91 | /// The node type to match 92 | /// The starting node 93 | /// The ancestor node of the specified type if found, null if not found 94 | public static TNode GetAncestor(this SyntaxNode node) where TNode : SyntaxNode 95 | { 96 | var current = node.Parent; 97 | 98 | while(current != null) 99 | { 100 | if(current is TNode tNode) 101 | return tNode; 102 | 103 | var parent = current.Parent; 104 | 105 | if(parent == null && current is IStructuredTriviaSyntax structuredTrivia) 106 | parent = structuredTrivia.ParentTrivia.Token.Parent; 107 | 108 | current = parent; 109 | } 110 | 111 | return null; 112 | } 113 | } 114 | } 115 | -------------------------------------------------------------------------------- /Source/ExtendedDocCommentsProvider.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 16.0 5 | $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) 6 | 7 | 8 | true 9 | 10 | 11 | ExtendedDocCommentsProvider.snk 12 | 13 | 14 | true 15 | bin\Debug\ 16 | DEBUG;TRACE 17 | full 18 | AnyCPU 19 | 7.3 20 | prompt 21 | 22 | 23 | 24 | Debug 25 | AnyCPU 26 | 2.0 27 | {82b43b9b-a64c-4715-b499-d71e9ca2bd60};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} 28 | {AC787F6B-6FB3-4F84-B8AE-26252450F07C} 29 | Library 30 | Properties 31 | EWSoftware.CompletionProviders 32 | ExtendedDocCommentsProvider 33 | v4.7.2 34 | false 35 | true 36 | false 37 | false 38 | true 39 | true 40 | Program 41 | $(DevEnvDir)devenv.exe 42 | /rootsuffix Exp 43 | true 44 | AllEnabledByDefault 45 | 46 | 47 | true 48 | full 49 | false 50 | bin\Debug\ 51 | DEBUG;TRACE 52 | prompt 53 | 4 54 | False 55 | 56 | 57 | pdbonly 58 | true 59 | bin\Release\ 60 | TRACE 61 | prompt 62 | 4 63 | False 64 | 65 | 66 | 67 | PreserveNewest 68 | true 69 | 70 | 71 | 72 | Designer 73 | 74 | 75 | 76 | 77 | 4.14.0 78 | 79 | 80 | 4.14.0 81 | 82 | 83 | 4.14.0 84 | 85 | 86 | compile; build; native; contentfiles; analyzers; buildtransitive 87 | 88 | 89 | runtime; build; native; contentfiles; analyzers; buildtransitive 90 | all 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | true 106 | PreserveNewest 107 | 108 | 109 | true 110 | PreserveNewest 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | IF NOT "$(ConfigurationName)"=="Release" Goto Exit 120 | 121 | IF NOT EXIST "$(SolutionDir)..\Deployment\" MD "$(SolutionDir)..\Deployment\" 122 | 123 | Copy "$(TargetDir)$(TargetName).vsix" "$(SolutionDir)Deployment\$(TargetName).vsix" 124 | 125 | :Exit 126 | 127 | 128 | 135 | -------------------------------------------------------------------------------- /Docs/ExtendedDocCommentsProviderDocs.shfbproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | v4.7.2 6 | 8 | Debug 9 | AnyCPU 10 | 2.0 11 | a405f2b6-a092-4dea-bc1e-4b9435e1b94f 12 | 2017.9.26.0 13 | 14 | ExtendedDocCommentsProviderDocs 15 | ExtendedDocCommentsProviderDocs 16 | ExtendedDocCommentsProviderDocs 17 | 18 | .NET Framework 4.8 19 | .\Help\ 20 | ExtendedDocCommentsProvider 21 | en-US 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | Website 87 | Standard 88 | Default2022 89 | True 90 | True 91 | False 92 | False 93 | OnlyWarningsAndErrors 94 | 100 95 | Extended XML Documentation Comments Provider 96 | 2025.9.12.0 97 | Guid 98 | AboveNamespaces 99 | False 100 | False 101 | 2 102 | False 103 | https://GitHub.com/EWSoftware/ExtendedDocCommentsProvider 104 | Copyright \xA9 2019-2025, Eric Woodruff, All rights reserved 105 | Eric%40EWoodruff.us 106 | Blank 107 | Msdn 108 | True 109 | False 110 | Msdn 111 | &lt%3biframe src=&quot%3bhttps://github.com/sponsors/EWSoftware/button&quot%3b title=&quot%3bSponsor EWSoftware&quot%3b height=&quot%3b32&quot%3b width=&quot%3b114&quot%3b style=&quot%3bborder: 0%3b border-radius: 6px%3b&quot%3b&gt%3b&lt%3b/iframe&gt%3b 112 | 113 | False 114 | 115 | 116 | 117 | 118 | 119 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | PayPal 161 | Pay Pal 162 | True 163 | 164 | 165 | 166 | 167 | 169 | 170 | 171 | 172 | 173 | 174 | OnBuildSuccess 175 | 176 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | [*] 2 | # Don't use tabs for indentation unless otherwise overridden 3 | indent_style = space 4 | end_of_line = crlf 5 | guidelines = 80 dotted, 114 dotted 6 | # (Please don't specify an indent_size here; that has too many unintended consequences.) 7 | 8 | # VSSPELL: Spell checker settings for all files 9 | vsspell_code_analyzer_ignore_identifier_if_private = true 10 | vsspell_code_analyzer_ignore_identifier_if_internal = true 11 | vsspell_code_analyzer_ignore_identifier_if_all_uppercase = true 12 | vsspell_code_analyzer_ignore_identifiers_within_member_bodies = true 13 | vsspell_code_analyzer_ignore_if_compiler_generated = true 14 | vsspell_code_analyzer_ignore_delimited_comments = true 15 | vsspell_code_analyzer_ignore_quadruple_slash_comments = true 16 | vsspell_code_analyzer_apply_to_all_c_style_languages = true 17 | 18 | [*.{aml,asax,ascx,asmx,asp,aspx,axml,config,content,cshtml,csproj,database,datasource,dbml,disco,discomap,dtsx,edmx,exclude,fxcop,htm,html,items,layout,maml,manifest,master,msha,myapp,nunit,nuspec,proj,projitems,props,publishproj,pubxml,rdl,rdlc,resx,ruleset,settings,shfbproj,shproj,sitemap,snippets,soap,svc,svcinfo,svcmap,targets,tasks,tokens,vbhtml,vbproj,vcxproj,vcxproj.filters,vsct,vsixmanifest,vstemplate,webinfo,wsdl,xaml,xamlcfg,xml,xsd,xsl,xslt,xsx}] 19 | # XML files of various types 20 | indent_style = tab 21 | indent_size = 2 22 | tab_width = 2 23 | 24 | [*.{cs,vb}] 25 | # C#/VB settings 26 | indent_size = 4 27 | tab_width = 4 28 | 29 | dotnet_sort_system_directives_first = true 30 | 31 | # Naming rules 32 | dotnet_naming_rule.interface_should_be_begins_with_i.severity = suggestion 33 | dotnet_naming_rule.interface_should_be_begins_with_i.symbols = interface 34 | dotnet_naming_rule.interface_should_be_begins_with_i.style = begins_with_i 35 | 36 | dotnet_naming_rule.types_should_be_pascal_case.severity = suggestion 37 | dotnet_naming_rule.types_should_be_pascal_case.symbols = types 38 | dotnet_naming_rule.types_should_be_pascal_case.style = pascal_case 39 | 40 | dotnet_naming_rule.non_field_members_should_be_pascal_case.severity = suggestion 41 | dotnet_naming_rule.non_field_members_should_be_pascal_case.symbols = non_field_members 42 | dotnet_naming_rule.non_field_members_should_be_pascal_case.style = pascal_case 43 | 44 | # Symbol specifications 45 | dotnet_naming_symbols.interface.applicable_kinds = interface 46 | dotnet_naming_symbols.interface.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected 47 | dotnet_naming_symbols.interface.required_modifiers = 48 | 49 | dotnet_naming_symbols.types.applicable_kinds = class, struct, interface, enum 50 | dotnet_naming_symbols.types.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected 51 | dotnet_naming_symbols.types.required_modifiers = 52 | 53 | dotnet_naming_symbols.non_field_members.applicable_kinds = property, event, method 54 | dotnet_naming_symbols.non_field_members.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected 55 | dotnet_naming_symbols.non_field_members.required_modifiers = 56 | 57 | # Naming styles 58 | dotnet_naming_style.begins_with_i.required_prefix = I 59 | dotnet_naming_style.begins_with_i.required_suffix = 60 | dotnet_naming_style.begins_with_i.word_separator = 61 | dotnet_naming_style.begins_with_i.capitalization = pascal_case 62 | 63 | dotnet_naming_style.pascal_case.required_prefix = 64 | dotnet_naming_style.pascal_case.required_suffix = 65 | dotnet_naming_style.pascal_case.word_separator = 66 | dotnet_naming_style.pascal_case.capitalization = pascal_case 67 | 68 | dotnet_naming_style.pascal_case.required_prefix = 69 | dotnet_naming_style.pascal_case.required_suffix = 70 | dotnet_naming_style.pascal_case.word_separator = 71 | dotnet_naming_style.pascal_case.capitalization = pascal_case 72 | 73 | # Code style settings 74 | dotnet_style_predefined_type_for_locals_parameters_members = true:none 75 | dotnet_style_predefined_type_for_member_access = false:error 76 | dotnet_style_coalesce_expression = true:suggestion 77 | dotnet_style_collection_initializer = true:suggestion 78 | dotnet_style_explicit_tuple_names = true:error 79 | dotnet_style_null_propagation = true:suggestion 80 | dotnet_style_object_initializer = true:suggestion 81 | dotnet_style_prefer_is_null_check_over_reference_equality_method = true:suggestion 82 | dotnet_style_prefer_auto_properties = true:silent 83 | dotnet_style_prefer_simplified_boolean_expressions = true:suggestion 84 | dotnet_style_prefer_conditional_expression_over_assignment = true:silent 85 | dotnet_style_prefer_conditional_expression_over_return = true:silent 86 | dotnet_style_prefer_inferred_tuple_names = true:suggestion 87 | dotnet_style_prefer_inferred_anonymous_type_member_names = true:suggestion 88 | dotnet_style_prefer_compound_assignment = true:suggestion 89 | dotnet_style_prefer_simplified_interpolation = true:suggestion 90 | dotnet_style_namespace_match_folder = true:suggestion 91 | dotnet_style_operator_placement_when_wrapping = beginning_of_line 92 | 93 | # "This." and "Me." qualification. Use is preferred where true but the lightbulbs tend to show up in places 94 | # they aren't wanted (within static methods and nameof parameters etc.) so no suggestions are enabled. 95 | dotnet_style_qualification_for_event = true:none 96 | dotnet_style_qualification_for_field = false:none 97 | dotnet_style_qualification_for_method = true:none 98 | dotnet_style_qualification_for_property = true:none 99 | 100 | # Code analyzer settings 101 | # CA1303: Do not pass literals as localized parameters 102 | dotnet_diagnostic.CA1303.severity = none 103 | 104 | # IDE0010: Add missing cases 105 | dotnet_diagnostic.IDE0010.severity = none 106 | 107 | # IDE1006: Naming Styles 108 | dotnet_diagnostic.IDE1006.severity = none 109 | 110 | # These are disabled as we're still targeting .NET Framework as well and I don't want a lot of conditional code 111 | # to suppress these or I'm not ready to use them just yet. 112 | # IDE0056: Use index operator 113 | dotnet_diagnostic.IDE0056.severity = none 114 | 115 | # IDE0057: Use range operator 116 | dotnet_diagnostic.IDE0057.severity = none 117 | 118 | # IDE0066: Convert switch statement to expression 119 | dotnet_diagnostic.IDE0066.severity = none 120 | 121 | # CA1510: Use ArgumentNullException throw helper 122 | dotnet_diagnostic.CA1510.severity = none 123 | 124 | # CA1845: Use span-based 'string.Concat' 125 | dotnet_diagnostic.CA1845.severity = none 126 | 127 | # CA1846: Prefer 'AsSpan' over 'Substring' 128 | dotnet_diagnostic.CA1846.severity = none 129 | 130 | # CA1863: Use 'CompositeFormat' 131 | dotnet_diagnostic.CA1863.severity = none 132 | 133 | # CA1865: Use char overload 134 | dotnet_diagnostic.CA1865.severity = none 135 | 136 | # CA2249: Consider using 'string.Contains' instead of 'string.IndexOf' 137 | dotnet_diagnostic.CA2249.severity = none 138 | 139 | # SYSLIB1045: Convert to 'GeneratedRegexAttribute'. 140 | dotnet_diagnostic.SYSLIB1045.severity = none 141 | 142 | # SYSLIB1054: Use 'LibraryImportAttribute' instead of 'DllImportAttribute' to generate P/Invoke marshalling code at compile time 143 | dotnet_diagnostic.SYSLIB1054.severity = none 144 | 145 | [*.cs] 146 | # CSharp code style settings 147 | csharp_style_var_elsewhere = false:none 148 | csharp_style_var_for_built_in_types = false:none 149 | csharp_style_var_when_type_is_apparent = false:none 150 | csharp_style_prefer_primary_constructors = false:none 151 | 152 | csharp_style_expression_bodied_accessors = true:suggestion 153 | csharp_style_expression_bodied_constructors = false:none 154 | csharp_style_expression_bodied_indexers = true:suggestion 155 | csharp_style_expression_bodied_methods = false:none 156 | csharp_style_expression_bodied_operators = false:none 157 | csharp_style_expression_bodied_properties = true:suggestion 158 | 159 | csharp_style_conditional_delegate_call = true:suggestion 160 | csharp_style_deconstructed_variable_declaration = false:none 161 | csharp_style_inlined_variable_declaration = true:suggestion 162 | csharp_style_pattern_local_over_anonymous_function = true:suggestion 163 | csharp_style_pattern_matching_over_as_with_null_check = true:suggestion 164 | csharp_style_pattern_matching_over_is_with_cast_check = true:suggestion 165 | csharp_style_throw_expression = true:suggestion 166 | csharp_style_namespace_declarations = block_scoped:silent 167 | csharp_style_prefer_method_group_conversion = true:silent 168 | csharp_style_prefer_top_level_statements = true:silent 169 | csharp_style_expression_bodied_lambdas = true:silent 170 | csharp_style_expression_bodied_local_functions = false:silent 171 | csharp_style_prefer_null_check_over_type_check = true:suggestion 172 | csharp_style_prefer_local_over_anonymous_function = true:suggestion 173 | csharp_style_prefer_index_operator = true:suggestion 174 | csharp_style_prefer_range_operator = true:suggestion 175 | csharp_style_implicit_object_creation_when_type_is_apparent = true:suggestion 176 | csharp_style_prefer_tuple_swap = true:suggestion 177 | csharp_style_prefer_utf8_string_literals = true:suggestion 178 | csharp_style_unused_value_assignment_preference = discard_variable:suggestion 179 | csharp_style_unused_value_expression_statement_preference = discard_variable:silent 180 | 181 | csharp_prefer_braces = when_multiline:none 182 | csharp_prefer_simple_default_expression = true:suggestion 183 | csharp_prefer_simple_using_statement = true:suggestion 184 | csharp_preserve_single_line_blocks = true 185 | csharp_using_directive_placement = outside_namespace:silent 186 | 187 | # Indentation options 188 | csharp_indent_block_contents = true 189 | csharp_indent_braces = false 190 | csharp_indent_case_contents = true 191 | csharp_indent_labels = no_change 192 | 193 | # New line options 194 | csharp_new_line_before_catch = true 195 | csharp_new_line_before_else = true 196 | csharp_new_line_before_finally = true 197 | csharp_new_line_before_members_in_anonymous_types = true 198 | csharp_new_line_before_members_in_object_initializers = true 199 | csharp_new_line_before_open_brace = all 200 | csharp_new_line_between_query_expression_clauses = true 201 | 202 | # Spacing options 203 | csharp_space_after_cast = false 204 | csharp_space_after_colon_in_inheritance_clause = true 205 | csharp_space_after_comma = true 206 | csharp_space_after_dot = false 207 | csharp_space_after_keywords_in_control_flow_statements = false 208 | csharp_space_after_semicolon_in_for_statement = true 209 | csharp_space_around_binary_operators = before_and_after 210 | csharp_space_before_colon_in_inheritance_clause = true 211 | csharp_space_before_comma = false 212 | csharp_space_before_dot = false 213 | csharp_space_before_open_square_brackets = false 214 | csharp_space_before_semicolon_in_for_statement = false 215 | csharp_space_between_method_call_empty_parameter_list_parentheses = false 216 | csharp_space_between_method_call_name_and_opening_parenthesis = false 217 | csharp_space_between_method_call_parameter_list_parentheses = false 218 | csharp_space_between_method_declaration_empty_parameter_list_parentheses = false 219 | csharp_space_between_method_declaration_name_and_open_parenthesis = false 220 | csharp_space_between_method_declaration_parameter_list_parentheses = false 221 | -------------------------------------------------------------------------------- /Source/CommentsElement.cs: -------------------------------------------------------------------------------- 1 | //=============================================================================================================== 2 | // System : Extended Doc Comments Completion Provider Package 3 | // File : CommentsElement.cs 4 | // Author : Eric Woodruff (Eric@EWoodruff.us) 5 | // Updated : 02/10/2023 6 | // Note : Copyright 2019-2023, Eric Woodruff, All rights reserved 7 | // 8 | // This file contains the class used to define an XML documentation comments element 9 | // 10 | // This code is published under the Microsoft Public License (Ms-PL). A copy of the license should be 11 | // distributed with the code and can be found at the project website: 12 | // https://github.com/EWSoftware/ExtendedDocCommentsProvider. This notice, the author's name, and all copyright 13 | // notices must remain intact in all applications, documentation, and source files. 14 | // 15 | // Date Who Comments 16 | // ============================================================================================================== 17 | // 10/18/2019 EFW Created the code 18 | //=============================================================================================================== 19 | 20 | // Ignore Spelling: cpp fs javascript vbnet html xml xsl xaml sql py pshell cref threadsafety href seealso todo 21 | 22 | using System; 23 | using System.Collections.Generic; 24 | using System.Collections.Immutable; 25 | using System.Linq; 26 | 27 | using Microsoft.CodeAnalysis.Completion; 28 | 29 | namespace EWSoftware.CompletionProviders 30 | { 31 | /// 32 | /// This is used to define an XML documentation comments element 33 | /// 34 | public class CommentsElement 35 | { 36 | #region Private data members 37 | //===================================================================== 38 | 39 | private static readonly CompletionItemRules defaultRules = CompletionItemRules.Create( 40 | ImmutableArray.Create(CharacterSetModificationRule.Create(CharacterSetModificationKind.Add, '!', '-', '[')), 41 | ImmutableArray.Create(CharacterSetModificationRule.Create(CharacterSetModificationKind.Add, '>', '\t')), 42 | EnterKeyRule.Never); 43 | private static readonly CharacterSetModificationRule withoutQuoteRule = 44 | CharacterSetModificationRule.Create(CharacterSetModificationKind.Remove, '"'); 45 | private static readonly CharacterSetModificationRule withoutSpaceRule = 46 | CharacterSetModificationRule.Create(CharacterSetModificationKind.Remove, ' '); 47 | 48 | private readonly HashSet attributes; 49 | private readonly HashSet childOf; 50 | 51 | private string displayText; 52 | 53 | #endregion 54 | 55 | #region Properties 56 | //===================================================================== 57 | 58 | /// 59 | /// This static read-only property returns a dictionary containing the current set of custom element 60 | /// definitions. 61 | /// 62 | public static Dictionary CustomElements { get; } = CreateDefaultCommentElements(); 63 | 64 | /// 65 | /// The element name 66 | /// 67 | public string Name { get; set; } 68 | 69 | /// 70 | /// Optional display text to show in the completion popup 71 | /// 72 | /// If not set, the is used. This allows alternate text to be shown in place 73 | /// or the element name or to allow multiple instances of a particular element with different before and 74 | /// after text for example. 75 | public string DisplayText 76 | { 77 | get => displayText ?? this.Name; 78 | set 79 | { 80 | if(String.IsNullOrWhiteSpace(value)) 81 | displayText = null; 82 | else 83 | displayText = value.Trim(); 84 | } 85 | } 86 | 87 | /// 88 | /// An optional description to show when the completion item is selected in the completion popup list 89 | /// 90 | /// If not set, no description will be shown 91 | public string Description { get; set; } 92 | 93 | /// 94 | /// Additional text to include after the element name and before the caret if the element is inserted 95 | /// 96 | /// This is typically a default attribute name, the equals sign, and the opening quote mark 97 | public string TextBeforeCaret { get; set; } 98 | 99 | /// 100 | /// Additional text to include after the caret if the element is inserted 101 | /// 102 | /// When is specified, this is typically a closing quote mark 103 | public string TextAfterCaret { get; set; } 104 | 105 | /// 106 | /// This indicates how the element is used 107 | /// 108 | /// If , this element cannot be nested within other elements. 109 | /// If or , it can. If 110 | /// is empty, it can appear within any element. If specific parent elements are 111 | /// specified, it can only appear within them. 112 | public ElementUsage ElementUsage { get; set; } 113 | 114 | /// 115 | /// This indicates whether or not the top-level element is single-use or can appear multiple times 116 | /// 117 | public bool IsSingleUse { get; set; } 118 | 119 | /// 120 | /// This is used to indicate whether or not the element is inserted as a self-closing element or if it 121 | /// is left open. 122 | /// 123 | public bool IsSelfClosing { get; set; } 124 | 125 | /// 126 | /// This returns a collection of attributes supported by the element, if any 127 | /// 128 | public IReadOnlyCollection Attributes => attributes; 129 | 130 | /// 131 | /// This returns a collection of parent element names of which this element can be a child 132 | /// 133 | /// If empty and not a top-level element, this element can appear in any other element. If not 134 | /// empty, it can only appear within the specified elements. 135 | public IReadOnlyCollection ChildOf => childOf; 136 | 137 | #endregion 138 | 139 | #region Constructor 140 | //===================================================================== 141 | 142 | /// 143 | /// Constructor 144 | /// 145 | public CommentsElement() 146 | { 147 | attributes = new HashSet(); 148 | childOf = new HashSet(); 149 | } 150 | #endregion 151 | 152 | #region Methods 153 | //===================================================================== 154 | 155 | /// 156 | /// Add supported attribute information to the element 157 | /// 158 | /// An enumerable list of attribute information to add 159 | /// A reference to the comment element instance 160 | public CommentsElement AddAttributes(IEnumerable elementNames) 161 | { 162 | attributes.UnionWith(elementNames); 163 | return this; 164 | } 165 | 166 | /// 167 | /// Add parent element information to the element 168 | /// 169 | /// An enumerable list of parent element names 170 | /// A reference to the comment element instance 171 | public CommentsElement AddChildOfElements(IEnumerable parentElements) 172 | { 173 | childOf.UnionWith(parentElements); 174 | return this; 175 | } 176 | 177 | /// 178 | /// Convert the element to a 179 | /// 180 | /// The element information as a 181 | public CompletionItem ToCompletionItem() 182 | { 183 | var rules = defaultRules; 184 | 185 | if(this.DisplayText.IndexOfAny(new[] { '"', ' ' }) != -1) 186 | { 187 | var commitRules = defaultRules.CommitCharacterRules; 188 | 189 | if(this.DisplayText.IndexOf('"') != -1) 190 | commitRules = commitRules.Add(withoutQuoteRule); 191 | 192 | if(this.DisplayText.IndexOf(' ') != -1) 193 | commitRules = commitRules.Add(withoutSpaceRule); 194 | 195 | rules = defaultRules.WithCommitCharacterRules(commitRules); 196 | } 197 | 198 | string beforeCaret = "<" + this.Name, afterCaret = this.TextAfterCaret; 199 | 200 | if(!String.IsNullOrWhiteSpace(this.TextBeforeCaret)) 201 | beforeCaret += " " + this.TextBeforeCaret; 202 | 203 | if(this.IsSelfClosing) 204 | afterCaret += "/>"; 205 | 206 | var properties = new Dictionary { { nameof(TextBeforeCaret), beforeCaret } }; 207 | 208 | if(!String.IsNullOrWhiteSpace(afterCaret)) 209 | properties.Add(nameof(TextAfterCaret), afterCaret); 210 | 211 | if(!String.IsNullOrWhiteSpace(this.Description)) 212 | properties.Add(nameof(Description), this.Description); 213 | 214 | return CompletionItem.Create(this.DisplayText, null, null, ImmutableDictionary.CreateRange(properties), 215 | ImmutableArray.Create("Keyword"), rules); 216 | } 217 | 218 | /// 219 | /// Convert an attribute to a 220 | /// 221 | /// The attribute to use 222 | /// The attribute as a 223 | public static CompletionItem AttributeToCompletionItem(ElementAttribute attribute) 224 | { 225 | if(attribute == null) 226 | throw new ArgumentNullException(nameof(attribute)); 227 | 228 | var properties = new Dictionary 229 | { 230 | { nameof(TextBeforeCaret), attribute.Name + "=\"" }, 231 | { nameof(TextAfterCaret), "\"" } 232 | }; 233 | 234 | if(!String.IsNullOrWhiteSpace(attribute.Description)) 235 | properties.Add(nameof(Description), attribute.Description); 236 | 237 | return CompletionItem.Create(attribute.Name, null, null, ImmutableDictionary.CreateRange(properties), 238 | ImmutableArray.Create("Keyword"), defaultRules); 239 | } 240 | 241 | /// 242 | /// Convert an attribute value to a 243 | /// 244 | /// The attribute value to use 245 | /// The attribute value as a 246 | public static CompletionItem AttributeValueToCompletionItem(string value) 247 | { 248 | return CompletionItem.Create(value, null, null, ImmutableDictionary.Empty, 249 | ImmutableArray.Create("Keyword"), defaultRules); 250 | } 251 | 252 | /// 253 | /// Create the default comment element dictionary 254 | /// 255 | /// A dictionary containing the default comment element information 256 | private static Dictionary CreateDefaultCommentElements() 257 | { 258 | return new List 259 | { 260 | new CommentsElement 261 | { 262 | Name = "AttachedEventComments", 263 | ElementUsage = ElementUsage.TopLevel, 264 | Description = "Define the content that should appear on the auto-generated attached event " + 265 | "member topic for a given WPF routed event member." 266 | }, 267 | new CommentsElement 268 | { 269 | Name = "AttachedPropertyComments", 270 | ElementUsage = ElementUsage.TopLevel, 271 | Description = "Define the content that should appear on the auto-generated attached " + 272 | "property member topic for a given WPF dependency property member." 273 | }, 274 | new CommentsElement 275 | { 276 | Name = "code", 277 | ElementUsage = ElementUsage.Nested, 278 | TextBeforeCaret="language=\"", 279 | TextAfterCaret="\"", 280 | Description = "Format a multi-line section of text as source code.", 281 | }.AddAttributes(new[] { 282 | new ElementAttribute(new[] { "cs", "cpp", "c", "fs", "javascript", "vb", "vbnet", 283 | "html", "xml", "xsl", "xaml", "sql", "py", "pshell", "bat", "none" }) { 284 | Name = "language", Description = "Specify the code language." }, 285 | new ElementAttribute { Name = "title", Description = "An optional title or a space to " + 286 | "suppress the title." }, 287 | new ElementAttribute { Name = "source", Description = "Specify a source code file from " + 288 | "which this element's content will be imported." }, 289 | new ElementAttribute { Name = "region", Description = "Limit the imported code to a " + 290 | "specific named region within it." }, 291 | new ElementAttribute(new[] { "true", "false" }) { 292 | Name = "removeRegionMarkers", Description = "Indicate whether or not region markers " + 293 | "within the imported code file or region are removed." }, 294 | new ElementAttribute { Name = "tabSize", Description = "Override the default tab size " + 295 | "setting for the language which is defined by the code colorizer." }, 296 | new ElementAttribute(new[] { "true", "false" }) { 297 | Name = "numberLines", Description = "Override the default line numbering setting in " + 298 | "the code colorizer." }, 299 | new ElementAttribute(new[] { "true", "false" }) { 300 | Name = "outlining", Description = "Override the default outlining setting in the " + 301 | "code colorizer." }, 302 | new ElementAttribute(new[] { "true", "false" }) { 303 | Name = "keepSeeTags", Description = "Override the default setting in the code " + 304 | "colorizer that determines whether or not elements in the code are " + 305 | "rendered as clickable links or are rendered as literal text."} 306 | }), 307 | new CommentsElement 308 | { 309 | Name = "conceptualLink", 310 | ElementUsage = ElementUsage.Both, 311 | TextBeforeCaret = "target=\"", 312 | TextAfterCaret = "\"", 313 | IsSelfClosing = true, 314 | Description = "Create a link to a MAML topic within the See Also section of a topic or an " + 315 | "inline link to a MAML topic within one of the other XML comments elements." 316 | }, 317 | new CommentsElement 318 | { 319 | Name = "event", 320 | ElementUsage = ElementUsage.TopLevel, 321 | TextBeforeCaret = "cref=\"", 322 | TextAfterCaret = "\"", 323 | Description = "List events that can be raised by a type's member." 324 | }, 325 | new CommentsElement 326 | { 327 | Name = "list", 328 | ElementUsage = ElementUsage.Nested, 329 | TextBeforeCaret = "type=\"", 330 | TextAfterCaret = "\"", 331 | Description = "Specify content that should be displayed as a list or a table." 332 | }.AddAttributes(new[] { 333 | new ElementAttribute(new[] { "definition" }) { 334 | Name="type", Description = "The list type" }, 335 | new ElementAttribute { Name = "start", Description = "The starting number for numbered lists." } 336 | }), 337 | new CommentsElement 338 | { 339 | Name = "note", 340 | ElementUsage = ElementUsage.Nested, 341 | TextBeforeCaret = "type=\"", 342 | TextAfterCaret = "\"", 343 | Description = "Create a note within a topic to draw attention to some important information." 344 | }.AddAttributes(new [] { 345 | new ElementAttribute(new[] { "note", "tip", "implement", "caller", "inherit", "caution", 346 | "warning", "important", "security", "cs", "cpp", "vb", "todo" }) { 347 | Name = "type", Description = "Specifies the note type." }, 348 | new ElementAttribute { Name = "title", Description = "An optional title override" } 349 | }), 350 | new CommentsElement 351 | { 352 | Name = "overloads", 353 | ElementUsage = ElementUsage.TopLevel, 354 | Description = "Define the content that should appear on the auto-generated overloads topic " + 355 | "for a given set of member overloads." 356 | }, 357 | new CommentsElement 358 | { 359 | Name = "preliminary", 360 | ElementUsage = ElementUsage.TopLevel, 361 | IsSelfClosing = true, 362 | Description = "Indicate that a particular type or member is preliminary and is subject to change." 363 | }, 364 | new CommentsElement 365 | { 366 | Name = "revisionHistory", 367 | ElementUsage = ElementUsage.TopLevel, 368 | TextBeforeCaret = "visible=\"", 369 | TextAfterCaret = "true\"", 370 | Description = "Display revision history for a type or its members." 371 | }.AddAttributes(new[] { 372 | new ElementAttribute(new[] { "true", "false" }) { 373 | Name = "visible", 374 | Description = "Indicate whether or not the revision history is included in the help topic." }, 375 | }), 376 | new CommentsElement 377 | { 378 | Name = "revision", 379 | ElementUsage = ElementUsage.Nested, 380 | TextBeforeCaret = "date=\"", 381 | TextAfterCaret = "\" version=\"\"", 382 | Description = "Describe a revision to the type or member." 383 | }.AddAttributes(new[] { 384 | new ElementAttribute{ Name = "date", Description = "The revision date." }, 385 | new ElementAttribute{ Name = "version", Description = "The version in which the revision was made." }, 386 | new ElementAttribute{ Name = "author", Description = "The name of the person that made the revision." }, 387 | new ElementAttribute(new[] { "true", "false" }) { 388 | Name = "visible", 389 | Description = "Indicate whether or not the revision is included in the help topic." }, 390 | }).AddChildOfElements( 391 | new[] { "revisionHistory" }), 392 | new CommentsElement 393 | { 394 | Name = "see", 395 | ElementUsage = ElementUsage.Nested, 396 | TextBeforeCaret = "cref=\"", 397 | TextAfterCaret = "\"", 398 | IsSelfClosing = true, 399 | Description = "Create an inline link to another API topic or an external website." 400 | }.AddAttributes(new[] { 401 | new ElementAttribute(new[] { "true", "false" }) { 402 | Name = "qualifyHint", 403 | Description = "Indicate whether or not the type or member name should be qualified." }, 404 | new ElementAttribute(new[] { "true", "false" }) { 405 | Name = "autoUpgrade", 406 | Description = "Indicate whether or not the link should go to the method overloads topic." }, 407 | new ElementAttribute { Name = "href", Description = "Specify a URL to which the link should go." }, 408 | new ElementAttribute { Name = "alt", Description = "Specify alternate text for a URL link." }, 409 | new ElementAttribute(new[] { "_blank", "_self", "_parent", "_top" }) { 410 | Name = "target", Description = "Specify where a URL link will be opened." }, 411 | }), 412 | new CommentsElement 413 | { 414 | Name = "seealso", 415 | ElementUsage = ElementUsage.Nested, 416 | TextBeforeCaret = "cref=\"", 417 | TextAfterCaret = "\"", 418 | IsSelfClosing = true, 419 | Description = "Create an link to another API topic or an external website in the See Also " + 420 | "section of a help topic." 421 | }.AddAttributes(new[] { 422 | new ElementAttribute(new[] { "true", "false" }) { 423 | Name = "qualifyHint", 424 | Description = "Indicate whether or not the type or member name should be qualified." }, 425 | new ElementAttribute(new[] { "true", "false" }) { 426 | Name = "autoUpgrade", 427 | Description = "Indicate whether or not the link should go to the method overloads topic." }, 428 | new ElementAttribute { Name = "href", Description = "Specify a URL to which the link should go." }, 429 | new ElementAttribute { Name = "alt", Description = "Specify alternate text for a URL link." }, 430 | new ElementAttribute(new[] { "_blank", "_self", "_parent", "_top" }) { 431 | Name = "target", Description = "Specify where a URL link will be opened." }, 432 | }), 433 | new CommentsElement 434 | { 435 | Name = "threadsafety", 436 | ElementUsage = ElementUsage.TopLevel, 437 | TextBeforeCaret = "static=\"", 438 | TextAfterCaret = "true\" instance=\"false\"", 439 | IsSelfClosing = true, 440 | Description = "Indicate whether or not a class or structure's static and instance members " + 441 | "are safe for use in multi-threaded scenarios." 442 | }.AddAttributes(new[] { 443 | new ElementAttribute(new[] { "true", "false" }) { 444 | Name = "static", Description = "The thread safety of static members." }, 445 | new ElementAttribute(new[] { "true", "false" }) { 446 | Name = "instance", Description = "The thread safety of instance member." } 447 | }), 448 | new CommentsElement 449 | { 450 | Name = "token", 451 | ElementUsage = ElementUsage.Both, 452 | Description = "Insert a replaceable tag within a topic." 453 | } 454 | }.ToDictionary(k => k.DisplayText, v => v); 455 | } 456 | #endregion 457 | } 458 | } 459 | -------------------------------------------------------------------------------- /Source/CSharpXmlDocCommentsCompletionProvider.cs: -------------------------------------------------------------------------------- 1 | //=============================================================================================================== 2 | // System : Extended Doc Comments Completion Provider Package 3 | // File : CSharpXmlDocCommentsCompletionProvider.cs 4 | // Author : Eric Woodruff (Eric@EWoodruff.us) 5 | // Updated : 09/12/2025 6 | // Note : Copyright 2019-2025, Eric Woodruff, All rights reserved 7 | // 8 | // This file contains the extended documentation comments completion provider for C# 9 | // 10 | // This code is published under the Microsoft Public License (Ms-PL). A copy of the license should be 11 | // distributed with the code and can be found at the project website: 12 | // https://github.com/EWSoftware/ExtendedDocCommentsProvider. This notice, the author's name, and all copyright 13 | // notices must remain intact in all applications, documentation, and source files. 14 | // 15 | // Date Who Comments 16 | // ============================================================================================================== 17 | // 10/09/2019 EFW Created the code 18 | //=============================================================================================================== 19 | 20 | // Ignore Spelling: lexer attr cref 21 | 22 | using System; 23 | using System.Collections.Generic; 24 | using System.Collections.Immutable; 25 | using System.Linq; 26 | using System.Reflection; 27 | using System.Threading; 28 | using System.Threading.Tasks; 29 | 30 | using Microsoft.CodeAnalysis; 31 | using Microsoft.CodeAnalysis.Completion; 32 | using Microsoft.CodeAnalysis.CSharp; 33 | using Microsoft.CodeAnalysis.CSharp.Syntax; 34 | using Microsoft.CodeAnalysis.Options; 35 | using Microsoft.CodeAnalysis.Text; 36 | 37 | namespace EWSoftware.CompletionProviders 38 | { 39 | /// 40 | /// This completion provider augments the standard XML documentation comments elements with custom elements, 41 | /// attributes, and attribute values supported by the Sandcastle Help File Builder and other documentation 42 | /// tools. 43 | /// 44 | /// The core logic used to determine which completion items to return based on the current context 45 | /// is based largely on the Roslyn XML comments completion providers. This runs after the built in C# 46 | /// comments provider so that our extensions override the ones provided by it such as code. This 47 | /// allows our before/after text options to work properly. The built in provider is internal so we need to 48 | /// specify it's name as a literal string in the attribute. 49 | [ExportCompletionProvider(nameof(CSharpXmlDocCommentsCompletionProvider), LanguageNames.CSharp)] 50 | [ExtensionOrder(After = "XmlDocCommentCompletionProvider")] 51 | internal sealed class CSharpXmlDocCommentsCompletionProvider : CompletionProvider 52 | { 53 | #region CompletionProvider abstract method implementation 54 | //===================================================================== 55 | 56 | /// 57 | public override async Task GetChangeAsync(Document document, CompletionItem item, 58 | char? commitChar, CancellationToken cancellationToken) 59 | { 60 | var text = await document.GetTextAsync(cancellationToken).ConfigureAwait(false); 61 | 62 | if(!item.Properties.TryGetValue(nameof(CommentsElement.TextBeforeCaret), out string replacementText)) 63 | replacementText = item.DisplayText; 64 | 65 | var itemSpan = item.Span; 66 | var replacementSpan = TextSpan.FromBounds(text[itemSpan.Start - 1] == '<' && replacementText.Length > 0 && 67 | replacementText[0] == '<' ? itemSpan.Start - 1 : itemSpan.Start, itemSpan.End); 68 | 69 | int newPosition = replacementSpan.Start + replacementText.Length; 70 | 71 | // Include the commit character? 72 | if(commitChar != null && !Char.IsWhiteSpace(commitChar.Value) && 73 | commitChar.Value != replacementText[replacementText.Length - 1]) 74 | { 75 | replacementText += commitChar.Value; 76 | newPosition++; 77 | } 78 | 79 | if(item.Properties.TryGetValue(nameof(CommentsElement.TextAfterCaret), out string afterCaretText)) 80 | replacementText += afterCaretText; 81 | 82 | return CompletionChange.Create(new TextChange(replacementSpan, replacementText), newPosition, true); 83 | } 84 | 85 | /// 86 | public override Task GetDescriptionAsync( 87 | Document document, CompletionItem item, CancellationToken cancellationToken) 88 | { 89 | if(!item.Properties.TryGetValue(nameof(CommentsElement.Description), out string description)) 90 | return Task.FromResult(CompletionDescription.Empty); 91 | 92 | return Task.FromResult(CompletionDescription.Create(ImmutableArray.Create(new TaggedText[] { 93 | new TaggedText(TextTags.Text, description) }))); 94 | } 95 | 96 | /// 97 | public override async Task ProvideCompletionsAsync(CompletionContext context) 98 | { 99 | var items = await GetItemsAsync(context.Document, context.Position, context.Trigger, 100 | context.CancellationToken).ConfigureAwait(false); 101 | 102 | if(items != null) 103 | context.AddItems(items); 104 | } 105 | 106 | /// 107 | public override bool ShouldTriggerCompletion(SourceText text, int position, CompletionTrigger trigger, 108 | OptionSet options) 109 | { 110 | if(trigger.Kind != CompletionTriggerKind.Insertion || position < 1) 111 | return false; 112 | 113 | // Trigger it on an open bracket, quote, or at the start of a word 114 | char ch = text[position - 1]; 115 | 116 | if(ch == '<' || ch == '"' || (ch == ' ' && (position == text.Length || 117 | !SyntaxFacts.IsIdentifierStartCharacter(text[position])))) 118 | { 119 | return true; 120 | } 121 | 122 | position--; 123 | 124 | // We only want to trigger if we're the first character in an identifier. If there's a character 125 | // before or after us, then we don't want to trigger. 126 | if(!SyntaxFacts.IsIdentifierStartCharacter(text[position]) || 127 | (position > 0 && SyntaxFacts.IsIdentifierPartCharacter(text[position - 1])) || 128 | (position < text.Length - 1 && SyntaxFacts.IsIdentifierPartCharacter(text[position + 1]))) 129 | { 130 | return false; 131 | } 132 | 133 | // Try to honor the "Show completion list after a character is typed" option 134 | return TriggerOnTypingLetters(options); 135 | } 136 | #endregion 137 | 138 | #region Helper methods 139 | //===================================================================== 140 | 141 | /// 142 | /// This is used to get the TriggerOnTypingLetters option from the option set 143 | /// 144 | /// The option set from which to get the option 145 | /// The per-language options are passed to but Roslyn 146 | /// implements a majority of that stuff internally so it's inaccessible to us publicly. As such, we 147 | /// resort to Reflection to get at it. If there's a better way to do this, I can't find it. 148 | private static bool TriggerOnTypingLetters(OptionSet options) 149 | { 150 | try 151 | { 152 | FieldInfo fi = options.GetType().GetField("_values", BindingFlags.NonPublic | 153 | BindingFlags.Instance); 154 | 155 | if(fi != null) 156 | { 157 | if(fi.GetValue(options) is ImmutableDictionary optionValues && optionValues.Count != 0) 158 | { 159 | var key = optionValues.Keys.FirstOrDefault(k => k.Language == LanguageNames.CSharp && 160 | k.Option.Name == nameof(TriggerOnTypingLetters) && k.Option.Type == typeof(bool)); 161 | 162 | if(key.Language != null) 163 | return (bool)optionValues[key]; 164 | } 165 | } 166 | } 167 | catch(Exception ex) 168 | { 169 | // Ignore exceptions, we'll just use the default 170 | System.Diagnostics.Debug.WriteLine(ex); 171 | 172 | if(System.Diagnostics.Debugger.IsAttached) 173 | System.Diagnostics.Debugger.Break(); 174 | } 175 | 176 | // If we couldn't get it, use the default value which assumes it is enabled 177 | return true; 178 | } 179 | 180 | /// 181 | /// This is used to determine which completion items should appear, if any 182 | /// 183 | /// The document for which to provide completions 184 | /// The position of the caret within the document 185 | /// The action that triggered the completion to start 186 | /// A cancellation token used to cancel the operation 187 | /// An enumerable set of completion items if any are determined to be relevant 188 | private static async Task> GetItemsAsync(Document document, int position, 189 | CompletionTrigger trigger, CancellationToken cancellationToken) 190 | { 191 | try 192 | { 193 | var tree = await document.GetSyntaxTreeAsync(cancellationToken).ConfigureAwait(false); 194 | var token = tree.FindTokenOnLeftOfPosition(position, cancellationToken); 195 | var parentTrivia = token.Parent?.FirstAncestorOrSelf(); 196 | 197 | if(parentTrivia == null || parentTrivia.ParentTrivia.Token.IsKind(SyntaxKind.None)) 198 | return null; 199 | 200 | // Offer attribute names based on the element 201 | if(IsAttributeNameContext(token, position, out string elementName, out var existingAttributes)) 202 | { 203 | if(CommentsElement.CustomElements.TryGetValue(elementName, out CommentsElement ce) && 204 | ce.Attributes.Count != 0) 205 | { 206 | return ce.Attributes.Where(attr => !existingAttributes.Contains(attr.Name)).Select( 207 | attr => CommentsElement.AttributeToCompletionItem(attr)); 208 | } 209 | 210 | return null; 211 | } 212 | 213 | // Only attribute names should be triggered by a space. Nothing past this point should be. 214 | if(trigger.Kind == CompletionTriggerKind.Insertion && trigger.Character == ' ') 215 | return null; 216 | 217 | // Offer attribute values based on the element and attribute names 218 | if(IsAttributeValueContext(token, out elementName, out string attributeName)) 219 | { 220 | if(CommentsElement.CustomElements.TryGetValue(elementName, out CommentsElement ce)) 221 | { 222 | var attr = ce.Attributes.FirstOrDefault(a => a.Name == attributeName); 223 | 224 | if(attr != null) 225 | return attr.Values.Select(v => CommentsElement.AttributeValueToCompletionItem(v)); 226 | } 227 | 228 | return null; 229 | } 230 | 231 | // Everything below this point should only be offered if triggered by an opening bracket 232 | if(trigger.Kind == CompletionTriggerKind.Insertion && trigger.Character != '<') 233 | return null; 234 | 235 | var elementNames = new HashSet(); 236 | 237 | if(token.Parent.IsKind(SyntaxKind.XmlEmptyElement) || token.Parent.IsKind(SyntaxKind.XmlText) || 238 | (token.Parent.IsKind(SyntaxKind.XmlElementEndTag) && token.IsKind(SyntaxKind.GreaterThanToken)) || 239 | (token.Parent.IsKind(SyntaxKind.XmlName) && token.Parent.Parent.IsKind(SyntaxKind.XmlEmptyElement))) 240 | { 241 | // Add child elements with no defined parentage 242 | if(token.Parent.Parent.IsKind(SyntaxKind.XmlElement) || 243 | token.Parent.Parent.Parent.IsKind(SyntaxKind.XmlElement)) 244 | { 245 | elementNames.UnionWith(CommentsElement.CustomElements.Values.Where( 246 | el => el.ElementUsage != ElementUsage.TopLevel && !el.ChildOf.Any()).Select( 247 | el => el.DisplayText)); 248 | } 249 | 250 | // Add child elements based on the parent element's name 251 | if(token.Parent.Parent is XmlElementSyntax xmlElement) 252 | { 253 | elementNames.UnionWith(CommentsElement.CustomElements.Values.Where(el => el.ChildOf.Contains( 254 | xmlElement.StartTag.Name.LocalName.ValueText)).Select(el => el.DisplayText)); 255 | } 256 | 257 | if(token.Parent.Parent.IsKind(SyntaxKind.XmlEmptyElement) && 258 | token.Parent.Parent.Parent is XmlElementSyntax nestedXmlElement) 259 | { 260 | elementNames.UnionWith(CommentsElement.CustomElements.Values.Where(el => el.ChildOf.Contains( 261 | nestedXmlElement.StartTag.Name.LocalName.ValueText)).Select(el => el.DisplayText)); 262 | } 263 | 264 | // Add top-level elements 265 | if(token.Parent.Parent is DocumentationCommentTriviaSyntax || 266 | (token.Parent.Parent.IsKind(SyntaxKind.XmlEmptyElement) && 267 | token.Parent.Parent.Parent is DocumentationCommentTriviaSyntax)) 268 | { 269 | var existingTopLevelElements = new HashSet(parentTrivia.Content.Select( 270 | n => GetElementNameAndAttributes(n).Name).Where(el => el != null)); 271 | 272 | // Top-level single-use elements 273 | elementNames.UnionWith(CommentsElement.CustomElements.Values.Where( 274 | el => el.ElementUsage == ElementUsage.TopLevel && el.IsSingleUse && 275 | !existingTopLevelElements.Contains(el.Name)).Select(el => el.DisplayText)); 276 | 277 | // Top-level repeatable elements 278 | elementNames.UnionWith(CommentsElement.CustomElements.Values.Where( 279 | el => el.ElementUsage == ElementUsage.TopLevel && !el.IsSingleUse).Select(el => el.DisplayText)); 280 | } 281 | } 282 | 283 | // This case only appears to happen if using the shortcut key to invoke completion and the caret 284 | // is at the end of a start tag: |. In such cases, add child elements with no defined 285 | // parentage and child elements based on the start tag's name. 286 | if(token.Parent is XmlElementStartTagSyntax startTag && token == startTag.GreaterThanToken) 287 | { 288 | elementNames.UnionWith(CommentsElement.CustomElements.Values.Where( 289 | el => el.ElementUsage != ElementUsage.TopLevel && !el.ChildOf.Any()).Select( 290 | el => el.DisplayText)); 291 | 292 | elementNames.UnionWith(CommentsElement.CustomElements.Values.Where(el => el.ChildOf.Contains( 293 | startTag.Name.LocalName.ValueText)).Select(el => el.DisplayText)); 294 | } 295 | 296 | // Add use anywhere elements 297 | elementNames.UnionWith(CommentsElement.CustomElements.Values.Where( 298 | el => el.ElementUsage == ElementUsage.Both).Select(el => el.DisplayText)); 299 | 300 | if(elementNames.Any()) 301 | return elementNames.Select(el => CommentsElement.CustomElements[el].ToCompletionItem()); 302 | } 303 | catch(Exception ex) 304 | { 305 | // Ignore any exceptions. We just won't offer any completions. 306 | if(!(ex is OperationCanceledException)) 307 | System.Diagnostics.Debug.WriteLine(ex); 308 | 309 | if(System.Diagnostics.Debugger.IsAttached) 310 | System.Diagnostics.Debugger.Break(); 311 | } 312 | 313 | return null; 314 | } 315 | 316 | /// 317 | /// Get the element name and attributes from the current syntax node 318 | /// 319 | /// The syntax node to use 320 | /// A tuple containing the element name and the attributes 321 | private static (string Name, IEnumerable Attributes) GetElementNameAndAttributes( 322 | SyntaxNode node) 323 | { 324 | switch(node) 325 | { 326 | // Self-closing or incomplete element: or 331 | case XmlElementSyntax nonEmptyElement: 332 | return GetElementNameAndAttributes(nonEmptyElement.StartTag); 333 | 334 | // Start tag: 335 | case XmlElementStartTagSyntax startTag: 336 | return (startTag.Name.LocalName.ValueText, startTag.Attributes); 337 | 338 | default: 339 | return (null, null); 340 | } 341 | } 342 | 343 | /// 344 | /// This is used to determine whether or not the current caret location is in an attribute name context 345 | /// 346 | /// The token to check. 347 | /// The position of the caret. 348 | /// On return, this will contain the element name if it is an attribute name 349 | /// context, null if not. 350 | /// On return, this will contain an enumerable list of the current 351 | /// attribute names for the element if it is an attribute name context, null if not. 352 | /// True if it is within the attribute name context, false if not. 353 | private static bool IsAttributeNameContext(SyntaxToken token, int position, out string elementName, 354 | out IEnumerable attributeNames) 355 | { 356 | elementName = null; 357 | 358 | // Unlike VB, the C# lexer has a preference for leading trivia. In cases such as " attributes = null; 374 | 375 | if(token.IsKind(SyntaxKind.IdentifierToken) && token.Parent.IsKind(SyntaxKind.XmlName)) 376 | { 377 | // "(attributes.Select(attr => attr.Name.LocalName.ValueText)); 398 | else 399 | attributeNames = null; 400 | 401 | return elementName != null; 402 | } 403 | 404 | /// 405 | /// This is used to determine whether or not the current caret location is in an attribute value context 406 | /// 407 | /// The token to check 408 | /// On return, this will contain the element name if it is an attribute value 409 | /// context, null if not. 410 | /// On return, this will contain the attribute name if it is an attribute 411 | /// value context, null if not. 412 | /// True if it is within the attribute value context, false if not. 413 | private static bool IsAttributeValueContext(SyntaxToken token, out string elementName, out string attributeName) 414 | { 415 | XmlAttributeSyntax attributeSyntax = null; 416 | 417 | if(token.IsKind(SyntaxKind.XmlTextLiteralToken) && token.Parent.IsKind(SyntaxKind.XmlTextAttribute)) 418 | { 419 | // General attribute: attr="value| 420 | attributeSyntax = (XmlTextAttributeSyntax)token.Parent; 421 | } 422 | else 423 | { 424 | if(token.Parent.IsKind(SyntaxKind.XmlNameAttribute) || token.Parent.IsKind(SyntaxKind.XmlTextAttribute)) 425 | { 426 | // Return the parent attribute if there is no value yet: attr="| 427 | attributeSyntax = (XmlAttributeSyntax)token.Parent; 428 | 429 | if(token != attributeSyntax.StartQuoteToken) 430 | attributeSyntax = null; 431 | } 432 | } 433 | 434 | if(attributeSyntax != null) 435 | { 436 | attributeName = attributeSyntax.Name.LocalName.ValueText; 437 | 438 | var emptyElement = attributeSyntax.GetAncestor(); 439 | 440 | if(emptyElement != null) 441 | { 442 | // Self-closing or incomplete element: or (); 448 | 449 | if(startTag != null) 450 | { 451 | // Start tag: 452 | elementName = startTag.Name.LocalName.Text; 453 | return true; 454 | } 455 | } 456 | 457 | attributeName = elementName = null; 458 | return false; 459 | } 460 | #endregion 461 | } 462 | } 463 | -------------------------------------------------------------------------------- /Source/License.rtf: -------------------------------------------------------------------------------- 1 | {\rtf1\adeflang1025\ansi\ansicpg1252\uc1\adeff0\deff0\stshfdbch31505\stshfloch31506\stshfhich31506\stshfbi0\deflang1033\deflangfe1033\themelang1033\themelangfe0\themelangcs0{\fonttbl{\f0\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\f1\fbidi \fswiss\fcharset0\fprq2{\*\panose 020b0604020202020204}Arial;} 2 | {\f34\fbidi \froman\fcharset0\fprq2{\*\panose 02040503050406030204}Cambria Math;}{\flomajor\f31500\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;} 3 | {\fdbmajor\f31501\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\fhimajor\f31502\fbidi \fswiss\fcharset0\fprq2{\*\panose 020f0302020204030204}Calibri Light;} 4 | {\fbimajor\f31503\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\flominor\f31504\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;} 5 | {\fdbminor\f31505\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\fhiminor\f31506\fbidi \fswiss\fcharset0\fprq2{\*\panose 020f0502020204030204}Calibri;} 6 | {\fbiminor\f31507\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\f43\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\f44\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;} 7 | {\f46\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\f47\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\f48\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\f49\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);} 8 | {\f50\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\f51\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\f53\fbidi \fswiss\fcharset238\fprq2 Arial CE;}{\f54\fbidi \fswiss\fcharset204\fprq2 Arial Cyr;} 9 | {\f56\fbidi \fswiss\fcharset161\fprq2 Arial Greek;}{\f57\fbidi \fswiss\fcharset162\fprq2 Arial Tur;}{\f58\fbidi \fswiss\fcharset177\fprq2 Arial (Hebrew);}{\f59\fbidi \fswiss\fcharset178\fprq2 Arial (Arabic);} 10 | {\f60\fbidi \fswiss\fcharset186\fprq2 Arial Baltic;}{\f61\fbidi \fswiss\fcharset163\fprq2 Arial (Vietnamese);}{\f383\fbidi \froman\fcharset238\fprq2 Cambria Math CE;}{\f384\fbidi \froman\fcharset204\fprq2 Cambria Math Cyr;} 11 | {\f386\fbidi \froman\fcharset161\fprq2 Cambria Math Greek;}{\f387\fbidi \froman\fcharset162\fprq2 Cambria Math Tur;}{\f390\fbidi \froman\fcharset186\fprq2 Cambria Math Baltic;}{\f391\fbidi \froman\fcharset163\fprq2 Cambria Math (Vietnamese);} 12 | {\flomajor\f31508\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\flomajor\f31509\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\flomajor\f31511\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;} 13 | {\flomajor\f31512\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\flomajor\f31513\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\flomajor\f31514\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);} 14 | {\flomajor\f31515\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\flomajor\f31516\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\fdbmajor\f31518\fbidi \froman\fcharset238\fprq2 Times New Roman CE;} 15 | {\fdbmajor\f31519\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\fdbmajor\f31521\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\fdbmajor\f31522\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;} 16 | {\fdbmajor\f31523\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\fdbmajor\f31524\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\fdbmajor\f31525\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;} 17 | {\fdbmajor\f31526\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\fhimajor\f31528\fbidi \fswiss\fcharset238\fprq2 Calibri Light CE;}{\fhimajor\f31529\fbidi \fswiss\fcharset204\fprq2 Calibri Light Cyr;} 18 | {\fhimajor\f31531\fbidi \fswiss\fcharset161\fprq2 Calibri Light Greek;}{\fhimajor\f31532\fbidi \fswiss\fcharset162\fprq2 Calibri Light Tur;}{\fhimajor\f31533\fbidi \fswiss\fcharset177\fprq2 Calibri Light (Hebrew);} 19 | {\fhimajor\f31534\fbidi \fswiss\fcharset178\fprq2 Calibri Light (Arabic);}{\fhimajor\f31535\fbidi \fswiss\fcharset186\fprq2 Calibri Light Baltic;}{\fhimajor\f31536\fbidi \fswiss\fcharset163\fprq2 Calibri Light (Vietnamese);} 20 | {\fbimajor\f31538\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\fbimajor\f31539\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\fbimajor\f31541\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;} 21 | {\fbimajor\f31542\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\fbimajor\f31543\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\fbimajor\f31544\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);} 22 | {\fbimajor\f31545\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\fbimajor\f31546\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\flominor\f31548\fbidi \froman\fcharset238\fprq2 Times New Roman CE;} 23 | {\flominor\f31549\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\flominor\f31551\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\flominor\f31552\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;} 24 | {\flominor\f31553\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\flominor\f31554\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\flominor\f31555\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;} 25 | {\flominor\f31556\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\fdbminor\f31558\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\fdbminor\f31559\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;} 26 | {\fdbminor\f31561\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\fdbminor\f31562\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\fdbminor\f31563\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);} 27 | {\fdbminor\f31564\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\fdbminor\f31565\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\fdbminor\f31566\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);} 28 | {\fhiminor\f31568\fbidi \fswiss\fcharset238\fprq2 Calibri CE;}{\fhiminor\f31569\fbidi \fswiss\fcharset204\fprq2 Calibri Cyr;}{\fhiminor\f31571\fbidi \fswiss\fcharset161\fprq2 Calibri Greek;}{\fhiminor\f31572\fbidi \fswiss\fcharset162\fprq2 Calibri Tur;} 29 | {\fhiminor\f31573\fbidi \fswiss\fcharset177\fprq2 Calibri (Hebrew);}{\fhiminor\f31574\fbidi \fswiss\fcharset178\fprq2 Calibri (Arabic);}{\fhiminor\f31575\fbidi \fswiss\fcharset186\fprq2 Calibri Baltic;} 30 | {\fhiminor\f31576\fbidi \fswiss\fcharset163\fprq2 Calibri (Vietnamese);}{\fbiminor\f31578\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\fbiminor\f31579\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;} 31 | {\fbiminor\f31581\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\fbiminor\f31582\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\fbiminor\f31583\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);} 32 | {\fbiminor\f31584\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\fbiminor\f31585\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\fbiminor\f31586\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}} 33 | {\colortbl;\red0\green0\blue0;\red0\green0\blue255;\red0\green255\blue255;\red0\green255\blue0;\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0;\red255\green255\blue255;\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0; 34 | \red128\green0\blue128;\red128\green0\blue0;\red128\green128\blue0;\red128\green128\blue128;\red192\green192\blue192;\red0\green0\blue0;\red0\green0\blue0;}{\*\defchp \fs22\loch\af31506\hich\af31506\dbch\af31505 }{\*\defpap 35 | \ql \li0\ri0\sa160\sl259\slmult1\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 }\noqfpromote {\stylesheet{\ql \li0\ri0\sa160\sl259\slmult1\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 36 | \af0\afs22\alang1025 \ltrch\fcs0 \fs22\lang1033\langfe1033\loch\f31506\hich\af31506\dbch\af31505\cgrid\langnp1033\langfenp1033 \snext0 \sqformat \spriority0 Normal;}{\*\cs10 \additive \ssemihidden \sunhideused \spriority1 Default Paragraph Font;}{\* 37 | \ts11\tsrowd\trftsWidthB3\trpaddl108\trpaddr108\trpaddfl3\trpaddft3\trpaddfb3\trpaddfr3\trcbpat1\trcfpat1\tblind0\tblindtype3\tsvertalt\tsbrdrt\tsbrdrl\tsbrdrb\tsbrdrr\tsbrdrdgl\tsbrdrdgr\tsbrdrh\tsbrdrv \ql \li0\ri0\sa160\sl259\slmult1 38 | \widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af0\afs22\alang1025 \ltrch\fcs0 \fs22\lang1033\langfe1033\loch\f31506\hich\af31506\dbch\af31505\cgrid\langnp1033\langfenp1033 \snext11 \ssemihidden \sunhideused 39 | Normal Table;}}{\*\rsidtbl \rsid10425903\rsid13042251\rsid13172878}{\mmathPr\mmathFont34\mbrkBin0\mbrkBinSub0\msmallFrac0\mdispDef1\mlMargin0\mrMargin0\mdefJc1\mwrapIndent1440\mintLim0\mnaryLim1}{\info{\operator Eric Woodruff} 40 | {\creatim\yr2019\mo4\dy14\hr13\min31}{\revtim\yr2019\mo10\dy27\hr13\min10}{\version3}{\edmins1}{\nofpages1}{\nofwords390}{\nofchars2226}{\nofcharsws2611}{\vern113}}{\*\xmlnstbl {\xmlns1 http://schemas.microsoft.com/office/word/2003/wordml}} 41 | \paperw12240\paperh15840\margl1440\margr1440\margt1440\margb1440\gutter0\ltrsect 42 | \widowctrl\ftnbj\aenddoc\trackmoves0\trackformatting1\donotembedsysfont0\relyonvml0\donotembedlingdata1\grfdocevents0\validatexml0\showplaceholdtext0\ignoremixedcontent0\saveinvalidxml0\showxmlerrors0\horzdoc\dghspace120\dgvspace120\dghorigin1701 43 | \dgvorigin1984\dghshow0\dgvshow3\jcompress\viewkind1\viewscale100\rsidroot13042251 \fet0{\*\wgrffmtfilter 2450}\ilfomacatclnup0\ltrpar \sectd \ltrsect\linex0\sectdefaultcl\sftnbj {\*\pnseclvl1\pnucrm\pnstart1\pnindent720\pnhang {\pntxta .}}{\*\pnseclvl2 44 | \pnucltr\pnstart1\pnindent720\pnhang {\pntxta .}}{\*\pnseclvl3\pndec\pnstart1\pnindent720\pnhang {\pntxta .}}{\*\pnseclvl4\pnlcltr\pnstart1\pnindent720\pnhang {\pntxta )}}{\*\pnseclvl5\pndec\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl6 45 | \pnlcltr\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl7\pnlcrm\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl8\pnlcltr\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl9\pnlcrm\pnstart1\pnindent720\pnhang 46 | {\pntxtb (}{\pntxta )}}\pard\plain \ltrpar\ql \li0\ri0\sa200\sl276\slmult1\nowidctlpar\wrapdefault\faauto\rin0\lin0\itap0 \rtlch\fcs1 \af0\afs22\alang1025 \ltrch\fcs0 47 | \fs22\lang1033\langfe1033\loch\af31506\hich\af31506\dbch\af31505\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \ab\af1\afs18 \ltrch\fcs0 \b\f1\fs18\ul\lang9\langfe1033\langnp9\insrsid13172878 \hich\af1\dbch\af31505\loch\f1 Microsoft Public License (Ms-PL)}{ 48 | \rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\lang9\langfe1033\langnp9\insrsid13172878 49 | \par \hich\af1\dbch\af31505\loch\f1 This license governs use of the accompanying software. If you use the software, you accept this license. If you do not accept the license, do not use the software. 50 | \par }{\rtlch\fcs1 \ab\af1\afs18 \ltrch\fcs0 \b\f1\fs18\lang9\langfe1033\langnp9\insrsid13172878 \hich\af1\dbch\af31505\loch\f1 1. Definitions}{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\lang9\langfe1033\langnp9\insrsid13172878 51 | \par \hich\af1\dbch\af31505\loch\f1 The terms "reproduce," "reproduction," "derivative works," and "distribution"\hich\af1\dbch\af31505\loch\f1 have the same meaning here as under U.S. copyright law. 52 | \par \hich\af1\dbch\af31505\loch\f1 A "contribution" is the original software, or any additions or changes to the software. 53 | \par \hich\af1\dbch\af31505\loch\f1 A "contributor" is any person that distributes its contribution under this license. 54 | \par \hich\af1\dbch\af31505\loch\f1 "Licensed patents" are a co\hich\af1\dbch\af31505\loch\f1 ntributor's patent claims that read directly on its contribution. 55 | \par }{\rtlch\fcs1 \ab\af1\afs18 \ltrch\fcs0 \b\f1\fs18\lang9\langfe1033\langnp9\insrsid13172878 \hich\af1\dbch\af31505\loch\f1 2. Grant of Rights}{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\lang9\langfe1033\langnp9\insrsid13172878 56 | \par \hich\af1\dbch\af31505\loch\f1 (A) Copyright Grant- Subject to the terms of this license, including the license conditions and limitations in section 3, each contributor grants you a non-exclusive, worl\hich\af1\dbch\af31505\loch\f1 57 | dwide, royalty-free copyright license to reproduce its contribution, prepare derivative works of its contribution, and distribute its contribution or any derivative works that you create. 58 | \par \hich\af1\dbch\af31505\loch\f1 (B) Patent Grant- Subject to the terms of this license, including th\hich\af1\dbch\af31505\loch\f1 59 | e license conditions and limitations in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free license under its licensed patents to make, have made, use, sell, offer for sale, import, and/or otherwise dispose of its contribution 60 | \hich\af1\dbch\af31505\loch\f1 i\hich\af1\dbch\af31505\loch\f1 n the software or derivative works of the contribution in the software. 61 | \par }{\rtlch\fcs1 \ab\af1\afs18 \ltrch\fcs0 \b\f1\fs18\lang9\langfe1033\langnp9\insrsid13172878 \hich\af1\dbch\af31505\loch\f1 3. Conditions and Limitations}{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\lang9\langfe1033\langnp9\insrsid13172878 62 | \par \hich\af1\dbch\af31505\loch\f1 (A) No Trademark License- This license does not grant you rights to use any contributors' name, logo, or trademarks. 63 | \par \hich\af1\dbch\af31505\loch\f1 (B) If you bring a patent claim again\hich\af1\dbch\af31505\loch\f1 st any contributor over patents that you claim are infringed by the software, your patent license from such contributor to the software ends automatically. 64 | 65 | \par \hich\af1\dbch\af31505\loch\f1 (C) If you distribute any portion of the software, you must retain all copyright, patent, trademark,\hich\af1\dbch\af31505\loch\f1 and attribution notices that are present in the software. 66 | \par \hich\af1\dbch\af31505\loch\f1 (D) If you distribute any portion of the software in source code form, you may do so only under this license by including a complete copy of this license with your distribution. If you distribute a 67 | \hich\af1\dbch\af31505\loch\f1 ny portion of the software in compiled or object code form, you may only do so under a license that complies with this license. 68 | \par \hich\af1\dbch\af31505\loch\f1 (E) The software is licensed "as-is." You bear the risk of using it. The contributors give no express warranties, guarantees or \hich\af1\dbch\af31505\loch\f1 69 | conditions. You may have additional consumer rights under your local laws which this license cannot change. To the extent permitted under your local laws, the contributors exclude the implied warranties of merchantability, fitness for a particular purpose 70 | \hich\af1\dbch\af31505\loch\f1 \hich\af1\dbch\af31505\loch\f1 and non-infringement. 71 | \par }{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\lang9\langfe1033\langnp9\insrsid10425903 72 | \par }{\*\themedata 504b030414000600080000002100e9de0fbfff0000001c020000130000005b436f6e74656e745f54797065735d2e786d6cac91cb4ec3301045f748fc83e52d4a 73 | 9cb2400825e982c78ec7a27cc0c8992416c9d8b2a755fbf74cd25442a820166c2cd933f79e3be372bd1f07b5c3989ca74aaff2422b24eb1b475da5df374fd9ad 74 | 5689811a183c61a50f98f4babebc2837878049899a52a57be670674cb23d8e90721f90a4d2fa3802cb35762680fd800ecd7551dc18eb899138e3c943d7e503b6 75 | b01d583deee5f99824e290b4ba3f364eac4a430883b3c092d4eca8f946c916422ecab927f52ea42b89a1cd59c254f919b0e85e6535d135a8de20f20b8c12c3b0 76 | 0c895fcf6720192de6bf3b9e89ecdbd6596cbcdd8eb28e7c365ecc4ec1ff1460f53fe813d3cc7f5b7f020000ffff0300504b030414000600080000002100a5d6 77 | a7e7c0000000360100000b0000005f72656c732f2e72656c73848fcf6ac3300c87ef85bd83d17d51d2c31825762fa590432fa37d00e1287f68221bdb1bebdb4f 78 | c7060abb0884a4eff7a93dfeae8bf9e194e720169aaa06c3e2433fcb68e1763dbf7f82c985a4a725085b787086a37bdbb55fbc50d1a33ccd311ba548b6309512 79 | 0f88d94fbc52ae4264d1c910d24a45db3462247fa791715fd71f989e19e0364cd3f51652d73760ae8fa8c9ffb3c330cc9e4fc17faf2ce545046e37944c69e462 80 | a1a82fe353bd90a865aad41ed0b5b8f9d6fd010000ffff0300504b0304140006000800000021006b799616830000008a0000001c0000007468656d652f746865 81 | 6d652f7468656d654d616e616765722e786d6c0ccc4d0ac3201040e17da17790d93763bb284562b2cbaebbf600439c1a41c7a0d29fdbd7e5e38337cedf14d59b 82 | 4b0d592c9c070d8a65cd2e88b7f07c2ca71ba8da481cc52c6ce1c715e6e97818c9b48d13df49c873517d23d59085adb5dd20d6b52bd521ef2cdd5eb9246a3d8b 83 | 4757e8d3f729e245eb2b260a0238fd010000ffff0300504b030414000600080000002100aa5225dfc60600008b1a0000160000007468656d652f7468656d652f 84 | 7468656d65312e786d6cec595d8bdb46147d2ff43f08bd3bfe92fcb1c41b6cd9ceb6d94d42eca4e4716c8fadc98e344633de8d0981923c160aa569e943037deb 85 | 43691b48a02fe9afd936a54d217fa17746b63c638fbb9b2585a5640d8b343af7ce997bafce1d4997afdc8fa87384134e58dc708b970aae83e3211b9178d2706f 86 | f7bbb99aeb7081e211a22cc60d778eb97b65f7c30f2ea31d11e2083b601ff31dd4704321a63bf93c1fc230e297d814c7706dcc920809384d26f951828ec16f44 87 | f3a542a1928f10895d274611b8bd311e932176fad2a5bbbb74dea1701a0b2e078634e949d7d8b050d8d1615122f89c0734718e106db830cf881df7f17de13a14 88 | 7101171a6e41fdb9f9ddcb79b4b330a2628bad66d7557f0bbb85c1e8b0a4e64c26836c52cff3bd4a33f3af00546ce23ad54ea553c9fc29001a0e61a52917dda7 89 | dfaab7dafe02ab81d2438bef76b55d2e1a78cd7f798373d3973f03af40a97f6f03dfed06104503af4029dedfc07b5eb51478065e81527c65035f2d34db5ed5c0 90 | 2b5048497cb8812ef89572b05c6d061933ba6785d77daf5b2d2d9caf50500d5975c929c62c16db6a2d42f758d2058004522448ec88f9148fd110aa3840940c12 91 | e2ec93490885374531e3305c2815ba8532fc973f4f1da988a01d8c346bc90b98f08d21c9c7e1c3844c45c3fd18bcba1ae4cdcb1fdfbc7cee9c3c7a71f2e89793 92 | c78f4f1efd9c3a32acf6503cd1ad5e7fffc5df4f3f75fe7afeddeb275fd9f15cc7fffed367bffdfaa51d082b5d85e0d5d7cffe78f1ecd5379ffff9c3130bbc99 93 | a0810eef930873e73a3e766eb10816a6426032c783e4ed2cfa2122ba45339e701423398bc57f478406fafa1c5164c1b5b019c13b09488c0d787576cf20dc0b93 94 | 9920168fd7c2c8001e30465b2cb146e19a9c4b0b737f164fec9327331d770ba123dbdc018a8dfc766653d05662731984d8a07993a258a0098eb170e4357688b1 95 | 6575770931e27a408609e36c2c9cbbc46921620d499f0c8c6a5a19ed9108f232b711847c1bb139b8e3b418b5adba8d8f4c24dc15885ac8f73135c27815cd048a 96 | 6c2efb28a27ac0f791086d247bf364a8e33a5c40a6279832a733c29cdb6c6e24b05e2de9d7405eec693fa0f3c84426821cda7cee23c674649b1d06218aa6366c 97 | 8fc4a18efd881f428922e7261336f80133ef10790e7940f1d674df21d848f7e96a701b9455a7b42a107965965872791533a37e7b733a4658490d08bfa1e71189 98 | 4f15f73559f7ff5b5907217df5ed53cbaa2eaaa0371362bda3f6d6647c1b6e5dbc03968cc8c5d7ee369ac53731dc2e9b0decbd74bf976ef77f2fdddbeee7772f 99 | d82b8d06f9965bc574abae36eed1d67dfb9850da13738af7b9daba73e84ca32e0c4a3bf5cc8ab3e7b8690887f24e86090cdc2441cac64998f88488b017a229ec 100 | ef8bae7432e10bd713ee4c19876dbf1ab6fa96783a8b0ed8287d5c2d16e5a3692a1e1c89d578c1cfc6e15143a4e84a75f50896b9576c27ea51794940dabe0d09 101 | 6d329344d942a2ba1c9441520fe610340b09b5b277c2a26e615193ee97a9da6001d4b2acc0d6c9810d57c3f53d30012378a242148f649ed2542fb3ab92f92e33 102 | bd2d984605c03e625901ab4cd725d7adcb93ab4b4bed0c99364868e566925091513d8c87688417d52947cf42e36d735d5fa5d4a02743a1e683d25ad1a8d6fe8d 103 | c579730d76ebda40635d2968ec1c37dc4ad9879219a269c31dc3633f1c4653a81d2eb7bc884ee0ddd95024e90d7f1e6599265cb4110fd3802bd149d520220227 104 | 0e2551c395cbcfd24063a5218a5bb104827061c9d541562e1a3948ba99643c1ee3a1d0d3ae8dc848a7a7a0f0a95658af2af3f383a5259b41ba7be1e8d819d059 105 | 720b4189f9d5a20ce0887078fb534ca33922f03a3313b255fdad35a685eceaef13550da5e3884e43b4e828ba98a77025e5191d7596c5403b5bac1902aa8564d1 106 | 080713d960f5a01add34eb1a2987ad5df7742319394d34573dd35015d935ed2a66ccb06c036bb13c5f93d7582d430c9aa677f854bad725b7bed4bab57d42d625 107 | 20e059fc2c5df70c0d41a3b69acca026196fcab0d4ecc5a8d93b960b3c85da599a84a6fa95a5dbb5b8653dc23a1d0c9eabf383dd7ad5c2d078b9af549156df3d 108 | f44f136c700fc4a30d2f81675470954af8f09020d810f5d49e24950db845ee8bc5ad0147ce2c210df741c16f7a41c90f72859adfc97965af90abf9cd72aee9fb 109 | e562c72f16daadd243682c228c8a7efacda50bafa2e87cf1e5458d6f7c7d89966fdb2e0d599467eaeb4a5e11575f5f8aa5ed5f5f1c02a2f3a052ead6cbf55625 110 | 572f37bb39afddaae5ea41a5956b57826abbdb0efc5abdfbd0758e14d86b9603afd2a9e52ac520c8799582a45fabe7aa5ea9d4f4aacd5ac76b3e5c6c6360e5a9 111 | 7c2c6201e155bc76ff010000ffff0300504b0304140006000800000021000dd1909fb60000001b010000270000007468656d652f7468656d652f5f72656c732f 112 | 7468656d654d616e616765722e786d6c2e72656c73848f4d0ac2301484f78277086f6fd3ba109126dd88d0add40384e4350d363f2451eced0dae2c082e8761be 113 | 9969bb979dc9136332de3168aa1a083ae995719ac16db8ec8e4052164e89d93b64b060828e6f37ed1567914b284d262452282e3198720e274a939cd08a54f980 114 | ae38a38f56e422a3a641c8bbd048f7757da0f19b017cc524bd62107bd5001996509affb3fd381a89672f1f165dfe514173d9850528a2c6cce0239baa4c04ca5b 115 | babac4df000000ffff0300504b01022d0014000600080000002100e9de0fbfff0000001c0200001300000000000000000000000000000000005b436f6e74656e 116 | 745f54797065735d2e786d6c504b01022d0014000600080000002100a5d6a7e7c0000000360100000b00000000000000000000000000300100005f72656c732f 117 | 2e72656c73504b01022d00140006000800000021006b799616830000008a0000001c00000000000000000000000000190200007468656d652f7468656d652f74 118 | 68656d654d616e616765722e786d6c504b01022d0014000600080000002100aa5225dfc60600008b1a00001600000000000000000000000000d6020000746865 119 | 6d652f7468656d652f7468656d65312e786d6c504b01022d00140006000800000021000dd1909fb60000001b0100002700000000000000000000000000d00900007468656d652f7468656d652f5f72656c732f7468656d654d616e616765722e786d6c2e72656c73504b050600000000050005005d010000cb0a00000000} 120 | {\*\colorschememapping 3c3f786d6c2076657273696f6e3d22312e302220656e636f64696e673d225554462d3822207374616e64616c6f6e653d22796573223f3e0d0a3c613a636c724d 121 | 617020786d6c6e733a613d22687474703a2f2f736368656d61732e6f70656e786d6c666f726d6174732e6f72672f64726177696e676d6c2f323030362f6d6169 122 | 6e22206267313d226c743122207478313d22646b3122206267323d226c743222207478323d22646b322220616363656e74313d22616363656e74312220616363 123 | 656e74323d22616363656e74322220616363656e74333d22616363656e74332220616363656e74343d22616363656e74342220616363656e74353d22616363656e74352220616363656e74363d22616363656e74362220686c696e6b3d22686c696e6b2220666f6c486c696e6b3d22666f6c486c696e6b222f3e} 124 | {\*\latentstyles\lsdstimax377\lsdlockeddef0\lsdsemihiddendef0\lsdunhideuseddef0\lsdqformatdef0\lsdprioritydef99{\lsdlockedexcept \lsdqformat1 \lsdpriority0 \lsdlocked0 Normal;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 1; 125 | \lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 2;\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 3;\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 4; 126 | \lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 5;\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 6;\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 7; 127 | \lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 8;\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 9;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 index 1; 128 | \lsdsemihidden1 \lsdunhideused1 \lsdlocked0 index 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 index 3;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 index 4;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 index 5; 129 | \lsdsemihidden1 \lsdunhideused1 \lsdlocked0 index 6;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 index 7;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 index 8;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 index 9; 130 | \lsdsemihidden1 \lsdunhideused1 \lsdpriority39 \lsdlocked0 toc 1;\lsdsemihidden1 \lsdunhideused1 \lsdpriority39 \lsdlocked0 toc 2;\lsdsemihidden1 \lsdunhideused1 \lsdpriority39 \lsdlocked0 toc 3; 131 | \lsdsemihidden1 \lsdunhideused1 \lsdpriority39 \lsdlocked0 toc 4;\lsdsemihidden1 \lsdunhideused1 \lsdpriority39 \lsdlocked0 toc 5;\lsdsemihidden1 \lsdunhideused1 \lsdpriority39 \lsdlocked0 toc 6; 132 | \lsdsemihidden1 \lsdunhideused1 \lsdpriority39 \lsdlocked0 toc 7;\lsdsemihidden1 \lsdunhideused1 \lsdpriority39 \lsdlocked0 toc 8;\lsdsemihidden1 \lsdunhideused1 \lsdpriority39 \lsdlocked0 toc 9;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Normal Indent; 133 | \lsdsemihidden1 \lsdunhideused1 \lsdlocked0 footnote text;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 annotation text;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 header;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 footer; 134 | \lsdsemihidden1 \lsdunhideused1 \lsdlocked0 index heading;\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority35 \lsdlocked0 caption;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 table of figures; 135 | \lsdsemihidden1 \lsdunhideused1 \lsdlocked0 envelope address;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 envelope return;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 footnote reference;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 annotation reference; 136 | \lsdsemihidden1 \lsdunhideused1 \lsdlocked0 line number;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 page number;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 endnote reference;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 endnote text; 137 | \lsdsemihidden1 \lsdunhideused1 \lsdlocked0 table of authorities;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 macro;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 toa heading;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List; 138 | \lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Bullet;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Number;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List 3; 139 | \lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List 4;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List 5;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Bullet 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Bullet 3; 140 | \lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Bullet 4;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Bullet 5;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Number 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Number 3; 141 | \lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Number 4;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Number 5;\lsdqformat1 \lsdpriority10 \lsdlocked0 Title;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Closing; 142 | \lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Signature;\lsdsemihidden1 \lsdunhideused1 \lsdpriority1 \lsdlocked0 Default Paragraph Font;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Body Text;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Body Text Indent; 143 | \lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Continue;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Continue 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Continue 3;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Continue 4; 144 | \lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Continue 5;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Message Header;\lsdqformat1 \lsdpriority11 \lsdlocked0 Subtitle;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Salutation; 145 | \lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Date;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Body Text First Indent;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Body Text First Indent 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Note Heading; 146 | \lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Body Text 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Body Text 3;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Body Text Indent 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Body Text Indent 3; 147 | \lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Block Text;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Hyperlink;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 FollowedHyperlink;\lsdqformat1 \lsdpriority22 \lsdlocked0 Strong; 148 | \lsdqformat1 \lsdpriority20 \lsdlocked0 Emphasis;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Document Map;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Plain Text;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 E-mail Signature; 149 | \lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Top of Form;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Bottom of Form;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Normal (Web);\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Acronym; 150 | \lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Address;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Cite;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Code;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Definition; 151 | \lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Keyboard;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Preformatted;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Sample;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Typewriter; 152 | \lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Variable;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 annotation subject;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 No List;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Outline List 1; 153 | \lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Outline List 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Outline List 3;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Balloon Text;\lsdpriority39 \lsdlocked0 Table Grid; 154 | \lsdsemihidden1 \lsdlocked0 Placeholder Text;\lsdqformat1 \lsdpriority1 \lsdlocked0 No Spacing;\lsdpriority60 \lsdlocked0 Light Shading;\lsdpriority61 \lsdlocked0 Light List;\lsdpriority62 \lsdlocked0 Light Grid; 155 | \lsdpriority63 \lsdlocked0 Medium Shading 1;\lsdpriority64 \lsdlocked0 Medium Shading 2;\lsdpriority65 \lsdlocked0 Medium List 1;\lsdpriority66 \lsdlocked0 Medium List 2;\lsdpriority67 \lsdlocked0 Medium Grid 1;\lsdpriority68 \lsdlocked0 Medium Grid 2; 156 | \lsdpriority69 \lsdlocked0 Medium Grid 3;\lsdpriority70 \lsdlocked0 Dark List;\lsdpriority71 \lsdlocked0 Colorful Shading;\lsdpriority72 \lsdlocked0 Colorful List;\lsdpriority73 \lsdlocked0 Colorful Grid;\lsdpriority60 \lsdlocked0 Light Shading Accent 1; 157 | \lsdpriority61 \lsdlocked0 Light List Accent 1;\lsdpriority62 \lsdlocked0 Light Grid Accent 1;\lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 1;\lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 1;\lsdpriority65 \lsdlocked0 Medium List 1 Accent 1; 158 | \lsdsemihidden1 \lsdlocked0 Revision;\lsdqformat1 \lsdpriority34 \lsdlocked0 List Paragraph;\lsdqformat1 \lsdpriority29 \lsdlocked0 Quote;\lsdqformat1 \lsdpriority30 \lsdlocked0 Intense Quote;\lsdpriority66 \lsdlocked0 Medium List 2 Accent 1; 159 | \lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 1;\lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 1;\lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 1;\lsdpriority70 \lsdlocked0 Dark List Accent 1;\lsdpriority71 \lsdlocked0 Colorful Shading Accent 1; 160 | \lsdpriority72 \lsdlocked0 Colorful List Accent 1;\lsdpriority73 \lsdlocked0 Colorful Grid Accent 1;\lsdpriority60 \lsdlocked0 Light Shading Accent 2;\lsdpriority61 \lsdlocked0 Light List Accent 2;\lsdpriority62 \lsdlocked0 Light Grid Accent 2; 161 | \lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 2;\lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 2;\lsdpriority65 \lsdlocked0 Medium List 1 Accent 2;\lsdpriority66 \lsdlocked0 Medium List 2 Accent 2; 162 | \lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 2;\lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 2;\lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 2;\lsdpriority70 \lsdlocked0 Dark List Accent 2;\lsdpriority71 \lsdlocked0 Colorful Shading Accent 2; 163 | \lsdpriority72 \lsdlocked0 Colorful List Accent 2;\lsdpriority73 \lsdlocked0 Colorful Grid Accent 2;\lsdpriority60 \lsdlocked0 Light Shading Accent 3;\lsdpriority61 \lsdlocked0 Light List Accent 3;\lsdpriority62 \lsdlocked0 Light Grid Accent 3; 164 | \lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 3;\lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 3;\lsdpriority65 \lsdlocked0 Medium List 1 Accent 3;\lsdpriority66 \lsdlocked0 Medium List 2 Accent 3; 165 | \lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 3;\lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 3;\lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 3;\lsdpriority70 \lsdlocked0 Dark List Accent 3;\lsdpriority71 \lsdlocked0 Colorful Shading Accent 3; 166 | \lsdpriority72 \lsdlocked0 Colorful List Accent 3;\lsdpriority73 \lsdlocked0 Colorful Grid Accent 3;\lsdpriority60 \lsdlocked0 Light Shading Accent 4;\lsdpriority61 \lsdlocked0 Light List Accent 4;\lsdpriority62 \lsdlocked0 Light Grid Accent 4; 167 | \lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 4;\lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 4;\lsdpriority65 \lsdlocked0 Medium List 1 Accent 4;\lsdpriority66 \lsdlocked0 Medium List 2 Accent 4; 168 | \lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 4;\lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 4;\lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 4;\lsdpriority70 \lsdlocked0 Dark List Accent 4;\lsdpriority71 \lsdlocked0 Colorful Shading Accent 4; 169 | \lsdpriority72 \lsdlocked0 Colorful List Accent 4;\lsdpriority73 \lsdlocked0 Colorful Grid Accent 4;\lsdpriority60 \lsdlocked0 Light Shading Accent 5;\lsdpriority61 \lsdlocked0 Light List Accent 5;\lsdpriority62 \lsdlocked0 Light Grid Accent 5; 170 | \lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 5;\lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 5;\lsdpriority65 \lsdlocked0 Medium List 1 Accent 5;\lsdpriority66 \lsdlocked0 Medium List 2 Accent 5; 171 | \lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 5;\lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 5;\lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 5;\lsdpriority70 \lsdlocked0 Dark List Accent 5;\lsdpriority71 \lsdlocked0 Colorful Shading Accent 5; 172 | \lsdpriority72 \lsdlocked0 Colorful List Accent 5;\lsdpriority73 \lsdlocked0 Colorful Grid Accent 5;\lsdpriority60 \lsdlocked0 Light Shading Accent 6;\lsdpriority61 \lsdlocked0 Light List Accent 6;\lsdpriority62 \lsdlocked0 Light Grid Accent 6; 173 | \lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 6;\lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 6;\lsdpriority65 \lsdlocked0 Medium List 1 Accent 6;\lsdpriority66 \lsdlocked0 Medium List 2 Accent 6; 174 | \lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 6;\lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 6;\lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 6;\lsdpriority70 \lsdlocked0 Dark List Accent 6;\lsdpriority71 \lsdlocked0 Colorful Shading Accent 6; 175 | \lsdpriority72 \lsdlocked0 Colorful List Accent 6;\lsdpriority73 \lsdlocked0 Colorful Grid Accent 6;\lsdqformat1 \lsdpriority19 \lsdlocked0 Subtle Emphasis;\lsdqformat1 \lsdpriority21 \lsdlocked0 Intense Emphasis; 176 | \lsdqformat1 \lsdpriority31 \lsdlocked0 Subtle Reference;\lsdqformat1 \lsdpriority32 \lsdlocked0 Intense Reference;\lsdqformat1 \lsdpriority33 \lsdlocked0 Book Title;\lsdsemihidden1 \lsdunhideused1 \lsdpriority37 \lsdlocked0 Bibliography; 177 | \lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority39 \lsdlocked0 TOC Heading;\lsdpriority41 \lsdlocked0 Plain Table 1;\lsdpriority42 \lsdlocked0 Plain Table 2;\lsdpriority43 \lsdlocked0 Plain Table 3;\lsdpriority44 \lsdlocked0 Plain Table 4; 178 | \lsdpriority45 \lsdlocked0 Plain Table 5;\lsdpriority40 \lsdlocked0 Grid Table Light;\lsdpriority46 \lsdlocked0 Grid Table 1 Light;\lsdpriority47 \lsdlocked0 Grid Table 2;\lsdpriority48 \lsdlocked0 Grid Table 3;\lsdpriority49 \lsdlocked0 Grid Table 4; 179 | \lsdpriority50 \lsdlocked0 Grid Table 5 Dark;\lsdpriority51 \lsdlocked0 Grid Table 6 Colorful;\lsdpriority52 \lsdlocked0 Grid Table 7 Colorful;\lsdpriority46 \lsdlocked0 Grid Table 1 Light Accent 1;\lsdpriority47 \lsdlocked0 Grid Table 2 Accent 1; 180 | \lsdpriority48 \lsdlocked0 Grid Table 3 Accent 1;\lsdpriority49 \lsdlocked0 Grid Table 4 Accent 1;\lsdpriority50 \lsdlocked0 Grid Table 5 Dark Accent 1;\lsdpriority51 \lsdlocked0 Grid Table 6 Colorful Accent 1; 181 | \lsdpriority52 \lsdlocked0 Grid Table 7 Colorful Accent 1;\lsdpriority46 \lsdlocked0 Grid Table 1 Light Accent 2;\lsdpriority47 \lsdlocked0 Grid Table 2 Accent 2;\lsdpriority48 \lsdlocked0 Grid Table 3 Accent 2; 182 | \lsdpriority49 \lsdlocked0 Grid Table 4 Accent 2;\lsdpriority50 \lsdlocked0 Grid Table 5 Dark Accent 2;\lsdpriority51 \lsdlocked0 Grid Table 6 Colorful Accent 2;\lsdpriority52 \lsdlocked0 Grid Table 7 Colorful Accent 2; 183 | \lsdpriority46 \lsdlocked0 Grid Table 1 Light Accent 3;\lsdpriority47 \lsdlocked0 Grid Table 2 Accent 3;\lsdpriority48 \lsdlocked0 Grid Table 3 Accent 3;\lsdpriority49 \lsdlocked0 Grid Table 4 Accent 3; 184 | \lsdpriority50 \lsdlocked0 Grid Table 5 Dark Accent 3;\lsdpriority51 \lsdlocked0 Grid Table 6 Colorful Accent 3;\lsdpriority52 \lsdlocked0 Grid Table 7 Colorful Accent 3;\lsdpriority46 \lsdlocked0 Grid Table 1 Light Accent 4; 185 | \lsdpriority47 \lsdlocked0 Grid Table 2 Accent 4;\lsdpriority48 \lsdlocked0 Grid Table 3 Accent 4;\lsdpriority49 \lsdlocked0 Grid Table 4 Accent 4;\lsdpriority50 \lsdlocked0 Grid Table 5 Dark Accent 4; 186 | \lsdpriority51 \lsdlocked0 Grid Table 6 Colorful Accent 4;\lsdpriority52 \lsdlocked0 Grid Table 7 Colorful Accent 4;\lsdpriority46 \lsdlocked0 Grid Table 1 Light Accent 5;\lsdpriority47 \lsdlocked0 Grid Table 2 Accent 5; 187 | \lsdpriority48 \lsdlocked0 Grid Table 3 Accent 5;\lsdpriority49 \lsdlocked0 Grid Table 4 Accent 5;\lsdpriority50 \lsdlocked0 Grid Table 5 Dark Accent 5;\lsdpriority51 \lsdlocked0 Grid Table 6 Colorful Accent 5; 188 | \lsdpriority52 \lsdlocked0 Grid Table 7 Colorful Accent 5;\lsdpriority46 \lsdlocked0 Grid Table 1 Light Accent 6;\lsdpriority47 \lsdlocked0 Grid Table 2 Accent 6;\lsdpriority48 \lsdlocked0 Grid Table 3 Accent 6; 189 | \lsdpriority49 \lsdlocked0 Grid Table 4 Accent 6;\lsdpriority50 \lsdlocked0 Grid Table 5 Dark Accent 6;\lsdpriority51 \lsdlocked0 Grid Table 6 Colorful Accent 6;\lsdpriority52 \lsdlocked0 Grid Table 7 Colorful Accent 6; 190 | \lsdpriority46 \lsdlocked0 List Table 1 Light;\lsdpriority47 \lsdlocked0 List Table 2;\lsdpriority48 \lsdlocked0 List Table 3;\lsdpriority49 \lsdlocked0 List Table 4;\lsdpriority50 \lsdlocked0 List Table 5 Dark; 191 | \lsdpriority51 \lsdlocked0 List Table 6 Colorful;\lsdpriority52 \lsdlocked0 List Table 7 Colorful;\lsdpriority46 \lsdlocked0 List Table 1 Light Accent 1;\lsdpriority47 \lsdlocked0 List Table 2 Accent 1;\lsdpriority48 \lsdlocked0 List Table 3 Accent 1; 192 | \lsdpriority49 \lsdlocked0 List Table 4 Accent 1;\lsdpriority50 \lsdlocked0 List Table 5 Dark Accent 1;\lsdpriority51 \lsdlocked0 List Table 6 Colorful Accent 1;\lsdpriority52 \lsdlocked0 List Table 7 Colorful Accent 1; 193 | \lsdpriority46 \lsdlocked0 List Table 1 Light Accent 2;\lsdpriority47 \lsdlocked0 List Table 2 Accent 2;\lsdpriority48 \lsdlocked0 List Table 3 Accent 2;\lsdpriority49 \lsdlocked0 List Table 4 Accent 2; 194 | \lsdpriority50 \lsdlocked0 List Table 5 Dark Accent 2;\lsdpriority51 \lsdlocked0 List Table 6 Colorful Accent 2;\lsdpriority52 \lsdlocked0 List Table 7 Colorful Accent 2;\lsdpriority46 \lsdlocked0 List Table 1 Light Accent 3; 195 | \lsdpriority47 \lsdlocked0 List Table 2 Accent 3;\lsdpriority48 \lsdlocked0 List Table 3 Accent 3;\lsdpriority49 \lsdlocked0 List Table 4 Accent 3;\lsdpriority50 \lsdlocked0 List Table 5 Dark Accent 3; 196 | \lsdpriority51 \lsdlocked0 List Table 6 Colorful Accent 3;\lsdpriority52 \lsdlocked0 List Table 7 Colorful Accent 3;\lsdpriority46 \lsdlocked0 List Table 1 Light Accent 4;\lsdpriority47 \lsdlocked0 List Table 2 Accent 4; 197 | \lsdpriority48 \lsdlocked0 List Table 3 Accent 4;\lsdpriority49 \lsdlocked0 List Table 4 Accent 4;\lsdpriority50 \lsdlocked0 List Table 5 Dark Accent 4;\lsdpriority51 \lsdlocked0 List Table 6 Colorful Accent 4; 198 | \lsdpriority52 \lsdlocked0 List Table 7 Colorful Accent 4;\lsdpriority46 \lsdlocked0 List Table 1 Light Accent 5;\lsdpriority47 \lsdlocked0 List Table 2 Accent 5;\lsdpriority48 \lsdlocked0 List Table 3 Accent 5; 199 | \lsdpriority49 \lsdlocked0 List Table 4 Accent 5;\lsdpriority50 \lsdlocked0 List Table 5 Dark Accent 5;\lsdpriority51 \lsdlocked0 List Table 6 Colorful Accent 5;\lsdpriority52 \lsdlocked0 List Table 7 Colorful Accent 5; 200 | \lsdpriority46 \lsdlocked0 List Table 1 Light Accent 6;\lsdpriority47 \lsdlocked0 List Table 2 Accent 6;\lsdpriority48 \lsdlocked0 List Table 3 Accent 6;\lsdpriority49 \lsdlocked0 List Table 4 Accent 6; 201 | \lsdpriority50 \lsdlocked0 List Table 5 Dark Accent 6;\lsdpriority51 \lsdlocked0 List Table 6 Colorful Accent 6;\lsdpriority52 \lsdlocked0 List Table 7 Colorful Accent 6;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Mention; 202 | \lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Smart Hyperlink;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Hashtag;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Unresolved Mention;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Smart Link; 203 | \lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Smart Link Error;}}{\*\datastore 0105000002000000180000004d73786d6c322e534158584d4c5265616465722e362e3000000000000000000000060000 204 | d0cf11e0a1b11ae1000000000000000000000000000000003e000300feff090006000000000000000000000001000000010000000000000000100000feffffff00000000feffffff0000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 205 | ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 206 | ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 207 | ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 208 | fffffffffffffffffdfffffffeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 209 | ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 210 | ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 211 | ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 212 | ffffffffffffffffffffffffffffffff52006f006f007400200045006e00740072007900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016000500ffffffffffffffffffffffff0c6ad98892f1d411a65f0040963251e5000000000000000000000000e0f5 213 | e5a5028dd501feffffff00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff00000000000000000000000000000000000000000000000000000000 214 | 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff0000000000000000000000000000000000000000000000000000 215 | 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff000000000000000000000000000000000000000000000000 216 | 0000000000000000000000000000000000000000000000000105000000000000}} --------------------------------------------------------------------------------