scenarios/DCB/PFC.ps1

param
(
    [object] $EventInfo,
    [Switch] $Debug
)

if ($Debug) {$DebugPreference = 'Continue'}

Add-Type -Path "$PSScriptRoot\..\..\Microsoft.NetworkHud.Module.dll" -ErrorAction SilentlyContinue
$dictionary = [Microsoft.NetworkHud.Module.SharedConcurrentDictionary]::GetInstance("LLDP")

$config = (Import-PowerShellDataFile "$PSScriptRoot\..\Config.psd1").DCB
Import-LocalizedData -BindingVariable "LocMessage" -FileName "LocalizationMessages" -BaseDirectory $PSScriptRoot\..\..\

$logName = 'NetworkHud'

$helpersPath = Join-Path -Path $PSScriptRoot -ChildPath '..\helpers'
Import-Module "$helpersPath\helper.HealthFaults.psm1"
Import-Module "$helpersPath\helper.NetworkATC.psm1"
Add-FaultApi

$ClusterName = (Get-ItemProperty -Path "HKLM:\Cluster").ClusterName
$IntentInfo = Get-NetworkATCAdapters -ClusterName $ClusterName

function Get-PFCConfiguration {
    param (
        [Parameter(Mandatory = $true)]
        [object[]] $Data
    )

   [Flags()] enum PFCBitMask {
        Priority0 = 1
        Priority1 = 2
        Priority2 = 4
        Priority3 = 8
        Priority4 = 16
        Priority5 = 32
        Priority6 = 64
        Priority7 = 128
    }

    Remove-Variable PrioritiesEnabled, PrioritiesDisabled -ErrorAction SilentlyContinue

    $PrioritiesEnabled   += [enum]::GetValues([PFCBitMask]) | Where-Object {$_.value__ -band $Data[0]}
    $PrioritiesDisabled  += [enum]::GetValues([PFCBitMask]) | Where-Object {$_.value__ -band (-bnot $Data[0])}
    
    $AllPriorities = @()

    foreach ($Priority in $PrioritiesEnabled) {
        $thisPriorityState = New-Object -TypeName psobject
        $thisPriorityState | Add-Member -MemberType NoteProperty -Name Priority -Value $($Priority -replace 'Priority')
        $thisPriorityState | Add-Member -MemberType NoteProperty -Name Enabled  -Value $true

        $AllPriorities += $thisPriorityState
    }

    foreach ($Priority in $PrioritiesDisabled) {
        $thisPriorityState = New-Object -TypeName psobject
        $thisPriorityState | Add-Member -MemberType NoteProperty -Name Priority -Value $($Priority -replace 'Priority')
        $thisPriorityState | Add-Member -MemberType NoteProperty -Name Enabled  -Value $false

        $AllPriorities += $thisPriorityState
    }

    0..7 | Foreach-Object {
        $thisPriority = $_

        if ($thisPriority -notin $AllPriorities.Priority) {
            $thisPriorityState = New-Object -TypeName psobject

            $thisPriorityState | Add-Member -MemberType NoteProperty -Name Priority -Value $thisPriority
            $thisPriorityState | Add-Member -MemberType NoteProperty -Name Enabled  -Value $false

            $AllPriorities += $thisPriorityState
        }
    }

    Return $AllPriorities | Sort-Object Priority
}

