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 # MIInZAYJKoZIhvcNAQcCoIInVTCCJ1ECAQExDzANBglghkgBZQMEAgEFADB5Bgor # 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 # GwYwghsCAgEBMIGmMIGOMQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3Rv # 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/6GCF5QwgheQBgorBgEEAYI3AwMBMYIXgDCCF3wGCSqG # SIb3DQEHAqCCF20wghdpAgEDMQ8wDQYJYIZIAWUDBAIBBQAwggFSBgsqhkiG9w0B # CRABBKCCAUEEggE9MIIBOQIBAQYKKwYBBAGEWQoDATAxMA0GCWCGSAFlAwQCAQUA # BCCGCDCwQuQFn30dAO4zntuPEDNqlvyfCGGPoFJFfPWD5AIGajFNQNL/GBMyMDI2 # MDcxMTA0MDMyNC40OTlaMASAAgH0oIHRpIHOMIHLMQswCQYDVQQGEwJVUzETMBEG # A1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWlj # cm9zb2Z0IENvcnBvcmF0aW9uMSUwIwYDVQQLExxNaWNyb3NvZnQgQW1lcmljYSBP # cGVyYXRpb25zMScwJQYDVQQLEx5uU2hpZWxkIFRTUyBFU046QTkzNS0wM0UwLUQ5 # NDcxJTAjBgNVBAMTHE1pY3Jvc29mdCBUaW1lLVN0YW1wIFNlcnZpY2WgghHqMIIH # IDCCBQigAwIBAgITMwAAAifVwIPDsS5XLQABAAACJzANBgkqhkiG9w0BAQsFADB8 # MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVk # bW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSYwJAYDVQQDEx1N # aWNyb3NvZnQgVGltZS1TdGFtcCBQQ0EgMjAxMDAeFw0yNjAyMTkxOTQwMDRaFw0y # NzA1MTcxOTQwMDRaMIHLMQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3Rv # bjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0 # aW9uMSUwIwYDVQQLExxNaWNyb3NvZnQgQW1lcmljYSBPcGVyYXRpb25zMScwJQYD # VQQLEx5uU2hpZWxkIFRTUyBFU046QTkzNS0wM0UwLUQ5NDcxJTAjBgNVBAMTHE1p # Y3Jvc29mdCBUaW1lLVN0YW1wIFNlcnZpY2UwggIiMA0GCSqGSIb3DQEBAQUAA4IC # DwAwggIKAoICAQDixWy1fDOSL4qj3A1pady+elIDLwnF3UuLzJIOWwGHcEgrxxwt # nyviUIDmmxylTUl1u+2rBPp2zT4BwwQhvGaJpExqvPLlDFlbfmSflKI86eFqofiZ # 7j8NTRO4l7wGg9Njm+muNauTcFW2qdfIjKE950Okrm9MnMOGYy+fibNYdxTPRPq1 # T4MLZK3s3vdMyMEOldcOQkSKpxD6/1Gk6gOmCu2KgI8f0ex6vYxnKDl9W0OLSEa/ # 6y82oIbsm+1QBifOQ47xWKTG1CmvtGr85LzA75/MAcUmRw5/of/qET0UFV1WulMc # JrI6DASAsNCNB+6WLrotuBZAj+VMlqbn5RMZ6Q4IY7JwaAiIXh7VjxrnwUOYZG8W # EGhfrA98di+7LEn9AqvvEOyG+UQcjVhCCbMGXigJXSApeyeWupCsD0jgQMNCxfB5 # BLBDWxgdY3dJBEPgxfkgTDQLBggtVv2d5CYxHKgIItB4bI5eSb5jkIG2WotnFetT # 0legpw/Eozwf39ao6tENY21eVWIzRw/GsmvwjYQF6vVrxOD0pGVsfqGF8s3VPeY7 # hI2TxHFMqNA0IB/a2NLY7JTxYAKAP/11EJZt7xbqDLMgD1YDdGEzGpQijm3nAPCL # 2CebP/jmu90abJ2W425yglGHTI/nCBrwSpfRCgwzrfFelJaCKM6+35aFfwIDAQAB # o4IBSTCCAUUwHQYDVR0OBBYEFNLW58N4MGSG6ud7jWqgT92orfReMB8GA1UdIwQY # MBaAFJ+nFV0AXmJdg/Tl0mWnG1M1GelyMF8GA1UdHwRYMFYwVKBSoFCGTmh0dHA6 # Ly93d3cubWljcm9zb2Z0LmNvbS9wa2lvcHMvY3JsL01pY3Jvc29mdCUyMFRpbWUt # U3RhbXAlMjBQQ0ElMjAyMDEwKDEpLmNybDBsBggrBgEFBQcBAQRgMF4wXAYIKwYB # BQUHMAKGUGh0dHA6Ly93d3cubWljcm9zb2Z0LmNvbS9wa2lvcHMvY2VydHMvTWlj # cm9zb2Z0JTIwVGltZS1TdGFtcCUyMFBDQSUyMDIwMTAoMSkuY3J0MAwGA1UdEwEB # /wQCMAAwFgYDVR0lAQH/BAwwCgYIKwYBBQUHAwgwDgYDVR0PAQH/BAQDAgeAMA0G # CSqGSIb3DQEBCwUAA4ICAQAqncud4PSC1teb2H6nRuy7sDiKK13FXJirVB4Tfwjd # o2Mb+QL4j7wZ/k4G9P0CANHZFrDQcK0VFDTysrYu8Z0Aha14acDZPsyIoPvAGRRh # aHEuf7NckRjkfa/ylo1KyII8jbL9N9sJAqBPL8V4FNBjljv+1GHDOw127rZz5ZST # PoAPb2SA0v5yDgcpUMfxglPyp6cnPPoQpTtD9OGx8Dwm2P+o1TPxBIy6I0T9Rauu # logVCvKwflfeLTcKAvnSG1rCjerSXmU1DNXOsAD/bsrSjgbX5mAbD7XTRMF/vawA # WESFcn/BjjizxeWZb00aYSlkJA2rVtFlMM481aVWXdAbXPP5RzUiWTlgyHf/G7lC # xHYWGIZuB13T3aI6Y8mEgn/ou40aiFJo8r0+i0P5GdNneWtxiR0CMKUfko+5s/73 # cwe1Wfp8BKXa270cicVQasFf5sRV7pFm+V7fNRXwCu7anTOmga76zO7/2t+zOlib # vphT+Q6Zd+B2qYsSn4xBaY+YzHpnycLW5cvJyhPxBCcb1oRYfhRzCADb2utI2EtG # Cjc2P2ii4LyR4QMb/n8cOweL9IqVTKKzzVk+zZJxV3vrp4LyuQXw0O30la6BcHdN # AAAB9UC83zs3G9d+AlIfZLM97tMUNKWjbBpIirFx6LTDFXVtZQd7hqzLYByjbjH0 # ujCCB3EwggVZoAMCAQICEzMAAAAVxedrngKbSZkAAAAAABUwDQYJKoZIhvcNAQEL # BQAwgYgxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQH # EwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xMjAwBgNV # BAMTKU1pY3Jvc29mdCBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAyMDEwMB4X # DTIxMDkzMDE4MjIyNVoXDTMwMDkzMDE4MzIyNVowfDELMAkGA1UEBhMCVVMxEzAR # BgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1p # Y3Jvc29mdCBDb3Jwb3JhdGlvbjEmMCQGA1UEAxMdTWljcm9zb2Z0IFRpbWUtU3Rh # bXAgUENBIDIwMTAwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDk4aZM # 57RyIQt5osvXJHm9DtWC0/3unAcH0qlsTnXIyjVX9gF/bErg4r25PhdgM/9cT8dm # 95VTcVrifkpa/rg2Z4VGIwy1jRPPdzLAEBjoYH1qUoNEt6aORmsHFPPFdvWGUNzB # RMhxXFExN6AKOG6N7dcP2CZTfDlhAnrEqv1yaa8dq6z2Nr41JmTamDu6GnszrYBb # fowQHJ1S/rboYiXcag/PXfT+jlPP1uyFVk3v3byNpOORj7I5LFGc6XBpDco2LXCO # Mcg1KL3jtIckw+DJj361VI/c+gVVmG1oO5pGve2krnopN6zL64NF50ZuyjLVwIYw # XE8s4mKyzbnijYjklqwBSru+cakXW2dg3viSkR4dPf0gz3N9QZpGdc3EXzTdEonW # /aUgfX782Z5F37ZyL9t9X4C626p+Nuw2TPYrbqgSUei/BQOj0XOmTTd0lBw0gg/w # EPK3Rxjtp+iZfD9M269ewvPV2HM9Q07BMzlMjgK8QmguEOqEUUbi0b1qGFphAXPK # Z6Je1yh2AuIzGHLXpyDwwvoSCtdjbwzJNmSLW6CmgyFdXzB0kZSU2LlQ+QuJYfM2 # BjUYhEfb3BvR/bLUHMVr9lxSUV0S2yW6r1AFemzFER1y7435UsSFF5PAPBXbGjfH # CBUYP3irRbb1Hode2o+eFnJpxq57t7c+auIurQIDAQABo4IB3TCCAdkwEgYJKwYB # BAGCNxUBBAUCAwEAATAjBgkrBgEEAYI3FQIEFgQUKqdS/mTEmr6CkTxGNSnPEP8v # BO4wHQYDVR0OBBYEFJ+nFV0AXmJdg/Tl0mWnG1M1GelyMFwGA1UdIARVMFMwUQYM # KwYBBAGCN0yDfQEBMEEwPwYIKwYBBQUHAgEWM2h0dHA6Ly93d3cubWljcm9zb2Z0 # LmNvbS9wa2lvcHMvRG9jcy9SZXBvc2l0b3J5Lmh0bTATBgNVHSUEDDAKBggrBgEF # BQcDCDAZBgkrBgEEAYI3FAIEDB4KAFMAdQBiAEMAQTALBgNVHQ8EBAMCAYYwDwYD # VR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAWgBTV9lbLj+iiXGJo0T2UkFvXzpoYxDBW # BgNVHR8ETzBNMEugSaBHhkVodHRwOi8vY3JsLm1pY3Jvc29mdC5jb20vcGtpL2Ny # bC9wcm9kdWN0cy9NaWNSb29DZXJBdXRfMjAxMC0wNi0yMy5jcmwwWgYIKwYBBQUH # AQEETjBMMEoGCCsGAQUFBzAChj5odHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtp # L2NlcnRzL01pY1Jvb0NlckF1dF8yMDEwLTA2LTIzLmNydDANBgkqhkiG9w0BAQsF # AAOCAgEAnVV9/Cqt4SwfZwExJFvhnnJL/Klv6lwUtj5OR2R4sQaTlz0xM7U518Jx # Nj/aZGx80HU5bbsPMeTCj/ts0aGUGCLu6WZnOlNN3Zi6th542DYunKmCVgADsAW+ # iehp4LoJ7nvfam++Kctu2D9IdQHZGN5tggz1bSNU5HhTdSRXud2f8449xvNo32X2 # pFaq95W2KFUn0CS9QKC/GbYSEhFdPSfgQJY4rPf5KYnDvBewVIVCs/wMnosZiefw # C2qBwoEZQhlSdYo2wh3DYXMuLGt7bj8sCXgU6ZGyqVvfSaN0DLzskYDSPeZKPmY7 # T7uG+jIa2Zb0j/aRAfbOxnT99kxybxCrdTDFNLB62FD+CljdQDzHVG2dY3RILLFO # Ry3BFARxv2T5JL5zbcqOCb2zAVdJVGTZc9d/HltEAY5aGZFrDZ+kKNxnGSgkujhL # mm77IVRrakURR6nxt67I6IleT53S0Ex2tVdUCbFpAUR+fKFhbHP+CrvsQWY9af3L # wUFJfn6Tvsv4O+S3Fb+0zj6lMVGEvL8CwYKiexcdFYmNcP7ntdAoGokLjzbaukz5 # m/8K6TT4JDVnK+ANuOaMmdbhIurwJ0I9JZTmdHRbatGePu1+oDEzfbzL6Xu/OHBE # 0ZDxyKs6ijoIYn/ZcGNTTY3ugm2lBRDBcQZqELQdVTNYs6FwZvKhggNNMIICNQIB # ATCB+aGB0aSBzjCByzELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24x # EDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlv # bjElMCMGA1UECxMcTWljcm9zb2Z0IEFtZXJpY2EgT3BlcmF0aW9uczEnMCUGA1UE # CxMeblNoaWVsZCBUU1MgRVNOOkE5MzUtMDNFMC1EOTQ3MSUwIwYDVQQDExxNaWNy # b3NvZnQgVGltZS1TdGFtcCBTZXJ2aWNloiMKAQEwBwYFKw4DAhoDFQAjHzqthPwO # 0GDckDMA6x54lIiMKqCBgzCBgKR+MHwxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpX # YXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQg # Q29ycG9yYXRpb24xJjAkBgNVBAMTHU1pY3Jvc29mdCBUaW1lLVN0YW1wIFBDQSAy # MDEwMA0GCSqGSIb3DQEBCwUAAgUA7fwVADAiGA8yMDI2MDcxMTAxMDQwMFoYDzIw # MjYwNzEyMDEwNDAwWjB0MDoGCisGAQQBhFkKBAExLDAqMAoCBQDt/BUAAgEAMAcC # AQACAhmEMAcCAQACAhLgMAoCBQDt/WaAAgEAMDYGCisGAQQBhFkKBAIxKDAmMAwG # CisGAQQBhFkKAwKgCjAIAgEAAgMHoSChCjAIAgEAAgMBhqAwDQYJKoZIhvcNAQEL # BQADggEBADbiDOygkBkm7SR2lJuEWwi4tXQy2r0pragGBi3WqWQCku3t30Z5kN+W # QSpn48TO+nxcxXgmOVoGk8zoNv9U5h15bsZHKvHMGO7YPX+czw6mFuwYlFIyyOOL # KtqPt94uO0ghUTZ9jbV2ySH24bY196p6a1umfrllUoh29VD68tYhH/KG8l+1WyfJ # /zZh9W0PwlwrPkEw/JShis/Y//1UAIJDBKyDpDRBeNVve13BwIdajKQ4ieIW+jMB # wGtdet8SDmV41LJi3r+Ut+4z7j77Sqj+QJRm9M7D9b3BizijFE9YqK18cwq6rJkH # q1Hc7hQkRadv7RzohWat3o3Hp/DHP3wxggQNMIIECQIBATCBkzB8MQswCQYDVQQG # EwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwG # A1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSYwJAYDVQQDEx1NaWNyb3NvZnQg # VGltZS1TdGFtcCBQQ0EgMjAxMAITMwAAAifVwIPDsS5XLQABAAACJzANBglghkgB # ZQMEAgEFAKCCAUowGgYJKoZIhvcNAQkDMQ0GCyqGSIb3DQEJEAEEMC8GCSqGSIb3 # DQEJBDEiBCDGUAErMyLIIddmBnDLrd4uwRH3GnIHmkqUNHtADUd7TTCB+gYLKoZI # hvcNAQkQAi8xgeowgecwgeQwgb0EIOXnARo1oVIcOLJKDqlE0adq/jZ9TXdlnXWR # cXGThBFyMIGYMIGApH4wfDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0 # b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3Jh # dGlvbjEmMCQGA1UEAxMdTWljcm9zb2Z0IFRpbWUtU3RhbXAgUENBIDIwMTACEzMA # AAIn1cCDw7EuVy0AAQAAAicwIgQgiyJO45KRi+X1IjZ9RaCxj4QkYZspEo5SzIx2 # LU+UN+gwDQYJKoZIhvcNAQELBQAEggIAqCQwecLD0WzYztsBmuy6t9WiZ8iCvL/n # JKYRtQ15ZGy+4jHAKr5+Ggsn5/kwSPlL5GZr2hI5/sTrsaQfNQzNcLqJRoQO2HoY # Xvs1nTnm4mw0DJWlxICXXLLlKUGEpO7XhopDEL6a8ok1aKQabqxeKC+Vs4FtvcfU # kWLJ3PYaFIcVvoMkCzQaqroRuBlv1Y7YH7zcg1jIzKhgoS6RvivpDLoGDznAf4Lj # 2IE3ScYFH74QVJSBBvDHeC8Y/0IZ7iSSUFdavnqPEv7+NgAfuoFoNIHX87GdV8Id # kFixPxive9XVUO9nSxnP/IW3ZSmssZht+RZ/B3thUJZ4nK901LhXTU9v/PJyMtoI # B0Md0iJ9plm2s5ra1QEoa2zeWUvSlFLs213CDlOdfgBHH3fCPHTTFeU3nM0UyYqf # 14XOLZdkUYKyWc/uB9sAGSSMXRKXCNWWXPtIKf00awNzrtT87XXey6AXwNz/7kqT # qEJcDMZu5i8MpE5EFIvBwY4sitwXTr65/nN9vRfvkdFv5AtC0aADNoqCCs7WHyo2 # 4lF2juIU4xX9j/mN0TZQlIDGcVksfcHjAU1/uKRkKjEH/heQ+NtTwKbtfC52TXSQ # 2qX+KWBz5zewygDXM8d2Dlpqny068V+JkYVfk5as788rXv+3t59jPqR3HWfcpdzk # 0hErIjXh9oc= # SIG # End signature block