| Server IP : 121.121.20.254 / Your IP : 216.73.216.142 Web Server : Microsoft-IIS/10.0 System : Windows NT WEB-SERVER 10.0 build 20348 (Windows Server 2022) AMD64 User : IUSR ( 0) PHP Version : 8.3.28 Disable Function : NONE MySQL : ON | cURL : ON | WGET : OFF | Perl : OFF | Python : OFF | Sudo : OFF | Pkexec : OFF Directory : C:/Program Files/WindowsPowerShell/Modules/Pester/3.4.0/Functions/ |
Upload File : |
if ($PSVersionTable.PSVersion.Major -le 2) { return }
InModuleScope Pester {
Describe 'Code Coverage Analysis' {
$root = (Get-PSDrive TestDrive).Root
$null = New-Item -Path $root\TestScript.ps1 -ItemType File -ErrorAction SilentlyContinue
Set-Content -Path $root\TestScript.ps1 -Value @'
function FunctionOne
{
function NestedFunction
{
'I am the nested function.'
'I get fully executed.'
}
if ($true)
{
'I am functionOne'
NestedFunction
}
}
function FunctionTwo
{
'I am function two. I never get called.'
}
FunctionOne
'@
Context 'Entire file' {
$testState = New-PesterState -Path $root
# Path deliberately duplicated to make sure the code doesn't produce multiple breakpoints for the same commands
Enter-CoverageAnalysis -CodeCoverage "$root\TestScript.ps1", "$root\TestScript.ps1" -PesterState $testState
It 'Has the proper number of breakpoints defined' {
$testState.CommandCoverage.Count | Should Be 7
}
$null = & "$root\TestScript.ps1"
$coverageReport = Get-CoverageReport -PesterState $testState
It 'Reports the proper number of executed commands' {
$coverageReport.NumberOfCommandsExecuted | Should Be 6
}
It 'Reports the proper number of analyzed commands' {
$coverageReport.NumberOfCommandsAnalyzed | Should Be 7
}
It 'Reports the proper number of analyzed files' {
$coverageReport.NumberOfFilesAnalyzed | Should Be 1
}
It 'Reports the proper number of missed commands' {
$coverageReport.MissedCommands.Count | Should Be 1
}
It 'Reports the correct missed command' {
$coverageReport.MissedCommands[0].Command | Should Be "'I am function two. I never get called.'"
}
It 'Reports the proper number of hit commands' {
$coverageReport.HitCommands.Count | Should Be 6
}
It 'Reports the correct hit command' {
$coverageReport.HitCommands[0].Command | Should Be "'I am the nested function.'"
}
Exit-CoverageAnalysis -PesterState $testState
}
Context 'Single function with missed commands' {
$testState = New-PesterState -Path $root
Enter-CoverageAnalysis -CodeCoverage @{Path = "$root\TestScript.ps1"; Function = 'FunctionTwo'} -PesterState $testState
It 'Has the proper number of breakpoints defined' {
$testState.CommandCoverage.Count | Should Be 1
}
$null = & "$root\TestScript.ps1"
$coverageReport = Get-CoverageReport -PesterState $testState
It 'Reports the proper number of executed commands' {
$coverageReport.NumberOfCommandsExecuted | Should Be 0
}
It 'Reports the proper number of analyzed commands' {
$coverageReport.NumberOfCommandsAnalyzed | Should Be 1
}
It 'Reports the proper number of missed commands' {
$coverageReport.MissedCommands.Count | Should Be 1
}
It 'Reports the correct missed command' {
$coverageReport.MissedCommands[0].Command | Should Be "'I am function two. I never get called.'"
}
It 'Reports the proper number of hit commands' {
$coverageReport.HitCommands.Count | Should Be 0
}
Exit-CoverageAnalysis -PesterState $testState
}
Context 'Single function with no missed commands' {
$testState = New-PesterState -Path $root
Enter-CoverageAnalysis -CodeCoverage @{Path = "$root\TestScript.ps1"; Function = 'FunctionOne'} -PesterState $testState
It 'Has the proper number of breakpoints defined' {
$testState.CommandCoverage.Count | Should Be 5
}
$null = & "$root\TestScript.ps1"
$coverageReport = Get-CoverageReport -PesterState $testState
It 'Reports the proper number of executed commands' {
$coverageReport.NumberOfCommandsExecuted | Should Be 5
}
It 'Reports the proper number of analyzed commands' {
$coverageReport.NumberOfCommandsAnalyzed | Should Be 5
}
It 'Reports the proper number of missed commands' {
$coverageReport.MissedCommands.Count | Should Be 0
}
It 'Reports the proper number of hit commands' {
$coverageReport.HitCommands.Count | Should Be 5
}
It 'Reports the correct hit command' {
$coverageReport.HitCommands[0].Command | Should Be "'I am the nested function.'"
}
Exit-CoverageAnalysis -PesterState $testState
}
Context 'Range of lines' {
$testState = New-PesterState -Path $root
Enter-CoverageAnalysis -CodeCoverage @{Path = "$root\TestScript.ps1"; StartLine = 11; EndLine = 12 } -PesterState $testState
It 'Has the proper number of breakpoints defined' {
$testState.CommandCoverage.Count | Should Be 2
}
$null = & "$root\TestScript.ps1"
$coverageReport = Get-CoverageReport -PesterState $testState
It 'Reports the proper number of executed commands' {
$coverageReport.NumberOfCommandsExecuted | Should Be 2
}
It 'Reports the proper number of analyzed commands' {
$coverageReport.NumberOfCommandsAnalyzed | Should Be 2
}
It 'Reports the proper number of missed commands' {
$coverageReport.MissedCommands.Count | Should Be 0
}
It 'Reports the proper number of hit commands' {
$coverageReport.HitCommands.Count | Should Be 2
}
It 'Reports the correct hit command' {
$coverageReport.HitCommands[0].Command | Should Be "'I am functionOne'"
}
Exit-CoverageAnalysis -PesterState $testState
}
Context 'Wildcard resolution' {
$testState = New-PesterState -Path $root
Enter-CoverageAnalysis -CodeCoverage @{Path = "$root\*.ps1"; Function = '*' } -PesterState $testState
It 'Has the proper number of breakpoints defined' {
$testState.CommandCoverage.Count | Should Be 6
}
$null = & "$root\TestScript.ps1"
$coverageReport = Get-CoverageReport -PesterState $testState
It 'Reports the proper number of executed commands' {
$coverageReport.NumberOfCommandsExecuted | Should Be 5
}
It 'Reports the proper number of analyzed commands' {
$coverageReport.NumberOfCommandsAnalyzed | Should Be 6
}
It 'Reports the proper number of analyzed files' {
$coverageReport.NumberOfFilesAnalyzed | Should Be 1
}
It 'Reports the proper number of missed commands' {
$coverageReport.MissedCommands.Count | Should Be 1
}
It 'Reports the correct missed command' {
$coverageReport.MissedCommands[0].Command | Should Be "'I am function two. I never get called.'"
}
It 'Reports the proper number of hit commands' {
$coverageReport.HitCommands.Count | Should Be 5
}
It 'Reports the correct hit command' {
$coverageReport.HitCommands[0].Command | Should Be "'I am the nested function.'"
}
Exit-CoverageAnalysis -PesterState $testState
}
}
Describe 'Stripping common parent paths' {
$paths = @(
'C:\Common\Folder\UniqueSubfolder1\File.ps1'
'C:\Common\Folder\UniqueSubfolder2\File2.ps1'
'C:\Common\Folder\UniqueSubfolder3\File3.ps1'
)
$commonPath = Get-CommonParentPath -Path $paths
It 'Identifies the correct parent path' {
$commonPath | Should Be 'C:\Common\Folder'
}
It 'Strips the common path correctly' {
Get-RelativePath -Path $paths[0] -RelativeTo $commonPath |
Should Be 'UniqueSubfolder1\File.ps1'
}
}
if ((Get-Module -ListAvailable PSDesiredStateConfiguration) -and $PSVersionTable.PSVersion.Major -ge 4)
{
Describe 'Analyzing coverage of a DSC configuration' {
$root = (Get-PSDrive TestDrive).Root
$null = New-Item -Path $root\TestScriptWithConfiguration.ps1 -ItemType File -ErrorAction SilentlyContinue
Set-Content -Path $root\TestScriptWithConfiguration.ps1 -Value @'
$line1 = $true # Triggers breakpoint
$line2 = $true # Triggers breakpoint
configuration MyTestConfig # does NOT trigger breakpoint
{
Node localhost # Triggers breakpoint
{
WindowsFeature XPSViewer # Triggers breakpoint
{
Name = 'XPS-Viewer' # does NOT trigger breakpoint
Ensure = 'Present' # does NOT trigger breakpoint
}
}
return # does NOT trigger breakpoint
$doesNotExecute = $true # Triggers breakpoint
}
$line3 = $true # Triggers breakpoint
return # does NOT trigger breakpoint
$doesnotexecute = $true # Triggers breakpoint
'@
$testState = New-PesterState -Path $root
Enter-CoverageAnalysis -CodeCoverage "$root\TestScriptWithConfiguration.ps1" -PesterState $testState
It 'Has the proper number of breakpoints defined' {
$testState.CommandCoverage.Count | Should Be 7
}
$null = . "$root\TestScriptWithConfiguration.ps1"
$coverageReport = Get-CoverageReport -PesterState $testState
It 'Reports the proper number of missed commands before running the configuration' {
$coverageReport.MissedCommands.Count | Should Be 4
}
MyTestConfig -OutputPath $root
$coverageReport = Get-CoverageReport -PesterState $testState
It 'Reports the proper number of missed commands after running the configuration' {
$coverageReport.MissedCommands.Count | Should Be 2
}
Exit-CoverageAnalysis -PesterState $testState
}
}
}
# SIG # Begin signature block
# MIInZgYJKoZIhvcNAQcCoIInVzCCJ1MCAQExDzANBglghkgBZQMEAgEFADB5Bgor
# BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG
# KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCA+NSWJ517aiUrV
# KJxHqsXAXCXEXlAqDflUM+iV0N1usqCCC7QwggXLMIIEs6ADAgECAhMzAAABQGf2
# mGsxCLhyAAAAAAFAMA0GCSqGSIb3DQEBCwUAMIGOMQswCQYDVQQGEwJVUzETMBEG
# A1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWlj
# cm9zb2Z0IENvcnBvcmF0aW9uMTgwNgYDVQQDEy9NaWNyb3NvZnQgV2luZG93cyBU
# aGlyZCBQYXJ0eSBDb21wb25lbnQgQ0EgMjAxMjAeFw0yNTExMTMxOTU5NDNaFw0y
# NjExMTAxOTU5NDNaMIGEMQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3Rv
# bjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0
# aW9uMS4wLAYDVQQDEyVNaWNyb3NvZnQgV2luZG93cyAzcmQgcGFydHkgQ29tcG9u
# ZW50MIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIBigKCAYEArGt4Hrjs3D7+IIab
# GkPGtg4XeWQFi8nKsdeF+N6nkYF9wsmw0qPk4OovEiJnCSRiEtLfYy3Icn4iOp7L
# 24oCa0zlgYCND3OnNfYOuVpMsq3CSkXYg3H+VMiB11hOLcctTu4RWy4ZRKsL5NVI
# AduJFgd/1Qs2mQpUuOyFfLKhu/+Z+T2c9YALxsfnPvqn8Tn8Tt8wdZuFwz7kK3jl
# e2T3YBofybAR2aH678TnOxhLe2/hEpTdKaVfcqyrIX0Mw/LwqEJnj4G8amBbQ7OG
# RnKm1VNd4nMpRt1SflNlVo1Q3Qqnj9K6mSPw99YGMCTaVr6jKPylsWyW4nsvu8m0
# MbBJJiLOi0sOTHtwQEVcBH6WM7xbODqwPaklS1wDbED1wfzImIUR8WsXJVjDm7Fg
# x4JDo8oLIjKFrEvzBfrYWsvlDg8p9XgR7EB/IJwXGuJbFzo/S+r3D5DkUZXX/72k
# XA4FeRJAgLePAuGChPvyQiLtKJeJm9ftJeukrIcs7JpJVHObAgMBAAGjggGoMIIB
# pDATBgNVHSUEDDAKBggrBgEFBQcDAzAdBgNVHQ4EFgQUB9FDBUZ0W11vsv6qqb9t
# vKspCIowRQYDVR0RBD4wPKQ6MDgxHjAcBgNVBAsTFU1pY3Jvc29mdCBDb3Jwb3Jh
# dGlvbjEWMBQGA1UEBRMNMjMwODA5KzUwNjIyOTAfBgNVHSMEGDAWgBRhcaeHr/9p
# 1SF2T1KTKAC+eRKrhDB0BgNVHR8EbTBrMGmgZ6BlhmNodHRwOi8vd3d3Lm1pY3Jv
# c29mdC5jb20vcGtpb3BzL2NybC9NaWNyb3NvZnQlMjBXaW5kb3dzJTIwVGhpcmQl
# MjBQYXJ0eSUyMENvbXBvbmVudCUyMENBJTIwMjAxMi5jcmwwgYEGCCsGAQUFBwEB
# BHUwczBxBggrBgEFBQcwAoZlaHR0cDovL3d3dy5taWNyb3NvZnQuY29tL3BraW9w
# cy9jZXJ0cy9NaWNyb3NvZnQlMjBXaW5kb3dzJTIwVGhpcmQlMjBQYXJ0eSUyMENv
# bXBvbmVudCUyMENBJTIwMjAxMi5jcnQwDAYDVR0TAQH/BAIwADANBgkqhkiG9w0B
# AQsFAAOCAQEAmFzJPKhkAXPOcfy9S4q1nP3XCvmABVGv/VRzFZ1e+oVtVzOFkbZ6
# osY1OpZqa9CEvtgcrtciv1y9mV1SpxAMwfEqq+Nhw2GdZ3IWqFzWFsEe2S9U196s
# XRIRIxglZMBWyzdy8rQ+P7L2+LciW4qcaw2wtv6YoI0q1isgk0t1OF5kEL0t9hhx
# UrBavTdoqZ3b5JtwDqzmIsxuLtGbE9Pqbz2gx/me+7yduYpIcYlmEmPQkg3gmWkZ
# lnSRePu7/5RXS2TGW1O5JP8aqVcMn0ZkHEhtT368pE/CxQVAkAYHNz6+enP9n+HC
# 2udu395c0fVlRHy/d53f32RukfbjakH8uzCCBeEwggPJoAMCAQICCmELqsEAAAAA
# AAkwDQYJKoZIhvcNAQELBQAwgYgxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNo
# aW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29y
# cG9yYXRpb24xMjAwBgNVBAMTKU1pY3Jvc29mdCBSb290IENlcnRpZmljYXRlIEF1
# dGhvcml0eSAyMDEwMB4XDTEyMDQxODIzNDgzOFoXDTI3MDQxODIzNTgzOFowgY4x
# CzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRt
# b25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xODA2BgNVBAMTL01p
# Y3Jvc29mdCBXaW5kb3dzIFRoaXJkIFBhcnR5IENvbXBvbmVudCBDQSAyMDEyMIIB
# IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAo5wwhAmnYy7PCkfw6iT5ozAg
# D15XMSaBmjEHslDUzmcJCGUKWqVLrtXtEC7npZm1n2gvmItYAqwgtCnEcb0oHKX9
# PJtk5MXr32ElvPDuaL/Rp8t+KgKBTmRcDFOGeVcZN2G3mPkMoE4iWZv5Gy1nPCc8
# VpBm4/1/ZX0Phr01R+iKzPTajulqTqunVeyiiR7VM0VTy/med73NLPkFuH90AR3o
# +xjhQ9EN6arcN2+9/rgP7R1NAUZOCqz8gujsVoMTjjoB7RRkdOpksmYQtmhtyHAA
# fVBILj1D7uAklcbNjsf9uOSVz91++5VeoQHNQ7EH16Qw7puGGipuwQtZonRviwID
# AQABo4IBQzCCAT8wEAYJKwYBBAGCNxUBBAMCAQAwHQYDVR0OBBYEFGFxp4ev/2nV
# IXZPUpMoAL55EquEMBkGCSsGAQQBgjcUAgQMHgoAUwB1AGIAQwBBMAsGA1UdDwQE
# AwIBhjAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFNX2VsuP6KJcYmjRPZSQ
# W9fOmhjEMFYGA1UdHwRPME0wS6BJoEeGRWh0dHA6Ly9jcmwubWljcm9zb2Z0LmNv
# bS9wa2kvY3JsL3Byb2R1Y3RzL01pY1Jvb0NlckF1dF8yMDEwLTA2LTIzLmNybDBa
# BggrBgEFBQcBAQROMEwwSgYIKwYBBQUHMAKGPmh0dHA6Ly93d3cubWljcm9zb2Z0
# LmNvbS9wa2kvY2VydHMvTWljUm9vQ2VyQXV0XzIwMTAtMDYtMjMuY3J0MA0GCSqG
# SIb3DQEBCwUAA4ICAQBaimfazNX9DSZBd78KRni0s94SaSt3I8JlLwFf0gP0YbpQ
# nS6MOXLzbD5qsR52bey384LczLvFaXAoc2YXP1Tr7gEWSMRG2RuAroE6jQ95bWiw
# nuotPznTyjh+vV58CG4Z3MbC9DgzaGHiUkeD4QABVtK6y4eCBTEKQYtO539fX+1f
# 0zktReuiE7/9HsKYQXFhFl/ICnAlfFlpMSTkcecKuwQX959yHsnSuxq+PQL+CQyy
# Q7RZGplTk5YhX+DWtyYBQpU2rCf9vvSFd2g9GL30vpiIIhGGUhbzRewDlxBwh6Nw
# Q3E828mGAxcM9XNbxn3hXGTt18VI1+0y4tGq08+n9ldOYfl362fyiLPeANoDj9CK
# NDc+HdhiuNKx8+Evi3I7gZZ8b/zsZnZyYBsk8qCJbVttAC7vKN2GhwXCtLnlvmTC
# KvJKFVyY4sQnhf9S42J+D7ICC9dmxwqy0z0gBBRQMlmDCn2b7Vo4EgFSui9eIHKO
# SvH953ECjDvhB77Jc/TdR9i077SkszC5iT52yrkAmFZ+q+qKuKXQOKtpdxMLFC/p
# qkEf97q9Ois0iu4Kq2PmY/eIJI4gDSs7nePCSVKsnx8OOTtd1G5QauZ9UjqqfDMV
# KQ0mXgFYp06pPXqEb3Q/YJ/kMk82AK9tcdM+pkZlX4F08f7BcdpMoEFagt3xHzGC
# GwgwghsEAgEBMIGmMIGOMQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3Rv
# bjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0
# aW9uMTgwNgYDVQQDEy9NaWNyb3NvZnQgV2luZG93cyBUaGlyZCBQYXJ0eSBDb21w
# b25lbnQgQ0EgMjAxMgITMwAAAUBn9phrMQi4cgAAAAABQDANBglghkgBZQMEAgEF
# AKCCARgwGQYJKoZIhvcNAQkDMQwGCisGAQQBgjcCAQQwHAYKKwYBBAGCNwIBCzEO
# MAwGCisGAQQBgjcCARUwLwYJKoZIhvcNAQkEMSIEIMZqgp4hFhMFcZTtNEMaYWbh
# HY2jlSJ76+MpIk9K/yWiMFAGCisGAQQBgjcKAxwxQgxARDBGNEMzRDBEMTdCNDlC
# MUJENjQwM0NFNDMwMUM4MjE5MEYxRjA0NDJFNTQ2NTAzNEQ2QkY1NzBBQkM3QzdB
# NjBaBgorBgEEAYI3AgEMMUwwSqAkgCIATQBpAGMAcgBvAHMAbwBmAHQAIABXAGkA
# bgBkAG8AdwBzoSKAIGh0dHA6Ly93d3cubWljcm9zb2Z0LmNvbS93aW5kb3dzMA0G
# CSqGSIb3DQEBAQUABIIBgBRX4Itjc4ji53f2l7q29+UCHOdX1HxggK3wZQc9tWZ3
# kgMiFGlX35s6y4vw+MmEVnyi3MWYKcKY9x3uJ26mXxHpI7wcSSwykfDhBPmI4OTj
# ZyMqj4c+PxnhxHiWMVJfZFbFe2DJZkOEcEGu/dVMd2k36jL4T7eBUh2c5uysEa10
# n8PAiv0+KcUix4kQGAUxjKny+9/o5GroLup8l3tmBl6sCfdGelBhNiTgeKXX0Spg
# AyBBUpFDDnFPp1oFQboDAmC8qcG1mQLghBhDka7uGQ4rVWVFKkHf0MET21sRieT0
# NopdZOmnFDCibhiYNPdZ4XsSDvJFVE3AZ5KrxUgjZj50nCHUhz7+KQADKgi23/PN
# ZZnZBCIS1P4NbAz0tOwYrRrSdpILq+iWc7tsUqGkLR1fu8uHWVIMaRZSTcCv9VQ3
# vJf6lXqnUKlTcgkLdjzuOYXiOrWgpvxHxjalak93qDEoVSNGS10nGG4B0SK0YivA
# GEaJkIqyrcz4X/WjuRZ7/6GCF5YwgheSBgorBgEEAYI3AwMBMYIXgjCCF34GCSqG
# SIb3DQEHAqCCF28wghdrAgEDMQ8wDQYJYIZIAWUDBAIBBQAwggFRBgsqhkiG9w0B
# CRABBKCCAUAEggE8MIIBOAIBAQYKKwYBBAGEWQoDATAxMA0GCWCGSAFlAwQCAQUA
# BCCGCDCwQuQFn30dAO4zntuPEDNqlvyfCGGPoFJFfPWD5AIGal9Y9NXKGBIyMDI2
# MDgwODE4MzQ0NC4xM1owBIACAfSggdGkgc4wgcsxCzAJBgNVBAYTAlVTMRMwEQYD
# VQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNy
# b3NvZnQgQ29ycG9yYXRpb24xJTAjBgNVBAsTHE1pY3Jvc29mdCBBbWVyaWNhIE9w
# ZXJhdGlvbnMxJzAlBgNVBAsTHm5TaGllbGQgVFNTIEVTTjpBNDAwLTA1RTAtRDk0
# NzElMCMGA1UEAxMcTWljcm9zb2Z0IFRpbWUtU3RhbXAgU2VydmljZaCCEe0wggcg
# MIIFCKADAgECAhMzAAACKPClh9fzyB5AAAEAAAIoMA0GCSqGSIb3DQEBCwUAMHwx
# CzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRt
# b25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xJjAkBgNVBAMTHU1p
# Y3Jvc29mdCBUaW1lLVN0YW1wIFBDQSAyMDEwMB4XDTI2MDIxOTE5NDAwNloXDTI3
# MDUxNzE5NDAwNlowgcsxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9u
# MRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRp
# b24xJTAjBgNVBAsTHE1pY3Jvc29mdCBBbWVyaWNhIE9wZXJhdGlvbnMxJzAlBgNV
# BAsTHm5TaGllbGQgVFNTIEVTTjpBNDAwLTA1RTAtRDk0NzElMCMGA1UEAxMcTWlj
# cm9zb2Z0IFRpbWUtU3RhbXAgU2VydmljZTCCAiIwDQYJKoZIhvcNAQEBBQADggIP
# ADCCAgoCggIBAK6O9uT+ypwJJF5lol8K5/U3BFxzteSeETrCQuh+Q2PWbEQCDfmr
# LbFwWOCNqu1W8DT1bxAdynIypVJc5PE0cmyaTSo/YIMu9QC6VaDtpLmgE5GkRfWj
# PefRHac+p4fQgcrXMnGPFodbbUBu5nRn7AzdZg3OQGVweZV7TdkbuuWTbyHvavk/
# kwTwUakWZhbkeXumwpuAsR+tgCK2m22xv6xmwFQj6EwqXi4slii0rJm/V7A4iKcF
# 9FTxCiyK+Oh9oF7NR/011X6IataHfbVadKwrcD8mXoYu1tJZdwlZQuBvG6qehs8r
# 5iUHfXvhMxZOBfhhaMbujQ63P+mMc0IoFsHvzx3KeEt0ZjoHTwT37hIatGmy3LiI
# kc7J0cIDkziLnJhHCx2636Ca/EilPzI1clyMkKDS87ya/+cVj1bK2/aqYK0IUWK8
# ZRapTbT+xR5GihBkaJA4lCfT3kKPeKwiy9E/wpTuE38QMjwdWxv80/MwUu9HOetG
# ePRM6cOI5NRydjCaT5d+hLWjCyRwIILAedsLTQPnzPzfLsrlkkHvjmFyfgITadHd
# 7pEayvjbLmq23ox3P+zsxOcNLZSZUdZfVf8dl7dSVfyCP+3rcvnTEg+qREIER0zU
# AM1RpJ+j05CIpv9uPV2JkIZN8QNQEEuinWaGTAgXzZ9qmVXZu6xn5TiRAgMBAAGj
# ggFJMIIBRTAdBgNVHQ4EFgQUqsmljPjy3Oi69WQFW2EBIWlD3cMwHwYDVR0jBBgw
# FoAUn6cVXQBeYl2D9OXSZacbUzUZ6XIwXwYDVR0fBFgwVjBUoFKgUIZOaHR0cDov
# L3d3dy5taWNyb3NvZnQuY29tL3BraW9wcy9jcmwvTWljcm9zb2Z0JTIwVGltZS1T
# dGFtcCUyMFBDQSUyMDIwMTAoMSkuY3JsMGwGCCsGAQUFBwEBBGAwXjBcBggrBgEF
# BQcwAoZQaHR0cDovL3d3dy5taWNyb3NvZnQuY29tL3BraW9wcy9jZXJ0cy9NaWNy
# b3NvZnQlMjBUaW1lLVN0YW1wJTIwUENBJTIwMjAxMCgxKS5jcnQwDAYDVR0TAQH/
# BAIwADAWBgNVHSUBAf8EDDAKBggrBgEFBQcDCDAOBgNVHQ8BAf8EBAMCB4AwDQYJ
# KoZIhvcNAQELBQADggIBAJDo18uatFqGBW2BaDfzcZpLTt8fKh3puFxQ423a1637
# oFo24fSvsAGRUeF46nEF2tSs4RhURoiKL10rdy5ks2anWJQDH9VuY5liXvHP602u
# MJaquDWNCarShEHyIThAmnA2EY/ruhjmG5ghTQPiWEOhqGp+Aomf/QGT71QoM/Dl
# eVRiat4WYmWP1hDNw896nwzEFfGH9jkju9B5FpblKO2ItA4tGTeCC+toOzlJ/j0w
# lXr8HDFcLau9R8QVfpJQOiioogT02BUhGrRFm7s63SLQiz4e88/SEHorA7EyDVJY
# o59O0Wlal2jwwm+AoIeQ+lcTOCms/6nIge47uBVGVJOxtgEUuHbIh3+K0zi5gvRH
# 7ZJIEFOlJJG2Gsa4SYSUjkEIczHMyD+iodI/BkAgCQzYLjHGLRK3uoy4D6b5nMVi
# R+gXjVChImf4eOqGpZhDSb9I738qclEklTAx3lOIyeNn4T8MmJSvLm52JbJCm9+P
# aFAUjR2OFqGgBcNrN4RyIsXa4SdO6v1R+NzA66f+gxj5Qt+2c6LaMosyut5XT3tq
# TPP8nGmcOBglT+2BTt9B+WDsiqIv37Tbvr6OhAejbWZV5jlgPwqH+RRpjomb85Mz
# zwbt69PP+qdG6bGi9OMxK2+lsAc1GGZJN0g9NXfYLK7EMpL9XlrmLAD5/1WIGj7C
# MIIHcTCCBVmgAwIBAgITMwAAABXF52ueAptJmQAAAAAAFTANBgkqhkiG9w0BAQsF
# ADCBiDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcT
# B1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEyMDAGA1UE
# AxMpTWljcm9zb2Z0IFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIwMTAwHhcN
# MjEwOTMwMTgyMjI1WhcNMzAwOTMwMTgzMjI1WjB8MQswCQYDVQQGEwJVUzETMBEG
# A1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWlj
# cm9zb2Z0IENvcnBvcmF0aW9uMSYwJAYDVQQDEx1NaWNyb3NvZnQgVGltZS1TdGFt
# cCBQQ0EgMjAxMDCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAOThpkzn
# tHIhC3miy9ckeb0O1YLT/e6cBwfSqWxOdcjKNVf2AX9sSuDivbk+F2Az/1xPx2b3
# lVNxWuJ+Slr+uDZnhUYjDLWNE893MsAQGOhgfWpSg0S3po5GawcU88V29YZQ3MFE
# yHFcUTE3oAo4bo3t1w/YJlN8OWECesSq/XJprx2rrPY2vjUmZNqYO7oaezOtgFt+
# jBAcnVL+tuhiJdxqD89d9P6OU8/W7IVWTe/dvI2k45GPsjksUZzpcGkNyjYtcI4x
# yDUoveO0hyTD4MmPfrVUj9z6BVWYbWg7mka97aSueik3rMvrg0XnRm7KMtXAhjBc
# TyziYrLNueKNiOSWrAFKu75xqRdbZ2De+JKRHh09/SDPc31BmkZ1zcRfNN0Sidb9
# pSB9fvzZnkXftnIv231fgLrbqn427DZM9ituqBJR6L8FA6PRc6ZNN3SUHDSCD/AQ
# 8rdHGO2n6Jl8P0zbr17C89XYcz1DTsEzOUyOArxCaC4Q6oRRRuLRvWoYWmEBc8pn
# ol7XKHYC4jMYctenIPDC+hIK12NvDMk2ZItboKaDIV1fMHSRlJTYuVD5C4lh8zYG
# NRiER9vcG9H9stQcxWv2XFJRXRLbJbqvUAV6bMURHXLvjflSxIUXk8A8FdsaN8cI
# FRg/eKtFtvUeh17aj54WcmnGrnu3tz5q4i6tAgMBAAGjggHdMIIB2TASBgkrBgEE
# AYI3FQEEBQIDAQABMCMGCSsGAQQBgjcVAgQWBBQqp1L+ZMSavoKRPEY1Kc8Q/y8E
# 7jAdBgNVHQ4EFgQUn6cVXQBeYl2D9OXSZacbUzUZ6XIwXAYDVR0gBFUwUzBRBgwr
# BgEEAYI3TIN9AQEwQTA/BggrBgEFBQcCARYzaHR0cDovL3d3dy5taWNyb3NvZnQu
# Y29tL3BraW9wcy9Eb2NzL1JlcG9zaXRvcnkuaHRtMBMGA1UdJQQMMAoGCCsGAQUF
# BwMIMBkGCSsGAQQBgjcUAgQMHgoAUwB1AGIAQwBBMAsGA1UdDwQEAwIBhjAPBgNV
# HRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFNX2VsuP6KJcYmjRPZSQW9fOmhjEMFYG
# A1UdHwRPME0wS6BJoEeGRWh0dHA6Ly9jcmwubWljcm9zb2Z0LmNvbS9wa2kvY3Js
# L3Byb2R1Y3RzL01pY1Jvb0NlckF1dF8yMDEwLTA2LTIzLmNybDBaBggrBgEFBQcB
# AQROMEwwSgYIKwYBBQUHMAKGPmh0dHA6Ly93d3cubWljcm9zb2Z0LmNvbS9wa2kv
# Y2VydHMvTWljUm9vQ2VyQXV0XzIwMTAtMDYtMjMuY3J0MA0GCSqGSIb3DQEBCwUA
# A4ICAQCdVX38Kq3hLB9nATEkW+Geckv8qW/qXBS2Pk5HZHixBpOXPTEztTnXwnE2
# P9pkbHzQdTltuw8x5MKP+2zRoZQYIu7pZmc6U03dmLq2HnjYNi6cqYJWAAOwBb6J
# 6Gngugnue99qb74py27YP0h1AdkY3m2CDPVtI1TkeFN1JFe53Z/zjj3G82jfZfak
# Vqr3lbYoVSfQJL1AoL8ZthISEV09J+BAljis9/kpicO8F7BUhUKz/AyeixmJ5/AL
# aoHCgRlCGVJ1ijbCHcNhcy4sa3tuPywJeBTpkbKpW99Jo3QMvOyRgNI95ko+ZjtP
# u4b6MhrZlvSP9pEB9s7GdP32THJvEKt1MMU0sHrYUP4KWN1APMdUbZ1jdEgssU5H
# LcEUBHG/ZPkkvnNtyo4JvbMBV0lUZNlz138eW0QBjloZkWsNn6Qo3GcZKCS6OEua
# bvshVGtqRRFHqfG3rsjoiV5PndLQTHa1V1QJsWkBRH58oWFsc/4Ku+xBZj1p/cvB
# QUl+fpO+y/g75LcVv7TOPqUxUYS8vwLBgqJ7Fx0ViY1w/ue10CgaiQuPNtq6TPmb
# /wrpNPgkNWcr4A245oyZ1uEi6vAnQj0llOZ0dFtq0Z4+7X6gMTN9vMvpe784cETR
# kPHIqzqKOghif9lwY1NNje6CbaUFEMFxBmoQtB1VM1izoXBm8qGCA1AwggI4AgEB
# MIH5oYHRpIHOMIHLMQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQ
# MA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9u
# MSUwIwYDVQQLExxNaWNyb3NvZnQgQW1lcmljYSBPcGVyYXRpb25zMScwJQYDVQQL
# Ex5uU2hpZWxkIFRTUyBFU046QTQwMC0wNUUwLUQ5NDcxJTAjBgNVBAMTHE1pY3Jv
# c29mdCBUaW1lLVN0YW1wIFNlcnZpY2WiIwoBATAHBgUrDgMCGgMVAHWtuYWTNLuo
# ArU5q/TwBSeFs0hSoIGDMIGApH4wfDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldh
# c2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBD
# b3Jwb3JhdGlvbjEmMCQGA1UEAxMdTWljcm9zb2Z0IFRpbWUtU3RhbXAgUENBIDIw
# MTAwDQYJKoZIhvcNAQELBQACBQDuIY/CMCIYDzIwMjYwODA4MTEyMTM4WhgPMjAy
# NjA4MDkxMTIxMzhaMHcwPQYKKwYBBAGEWQoEATEvMC0wCgIFAO4hj8ICAQAwCgIB
# AAICCSwCAf8wBwIBAAICEzcwCgIFAO4i4UICAQAwNgYKKwYBBAGEWQoEAjEoMCYw
# DAYKKwYBBAGEWQoDAqAKMAgCAQACAwehIKEKMAgCAQACAwGGoDANBgkqhkiG9w0B
# AQsFAAOCAQEAQ+5zOidwQwa2rqr7o1kATks5it6eSCpdVOR4DiYT2BZtmo9VGdod
# xj38iCIVbssso2Azj6SZlICuFBQhH5RekEhhJ519ts4ho8XSlpSa+hqsz05ko31M
# XQVDWy6lgxQ8a48pwJ1wcGKSd93AKwEq/NDxl2Ep40ZNxFXDK9Z9hgScDJLqOeZj
# Y6ydLMAJz4IYrqy2iI5Ady43GrtOp5Lfm3dm2E9MGG0LMOb57PznAEwR+1qUN6+k
# OtzKdMuaybaOTVg+3o6CSCnSIt2zhty6dAQzb2eakU7g8EPfFcfNkN05oh2J90Tn
# 9JZJR/9D0i6HHcfVPQZl1qpb0Tc3+NDmKDGCBA0wggQJAgEBMIGTMHwxCzAJBgNV
# BAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4w
# HAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xJjAkBgNVBAMTHU1pY3Jvc29m
# dCBUaW1lLVN0YW1wIFBDQSAyMDEwAhMzAAACKPClh9fzyB5AAAEAAAIoMA0GCWCG
# SAFlAwQCAQUAoIIBSjAaBgkqhkiG9w0BCQMxDQYLKoZIhvcNAQkQAQQwLwYJKoZI
# hvcNAQkEMSIEIEGvqEsBCjXGe4ZVhc2oTYDexF7fp7Gf12J7n7jMqgQtMIH6Bgsq
# hkiG9w0BCRACLzGB6jCB5zCB5DCBvQQgVbGKRlFgY1/igRVkrV5Pjkf7cZDf+rFX
# vlXC4G36ItcwgZgwgYCkfjB8MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGlu
# Z3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBv
# cmF0aW9uMSYwJAYDVQQDEx1NaWNyb3NvZnQgVGltZS1TdGFtcCBQQ0EgMjAxMAIT
# MwAAAijwpYfX88geQAABAAACKDAiBCCmmVqZJOVEXfKx1Jc9vWqTRxJpCOS0lg8Y
# dagXeYgTCDANBgkqhkiG9w0BAQsFAASCAgA93WSZjYv2wdl5kqpxTlwraCP3ql0i
# jk8dDIzeeJQ6SSeWMvt/9F4O61fp1Z5vPbpu0VYcrptMEZMMcfgVvh93K0QSbco2
# nG1aiLWAeUIqrGZEVXFhjNwgf+eGTd+ENLjNA8yd/jsXks0vWeFNz1Tem06BLLbf
# 5p9QLig4xBozWyLzwDI5GU8Kmyn80u2tDtbfVYIQtyIJ7o7YUmKq596PCAzprHzl
# bvz06quXgnvD6nUyghJJEp4SGfkc4kg9sCvCkNGS0IDN9E/e+23msKEhS5c0AgGa
# qwyq2JXs5utvKJJTCRl+pOOT/mtbIQZa/x/SUMRQZ0wLV5Lc3A8d+zq3OXU3ERVu
# j+03gLybYWgPguzRPZTT2kJkFiS1wVJcDxld9n5a3L8v01WjYkdLRe08A++ZknIs
# Y6NOX2gkxocSMGOTGugE+B10j5msey6MzOqQ3fcMztdD2arNtdHk2ho6B0FCCLbd
# kut/Z359QTTqmryp42bW/MFDKe7uEauuV7iZZoM2IS151KBSK0qDfEcuQB9OGA1z
# lM34y+rU3cCw89a1Eyay6keXodUVTHPokLnDcztlnBnAELJGq7EkRjox0il4YO1f
# 2GEJXXIEGPCONRIpdu0hvVMuRjeXSvDfl9CNi2wZxFxMLDVc/SMLUtTqJBtf8vJj
# foyN37KMhw+KnQ==
# SIG # End signature block