new-runtimepoc/Pester.RSpec.Configuration.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         = $true
        WriteDebugMessages     = $false
        WriteDebugMessagesFrom = "Mock"
    }
}

function Verify-PathEqual {
    [CmdletBinding()]
    param (
        [Parameter(ValueFromPipeline = $true)]
        $Actual,
        [Parameter(Mandatory = $true, Position = 0)]
        $Expected
    )

    if ([string]::IsNullOrEmpty($Expected)) {
        throw "Expected is null or empty."
    }

    if ([string]::IsNullOrEmpty($Actual)) {
        throw "Actual is null or empty."
    }

    $e = ($expected -replace "\\",'/').Trim('/')
    $a = ($actual -replace "\\",'/').Trim('/')

    if ($e -ne $a) {
        throw "Expected path '$e' to be equal to '$a'."
    }
}

i -PassThru:$PassThru {
    b "Default configuration" {

        # General configuration
        t "Exit is `$false" {
            [PesterConfiguration]::Default.Run.Exit.Value | Verify-False
        }

        t "Path is string array, with '.'" {
            $value = [PesterConfiguration]::Default.Run.Path.Value

            # do not do $value | Verify-NotNull
            # because nothing will reach the assetion
            Verify-NotNull -Actual $value
            Verify-Type ([string[]]) -Actual $value
            $value.Count | Verify-Equal 1
            $value[0] | Verify-Equal '.'
        }

        t "ScriptBlock is empty ScriptBlock array" {
            $value = [PesterConfiguration]::Default.Run.ScriptBlock.Value

            # do not do $value | Verify-NotNull
            # because nothing will reach the assetion
            Verify-NotNull -Actual $value
            Verify-Type ([ScriptBlock[]]) -Actual $value
            $value.Count | Verify-Equal 0
        }

        t "TestExtension is *.Tests.ps1" {
            [PesterConfiguration]::Default.Run.TestExtension.Value | Verify-Equal ".Tests.ps1"
        }


        # CodeCoverage configuration
        t "CodeCoverage.Enabled is `$false" {
            [PesterConfiguration]::Default.CodeCoverage.Enabled.Value | Verify-False
        }

        t "CodeCoverage.OutputFormat is JaCoCo" {
            [PesterConfiguration]::Default.CodeCoverage.OutputFormat.Value | Verify-Equal JaCoCo
        }

        t "CodeCoverage.OutputPath is coverage.xml" {
            [PesterConfiguration]::Default.CodeCoverage.OutputPath.Value | Verify-Equal "coverage.xml"
        }

        t "CodeCoverage.OutputEncoding is UTF8" {
            [PesterConfiguration]::Default.CodeCoverage.OutputEncoding.Value | Verify-Equal "UTF8"
        }

        t "CodeCoverage.Path is empty array" {
            $value = [PesterConfiguration]::Default.CodeCoverage.Path.Value
            Verify-NotNull $value
            $value.Count | Verify-Equal 0
        }

        t "CodeCoverage.ExcludeTests is `$true" {
            [PesterConfiguration]::Default.CodeCoverage.ExcludeTests.Value | Verify-True
        }

        # TestResult configuration
        t "TestResult.Enabled is `$false" {
            [PesterConfiguration]::Default.TestResult.Enabled.Value | Verify-False
        }

        t "TestResult.OutputFormat is NUnit2.5" {
            [PesterConfiguration]::Default.TestResult.OutputFormat.Value | Verify-Equal "NUnit2.5"
        }

        t "TestResult.OutputPath is testResults.xml" {
            [PesterConfiguration]::Default.TestResult.OutputPath.Value | Verify-Equal "testResults.xml"
        }

        t "TestResult.OutputEncoding is UTF8" {
            [PesterConfiguration]::Default.TestResult.OutputEncoding.Value | Verify-Equal "UTF8"
        }

        t "TestResult.TestSuiteName is Pester" {
            [PesterConfiguration]::Default.TestResult.TestSuiteName.Value | Verify-Equal "Pester"
        }

        # Should configuration
        t "Should.ErrorAction is Stop" {
            [PesterConfiguration]::Default.Should.ErrorAction.Value | Verify-Equal 'Stop'
        }

        # Debug configuration
        t "Debug.ShowFullErrors is `$false" {
            [PesterConfiguration]::Default.Debug.ShowFullErrors.Value | Verify-False
        }

        t "Debug.WriteDebugMessages is `$false" {
            [PesterConfiguration]::Default.Debug.WriteDebugMessages.Value | Verify-False
        }

        t "Debug.WriteDebugMessagesFrom is '*'" {
            [PesterConfiguration]::Default.Debug.WriteDebugMessagesFrom.Value | Verify-Equal '*'
        }

        t "Debug.ShowNavigationMarkers is `$false" {
            [PesterConfiguration]::Default.Debug.ShowNavigationMarkers.Value | Verify-False
        }

        t "Debug.WriteVSCodeMarker is `$false" {
            [PesterConfiguration]::Default.Debug.WriteVSCodeMarker.Value | Verify-False
        }
    }

    b "Assignment" {
        t "ScriptBlockArrayOption can be assigned a single ScriptBlock" {
            $config = [PesterConfiguration]::Default
            $sb = { "sb" }
            $config.Run.ScriptBlock = $sb

            $config.Run.ScriptBlock.Value | Verify-Equal $sb
        }

        t "ScriptBlockArrayOption can be assigned an array of ScriptBlocks" {
            $config = [PesterConfiguration]::Default
            $sb = { "sb" }, { "sb" }
            $config.Run.ScriptBlock = $sb

            Verify-Same $sb[0] -Actual $config.Run.ScriptBlock.Value[0]
            Verify-Same $sb[1] -Actual $config.Run.ScriptBlock.Value[1]
        }

        t "StringArrayOption can be assigned a single String" {
            $config = [PesterConfiguration]::Default
            $path = "C:\"
            $config.Run.Path = $path

            $config.Run.Path.Value | Verify-Equal $path
        }

        t "StringArrayOption can be assigned an array of Strings" {
            $config = [PesterConfiguration]::Default
            $path = "C:\",  "D:\"
            $config.Run.Path = $path

            Verify-Same $path[0] -Actual $config.Run.Path.Value[0]
            Verify-Same $path[1] -Actual $config.Run.Path.Value[1]
        }
    }

    b "Cloning" {
        t "Configuration can be shallow cloned to avoid modifying user values" {
            $user = [PesterConfiguration]::Default
            $user.Output.Verbosity = "Minimal"

            $cloned = [PesterConfiguration]::ShallowClone($user)
            $cloned.Output.Verbosity = "None"

            $user.Output.Verbosity.Value | Verify-Equal "Minimal"
            $cloned.Output.Verbosity.Value | Verify-Equal "None"
        }
    }

    b "Merging" {
        t "configurations can be merged" {
            $user = [PesterConfiguration]::Default
            $user.Output.Verbosity = "Minimal"
            $user.Filter.Tag = "abc"

            $override = [PesterConfiguration]::Default
            $override.Output.Verbosity = "None"
            $override.Run.Path = "C:\test.ps1"

            $result = [PesterConfiguration]::Merge($user, $override)

            $result.Output.Verbosity.Value | Verify-Equal "None"
            $result.Run.Path.Value | Verify-Equal "C:\test.ps1"
            $result.Filter.Tag.Value | Verify-Equal "abc"
        }

        t "merged object is a new instance" {
            $user = [PesterConfiguration]::Default
            $user.Output.Verbosity = "Minimal"

            $override = [PesterConfiguration]::Default
            $override.Output.Verbosity = "None"

            $result = [PesterConfiguration]::Merge($user, $override)

            [object]::ReferenceEquals($override, $result) | Verify-False
            [object]::ReferenceEquals($user, $result) | Verify-False
        }

        t "values are overwritten even if they are set to the same value as default" {
            $user = [PesterConfiguration]::Default
            $user.Output.Verbosity = "Minimal"
            $user.Filter.Tag = "abc"

            $override = [PesterConfiguration]::Default
            $override.Output.Verbosity = [PesterConfiguration]::Default.Output.Verbosity

            $result = [PesterConfiguration]::Merge($user, $override)

            # has the same value as default but was written so it will override
            $result.Output.Verbosity.Value | Verify-Equal "Normal"
            # has value different from default but was not written in override so the
            # override does not touch it
            $result.Filter.Tag.Value | Verify-Equal "abc"
        }
    }

    b "Advanced interface - Run paths"  {
        t "Running from multiple paths" {
            $container1 = "$PSScriptRoot/TestProjects/BasicTests/folder1"
            $container2 = "$PSScriptRoot/TestProjects/BasicTests/folder2"

            $c = [PesterConfiguration]@{
                Run = @{
                    Path = $container1, $container2
                }
                Output = @{
                    Verbosity = 'None'
                }
            }

            $r = Invoke-Pester -Configuration $c
            ($r.Containers[0].Path.Directory) | Verify-PathEqual $container1
            ($r.Containers[1].Path.Directory) | Verify-PathEqual $container2
        }

        t "Filtering based on tags" {
            $c = [PesterConfiguration]@{
                Run = @{
                    Path = "$PSScriptRoot/TestProjects/BasicTests"
                }
                Filter = @{
                    ExcludeTag = 'Slow'
                }
                Output = @{
                    Verbosity = 'None'
                }
            }

            $r = Invoke-Pester -Configuration $c
            $tests = $r.Containers.Blocks.Tests

            $allTags = $tests.Tag | where { $null -ne $_ }
            $allTags | Verify-NotNull
            'slow' -in $allTags | Verify-True

            $runTags = ($tests | where { $_.ShouldRun }).Tag
            'slow' -notin $runTags | Verify-True
        }

        t "Filtering test based on line" {
            $c = [PesterConfiguration]@{
                Run = @{
                    Path = "$PSScriptRoot/TestProjects/BasicTests"
                }
                Filter = @{
                    Line = "$PSScriptRoot/TestProjects/BasicTests/folder1/file1.Tests.ps1:6"
                }
                Output = @{
                    Verbosity = 'None'
                }
            }

            $r = Invoke-Pester -Configuration $c
            $tests = @($r.Containers.Blocks.Tests | where { $_.ShouldRun })

            $tests.Count | Verify-Equal 1
            $tests[0].Name | Verify-Equal "fails"
        }

        t "Filtering test based on line" {
            $c = [PesterConfiguration]@{
                Run = @{
                    Path = "$PSScriptRoot/TestProjects/BasicTests"
                }
                Filter = @{
                    Line = "$PSScriptRoot/TestProjects/BasicTests/folder1/file1.Tests.ps1:1"
                }
                Output = @{
                    Verbosity = 'None'
                }
            }

            $r = Invoke-Pester -Configuration $c
            $tests = @($r.Containers.Blocks.Tests | where { $_.ShouldRun })

            $tests.Count | Verify-Equal 2
            $tests[0].Name | Verify-Equal "passing"
            $tests[1].Name | Verify-Equal "fails"
        }
    }

    b "merging configuraiton in Invoke-Pester" {
        t "merges pester preference with provided configuration" {
            $PesterPreference = [PesterConfiguration] @{
                Output = @{
                    Verbosity = 'None'
                }
            }

            $sb = {
                Describe "a" {
                    It "b" {}
                }
            }

            $c = [PesterConfiguration] @{
                Run = @{
                    ScriptBlock = $sb
                }
            }

            $r = Invoke-Pester -Configuration $c
            $r.Configuration.Output.Verbosity.Value  | Verify-Equal 'None'
            $r.Configuration.Run.ScriptBlock.Value | Verify-Equal $sb
        }
    }
}

