Code/SymbolsSource.ps1
#requires -version 5.0 ############################################################################### # WintellectPowerShell Module # Copyright (c) 2010-2017 - John Robbins/Wintellect # # Do whatever you want with this module, but please do give credit. ############################################################################### # Always make sure all variables are defined and all best practices are # followed. Set-StrictMode -version Latest ############################################################################### # Script Global Variables ############################################################################### # The array that contains all the versions. $script:vsVersionArray = "2012", "2013", "2015", "2017" ############################################################################### # Module Only Functions ############################################################################### # Does the lookups and builds the hash tables for Get-SourceServer, Get-SymbolServer function GetCommonSettings($propertyValue="", $envVariable="") { $returnHash = [ordered]@{} # The XPath to look for. $xPathLookup = $script:dbgPropertyXPath -f $propertyValue # Loop through all the VS versions. for ($i = 0; $i -lt $script:vsVersionArray.Length; $i++) { [xml]$settings = OpenSettingsFile $script:vsVersionArray[$i] if ($null -ne $settings) { # Look for the property itself. $propNode = $settings | Select-Xml -XPath $xPathLookup # Add the value to the hash table. $returnHash["VS " + $script:vsVersionArray[$i]] = $propNode.Node.InnerText } } # Do the environment variable, too. if ($envVariable -ne "") { $envVal = Get-ItemProperty -Path HKCU:\Environment -Name $envVariable -ErrorAction SilentlyContinue if ($null -ne $envVal) { $returnHash[$envVariable] = $envVal.$envVariable } } return $returnHash } function CreateDirectoryIfNeeded { [CmdletBinding(SupportsShouldProcess=$true)] param ( [string] $directory="" ) if ($PSCmdlet.ShouldProcess($directory,"Creating directory")) { if ( ! (Test-Path -Path $directory -type "Container")) { New-Item -type directory -Path $directory > $null } } } # Makes doing ShouldProcess easier. function Set-ItemPropertyScript { [CmdletBinding(SupportsShouldProcess=$true)] param ( [Parameter(Mandatory=$true)] $path, [Parameter(Mandatory=$true)] $name, [Parameter(Mandatory=$true)] $value, $type=$null ) $propString = "Item: " + $path.ToString() + " Property: " + $name if ($PSCmdLet.ShouldProcess($propString ,"Set Property")) { if ($null -eq $type) { Set-ItemProperty -Path $path -Name $name -Value $value } else { Set-ItemProperty -Path $path -Name $name -Value $value -Type $type } } } function SetInternalSymbolServer([xml]$settings, $cacheDirectory, $symPath) { CreateDirectoryIfNeeded -directory $CacheDirectory # Turn off Just My Code. $xPathLookup = $script:dbgPropertyXPath -f "JustMyCode" $justMyCode = $settings | Select-Xml -XPath $xPathLookup $justMyCode.Node.InnerText = "0" # Turn on Source Server Diagnostics as that's a good thing. :) $xPathLookup = $script:dbgPropertyXPath -f "ShowSourceServerDiagnostics" $ssDiag = $settings | Select-Xml -XPath $xPathLookup $ssDiag.Node.InnerText = "1" # Turn off .NET Framework Source stepping. $xPathLookup = $script:dbgPropertyXPath -f "FrameworkSourceStepping" $noFramework = $settings | Select-Xml -XPath $xPathLookup $noFramework.Node.InnerText = "0" # Turn off using the Microsoft symbol servers. $xPathLookup = $script:dbgPropertyXPath -f "SymbolUseMSSymbolServers" $noMSSymServers = $settings | Select-Xml -XPath $xPathLookup $noMSSymServers.Node.InnerText = "0" # Set the symbol cache dir to the same value as used in the environment # variable. $xPathLookup = $script:dbgPropertyXPath -f "SymbolCacheDir" $cacheDir = $settings | Select-Xml -XPath $xPathLookup $cacheDir.Node.InnerText = $CacheDirectory } function SetPublicSymbolServer([xml]$settings, $cacheDirectory, $symPath, $vsVersion) { CreateDirectoryIfNeeded -directory $CacheDirectory # Turn off Just My Code. $xPathLookup = $script:dbgPropertyXPath -f "JustMyCode" $justMyCode = $settings | Select-Xml -XPath $xPathLookup $justMyCode.Node.InnerText = "0" # Turn on .NET Framework Source stepping. $xPathLookup = $script:dbgPropertyXPath -f "FrameworkSourceStepping" $noFramework = $settings | Select-Xml -XPath $xPathLookup $noFramework.Node.InnerText = "1" # Turn on Source Server Support. $xPathLookup = $script:dbgPropertyXPath -f "UseSourceServer" $useSS = $settings | Select-Xml -XPath $xPathLookup $useSS.Node.InnerText = "1" # Turn on Source Server Diagnostics as that's a good thing. :) $xPathLookup = $script:dbgPropertyXPath -f "ShowSourceServerDiagnostics" $ssDiag = $settings | Select-Xml -XPath $xPathLookup $ssDiag.Node.InnerText = "1" # It's very important to turn off requiring the source to match exactly. # With this flag on, .NET Reference Source Stepping doesn't work. $xPathLookup = $script:dbgPropertyXPath -f "UseDocumentChecksum" $noDoc = $settings | Select-Xml -XPath $xPathLookup $noDoc.Node.InnerText = "0" # Turn off using the Microsoft symbol servers. $xPathLookup = $script:dbgPropertyXPath -f "SymbolUseMSSymbolServers" $noMSSymServers = $settings | Select-Xml -XPath $xPathLookup $noMSSymServers.Node.InnerText = "0" # Set the VS SymbolPath setting. $xPathLookup = $script:dbgPropertyXPath -f "SymbolPath" $symPath = $settings | Select-Xml -XPath $xPathLookup $symPath.Node.IsEmpty = $true # Tell VS that all paths are empty. $xPathLookup = $script:dbgPropertyXPath -f "SymbolPathState" $symPathState = $settings | Select-Xml -XPath $xPathLookup $symPathState.Node.IsEmpty = $true # Set the symbol cache dir to the same value as used in the environment # variable. $xPathLookup = $script:dbgPropertyXPath -f "SymbolCacheDir" $cacheDir = $settings | Select-Xml -XPath $xPathLookup $cacheDir.Node.InnerText = $CacheDirectory # Turn on the SourceLinking option new to VS 2017. if ($vsVersion -ge "2017") { $xPathLookup = $script:dbgPropertyXPath -f "UseSourceLink" $ssDiag = $settings | Select-Xml -XPath $xPathLookup $ssDiag.Node.InnerText = "1" } } ############################################################################### # Public Cmdlets ############################################################################### function Get-SourceServer { <# .SYNOPSIS Returns a hashtable of the current source server settings. .DESCRIPTION Returns a hashtable with the current source server directories settings for VS 2012-2017, and the _NT_SOURCE_PATH enviroment variable used by WinDBG. .OUTPUTS HashTable The keys are, if all present, VS 2012-2017, and WinDBG. The values are those set for each debugger. .LINK http://www.wintellect.com/devcenter/author/jrobbins https://github.com/Wintellect/WintellectPowerShell #> GetCommonSettings SourceServerExtractToDirectory _NT_SOURCE_PATH } ############################################################################### function Get-SymbolServer { <# .SYNOPSIS Returns a hashtable of the current symbol server settings. .DESCRIPTION Returns a hashtable with the current source server directories settings for VS 2012-2017, and the _NT_SYMBOL_PATH enviroment variable. .LINK http://www.wintellect.com/devcenter/author/jrobbins https://github.com/Wintellect/WintellectPowerShell #> GetCommonSettings SymbolCacheDir _NT_SYMBOL_PATH } ############################################################################### function Set-SourceServer { <# .SYNOPSIS Sets the source server directory. .DESCRIPTION Sets the source server cache directory for VS 2012-2017, and WinDBG through the _NT_SOURCE_PATH environment variable to all reference the same location. This ensures you only download the file once no matter which debugger you use. Because this cmdlet sets an environment variable you need to log off to ensure it's properly set. .PARAMETER CacheDirectory The directory to use. If the directory does not exist, it will be created. .PARAMETER CurrentEnvironmentOnly If specified will only set the current PowerShell window _NT_SOURCE_PATH environment variable and not overwrite the global settings. This is primarily for use with WinDBG as Visual Studio does not use this environment variable. .LINK http://www.wintellect.com/devcenter/author/jrobbins https://github.com/Wintellect/WintellectPowerShell #> [CmdletBinding(SupportsShouldProcess=$true)] # This triggers on the environment variable setting ($env:_NT_SOURCE_PATH = "SRV*" + $CacheDirectory) # That seems like an issue in the rule. [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseDeclaredVarsMoreThanAssignments", "", Scope="Function")] param ( [Parameter(Mandatory=$true, HelpMessage="Please specify the source server cache directory")] [string] $CacheDirectory, [switch] $CurrentEnvironmentOnly ) # Check if VS is running if we are going to be setting the global stuff. if (($CurrentEnvironmentOnly -eq $false) -and (Get-Process -Name 'devenv' -ErrorAction SilentlyContinue)) { throw "Visual Studio is running. Please close all instances before executing Set-SourceServer" } # Does the cache directory exist or need to be created? CreateDirectoryIfNeeded $CacheDirectory # If just setting the current environment, that's easy. if ($CurrentEnvironmentOnly) { $env:_NT_SOURCE_PATH = "SRV*" + $CacheDirectory } else { # The XPath to look for. $xPathLookup = $script:dbgPropertyXPath -f "SourceServerExtractToDirectory" # Loop through all VS versions. for ($i = 0; $i -lt $script:vsVersionArray.Length; $i++) { [xml]$settings = OpenSettingsFile $script:vsVersionArray[$i] if ($null -ne $settings) { if ($PSCmdlet.ShouldProcess("VS " + $script:vsVersionArray[$i], "Setting Source Server")) { # Grab the SourceServerExtractToDirectory element $extractDirNode = $settings | Select-Xml -XPath $xPathLookup # Set it. $extractDirNode.Node.InnerXml = $CacheDirectory WriteSettingsFile $script:vsVersionArray[$i] $settings } } } # Always set the _NT_SOURCE_PATH value for WinDBG. Set-ItemProperty -Path HKCU:\Environment -Name _NT_SOURCE_PATH -Value "SRV*$CacheDirectory" } if ($CurrentEnvironmentOnly) { Write-Verbose -Message "`nThe _NT_SOURCE_PATH environment variable was updated for this window only`n" } else { Write-Verbose -Message "`nPlease log out to activate the new source server settings`n" } } ############################################################################### function Set-SymbolServer { <# .SYNOPSIS Sets up a computer to use a symbol server. DESCRIPTION Sets up both the _NT_SYMBOL_PATH environment variable as well as VS 2012-2017, (for all installed) to use a common symbol cache directory as well as common symbol servers. Optionally can be used to only set _NT_SYMBOL_PATH for an individual PowerShell window. .PARAMETER Internal Sets the symbol server to use to http://SymWeb. Visual Studio will not use the public symbol servers. This will turn off the .NET Framework Source Stepping. This switch is intended for internal Microsoft use only. You must specify either -Internal or -Public to the script. .PARAMETER Public Sets the symbol server to use as the two public symbol servers from Microsoft. All the appropriate settings are configured to properly have .NET Reference Source stepping working and for VS 2017 and above, Source Linking turned on so you can debug GitHub-based repositories, like .NET Core, etc. .PARAMETER CacheDirectory Defaults to C:\SYMBOLS\PUBLIC for -Public and C:\SYMBOLS\INTERNAL for -Internal. .PARAMETER SymbolServers A string array of additional symbol servers to use. If -Internal is set, these additional symbol servers will appear before HTTP://SYMWEB. If -Public is set, these symbol servers will appear before the public symbol servers so both the environment variable and Visual Studio have the same search order. .PARAMETER CurrentEnvironmentOnly If specified will only set the current PowerShell window _NT_SYMBOL_PATH environment variable and not overwrite the global settings. This is primarily for use with WinDBG as Visual Studio requires settings files for the cache directory. .LINK http://www.wintellect.com/devcenter/author/jrobbins https://github.com/Wintellect/WintellectPowerShell #> [CmdLetBinding(SupportsShouldProcess=$true)] param ( [switch] $Internal, [switch] $Public, [string] $CacheDirectory="", [string[]] $SymbolServers=@(), [switch] $CurrentEnvironmentOnly) # Do the parameter checking. if ($Internal -eq $Public) { throw "You must specify either -Internal or -Public" } # Check if VS is running if we are going to be setting the global stuff. if (($CurrentEnvironmentOnly -eq $false) -and (Get-Process -Name 'devenv' -ErrorAction SilentlyContinue)) { throw "Visual Studio is running. Please close all instances before running Set-SymbolServer" } if ($Internal) { if ($CacheDirectory.Length -eq 0) { $CacheDirectory = "C:\SYMBOLS\INTERNAL" } $symPath = "" for ($i = 0 ; $i -lt $SymbolServers.Length ; $i++) { $symPath += "SRV*$CacheDirectory*" $symPath += $SymbolServers[$i] $symPath += ";" } $symPath += "SRV*$CacheDirectory*http://SYMWEB" if ($CurrentEnvironmentOnly) { CreateDirectoryIfNeeded -directory $CacheDirectory $env:_NT_SYMBOL_PATH = $symPath } else { # Set the environment variable. Set-ItemPropertyScript HKCU:\Environment _NT_SYMBOL_PATH $symPath for ($i = 0; $i -lt $script:vsVersionArray.Length; $i++) { [xml]$settings = OpenSettingsFile $script:vsVersionArray[$i] if ($null -ne $settings) { if ($PSCmdlet.ShouldProcess("VS "+ $script:vsVersionArray[$i], "Symbol Server settings for internal usage")) { SetInternalSymbolServer $settings $CacheDirectory $symPath WriteSettingsFile $script:vsVersionArray[$i] $settings } } } } } else { if ($CacheDirectory.Length -eq 0) { $CacheDirectory = "C:\SYMBOLS\PUBLIC" } # It's public so we have a little different processing to do as there are # two public symbol servers where MSFT provides symbols. $refSrcPath = "$CacheDirectory*http://referencesource.microsoft.com/symbols" $msdlPath = "$CacheDirectory*https://msdl.microsoft.com/download/symbols" $extraPaths = "" # Poke on any additional symbol servers. I've keeping everything the # same between VS as WinDBG. for ($i = 0 ; $i -lt $SymbolServers.Length ; $i++) { $extraPaths += "SRV*$CacheDirectory*" $extraPaths += $SymbolServers[$i] $extraPaths += ";" } $envPath = "$extraPaths" + "SRV*$refSrcPath;SRV*$msdlPath" if ($CurrentEnvironmentOnly) { CreateDirectoryIfNeeded -directory $CacheDirectory $env:_NT_SYMBOL_PATH = $envPath } else { Set-ItemPropertyScript HKCU:\Environment _NT_SYMBOL_PATH $envPath for ($i = 0; $i -lt $script:vsVersionArray.Length; $i++) { [xml]$settings = OpenSettingsFile $script:vsVersionArray[$i] if ($null -ne $settings) { if ($PSCmdlet.ShouldProcess("VS "+ $script:vsVersionArray[$i], "Symbol Server settings for public usage")) { SetPublicSymbolServer $settings $CacheDirectory $envPath $script:vsVersionArray[$i] WriteSettingsFile $script:vsVersionArray[$i] $settings } } } } } if ($CurrentEnvironmentOnly) { Write-Verbose -Message "`nThe _NT_SYMBOL_PATH environment variable was updated for this window only`n" } else { Write-Verbose -Message "`nPlease log out to activate the new symbol server settings`n" } } ############################################################################### function Get-SourceServerFiles { <# .SYNOPSIS Prepopulate your symbol cache with all your Source Server extracted source code. .DESCRIPTION Recurses the specified symbol cache directory for PDB files with Source Server sections and extracts the source code. This script is a simple wrapper around SRCTOOl.EXE from the Debugging Tools for Windows (AKA WinDBG). If WinDBG is in the PATH this script will find SRCTOOL.EXE. If WinDBG is not in your path, use the SrcTool parameter to specify the complete path to the tool. .PARAMETER CacheDirectory The required cache directory for the local machine. .PARAMETER SrcTool The optional parameter to specify where SRCTOOL.EXE resides. .LINK http://www.wintellect.com/devcenter/author/jrobbins https://github.com/Wintellect/WintellectPowerShell #> # I hate suppressing this warning, but I created this cmdlet long before the # script analyzer came out. If someone has this in a script, changing the # cmdlet name will break them. [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseSingularNouns", "", Scope="Function")] param ( [Parameter(Mandatory=$true, HelpMessage="Please specify the source server directory")] [string] $CacheDirectory , [Parameter(HelpMessage="The optional full path to SCRTOOL.EXE")] [string] $SrcTool = "" ) if ($SrcTool -eq "") { # Go with the default of looking up WinDBG in the path. $windbg = Get-Command -Name windbg.exe -ErrorAction SilentlyContinue if ($null -eq $windbg) { throw "Please use the -SrcTool parameter or have WinDBG in the path" } $windbgPath = Split-Path -Path ($windbg.Definition) $SrcTool = $windbgPath + "\SRCSRV\SRCTOOL.EXE" } if ($null -eq (Get-Command -Name $SrcTool -ErrorAction SilentlyContinue)) { throw "SRCTOOL.EXE does not exist." } if ((Test-Path -Path $CacheDirectory) -eq $false) { throw "The specified cache directory does not exist." } # Get all the PDB files, execute SRCTOOL.EXE on each one. Get-ChildItem -Recurse -Include *.pdb -Path $cacheDirectory | ` ForEach-Object { &$SrcTool -d:$CacheDirectory -x $_.FullName } } ############################################################################### function Set-SymbolAndSourceServer { <# .SYNOPSIS Sets up a computer to use a symbol and source server. .DESCRIPTION Sets up both the _NT_SYMBOL_PATH and _NT_SOURCE_PATH environment variable as well as VS 2012-2017 (for each installed) to use a common symbol and source cache directory as well as common symbol servers. Optionally can be used to only set _NT_SYMBOL_PATH and _NT_SOURCE_PATH for an individual PowerShell window. This is a wrapper around Set-SymbolServer and Set-SourceServer. These have been a single command anyway. .PARAMETER Internal Sets the symbol server to use to http://SymWeb. Visual Studio will not use the public symbol servers. This will turn off the .NET Framework Source Stepping. This switch is intended for internal Microsoft use only. You must specify either -Internal or -Public to the script. .PARAMETER Public Sets the symbol server to use as the two public symbol servers from Microsoft. All the appropriate settings are configured to properly have .NET Reference Source stepping working. .PARAMETER CacheDirectory Defaults to C:\SYMBOLS\PUBLIC for -Public and C:\SYMBOLS\INTERNAL for -Internal. .PARAMETER SymbolServers A string array of additional symbol servers to use. If -Internal is set, these additional symbol servers will appear before HTTP://SYMWEB. If -Public is set, these symbol servers will appear before the public symbol servers so both the environment variable and Visual Studio have the same search order. .PARAMETER CurrentEnvironmentOnly If specified will only set the current PowerShell window _NT_SYMBOL_PATH and _NT_SOURCE_PATH environment variable and not overwrite the global settings. This is primarily for use with WinDBG as Visual Studio requires settings files for the cache directory and other settings. .LINK http://www.wintellect.com/devcenter/author/jrobbins https://github.com/Wintellect/WintellectPowerShell #> [CmdLetBinding(SupportsShouldProcess=$true)] param ( [switch] $Internal, [switch] $Public, [string] $CacheDirectory="", [string[]] $SymbolServers=@(), [switch] $CurrentEnvironmentOnly) # Splatting is just so cool... Set-SymbolServer @psBoundParameters if ($CacheDirectory.Length -eq 0) { if ($Public) { $CacheDirectory = "C:\SYMBOLS\PUBLIC" } else { $CacheDirectory = "C:\SYMBOLS\INTERNAL" } } Set-SourceServer -CacheDirectory $CacheDirectory } # SIG # Begin signature block # MIIUywYJKoZIhvcNAQcCoIIUvDCCFLgCAQExCzAJBgUrDgMCGgUAMGkGCisGAQQB # gjcCAQSgWzBZMDQGCisGAQQBgjcCAR4wJgIDAQAABBAfzDtgWUsITrck0sYpfvNR # AgEAAgEAAgEAAgEAAgEAMCEwCQYFKw4DAhoFAAQUSuGi+KKJWA7wS5bKuvdgdtJB # aTCggg+6MIIEmTCCA4GgAwIBAgIPFojwOSVeY45pFDkH5jMLMA0GCSqGSIb3DQEB # BQUAMIGVMQswCQYDVQQGEwJVUzELMAkGA1UECBMCVVQxFzAVBgNVBAcTDlNhbHQg # TGFrZSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxITAfBgNV # BAsTGGh0dHA6Ly93d3cudXNlcnRydXN0LmNvbTEdMBsGA1UEAxMUVVROLVVTRVJG # aXJzdC1PYmplY3QwHhcNMTUxMjMxMDAwMDAwWhcNMTkwNzA5MTg0MDM2WjCBhDEL # MAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UE # BxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxKjAoBgNVBAMT # IUNPTU9ETyBTSEEtMSBUaW1lIFN0YW1waW5nIFNpZ25lcjCCASIwDQYJKoZIhvcN # AQEBBQADggEPADCCAQoCggEBAOnpPd/XNwjJHjiyUlNCbSLxscQGBGue/YJ0UEN9 # xqC7H075AnEmse9D2IOMSPznD5d6muuc3qajDjscRBh1jnilF2n+SRik4rtcTv6O # KlR6UPDV9syR55l51955lNeWM/4Og74iv2MWLKPdKBuvPavql9LxvwQQ5z1IRf0f # aGXBf1mZacAiMQxibqdcZQEhsGPEIhgn7ub80gA9Ry6ouIZWXQTcExclbhzfRA8V # zbfbpVd2Qm8AaIKZ0uPB3vCLlFdM7AiQIiHOIiuYDELmQpOUmJPv/QbZP7xbm1Q8 # ILHuatZHesWrgOkwmt7xpD9VTQoJNIp1KdJprZcPUL/4ygkCAwEAAaOB9DCB8TAf # BgNVHSMEGDAWgBTa7WR0FJwUPKvdmam9WyhNizzJ2DAdBgNVHQ4EFgQUjmstM2v0 # M6eTsxOapeAK9xI1aogwDgYDVR0PAQH/BAQDAgbAMAwGA1UdEwEB/wQCMAAwFgYD # VR0lAQH/BAwwCgYIKwYBBQUHAwgwQgYDVR0fBDswOTA3oDWgM4YxaHR0cDovL2Ny # bC51c2VydHJ1c3QuY29tL1VUTi1VU0VSRmlyc3QtT2JqZWN0LmNybDA1BggrBgEF # BQcBAQQpMCcwJQYIKwYBBQUHMAGGGWh0dHA6Ly9vY3NwLnVzZXJ0cnVzdC5jb20w # DQYJKoZIhvcNAQEFBQADggEBALozJEBAjHzbWJ+zYJiy9cAx/usfblD2CuDk5oGt # Joei3/2z2vRz8wD7KRuJGxU+22tSkyvErDmB1zxnV5o5NuAoCJrjOU+biQl/e8Vh # f1mJMiUKaq4aPvCiJ6i2w7iH9xYESEE9XNjsn00gMQTZZaHtzWkHUxY93TYCCojr # QOUGMAu4Fkvc77xVCf/GPhIudrPczkLv+XZX4bcKBUCYWJpdcRaTcYxlgepv84n3 # +3OttOe/2Y5vqgtPJfO44dXddZhogfiqwNGAwsTEOYnB9smebNd0+dmX+E/CmgrN # Xo/4GengpZ/E8JIh5i15Jcki+cPwOoRXrToW9GOUEB1d0MYwggU1MIIEHaADAgEC # AhEA+CGT8y+uLXmA2UBOFe5VGzANBgkqhkiG9w0BAQsFADB9MQswCQYDVQQGEwJH # QjEbMBkGA1UECBMSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHEwdTYWxmb3Jk # MRowGAYDVQQKExFDT01PRE8gQ0EgTGltaXRlZDEjMCEGA1UEAxMaQ09NT0RPIFJT # QSBDb2RlIFNpZ25pbmcgQ0EwHhcNMTYwMjE4MDAwMDAwWhcNMTgxMDI4MjM1OTU5 # WjCBnTELMAkGA1UEBhMCVVMxDjAMBgNVBBEMBTM3OTMyMQswCQYDVQQIDAJUTjES # MBAGA1UEBwwJS25veHZpbGxlMRIwEAYDVQQJDAlTdWl0ZSAzMDIxHzAdBgNVBAkM # FjEwMjA3IFRlY2hub2xvZ3kgRHJpdmUxEzARBgNVBAoMCldpbnRlbGxlY3QxEzAR # BgNVBAMMCldpbnRlbGxlY3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB # AQDfLujuIe3yrrTfTOdYfstwFDZrI7XezoeFPA33GRxY/MSbKuUvPcN8XqU8Jpg4 # NUkByzoSjPsq9Yjx3anHflcNendqa/8gbkPdiEMg+6kRVmtv1QHfGt+UbEMfrUk0 # Ltm0DE+6OIZFx8hjsxifJvWrQ/jG9lat6e2YwIdNAqyG2htqCrmBN90lW+0+zU9s # YJIVD0ZfyZJVkvbeay+HwlbojW7JQyyhdGOSa61zUqlD85RX6HzcCbb1WHf5bZRO # 2idaVNAOw1YHqJAUjY4oJY4lqWwg5Inza4f33Wt82zJAgKY4S01bddkvjPi6iMnG # y8bI1EfWAdFFC+UM2qKsNc2/AgMBAAGjggGNMIIBiTAfBgNVHSMEGDAWgBQpkWD/ # ik366/mmarjP+eZLvUnOEjAdBgNVHQ4EFgQUZdNFdxzRtMVCZCvcFV4g7vsL8vgw # DgYDVR0PAQH/BAQDAgeAMAwGA1UdEwEB/wQCMAAwEwYDVR0lBAwwCgYIKwYBBQUH # AwMwEQYJYIZIAYb4QgEBBAQDAgQQMEYGA1UdIAQ/MD0wOwYMKwYBBAGyMQECAQMC # MCswKQYIKwYBBQUHAgEWHWh0dHBzOi8vc2VjdXJlLmNvbW9kby5uZXQvQ1BTMEMG # A1UdHwQ8MDowOKA2oDSGMmh0dHA6Ly9jcmwuY29tb2RvY2EuY29tL0NPTU9ET1JT # QUNvZGVTaWduaW5nQ0EuY3JsMHQGCCsGAQUFBwEBBGgwZjA+BggrBgEFBQcwAoYy # aHR0cDovL2NydC5jb21vZG9jYS5jb20vQ09NT0RPUlNBQ29kZVNpZ25pbmdDQS5j # cnQwJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmNvbW9kb2NhLmNvbTANBgkqhkiG # 9w0BAQsFAAOCAQEAnSVG6TXbazSxczonyo/Q+pjX+6JERtMZ0sz3Fc3PTMDcb9DS # tALjZiZhOgOoRNC+5OHgE3tTPLCT6ZGktfedzp6J9mICzoJIIBelfdiIwJNkPTzR # I2krUn/6ld5coh0zyM85lCjXkqzZmyQmRRNQoycWtxUwxsNlkiGlRIiIJHztbg1I # lv9C90zCZ1nAhfOpv+maUohLtz22F9wXCJuIUQapOhPG5n/opM/AUQV2WuDa3AZP # VYleK90zOgHLDgLICxrx57z2JRlXyW2ga2N5J6DXzwGmxpCe0LbzYCj4h42SjUuf # 9hOQtORlSjYEj8RFpxatyxcmIIpej9/NDNXgIzCCBeAwggPIoAMCAQICEC58h8wO # k0pS/pT9HLfNNK8wDQYJKoZIhvcNAQEMBQAwgYUxCzAJBgNVBAYTAkdCMRswGQYD # VQQIExJHcmVhdGVyIE1hbmNoZXN0ZXIxEDAOBgNVBAcTB1NhbGZvcmQxGjAYBgNV # BAoTEUNPTU9ETyBDQSBMaW1pdGVkMSswKQYDVQQDEyJDT01PRE8gUlNBIENlcnRp # ZmljYXRpb24gQXV0aG9yaXR5MB4XDTEzMDUwOTAwMDAwMFoXDTI4MDUwODIzNTk1 # OVowfTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQ # MA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxIzAh # BgNVBAMTGkNPTU9ETyBSU0EgQ29kZSBTaWduaW5nIENBMIIBIjANBgkqhkiG9w0B # AQEFAAOCAQ8AMIIBCgKCAQEAppiQY3eRNH+K0d3pZzER68we/TEds7liVz+TvFvj # nx4kMhEna7xRkafPnp4ls1+BqBgPHR4gMA77YXuGCbPj/aJonRwsnb9y4+R1oOU1 # I47Jiu4aDGTH2EKhe7VSA0s6sI4jS0tj4CKUN3vVeZAKFBhRLOb+wRLwHD9hYQqM # otz2wzCqzSgYdUjBeVoIzbuMVYz31HaQOjNGUHOYXPSFSmsPgN1e1r39qS/AJfX5 # eNeNXxDCRFU8kDwxRstwrgepCuOvwQFvkBoj4l8428YIXUezg0HwLgA3FLkSqnmS # Us2HD3vYYimkfjC9G7WMcrRI8uPoIfleTGJ5iwIGn3/VCwIDAQABo4IBUTCCAU0w # HwYDVR0jBBgwFoAUu69+Aj36pvE8hI6t7jiY7NkyMtQwHQYDVR0OBBYEFCmRYP+K # Tfrr+aZquM/55ku9Sc4SMA4GA1UdDwEB/wQEAwIBhjASBgNVHRMBAf8ECDAGAQH/ # AgEAMBMGA1UdJQQMMAoGCCsGAQUFBwMDMBEGA1UdIAQKMAgwBgYEVR0gADBMBgNV # HR8ERTBDMEGgP6A9hjtodHRwOi8vY3JsLmNvbW9kb2NhLmNvbS9DT01PRE9SU0FD # ZXJ0aWZpY2F0aW9uQXV0aG9yaXR5LmNybDBxBggrBgEFBQcBAQRlMGMwOwYIKwYB # BQUHMAKGL2h0dHA6Ly9jcnQuY29tb2RvY2EuY29tL0NPTU9ET1JTQUFkZFRydXN0 # Q0EuY3J0MCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5jb21vZG9jYS5jb20wDQYJ # KoZIhvcNAQEMBQADggIBAAI/AjnD7vjKO4neDG1NsfFOkk+vwjgsBMzFYxGrCWOv # q6LXAj/MbxnDPdYaCJT/JdipiKcrEBrgm7EHIhpRHDrU4ekJv+YkdK8eexYxbiPv # VFEtUgLidQgFTPG3UeFRAMaH9mzuEER2V2rx31hrIapJ1Hw3Tr3/tnVUQBg2V2cR # zU8C5P7z2vx1F9vst/dlCSNJH0NXg+p+IHdhyE3yu2VNqPeFRQevemknZZApQIvf # ezpROYyoH3B5rW1CIKLPDGwDjEzNcweU51qOOgS6oqF8H8tjOhWn1BUbp1JHMqn0 # v2RH0aofU04yMHPCb7d4gp1c/0a7ayIdiAv4G6o0pvyM9d1/ZYyMMVcx0DbsR6HP # y4uo7xwYWMUGd8pLm1GvTAhKeo/io1Lijo7MJuSy2OU4wqjtxoGcNWupWGFKCpe0 # S0K2VZ2+medwbVn4bSoMfxlgXwyaiGwwrFIJkBYb/yud29AgyonqKH4yjhnfe0gz # Htdl+K7J+IMUk3Z9ZNCOzr41ff9yMU2fnr0ebC+ojwwGUPuMJ7N2yfTm18M04oyH # IYZh/r9VdOEhdwMKaGy75Mmp5s9ZJet87EUOeWZo6CLNuO+YhU2WETwJitB/vCgo # E/tqylSNklzNwmWYBp7OSFvUtTeTRkF8B93P+kPvumdh/31J4LswfVyA4+YWOUun # MYIEezCCBHcCAQEwgZIwfTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIg # TWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENB # IExpbWl0ZWQxIzAhBgNVBAMTGkNPTU9ETyBSU0EgQ29kZSBTaWduaW5nIENBAhEA # +CGT8y+uLXmA2UBOFe5VGzAJBgUrDgMCGgUAoHgwGAYKKwYBBAGCNwIBDDEKMAig # AoAAoQKAADAZBgkqhkiG9w0BCQMxDAYKKwYBBAGCNwIBBDAcBgorBgEEAYI3AgEL # MQ4wDAYKKwYBBAGCNwIBFTAjBgkqhkiG9w0BCQQxFgQUBDGLLv6NedAy/CnSAWXV # KeeVaH4wDQYJKoZIhvcNAQEBBQAEggEAjliMcs/L+7u7frv/sONu953tNOFjmnmv # OxwbhL/RijnQ3LHiP6iKqWufkW7d0yuc+fm9N1jeymqp6WmLc9H/kP2DRQlD5T5s # fsAc9tmcpP2pcIjvGczL0vwERODXFLilE9foJecJJD/JdbfgjjLWzsznsFmSiM3P # G53Y2y/pXCFy12rm3YMvceDbeYjd3shmTRoe8RD1Blv96qdPw8+hB+MFKpAosE4l # ckglvVjsvsFAJPzVlvmsBhdsbaS2JkFMQUl3yGV3tWQ6sx/agloFzVXJpIbCpvuR # KGMnT1uRNhPu8KD5YkRlci4a/6gQxt+2GsbBFZVgCCcU4H/RaPaMIaGCAkMwggI/ # BgkqhkiG9w0BCQYxggIwMIICLAIBATCBqTCBlTELMAkGA1UEBhMCVVMxCzAJBgNV # BAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2UgQ2l0eTEeMBwGA1UEChMVVGhlIFVT # RVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExhodHRwOi8vd3d3LnVzZXJ0cnVzdC5j # b20xHTAbBgNVBAMTFFVUTi1VU0VSRmlyc3QtT2JqZWN0Ag8WiPA5JV5jjmkUOQfm # MwswCQYFKw4DAhoFAKBdMBgGCSqGSIb3DQEJAzELBgkqhkiG9w0BBwEwHAYJKoZI # hvcNAQkFMQ8XDTE3MTIyMDIwMjUwMVowIwYJKoZIhvcNAQkEMRYEFOC4JDfKoI52 # RchFiM735/M70X5AMA0GCSqGSIb3DQEBAQUABIIBACraObHBWueI84hEe6WvAwSw # LcsvXSrHBlnmrFsvJf0YMgCAonG6NUrPaIiWAiNy901/rf4Pn/4kadmfG/o79tZI # tHaMUXP0nLJLm11QapFeZ0JHLj3Z7KrZLHeQSYnCACGwwnllZ+bqjrwT0KcZahf1 # yJW6YI6pUilley9TtEkpaSx/Qp5HKGzzESuf7o0+dnxce6Tr5w2PMgjjV9t9L2YP # rq+f9koTCha71sEbT2aFmRigMyyXg+aUfqUwxXjJB/PC6cAPLUHPZAhc8OXeVW+u # Z3em63Z44Zw8N9X1/KNult8fzlEoNHfmdNAeDZIpa0czTkXsCKNtssQbAsHQX7s= # SIG # End signature block |