AzStackHciObservability/AzStackHci.Observability.Helpers.psm1

Import-LocalizedData -BindingVariable lvsTxt -FileName AzStackHci.Observability.Strings.psd1

function Test-LogCollection
{
    <#
    .SYNOPSIS
        Check log collection component mets observability condition for update\upgrade
    .DESCRIPTION
        Check if log collection is in progress, if yes then indicate result with Warning
    .PARAMETER PsSession
        Specify the PsSession used to validation from.
    .PARAMETER OperationType
        Specify the Operation Type to target for observability validation. e.g. Deployment, Update, etc
    #>

    [CmdletBinding()]
    param (

        [Parameter(Mandatory = $true)]
        $PsSession,

        [Parameter(Mandatory = $false)]
        [string[]]
        $OperationType
    )

    try
    {
        Log-Info -Message ($lvsTxt.LogCollectiontInfo) -Type Info
        $logCollectiontErrMsg = $($lvsTxt.LogCollectiontInfo)

        # Scriptblock to check log collection status
        $testlogCollectionSb = {
            $AdditionalData = @()
            $status = 'SUCCESS'
            $errorMsg = $null
            $hardwareType = $null
            $logCollectionTime = $null
            $logCollectionStatus = $null
            $resource = $null

            try
            {
                # Get HardwareType
                    $hardwareType = (Get-WmiObject -Class Win32_ComputerSystem).Model

                    # Check check log collection status
                    $logCollectionHistory = Get-LogCollectionHistory -Verbose:$false -ErrorAction SilentlyContinue
                    if ($logCollectionHistory -ne $null `
                         -and $logCollectionHistory[0] -ne $null `
                         -and $logCollectionHistory[0].Status -eq "Running")
                    {
                        $logCollectionTime = $logCollectionHistory[0].TimeCollected
                        $logCollectionStatus = $logCollectionHistory[0].Status
                        $status = 'FAILURE'
                        $resource = "Log Collection in progress"
                        throw $args[0]
                    }
            }
            catch
            {
                $errorMsg = $_.Exception.Message
                $resource = "Error occurred in Environment Validator Log Collection test."
                $status = 'FAILURE'
            }
            finally
            {
                $AdditionalData += @{
                    LogCollectionTime = $logCollectionTime
                    LogCollectionStatus = $logCollectionStatus
                    HardwareType  = $hardwareType
                    Status    = $status
                    Source    = $ENV:COMPUTERNAME
                    Resource  = $resource
                    Detail    = $errorMsg
                }
            }
            return $AdditionalData
        }

        # Run scriptblock
        $logCollectionResult = Invoke-Command -Session $PsSession -ScriptBlock $testlogCollectionSb -ArgumentList $logCollectiontErrMsg

        # build result
        $logCollectionResultSet = @()
        foreach ($lc in $logCollectionResult)
        {
            $params = @{
                Name               = 'AzStackHci_Observability_LogCollection'
                Title              = 'Observability Log collection Requirement'
                DisplayName        = 'Observability Log collection Requirement'
                Severity           = 'WARNING'
                Description        = 'Test to check observability log collection requirement is met'
                Tags               = @{
                    'OperationType' = $OperationType
                }
                Remediation        = 'Stop or Wait for log collection to be completed'
                TargetResourceID   = $lc.Source
                TargetResourceName = $lc.Source
                TargetResourceType = $lc.HardwareType | Get-Unique
                Timestamp          = [datetime]::UtcNow
                Status             = $lc.Status
                AdditionalData     = $lc
                HealthCheckSource  = $ENV:EnvChkrId
            }
            $logCollectionResultSet += New-AzStackHciResultObject @params
        }
        return $logCollectionResultSet
    }
    catch
    {
        throw $_
    }
}