Foreach ($Intent in $($Intentinfo | Where-Object Intenttype -Contains 'Storage')) {
    foreach ($Adapter in $Intent.Adapters) {
        # This comes as a string from the dictionary, but each bit needs to be sent as part of an arry so we split on spaces.
        $PFCPriority   = Get-PFCConfiguration -Data $($dictionary[$Adapter]["PFC"] -Split ' ')
        $StorageIntent = Get-NetIntent -Name $Intent.IntentName

        $IsRoCE = (Get-NetAdapterAdvancedProperty -Name $Adapter -RegistryKeyword *NetworkDirectTechnology).RegistryValue

        if ($IsRoCE -eq 4 -or $IsRoCE -eq 3) {
            if ($StorageIntent.QosPolicyOverride.PriorityValue8021Action_SMB -eq $null) { $SMBPriority = 3 }
            else { $SMBPriority = $StorageIntent.QosPolicyOverride.PriorityValue8021Action_SMB }

            Write-Debug "Intent: $($Intent.IntentName)"
            Write-Debug "Network ATC SMB Priority: $SMBPriority"
            Write-Debug "Fabric Enabled Priorities: $( $PFCPriority | Format-List | Out-String)"
            Write-Debug "Adapter is RoCE (3 or 4): $IsRoCE"

            $ID = "$($env:ComputerName) :: $($Intent.IntentName) :: Physical Switchport ($($dictionary[$Adapter]["SourceMac"]))"
            if (($PFCPriority | Where-Object Priority -eq $SMBPriority).Enabled -eq $false)
            {
                Write-EventLog  -LogName $logName `
                    -Source    $($config.PFCDisabled.Source) `
                    -EventID   $($config.PFCDisabled.EventID) `
                    -EntryType $($config.PFCDisabled.EntryType) `
                    -Message   $($LocMessage.$($config.PFCDisabled.MessageKey) -f $Adapter, $($env:ComputerName), $Intent.IntentName, $SMBPriority)


                $faultDescription = $LocMessage.$($config.MissingSMBPFCFaultDescriptionKey) -f $Adapter, $($env:ComputerName), $Intent.IntentName, $SMBPriority
                $faultAction      = $LocMessage.$($config.MissingSMBPFCFaultActionKey) -f $SMBPriority

                [Microsoft.NetworkHud.Module.HciHealthUtils]::HciModifyFault($config.EntityType, $ID, "", "", "", $FRApiActionModify, $config.FaultType, $HealthUrgencyUnHealthy, "", $faultDescription, $faultAction, 0)
                [Microsoft.NetworkHud.Module.HciHealthUtils]::HciModifyRelationship($config.EntityType, $ID, "", "", "", $FRApiActionModify, "Microsoft.Health.EntityType.Server", $env:COMPUTERNAME, "", "", "", $HealthRelationshipGroupKey, $HealthUrgencyUnHealthy, $HealthRelationshipCollection, 0)
            }
            else
            {
                [Microsoft.NetworkHud.Module.HciHealthUtils]::HciModifyFault($config.EntityType, $ID, "", "", "", $FRApiActionDelete, $config.FaultType, $HealthUrgencyUnHealthy, "", "", "", 0)
            }
        }
    }
}

