DeprecatedApiTranslator/InputTransformation.Tests.ps1

Describe 'Test Transformation' {
    BeforeAll {
        . (Join-Path $PSScriptRoot 'vSphereRestApiTranslation.ps1')
    }

    Context 'Path Transformations' {
        It 'Moves "file_name" path parameter from path to body' {
            # Arrange
            $operationTranslationSchema = Get-OperationTranslationSchema -operationPath '/api/content/library/item/update-session/{update_session_id}/file/{file_name}' -operationVerb 'get'

            $expectedFileName = "test.file"
            $pathParams = @{
                "update_session_id" = "test-session-id"
                "file_name"         = $expectedFileName
            }

            # Act
            $actual = Format-PathParams -OperationTranslateSchema $operationTranslationSchema -PathParams $pathParams

            # Assert
            $actual | Should -Not -Be $null
            $actual.Path | Should -Be $null
            $actual.Query | Should -Be $null
            $actual.Header | Should -Be $null
            $actual.Body | Should -Not -Be $null
            $actual.Body.Count | Should -Be 1
            $actual.Body.file_name | Should -Be $expectedFileName
        }

        It 'Moves "download_session_id" path parameter from path to query' {
            # Arrange
            $operationTranslationSchema = Get-OperationTranslationSchema -operationPath '/api/content/library/item/download-session/{download_session_id}/file' -operationVerb 'get'

            $expectedSessionId = "test-session-id"
            $pathParams = @{
                "download_session_id" = $expectedSessionId
            }

            # Act
            $actual = Format-PathParams -OperationTranslateSchema $operationTranslationSchema -PathParams $pathParams

            # Assert
            $actual | Should -Not -Be $null
            $actual.Path | Should -Be $null
            $actual.Header | Should -Be $null
            $actual.Body | Should -Be $null
            $actual.Query | Should -Not -Be $null
            $actual.Query.Count | Should -Be 1
            $actual.Query.download_session_id | Should -Be $expectedSessionId
        }

        It 'Should not transform path params when they are the same in old and new API' {
            # Arrange
            $operationTranslationSchema = Get-OperationTranslationSchema -operationPath '/api/content/library/item/update-session/{update_session_id}' -operationVerb 'get'

            $pathParams = @{
                "update_session_id" = "test-session-id"
            }

            # Act
            $actual = Format-PathParams -OperationTranslateSchema $operationTranslationSchema -PathParams $pathParams

            # Assert
            $actual | Should -Not -Be $null
            $actual.Path | Should -Be $null
            $actual.Header | Should -Be $null
            $actual.Query | Should -Be $null
            $actual.Body | Should -Be $null
        }

        It 'Should do nothing when no Path params' {
            # Arrange
            $operationTranslationSchema = Get-OperationTranslationSchema -operationPath '/api/content/library/item?library_id' -operationVerb 'get'

            $pathParams = @{}

            # Act
            $actual = Format-PathParams -OperationTranslateSchema $operationTranslationSchema -PathParams $pathParams

            # Assert
            $actual | Should -Not -Be $null
            $actual.Path | Should -Be $null
            $actual.Header | Should -Be $null
            $actual.Query | Should -Be $null
            $actual.Body | Should -Be $null

        }
    }

    Context 'Header Transformations' {
        It 'Moves "client_token" from Header to Body' {
            # Arrange
            $operationTranslationSchema = Get-OperationTranslationSchema -operationPath '/api/content/library/item' -operationVerb 'post'

            $expectedClientToken = "test-client-token"
            $headers = @{
                "client_token" = $expectedClientToken
            }

            # Act
            $actual = Format-Headers -OperationTranslateSchema $operationTranslationSchema -Headers ($headers)

            # Assert
            $actual | Should -Not -Be $null
            $actual.Path | Should -Be $null
            $actual.Header | Should -Be $null
            $actual.Query | Should -Be $null
            $actual.Body | Should -Not -Be $null
            $actual.Body.client_token | Should -Be $expectedClientToken

            ## Assert 'client_token' is removed from Headers
            $headers | Should -Not -Be $null
            $headers.Count | Should -Be 0
        }

        It 'Should do nothing when no Headers' {
            # Arrange
            $operationTranslationSchema = Get-OperationTranslationSchema -operationPath '/api/content/library/item?library_id' -operationVerb 'get'

            $headers = @{}

            # Act
            $actual = Format-Headers -OperationTranslateSchema $operationTranslationSchema -Headers ($headers)

            # Assert
            $actual | Should -Not -Be $null
            $actual.Path | Should -Be $null
            $actual.Header | Should -Be $null
            $actual.Query | Should -Be $null
            $actual.Body | Should -Be $null

            # Assert input headers are not changed
            $headers | Should -Not -Be $null
            $headers.Count | Should -Be 0
        }
    }

    Context 'Body Transformations' {
        It 'Moves "schedule" field from Body to Path' {
            # Arrange
            $operationTranslationSchema = Get-OperationTranslationSchema -operationPath '/api/appliance/recovery/backup/schedules' -operationVerb 'post'

            $expectedSchedule = "test-shedule"
            $expectedBackupPassword = "test-password"
            $expectedEnable = $true
            $body = [PSCustomObject]@{
                schedule = $expectedSchedule
                spec = [PSCustomObject]@{
                    backup_password = $expectedBackupPassword
                    enable = $expectedEnable
                }
            }

            # Act
            $actual = Format-Body -OperationTranslateSchema $operationTranslationSchema -Body ([ref]$body)

            # Assert
            $actual | Should -Not -Be $null
            $actual.Header | Should -Be $null
            $actual.Query | Should -Be $null
            $actual.Body | Should -Be $null
            $actual.Path | Should -Not -Be $null
            $actual.Path.Count | Should -Be 1
            $actual.Path.schedule | Should -Be $expectedSchedule

            $bodyMembers = $body | Get-Member -MemberType NoteProperty
            $bodyMembers | Should -Not -Be $null
            $bodyMembers.Count | Should -Be 1
            $body.spec | Should -Not -Be $null
            $body.spec.backup_password | Should -Be $expectedBackupPassword
            $body.spec.enable | Should -Be $expectedEnable
        }

        It 'Should not modify body if not needed' {
            # Arrange
            $operationTranslationSchema = Get-OperationTranslationSchema -operationPath '/api/appliance/recovery/backup/schedules/{schedule}' -operationVerb 'patch'

            $expectedBackupPassword = "test-password"
            $expectedEnable = $true
            $expectedMaxCount = 7
            $body = [PSCustomObject]@{
                spec = [PSCustomObject]@{
                    backup_password = $expectedBackupPassword
                    enable = $expectedEnable
                }
                retention_info = [PSCustomObject]@{
                    max_count = $expectedMaxCount
                }
            }

            # Act
            $actual = Format-Body -OperationTranslateSchema $operationTranslationSchema -Body ([ref]$body)

            # Assert
            $actual | Should -Not -Be $null
            $actual.Header | Should -Be $null
            $actual.Query | Should -Be $null
            $actual.Body | Should -Be $null
            $actual.Path | Should -Be $null

            $body | Should -Not -Be $null
            $body.spec.backup_password | Should -Be $expectedBackupPassword
            $body.spec.enable | Should -Be $expectedEnable
            $body.retention_info.max_count | Should -Be $expectedMaxCount
        }

        It 'Should do nothing if operation has no body' {
            # Arrange
            $operationTranslationSchema = Get-OperationTranslationSchema -operationPath '/api/appliance/recovery/backup/schedules' -operationVerb 'get'

            $body = [PSCustomObject]@{}

            # Act
            $actual = Format-Body -OperationTranslateSchema $operationTranslationSchema -Body ([ref]$body)

            # Assert
            $actual | Should -Not -Be $null
            $actual.Header | Should -Be $null
            $actual.Query | Should -Be $null
            $actual.Body | Should -Be $null
            $actual.Path | Should -Be $null

            $body | Should -Not -Be $null
            $props = $body | Get-Member -MemberType NoteProperty
            $props.Count | Should -Be 0
        }
    }
}