function Test-RemoteSupport
{
    <#
    .SYNOPSIS
        Test Remote Support Session Terminal is active
    .DESCRIPTION
        Test if active Remote Support Session is in progress
    .PARAMETER PsSession
        Specify the PsSession used to validation from.
    .PARAMETER OperationType
        Specify the Operation Type to target for observability validation. e.g. Deployment, Update, etc
    #>

    [CmdletBinding()]
    param (

        [Parameter(Mandatory = $true)]
        $PsSession,

        [Parameter(Mandatory = $false)]
        [string[]]
        $OperationType
    )

    try
    {
        Log-Info -Message ($lvsTxt.RemoteSupportStartInfo) -Type Info
        $remoteSupportErrMsg = $($lvsTxt.RemoteSupportErrMsg)

        # Scriptblock to check remote support status
        $remoteSupportSessionSb = {
            $AdditionalData = @()
            $status = 'SUCCESS'
            $errorMsg = $null
            $hardwareType = $null
            $nodeName  = $null
            $startTime = $null
            $endTime = $null
            $resource = $null

            try
            {
                # Get HardwareType information
                $hardwareType = (Get-WmiObject -Class Win32_ComputerSystem).Model

                # Check remote support access state
                $getRemoteSupportAccessState = $(Get-AzStackHCIRemoteSupportAccess -Verbose:$false -ErrorAction SilentlyContinue).State
                if ($getRemoteSupportAccessState -eq "Active")
                {
                    $remoteSupportSessionHistory = Get-AzStackHCIRemoteSupportSessionHistory -Verbose:$false -ErrorAction SilentlyContinue | where { $_.EndTime -gt $(Get-Date) }
                    if ($remoteSupportSessionHistory -ne $null -and $($remoteSupportSessionHistory.count) -gt 0)
                    {
                        $startTime = $remoteSupportSessionHistory.StartTime
                        $endTime = $remoteSupportSessionHistory.EndTime
                        $nodeName = $remoteSupportSessionHistory.NodeName
                        $status = 'FAILURE'
                        $resource = "Open Remote Support Session terminal."
                        throw $args[0]
                    }
                }
            }
            catch
            {
                $errorMsg = $_.Exception.Message
                $resource = "Error occurred in Environment Validator Remote Support test."
                $status = 'FAILURE'
            }
            finally
            {
                $AdditionalData += @{
                    HardwareType  = $hardwareType
                    Status    = $status
                    RemoteSupportSessionEndTime  = $endTime
                    RemoteSupportSessionStartTime = $startTime
                    RemoteSupportSessionNodeName = $nodeName
                    Source = $ENV:COMPUTERNAME
                    Resource = $resource
                    Detail = $errorMsg
                }
            }
            return $AdditionalData
        }

        # Run scriptblock
        $remoteSupportSessionResult = Invoke-Command -Session $PsSession -ScriptBlock $remoteSupportSessionSb -ArgumentList $remoteSupportErrMsg
        $remoteSupportSessionSet = @()
        foreach ($rSS in $remoteSupportSessionResult)
        {
            $params = @{
                Name               = 'AzStackHci_Observability_RemoteSupport'
                Title              = 'Observability RemoteSupport Requirement'
                DisplayName        = 'Observability RemoteSupport Requirement'
                Severity           = 'CRITICAL'
                Description        = 'Test to check observability RemoteSupport requirement is met'
                Tags               = @{
                    'OperationType' = $OperationType
                }
                Remediation        = 'Active remote session terminal is open, please contact Microsoft Support'
                TargetResourceID   = $rSS.Source
                TargetResourceName = $rSS.Source
                TargetResourceType = $rSS.HardwareType | Get-Unique
                Timestamp          = [datetime]::UtcNow
                Status             = $rSS.Status
                AdditionalData     = $rSS
                HealthCheckSource  = $ENV:EnvChkrId
            }
            $remoteSupportSessionSet += New-AzStackHciResultObject @params
        }
        return $remoteSupportSessionSet
    }
    catch
    {
        throw $_
    }
}