# SIG # Begin signature block
# MIIoNwYJKoZIhvcNAQcCoIIoKDCCKCQCAQExDzANBglghkgBZQMEAgEFADB5Bgor
# BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG
# KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCBcPsA2mJM0K5wE
# jqNMcmUH/EyyuobT/9gsx4W7A/6REKCCDYUwggYDMIID66ADAgECAhMzAAADTU6R
# phoosHiPAAAAAANNMA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNVBAYTAlVTMRMwEQYD
# VQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNy
# b3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMTH01pY3Jvc29mdCBDb2RlIFNpZ25p
# bmcgUENBIDIwMTEwHhcNMjMwMzE2MTg0MzI4WhcNMjQwMzE0MTg0MzI4WjB0MQsw
# CQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9u
# ZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMR4wHAYDVQQDExVNaWNy
# b3NvZnQgQ29ycG9yYXRpb24wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
# AQDUKPcKGVa6cboGQU03ONbUKyl4WpH6Q2Xo9cP3RhXTOa6C6THltd2RfnjlUQG+
# Mwoy93iGmGKEMF/jyO2XdiwMP427j90C/PMY/d5vY31sx+udtbif7GCJ7jJ1vLzd
# j28zV4r0FGG6yEv+tUNelTIsFmmSb0FUiJtU4r5sfCThvg8dI/F9Hh6xMZoVti+k
# bVla+hlG8bf4s00VTw4uAZhjGTFCYFRytKJ3/mteg2qnwvHDOgV7QSdV5dWdd0+x
# zcuG0qgd3oCCAjH8ZmjmowkHUe4dUmbcZfXsgWlOfc6DG7JS+DeJak1DvabamYqH
# g1AUeZ0+skpkwrKwXTFwBRltAgMBAAGjggGCMIIBfjAfBgNVHSUEGDAWBgorBgEE
# AYI3TAgBBggrBgEFBQcDAzAdBgNVHQ4EFgQUId2Img2Sp05U6XI04jli2KohL+8w
# VAYDVR0RBE0wS6RJMEcxLTArBgNVBAsTJE1pY3Jvc29mdCBJcmVsYW5kIE9wZXJh
# dGlvbnMgTGltaXRlZDEWMBQGA1UEBRMNMjMwMDEyKzUwMDUxNzAfBgNVHSMEGDAW
# gBRIbmTlUAXTgqoXNzcitW2oynUClTBUBgNVHR8ETTBLMEmgR6BFhkNodHRwOi8v
# d3d3Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2NybC9NaWNDb2RTaWdQQ0EyMDExXzIw
# MTEtMDctMDguY3JsMGEGCCsGAQUFBwEBBFUwUzBRBggrBgEFBQcwAoZFaHR0cDov
# L3d3dy5taWNyb3NvZnQuY29tL3BraW9wcy9jZXJ0cy9NaWNDb2RTaWdQQ0EyMDEx
# XzIwMTEtMDctMDguY3J0MAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcNAQELBQADggIB
# ACMET8WuzLrDwexuTUZe9v2xrW8WGUPRQVmyJ1b/BzKYBZ5aU4Qvh5LzZe9jOExD
# YUlKb/Y73lqIIfUcEO/6W3b+7t1P9m9M1xPrZv5cfnSCguooPDq4rQe/iCdNDwHT
# 6XYW6yetxTJMOo4tUDbSS0YiZr7Mab2wkjgNFa0jRFheS9daTS1oJ/z5bNlGinxq
# 2v8azSP/GcH/t8eTrHQfcax3WbPELoGHIbryrSUaOCphsnCNUqUN5FbEMlat5MuY
# 94rGMJnq1IEd6S8ngK6C8E9SWpGEO3NDa0NlAViorpGfI0NYIbdynyOB846aWAjN
# fgThIcdzdWFvAl/6ktWXLETn8u/lYQyWGmul3yz+w06puIPD9p4KPiWBkCesKDHv
# XLrT3BbLZ8dKqSOV8DtzLFAfc9qAsNiG8EoathluJBsbyFbpebadKlErFidAX8KE
# usk8htHqiSkNxydamL/tKfx3V/vDAoQE59ysv4r3pE+zdyfMairvkFNNw7cPn1kH
# Gcww9dFSY2QwAxhMzmoM0G+M+YvBnBu5wjfxNrMRilRbxM6Cj9hKFh0YTwba6M7z
# ntHHpX3d+nabjFm/TnMRROOgIXJzYbzKKaO2g1kWeyG2QtvIR147zlrbQD4X10Ab
# rRg9CpwW7xYxywezj+iNAc+QmFzR94dzJkEPUSCJPsTFMIIHejCCBWKgAwIBAgIK
# YQ6Q0gAAAAAAAzANBgkqhkiG9w0BAQsFADCBiDELMAkGA1UEBhMCVVMxEzARBgNV
# BAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jv
# c29mdCBDb3Jwb3JhdGlvbjEyMDAGA1UEAxMpTWljcm9zb2Z0IFJvb3QgQ2VydGlm
# aWNhdGUgQXV0aG9yaXR5IDIwMTEwHhcNMTEwNzA4MjA1OTA5WhcNMjYwNzA4MjEw
# OTA5WjB+MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UE
# BxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSgwJgYD
# VQQDEx9NaWNyb3NvZnQgQ29kZSBTaWduaW5nIFBDQSAyMDExMIICIjANBgkqhkiG
# 9w0BAQEFAAOCAg8AMIICCgKCAgEAq/D6chAcLq3YbqqCEE00uvK2WCGfQhsqa+la
# UKq4BjgaBEm6f8MMHt03a8YS2AvwOMKZBrDIOdUBFDFC04kNeWSHfpRgJGyvnkmc
# 6Whe0t+bU7IKLMOv2akrrnoJr9eWWcpgGgXpZnboMlImEi/nqwhQz7NEt13YxC4D
# dato88tt8zpcoRb0RrrgOGSsbmQ1eKagYw8t00CT+OPeBw3VXHmlSSnnDb6gE3e+
# lD3v++MrWhAfTVYoonpy4BI6t0le2O3tQ5GD2Xuye4Yb2T6xjF3oiU+EGvKhL1nk
# kDstrjNYxbc+/jLTswM9sbKvkjh+0p2ALPVOVpEhNSXDOW5kf1O6nA+tGSOEy/S6
# A4aN91/w0FK/jJSHvMAhdCVfGCi2zCcoOCWYOUo2z3yxkq4cI6epZuxhH2rhKEmd
# X4jiJV3TIUs+UsS1Vz8kA/DRelsv1SPjcF0PUUZ3s/gA4bysAoJf28AVs70b1FVL
# 5zmhD+kjSbwYuER8ReTBw3J64HLnJN+/RpnF78IcV9uDjexNSTCnq47f7Fufr/zd
# sGbiwZeBe+3W7UvnSSmnEyimp31ngOaKYnhfsi+E11ecXL93KCjx7W3DKI8sj0A3
# T8HhhUSJxAlMxdSlQy90lfdu+HggWCwTXWCVmj5PM4TasIgX3p5O9JawvEagbJjS
# 4NaIjAsCAwEAAaOCAe0wggHpMBAGCSsGAQQBgjcVAQQDAgEAMB0GA1UdDgQWBBRI
# bmTlUAXTgqoXNzcitW2oynUClTAZBgkrBgEEAYI3FAIEDB4KAFMAdQBiAEMAQTAL
# BgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAWgBRyLToCMZBD
# uRQFTuHqp8cx0SOJNDBaBgNVHR8EUzBRME+gTaBLhklodHRwOi8vY3JsLm1pY3Jv
# c29mdC5jb20vcGtpL2NybC9wcm9kdWN0cy9NaWNSb29DZXJBdXQyMDExXzIwMTFf
# MDNfMjIuY3JsMF4GCCsGAQUFBwEBBFIwUDBOBggrBgEFBQcwAoZCaHR0cDovL3d3
# dy5taWNyb3NvZnQuY29tL3BraS9jZXJ0cy9NaWNSb29DZXJBdXQyMDExXzIwMTFf
# MDNfMjIuY3J0MIGfBgNVHSAEgZcwgZQwgZEGCSsGAQQBgjcuAzCBgzA/BggrBgEF
# BQcCARYzaHR0cDovL3d3dy5taWNyb3NvZnQuY29tL3BraW9wcy9kb2NzL3ByaW1h
# cnljcHMuaHRtMEAGCCsGAQUFBwICMDQeMiAdAEwAZQBnAGEAbABfAHAAbwBsAGkA
# YwB5AF8AcwB0AGEAdABlAG0AZQBuAHQALiAdMA0GCSqGSIb3DQEBCwUAA4ICAQBn
# 8oalmOBUeRou09h0ZyKbC5YR4WOSmUKWfdJ5DJDBZV8uLD74w3LRbYP+vj/oCso7
# v0epo/Np22O/IjWll11lhJB9i0ZQVdgMknzSGksc8zxCi1LQsP1r4z4HLimb5j0b
# pdS1HXeUOeLpZMlEPXh6I/MTfaaQdION9MsmAkYqwooQu6SpBQyb7Wj6aC6VoCo/
# KmtYSWMfCWluWpiW5IP0wI/zRive/DvQvTXvbiWu5a8n7dDd8w6vmSiXmE0OPQvy
# CInWH8MyGOLwxS3OW560STkKxgrCxq2u5bLZ2xWIUUVYODJxJxp/sfQn+N4sOiBp
# mLJZiWhub6e3dMNABQamASooPoI/E01mC8CzTfXhj38cbxV9Rad25UAqZaPDXVJi
# hsMdYzaXht/a8/jyFqGaJ+HNpZfQ7l1jQeNbB5yHPgZ3BtEGsXUfFL5hYbXw3MYb
# BL7fQccOKO7eZS/sl/ahXJbYANahRr1Z85elCUtIEJmAH9AAKcWxm6U/RXceNcbS
# oqKfenoi+kiVH6v7RyOA9Z74v2u3S5fi63V4GuzqN5l5GEv/1rMjaHXmr/r8i+sL
# gOppO6/8MO0ETI7f33VtY5E90Z1WTk+/gFcioXgRMiF670EKsT/7qMykXcGhiJtX
# cVZOSEXAQsmbdlsKgEhr/Xmfwb1tbWrJUnMTDXpQzTGCGggwghoEAgEBMIGVMH4x
# CzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRt
# b25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMTH01p
# Y3Jvc29mdCBDb2RlIFNpZ25pbmcgUENBIDIwMTECEzMAAANNTpGmGiiweI8AAAAA
# A00wDQYJYIZIAWUDBAIBBQCgga4wGQYJKoZIhvcNAQkDMQwGCisGAQQBgjcCAQQw
# HAYKKwYBBAGCNwIBCzEOMAwGCisGAQQBgjcCARUwLwYJKoZIhvcNAQkEMSIEINAr
# s4ijNhcv0x1vOgR1bzvouEzSKQ2I+mk26iTd5A/uMEIGCisGAQQBgjcCAQwxNDAy
# oBSAEgBNAGkAYwByAG8AcwBvAGYAdKEagBhodHRwOi8vd3d3Lm1pY3Jvc29mdC5j
# b20wDQYJKoZIhvcNAQEBBQAEggEA08KfHejxZg2bDpSrRtYM8NIUyk9fKErpRJJK
# I8m5aYcvuOXLG1eIIAu6mKUyn77koDgR04rw0BlLpDzicHzqkTbruKo8IyFz+xmY
# 2TEk+ksnFDtu5vS4DhRoCaJeVKyf8PBx5FfgTjmQ8m1Qgo4M/IlyEW5whM2CucjE
# +FDCcBWFD9eB03LJ4Wf8H26+dvyfDDOPDvfUUkeSxUK42XuZnkgNFr3zYSZlNu40
# xQDTnIp/g+CEBURMH1GeMXTiR3VMlMIOauN1Qp5gfujeKYnG6CW1Us2JOzsBicx8
# 9NQuKSBj0dzicNpa1FJWZSj2q0IlPuglMt0I8WAnIJqiy0/ixqGCF5IwgheOBgor
# BgEEAYI3AwMBMYIXfjCCF3oGCSqGSIb3DQEHAqCCF2swghdnAgEDMQ8wDQYJYIZI
# AWUDBAIBBQAwggFQBgsqhkiG9w0BCRABBKCCAT8EggE7MIIBNwIBAQYKKwYBBAGE
# WQoDATAxMA0GCWCGSAFlAwQCAQUABCAbxOY0bv9jZ3NA1Pao6iQAtrNXGQycHFX5
# h4RHu69cvwIGZSiz0XILGBEyMDIzMTAxOTIzNTkxOC4xWjAEgAIB9KCB0aSBzjCB
# yzELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1Jl
# ZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjElMCMGA1UECxMc
# TWljcm9zb2Z0IEFtZXJpY2EgT3BlcmF0aW9uczEnMCUGA1UECxMeblNoaWVsZCBU
# U1MgRVNOOjMzMDMtMDVFMC1EOTQ3MSUwIwYDVQQDExxNaWNyb3NvZnQgVGltZS1T
# dGFtcCBTZXJ2aWNloIIR6jCCByAwggUIoAMCAQICEzMAAAHMhqXcN+vZYS0AAQAA
# AcwwDQYJKoZIhvcNAQELBQAwfDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hp
# bmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jw
# b3JhdGlvbjEmMCQGA1UEAxMdTWljcm9zb2Z0IFRpbWUtU3RhbXAgUENBIDIwMTAw
# HhcNMjMwNTI1MTkxMjAxWhcNMjQwMjAxMTkxMjAxWjCByzELMAkGA1UEBhMCVVMx
# EzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoT
# FU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjElMCMGA1UECxMcTWljcm9zb2Z0IEFtZXJp
# Y2EgT3BlcmF0aW9uczEnMCUGA1UECxMeblNoaWVsZCBUU1MgRVNOOjMzMDMtMDVF
# MC1EOTQ3MSUwIwYDVQQDExxNaWNyb3NvZnQgVGltZS1TdGFtcCBTZXJ2aWNlMIIC
# IjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAzLEiBfHvTZhHPvNzVWRoFlmY
# v8AWLfM4cQH0hjO8cOyuwmwP9QOBoaLz75CGPO97Z8s3cmXvumB18fkXetfJUA5p
# puV+HromBudy3e1iCvg3focotB/ew+hzOGcxqqL5sAdH2d5YfqYSS6D0/vcq0yxc
# 5JCsNlXG+8FzAc4g9DFVWG5sEZUWsqU57Zd/SBDQhIo1vY+jBJU8lz9s63NDrYUD
# eUazE2OYmY2tzMhwhZmDBop5h37bGht2HYvBmvAUI3baE5uXVYZ6rNqijRDqmUqJ
# 9vEeF339LZSS+VB8iN28sB//s0HibvKp7EgovFRTzrGRG+nGc4Vx2gIkhrXSgG0E
# WgCIRMWyFKXicqQu5fsKigtwTvQAxrqQfWYFBW0r+RAhYzA8235vDOc89gOMWDT0
# F6mb9MBli/o072+5BWIgzz3vs0cgW85q0qTmwe16o6s1BTSpcKfjMdeZNRexTLOR
# DNrhuvCELHQBgZGW0g5rhpoz22e3bYpvlx7odzUuiZl2D0u64pKQm1LDGTJ+XlsY
# lhSJOn9NLJEeES1podDejqvimCNXwOfS8xogGzq3MYL0JEaNzg+KNSVvc9UzTMBG
# 5Mz61zKPK6xrLhqMmFnLJvcYXdBlyERxwuuJ82yN3tBuY6hLFkHOLmkHkkcq+9Ck
# Yo81clo42H7BLb1TJScCAwEAAaOCAUkwggFFMB0GA1UdDgQWBBSCphxkXTyHS0V7
# bEeV0UsjN/tpDDAfBgNVHSMEGDAWgBSfpxVdAF5iXYP05dJlpxtTNRnpcjBfBgNV
# HR8EWDBWMFSgUqBQhk5odHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2Ny
# bC9NaWNyb3NvZnQlMjBUaW1lLVN0YW1wJTIwUENBJTIwMjAxMCgxKS5jcmwwbAYI
# KwYBBQUHAQEEYDBeMFwGCCsGAQUFBzAChlBodHRwOi8vd3d3Lm1pY3Jvc29mdC5j
# b20vcGtpb3BzL2NlcnRzL01pY3Jvc29mdCUyMFRpbWUtU3RhbXAlMjBQQ0ElMjAy
# MDEwKDEpLmNydDAMBgNVHRMBAf8EAjAAMBYGA1UdJQEB/wQMMAoGCCsGAQUFBwMI
# MA4GA1UdDwEB/wQEAwIHgDANBgkqhkiG9w0BAQsFAAOCAgEAeRlDKPV74lJd4O9r
# vKEE6KyCg6AHYFmeC0PfnQBEApmnrbE4ZMWzZtebHruxpsKWXYTEDfEzXXRpIubO
# SHvmgNlRKPb2c99ZZbrBwVwFa0Labn0KrSAPtp57rH2mL4ora+qeZFU+tPSyEzmI
# HSkVhKX8f+Mk+UfcjHisaMZJPLchohj2SuNEk+WdeDj3SX1W5GHgr5S0HJbF9flg
# WTcf12b2syZl472I07htEG2accOGTt2aH30GMWWEc59M+NVOzAxZV6NooX2rHWx7
# rmupKR8SfQCKFHr4d5s71MWKdLtM98GAz6S7qPjNlWIfFzglAdLu+cRt0ufvfEyp
# hW6mWIKYK+j/mCnmqNmKQdYs7POdGEs7sGl+5EcQFEZZjf4+R7+MGm5zn2W9+pg6
# iaeCHhpsD7cCPLRD7LkQJsq3no8oZGVe3X4CeDfN0AYaR1WZQeBZpSUfMhd2gdeU
# FurcOAmh/jzCA7nehnjiTuHEBPpU3OqyCZjeHH4tk0xu3uPU74Ql3wUtqczsm/WH
# pkptJK5PIyYes4Hhqs7ZO83sHxPt7IUEXO+LFy2OfKb1aM534Hxr8tZZW6uDnsve
# iqLsIroQ7cbipU51u6cO8WjT4SDLDsVvHaUqfdeRbSnzqikf3XyTrGxw0iWP4oic
# +JligBqMnXizOsy5qIUQj1pP0OYwggdxMIIFWaADAgECAhMzAAAAFcXna54Cm0mZ
# AAAAAAAVMA0GCSqGSIb3DQEBCwUAMIGIMQswCQYDVQQGEwJVUzETMBEGA1UECBMK
# V2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0
# IENvcnBvcmF0aW9uMTIwMAYDVQQDEylNaWNyb3NvZnQgUm9vdCBDZXJ0aWZpY2F0
# ZSBBdXRob3JpdHkgMjAxMDAeFw0yMTA5MzAxODIyMjVaFw0zMDA5MzAxODMyMjVa
# MHwxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdS
# ZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xJjAkBgNVBAMT
# HU1pY3Jvc29mdCBUaW1lLVN0YW1wIFBDQSAyMDEwMIICIjANBgkqhkiG9w0BAQEF
# AAOCAg8AMIICCgKCAgEA5OGmTOe0ciELeaLL1yR5vQ7VgtP97pwHB9KpbE51yMo1
# V/YBf2xK4OK9uT4XYDP/XE/HZveVU3Fa4n5KWv64NmeFRiMMtY0Tz3cywBAY6GB9
# alKDRLemjkZrBxTzxXb1hlDcwUTIcVxRMTegCjhuje3XD9gmU3w5YQJ6xKr9cmmv
# Haus9ja+NSZk2pg7uhp7M62AW36MEBydUv626GIl3GoPz130/o5Tz9bshVZN7928
# jaTjkY+yOSxRnOlwaQ3KNi1wjjHINSi947SHJMPgyY9+tVSP3PoFVZhtaDuaRr3t
# pK56KTesy+uDRedGbsoy1cCGMFxPLOJiss254o2I5JasAUq7vnGpF1tnYN74kpEe
# HT39IM9zfUGaRnXNxF803RKJ1v2lIH1+/NmeRd+2ci/bfV+AutuqfjbsNkz2K26o
# ElHovwUDo9Fzpk03dJQcNIIP8BDyt0cY7afomXw/TNuvXsLz1dhzPUNOwTM5TI4C
# vEJoLhDqhFFG4tG9ahhaYQFzymeiXtcodgLiMxhy16cg8ML6EgrXY28MyTZki1ug
# poMhXV8wdJGUlNi5UPkLiWHzNgY1GIRH29wb0f2y1BzFa/ZcUlFdEtsluq9QBXps
# xREdcu+N+VLEhReTwDwV2xo3xwgVGD94q0W29R6HXtqPnhZyacaue7e3PmriLq0C
# AwEAAaOCAd0wggHZMBIGCSsGAQQBgjcVAQQFAgMBAAEwIwYJKwYBBAGCNxUCBBYE
# FCqnUv5kxJq+gpE8RjUpzxD/LwTuMB0GA1UdDgQWBBSfpxVdAF5iXYP05dJlpxtT
# NRnpcjBcBgNVHSAEVTBTMFEGDCsGAQQBgjdMg30BATBBMD8GCCsGAQUFBwIBFjNo
# dHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpb3BzL0RvY3MvUmVwb3NpdG9yeS5o
# dG0wEwYDVR0lBAwwCgYIKwYBBQUHAwgwGQYJKwYBBAGCNxQCBAweCgBTAHUAYgBD
# AEEwCwYDVR0PBAQDAgGGMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAU1fZW
# y4/oolxiaNE9lJBb186aGMQwVgYDVR0fBE8wTTBLoEmgR4ZFaHR0cDovL2NybC5t
# aWNyb3NvZnQuY29tL3BraS9jcmwvcHJvZHVjdHMvTWljUm9vQ2VyQXV0XzIwMTAt
# MDYtMjMuY3JsMFoGCCsGAQUFBwEBBE4wTDBKBggrBgEFBQcwAoY+aHR0cDovL3d3
# dy5taWNyb3NvZnQuY29tL3BraS9jZXJ0cy9NaWNSb29DZXJBdXRfMjAxMC0wNi0y
# My5jcnQwDQYJKoZIhvcNAQELBQADggIBAJ1VffwqreEsH2cBMSRb4Z5yS/ypb+pc
# FLY+TkdkeLEGk5c9MTO1OdfCcTY/2mRsfNB1OW27DzHkwo/7bNGhlBgi7ulmZzpT
# Td2YurYeeNg2LpypglYAA7AFvonoaeC6Ce5732pvvinLbtg/SHUB2RjebYIM9W0j
# VOR4U3UkV7ndn/OOPcbzaN9l9qRWqveVtihVJ9AkvUCgvxm2EhIRXT0n4ECWOKz3
# +SmJw7wXsFSFQrP8DJ6LGYnn8AtqgcKBGUIZUnWKNsIdw2FzLixre24/LAl4FOmR
# sqlb30mjdAy87JGA0j3mSj5mO0+7hvoyGtmW9I/2kQH2zsZ0/fZMcm8Qq3UwxTSw
# ethQ/gpY3UA8x1RtnWN0SCyxTkctwRQEcb9k+SS+c23Kjgm9swFXSVRk2XPXfx5b
# RAGOWhmRaw2fpCjcZxkoJLo4S5pu+yFUa2pFEUep8beuyOiJXk+d0tBMdrVXVAmx
# aQFEfnyhYWxz/gq77EFmPWn9y8FBSX5+k77L+DvktxW/tM4+pTFRhLy/AsGConsX
# HRWJjXD+57XQKBqJC4822rpM+Zv/Cuk0+CQ1ZyvgDbjmjJnW4SLq8CdCPSWU5nR0
# W2rRnj7tfqAxM328y+l7vzhwRNGQ8cirOoo6CGJ/2XBjU02N7oJtpQUQwXEGahC0
# HVUzWLOhcGbyoYIDTTCCAjUCAQEwgfmhgdGkgc4wgcsxCzAJBgNVBAYTAlVTMRMw
# EQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVN
# aWNyb3NvZnQgQ29ycG9yYXRpb24xJTAjBgNVBAsTHE1pY3Jvc29mdCBBbWVyaWNh
# IE9wZXJhdGlvbnMxJzAlBgNVBAsTHm5TaGllbGQgVFNTIEVTTjozMzAzLTA1RTAt
# RDk0NzElMCMGA1UEAxMcTWljcm9zb2Z0IFRpbWUtU3RhbXAgU2VydmljZaIjCgEB
# MAcGBSsOAwIaAxUATk7md7mH4ooUuM0U6MYrA7fZiaSggYMwgYCkfjB8MQswCQYD
# VQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEe
# MBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSYwJAYDVQQDEx1NaWNyb3Nv
# ZnQgVGltZS1TdGFtcCBQQ0EgMjAxMDANBgkqhkiG9w0BAQsFAAIFAOjbw9QwIhgP
# MjAyMzEwMTkxNTAzNDhaGA8yMDIzMTAyMDE1MDM0OFowdDA6BgorBgEEAYRZCgQB
# MSwwKjAKAgUA6NvD1AIBADAHAgEAAgIzRDAHAgEAAgITADAKAgUA6N0VVAIBADA2
# BgorBgEEAYRZCgQCMSgwJjAMBgorBgEEAYRZCgMCoAowCAIBAAIDB6EgoQowCAIB
# AAIDAYagMA0GCSqGSIb3DQEBCwUAA4IBAQBxz4U5HKixVaYyNLCgCsFNh9T6wqyb
# RHuUc87aG7EoGIrhBUmBrLB+TZ/Muif13QyeNL6W/81JLN+QVYEjlQMBnKROIOfi
# d7wLGm1sEEDjmCbj0wsJ/euOT5aIMf5lwccMetjqEtCzBQEKX8ecL7HRsDN3PPHy
# t0qpWZm2fBne+Y5RUr99R1Pb5Bdx76QOAW9dY8gXYWk6u8/wUbmnWZmhJemmCDFY
# 8j9bMjBGn1wMtR5wpzqcKAfbALEMDy0MfslNNyIjE0vgWZOug0OaMP4I1YHKqmNx
# wuB4+bFkd2CbuqzV/QHkWHaGW60sxGDfFxVquqq9reGFZoWNIPZs6GA1MYIEDTCC
# BAkCAQEwgZMwfDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAO
# BgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEm
# MCQGA1UEAxMdTWljcm9zb2Z0IFRpbWUtU3RhbXAgUENBIDIwMTACEzMAAAHMhqXc
# N+vZYS0AAQAAAcwwDQYJYIZIAWUDBAIBBQCgggFKMBoGCSqGSIb3DQEJAzENBgsq
# hkiG9w0BCRABBDAvBgkqhkiG9w0BCQQxIgQgs6fF/6yZko0fSrp/OjGRVI8Q7C3N
# cS2tur68a7YX2IMwgfoGCyqGSIb3DQEJEAIvMYHqMIHnMIHkMIG9BCDW7mUBwv7D
# AhPnIClUpMCqQyAn53nxWWIA2xeB63BY5jCBmDCBgKR+MHwxCzAJBgNVBAYTAlVT
# MRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQK
# ExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xJjAkBgNVBAMTHU1pY3Jvc29mdCBUaW1l
# LVN0YW1wIFBDQSAyMDEwAhMzAAABzIal3Dfr2WEtAAEAAAHMMCIEIDxwv7vJ3ps+
# yTYtFdk4IyVLEVBNikJfXHl2Azz6Xn+eMA0GCSqGSIb3DQEBCwUABIICAI7P8ReK
# xn2zM8B0sMC9YsNLdSYP7MEDftbwn+OV0JFfhcISpntasvJ+YIE6ZwIjmLxDzvJg
# kXU8ADgKnPNBfPXiPU3V+PQPh+Sgfml37/J31x+X2+FYmpnK9N3oXcb3EQYQYI/L
# 3PdZOUtHNzxmU+Evy5T3jmiwY1Za1TVUDgYcMdSZNGriX21dr4isdn4yjye0BHIV
# 78Bts5SCU5pMCIVsa7FKFM39YyKNOMjLJDxwpq8JSHWOKKuJkHlQxBaEaWbW2QqI
# WnylMweBzL+aDTTLAwiTqzxjGa7h5ZPOK6qwb9cL/hhrscRlJT9SOVwSsGv1B7cJ
# iH0poKWIkwtcc5SrflaBfhroSTBn5Y4o16A9oxfR5ibPNCEi6PfNm5mGs5SvvUgE
# 0Tyy43dFWMib1hWlQNWz00pVN5yvu5X40yOJ74+sXZEGBf7BJ9hlLZiba7DdFWz4
# pgYnRcKseR43FKlF0ZQYKYeBxuwcL4M7jjo7neyvhV2hooBYK65/i+xDHEEpHnci
# DBcNFEjjKfCtnKJAe/ryXvTzIW29I4SG6EtTl1i6JajXUWg3HjRy3JrSJLJ9v7Xe
# Ca/+9P8zs8M06Ngry4n+IO39xx3wnTGGVdDAbL0ZOuXuRQ29h8wijJuVBt8h6aEu
# IqTX0HzAe0V2xalJG38+RKhAZsXZqa4Tytko
# SIG # End signature block