public/Edit-GkSeAzSentinelWatchlist.ps1

<#
.SYNOPSIS
Modify a watchlist item by item
 
.DESCRIPTION
Modify a existing watchlist and create it if necessary. Existing values are only overwritten when the SearchKey matches.
Using tags as identifiers orphaned entries can also be removed
 
.PARAMETER NewWatchlistItems
A hashtable that represents the new watchlist items
 
.PARAMETER SearchKey
Define the SearchKey column for the watchlist
 
.PARAMETER WatchListName
Name of the watchlist. Will also be used as Alias
 
.PARAMETER SubscriptionId
Subscription of the Sentinel workspace
 
.PARAMETER ResourceGroupName
Resource Group of the Sentinel workspace
 
.PARAMETER WorkspaceName
The name of the Sentinel workspace
 
.PARAMETER Identifiers
A array of tags that will be used to remove any items that no longer exists in the NewWatchlistItems object.
Only if all the definied tags are present and watchlist items SearchKey cannot be found in the NewWatchlistItems object the watchlist item will be removed
 
.PARAMETER OverrideTags
Overwrite existing tags with new tags. Default is to merge tags.
 
.EXAMPLE
$Params = @{
    SearchKey = "IP Subnet"
    WatchListName = $WatchListName
    NewWatchlistItems = $NewWatchlistItems
    SubscriptionId = $SubscriptionId
    ResourceGroupName = $ResourceGroupName
    WorkspaceName = $WorkspaceName
    Identifiers = @("Entra ID", "Automated Enrichment" )
}
Edit-GkSeAzSentinelWatchlist -Verbose @Params
 
.NOTES
General notes
#>