Export-ModuleMember -Function Test-LogCollection
Export-ModuleMember -Function Test-RemoteSupport
# SIG # Begin signature block
# MIIoRQYJKoZIhvcNAQcCoIIoNjCCKDICAQExDzANBglghkgBZQMEAgEFADB5Bgor
# BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG
# KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCBFqw90/Q5zyktW
# plp0bIt9Kbe+FYaTbcFE7LIMIupjsKCCDXYwggX0MIID3KADAgECAhMzAAAEhV6Z
# 7A5ZL83XAAAAAASFMA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNVBAYTAlVTMRMwEQYD
# VQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNy
# b3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMTH01pY3Jvc29mdCBDb2RlIFNpZ25p
# bmcgUENBIDIwMTEwHhcNMjUwNjE5MTgyMTM3WhcNMjYwNjE3MTgyMTM3WjB0MQsw
# CQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9u
# ZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMR4wHAYDVQQDExVNaWNy
# b3NvZnQgQ29ycG9yYXRpb24wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
# AQDASkh1cpvuUqfbqxele7LCSHEamVNBfFE4uY1FkGsAdUF/vnjpE1dnAD9vMOqy
# 5ZO49ILhP4jiP/P2Pn9ao+5TDtKmcQ+pZdzbG7t43yRXJC3nXvTGQroodPi9USQi
# 9rI+0gwuXRKBII7L+k3kMkKLmFrsWUjzgXVCLYa6ZH7BCALAcJWZTwWPoiT4HpqQ
# hJcYLB7pfetAVCeBEVZD8itKQ6QA5/LQR+9X6dlSj4Vxta4JnpxvgSrkjXCz+tlJ
# 67ABZ551lw23RWU1uyfgCfEFhBfiyPR2WSjskPl9ap6qrf8fNQ1sGYun2p4JdXxe
# UAKf1hVa/3TQXjvPTiRXCnJPAgMBAAGjggFzMIIBbzAfBgNVHSUEGDAWBgorBgEE
# AYI3TAgBBggrBgEFBQcDAzAdBgNVHQ4EFgQUuCZyGiCuLYE0aU7j5TFqY05kko0w
# RQYDVR0RBD4wPKQ6MDgxHjAcBgNVBAsTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEW
# MBQGA1UEBRMNMjMwMDEyKzUwNTM1OTAfBgNVHSMEGDAWgBRIbmTlUAXTgqoXNzci
# tW2oynUClTBUBgNVHR8ETTBLMEmgR6BFhkNodHRwOi8vd3d3Lm1pY3Jvc29mdC5j
# b20vcGtpb3BzL2NybC9NaWNDb2RTaWdQQ0EyMDExXzIwMTEtMDctMDguY3JsMGEG
# CCsGAQUFBwEBBFUwUzBRBggrBgEFBQcwAoZFaHR0cDovL3d3dy5taWNyb3NvZnQu
# Y29tL3BraW9wcy9jZXJ0cy9NaWNDb2RTaWdQQ0EyMDExXzIwMTEtMDctMDguY3J0
# MAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcNAQELBQADggIBACjmqAp2Ci4sTHZci+qk
# tEAKsFk5HNVGKyWR2rFGXsd7cggZ04H5U4SV0fAL6fOE9dLvt4I7HBHLhpGdE5Uj
# Ly4NxLTG2bDAkeAVmxmd2uKWVGKym1aarDxXfv3GCN4mRX+Pn4c+py3S/6Kkt5eS
# DAIIsrzKw3Kh2SW1hCwXX/k1v4b+NH1Fjl+i/xPJspXCFuZB4aC5FLT5fgbRKqns
# WeAdn8DsrYQhT3QXLt6Nv3/dMzv7G/Cdpbdcoul8FYl+t3dmXM+SIClC3l2ae0wO
# lNrQ42yQEycuPU5OoqLT85jsZ7+4CaScfFINlO7l7Y7r/xauqHbSPQ1r3oIC+e71
# 5s2G3ClZa3y99aYx2lnXYe1srcrIx8NAXTViiypXVn9ZGmEkfNcfDiqGQwkml5z9
# nm3pWiBZ69adaBBbAFEjyJG4y0a76bel/4sDCVvaZzLM3TFbxVO9BQrjZRtbJZbk
# C3XArpLqZSfx53SuYdddxPX8pvcqFuEu8wcUeD05t9xNbJ4TtdAECJlEi0vvBxlm
# M5tzFXy2qZeqPMXHSQYqPgZ9jvScZ6NwznFD0+33kbzyhOSz/WuGbAu4cHZG8gKn
# lQVT4uA2Diex9DMs2WHiokNknYlLoUeWXW1QrJLpqO82TLyKTbBM/oZHAdIc0kzo
# STro9b3+vjn2809D0+SOOCVZMIIHejCCBWKgAwIBAgIKYQ6Q0gAAAAAAAzANBgkq
# hkiG9w0BAQsFADCBiDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24x
# EDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlv
# bjEyMDAGA1UEAxMpTWljcm9zb2Z0IFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5
# IDIwMTEwHhcNMTEwNzA4MjA1OTA5WhcNMjYwNzA4MjEwOTA5WjB+MQswCQYDVQQG
# EwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwG
# A1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSgwJgYDVQQDEx9NaWNyb3NvZnQg
# Q29kZSBTaWduaW5nIFBDQSAyMDExMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC
# CgKCAgEAq/D6chAcLq3YbqqCEE00uvK2WCGfQhsqa+laUKq4BjgaBEm6f8MMHt03
# a8YS2AvwOMKZBrDIOdUBFDFC04kNeWSHfpRgJGyvnkmc6Whe0t+bU7IKLMOv2akr
# rnoJr9eWWcpgGgXpZnboMlImEi/nqwhQz7NEt13YxC4Ddato88tt8zpcoRb0Rrrg
# OGSsbmQ1eKagYw8t00CT+OPeBw3VXHmlSSnnDb6gE3e+lD3v++MrWhAfTVYoonpy
# 4BI6t0le2O3tQ5GD2Xuye4Yb2T6xjF3oiU+EGvKhL1nkkDstrjNYxbc+/jLTswM9
# sbKvkjh+0p2ALPVOVpEhNSXDOW5kf1O6nA+tGSOEy/S6A4aN91/w0FK/jJSHvMAh
# dCVfGCi2zCcoOCWYOUo2z3yxkq4cI6epZuxhH2rhKEmdX4jiJV3TIUs+UsS1Vz8k
# A/DRelsv1SPjcF0PUUZ3s/gA4bysAoJf28AVs70b1FVL5zmhD+kjSbwYuER8ReTB
# w3J64HLnJN+/RpnF78IcV9uDjexNSTCnq47f7Fufr/zdsGbiwZeBe+3W7UvnSSmn
# Eyimp31ngOaKYnhfsi+E11ecXL93KCjx7W3DKI8sj0A3T8HhhUSJxAlMxdSlQy90
# lfdu+HggWCwTXWCVmj5PM4TasIgX3p5O9JawvEagbJjS4NaIjAsCAwEAAaOCAe0w
# ggHpMBAGCSsGAQQBgjcVAQQDAgEAMB0GA1UdDgQWBBRIbmTlUAXTgqoXNzcitW2o
# ynUClTAZBgkrBgEEAYI3FAIEDB4KAFMAdQBiAEMAQTALBgNVHQ8EBAMCAYYwDwYD
# VR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAWgBRyLToCMZBDuRQFTuHqp8cx0SOJNDBa
# BgNVHR8EUzBRME+gTaBLhklodHRwOi8vY3JsLm1pY3Jvc29mdC5jb20vcGtpL2Ny
# bC9wcm9kdWN0cy9NaWNSb29DZXJBdXQyMDExXzIwMTFfMDNfMjIuY3JsMF4GCCsG
# AQUFBwEBBFIwUDBOBggrBgEFBQcwAoZCaHR0cDovL3d3dy5taWNyb3NvZnQuY29t
# L3BraS9jZXJ0cy9NaWNSb29DZXJBdXQyMDExXzIwMTFfMDNfMjIuY3J0MIGfBgNV
# HSAEgZcwgZQwgZEGCSsGAQQBgjcuAzCBgzA/BggrBgEFBQcCARYzaHR0cDovL3d3
# dy5taWNyb3NvZnQuY29tL3BraW9wcy9kb2NzL3ByaW1hcnljcHMuaHRtMEAGCCsG
# AQUFBwICMDQeMiAdAEwAZQBnAGEAbABfAHAAbwBsAGkAYwB5AF8AcwB0AGEAdABl
# AG0AZQBuAHQALiAdMA0GCSqGSIb3DQEBCwUAA4ICAQBn8oalmOBUeRou09h0ZyKb
# C5YR4WOSmUKWfdJ5DJDBZV8uLD74w3LRbYP+vj/oCso7v0epo/Np22O/IjWll11l
# hJB9i0ZQVdgMknzSGksc8zxCi1LQsP1r4z4HLimb5j0bpdS1HXeUOeLpZMlEPXh6
# I/MTfaaQdION9MsmAkYqwooQu6SpBQyb7Wj6aC6VoCo/KmtYSWMfCWluWpiW5IP0
# wI/zRive/DvQvTXvbiWu5a8n7dDd8w6vmSiXmE0OPQvyCInWH8MyGOLwxS3OW560
# STkKxgrCxq2u5bLZ2xWIUUVYODJxJxp/sfQn+N4sOiBpmLJZiWhub6e3dMNABQam
# ASooPoI/E01mC8CzTfXhj38cbxV9Rad25UAqZaPDXVJihsMdYzaXht/a8/jyFqGa
# J+HNpZfQ7l1jQeNbB5yHPgZ3BtEGsXUfFL5hYbXw3MYbBL7fQccOKO7eZS/sl/ah
# XJbYANahRr1Z85elCUtIEJmAH9AAKcWxm6U/RXceNcbSoqKfenoi+kiVH6v7RyOA
# 9Z74v2u3S5fi63V4GuzqN5l5GEv/1rMjaHXmr/r8i+sLgOppO6/8MO0ETI7f33Vt
# Y5E90Z1WTk+/gFcioXgRMiF670EKsT/7qMykXcGhiJtXcVZOSEXAQsmbdlsKgEhr
# /Xmfwb1tbWrJUnMTDXpQzTGCGiUwghohAgEBMIGVMH4xCzAJBgNVBAYTAlVTMRMw
# EQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVN
# aWNyb3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMTH01pY3Jvc29mdCBDb2RlIFNp
# Z25pbmcgUENBIDIwMTECEzMAAASFXpnsDlkvzdcAAAAABIUwDQYJYIZIAWUDBAIB
# BQCgga4wGQYJKoZIhvcNAQkDMQwGCisGAQQBgjcCAQQwHAYKKwYBBAGCNwIBCzEO
# MAwGCisGAQQBgjcCARUwLwYJKoZIhvcNAQkEMSIEIMLpaXHhqNFd5Pw9IZPuSgzv
# tgbySMLN0+aMD8QEuznSMEIGCisGAQQBgjcCAQwxNDAyoBSAEgBNAGkAYwByAG8A
# cwBvAGYAdKEagBhodHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20wDQYJKoZIhvcNAQEB
# BQAEggEAeK+xZD53mIfVooUKL8o1v5JWSli3UPD19N2ddaNtO7PCIlXt/F4t3sj2
# Lp5dAX2+essn7+6y4/MBIraiv6/1ahvtnASxyjTGKXBmWSlgKiQEfEeixBrhJb79
# +c0bLk93SDQElfBlx3GJCI1eOBg4fw8qHMj3gzOfLi3CVKWVI+rmX36bEMrF9a6u
# dNRN/MjoI1TXIZ+ytTqmz2pePP7RCncphM1Cgitm3GAXcvx5Y5FdtXsUe31n0rPU
# IC+A2M3KP1oDxApMU2XOu8tEp67kb6osc3ed4d5HVQIZiONticc/yhEsAKa9dFim
# wKtLiaTLDV8Qv7i3l3qcxvYVjlc8vqGCF68wgherBgorBgEEAYI3AwMBMYIXmzCC
# F5cGCSqGSIb3DQEHAqCCF4gwgheEAgEDMQ8wDQYJYIZIAWUDBAIBBQAwggFZBgsq
# hkiG9w0BCRABBKCCAUgEggFEMIIBQAIBAQYKKwYBBAGEWQoDATAxMA0GCWCGSAFl
# AwQCAQUABCDN/xiybiRa6iqNgYOtn8dbuv4cUkqrXaVybTniExGO2gIGaKSi6gPv
# GBIyMDI1MDkwOTE5MjIwOC43OVowBIACAfSggdmkgdYwgdMxCzAJBgNVBAYTAlVT
# MRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQK
# ExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xLTArBgNVBAsTJE1pY3Jvc29mdCBJcmVs
# YW5kIE9wZXJhdGlvbnMgTGltaXRlZDEnMCUGA1UECxMeblNoaWVsZCBUU1MgRVNO
# OjZGMUEtMDVFMC1EOTQ3MSUwIwYDVQQDExxNaWNyb3NvZnQgVGltZS1TdGFtcCBT
# ZXJ2aWNloIIR/jCCBygwggUQoAMCAQICEzMAAAH8GKCvzGlahzoAAQAAAfwwDQYJ
# KoZIhvcNAQELBQAwfDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24x
# EDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlv
# bjEmMCQGA1UEAxMdTWljcm9zb2Z0IFRpbWUtU3RhbXAgUENBIDIwMTAwHhcNMjQw
# NzI1MTgzMTE0WhcNMjUxMDIyMTgzMTE0WjCB0zELMAkGA1UEBhMCVVMxEzARBgNV
# BAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jv
# c29mdCBDb3Jwb3JhdGlvbjEtMCsGA1UECxMkTWljcm9zb2Z0IElyZWxhbmQgT3Bl
# cmF0aW9ucyBMaW1pdGVkMScwJQYDVQQLEx5uU2hpZWxkIFRTUyBFU046NkYxQS0w
# NUUwLUQ5NDcxJTAjBgNVBAMTHE1pY3Jvc29mdCBUaW1lLVN0YW1wIFNlcnZpY2Uw
# ggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCnUMAovGltBw9Vg8eUkfJb
# tbmUFmMlZYOMx+XlbKG4DKU/8sObaFvjKZSZLKZXQQVFByYzwHKnCOFY/wXvHiI7
# zx370Zn0xCY2HeNIOiGFdeB/ys40QDJ8I9WYnMzvK2y6tn3Ghxu4Qvv4/sSQjCg6
# 4wWVMXYb/O6rHUT7AA2yWk+o+lvw8LnoFDGAkIjUs4XmWTcB48nvw4vdrD812WS9
# 1WXdWAFI9fg1rC3dSBSh+4+f9yn2/AooHC4hZAQVnzfsZdchOyF3Yx+zqhh/FcS2
# aPZIEYSHFWzvERG5YZvRwrpp/LudoqRtkja/VSqzG5m33iuf97LbKe+6eXHRHr9v
# qc2QLWs5MB9aWmwCP9CXPIzq5hNLFhkLZhbMtttGXSVG1LP7hN2lRT+gBlIH5j6z
# XZGqaDOLtFXE1wjaWb/+wISboDrecIkKBi0z4st72lOyGX9Z/w4649BGID6y1OyD
# z0E4b21uVrPaR946Rh/mF0fymEBu464NB+vqzlhrpb69nPoTRmx6fOLQ60x/lEJr
# aEANhWBTEP6CsLwSm19Z5UBaBgJpAWF4039kY1AySTvxXrfKg8F98kQC74HnGVM9
# iiKNR2j01ei8magZePpHxOCyj5A9oAYcrEJsdrVAv0BIwXc6zWOuiAIcaLKR+nV0
# oaeYDnAlPo3HsF52VIOwCQIDAQABo4IBSTCCAUUwHQYDVR0OBBYEFJjxpSuxRrOH
# EHIfv12GJAIv/tB2MB8GA1UdIwQYMBaAFJ+nFV0AXmJdg/Tl0mWnG1M1GelyMF8G
# A1UdHwRYMFYwVKBSoFCGTmh0dHA6Ly93d3cubWljcm9zb2Z0LmNvbS9wa2lvcHMv
# Y3JsL01pY3Jvc29mdCUyMFRpbWUtU3RhbXAlMjBQQ0ElMjAyMDEwKDEpLmNybDBs
# BggrBgEFBQcBAQRgMF4wXAYIKwYBBQUHMAKGUGh0dHA6Ly93d3cubWljcm9zb2Z0
# LmNvbS9wa2lvcHMvY2VydHMvTWljcm9zb2Z0JTIwVGltZS1TdGFtcCUyMFBDQSUy
# MDIwMTAoMSkuY3J0MAwGA1UdEwEB/wQCMAAwFgYDVR0lAQH/BAwwCgYIKwYBBQUH
# AwgwDgYDVR0PAQH/BAQDAgeAMA0GCSqGSIb3DQEBCwUAA4ICAQBPuyz9kBnRtNoW
# yuyIlh3/8tDoiYpv0llIqJHD3GzyHCTlj/vOKCf2Aa3B5EKELaUnwZVEeCsWQHEA
# KO64+mtLP9RhfufnbYkpy52da4h4TWnfQFmuo9M6exwP3wNmLpY1MDKadpLuK3mo
# CA0iet4AltNTZwCiwmh5cAevnRiBIaWYkz5w3qZgsAvpNMUy0Vgmukr1MzlHKHl5
# mabpRMmcaDSO3WkX/a7w9J3Pd0PLsMXsoMlp3aofFk5G8zeT1Xxifckjlgs+4uyj
# Ynmzd+lfIJWBH+GrzqDnON31tFHLKILyIsib833mrodZWwJ7JJ62up+wPJhZK3Av
# 3qHLsMjIsvmKHxgUx3QB2a9NGjKWYAO4rATZNAJO8+eOcuTvKklbb23XtjJrhX4m
# XPniwGc9TuQh5hmy9RP5gqDKQ/VAH6n65R1Efp7v1VqLP6J7Basglni1eQMyYvbW
# eHSP7nwTV5wBgO9PoHjIUh6ifED/oaX1ezsktyI8IgLqEZ2WKIQGnJh5QXSiFkWf
# s0pC7zQhnSN3nXVYDZurrH1pSr/MXJ/wSDD526dSPUq02hamrtW4mpqlyRiya+aZ
# gdlcKMrUS6ztXUj5peOsFi6rIz1Cl4VlThTTVgbXm5bBQJqPS5mVqH9EZJgx3zjL
# 0MKo6l94oTo8syTuEueG9w5CufE/qTCCB3EwggVZoAMCAQICEzMAAAAVxedrngKb
# SZkAAAAAABUwDQYJKoZIhvcNAQELBQAwgYgxCzAJBgNVBAYTAlVTMRMwEQYDVQQI
# EwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3Nv
# ZnQgQ29ycG9yYXRpb24xMjAwBgNVBAMTKU1pY3Jvc29mdCBSb290IENlcnRpZmlj
# YXRlIEF1dGhvcml0eSAyMDEwMB4XDTIxMDkzMDE4MjIyNVoXDTMwMDkzMDE4MzIy
# NVowfDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcT
# B1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEmMCQGA1UE
# AxMdTWljcm9zb2Z0IFRpbWUtU3RhbXAgUENBIDIwMTAwggIiMA0GCSqGSIb3DQEB
# AQUAA4ICDwAwggIKAoICAQDk4aZM57RyIQt5osvXJHm9DtWC0/3unAcH0qlsTnXI
# yjVX9gF/bErg4r25PhdgM/9cT8dm95VTcVrifkpa/rg2Z4VGIwy1jRPPdzLAEBjo
# YH1qUoNEt6aORmsHFPPFdvWGUNzBRMhxXFExN6AKOG6N7dcP2CZTfDlhAnrEqv1y
# aa8dq6z2Nr41JmTamDu6GnszrYBbfowQHJ1S/rboYiXcag/PXfT+jlPP1uyFVk3v
# 3byNpOORj7I5LFGc6XBpDco2LXCOMcg1KL3jtIckw+DJj361VI/c+gVVmG1oO5pG
# ve2krnopN6zL64NF50ZuyjLVwIYwXE8s4mKyzbnijYjklqwBSru+cakXW2dg3viS
# kR4dPf0gz3N9QZpGdc3EXzTdEonW/aUgfX782Z5F37ZyL9t9X4C626p+Nuw2TPYr
# bqgSUei/BQOj0XOmTTd0lBw0gg/wEPK3Rxjtp+iZfD9M269ewvPV2HM9Q07BMzlM
# jgK8QmguEOqEUUbi0b1qGFphAXPKZ6Je1yh2AuIzGHLXpyDwwvoSCtdjbwzJNmSL
# W6CmgyFdXzB0kZSU2LlQ+QuJYfM2BjUYhEfb3BvR/bLUHMVr9lxSUV0S2yW6r1AF
# emzFER1y7435UsSFF5PAPBXbGjfHCBUYP3irRbb1Hode2o+eFnJpxq57t7c+auIu
# rQIDAQABo4IB3TCCAdkwEgYJKwYBBAGCNxUBBAUCAwEAATAjBgkrBgEEAYI3FQIE
# FgQUKqdS/mTEmr6CkTxGNSnPEP8vBO4wHQYDVR0OBBYEFJ+nFV0AXmJdg/Tl0mWn
# G1M1GelyMFwGA1UdIARVMFMwUQYMKwYBBAGCN0yDfQEBMEEwPwYIKwYBBQUHAgEW
# M2h0dHA6Ly93d3cubWljcm9zb2Z0LmNvbS9wa2lvcHMvRG9jcy9SZXBvc2l0b3J5
# Lmh0bTATBgNVHSUEDDAKBggrBgEFBQcDCDAZBgkrBgEEAYI3FAIEDB4KAFMAdQBi
# AEMAQTALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAWgBTV
# 9lbLj+iiXGJo0T2UkFvXzpoYxDBWBgNVHR8ETzBNMEugSaBHhkVodHRwOi8vY3Js
# Lm1pY3Jvc29mdC5jb20vcGtpL2NybC9wcm9kdWN0cy9NaWNSb29DZXJBdXRfMjAx
# MC0wNi0yMy5jcmwwWgYIKwYBBQUHAQEETjBMMEoGCCsGAQUFBzAChj5odHRwOi8v
# d3d3Lm1pY3Jvc29mdC5jb20vcGtpL2NlcnRzL01pY1Jvb0NlckF1dF8yMDEwLTA2
# LTIzLmNydDANBgkqhkiG9w0BAQsFAAOCAgEAnVV9/Cqt4SwfZwExJFvhnnJL/Klv
# 6lwUtj5OR2R4sQaTlz0xM7U518JxNj/aZGx80HU5bbsPMeTCj/ts0aGUGCLu6WZn
# OlNN3Zi6th542DYunKmCVgADsAW+iehp4LoJ7nvfam++Kctu2D9IdQHZGN5tggz1
# bSNU5HhTdSRXud2f8449xvNo32X2pFaq95W2KFUn0CS9QKC/GbYSEhFdPSfgQJY4
# rPf5KYnDvBewVIVCs/wMnosZiefwC2qBwoEZQhlSdYo2wh3DYXMuLGt7bj8sCXgU
# 6ZGyqVvfSaN0DLzskYDSPeZKPmY7T7uG+jIa2Zb0j/aRAfbOxnT99kxybxCrdTDF
# NLB62FD+CljdQDzHVG2dY3RILLFORy3BFARxv2T5JL5zbcqOCb2zAVdJVGTZc9d/
# HltEAY5aGZFrDZ+kKNxnGSgkujhLmm77IVRrakURR6nxt67I6IleT53S0Ex2tVdU
# CbFpAUR+fKFhbHP+CrvsQWY9af3LwUFJfn6Tvsv4O+S3Fb+0zj6lMVGEvL8CwYKi
# excdFYmNcP7ntdAoGokLjzbaukz5m/8K6TT4JDVnK+ANuOaMmdbhIurwJ0I9JZTm
# dHRbatGePu1+oDEzfbzL6Xu/OHBE0ZDxyKs6ijoIYn/ZcGNTTY3ugm2lBRDBcQZq
# ELQdVTNYs6FwZvKhggNZMIICQQIBATCCAQGhgdmkgdYwgdMxCzAJBgNVBAYTAlVT
# MRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQK
# ExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xLTArBgNVBAsTJE1pY3Jvc29mdCBJcmVs
# YW5kIE9wZXJhdGlvbnMgTGltaXRlZDEnMCUGA1UECxMeblNoaWVsZCBUU1MgRVNO
# OjZGMUEtMDVFMC1EOTQ3MSUwIwYDVQQDExxNaWNyb3NvZnQgVGltZS1TdGFtcCBT
# ZXJ2aWNloiMKAQEwBwYFKw4DAhoDFQBOQSklc5qojbB+oGzDg0tXCpiqqqCBgzCB
# gKR+MHwxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQH
# EwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xJjAkBgNV
# BAMTHU1pY3Jvc29mdCBUaW1lLVN0YW1wIFBDQSAyMDEwMA0GCSqGSIb3DQEBCwUA
# AgUA7GrO+TAiGA8yMDI1MDkwOTE2MDYxN1oYDzIwMjUwOTEwMTYwNjE3WjB3MD0G
# CisGAQQBhFkKBAExLzAtMAoCBQDsas75AgEAMAoCAQACAivQAgH/MAcCAQACAhJ6
# MAoCBQDsbCB5AgEAMDYGCisGAQQBhFkKBAIxKDAmMAwGCisGAQQBhFkKAwKgCjAI
# AgEAAgMHoSChCjAIAgEAAgMBhqAwDQYJKoZIhvcNAQELBQADggEBABWmupStnEmD
# DN2DsxKbFuhjntjRlfpRatlOIsLfXb8UmL5x77qM0KZuiADbTToLihtjVY99G8w/
# +kaQXFjv3txZEiQGFrtIFwiFPGBvew16AWHU9tYkqO1Fyl+GFoK7aEF+B3g4ULh0
# B6BSuaygxtKmdZ7zHAIrc0h/oqWVPt7QvATVT+csScSrV7kb2x9bQZjjqQqtJpT2
# lWKeEuf3HGGGZMCKfroX3V1nKtjy92oZw3uRphXbjR2m5wTVse84CrsNh4WwbLtP
# 4aLMuSw573JiJL7sbX/zBkNN3oEJEaNcdk7nreUS0EKh5i8yt69xRsQCqA4ki0MT
# j4bilJIidrExggQNMIIECQIBATCBkzB8MQswCQYDVQQGEwJVUzETMBEGA1UECBMK
# V2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0
# IENvcnBvcmF0aW9uMSYwJAYDVQQDEx1NaWNyb3NvZnQgVGltZS1TdGFtcCBQQ0Eg
# MjAxMAITMwAAAfwYoK/MaVqHOgABAAAB/DANBglghkgBZQMEAgEFAKCCAUowGgYJ
# KoZIhvcNAQkDMQ0GCyqGSIb3DQEJEAEEMC8GCSqGSIb3DQEJBDEiBCCOWhntKIzl
# p6ryCxJsLzFlSqxOeweDJV2YWGqcyPtT7jCB+gYLKoZIhvcNAQkQAi8xgeowgecw
# geQwgb0EIJVCr5C77+H8E5U/jDB5TBse4JSGH5PuGrd3kwJo0S1iMIGYMIGApH4w
# fDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1Jl
# ZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEmMCQGA1UEAxMd
# TWljcm9zb2Z0IFRpbWUtU3RhbXAgUENBIDIwMTACEzMAAAH8GKCvzGlahzoAAQAA
# AfwwIgQgQ8nyhB8mdjoeJCQSqj2bLffzFo7dz3ry7bQ/bzmJO2cwDQYJKoZIhvcN
# AQELBQAEggIAXubQ0rfRCSJfrE4bNXZCLPbfzk81qTL6wIfH1A7XBhlAI5uxiQme
# nvaB2g+sLWlGMNkxvuN4f2B8FcpvLNV9lFkkho1Obglx0I5fHiZYAXl5cFYqwgAg
# XAsv4S7xlZxOXnpS5sYw+IqAQqlP5DYd5/9ICp/fS13B1CuntagSakZ9o5VSZe7X
# h4SIbilx5cjy6AQcD1HE2rsH/2tjpXI/j6x0Ru3Iq7JJVUDCk8GBHqWriHf1I2Pt
# 5lU5oGKjaU1jQMFo25Hys7orlNoE2C4EQJLCcZ+uuVwJs6aNG5dlWCpVdL0IOk18
# s25ymYiLBmWfbTA5V2lzbpL0uCitq0OQksaEYoW5LAj1EkyJXP1dZIcTE4iwFlr4
# IiBA0O8LyJWFoICG59i8O0r293IEIVS0MKI3112BRiHZK4xJe3tGWv9oFsCZ8mUr
# 22vkFWoMXaK44e3nbAgyAUlVRcri/shwmflVOMRJEsQfUyxA/0e72nL2lOJgFXlx
# y5gMFuoFqjXNCo4NBU4d3vAS/UCAny0fxSvKKIhzaryRFrg7x19Xeakj9GcgPax+
# vGtL+ahFhpQxAqlVl6iuVNLV2rZVxlzv3SP+6EoEvvjrDNpqcw78M7RnecXZJH1H
# T9kQgGDk8g5OOLDCxlyhFtFzAHpelbjbvpIvopyiBhBJej6V/rb/65I=
# SIG # End signature block