Describe 'Test Join-InputTransformationStructure' {
    BeforeAll {
        . (Join-Path $PSScriptRoot 'vSphereRestApiTranslation.ps1')
    }

    It "Should add Properties on an emtpy input structure" {
        # Arrange
        $Base = New-InputTransformationStructure
        $expectedAddition = New-InputTransformationStructure
        $expectedAddition.Path = @{
            'p1' = 'pv1'
            'p2' = 'pv2'
        }

        $expectedAddition.Query = @{
            'q1' = 'qv1'
            'q2' = 'qv2'
        }

        $expectedAddition.Header = @{
            'h1' = 'hv1'
            'h2' = 'hv2'
        }

        $expectedAddition.Body = [PSCustomObject]@{
            'b1' = 'bv1'
            'b2' = 'bv2'
        }

        # Act
        Join-InputTransformationStructure -Base ([ref]$Base) -Addition $expectedAddition

        # Assert
        $Base.Path.p1 | Should -Be $expectedAddition.Path.p1
        $Base.Path.p2 | Should -Be $expectedAddition.Path.p2

        $Base.Query.q1 | Should -Be $expectedAddition.Query.q1
        $Base.Query.q2 | Should -Be $expectedAddition.Query.q2

        $Base.Header.h1 | Should -Be $expectedAddition.Header.h1
        $Base.Header.h2 | Should -Be $expectedAddition.Header.h2

        $Base.Body.b1 | Should -Be $expectedAddition.Body.b1
        $Base.Body.b2 | Should -Be $expectedAddition.Body.b2
    }

    It "Should extend existing properties" {
        # Arrange
        $Base = New-InputTransformationStructure
        $Base.Path = @{
            'p1' = 'pv1'
        }

        $Base.Query = @{
            'q1' = 'qv1'
        }

        $Base.Header = @{
            'h1' = 'hv1'
        }

        $Base.Body = [PSCustomObject]@{
            'b1' = 'bv1'
        }

        $expectedAddition = New-InputTransformationStructure
        $expectedAddition.Path = @{
            'p2' = 'pv2'
        }

        $expectedAddition.Query = @{
            'q2' = 'qv2'
        }

        $expectedAddition.Header = @{
            'h2' = 'hv2'
        }

        $expectedAddition.Body = [PSCustomObject]@{
            'b2' = 'bv2'
        }

        # Act
        Join-InputTransformationStructure -Base ([ref]$Base) -Addition $expectedAddition

        # Assert
        $Base.Path.p1 | Should -Be 'pv1'
        $Base.Path.p2 | Should -Be $expectedAddition.Path.p2

        $Base.Query.q1 | Should -Be 'qv1'
        $Base.Query.q2 | Should -Be $expectedAddition.Query.q2

        $Base.Header.h1 | Should -Be 'hv1'
        $Base.Header.h2 | Should -Be $expectedAddition.Header.h2

        $Base.Body.b1 | Should -Be 'bv1'
        $Base.Body.b2 | Should -Be $expectedAddition.Body.b2

    }
}
# SIG # Begin signature block
# MIIexgYJKoZIhvcNAQcCoIIetzCCHrMCAQExDzANBglghkgBZQMEAgEFADB5Bgor
# BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG
# KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCCjknlDUi2i0CgV
# mU0dNL51fT9kv1q5umENOKq0bu/NU6CCDdowggawMIIEmKADAgECAhAIrUCyYNKc
# TJ9ezam9k67ZMA0GCSqGSIb3DQEBDAUAMGIxCzAJBgNVBAYTAlVTMRUwEwYDVQQK
# EwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xITAfBgNV
# BAMTGERpZ2lDZXJ0IFRydXN0ZWQgUm9vdCBHNDAeFw0yMTA0MjkwMDAwMDBaFw0z
# NjA0MjgyMzU5NTlaMGkxCzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5EaWdpQ2VydCwg
# SW5jLjFBMD8GA1UEAxM4RGlnaUNlcnQgVHJ1c3RlZCBHNCBDb2RlIFNpZ25pbmcg
# UlNBNDA5NiBTSEEzODQgMjAyMSBDQTEwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAw
# ggIKAoICAQDVtC9C0CiteLdd1TlZG7GIQvUzjOs9gZdwxbvEhSYwn6SOaNhc9es0
# JAfhS0/TeEP0F9ce2vnS1WcaUk8OoVf8iJnBkcyBAz5NcCRks43iCH00fUyAVxJr
# Q5qZ8sU7H/Lvy0daE6ZMswEgJfMQ04uy+wjwiuCdCcBlp/qYgEk1hz1RGeiQIXhF
# LqGfLOEYwhrMxe6TSXBCMo/7xuoc82VokaJNTIIRSFJo3hC9FFdd6BgTZcV/sk+F
# LEikVoQ11vkunKoAFdE3/hoGlMJ8yOobMubKwvSnowMOdKWvObarYBLj6Na59zHh
# 3K3kGKDYwSNHR7OhD26jq22YBoMbt2pnLdK9RBqSEIGPsDsJ18ebMlrC/2pgVItJ
# wZPt4bRc4G/rJvmM1bL5OBDm6s6R9b7T+2+TYTRcvJNFKIM2KmYoX7BzzosmJQay
# g9Rc9hUZTO1i4F4z8ujo7AqnsAMrkbI2eb73rQgedaZlzLvjSFDzd5Ea/ttQokbI
# YViY9XwCFjyDKK05huzUtw1T0PhH5nUwjewwk3YUpltLXXRhTT8SkXbev1jLchAp
# QfDVxW0mdmgRQRNYmtwmKwH0iU1Z23jPgUo+QEdfyYFQc4UQIyFZYIpkVMHMIRro
# OBl8ZhzNeDhFMJlP/2NPTLuqDQhTQXxYPUez+rbsjDIJAsxsPAxWEQIDAQABo4IB
# WTCCAVUwEgYDVR0TAQH/BAgwBgEB/wIBADAdBgNVHQ4EFgQUaDfg67Y7+F8Rhvv+
# YXsIiGX0TkIwHwYDVR0jBBgwFoAU7NfjgtJxXWRM3y5nP+e6mK4cD08wDgYDVR0P
# AQH/BAQDAgGGMBMGA1UdJQQMMAoGCCsGAQUFBwMDMHcGCCsGAQUFBwEBBGswaTAk
# BggrBgEFBQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQuY29tMEEGCCsGAQUFBzAC
# hjVodHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vRGlnaUNlcnRUcnVzdGVkUm9v
# dEc0LmNydDBDBgNVHR8EPDA6MDigNqA0hjJodHRwOi8vY3JsMy5kaWdpY2VydC5j
# b20vRGlnaUNlcnRUcnVzdGVkUm9vdEc0LmNybDAcBgNVHSAEFTATMAcGBWeBDAED
# MAgGBmeBDAEEATANBgkqhkiG9w0BAQwFAAOCAgEAOiNEPY0Idu6PvDqZ01bgAhql
# +Eg08yy25nRm95RysQDKr2wwJxMSnpBEn0v9nqN8JtU3vDpdSG2V1T9J9Ce7FoFF
# UP2cvbaF4HZ+N3HLIvdaqpDP9ZNq4+sg0dVQeYiaiorBtr2hSBh+3NiAGhEZGM1h
# mYFW9snjdufE5BtfQ/g+lP92OT2e1JnPSt0o618moZVYSNUa/tcnP/2Q0XaG3Ryw
# YFzzDaju4ImhvTnhOE7abrs2nfvlIVNaw8rpavGiPttDuDPITzgUkpn13c5Ubdld
# AhQfQDN8A+KVssIhdXNSy0bYxDQcoqVLjc1vdjcshT8azibpGL6QB7BDf5WIIIJw
# 8MzK7/0pNVwfiThV9zeKiwmhywvpMRr/LhlcOXHhvpynCgbWJme3kuZOX956rEnP
# LqR0kq3bPKSchh/jwVYbKyP/j7XqiHtwa+aguv06P0WmxOgWkVKLQcBIhEuWTatE
# QOON8BUozu3xGFYHKi8QxAwIZDwzj64ojDzLj4gLDb879M4ee47vtevLt/B3E+bn
# KD+sEq6lLyJsQfmCXBVmzGwOysWGw/YmMwwHS6DTBwJqakAwSEs0qFEgu60bhQji
# WQ1tygVQK+pKHJ6l/aCnHwZ05/LWUpD9r4VIIflXO7ScA+2GRfS0YW6/aOImYIbq
# yK+p/pQd52MbOoZWeE4wggciMIIFCqADAgECAhAOxvKydqFGoH0ObZNXteEIMA0G
# CSqGSIb3DQEBCwUAMGkxCzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5EaWdpQ2VydCwg
# SW5jLjFBMD8GA1UEAxM4RGlnaUNlcnQgVHJ1c3RlZCBHNCBDb2RlIFNpZ25pbmcg
# UlNBNDA5NiBTSEEzODQgMjAyMSBDQTEwHhcNMjEwODEwMDAwMDAwWhcNMjMwODEw
# MjM1OTU5WjCBhzELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExEjAQ
# BgNVBAcTCVBhbG8gQWx0bzEVMBMGA1UEChMMVk13YXJlLCBJbmMuMRUwEwYDVQQD
# EwxWTXdhcmUsIEluYy4xITAfBgkqhkiG9w0BCQEWEm5vcmVwbHlAdm13YXJlLmNv
# bTCCAaIwDQYJKoZIhvcNAQEBBQADggGPADCCAYoCggGBAMD6lJG8OWkM12huIQpO
# /q9JnhhhW5UyW9if3/UnoFY3oqmp0JYX/ZrXogUHYXmbt2gk01zz2P5Z89mM4gqR
# bGYC2tx+Lez4GxVkyslVPI3PXYcYSaRp39JsF3yYifnp9R+ON8O3Gf5/4EaFmbeT
# ElDCFBfExPMqtSvPZDqekodzX+4SK1PIZxCyR3gml8R3/wzhb6Li0mG7l0evQUD0
# FQAbKJMlBk863apeX4ALFZtrnCpnMlOjRb85LsjV5Ku4OhxQi1jlf8wR+za9C3DU
# ki60/yiWPu+XXwEUqGInIihECBbp7hfFWrnCCaOgahsVpgz8kKg/XN4OFq7rbh4q
# 5IkTauqFhHaE7HKM5bbIBkZ+YJs2SYvu7aHjw4Z8aRjaIbXhI1G+NtaNY7kSRrE4
# fAyC2X2zV5i4a0AuAMM40C1Wm3gTaNtRTHnka/pbynUlFjP+KqAZhOniJg4AUfjX
# sG+PG1LH2+w/sfDl1A8liXSZU1qJtUs3wBQFoSGEaGBeDQIDAQABo4ICJTCCAiEw
# HwYDVR0jBBgwFoAUaDfg67Y7+F8Rhvv+YXsIiGX0TkIwHQYDVR0OBBYEFIhC+HL9
# QlvsWsztP/I5wYwdfCFNMB0GA1UdEQQWMBSBEm5vcmVwbHlAdm13YXJlLmNvbTAO
# BgNVHQ8BAf8EBAMCB4AwEwYDVR0lBAwwCgYIKwYBBQUHAwMwgbUGA1UdHwSBrTCB
# qjBToFGgT4ZNaHR0cDovL2NybDMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0VHJ1c3Rl
# ZEc0Q29kZVNpZ25pbmdSU0E0MDk2U0hBMzg0MjAyMUNBMS5jcmwwU6BRoE+GTWh0
# dHA6Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydFRydXN0ZWRHNENvZGVTaWdu
# aW5nUlNBNDA5NlNIQTM4NDIwMjFDQTEuY3JsMD4GA1UdIAQ3MDUwMwYGZ4EMAQQB
# MCkwJwYIKwYBBQUHAgEWG2h0dHA6Ly93d3cuZGlnaWNlcnQuY29tL0NQUzCBlAYI
# KwYBBQUHAQEEgYcwgYQwJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0
# LmNvbTBcBggrBgEFBQcwAoZQaHR0cDovL2NhY2VydHMuZGlnaWNlcnQuY29tL0Rp
# Z2lDZXJ0VHJ1c3RlZEc0Q29kZVNpZ25pbmdSU0E0MDk2U0hBMzg0MjAyMUNBMS5j
# cnQwDAYDVR0TAQH/BAIwADANBgkqhkiG9w0BAQsFAAOCAgEACQAYaQI6Nt2KgxdN
# 6qqfcHB33EZRSXkvs8O9iPZkdDjEx+2fgbBPLUvk9A7T8mRw7brbcJv4PLTYJDFo
# c5mlcmG7/5zwTOuIs2nBGXc/uxCnyW8p7kD4Y0JxPKEVQoIQ8lJS9Uy/hBjyakeV
# ef982JyzvDbOlLBy6AS3ZpXVkRY5y3Va+3v0R/0xJ+JRxUicQhiZRidq2TCiWEas
# d+tLL6jrKaBO+rmP52IM4eS9d4Yids7ogKEBAlJi0NbvuKO0CkgOlFjp1tOvD4sQ
# taHIMmqi40p4Tjyf/sY6yGjROXbMeeF1vlwbBAASPWpQuEIxrNHoVN30YfJyuOWj
# zdiJUTpeLn9XdjM3UlhfaHP+oIAKcmkd33c40SFRlQG9+P9Wlm7TcPxGU4wzXI8n
# Cw/h235jFlAAiWq9L2r7Un7YduqsheJVpGoXmRXJH0T2G2eNFS5/+2sLn98kN2Cn
# J7j6C242onjkZuGL2/+gqx8m5Jbpu9P4IAeTC1He/mX9j6XpIu+7uBoRVwuWD1i0
# N5SiUz7Lfnbr6Q1tHMXKDLFdwVKZos2AKEZhv4SU0WvenMJKDgkkhVeHPHbTahQf
# P1MetR8tdRs7uyTWAjPK5xf5DLEkXbMrUkpJ089fPvAGVHBcHRMqFA5egexOb6sj
# tKncUjJ1xAAtAExGdCh6VD2U5iYxghBCMIIQPgIBATB9MGkxCzAJBgNVBAYTAlVT
# MRcwFQYDVQQKEw5EaWdpQ2VydCwgSW5jLjFBMD8GA1UEAxM4RGlnaUNlcnQgVHJ1
# c3RlZCBHNCBDb2RlIFNpZ25pbmcgUlNBNDA5NiBTSEEzODQgMjAyMSBDQTECEA7G
# 8rJ2oUagfQ5tk1e14QgwDQYJYIZIAWUDBAIBBQCggZYwGQYJKoZIhvcNAQkDMQwG
# CisGAQQBgjcCAQQwHAYKKwYBBAGCNwIBCzEOMAwGCisGAQQBgjcCARUwKgYKKwYB
# BAGCNwIBDDEcMBqhGIAWaHR0cDovL3d3dy52bXdhcmUuY29tLzAvBgkqhkiG9w0B
# CQQxIgQgruvTlqu8Qrh3+CmCtXUtK+3gbt+33dD3zvOLM2ut+ywwDQYJKoZIhvcN
# AQEBBQAEggGABvzfjWrQP7QqSwyNhO+r88YL1IJXv8DdWsUwkNxze56bpci/9GHe
# 1uHBg38jXXGogI5yiPKwgdhqQY58TxBy50x/9gveXo/mvtHP5em5dNUletLsPA/U
# PYWXHkojdH1wc2U7fDyZqne8MNJ1e/KgkduCES3ELj2A6mfRUtg7yRKMoNSsYsxv
# sYuUapXHKZMSQcHqNoyarnAJoTcU+7aVTZvONJ2GFzDnHOZU/18IxwHOFIQn5MxF
# S4/UqbW+y7dJGy30e0ILnI7oCrQzNHuetoauK3PBGMxxtFohTzLgZItIvY0oMm0I
# gkaRZ4UVFt6fPJ0PaArgMFjBtk/giv2wNaTpUoDQV3mkPM+WVlehjYh+GDVwM3xo
# hJMUpKiNlyxgzkWR+LrkZDGnRyTKBUcqHPc4KTS6r0yl46wYOBObJd30PvwAWBth
# cSftCj+n7DP0rjaEzMXpqAzYNHCgFOzmK8DgyACxVm/HzTHoDJgch5bVR1eijgI6
# Ftlx+Oj9E7+goYINfTCCDXkGCisGAQQBgjcDAwExgg1pMIINZQYJKoZIhvcNAQcC
# oIINVjCCDVICAQMxDzANBglghkgBZQMEAgEFADB3BgsqhkiG9w0BCRABBKBoBGYw
# ZAIBAQYJYIZIAYb9bAcBMDEwDQYJYIZIAWUDBAIBBQAEIGpxQ7E3mRbhauuqt2Ty
# Dw2CJOF2QikoT1fJSXJ/Ab0HAhBy9FLPfFBSQz94ofGg3f6QGA8yMDIxMDkyNDE2
# MTExNVqgggo3MIIE/jCCA+agAwIBAgIQDUJK4L46iP9gQCHOFADw3TANBgkqhkiG
# 9w0BAQsFADByMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkw
# FwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMTEwLwYDVQQDEyhEaWdpQ2VydCBTSEEy
# IEFzc3VyZWQgSUQgVGltZXN0YW1waW5nIENBMB4XDTIxMDEwMTAwMDAwMFoXDTMx
# MDEwNjAwMDAwMFowSDELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDkRpZ2lDZXJ0LCBJ
# bmMuMSAwHgYDVQQDExdEaWdpQ2VydCBUaW1lc3RhbXAgMjAyMTCCASIwDQYJKoZI
# hvcNAQEBBQADggEPADCCAQoCggEBAMLmYYRnxYr1DQikRcpja1HXOhFCvQp1dU2U
# tAxQtSYQ/h3Ib5FrDJbnGlxI70Tlv5thzRWRYlq4/2cLnGP9NmqB+in43Stwhd4C
# GPN4bbx9+cdtCT2+anaH6Yq9+IRdHnbJ5MZ2djpT0dHTWjaPxqPhLxs6t2HWc+xO
# bTOKfF1FLUuxUOZBOjdWhtyTI433UCXoZObd048vV7WHIOsOjizVI9r0TXhG4wOD
# MSlKXAwxikqMiMX3MFr5FK8VX2xDSQn9JiNT9o1j6BqrW7EdMMKbaYK02/xWVLwf
# oYervnpbCiAvSwnJlaeNsvrWY4tOpXIc7p96AXP4Gdb+DUmEvQECAwEAAaOCAbgw
# ggG0MA4GA1UdDwEB/wQEAwIHgDAMBgNVHRMBAf8EAjAAMBYGA1UdJQEB/wQMMAoG
# CCsGAQUFBwMIMEEGA1UdIAQ6MDgwNgYJYIZIAYb9bAcBMCkwJwYIKwYBBQUHAgEW
# G2h0dHA6Ly93d3cuZGlnaWNlcnQuY29tL0NQUzAfBgNVHSMEGDAWgBT0tuEgHf4p
# rtLkYaWyoiWyyBc1bjAdBgNVHQ4EFgQUNkSGjqS6sGa+vCgtHUQ23eNqerwwcQYD
# VR0fBGowaDAyoDCgLoYsaHR0cDovL2NybDMuZGlnaWNlcnQuY29tL3NoYTItYXNz
# dXJlZC10cy5jcmwwMqAwoC6GLGh0dHA6Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9zaGEy
# LWFzc3VyZWQtdHMuY3JsMIGFBggrBgEFBQcBAQR5MHcwJAYIKwYBBQUHMAGGGGh0
# dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBPBggrBgEFBQcwAoZDaHR0cDovL2NhY2Vy
# dHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0U0hBMkFzc3VyZWRJRFRpbWVzdGFtcGlu
# Z0NBLmNydDANBgkqhkiG9w0BAQsFAAOCAQEASBzctemaI7znGucgDo5nRv1CclF0
# CiNHo6uS0iXEcFm+FKDlJ4GlTRQVGQd58NEEw4bZO73+RAJmTe1ppA/2uHDPYuj1
# UUp4eTZ6J7fz51Kfk6ftQ55757TdQSKJ+4eiRgNO/PT+t2R3Y18jUmmDgvoaU+2Q
# zI2hF3MN9PNlOXBL85zWenvaDLw9MtAby/Vh/HUIAHa8gQ74wOFcz8QRcucbZEnY
# Ipp1FUL1LTI4gdr0YKK6tFL7XOBhJCVPst/JKahzQ1HavWPWH1ub9y4bTxMd90oN
# cX6Xt/Q/hOvB46NJofrOp79Wz7pZdmGJX36ntI5nePk2mOHLKNpbh6aKLzCCBTEw
# ggQZoAMCAQICEAqhJdbWMht+QeQF2jaXwhUwDQYJKoZIhvcNAQELBQAwZTELMAkG
# A1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3LmRp
# Z2ljZXJ0LmNvbTEkMCIGA1UEAxMbRGlnaUNlcnQgQXNzdXJlZCBJRCBSb290IENB
# MB4XDTE2MDEwNzEyMDAwMFoXDTMxMDEwNzEyMDAwMFowcjELMAkGA1UEBhMCVVMx
# FTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNv
# bTExMC8GA1UEAxMoRGlnaUNlcnQgU0hBMiBBc3N1cmVkIElEIFRpbWVzdGFtcGlu
# ZyBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL3QMu5LzY9/3am6
# gpnFOVQoV7YjSsQOB0UzURB90Pl9TWh+57ag9I2ziOSXv2MhkJi/E7xX08PhfgjW
# ahQAOPcuHjvuzKb2Mln+X2U/4Jvr40ZHBhpVfgsnfsCi9aDg3iI/Dv9+lfvzo7oi
# PhisEeTwmQNtO4V8CdPuXciaC1TjqAlxa+DPIhAPdc9xck4Krd9AOly3UeGheRTG
# TSQjMF287DxgaqwvB8z98OpH2YhQXv1mblZhJymJhFHmgudGUP2UKiyn5HU+upgP
# hH+fMRTWrdXyZMt7HgXQhBlyF/EXBu89zdZN7wZC/aJTKk+FHcQdPK/P2qwQ9d2s
# rOlW/5MCAwEAAaOCAc4wggHKMB0GA1UdDgQWBBT0tuEgHf4prtLkYaWyoiWyyBc1
# bjAfBgNVHSMEGDAWgBRF66Kv9JLLgjEtUYunpyGd823IDzASBgNVHRMBAf8ECDAG
# AQH/AgEAMA4GA1UdDwEB/wQEAwIBhjATBgNVHSUEDDAKBggrBgEFBQcDCDB5Bggr
# BgEFBQcBAQRtMGswJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNv
# bTBDBggrBgEFBQcwAoY3aHR0cDovL2NhY2VydHMuZGlnaWNlcnQuY29tL0RpZ2lD
# ZXJ0QXNzdXJlZElEUm9vdENBLmNydDCBgQYDVR0fBHoweDA6oDigNoY0aHR0cDov
# L2NybDQuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEUm9vdENBLmNybDA6
# oDigNoY0aHR0cDovL2NybDMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElE
# Um9vdENBLmNybDBQBgNVHSAESTBHMDgGCmCGSAGG/WwAAgQwKjAoBggrBgEFBQcC
# ARYcaHR0cHM6Ly93d3cuZGlnaWNlcnQuY29tL0NQUzALBglghkgBhv1sBwEwDQYJ
# KoZIhvcNAQELBQADggEBAHGVEulRh1Zpze/d2nyqY3qzeM8GN0CE70uEv8rPAwL9
# xafDDiBCLK938ysfDCFaKrcFNB1qrpn4J6JmvwmqYN92pDqTD/iy0dh8GWLoXoIl
# HsS6HHssIeLWWywUNUMEaLLbdQLgcseY1jxk5R9IEBhfiThhTWJGJIdjjJFSLK8p
# ieV4H9YLFKWA1xJHcLN11ZOFk362kmf7U2GJqPVrlsD0WGkNfMgBsbkodbeZY4Ui
# jGHKeZR+WfyMD+NvtQEmtmyl7odRIeRYYJu6DC0rbaLEfrvEJStHAgh8Sa4TtuF8
# QkIoxhhWz0E0tmZdtnR79VYzIi8iNrJLokqV2PWmjlIxggKGMIICggIBATCBhjBy
# MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
# d3cuZGlnaWNlcnQuY29tMTEwLwYDVQQDEyhEaWdpQ2VydCBTSEEyIEFzc3VyZWQg
# SUQgVGltZXN0YW1waW5nIENBAhANQkrgvjqI/2BAIc4UAPDdMA0GCWCGSAFlAwQC
# AQUAoIHRMBoGCSqGSIb3DQEJAzENBgsqhkiG9w0BCRABBDAcBgkqhkiG9w0BCQUx
# DxcNMjEwOTI0MTYxMTE1WjArBgsqhkiG9w0BCRACDDEcMBowGDAWBBTh14Ko4ZG+
# 72vKFpG1qrSUpiSb8zAvBgkqhkiG9w0BCQQxIgQgZ/quBL19L/6xNwibrAz4pIqr
# 34dcKEH6X12S1ThgfmgwNwYLKoZIhvcNAQkQAi8xKDAmMCQwIgQgsxCQBrwK2YMH
# kVcp4EQDQVyD4ykrYU8mlkyNNXHs9akwDQYJKoZIhvcNAQEBBQAEggEANkn5Yt+D
# ISgWsSvCl+MWOQKPaTEgEj90Lq+sfOfVhiiJYn9U9SgFtdou4r7DlAt7Li00u2Qy
# PSFejJcQ0hUwZPwplh81uzZB49W2B/Hp6dv3QlQPmn8+6gUL0646hJttlzbleNLb
# b0oqT6VvUa8CQOOMYZRgvrzWq0gITXH/q+octjIztwF6tDSUDFQNRDa023SkReyC
# LfNBzHcEW252WmeZEe2L2APb3KAp8pdwu0dj5a7LjIRoIZJryX+lAdmo4OjzIZQA
# 0Vc1Y0fqjN7o1CpnXUR7jGpAKJuM9mDiujdBJI8NvRSdDmiL4sW7zlKdKgZvvrEX
# T9rCJprPmpMI8g==
# SIG # End signature block