new-runtimepoc/Pester.RSpec.Nunit.TestResults.ts.ps1
param ([switch] $PassThru) Get-Module Pester.Runtime, Pester.Utility, P, Pester, Axiom, Stack | Remove-Module Import-Module $PSScriptRoot\p.psm1 -DisableNameChecking Import-Module $PSScriptRoot\..\Dependencies\Axiom\Axiom.psm1 -DisableNameChecking Import-Module $PSScriptRoot\..\Pester.psd1 $global:PesterPreference = @{ Debug = @{ ShowFullErrors = $false } } function Verify-XmlTime { param ( [Parameter(ValueFromPipeline = $true)] $Actual, [Parameter(Mandatory = $true, Position = 0)] [AllowNull()] [Nullable[TimeSpan]] $Expected ) if ($null -eq $Expected) { throw [Exception]'Expected value is $null.' } if ($null -eq $Actual) { throw [Exception]'Actual value is $null.' } if ('0.0000' -eq $Actual) { # it is unlikely that anything takes less than # 0.0001 seconds (one tenth of a millisecond) so # throw when we see 0, because that probably means # we are not measuring at all throw [Exception]'Actual value is zero.' } $e = [string][Math]::Round($Expected.TotalSeconds, 4) if ($e -ne $Actual) { $message = "Expected and actual values differ!`n" + "Expected: '$e' seconds (raw '$($Expected.TotalSeconds)' seconds)`n" + "Actual : '$Actual' seconds" throw [Exception]$message } $Actual } i -PassThru:$PassThru { b "Write nunit test results" { t "should write a successful test result" { $sb = { Describe "Mocked Describe" { It "Successful testcase" { $true | Should -Be $true } } } $r = Invoke-Pester -Configuration ([PesterConfiguration]@{ Run = @{ ScriptBlock = $sb }; Output = @{ Verbosity = 'None' } }) $xmlResult = $r | ConvertTo-NUnitReport $xmlTestCase = $xmlResult.'test-results'.'test-suite'.'results'.'test-suite'.'results'.'test-suite'.'results'.'test-case' $xmlTestCase.name | Verify-Equal "Mocked Describe.Successful testcase" $xmlTestCase.result | Verify-Equal "Success" $xmlTestCase.time | Verify-XmlTime $r.Containers[0].Blocks[0].Tests[0].Duration } t "should write a failed test result" { $sb = { Describe "Mocked Describe" { It "Failed testcase" { "Testing" | Should -Be "Test" } } } $r = Invoke-Pester -Configuration ([PesterConfiguration]@{ Run = @{ ScriptBlock = $sb }; Output = @{ Verbosity = 'None' } }) $xmlResult = $r | ConvertTo-NUnitReport $xmlTestCase = $xmlResult.'test-results'.'test-suite'.'results'.'test-suite'.'results'.'test-suite'.'results'.'test-case' $xmlTestCase.name | Verify-Equal "Mocked Describe.Failed testcase" $xmlTestCase.result | Verify-Equal "Failure" $xmlTestCase.time | Verify-XmlTime $r.Containers[0].Blocks[0].Tests[0].Duration $failureLine = $sb.StartPosition.StartLine+3 $message = $xmlTestCase.failure.message -split "`n" $message[0] | Verify-Equal "Expected strings to be the same, but they were different." $message[-3] | Verify-Equal "Expected: 'Test'" $message[-2] | Verify-Equal "But was: 'Testing'" $message[-1] | Verify-Equal "at ""Testing"" | Should -Be ""Test"", ${PSCommandPath}:$failureLine" $stackTrace = $xmlTestCase.failure.'stack-trace' -split "`n" $stackTrace[0] | Verify-Equal "at <ScriptBlock>, ${PSCommandPath}:$failureLine" } t "should write a failed test result when there are multiple errors" { $sb = { Describe "Mocked Describe" { It "Failed testcase" { "Testing" | Should -Be "Test" } AfterEach { throw "teardown failed" } } } $r = Invoke-Pester -Configuration ([PesterConfiguration]@{ Run = @{ ScriptBlock = $sb }; Output = @{ Verbosity = 'None' } }) $xmlResult = $r | ConvertTo-NUnitReport $xmlTestCase = $xmlResult.'test-results'.'test-suite'.'results'.'test-suite'.'results'.'test-suite'.'results'.'test-case' $xmlTestCase.name | Verify-Equal "Mocked Describe.Failed testcase" $xmlTestCase.result | Verify-Equal "Failure" $xmlTestCase.time | Verify-XmlTime $r.Containers[0].Blocks[0].Tests[0].Duration $message = $xmlTestCase.failure.message -split "`n" $message[0] | Verify-Equal "[0] Expected strings to be the same, but they were different." $message[7] | Verify-Equal "[1] RuntimeException: teardown failed" $sbStartLine = $sb.StartPosition.StartLine $stackTrace = $xmlTestCase.failure.'stack-trace' -split "`n" $stackTrace[0] | Verify-Equal "[0] at <ScriptBlock>, ${PSCommandPath}:$($sbStartLine+3)" $stackTrace[1] | Verify-Equal "[1] at <ScriptBlock>, ${PSCommandPath}:$($sbStartLine+7)" } t "should write the test summary" { $sb = { Describe "Mocked Describe" { It "Successful testcase" { $true | Should -Be $true } } } $r = Invoke-Pester -Configuration ([PesterConfiguration]@{ Run = @{ ScriptBlock = $sb }; Output = @{ Verbosity = 'None' } }) $xmlResult = $r | ConvertTo-NUnitReport $xmlTestResult = $xmlResult.'test-results' $xmlTestResult.total | Verify-Equal 1 $xmlTestResult.failures | Verify-Equal 0 $xmlTestResult.date | Verify-Equal (Get-Date -Format "yyyy-MM-dd" $r.ExecutedAt) $xmlTestResult.time | Verify-Equal (Get-Date -Format "HH:mm:ss" $r.ExecutedAt) } t "should write the test-suite information" { $sb = { Describe "Mocked Describe" { It "Successful testcase" { $true | Should -Be $true } It "Successful testcase" { $true | Should -Be $true } } } $r = Invoke-Pester -Configuration ([PesterConfiguration]@{ Run = @{ ScriptBlock = $sb }; Output = @{ Verbosity = 'None' } }) $xmlResult = $r | ConvertTo-NUnitReport $xmlTestResult = $xmlResult.'test-results'.'test-suite'.'results'.'test-suite'.'results'.'test-suite' $xmlTestResult.type | Verify-Equal "TestFixture" $xmlTestResult.name | Verify-Equal "Mocked Describe" $xmlTestResult.description | Verify-Equal "Mocked Describe" $xmlTestResult.result | Verify-Equal "Success" $xmlTestResult.success | Verify-Equal "True" $xmlTestResult.time | Verify-XmlTime $r.Containers[0].Blocks[0].Duration } t "should write two test-suite elements for two describes" { $sb = { Describe "Describe #1" { It "Successful testcase" { $true | Should -Be $true } } Describe "Describe #2" { It "Failed testcase" { $false | Should -Be $true } } } $r = Invoke-Pester -Configuration ([PesterConfiguration]@{ Run = @{ ScriptBlock = $sb }; Output = @{ Verbosity = 'None' } }) $xmlResult = $r | ConvertTo-NUnitReport $xmlTestSuite1 = $xmlResult.'test-results'.'test-suite'.'results'.'test-suite'.'results'.'test-suite'[0] $xmlTestSuite1.name | Verify-Equal "Describe #1" $xmlTestSuite1.description | Verify-Equal "Describe #1" $xmlTestSuite1.result | Verify-Equal "Success" $xmlTestSuite1.success | Verify-Equal "True" $xmlTestSuite1.time | Verify-XmlTime $r.Containers[0].Blocks[0].Duration $xmlTestSuite2 = $xmlResult.'test-results'.'test-suite'.'results'.'test-suite'.'results'.'test-suite'[1] $xmlTestSuite2.name | Verify-Equal "Describe #2" $xmlTestSuite2.description | Verify-Equal "Describe #2" $xmlTestSuite2.result | Verify-Equal "Failure" $xmlTestSuite2.success | Verify-Equal "False" $xmlTestSuite2.time | Verify-XmlTime $r.Containers[0].Blocks[1].Duration } t "should write the environment information" { $sb = { } $r = Invoke-Pester -Configuration ([PesterConfiguration]@{ Run = @{ ScriptBlock = $sb }; Output = @{ Verbosity = 'None' } }) $xmlResult = $r | ConvertTo-NUnitReport $xmlEnvironment = $xmlResult.'test-results'.'environment' $xmlEnvironment.'os-Version' | Verify-NotNull $xmlEnvironment.platform | Verify-NotNull $xmlEnvironment.cwd | Verify-Equal (Get-Location).Path if ($env:Username) { $xmlEnvironment.user | Verify-Equal $env:Username } $xmlEnvironment.'machine-name' | Verify-Equal $(hostname) } t "Should validate test results against the nunit 2.5 schema" { $sb = { Describe "Describe #1" { It "Successful testcase" { $true | Should -Be $true } } Describe "Describe #2" { It "Failed testcase" { $false | Should -Be $true 5 } } } $r = Invoke-Pester -Configuration ([PesterConfiguration]@{ Run = @{ ScriptBlock = $sb }; Output = @{ Verbosity = 'None' } }) $xmlResult = [xml] ($r | ConvertTo-NUnitReport) $schemePath = (Get-Module -Name Pester).Path | Split-Path | Join-Path -ChildPath "nunit_schema_2.5.xsd" $xmlResult.Schemas.Add($null, $schemePath) > $null $xmlResult.Validate( { throw $args[1].Exception }) } t "handles special characters in block descriptions well -!@#$%^&*()_+`1234567890[];'',./""- " { $sb = { Describe 'Describe -!@#$%^&*()_+`1234567890[];'',./"- #1' { It "Successful testcase -!@#$%^&*()_+`1234567890[];'',./""-" { $true | Should -Be $true } } } $r = Invoke-Pester -Configuration ([PesterConfiguration]@{ Run = @{ ScriptBlock = $sb }; Output = @{ Verbosity = 'None' } }) $xmlResult = [xml] ($r | ConvertTo-NUnitReport) $schemePath = (Get-Module -Name Pester).Path | Split-Path | Join-Path -ChildPath "nunit_schema_2.5.xsd" $xmlResult.Schemas.Add($null, $schemePath) > $null $xmlResult.Validate( { throw $args[1].Exception }) } } b 'Exporting Parameterized Tests (Newer format)' { t 'should write parameterized test results correctly' { $sb = { Describe "Mocked Describe" { It "Parameterized Testcase <value>" -TestCases @( @{ Value = 1 } [ordered] @{ Value = 2; StringParameter = "two"; NullParameter = $null; NumberParameter = -42.67 } ) { param ($Value) $Value | Should -Be 1 } } } $r = Invoke-Pester -Configuration ([PesterConfiguration]@{ Run = @{ ScriptBlock = $sb }; Output = @{ Verbosity = 'None' } }) $xmlResult = $r | ConvertTo-NUnitReport $xmlTestSuite = $xmlResult.'test-results'.'test-suite'.'results'.'test-suite'.'results'.'test-suite'.'results'.'test-suite' $xmlTestSuite.name | Verify-Equal 'Mocked Describe.Parameterized Testcase <value>' $xmlTestSuite.description | Verify-Equal 'Parameterized Testcase <value>' $xmlTestSuite.type | Verify-Equal 'ParameterizedTest' $xmlTestSuite.result | Verify-Equal 'Failure' $xmlTestSuite.success | Verify-Equal 'False' $xmlTestSuite.time | Verify-XmlTime ( $r.Containers[0].Blocks[0].Tests[0].Duration + $r.Containers[0].Blocks[0].Tests[1].Duration) $testCase1 = $xmlTestSuite.results.'test-case'[0] $testCase2 = $xmlTestSuite.results.'test-case'[1] $testCase1.Name | Verify-Equal 'Mocked Describe.Parameterized Testcase <value>(1)' $testCase1.Time | Verify-XmlTime $r.Containers[0].Blocks[0].Tests[0].Duration $testCase2.Name | Verify-Equal 'Mocked Describe.Parameterized Testcase <value>(2,"two",null,-42.67)' $testCase2.Time | Verify-XmlTime $r.Containers[0].Blocks[0].Tests[1].Duration # verify against schema $schemaPath = (Get-Module -Name Pester).Path | Split-Path | Join-Path -ChildPath "nunit_schema_2.5.xsd" $null = $xmlResult.Schemas.Add($null, $schemaPath) $xmlResult.Validate( { throw $args[1].Exception }) } } b "Exporting multiple containers" { t "should write report for multiple containers" { $sb = @( { Describe "Describe #1" { It "Successful testcase" { $true | Should -Be $true } } }, { Describe "Describe #2" { It "Failed testcase" { $false | Should -Be $true } } }) $r = Invoke-Pester -Configuration ([PesterConfiguration]@{ Run = @{ ScriptBlock = $sb }; Output = @{ Verbosity = 'None' } }) $xmlResult = ConvertTo-NUnitReport $r $xmlTestSuite1 = $xmlResult.'test-results'.'test-suite'.'results'.'test-suite'.'results'.'test-suite'[0] $xmlTestSuite1.name | Verify-Equal "Describe #1" $xmlTestSuite1.description | Verify-Equal "Describe #1" $xmlTestSuite1.result | Verify-Equal "Success" $xmlTestSuite1.success | Verify-Equal "True" $xmlTestSuite1.time | Verify-XmlTime $r.Containers[0].Blocks[0].Duration $xmlTestSuite2 = $xmlResult.'test-results'.'test-suite'.'results'.'test-suite'.'results'.'test-suite'[1] $xmlTestSuite2.name | Verify-Equal "Describe #2" $xmlTestSuite2.description | Verify-Equal "Describe #2" $xmlTestSuite2.result | Verify-Equal "Failure" $xmlTestSuite2.success | Verify-Equal "False" $xmlTestSuite2.time | Verify-XmlTime $r.Containers[1].Blocks[0].Duration } } } # SIG # Begin signature block # MIIcVgYJKoZIhvcNAQcCoIIcRzCCHEMCAQExCzAJBgUrDgMCGgUAMGkGCisGAQQB # gjcCAQSgWzBZMDQGCisGAQQBgjcCAR4wJgIDAQAABBAfzDtgWUsITrck0sYpfvNR # AgEAAgEAAgEAAgEAAgEAMCEwCQYFKw4DAhoFAAQUatMFa29Z7uPFLnhalHVlw0Os # vYiggheFMIIFDjCCA/agAwIBAgIQCIQ1OU/QbU6rESO7M78utDANBgkqhkiG9w0B # AQsFADByMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYD # VQQLExB3d3cuZGlnaWNlcnQuY29tMTEwLwYDVQQDEyhEaWdpQ2VydCBTSEEyIEFz # c3VyZWQgSUQgQ29kZSBTaWduaW5nIENBMB4XDTIwMDEzMTAwMDAwMFoXDTIxMDEw # NTEyMDAwMFowSzELMAkGA1UEBhMCQ1oxDjAMBgNVBAcTBVByYWhhMRUwEwYDVQQK # DAxKYWt1YiBKYXJlxaExFTATBgNVBAMMDEpha3ViIEphcmXFoTCCASIwDQYJKoZI # hvcNAQEBBQADggEPADCCAQoCggEBALYF0cDtFUyYgraHpHdObGJM9dxjfRr0WaPN # kVZcEHdPXk4bVCPZLSca3Byybx745CpB3oejDHEbohLSTrbunoSA9utpwxVQSutt # /H1onVexiJgwGJ6xoQgR17FGLBGiIHgyPhFJhba9yENh0dqargLWllsg070WE2yb # gz3m659gmfuCuSZOhQ2nCHvOjEocTiI67mZlHvN7axg+pCgdEJrtIyvhHPqXeE2j # cdMrfmYY1lq2FBpELEW1imYlu5BnaJd/5IT7WjHL3LWx5Su9FkY5RwrA6+X78+j+ # vKv00JtDjM0dT+4A/m65jXSywxa4YoGDqQ5n+BwDMQlWCzfu37sCAwEAAaOCAcUw # ggHBMB8GA1UdIwQYMBaAFFrEuXsqCqOl6nEDwGD5LfZldQ5YMB0GA1UdDgQWBBRE # 05R/U5mVzc4vKq4rvKyyPm12EzAOBgNVHQ8BAf8EBAMCB4AwEwYDVR0lBAwwCgYI # KwYBBQUHAwMwdwYDVR0fBHAwbjA1oDOgMYYvaHR0cDovL2NybDMuZGlnaWNlcnQu # Y29tL3NoYTItYXNzdXJlZC1jcy1nMS5jcmwwNaAzoDGGL2h0dHA6Ly9jcmw0LmRp # Z2ljZXJ0LmNvbS9zaGEyLWFzc3VyZWQtY3MtZzEuY3JsMEwGA1UdIARFMEMwNwYJ # YIZIAYb9bAMBMCowKAYIKwYBBQUHAgEWHGh0dHBzOi8vd3d3LmRpZ2ljZXJ0LmNv # bS9DUFMwCAYGZ4EMAQQBMIGEBggrBgEFBQcBAQR4MHYwJAYIKwYBBQUHMAGGGGh0 # dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBOBggrBgEFBQcwAoZCaHR0cDovL2NhY2Vy # dHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0U0hBMkFzc3VyZWRJRENvZGVTaWduaW5n # Q0EuY3J0MAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcNAQELBQADggEBADAk7PRuDcdl # lPZQSfZ1Y0jeItmEWPMNcAL0LQaa6M5Slrznjxv1ZiseT9SMWTxOQylfPvpOSo1x # xV3kD7qf7tf2EuicKkV6dBgGiHb0riWZ3+wMA6C8IK3cGesJ4jgpTtYEzbh88pxT # g2MSzpRnwyXHhrgcKSps1z34JmmmHP1lncxNC6DTM6yEUwE7XiDD2xNoeLITgdTQ # jjMMT6nDJe8+xL0Zyh32OPIyrG7qPjG6MmEjzlCaWsE/trVo7I9CSOjwpp8721Hj # q/tIHzPFg1C3dYmDh8Kbmr21dHWBLYQF4P8lq8u8AYDa6H7xvkx7G0i2jglAA4YK # i1V8AlyTwRkwggUwMIIEGKADAgECAhAECRgbX9W7ZnVTQ7VvlVAIMA0GCSqGSIb3 # DQEBCwUAMGUxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAX # BgNVBAsTEHd3dy5kaWdpY2VydC5jb20xJDAiBgNVBAMTG0RpZ2lDZXJ0IEFzc3Vy # ZWQgSUQgUm9vdCBDQTAeFw0xMzEwMjIxMjAwMDBaFw0yODEwMjIxMjAwMDBaMHIx # CzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3 # dy5kaWdpY2VydC5jb20xMTAvBgNVBAMTKERpZ2lDZXJ0IFNIQTIgQXNzdXJlZCBJ # RCBDb2RlIFNpZ25pbmcgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB # AQD407Mcfw4Rr2d3B9MLMUkZz9D7RZmxOttE9X/lqJ3bMtdx6nadBS63j/qSQ8Cl # +YnUNxnXtqrwnIal2CWsDnkoOn7p0WfTxvspJ8fTeyOU5JEjlpB3gvmhhCNmElQz # UHSxKCa7JGnCwlLyFGeKiUXULaGj6YgsIJWuHEqHCN8M9eJNYBi+qsSyrnAxZjNx # PqxwoqvOf+l8y5Kh5TsxHM/q8grkV7tKtel05iv+bMt+dDk2DZDv5LVOpKnqagqr # hPOsZ061xPeM0SAlI+sIZD5SlsHyDxL0xY4PwaLoLFH3c7y9hbFig3NBggfkOItq # cyDQD2RzPJ6fpjOp/RnfJZPRAgMBAAGjggHNMIIByTASBgNVHRMBAf8ECDAGAQH/ # AgEAMA4GA1UdDwEB/wQEAwIBhjATBgNVHSUEDDAKBggrBgEFBQcDAzB5BggrBgEF # BQcBAQRtMGswJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBD # BggrBgEFBQcwAoY3aHR0cDovL2NhY2VydHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0 # QXNzdXJlZElEUm9vdENBLmNydDCBgQYDVR0fBHoweDA6oDigNoY0aHR0cDovL2Ny # bDQuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEUm9vdENBLmNybDA6oDig # NoY0aHR0cDovL2NybDMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEUm9v # dENBLmNybDBPBgNVHSAESDBGMDgGCmCGSAGG/WwAAgQwKjAoBggrBgEFBQcCARYc # aHR0cHM6Ly93d3cuZGlnaWNlcnQuY29tL0NQUzAKBghghkgBhv1sAzAdBgNVHQ4E # FgQUWsS5eyoKo6XqcQPAYPkt9mV1DlgwHwYDVR0jBBgwFoAUReuir/SSy4IxLVGL # p6chnfNtyA8wDQYJKoZIhvcNAQELBQADggEBAD7sDVoks/Mi0RXILHwlKXaoHV0c # LToaxO8wYdd+C2D9wz0PxK+L/e8q3yBVN7Dh9tGSdQ9RtG6ljlriXiSBThCk7j9x # jmMOE0ut119EefM2FAaK95xGTlz/kLEbBw6RFfu6r7VRwo0kriTGxycqoSkoGjpx # KAI8LpGjwCUR4pwUR6F6aGivm6dcIFzZcbEMj7uo+MUSaJ/PQMtARKUT8OZkDCUI # QjKyNookAv4vcn4c10lFluhZHen6dGRrsutmQ9qzsIzV6Q3d9gEgzpkxYz0IGhiz # gZtPxpMQBvwHgfqL2vmCSfdibqFT+hKUGIUukpHqaGxEMrJmoecYpJpkUe8wggZq # MIIFUqADAgECAhADAZoCOv9YsWvW1ermF/BmMA0GCSqGSIb3DQEBBQUAMGIxCzAJ # BgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5k # aWdpY2VydC5jb20xITAfBgNVBAMTGERpZ2lDZXJ0IEFzc3VyZWQgSUQgQ0EtMTAe # Fw0xNDEwMjIwMDAwMDBaFw0yNDEwMjIwMDAwMDBaMEcxCzAJBgNVBAYTAlVTMREw # DwYDVQQKEwhEaWdpQ2VydDElMCMGA1UEAxMcRGlnaUNlcnQgVGltZXN0YW1wIFJl # c3BvbmRlcjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKNkXfx8s+CC # NeDg9sYq5kl1O8xu4FOpnx9kWeZ8a39rjJ1V+JLjntVaY1sCSVDZg85vZu7dy4Xp # X6X51Id0iEQ7Gcnl9ZGfxhQ5rCTqqEsskYnMXij0ZLZQt/USs3OWCmejvmGfrvP9 # Enh1DqZbFP1FI46GRFV9GIYFjFWHeUhG98oOjafeTl/iqLYtWQJhiGFyGGi5uHzu # 5uc0LzF3gTAfuzYBje8n4/ea8EwxZI3j6/oZh6h+z+yMDDZbesF6uHjHyQYuRhDI # jegEYNu8c3T6Ttj+qkDxss5wRoPp2kChWTrZFQlXmVYwk/PJYczQCMxr7GJCkawC # wO+k8IkRj3cCAwEAAaOCAzUwggMxMA4GA1UdDwEB/wQEAwIHgDAMBgNVHRMBAf8E # AjAAMBYGA1UdJQEB/wQMMAoGCCsGAQUFBwMIMIIBvwYDVR0gBIIBtjCCAbIwggGh # BglghkgBhv1sBwEwggGSMCgGCCsGAQUFBwIBFhxodHRwczovL3d3dy5kaWdpY2Vy # dC5jb20vQ1BTMIIBZAYIKwYBBQUHAgIwggFWHoIBUgBBAG4AeQAgAHUAcwBlACAA # bwBmACAAdABoAGkAcwAgAEMAZQByAHQAaQBmAGkAYwBhAHQAZQAgAGMAbwBuAHMA # dABpAHQAdQB0AGUAcwAgAGEAYwBjAGUAcAB0AGEAbgBjAGUAIABvAGYAIAB0AGgA # ZQAgAEQAaQBnAGkAQwBlAHIAdAAgAEMAUAAvAEMAUABTACAAYQBuAGQAIAB0AGgA # ZQAgAFIAZQBsAHkAaQBuAGcAIABQAGEAcgB0AHkAIABBAGcAcgBlAGUAbQBlAG4A # dAAgAHcAaABpAGMAaAAgAGwAaQBtAGkAdAAgAGwAaQBhAGIAaQBsAGkAdAB5ACAA # YQBuAGQAIABhAHIAZQAgAGkAbgBjAG8AcgBwAG8AcgBhAHQAZQBkACAAaABlAHIA # ZQBpAG4AIABiAHkAIAByAGUAZgBlAHIAZQBuAGMAZQAuMAsGCWCGSAGG/WwDFTAf # BgNVHSMEGDAWgBQVABIrE5iymQftHt+ivlcNK2cCzTAdBgNVHQ4EFgQUYVpNJLZJ # Mp1KKnkag0v0HonByn0wfQYDVR0fBHYwdDA4oDagNIYyaHR0cDovL2NybDMuZGln # aWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEQ0EtMS5jcmwwOKA2oDSGMmh0dHA6 # Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJRENBLTEuY3JsMHcG # CCsGAQUFBwEBBGswaTAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQu # Y29tMEEGCCsGAQUFBzAChjVodHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vRGln # aUNlcnRBc3N1cmVkSURDQS0xLmNydDANBgkqhkiG9w0BAQUFAAOCAQEAnSV+GzNN # siaBXJuGziMgD4CH5Yj//7HUaiwx7ToXGXEXzakbvFoWOQCd42yE5FpA+94GAYw3 # +puxnSR+/iCkV61bt5qwYCbqaVchXTQvH3Gwg5QZBWs1kBCge5fH9j/n4hFBpr1i # 2fAnPTgdKG86Ugnw7HBi02JLsOBzppLA044x2C/jbRcTBu7kA7YUq/OPQ6dxnSHd # FMoVXZJB2vkPgdGZdA0mxA5/G7X1oPHGdwYoFenYk+VVFvC7Cqsc21xIJ2bIo4sK # HOWV2q7ELlmgYd3a822iYemKC23sEhi991VUQAOSK2vCUcIKSK+w1G7g9BQKOhvj # jz3Kr2qNe9zYRDCCBs0wggW1oAMCAQICEAb9+QOWA63qAArrPye7uhswDQYJKoZI # hvcNAQEFBQAwZTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZ # MBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTEkMCIGA1UEAxMbRGlnaUNlcnQgQXNz # dXJlZCBJRCBSb290IENBMB4XDTA2MTExMDAwMDAwMFoXDTIxMTExMDAwMDAwMFow # YjELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQ # d3d3LmRpZ2ljZXJ0LmNvbTEhMB8GA1UEAxMYRGlnaUNlcnQgQXNzdXJlZCBJRCBD # QS0xMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA6IItmfnKwkKVpYBz # QHDSnlZUXKnE0kEGj8kz/E1FkVyBn+0snPgWWd+etSQVwpi5tHdJ3InECtqvy15r # 7a2wcTHrzzpADEZNk+yLejYIA6sMNP4YSYL+x8cxSIB8HqIPkg5QycaH6zY/2DDD # /6b3+6LNb3Mj/qxWBZDwMiEWicZwiPkFl32jx0PdAug7Pe2xQaPtP77blUjE7h6z # 8rwMK5nQxl0SQoHhg26Ccz8mSxSQrllmCsSNvtLOBq6thG9IhJtPQLnxTPKvmPv2 # zkBdXPao8S+v7Iki8msYZbHBc63X8djPHgp0XEK4aH631XcKJ1Z8D2KkPzIUYJX9 # BwSiCQIDAQABo4IDejCCA3YwDgYDVR0PAQH/BAQDAgGGMDsGA1UdJQQ0MDIGCCsG # AQUFBwMBBggrBgEFBQcDAgYIKwYBBQUHAwMGCCsGAQUFBwMEBggrBgEFBQcDCDCC # AdIGA1UdIASCAckwggHFMIIBtAYKYIZIAYb9bAABBDCCAaQwOgYIKwYBBQUHAgEW # Lmh0dHA6Ly93d3cuZGlnaWNlcnQuY29tL3NzbC1jcHMtcmVwb3NpdG9yeS5odG0w # ggFkBggrBgEFBQcCAjCCAVYeggFSAEEAbgB5ACAAdQBzAGUAIABvAGYAIAB0AGgA # aQBzACAAQwBlAHIAdABpAGYAaQBjAGEAdABlACAAYwBvAG4AcwB0AGkAdAB1AHQA # ZQBzACAAYQBjAGMAZQBwAHQAYQBuAGMAZQAgAG8AZgAgAHQAaABlACAARABpAGcA # aQBDAGUAcgB0ACAAQwBQAC8AQwBQAFMAIABhAG4AZAAgAHQAaABlACAAUgBlAGwA # eQBpAG4AZwAgAFAAYQByAHQAeQAgAEEAZwByAGUAZQBtAGUAbgB0ACAAdwBoAGkA # YwBoACAAbABpAG0AaQB0ACAAbABpAGEAYgBpAGwAaQB0AHkAIABhAG4AZAAgAGEA # cgBlACAAaQBuAGMAbwByAHAAbwByAGEAdABlAGQAIABoAGUAcgBlAGkAbgAgAGIA # eQAgAHIAZQBmAGUAcgBlAG4AYwBlAC4wCwYJYIZIAYb9bAMVMBIGA1UdEwEB/wQI # MAYBAf8CAQAweQYIKwYBBQUHAQEEbTBrMCQGCCsGAQUFBzABhhhodHRwOi8vb2Nz # cC5kaWdpY2VydC5jb20wQwYIKwYBBQUHMAKGN2h0dHA6Ly9jYWNlcnRzLmRpZ2lj # ZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJRFJvb3RDQS5jcnQwgYEGA1UdHwR6MHgw # OqA4oDaGNGh0dHA6Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJ # RFJvb3RDQS5jcmwwOqA4oDaGNGh0dHA6Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9EaWdp # Q2VydEFzc3VyZWRJRFJvb3RDQS5jcmwwHQYDVR0OBBYEFBUAEisTmLKZB+0e36K+ # Vw0rZwLNMB8GA1UdIwQYMBaAFEXroq/0ksuCMS1Ri6enIZ3zbcgPMA0GCSqGSIb3 # DQEBBQUAA4IBAQBGUD7Jtygkpzgdtlspr1LPUukxR6tWXHvVDQtBs+/sdR90OPKy # XGGinJXDUOSCuSPRujqGcq04eKx1XRcXNHJHhZRW0eu7NoR3zCSl8wQZVann4+er # Ys37iy2QwsDStZS9Xk+xBdIOPRqpFFumhjFiqKgz5Js5p8T1zh14dpQlc+Qqq8+c # dkvtX8JLFuRLcEwAiR78xXm8TBJX/l/hHrwCXaj++wc4Tw3GXZG5D2dFzdaD7eeS # DY2xaYxP+1ngIw/Sqq4AfO6cQg7PkdcntxbuD8O9fAqg7iwIVYUiuOsYGk38KiGt # STGDR5V3cdyxG0tLHBCcdxTBnU8vWpUIKRAmMYIEOzCCBDcCAQEwgYYwcjELMAkG # A1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3LmRp # Z2ljZXJ0LmNvbTExMC8GA1UEAxMoRGlnaUNlcnQgU0hBMiBBc3N1cmVkIElEIENv # ZGUgU2lnbmluZyBDQQIQCIQ1OU/QbU6rESO7M78utDAJBgUrDgMCGgUAoHgwGAYK # KwYBBAGCNwIBDDEKMAigAoAAoQKAADAZBgkqhkiG9w0BCQMxDAYKKwYBBAGCNwIB # BDAcBgorBgEEAYI3AgELMQ4wDAYKKwYBBAGCNwIBFTAjBgkqhkiG9w0BCQQxFgQU # WpqeuBHEUvsQtlIBG3SnbcyH5KwwDQYJKoZIhvcNAQEBBQAEggEAPMAbPPXkbe3m # tO1SXUgGvBW2y98052YtTYLDM+vzNTjcwJKn9cK8yMg+lbIv8RnR+c3Yj3WYcuNi # 9TdkizfCB9w1MzusMY0UwOILS9G2ZBNxDiCIRI4SFBBwMFOQoPfZRQIKHtH3vlEz # BHBR4LX/YDLc1fkHE8IecCM5TfbzfeuaIxrJfzdvV+d3MhAHjGD9HWtBzOq/szWt # M4lUo/qsowbuKiJ5rVxuUEEAiu0qTJOcEcb5zcP3lDhV1KmbeJPBFqIrCCkxALBR # BvKgE+Pew4OpnqFrxBM9BxdC6UDOE1fsO+rbwDYh0Ku4S7aGGpX22o3aN/mcyuK3 # +oeZS2uQeaGCAg8wggILBgkqhkiG9w0BCQYxggH8MIIB+AIBATB2MGIxCzAJBgNV # BAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdp # Y2VydC5jb20xITAfBgNVBAMTGERpZ2lDZXJ0IEFzc3VyZWQgSUQgQ0EtMQIQAwGa # Ajr/WLFr1tXq5hfwZjAJBgUrDgMCGgUAoF0wGAYJKoZIhvcNAQkDMQsGCSqGSIb3 # DQEHATAcBgkqhkiG9w0BCQUxDxcNMjAwNDA0MTc1MTQzWjAjBgkqhkiG9w0BCQQx # FgQU7I5SWZJiWaNaS52ot+2NA24ZCXMwDQYJKoZIhvcNAQEBBQAEggEAF+dkGWz7 # Y9R00/wVzzjDuIEcKsAGqeZh6+5hMHKBQXyjINOfqiEjoCZgNQtp7nvNEwUlVyCF # WeF5Ce2935QSWTRm53TtgkYI898H2f6h6ffg2UKOLk1j058h01yY/s6r9H+BFzzl # 6BTn7LcRrO/8GcVrUC4E1HBOY7+uW1UeePMt5RlkQ1fYoGrSU6iurUJkqO9kNXUA # kev9j6EGeEjCh/CPwWSS3RiXLDIGmupRHyLXBEAkyPuufldkqKF19LR9xdlBMACv # TBMPG79MFMEV+9Y3wlcW2k3wGgezGzYcxMnCRZ/sdG2ImPk2QXmhJjWYWEf8rAuS # OxBiY386T2tAHw== # SIG # End signature block |