# SIG # Begin signature block
# MIIcVgYJKoZIhvcNAQcCoIIcRzCCHEMCAQExCzAJBgUrDgMCGgUAMGkGCisGAQQB
# gjcCAQSgWzBZMDQGCisGAQQBgjcCAR4wJgIDAQAABBAfzDtgWUsITrck0sYpfvNR
# AgEAAgEAAgEAAgEAAgEAMCEwCQYFKw4DAhoFAAQUR4F/bH1nKcdlSHlxMXsiEvws
# JEWggheFMIIFDjCCA/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
# zDBWia04AOFxmzIxqI1lPdtzURAwDQYJKoZIhvcNAQEBBQAEggEAcpfRB4wSFQxY
# LMgLs1JIUo40haR3zxycaJ3iRQdoVYlqMt7wMyXl/uGn0K7Skb/nmrMlpXO5wnSa
# 95Kc/IaI/x3OfJ/AyPseglMHDf4x1OYM10W0k6hhXkTNj5KFKrbqFncuTr2XtkPf
# hGy5MU1kmsG1yRPBqN0kFj+B7D4kgAySrb7lIVaf8YZyoUmsmTZtBGg7Qn72NW9I
# NvahvItGEhK4HDGrSvcdprUi7WAXOP/d7KapkQY/ZwFYlpAPBgqnQWOvqs/6/R6Y
# gp3SxopOBTvc/hBp/Q0C+vMpIdQBOU5nULo0Q6OIrCesLmkSdosNBjBpMLRZq7w8
# C9gyf0sptaGCAg8wggILBgkqhkiG9w0BCQYxggH8MIIB+AIBATB2MGIxCzAJBgNV
# BAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdp
# Y2VydC5jb20xITAfBgNVBAMTGERpZ2lDZXJ0IEFzc3VyZWQgSUQgQ0EtMQIQAwGa
# Ajr/WLFr1tXq5hfwZjAJBgUrDgMCGgUAoF0wGAYJKoZIhvcNAQkDMQsGCSqGSIb3
# DQEHATAcBgkqhkiG9w0BCQUxDxcNMjAwMjA4MjMyOTA1WjAjBgkqhkiG9w0BCQQx
# FgQU/AMqnkdu4AxTLkeBHM5JqW4cT58wDQYJKoZIhvcNAQEBBQAEggEAPorsizBm
# ndiIqNygw19xmQX/yOW3/+yV7BhMvhnEDrfHS8vcMzo09kul7RhL57QmDnw8qhsC
# +rrpra2sNNxRdwNjvnhhac6o6MRsGgQFclmAy/pkrxLjeuh0r01mz9LArvcnBenU
# GnFRdZBexPR3PNX8RtdtKT36NTV0NEdvx+5VtBuSHOZ6oktlxf+akPx+y8oSFpjN
# +cV2JtizqK4g+nociE7trSkelPXtM3DJ4CA69hZsYF+ZqGn+ovmLPxn+iV9haowg
# wgHCE+Yjor95qd0ZG9TYoCfdPZ157mAkxWxmmTDnSDWQ8tewuabAGu/oAUN6FPVD
# bUymOuNstsj1QQ==
# SIG # End signature block