function Edit-GkSeAzSentinelWatchlist {
    [CmdletBinding()]
    param (
        [Parameter(Mandatory)]
        [Array]$NewWatchlistItems,

        # Which field of the watchlist should be used to
        [Parameter(Mandatory)]
        [Alias("itemsSearchKey")]
        [string]$SearchKey,

        # Watchlist name
        [Alias("WatchListName")]
        [Parameter(Mandatory)]
        [string]$DisplayName,

        # Watchlist alias
        [Parameter()]
        [string]$WatchListAlias,

        [Parameter(Mandatory)]
        [string]$SubscriptionId,

        [Parameter(Mandatory)]
        [string]$ResourceGroupName,

        [Parameter(Mandatory)]
        [string]$WorkspaceName,

        [Parameter()]
        [string[]]$Identifiers,

        [Parameter()]
        [switch]$OverrideTags,

        [Parameter()]
        [string]$Provider = "glueckkanja"
    )

    process {

        if ( [string]::IsNullOrWhiteSpace($WatchlistAlias) ) {
            $WatchlistAlias = Get-GkSeValidWatchlistAlias -WatchListName $DisplayName
        } else {
            $WatchlistAlias = Get-GkSeValidWatchlistAlias -WatchListName $WatchlistAlias
        }

        if ( $WatchlistAlias -in @("HighValueAssets", "IdentityCorrelation", "NetworkAddresses", "ServiceAccounts", "TerminatedEmployees", "VIPUsers") ) {
            $Provider = "Microsoft"
        } else {
            $Provider = $Provider
        }

        # Apply correct formating of watchlist items
        if ( "itemsKeyValue" -notin $NewWatchlistItems.properties.Keys ) {
            $WatchlistItems = New-Object System.Collections.ArrayList
            foreach ($NewWatchlistItem in $NewWatchlistItems) {
                $CurrentItem = @{
                    properties = @{
                        "itemsKeyValue" = $NewWatchlistItem
                    }
                }
                $WatchlistItems.Add($CurrentItem) | Out-Null
            }
            $NewWatchlistItems = $WatchlistItems
        }

        #region Get all current watchlist items
        try {
            $Param1 = @{
                WatchListName     = $WatchlistAlias
                SubscriptionId    = $SubscriptionId
                ResourceGroupName = $ResourceGroupName
                WorkspaceName     = $WorkspaceName
            }
            $CurrentWatchlistItems = Get-GkSeAzSentinelWatchlist @Param1 -ErrorAction Stop
        } catch {
            Write-Verbose "Could not get current watchlist items. Try to create a new watchlist."
            $Watchlist = @{
                "properties" = @{
                    "displayName"    = $DisplayName
                    "itemsSearchKey" = $SearchKey
                    "provider"       = $Provider
                    "watchlistAlias" = $WatchlistAlias
                }
            }
            Write-Verbose ( $Watchlist | ConvertTo-Json -Depth 99 | Out-String )
            $Uri = 'https://management.azure.com/subscriptions/{0}/resourceGroups/{1}/providers/Microsoft.OperationalInsights/workspaces/{2}/providers/Microsoft.SecurityInsights/watchlists/{3}?api-version=2022-01-01-preview' -f $SubscriptionId, $ResourceGroupName, $WorkspaceName, $WatchlistAlias
            $Result = Invoke-AzRestMethod -Method PUT -Uri $Uri -Payload ( $Watchlist | ConvertTo-Json -Depth 99)
            Write-Verbose ($Result | Out-String)
            if ( $Result.StatusCode -eq 200 ) {
                Write-Verbose "New watchlist with name $WatchListName ($WatchlistAlias) created"
                $CurrentWatchlistItems = Get-GkSeAzSentinelWatchlist @Param1
            } else {
                throw
            }

        }
        #endregion

        # Check if tags are present and must be updated
        try {
            if ( "Tags" -in $CurrentWatchlistItems[0].itemsKeyValue.PSObject.Properties.Name ) {
                $UpdateCurrentTags = $true
            } else {
                $UpdateCurrentTags = $false
            }
        } catch {
            $UpdateCurrentTags = $false
        }

        $ChangedOrNewWatchlistEntries = New-Object System.Collections.ArrayList
        foreach ($TmpWatchlistItem in $NewWatchlistItems) {
            # Don't override the original items
            $NewWatchlistItem = Get-DeepClone $TmpWatchlistItem
            $ResultBasedOnSearchKey = $NewWatchlistItem.properties.itemsKeyValue.$SearchKey
            $WatchlistItem = $CurrentWatchlistItems | Where-Object { $_.itemsKeyValue.$SearchKey -eq $ResultBasedOnSearchKey }
            Write-Verbose ($WatchlistItem | Out-String)
            if ( $null -eq $WatchlistItem ) {
                $WatchlistItemId = New-Guid | Select-Object -ExpandProperty Guid
                Write-Verbose "No current watchlist item found, create new one ($WatchlistItemId)"
                $CurrentTags = $null
            } else {
                $WatchlistItemId = $WatchlistItem.watchlistItemId
                Write-Verbose "Watchlist item matching the search key found ($WatchlistItemId)"
                try {
                    $CurrentTags = $WatchlistItem.itemsKeyValue.Tags | ConvertFrom-Json -ErrorAction Stop
                } catch {
                    $CurrentTags = $null
                }
            }
            # Add tags if needed
            if ($UpdateCurrentTags) {
                $NewTags = $NewWatchlistItem.properties.itemsKeyValue.Tags
                # Must be declared as arrays to avoid a single string
                if ($OverrideTags) {
                    $Tags = @($NewTags) | Sort-Object | Select-Object -Unique
                } else {
                    $Tags = @($CurrentTags) + @($NewTags) | Sort-Object | Select-Object -Unique
                }
                $NewWatchlistItem.properties.itemsKeyValue.Tags = $Tags | ConvertTo-Json -Compress
            } else {
                # Make sure if there are any tag in the new watchlist items, that they are written
                if ( -not ( [string]::IsNullOrWhiteSpace($NewWatchlistItem.properties.itemsKeyValue.Tags) )) {
                    $NewWatchlistItem.properties.itemsKeyValue.Tags = $NewWatchlistItem.properties.itemsKeyValue.Tags | ConvertTo-Json -Compress
                }
            }
            # Set new watchlist Id
            $NewWatchlistItem.properties.watchlistItemId = $WatchlistItemId
            $ChangedOrNewWatchlistEntries.Add($WatchlistItemId) | Out-Null
            Write-Verbose ( $NewWatchlistItem | ConvertTo-Json -Depth 99 | Out-String )

            $RowEntryJson = $NewWatchlistItem | ConvertTo-Json -Depth 10 -Compress
            $RowEntrySize = [System.Text.Encoding]::ASCII.GetByteCount($RowEntryJson)
            if ($RowEntrySize -gt "10000") {
                Write-Warning "$($WatchlistItem.watchlistItemId) with exceeded entry size of 10 KB and will be skipped!"
            } else {
                $Uri = 'https://management.azure.com/subscriptions/{0}/resourceGroups/{1}/providers/Microsoft.OperationalInsights/workspaces/{2}/providers/Microsoft.SecurityInsights/watchlists/{3}/watchlistitems/{4}?api-version=2023-07-01-preview' -f $SubscriptionId, $ResourceGroupName, $WorkspaceName, $WatchlistAlias, $WatchListItemId
                Write-Verbose $Uri
                $Result = Invoke-AzRestMethod -Method PUT -Uri $Uri -Payload ( $NewWatchlistItem | ConvertTo-Json -Depth 99)
                Write-Verbose ($Result | Out-String)
            }
        }

        if ( -not [string]::IsNullOrWhiteSpace($Identifiers) ) {
            # Remove orphaned entries
            foreach ($WatchlistItem in $CurrentWatchlistItems) {
                if ($WatchlistItem.watchlistItemId -in $ChangedOrNewWatchlistEntries) {
                    # Do nothing, this entry was already updated
                    Write-Verbose "$($WatchlistItem.watchlistItemId) was already modified. Nothing to to"
                    Continue
                }

                try {
                    $Tags = $WatchlistItem.itemsKeyValue.Tags | ConvertFrom-Json -ErrorAction Stop
                } catch {
                    Write-Verbose "$($WatchlistItem.watchlistItemId) has not tags. Can't decide if to remove"
                    Continue
                }

                try {
                    if ([string]::IsNullOrWhiteSpace($Tags)) {
                        Write-Verbose "$($WatchlistItem.watchlistItemId) has not tags. Can't decide if to remove"
                        Continue
                    }
                    $CompareIdentifiers = Compare-Object -ReferenceObject $Identifiers -DifferenceObject $Tags -ErrorAction Stop | Where-Object { $_.SideIndicator -eq "<=" }
                    if ( $null -ne $CompareIdentifiers ) {
                        Write-Verbose "$($WatchlistItem.watchlistItemId) has not all identifier tag. Can't decide if to remove"
                        Continue
                    }
                } catch {
                    Write-Verbose "$($WatchlistItem.watchlistItemId) error when comparing. Can't decide if to remove"
                    Continue
                }

                # All identifiers matched but the item was not part of the updated group
                # Remove this orphaned watchlist item
                $Uri = 'https://management.azure.com/subscriptions/{0}/resourceGroups/{1}/providers/Microsoft.OperationalInsights/workspaces/{2}/providers/Microsoft.SecurityInsights/watchlists/{3}/watchlistitems/{4}?api-version=2023-07-01-preview' -f $SubscriptionId, $ResourceGroupName, $WorkspaceName, $WatchlistAlias, $WatchlistItem.watchlistItemId
                Write-Verbose "$($WatchlistItem.watchlistItemId) is no longer part of the configuration. Will be removed."
                Write-Verbose ($WatchlistItem | Format-List | out-string)
                $Result = Invoke-AzRestMethod -Method DELETE -Uri $Uri
                Write-Verbose ($Result | Out-String)
            }
        }
    }
}
# SIG # Begin signature block
# MIIvUQYJKoZIhvcNAQcCoIIvQjCCLz4CAQExDzANBglghkgBZQMEAgEFADB5Bgor
# BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG
# KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCDx8Z4G1CEAIws0
# GUPeg76oXXePQhV4y5BUKyJ10ENTkqCCFDUwggWQMIIDeKADAgECAhAFmxtXno4h
# MuI5B72nd3VcMA0GCSqGSIb3DQEBDAUAMGIxCzAJBgNVBAYTAlVTMRUwEwYDVQQK
# EwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xITAfBgNV
# BAMTGERpZ2lDZXJ0IFRydXN0ZWQgUm9vdCBHNDAeFw0xMzA4MDExMjAwMDBaFw0z
# ODAxMTUxMjAwMDBaMGIxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJ
# bmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xITAfBgNVBAMTGERpZ2lDZXJ0
# IFRydXN0ZWQgUm9vdCBHNDCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIB
# AL/mkHNo3rvkXUo8MCIwaTPswqclLskhPfKK2FnC4SmnPVirdprNrnsbhA3EMB/z
# G6Q4FutWxpdtHauyefLKEdLkX9YFPFIPUh/GnhWlfr6fqVcWWVVyr2iTcMKyunWZ
# anMylNEQRBAu34LzB4TmdDttceItDBvuINXJIB1jKS3O7F5OyJP4IWGbNOsFxl7s
# Wxq868nPzaw0QF+xembud8hIqGZXV59UWI4MK7dPpzDZVu7Ke13jrclPXuU15zHL
# 2pNe3I6PgNq2kZhAkHnDeMe2scS1ahg4AxCN2NQ3pC4FfYj1gj4QkXCrVYJBMtfb
# BHMqbpEBfCFM1LyuGwN1XXhm2ToxRJozQL8I11pJpMLmqaBn3aQnvKFPObURWBf3
# JFxGj2T3wWmIdph2PVldQnaHiZdpekjw4KISG2aadMreSx7nDmOu5tTvkpI6nj3c
# AORFJYm2mkQZK37AlLTSYW3rM9nF30sEAMx9HJXDj/chsrIRt7t/8tWMcCxBYKqx
# YxhElRp2Yn72gLD76GSmM9GJB+G9t+ZDpBi4pncB4Q+UDCEdslQpJYls5Q5SUUd0
# viastkF13nqsX40/ybzTQRESW+UQUOsxxcpyFiIJ33xMdT9j7CFfxCBRa2+xq4aL
# T8LWRV+dIPyhHsXAj6KxfgommfXkaS+YHS312amyHeUbAgMBAAGjQjBAMA8GA1Ud
# EwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBTs1+OC0nFdZEzf
# Lmc/57qYrhwPTzANBgkqhkiG9w0BAQwFAAOCAgEAu2HZfalsvhfEkRvDoaIAjeNk
# aA9Wz3eucPn9mkqZucl4XAwMX+TmFClWCzZJXURj4K2clhhmGyMNPXnpbWvWVPjS
# PMFDQK4dUPVS/JA7u5iZaWvHwaeoaKQn3J35J64whbn2Z006Po9ZOSJTROvIXQPK
# 7VB6fWIhCoDIc2bRoAVgX+iltKevqPdtNZx8WorWojiZ83iL9E3SIAveBO6Mm0eB
# cg3AFDLvMFkuruBx8lbkapdvklBtlo1oepqyNhR6BvIkuQkRUNcIsbiJeoQjYUIp
# 5aPNoiBB19GcZNnqJqGLFNdMGbJQQXE9P01wI4YMStyB0swylIQNCAmXHE/A7msg
# dDDS4Dk0EIUhFQEI6FUy3nFJ2SgXUE3mvk3RdazQyvtBuEOlqtPDBURPLDab4vri
# RbgjU2wGb2dVf0a1TD9uKFp5JtKkqGKX0h7i7UqLvBv9R0oN32dmfrJbQdA75PQ7
# 9ARj6e/CVABRoIoqyc54zNXqhwQYs86vSYiv85KZtrPmYQ/ShQDnUBrkG5WdGaG5
# nLGbsQAe79APT0JsyQq87kP6OnGlyE0mpTX9iV28hWIdMtKgK1TtmlfB2/oQzxm3
# i0objwG2J5VT6LaJbVu8aNQj6ItRolb58KaAoNYes7wPD1N1KarqE3fk3oyBIa0H
# EEcRrYc9B9F1vM/zZn4wggawMIIEmKADAgECAhAIrUCyYNKcTJ9ezam9k67ZMA0G
# CSqGSIb3DQEBDAUAMGIxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJ
# bmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xITAfBgNVBAMTGERpZ2lDZXJ0
# IFRydXN0ZWQgUm9vdCBHNDAeFw0yMTA0MjkwMDAwMDBaFw0zNjA0MjgyMzU5NTla
# MGkxCzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5EaWdpQ2VydCwgSW5jLjFBMD8GA1UE
# AxM4RGlnaUNlcnQgVHJ1c3RlZCBHNCBDb2RlIFNpZ25pbmcgUlNBNDA5NiBTSEEz
# ODQgMjAyMSBDQTEwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDVtC9C
# 0CiteLdd1TlZG7GIQvUzjOs9gZdwxbvEhSYwn6SOaNhc9es0JAfhS0/TeEP0F9ce
# 2vnS1WcaUk8OoVf8iJnBkcyBAz5NcCRks43iCH00fUyAVxJrQ5qZ8sU7H/Lvy0da
# E6ZMswEgJfMQ04uy+wjwiuCdCcBlp/qYgEk1hz1RGeiQIXhFLqGfLOEYwhrMxe6T
# SXBCMo/7xuoc82VokaJNTIIRSFJo3hC9FFdd6BgTZcV/sk+FLEikVoQ11vkunKoA
# FdE3/hoGlMJ8yOobMubKwvSnowMOdKWvObarYBLj6Na59zHh3K3kGKDYwSNHR7Oh
# D26jq22YBoMbt2pnLdK9RBqSEIGPsDsJ18ebMlrC/2pgVItJwZPt4bRc4G/rJvmM
# 1bL5OBDm6s6R9b7T+2+TYTRcvJNFKIM2KmYoX7BzzosmJQayg9Rc9hUZTO1i4F4z
# 8ujo7AqnsAMrkbI2eb73rQgedaZlzLvjSFDzd5Ea/ttQokbIYViY9XwCFjyDKK05
# huzUtw1T0PhH5nUwjewwk3YUpltLXXRhTT8SkXbev1jLchApQfDVxW0mdmgRQRNY
# mtwmKwH0iU1Z23jPgUo+QEdfyYFQc4UQIyFZYIpkVMHMIRroOBl8ZhzNeDhFMJlP
# /2NPTLuqDQhTQXxYPUez+rbsjDIJAsxsPAxWEQIDAQABo4IBWTCCAVUwEgYDVR0T
# AQH/BAgwBgEB/wIBADAdBgNVHQ4EFgQUaDfg67Y7+F8Rhvv+YXsIiGX0TkIwHwYD
# VR0jBBgwFoAU7NfjgtJxXWRM3y5nP+e6mK4cD08wDgYDVR0PAQH/BAQDAgGGMBMG
# A1UdJQQMMAoGCCsGAQUFBwMDMHcGCCsGAQUFBwEBBGswaTAkBggrBgEFBQcwAYYY
# aHR0cDovL29jc3AuZGlnaWNlcnQuY29tMEEGCCsGAQUFBzAChjVodHRwOi8vY2Fj
# ZXJ0cy5kaWdpY2VydC5jb20vRGlnaUNlcnRUcnVzdGVkUm9vdEc0LmNydDBDBgNV
# HR8EPDA6MDigNqA0hjJodHRwOi8vY3JsMy5kaWdpY2VydC5jb20vRGlnaUNlcnRU
# cnVzdGVkUm9vdEc0LmNybDAcBgNVHSAEFTATMAcGBWeBDAEDMAgGBmeBDAEEATAN
# BgkqhkiG9w0BAQwFAAOCAgEAOiNEPY0Idu6PvDqZ01bgAhql+Eg08yy25nRm95Ry
# sQDKr2wwJxMSnpBEn0v9nqN8JtU3vDpdSG2V1T9J9Ce7FoFFUP2cvbaF4HZ+N3HL
# IvdaqpDP9ZNq4+sg0dVQeYiaiorBtr2hSBh+3NiAGhEZGM1hmYFW9snjdufE5Btf
# Q/g+lP92OT2e1JnPSt0o618moZVYSNUa/tcnP/2Q0XaG3RywYFzzDaju4ImhvTnh
# OE7abrs2nfvlIVNaw8rpavGiPttDuDPITzgUkpn13c5UbdldAhQfQDN8A+KVssIh
# dXNSy0bYxDQcoqVLjc1vdjcshT8azibpGL6QB7BDf5WIIIJw8MzK7/0pNVwfiThV
# 9zeKiwmhywvpMRr/LhlcOXHhvpynCgbWJme3kuZOX956rEnPLqR0kq3bPKSchh/j
# wVYbKyP/j7XqiHtwa+aguv06P0WmxOgWkVKLQcBIhEuWTatEQOON8BUozu3xGFYH
# Ki8QxAwIZDwzj64ojDzLj4gLDb879M4ee47vtevLt/B3E+bnKD+sEq6lLyJsQfmC
# XBVmzGwOysWGw/YmMwwHS6DTBwJqakAwSEs0qFEgu60bhQjiWQ1tygVQK+pKHJ6l
# /aCnHwZ05/LWUpD9r4VIIflXO7ScA+2GRfS0YW6/aOImYIbqyK+p/pQd52MbOoZW
# eE4wggfpMIIF0aADAgECAhAE0w/ewLw2E3KQ6RwmFyT5MA0GCSqGSIb3DQEBCwUA
# MGkxCzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5EaWdpQ2VydCwgSW5jLjFBMD8GA1UE
# AxM4RGlnaUNlcnQgVHJ1c3RlZCBHNCBDb2RlIFNpZ25pbmcgUlNBNDA5NiBTSEEz
# ODQgMjAyMSBDQTEwHhcNMjMxMTE2MDAwMDAwWhcNMjYxMTE1MjM1OTU5WjCB8TET
# MBEGCysGAQQBgjc8AgEDEwJERTEXMBUGCysGAQQBgjc8AgECEwZIZXNzZW4xIjAg
# BgsrBgEEAYI3PAIBARMRT2ZmZW5iYWNoIGFtIE1haW4xHTAbBgNVBA8MFFByaXZh
# dGUgT3JnYW5pemF0aW9uMRIwEAYDVQQFEwlIUkIgMTIzODExCzAJBgNVBAYTAkRF
# MQ8wDQYDVQQIEwZIZXNzZW4xGjAYBgNVBAcTEU9mZmVuYmFjaCBhbSBNYWluMRcw
# FQYDVQQKEw5nbHVlY2trYW5qYSBBRzEXMBUGA1UEAxMOZ2x1ZWNra2FuamEgQUcw
# ggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDOkzyWiAT0dzoCrdo4dTaE
# UjIJKcht/Gvb3OOJ/WpNQYJius0XbgOcyBu+7+yGANG0SKDbGxuy8gl6FDMkMKXS
# g4ukpw2GLeMNATJ+MBd5FL3MwTSyZS0SljlAbIdyo7ydBeCNrCqKsJoBLARTdxSu
# fsxRtgsEOM3AqkT51Z+oSb3fOpAvG3E6fj6ViQP2C37m3t9LvCzNJO6TQ94ylKFg
# WxOLmHlBnvBEK6wLsL3FRWl0avXTNvheH7XmY7vI9Othb469+V+FJVBbmD7SE0f5
# miAND4wpNGObz76r2TsHFcgTHah8EGKTJeo0+m3AM158ILT2cN35v8z7X4RbJ7L5
# k4eMFNoWKwPc72UPZKdlo0OQuutL5ehtFhopnB7WUUFCNV4+KQGYo9cKEeufGqV0
# xrIcdH409ejAuMleNZ4CLyU5LE5qVkYxLgdjDdCdxbk2ADSTOwQtpLJExnhf/jkc
# 9sRTys9i6NtpE+hb6xbAJ7p4vQt3iLMDQHy6l98HNJNlmY3Phvk0ViUIzRC7qgv7
# Fe+5bE6FkFc/J4rrx6AUTJek/WvkhbvJp39IvspHUxTYC34l9y8Dcnxk3XU2TASn
# JR6yKElD+OetRKE0rS9VcuL7kJrTY9det5Kv1hzoZj3zPqd5X+cqqV5hzE3aI3TP
# 1v0zICGYf5ayeA1zg9aCkQIDAQABo4ICAjCCAf4wHwYDVR0jBBgwFoAUaDfg67Y7
# +F8Rhvv+YXsIiGX0TkIwHQYDVR0OBBYEFOTb7LJoGHhU5+5fcQSNJKUzQX0kMD0G
# A1UdIAQ2MDQwMgYFZ4EMAQMwKTAnBggrBgEFBQcCARYbaHR0cDovL3d3dy5kaWdp
# Y2VydC5jb20vQ1BTMA4GA1UdDwEB/wQEAwIHgDATBgNVHSUEDDAKBggrBgEFBQcD
# AzCBtQYDVR0fBIGtMIGqMFOgUaBPhk1odHRwOi8vY3JsMy5kaWdpY2VydC5jb20v
# RGlnaUNlcnRUcnVzdGVkRzRDb2RlU2lnbmluZ1JTQTQwOTZTSEEzODQyMDIxQ0Ex
# LmNybDBToFGgT4ZNaHR0cDovL2NybDQuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0VHJ1
# c3RlZEc0Q29kZVNpZ25pbmdSU0E0MDk2U0hBMzg0MjAyMUNBMS5jcmwwgZQGCCsG
# AQUFBwEBBIGHMIGEMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdpY2VydC5j
# b20wXAYIKwYBBQUHMAKGUGh0dHA6Ly9jYWNlcnRzLmRpZ2ljZXJ0LmNvbS9EaWdp
# Q2VydFRydXN0ZWRHNENvZGVTaWduaW5nUlNBNDA5NlNIQTM4NDIwMjFDQTEuY3J0
# MAkGA1UdEwQCMAAwDQYJKoZIhvcNAQELBQADggIBAMkcpd3bsp6QPtw6hZFySq8n
# 50F0KYvrGH0MnQipkz7lV5RvFjl/cBf5gRSrebMIV1rvQMttrFxC06Y3zTbU6t4E
# z1nDX76GZV7bmomreROITlH43UvsYacedTmiPp+SFDF5hjDz71XHaATzaSSL5puE
# GRrGCyEh2Y/tw823jtk7jDLZrjb74kbGIB21/uUkjOWkhNGN55rDa933sjJuoZx2
# /pVSSmHxo+Bvc3td67EY4ylZj4CsBHmr6afeGKtZFT/QtnilYq+5nARiCDVKSHP0
# svNpmOCDZJg+aaq+TBAtvu6ddAogZ4FHtpOFQ+NQZeO9jWNn/9bYDdBlwejQKPqZ
# 0p3oO+25FyYe8dxr1j82TyefL4mC486nVbSSk3XCu+LUKRmMkOh8cSKXyIP06RIz
# LWQSpS1zenI+DREJ6VJHI/pBhRZGr9i6gwOIVaKva2t/AnaCkI4ulJd8iq6/lI+z
# DvuLPjRqQOv2+Zf+1jbNV2I0BttmiFfXGDeAOCEaiF82lak6CcwkrGj3Hbt7YjuF
# Zd7qCJWHG4pVrpJhwEScp+1+kDLpWGlupiPJv4XDhKUEqJPQ2KGhMzE0JDd8V7Si
# 4gXvAoEZAPb1sjLcatDHYJX1acsAHEoYD2Um1Lx0pARy4LcHsTPrETz4EiiGg/iE
# qeoXQDjtJraR++BTJXQyMYIacjCCGm4CAQEwfTBpMQswCQYDVQQGEwJVUzEXMBUG
# A1UEChMORGlnaUNlcnQsIEluYy4xQTA/BgNVBAMTOERpZ2lDZXJ0IFRydXN0ZWQg
# RzQgQ29kZSBTaWduaW5nIFJTQTQwOTYgU0hBMzg0IDIwMjEgQ0ExAhAE0w/ewLw2
# E3KQ6RwmFyT5MA0GCWCGSAFlAwQCAQUAoIGEMBgGCisGAQQBgjcCAQwxCjAIoAKA
# AKECgAAwGQYJKoZIhvcNAQkDMQwGCisGAQQBgjcCAQQwHAYKKwYBBAGCNwIBCzEO
# MAwGCisGAQQBgjcCARUwLwYJKoZIhvcNAQkEMSIEIPHcfDJEDLhcn0ATbPS98n2G
# 0jEfcjG1hGgZ4c9vl+DRMA0GCSqGSIb3DQEBAQUABIICADkRD7lq+qjNDqoDeTPc
# ecw9Suy0NT6fe10/8Rlrky2O4wREINwds0dU81Z+IO4N1IAu0dvEUMa3Vo5XC/+G
# WdMzzs52n+FXfiLqsJsnEIsknDlS/tz+9vMDpVpCQGVD6JhrWqBa1PMWlqrw/OFv
# yuUPUGEpZ0JCThpo9uxhxxlAKxXRfktVVJ1v/1wHabdly1zHMel4whgzx5gtQMUB
# E/4HodWEs+BpRiqZGr3ZoBTaH0chvsDv8sH/3SpNQ8igDcmCM7XDI0ehWTRqyE5C
# AwsIyClt6Ui6cBBz/nzLOY2vMRcNMT6NVC4AQGgxVJEUebpOl/XCOrWEs0xFIkT7
# nzouRpr22ZgpDlbdmMQ9yhjXwnrOY5jA1I37gnyJWyoAXXWOtgBqTaFQYgExGiGa
# hXl8q7perGYFpc0yo5sgKiq8XUWsm0TR3/E1EhgmLBMLo4NrhmgxKDd8i6i7EPix
# AYp4mM4nTpJiYHoliUiJoJV/hrvS1gTt/JtC415xZ+VzDrVP0eLeJRavH9elppph
# c6eQUT7O9rs2asqa+jxPlv9d4UMevCxBdnv6HpdLxRYm0ng3uUcpRkolYlbad7lZ
# GsQKoM25AqVEWsFvTD5Ql8ZmL9iR6vZvLJWB6Jgz7RsVBHJxEnDBjadApelFaEfg
# FVe3b9GR+RGtvM3735uh12BDoYIXPzCCFzsGCisGAQQBgjcDAwExghcrMIIXJwYJ
# KoZIhvcNAQcCoIIXGDCCFxQCAQMxDzANBglghkgBZQMEAgEFADB3BgsqhkiG9w0B
# CRABBKBoBGYwZAIBAQYJYIZIAYb9bAcBMDEwDQYJYIZIAWUDBAIBBQAEILHyIbWQ
# 4m08KapVXvWY9Lrde9fhuzWRq+pv+K130ngoAhBUQ8xdUWxF9KiIOnIEgfxpGA8y
# MDIzMTIxODA4MDQxOFqgghMJMIIGwjCCBKqgAwIBAgIQBUSv85SdCDmmv9s/X+Vh
# FjANBgkqhkiG9w0BAQsFADBjMQswCQYDVQQGEwJVUzEXMBUGA1UEChMORGlnaUNl
# cnQsIEluYy4xOzA5BgNVBAMTMkRpZ2lDZXJ0IFRydXN0ZWQgRzQgUlNBNDA5NiBT
# SEEyNTYgVGltZVN0YW1waW5nIENBMB4XDTIzMDcxNDAwMDAwMFoXDTM0MTAxMzIz
# NTk1OVowSDELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDkRpZ2lDZXJ0LCBJbmMuMSAw
# HgYDVQQDExdEaWdpQ2VydCBUaW1lc3RhbXAgMjAyMzCCAiIwDQYJKoZIhvcNAQEB
# BQADggIPADCCAgoCggIBAKNTRYcdg45brD5UsyPgz5/X5dLnXaEOCdwvSKOXejsq
# nGfcYhVYwamTEafNqrJq3RApih5iY2nTWJw1cb86l+uUUI8cIOrHmjsvlmbjaedp
# /lvD1isgHMGXlLSlUIHyz8sHpjBoyoNC2vx/CSSUpIIa2mq62DvKXd4ZGIX7ReoN
# YWyd/nFexAaaPPDFLnkPG2ZS48jWPl/aQ9OE9dDH9kgtXkV1lnX+3RChG4PBuOZS
# lbVH13gpOWvgeFmX40QrStWVzu8IF+qCZE3/I+PKhu60pCFkcOvV5aDaY7Mu6QXu
# qvYk9R28mxyyt1/f8O52fTGZZUdVnUokL6wrl76f5P17cz4y7lI0+9S769SgLDSb
# 495uZBkHNwGRDxy1Uc2qTGaDiGhiu7xBG3gZbeTZD+BYQfvYsSzhUa+0rRUGFOpi
# CBPTaR58ZE2dD9/O0V6MqqtQFcmzyrzXxDtoRKOlO0L9c33u3Qr/eTQQfqZcClhM
# AD6FaXXHg2TWdc2PEnZWpST618RrIbroHzSYLzrqawGw9/sqhux7UjipmAmhcbJs
# ca8+uG+W1eEQE/5hRwqM/vC2x9XH3mwk8L9CgsqgcT2ckpMEtGlwJw1Pt7U20clf
# CKRwo+wK8REuZODLIivK8SgTIUlRfgZm0zu++uuRONhRB8qUt+JQofM604qDy0B7
# AgMBAAGjggGLMIIBhzAOBgNVHQ8BAf8EBAMCB4AwDAYDVR0TAQH/BAIwADAWBgNV
# HSUBAf8EDDAKBggrBgEFBQcDCDAgBgNVHSAEGTAXMAgGBmeBDAEEAjALBglghkgB
# hv1sBwEwHwYDVR0jBBgwFoAUuhbZbU2FL3MpdpovdYxqII+eyG8wHQYDVR0OBBYE
# FKW27xPn783QZKHVVqllMaPe1eNJMFoGA1UdHwRTMFEwT6BNoEuGSWh0dHA6Ly9j
# cmwzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydFRydXN0ZWRHNFJTQTQwOTZTSEEyNTZU
# aW1lU3RhbXBpbmdDQS5jcmwwgZAGCCsGAQUFBwEBBIGDMIGAMCQGCCsGAQUFBzAB
# hhhodHRwOi8vb2NzcC5kaWdpY2VydC5jb20wWAYIKwYBBQUHMAKGTGh0dHA6Ly9j
# YWNlcnRzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydFRydXN0ZWRHNFJTQTQwOTZTSEEy
# NTZUaW1lU3RhbXBpbmdDQS5jcnQwDQYJKoZIhvcNAQELBQADggIBAIEa1t6gqbWY
# F7xwjU+KPGic2CX/yyzkzepdIpLsjCICqbjPgKjZ5+PF7SaCinEvGN1Ott5s1+Fg
# nCvt7T1IjrhrunxdvcJhN2hJd6PrkKoS1yeF844ektrCQDifXcigLiV4JZ0qBXqE
# KZi2V3mP2yZWK7Dzp703DNiYdk9WuVLCtp04qYHnbUFcjGnRuSvExnvPnPp44pMa
# dqJpddNQ5EQSviANnqlE0PjlSXcIWiHFtM+YlRpUurm8wWkZus8W8oM3NG6wQSbd
# 3lqXTzON1I13fXVFoaVYJmoDRd7ZULVQjK9WvUzF4UbFKNOt50MAcN7MmJ4ZiQPq
# 1JE3701S88lgIcRWR+3aEUuMMsOI5ljitts++V+wQtaP4xeR0arAVeOGv6wnLEHQ
# mjNKqDbUuXKWfpd5OEhfysLcPTLfddY2Z1qJ+Panx+VPNTwAvb6cKmx5AdzaROY6
# 3jg7B145WPR8czFVoIARyxQMfq68/qTreWWqaNYiyjvrmoI1VygWy2nyMpqy0tg6
# uLFGhmu6F/3Ed2wVbK6rr3M66ElGt9V/zLY4wNjsHPW2obhDLN9OTH0eaHDAdwrU
# AuBcYLso/zjlUlrWrBciI0707NMX+1Br/wd3H3GXREHJuEbTbDJ8WC9nR2XlG3O2
# mflrLAZG70Ee8PBf4NvZrZCARK+AEEGKMIIGrjCCBJagAwIBAgIQBzY3tyRUfNhH
# rP0oZipeWzANBgkqhkiG9w0BAQsFADBiMQswCQYDVQQGEwJVUzEVMBMGA1UEChMM
# RGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSEwHwYDVQQD
# ExhEaWdpQ2VydCBUcnVzdGVkIFJvb3QgRzQwHhcNMjIwMzIzMDAwMDAwWhcNMzcw
# MzIyMjM1OTU5WjBjMQswCQYDVQQGEwJVUzEXMBUGA1UEChMORGlnaUNlcnQsIElu
# Yy4xOzA5BgNVBAMTMkRpZ2lDZXJ0IFRydXN0ZWQgRzQgUlNBNDA5NiBTSEEyNTYg
# VGltZVN0YW1waW5nIENBMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA
# xoY1BkmzwT1ySVFVxyUDxPKRN6mXUaHW0oPRnkyibaCwzIP5WvYRoUQVQl+kiPNo
# +n3znIkLf50fng8zH1ATCyZzlm34V6gCff1DtITaEfFzsbPuK4CEiiIY3+vaPcQX
# f6sZKz5C3GeO6lE98NZW1OcoLevTsbV15x8GZY2UKdPZ7Gnf2ZCHRgB720RBidx8
# ald68Dd5n12sy+iEZLRS8nZH92GDGd1ftFQLIWhuNyG7QKxfst5Kfc71ORJn7w6l
# Y2zkpsUdzTYNXNXmG6jBZHRAp8ByxbpOH7G1WE15/tePc5OsLDnipUjW8LAxE6lX
# KZYnLvWHpo9OdhVVJnCYJn+gGkcgQ+NDY4B7dW4nJZCYOjgRs/b2nuY7W+yB3iIU
# 2YIqx5K/oN7jPqJz+ucfWmyU8lKVEStYdEAoq3NDzt9KoRxrOMUp88qqlnNCaJ+2
# RrOdOqPVA+C/8KI8ykLcGEh/FDTP0kyr75s9/g64ZCr6dSgkQe1CvwWcZklSUPRR
# 8zZJTYsg0ixXNXkrqPNFYLwjjVj33GHek/45wPmyMKVM1+mYSlg+0wOI/rOP015L
# dhJRk8mMDDtbiiKowSYI+RQQEgN9XyO7ZONj4KbhPvbCdLI/Hgl27KtdRnXiYKNY
# CQEoAA6EVO7O6V3IXjASvUaetdN2udIOa5kM0jO0zbECAwEAAaOCAV0wggFZMBIG
# A1UdEwEB/wQIMAYBAf8CAQAwHQYDVR0OBBYEFLoW2W1NhS9zKXaaL3WMaiCPnshv
# MB8GA1UdIwQYMBaAFOzX44LScV1kTN8uZz/nupiuHA9PMA4GA1UdDwEB/wQEAwIB
# hjATBgNVHSUEDDAKBggrBgEFBQcDCDB3BggrBgEFBQcBAQRrMGkwJAYIKwYBBQUH
# MAGGGGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBBBggrBgEFBQcwAoY1aHR0cDov
# L2NhY2VydHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0VHJ1c3RlZFJvb3RHNC5jcnQw
# QwYDVR0fBDwwOjA4oDagNIYyaHR0cDovL2NybDMuZGlnaWNlcnQuY29tL0RpZ2lD
# ZXJ0VHJ1c3RlZFJvb3RHNC5jcmwwIAYDVR0gBBkwFzAIBgZngQwBBAIwCwYJYIZI
# AYb9bAcBMA0GCSqGSIb3DQEBCwUAA4ICAQB9WY7Ak7ZvmKlEIgF+ZtbYIULhsBgu
# EE0TzzBTzr8Y+8dQXeJLKftwig2qKWn8acHPHQfpPmDI2AvlXFvXbYf6hCAlNDFn
# zbYSlm/EUExiHQwIgqgWvalWzxVzjQEiJc6VaT9Hd/tydBTX/6tPiix6q4XNQ1/t
# YLaqT5Fmniye4Iqs5f2MvGQmh2ySvZ180HAKfO+ovHVPulr3qRCyXen/KFSJ8NWK
# cXZl2szwcqMj+sAngkSumScbqyQeJsG33irr9p6xeZmBo1aGqwpFyd/EjaDnmPv7
# pp1yr8THwcFqcdnGE4AJxLafzYeHJLtPo0m5d2aR8XKc6UsCUqc3fpNTrDsdCEkP
# lM05et3/JWOZJyw9P2un8WbDQc1PtkCbISFA0LcTJM3cHXg65J6t5TRxktcma+Q4
# c6umAU+9Pzt4rUyt+8SVe+0KXzM5h0F4ejjpnOHdI/0dKNPH+ejxmF/7K9h+8kad
# dSweJywm228Vex4Ziza4k9Tm8heZWcpw8De/mADfIBZPJ/tgZxahZrrdVcA6KYaw
# mKAr7ZVBtzrVFZgxtGIJDwq9gdkT/r+k0fNX2bwE+oLeMt8EifAAzV3C+dAjfwAL
# 5HYCJtnwZXZCpimHCUcr5n8apIUP/JiW9lVUKx+A+sDyDivl1vupL0QVSucTDh3b
# NzgaoSv27dZ8/DCCBY0wggR1oAMCAQICEA6bGI750C3n79tQ4ghAGFowDQYJKoZI
# hvcNAQEMBQAwZTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZ
# MBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTEkMCIGA1UEAxMbRGlnaUNlcnQgQXNz
# dXJlZCBJRCBSb290IENBMB4XDTIyMDgwMTAwMDAwMFoXDTMxMTEwOTIzNTk1OVow
# YjELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQ
# d3d3LmRpZ2ljZXJ0LmNvbTEhMB8GA1UEAxMYRGlnaUNlcnQgVHJ1c3RlZCBSb290
# IEc0MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAv+aQc2jeu+RdSjww
# IjBpM+zCpyUuySE98orYWcLhKac9WKt2ms2uexuEDcQwH/MbpDgW61bGl20dq7J5
# 8soR0uRf1gU8Ug9SH8aeFaV+vp+pVxZZVXKvaJNwwrK6dZlqczKU0RBEEC7fgvMH
# hOZ0O21x4i0MG+4g1ckgHWMpLc7sXk7Ik/ghYZs06wXGXuxbGrzryc/NrDRAX7F6
# Zu53yEioZldXn1RYjgwrt0+nMNlW7sp7XeOtyU9e5TXnMcvak17cjo+A2raRmECQ
# ecN4x7axxLVqGDgDEI3Y1DekLgV9iPWCPhCRcKtVgkEy19sEcypukQF8IUzUvK4b
# A3VdeGbZOjFEmjNAvwjXWkmkwuapoGfdpCe8oU85tRFYF/ckXEaPZPfBaYh2mHY9
# WV1CdoeJl2l6SPDgohIbZpp0yt5LHucOY67m1O+SkjqePdwA5EUlibaaRBkrfsCU
# tNJhbesz2cXfSwQAzH0clcOP9yGyshG3u3/y1YxwLEFgqrFjGESVGnZifvaAsPvo
# ZKYz0YkH4b235kOkGLimdwHhD5QMIR2yVCkliWzlDlJRR3S+Jqy2QXXeeqxfjT/J
# vNNBERJb5RBQ6zHFynIWIgnffEx1P2PsIV/EIFFrb7GrhotPwtZFX50g/KEexcCP
# orF+CiaZ9eRpL5gdLfXZqbId5RsCAwEAAaOCATowggE2MA8GA1UdEwEB/wQFMAMB
# Af8wHQYDVR0OBBYEFOzX44LScV1kTN8uZz/nupiuHA9PMB8GA1UdIwQYMBaAFEXr
# oq/0ksuCMS1Ri6enIZ3zbcgPMA4GA1UdDwEB/wQEAwIBhjB5BggrBgEFBQcBAQRt
# MGswJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBDBggrBgEF
# BQcwAoY3aHR0cDovL2NhY2VydHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJl
# ZElEUm9vdENBLmNydDBFBgNVHR8EPjA8MDqgOKA2hjRodHRwOi8vY3JsMy5kaWdp
# Y2VydC5jb20vRGlnaUNlcnRBc3N1cmVkSURSb290Q0EuY3JsMBEGA1UdIAQKMAgw
# BgYEVR0gADANBgkqhkiG9w0BAQwFAAOCAQEAcKC/Q1xV5zhfoKN0Gz22Ftf3v1cH
# vZqsoYcs7IVeqRq7IviHGmlUIu2kiHdtvRoU9BNKei8ttzjv9P+Aufih9/Jy3iS8
# UgPITtAq3votVs/59PesMHqai7Je1M/RQ0SbQyHrlnKhSLSZy51PpwYDE3cnRNTn
# f+hZqPC/Lwum6fI0POz3A8eHqNJMQBk1RmppVLC4oVaO7KTVPeix3P0c2PR3WlxU
# jG/voVA9/HYJaISfb8rbII01YBwCA8sgsKxYoA5AY8WYIsGyWfVVa88nq2x2zm8j
# LfR+cWojayL/ErhULSd+2DrZ8LaHlv1b0VysGMNNn3O3AamfV6peKOK5lDGCA3Yw
# ggNyAgEBMHcwYzELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDkRpZ2lDZXJ0LCBJbmMu
# MTswOQYDVQQDEzJEaWdpQ2VydCBUcnVzdGVkIEc0IFJTQTQwOTYgU0hBMjU2IFRp
# bWVTdGFtcGluZyBDQQIQBUSv85SdCDmmv9s/X+VhFjANBglghkgBZQMEAgEFAKCB
# 0TAaBgkqhkiG9w0BCQMxDQYLKoZIhvcNAQkQAQQwHAYJKoZIhvcNAQkFMQ8XDTIz
# MTIxODA4MDQxOFowKwYLKoZIhvcNAQkQAgwxHDAaMBgwFgQUZvArMsLCyQ+CXc6q
# isnGTxmcz0AwLwYJKoZIhvcNAQkEMSIEIHI3dc863Sj6vvfyBg3ubfQe8kYtE04a
# q/8F1HAxn081MDcGCyqGSIb3DQEJEAIvMSgwJjAkMCIEINL25G3tdCLM0dRAV2hB
# Nm+CitpVmq4zFq9NGprUDHgoMA0GCSqGSIb3DQEBAQUABIICAA59SBhvgFLXDg2s
# RUQHnFcJNK6GGE4dTiigiy/c+EgLGUKgacXFBFU2aynPUaM2E6hFzVDLGn5dvXao
# sl0q5drueuoyBOw3K7KH2vlKRlK+FOmFdfsw8kU1wSt174p5udzy4HbQ0d58yMpQ
# eTnyDZPAajYCkm3MsOU1N1e0Mj7NFyVfh1IbZxpBf8vxEFanRsDbac3ooVERQQhu
# V6mV2Pq3AfResln9TEWPU4TlE0OMXsel9bxp+a1OacRa1zxIzXmZaFcgc9ZiHPgu
# PMmODMnXFL0F8KrCxUZMMnkh9BwBr6atOP4F51cb0wOHYJFqWUIEaszNJE32eatq
# SynQEZYfrRLaV1FT0mpEJSekl1mzWsd3dYtMZie6cYq4Q+VZqvJVeRsXtGegB5uo
# iyMYjtFyfelRpNUtXqbIf86wI4ChCb14vn0Ho7KSiVjN6kJPXSahrqFmlBuIl5LS
# JjKh1LrAZLXuJYdUbAPYihlaio4HtkbS7X2NNp+ukfcLCcROuDDHEBugyPcwzC8E
# Gb4JXwj6C/qk3uBNAFKavotezgRDVSrtU93l+x9gHy+x1smFC9/t4BUK2wbmNu1H
# FPuJzKeSURMBkZ/HPxYlGj/her6EUdUzUnM4ya2XvtTXWNi/TFNgJkCgDReLsDcB
# D/9SpQnK0zb4wJ1cyI+RQx+18u+q
# SIG # End signature block