Bin/ADSyncDiagnostics/PSScripts/ADSyncDiagnosticsUtils.ps1

#-------------------------------------------------------------------------
# Copyright (c) Microsoft Corporation. All rights reserved.
#-------------------------------------------------------------------------

#
# Returns given date-time by locale 'en-us'
#
Function Global:GetDateTimeLocaleEnUs
{
    param
    (
        [DateTime]
        [parameter(mandatory=$true)]
        $DateTime
    )

    $culture = New-Object System.Globalization.CultureInfo 'en-us'
    $dateTime = $($DateTime.ToUniversalTime()).ToString($culture)

    Write-Output $dateTime
}

#
# Emit events in order to track usage and problems through ADHealth
#
Function Global:WriteEventLog
{
    param
    (
        [int]
        [parameter(mandatory=$true)]
        $EventId,

        [string]
        [parameter(mandatory=$true)]
        $Message
    )

    Write-EventLog -LogName "Application" -Source "Directory Synchronization" -EventID $EventId -EntryType Information -Message $Message -Category 0
}

Function Global:GetValidADForestCredentials
{
    param
    (
        [string]
        [parameter(mandatory=$true)]
        $ADForestName
    )

    while ($true)
    {
        $ADForestCredential = Get-Credential -Message "Please enter credentials for an AD account that has permissions to read all attributes on the target object. Use the fully qualified domain name of the account (Example: CONTOSO\admin):"
        $networkCredential = $ADForestCredential.GetNetworkCredential()

        if ($networkCredential.UserName.Contains("@") -or $networkCredential.Domain.ToString() -eq "")
        {
            "Credential should use the fully qualified domain name of the account. Example: CONTOSO\admin" | Write-Host -fore Red
            Write-Host "`r`n"
        } else {
            try
            {
                $credentialTestContext = New-Object System.DirectoryServices.ActiveDirectory.DirectoryContext([System.DirectoryServices.ActiveDirectory.DirectoryContextType]::Forest, $ADForestName, $ADForestCredential.UserName, $networkCredential.Password)
                $credentialTestForest = [System.DirectoryServices.ActiveDirectory.Forest]::GetForest($credentialTestContext)
                return $ADForestCredential
            }
            catch
            {
                "Invalid Credentials. Details: $($_.Exception.Message)" | Write-Host -fore Red
                Write-Host "`r`n"
            }
        }

        $retryCredentialOptions = [System.Management.Automation.Host.ChoiceDescription[]] @("&Provide credentials", "&Back to previous")
        $retryCredential = !($host.UI.PromptForChoice("Credentials Invalid", "Provide credentials again or return to previous menu?", $retryCredentialOptions, 0))

        if (!$retryCredential)
        {
            return $null
        }
    }
}

Function Global:GetADConnectors
{
    $adConnectors = Get-ADSyncConnector | Where-Object {$_.ConnectorTypeName -eq "AD"}
    Write-Output $adConnectors
}

Function Global:GetADConnectorByName
{
    param
    (
        [string]
        [parameter(mandatory=$false)]
        [AllowNull()]
        $ADConnectorName,

        [string]
        [parameter(mandatory=$false)]
        $PromptMessage
    )

    while ([string]::IsNullOrEmpty($ADConnectorName))
    {
        $adConnectors = GetADConnectors
        if ($adConnectors -eq $null)
        {
            "No AD Connector is found." | ReportError
            Write-Host "`r`n"
            $ADConnectorName = $null
            return
        }

        Write-Host "`r`n"

        Write-Host "List of AD Connectors:"
        Write-Host "----------------------"

        foreach ($adConnector in $adConnectors)
        {
            Write-Host $adConnector.Name
        }

        if ($adConnectors.length -eq 1)
        {
            $ADConnectorName = $adConnectors[0].Name
        }
        else
        {
            Write-Host "`r`n"

            $ADConnectorName = Read-Host $PromptMessage
        }
    }

    $adConnector = Get-ADSyncConnector | Where-Object {($_.ConnectorTypeName -eq "AD") -and ($_.Name -eq $ADConnectorName)}
    Write-Output $adConnector
}

Function Global:GetAADConnector
{
   $aadConnectors = Get-ADSyncConnector | Where-Object {$_.Identifier -eq "b891884f-051e-4a83-95af-2544101c9083"}

   if ($aadConnectors -eq $null)
   {
        Write-Output $null
   }
   else
   {
        Write-Output $aadConnectors[0]
   }
}

Function Global:GetAADTenantName
{
    param
    (
        [Microsoft.IdentityManagement.PowerShell.ObjectModel.Connector]
        [parameter(mandatory=$true)]
        $AADConnector
    )

    $aadConnectorUserName = $AADConnector.ConnectivityParameters["UserName"].Value
    $aadTenantName = $($aadConnectorUserName.Split('@'))[1]

    Write-Output $aadTenantName
}

Function Global:GetCSObject
{
    param
    (
        [string]
        [parameter(mandatory=$true)]
        $ConnectorName,

        [string]
        [parameter(mandatory=$true)]
        $DistinguishedName
    )

    Try
    {
        $csObject = Get-ADSyncCSObject -ConnectorName $ConnectorName -DistinguishedName $DistinguishedName
        Write-Output $csObject
    }
    Catch
    {
        Write-Output $null
    }
}

Function Global:GetCSObjectByIdentifier
{
    param
    (
        [Guid]
        [parameter(mandatory=$true)]
        $CsObjectId
    )

    Try
    {
        $csObject = Get-ADSyncCSObject -Identifier $CsObjectId
        Write-Output $csObject
    }
    Catch
    {
        Write-Output $null
    }
}

Function Global:GetMVObjectByIdentifier
{
    param
    (
        [Guid]
        [parameter(mandatory=$true)]
        $MvObjectId
    )

    Try
    {
        $mvObject = Get-ADSyncMVObject -Identifier $MvObjectId
        Write-Output $mvObject
    }
    Catch
    {
        Write-Output $null
    }
}

Function Global:GetTargetCSObjectId
{
    param
    (
        [Microsoft.IdentityManagement.PowerShell.ObjectModel.MvObject]
        [parameter(mandatory=$true)]
        $MvObject,

        [Guid]
        [parameter(mandatory=$true)]
        $TargetConnectorId
    )

    foreach ($mvObjectLink in $MvObject.Lineage)
    {
        if ($mvObjectLink.ConnectorId -eq $TargetConnectorId)
        {
            Write-Output $mvObjectLink.ConnectedCsObjectId
            return
        }
    }

    Write-Output $null
}

Function Global:IsStagingModeEnabled
{
    $isStagingModeEnabled = $false
    $globalParameters = Get-ADSyncGlobalSettingsParameter
    $stagingModeGlobalParameter = $globalParameters | Where-Object {$_.Name -eq "Microsoft.Synchronize.StagingMode"}

    if ($stagingModeGlobalParameter -ne $null)
    {
        $isStagingModeEnabled = $stagingModeGlobalParameter.Value
    }

    Write-Output $isStagingModeEnabled
}

Function Global:ConvertADObjectToHashTable
{
    param
    (
        [System.Collections.Generic.Dictionary[[String], [Object]]]
        [parameter(mandatory=$true)]
        $AdObject,

        [bool]
        [parameter(mandatory=$false)]
        $AllAttributes
    )

    $ADObjectHashTable = @{}

    if ($AllAttributes)
    {
        foreach ($attributeName in $AdObject.Keys)
        {
            $attributeValues = [System.Collections.ArrayList] $AdObject[$attributeName]

            $ADObjectHashTable[$attributeName] = New-Object System.Collections.Generic.List[String]

            foreach ($attributeValue in $attributeValues)
            {
                $ADObjectHashTable[$attributeName].Add($attributeValue)
            }
        }
    }
    else
    {
        foreach ($attributeName in $global:ADObjectAttributes)
        {
            if (!$AdObject.ContainsKey($attributeName))
            {
                continue
            }

            $attributeValues = [System.Collections.ArrayList] $AdObject[$attributeName]

            $ADObjectHashTable[$attributeName] = New-Object System.Collections.Generic.List[String]

            foreach ($attributeValue in $attributeValues)
            {
                $ADObjectHashTable[$attributeName].Add($attributeValue)
            }
        }
    }

    Write-Output $ADObjectHashTable
}

Function Global:ConvertCSObjectToHashTable
{
    param
    (
        [Microsoft.IdentityManagement.PowerShell.ObjectModel.CsObject]
        [parameter(mandatory=$true)]
        $CsObject,

        [string[]]
        [parameter(mandatory=$true)]
        $CsObjectAttributes
    )

    $CsObjectHashTable = @{}

    foreach ($attributeName in $CsObjectAttributes)
    {
        if (!$CsObject.Attributes.Contains($attributeName))
        {
            continue
        }

        $attributeValues = $CsObject.Attributes[$attributeName].Values

        $CsObjectHashTable[$attributeName] = New-Object System.Collections.Generic.List[String]

        foreach ($attributeValue in $attributeValues)
        {
            $CsObjectHashTable[$attributeName].Add($attributeValue)
        }
    }

    Write-Output $CsObjectHashTable
}

Function Global:ConvertMVObjectToHashTable
{
    param
    (
        [Microsoft.IdentityManagement.PowerShell.ObjectModel.MvObject]
        [parameter(mandatory=$true)]
        $MvObject
    )

    $MvObjectHashTable = @{}

    foreach ($attributeName in $global:MvObjectAttributes)
    {
        if (!$MvObject.Attributes.Contains($attributeName))   
        {
            continue
        }

        $attributeValues = $MvObject.Attributes[$attributeName].Values

        $MvObjectHashTable[$attributeName] = New-Object System.Collections.Generic.List[String]

        foreach ($attributeValue in $attributeValues)
        {
            $MvObjectHashTable[$attributeName].Add($attributeValue)
        }
    }

    Write-Output $MvObjectHashTable
}

Function Global:ConvertAADUserObjectToHashTable
{
    param
    (
        [Microsoft.Online.Administration.User]
        [parameter(mandatory=$true)]
        $AadUserObject
    )

    $AadUserObjectHashTable = @{}

    if ($AadUserObject.DisplayName)
    {
        $AadUserObjectHashTable["DisplayName"] = New-Object System.Collections.Generic.List[String]

        $AadUserObjectHashTable["DisplayName"].Add($AadUserObject.DisplayName)
    }

    if ($AadUserObject.ImmutableId)
    {
        $AadUserObjectHashTable["ImmutableId"] = New-Object System.Collections.Generic.List[String]

        $AadUserObjectHashTable["ImmutableId"].Add($AadUserObject.ImmutableId)
    }

    if ($AadUserObject.IsLicensed)
    {
        $AadUserObjectHashTable["IsLicensed"] = New-Object System.Collections.Generic.List[String]
    
        $AadUserObjectHashTable["IsLicensed"].Add($AadUserObject.IsLicensed)    
    }
    
    if ($AadUserObject.LastDirSyncTime)
    {
        $AadUserObjectHashTable["LastDirSyncTime"] = New-Object System.Collections.Generic.List[String]
    
        $AadUserObjectHashTable["LastDirSyncTime"].Add($AadUserObject.LastDirSyncTime)
    }

    if ($AadUserObject.UserPrincipalName)
    {
        $AadUserObjectHashTable["UserPrincipalName"] = New-Object System.Collections.Generic.List[String]

        $AadUserObjectHashTable["UserPrincipalName"].Add($AadUserObject.UserPrincipalName)    
    }
    
    if ($AadUserObject.ProxyAddresses)
    {
        $AadUserObjectHashTable["ProxyAddresses"] = New-Object System.Collections.Generic.List[String]
    
        foreach ($proxyAddress in $AadUserObject.ProxyAddresses)
        {
            $AadUserObjectHashTable["ProxyAddresses"].Add($proxyAddress)    
        }
    }

    Write-Output $AadUserObjectHashTable
}

Function Global:ConvertAADContactObjectToHashTable
{
    param
    (
        [Microsoft.Online.Administration.Contact]
        [parameter(mandatory=$true)]
        $AadContactObject
    )

    $AadContactObjectHashTable = @{}

    if ($AadContactObject.DisplayName)
    {
        $AadContactObjectHashTable["DisplayName"] = New-Object System.Collections.Generic.List[String]

        $AadContactObjectHashTable["DisplayName"].Add($AadContactObject.DisplayName)
    }

    if ($AadContactObject.ImmutableId)
    {
        $AadContactObjectHashTable["ImmutableId"] = New-Object System.Collections.Generic.List[String]

        $AadContactObjectHashTable["ImmutableId"].Add($AadContactObject.ImmutableId)
    }
    
    if ($AadContactObject.LastDirSyncTime)
    {
        $AadContactObjectHashTable["LastDirSyncTime"] = New-Object System.Collections.Generic.List[String]
    
        $AadContactObjectHashTable["LastDirSyncTime"].Add($AadContactObject.LastDirSyncTime)
    }

    if ($AadContactObject.UserPrincipalName)
    {
        $AadContactObjectHashTable["UserPrincipalName"] = New-Object System.Collections.Generic.List[String]

        $AadContactObjectHashTable["UserPrincipalName"].Add($AadContactObject.UserPrincipalName)    
    }
    
    if ($AadContactObject.ProxyAddresses)
    {
        $AadContactObjectHashTable["ProxyAddresses"] = New-Object System.Collections.Generic.List[String]
    
        foreach ($proxyAddress in $AadContactObject.ProxyAddresses)
        {
            $AadContactObjectHashTable["ProxyAddresses"].Add($proxyAddress)    
        }
    }

    Write-Output $AadContactObjectHashTable
}

Function Global:ConvertAADGroupObjectToHashTable
{
    param
    (
        [Microsoft.Online.Administration.Group]
        [parameter(mandatory=$true)]
        $AadGroupObject
    )

    $AadGroupObjectHashTable = @{}

    if ($AadGroupObject.DisplayName)
    {
        $AadGroupObjectHashTable["DisplayName"] = New-Object System.Collections.Generic.List[String]

        $AadGroupObjectHashTable["DisplayName"].Add($AadGroupObject.DisplayName)
    }

    if ($AadGroupObject.ImmutableId)
    {
        $AadGroupObjectHashTable["ImmutableId"] = New-Object System.Collections.Generic.List[String]

        $AadGroupObjectHashTable["ImmutableId"].Add($AadGroupObject.ImmutableId)
    }
    
    if ($AadGroupObject.LastDirSyncTime)
    {
        $AadGroupObjectHashTable["LastDirSyncTime"] = New-Object System.Collections.Generic.List[String]
    
        $AadGroupObjectHashTable["LastDirSyncTime"].Add($AadGroupObject.LastDirSyncTime)
    }
    
    if ($AadGroupObject.ProxyAddresses)
    {
        $AadGroupObjectHashTable["ProxyAddresses"] = New-Object System.Collections.Generic.List[String]
    
        foreach ($proxyAddress in $AadGroupObject.ProxyAddresses)
        {
            $AadGroupObjectHashTable["ProxyAddresses"].Add($proxyAddress)    
        }
    }

    Write-Output $AadGroupObjectHashTable
}


Function ReportOutput
{
    param
    (
        [string]
        [parameter(mandatory=$false, ValueFromPipeline=$True)]
        $Output,

        [string]
        [parameter(mandatory=$false)]
        $PropertyName = [string]::Empty,

        [string]
        [parameter(mandatory=$false)]
        $PropertyValue = [string]::Empty
    )

    if ($isNonInteractiveMode)
    {
        Write-AscOutput -Message $Output -PropertyName $PropertyName -PropertyValue $PropertyValue -OutputType 'Output'
    }
    else
    {
        Write-Host $Output -fore Green
    }
}

Function ReportError
{
    param
    (
        [string]
        [parameter(mandatory=$true, ValueFromPipeline=$True)]
        $ErrorString,

        [string]
        [parameter(mandatory=$false)]
        $PropertyName = [string]::Empty,

        [string]
        [parameter(mandatory=$false)]
        $PropertyValue = [string]::Empty

    )

    if ($isNonInteractiveMode)
    {
        Write-AscOutput -Message $ErrorString -PropertyName $PropertyName -PropertyValue $PropertyValue -OutputType 'Error'
    }
    else
    {
        Write-Host $ErrorString -fore Red
    }
}

Function ReportWarning
{
    param
    (
        [string]
        [parameter(mandatory=$true, ValueFromPipeline=$True)]
        $WarningString,

        [string]
        [parameter(mandatory=$false)]
        $PropertyName = [string]::Empty,

        [string]
        [parameter(mandatory=$false)]
        $PropertyValue = [string]::Empty
    )

    if ($isNonInteractiveMode)
    {
        Write-AscOutput -Message $WarningString -PropertyName $PropertyName -PropertyValue $PropertyValue -OutputType 'Warning'   
    }
    else
    {
        Write-Host $WarningString -fore Cyan
    }
}

Function Write-AscOutput
{
    param
    (
        [string]
        [parameter(mandatory=$false, ValueFromPipeline=$True)]
        $Message = [string]::Empty,

        [string]
        [parameter(mandatory=$false)]
        $PropertyName = [string]::Empty,

        [string]
        [parameter(mandatory=$false)]
        $PropertyValue = [string]::Empty,

        [string]
        [parameter(mandatory=$true)]
        $OutputType
    )

    $obj = New-Object PSCustomObject -Property @{
        $AscCustomScriptObjectProperty      = $true          
        PropertyName                        = $PropertyName                 
        PropertyValue                       = $PropertyValue              
        Message                             = $Message
        OutputType                          = $OutputType            
    }

    Write-Output $obj  
}
# SIG # Begin signature block
# MIInogYJKoZIhvcNAQcCoIInkzCCJ48CAQExDzANBglghkgBZQMEAgEFADB5Bgor
# BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG
# KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCAj37X/gCZTRN9G
# Coga+KauNaiZYyma0dopRtmVHVrXJ6CCDYIwggYAMIID6KADAgECAhMzAAADXJXz
# SFtKBGrPAAAAAANcMA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNVBAYTAlVTMRMwEQYD
# VQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNy
# b3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMTH01pY3Jvc29mdCBDb2RlIFNpZ25p
# bmcgUENBIDIwMTEwHhcNMjMwNDA2MTgyOTIyWhcNMjQwNDAyMTgyOTIyWjB0MQsw
# CQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9u
# ZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMR4wHAYDVQQDExVNaWNy
# b3NvZnQgQ29ycG9yYXRpb24wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
# AQDijA1UCC84R0x+9Vr/vQhPNbfvIOBFfymE+kuP+nho3ixnjyv6vdnUpgmm6RT/
# pL9cXL27zmgVMw7ivmLjR5dIm6qlovdrc5QRrkewnuQHnvhVnLm+pLyIiWp6Tow3
# ZrkoiVdip47m+pOBYlw/vrkb8Pju4XdA48U8okWmqTId2CbZTd8yZbwdHb8lPviE
# NMKzQ2bAjytWVEp3y74xc8E4P6hdBRynKGF6vvS6sGB9tBrvu4n9mn7M99rp//7k
# ku5t/q3bbMjg/6L6mDePok6Ipb22+9Fzpq5sy+CkJmvCNGPo9U8fA152JPrt14uJ
# ffVvbY5i9jrGQTfV+UAQ8ncPAgMBAAGjggF/MIIBezArBgNVHSUEJDAiBgorBgEE
# AYI3TBMBBgorBgEEAYI3TAgBBggrBgEFBQcDAzAdBgNVHQ4EFgQUXgIsrR+tkOQ8
# 10ekOnvvfQDgTHAwRQYDVR0RBD4wPKQ6MDgxHjAcBgNVBAsTFU1pY3Jvc29mdCBD
# b3Jwb3JhdGlvbjEWMBQGA1UEBRMNMjMzMTEwKzUwMDg2ODAfBgNVHSMEGDAWgBRI
# bmTlUAXTgqoXNzcitW2oynUClTBUBgNVHR8ETTBLMEmgR6BFhkNodHRwOi8vd3d3
# Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2NybC9NaWNDb2RTaWdQQ0EyMDExXzIwMTEt
# MDctMDguY3JsMGEGCCsGAQUFBwEBBFUwUzBRBggrBgEFBQcwAoZFaHR0cDovL3d3
# dy5taWNyb3NvZnQuY29tL3BraW9wcy9jZXJ0cy9NaWNDb2RTaWdQQ0EyMDExXzIw
# MTEtMDctMDguY3J0MAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcNAQELBQADggIBABIm
# T2UTYlls5t6i5kWaqI7sEfIKgNquF8Ex9yMEz+QMmc2FjaIF/HQQdpJZaEtDM1Xm
# 07VD4JvNJEplZ91A4SIxjHzqgLegfkyc384P7Nn+SJL3XK2FK+VAFxdvZNXcrkt2
# WoAtKo0PclJOmHheHImWSqfCxRispYkKT9w7J/84fidQxSj83NPqoCfUmcy3bWKY
# jRZ6PPDXlXERRvl825dXOfmCKGYJXHKyOEcU8/6djs7TDyK0eH9ss4G9mjPnVZzq
# Gi/qxxtbddZtkREDd0Acdj947/BTwsYLuQPz7SNNUAmlZOvWALPU7OOVQlEZzO8u
# Ec+QH24nep/yhKvFYp4sHtxUKm1ZPV4xdArhzxJGo48Be74kxL7q2AlTyValLV98
# u3FY07rNo4Xg9PMHC6sEAb0tSplojOHFtGtNb0r+sioSttvd8IyaMSfCPwhUxp+B
# Td0exzQ1KnRSBOZpxZ8h0HmOlMJOInwFqrCvn5IjrSdjxKa/PzOTFPIYAfMZ4hJn
# uKu15EUuv/f0Tmgrlfw+cC0HCz/5WnpWiFso2IPHZyfdbbOXO2EZ9gzB1wmNkbBz
# hj8hFyImnycY+94Eo2GLavVTtgBiCcG1ILyQabKDbL7Vh/OearAxcRAmcuVAha07
# WiQx2aLghOSaZzKFOx44LmwUxRuaJ4vO/PRZ7EzAMIIHejCCBWKgAwIBAgIKYQ6Q
# 0gAAAAAAAzANBgkqhkiG9w0BAQsFADCBiDELMAkGA1UEBhMCVVMxEzARBgNVBAgT
# Cldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29m
# dCBDb3Jwb3JhdGlvbjEyMDAGA1UEAxMpTWljcm9zb2Z0IFJvb3QgQ2VydGlmaWNh
# dGUgQXV0aG9yaXR5IDIwMTEwHhcNMTEwNzA4MjA1OTA5WhcNMjYwNzA4MjEwOTA5
# WjB+MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMH
# UmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSgwJgYDVQQD
# Ex9NaWNyb3NvZnQgQ29kZSBTaWduaW5nIFBDQSAyMDExMIICIjANBgkqhkiG9w0B
# AQEFAAOCAg8AMIICCgKCAgEAq/D6chAcLq3YbqqCEE00uvK2WCGfQhsqa+laUKq4
# BjgaBEm6f8MMHt03a8YS2AvwOMKZBrDIOdUBFDFC04kNeWSHfpRgJGyvnkmc6Whe
# 0t+bU7IKLMOv2akrrnoJr9eWWcpgGgXpZnboMlImEi/nqwhQz7NEt13YxC4Ddato
# 88tt8zpcoRb0RrrgOGSsbmQ1eKagYw8t00CT+OPeBw3VXHmlSSnnDb6gE3e+lD3v
# ++MrWhAfTVYoonpy4BI6t0le2O3tQ5GD2Xuye4Yb2T6xjF3oiU+EGvKhL1nkkDst
# rjNYxbc+/jLTswM9sbKvkjh+0p2ALPVOVpEhNSXDOW5kf1O6nA+tGSOEy/S6A4aN
# 91/w0FK/jJSHvMAhdCVfGCi2zCcoOCWYOUo2z3yxkq4cI6epZuxhH2rhKEmdX4ji
# JV3TIUs+UsS1Vz8kA/DRelsv1SPjcF0PUUZ3s/gA4bysAoJf28AVs70b1FVL5zmh
# D+kjSbwYuER8ReTBw3J64HLnJN+/RpnF78IcV9uDjexNSTCnq47f7Fufr/zdsGbi
# wZeBe+3W7UvnSSmnEyimp31ngOaKYnhfsi+E11ecXL93KCjx7W3DKI8sj0A3T8Hh
# hUSJxAlMxdSlQy90lfdu+HggWCwTXWCVmj5PM4TasIgX3p5O9JawvEagbJjS4NaI
# jAsCAwEAAaOCAe0wggHpMBAGCSsGAQQBgjcVAQQDAgEAMB0GA1UdDgQWBBRIbmTl
# UAXTgqoXNzcitW2oynUClTAZBgkrBgEEAYI3FAIEDB4KAFMAdQBiAEMAQTALBgNV
# HQ8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAWgBRyLToCMZBDuRQF
# TuHqp8cx0SOJNDBaBgNVHR8EUzBRME+gTaBLhklodHRwOi8vY3JsLm1pY3Jvc29m
# dC5jb20vcGtpL2NybC9wcm9kdWN0cy9NaWNSb29DZXJBdXQyMDExXzIwMTFfMDNf
# MjIuY3JsMF4GCCsGAQUFBwEBBFIwUDBOBggrBgEFBQcwAoZCaHR0cDovL3d3dy5t
# aWNyb3NvZnQuY29tL3BraS9jZXJ0cy9NaWNSb29DZXJBdXQyMDExXzIwMTFfMDNf
# MjIuY3J0MIGfBgNVHSAEgZcwgZQwgZEGCSsGAQQBgjcuAzCBgzA/BggrBgEFBQcC
# ARYzaHR0cDovL3d3dy5taWNyb3NvZnQuY29tL3BraW9wcy9kb2NzL3ByaW1hcnlj
# cHMuaHRtMEAGCCsGAQUFBwICMDQeMiAdAEwAZQBnAGEAbABfAHAAbwBsAGkAYwB5
# AF8AcwB0AGEAdABlAG0AZQBuAHQALiAdMA0GCSqGSIb3DQEBCwUAA4ICAQBn8oal
# mOBUeRou09h0ZyKbC5YR4WOSmUKWfdJ5DJDBZV8uLD74w3LRbYP+vj/oCso7v0ep
# o/Np22O/IjWll11lhJB9i0ZQVdgMknzSGksc8zxCi1LQsP1r4z4HLimb5j0bpdS1
# HXeUOeLpZMlEPXh6I/MTfaaQdION9MsmAkYqwooQu6SpBQyb7Wj6aC6VoCo/KmtY
# SWMfCWluWpiW5IP0wI/zRive/DvQvTXvbiWu5a8n7dDd8w6vmSiXmE0OPQvyCInW
# H8MyGOLwxS3OW560STkKxgrCxq2u5bLZ2xWIUUVYODJxJxp/sfQn+N4sOiBpmLJZ
# iWhub6e3dMNABQamASooPoI/E01mC8CzTfXhj38cbxV9Rad25UAqZaPDXVJihsMd
# YzaXht/a8/jyFqGaJ+HNpZfQ7l1jQeNbB5yHPgZ3BtEGsXUfFL5hYbXw3MYbBL7f
# QccOKO7eZS/sl/ahXJbYANahRr1Z85elCUtIEJmAH9AAKcWxm6U/RXceNcbSoqKf
# enoi+kiVH6v7RyOA9Z74v2u3S5fi63V4GuzqN5l5GEv/1rMjaHXmr/r8i+sLgOpp
# O6/8MO0ETI7f33VtY5E90Z1WTk+/gFcioXgRMiF670EKsT/7qMykXcGhiJtXcVZO
# SEXAQsmbdlsKgEhr/Xmfwb1tbWrJUnMTDXpQzTGCGXYwghlyAgEBMIGVMH4xCzAJ
# BgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25k
# MR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMTH01pY3Jv
# c29mdCBDb2RlIFNpZ25pbmcgUENBIDIwMTECEzMAAANclfNIW0oEas8AAAAAA1ww
# DQYJYIZIAWUDBAIBBQCgga4wGQYJKoZIhvcNAQkDMQwGCisGAQQBgjcCAQQwHAYK
# KwYBBAGCNwIBCzEOMAwGCisGAQQBgjcCARUwLwYJKoZIhvcNAQkEMSIEIJa7XmiD
# 0MBcuOi5ImObF7o+imkYAuGPoxYS/eXb9JOWMEIGCisGAQQBgjcCAQwxNDAyoBSA
# EgBNAGkAYwByAG8AcwBvAGYAdKEagBhodHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20w
# DQYJKoZIhvcNAQEBBQAEggEAWZFJ6e4YyImdN3j1WYYPr/tOK6T1YWa50VqiYwW/
# 9qm1EfEB3LXbqpEachVEX3S3l63Fno2T/QeaXcuMOFXtczHq0k1MCSZs00u64txR
# jw8ny50o+1FoYRa0w+ioHtH8sX5nY0lmi+G8FoC+DjbO9OclJHgAeCChbCLL4A/+
# G/+Aej3MW6yS6+mld5L69J9+erjgm4zaK3XHu4+BeRBeBwKSZ30VPKLSeF8I0PS4
# P2IzV+TsDuMiAUFqXwHoO5/di3NlynjsCMWlSLNIPLDGExKVqUqCDOYnURFzKz40
# 65BcQmc71g++Xf2AuCfXUT5LsXosDmU50u/IrfmfGzuEX6GCFwAwghb8BgorBgEE
# AYI3AwMBMYIW7DCCFugGCSqGSIb3DQEHAqCCFtkwghbVAgEDMQ8wDQYJYIZIAWUD
# BAIBBQAwggFRBgsqhkiG9w0BCRABBKCCAUAEggE8MIIBOAIBAQYKKwYBBAGEWQoD
# ATAxMA0GCWCGSAFlAwQCAQUABCB/eJFSidn8hc7HCbj2CpDV7l8KODz0xTi/rpLt
# CJlPOAIGZFzvGDIGGBMyMDIzMDUxNzIyNTUyOS45MzVaMASAAgH0oIHQpIHNMIHK
# MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVk
# bW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSUwIwYDVQQLExxN
# aWNyb3NvZnQgQW1lcmljYSBPcGVyYXRpb25zMSYwJAYDVQQLEx1UaGFsZXMgVFNT
# IEVTTjo3QkYxLUUzRUEtQjgwODElMCMGA1UEAxMcTWljcm9zb2Z0IFRpbWUtU3Rh
# bXAgU2VydmljZaCCEVcwggcMMIIE9KADAgECAhMzAAAByPmw7mft6mtGAAEAAAHI
# MA0GCSqGSIb3DQEBCwUAMHwxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5n
# dG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9y
# YXRpb24xJjAkBgNVBAMTHU1pY3Jvc29mdCBUaW1lLVN0YW1wIFBDQSAyMDEwMB4X
# DTIyMTEwNDE5MDEzN1oXDTI0MDIwMjE5MDEzN1owgcoxCzAJBgNVBAYTAlVTMRMw
# EQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVN
# aWNyb3NvZnQgQ29ycG9yYXRpb24xJTAjBgNVBAsTHE1pY3Jvc29mdCBBbWVyaWNh
# IE9wZXJhdGlvbnMxJjAkBgNVBAsTHVRoYWxlcyBUU1MgRVNOOjdCRjEtRTNFQS1C
# ODA4MSUwIwYDVQQDExxNaWNyb3NvZnQgVGltZS1TdGFtcCBTZXJ2aWNlMIICIjAN
# BgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAucudfihPgyRWwnnIuJCqc3TCtFk0
# XOimFcKjU9bS6WFng2l+FrIid0mPZ7KWs6Ewj21X+ZkGkM6x+ozHlmNtnHSQ48pj
# IFdlKXIoh7fSo41A4n0tQIlwhs8uIYIocp72xwDBHKSZxGaEa/0707iyOw+aXZXN
# cTxgNiREASb9thlLZM75mfJIgBVvUmdLZc+XOUYwz/8ul7IEztPNH4cn8Cn0tJhI
# Ffp2netr8GYNoiyIqxueG7+sSt2xXl7/igc5cHPZnWhfl9PaB4+SutrA8zAhzVHT
# nj4RffxA4R3k4BRbPdGowQfOf95ZeYxLTHf5awB0nqZxOY+yuGWhf6hp5RGRouc9
# beVZv98M1erYa55S1ahZgGDQJycVtEy82RlmKfTYY2uNmlPLWtnD7sDlpVkhYQGK
# uTWnuwQKq9ZTSE+0V2cH8JaWBYJQMIuWWM83vLPo3IT/S/5jT2oZOS9nsJgwwCwR
# UtYtwtq8/PJtvt1V6VoG4Wd2/MAifgEJOkHF7ARPqI9Xv28+riqJZ5mjLGz84dP2
# ryoe0lxYSz3PT5ErKoS0+zJpYNAcxbv2UXiTk3Wj/mZ3tulz6z4XnSl5gy0PLer+
# EVjz4G96GcZgK2d9G+uYylHWwBneIv9YFQj6yMdW/4sEpkEbrpiJNemcxUCmBipZ
# 7Sc35rv4utkJ4/UCAwEAAaOCATYwggEyMB0GA1UdDgQWBBS1XC9JgbrSwLDTiJJT
# 4iK7NUvk9TAfBgNVHSMEGDAWgBSfpxVdAF5iXYP05dJlpxtTNRnpcjBfBgNVHR8E
# WDBWMFSgUqBQhk5odHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2NybC9N
# aWNyb3NvZnQlMjBUaW1lLVN0YW1wJTIwUENBJTIwMjAxMCgxKS5jcmwwbAYIKwYB
# BQUHAQEEYDBeMFwGCCsGAQUFBzAChlBodHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20v
# cGtpb3BzL2NlcnRzL01pY3Jvc29mdCUyMFRpbWUtU3RhbXAlMjBQQ0ElMjAyMDEw
# KDEpLmNydDAMBgNVHRMBAf8EAjAAMBMGA1UdJQQMMAoGCCsGAQUFBwMIMA0GCSqG
# SIb3DQEBCwUAA4ICAQDD1nJSyEPDqSgnfkFifIbteJb7NkZCbRj5yBGiT1f9fTGv
# Ub5CW7k3eSp3uxUqom9LWykcNfQa/Yfw0libEim9YRjUNcL42oIFqtp/7rl9gg61
# oiB8PB+6vLEmjXkYxUUR8WjKKC5Q5dx96B21faSco2MOmvjYxGUR7An+4529lQPP
# LqbEKRjcNQb+p+mkQH2XeMbsh5EQCkTuYAimFTgnui2ZPFLEuBpxBK5z2HnKneHU
# J9i4pcKWdCqF1AOVN8gXIH0R0FflMcCg5TW8v90Vwx/mP3aE2Ige1uE8M9YNBn57
# 76PxmA16Z+c2s+hYI+9sJZhhRA8aSYacrlLz7aU/56OvEYRERQZttuAFkrV+M/J+
# tCeGNv0Gd75Y4lKLMp5/0xoOviPBdB2rD5C/U+B8qt1bBqQLVZ1wHRy0/6HhJxbO
# i2IgGJaOCYLGX2zz0VAT6mZ2BTWrJmcK6SDv7rX7psgC+Cf1t0R1aWCkCHJtpYuy
# Kjf7UodRazevOf6V01XkrARHKrI7bQoHFL+sun2liJCBjN51mDWoEgUCEvwB3l+R
# FYAL0aIisc5cTaGX/T8F+iAbz+j2GGVum85gEQS9uLzSedoYPyEXxTblwewGdAxq
# IZaKozRBow49OnL+5CgooVMf3ZSqpxc2QC0E03l6c/vChkYyqMXq7Lwd4PnHqjCC
# B3EwggVZoAMCAQICEzMAAAAVxedrngKbSZkAAAAAABUwDQYJKoZIhvcNAQELBQAw
# gYgxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdS
# ZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xMjAwBgNVBAMT
# KU1pY3Jvc29mdCBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAyMDEwMB4XDTIx
# MDkzMDE4MjIyNVoXDTMwMDkzMDE4MzIyNVowfDELMAkGA1UEBhMCVVMxEzARBgNV
# BAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jv
# c29mdCBDb3Jwb3JhdGlvbjEmMCQGA1UEAxMdTWljcm9zb2Z0IFRpbWUtU3RhbXAg
# UENBIDIwMTAwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDk4aZM57Ry
# IQt5osvXJHm9DtWC0/3unAcH0qlsTnXIyjVX9gF/bErg4r25PhdgM/9cT8dm95VT
# cVrifkpa/rg2Z4VGIwy1jRPPdzLAEBjoYH1qUoNEt6aORmsHFPPFdvWGUNzBRMhx
# XFExN6AKOG6N7dcP2CZTfDlhAnrEqv1yaa8dq6z2Nr41JmTamDu6GnszrYBbfowQ
# HJ1S/rboYiXcag/PXfT+jlPP1uyFVk3v3byNpOORj7I5LFGc6XBpDco2LXCOMcg1
# KL3jtIckw+DJj361VI/c+gVVmG1oO5pGve2krnopN6zL64NF50ZuyjLVwIYwXE8s
# 4mKyzbnijYjklqwBSru+cakXW2dg3viSkR4dPf0gz3N9QZpGdc3EXzTdEonW/aUg
# fX782Z5F37ZyL9t9X4C626p+Nuw2TPYrbqgSUei/BQOj0XOmTTd0lBw0gg/wEPK3
# Rxjtp+iZfD9M269ewvPV2HM9Q07BMzlMjgK8QmguEOqEUUbi0b1qGFphAXPKZ6Je
# 1yh2AuIzGHLXpyDwwvoSCtdjbwzJNmSLW6CmgyFdXzB0kZSU2LlQ+QuJYfM2BjUY
# hEfb3BvR/bLUHMVr9lxSUV0S2yW6r1AFemzFER1y7435UsSFF5PAPBXbGjfHCBUY
# P3irRbb1Hode2o+eFnJpxq57t7c+auIurQIDAQABo4IB3TCCAdkwEgYJKwYBBAGC
# NxUBBAUCAwEAATAjBgkrBgEEAYI3FQIEFgQUKqdS/mTEmr6CkTxGNSnPEP8vBO4w
# HQYDVR0OBBYEFJ+nFV0AXmJdg/Tl0mWnG1M1GelyMFwGA1UdIARVMFMwUQYMKwYB
# BAGCN0yDfQEBMEEwPwYIKwYBBQUHAgEWM2h0dHA6Ly93d3cubWljcm9zb2Z0LmNv
# bS9wa2lvcHMvRG9jcy9SZXBvc2l0b3J5Lmh0bTATBgNVHSUEDDAKBggrBgEFBQcD
# CDAZBgkrBgEEAYI3FAIEDB4KAFMAdQBiAEMAQTALBgNVHQ8EBAMCAYYwDwYDVR0T
# AQH/BAUwAwEB/zAfBgNVHSMEGDAWgBTV9lbLj+iiXGJo0T2UkFvXzpoYxDBWBgNV
# HR8ETzBNMEugSaBHhkVodHRwOi8vY3JsLm1pY3Jvc29mdC5jb20vcGtpL2NybC9w
# cm9kdWN0cy9NaWNSb29DZXJBdXRfMjAxMC0wNi0yMy5jcmwwWgYIKwYBBQUHAQEE
# TjBMMEoGCCsGAQUFBzAChj5odHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpL2Nl
# cnRzL01pY1Jvb0NlckF1dF8yMDEwLTA2LTIzLmNydDANBgkqhkiG9w0BAQsFAAOC
# AgEAnVV9/Cqt4SwfZwExJFvhnnJL/Klv6lwUtj5OR2R4sQaTlz0xM7U518JxNj/a
# ZGx80HU5bbsPMeTCj/ts0aGUGCLu6WZnOlNN3Zi6th542DYunKmCVgADsAW+iehp
# 4LoJ7nvfam++Kctu2D9IdQHZGN5tggz1bSNU5HhTdSRXud2f8449xvNo32X2pFaq
# 95W2KFUn0CS9QKC/GbYSEhFdPSfgQJY4rPf5KYnDvBewVIVCs/wMnosZiefwC2qB
# woEZQhlSdYo2wh3DYXMuLGt7bj8sCXgU6ZGyqVvfSaN0DLzskYDSPeZKPmY7T7uG
# +jIa2Zb0j/aRAfbOxnT99kxybxCrdTDFNLB62FD+CljdQDzHVG2dY3RILLFORy3B
# FARxv2T5JL5zbcqOCb2zAVdJVGTZc9d/HltEAY5aGZFrDZ+kKNxnGSgkujhLmm77
# IVRrakURR6nxt67I6IleT53S0Ex2tVdUCbFpAUR+fKFhbHP+CrvsQWY9af3LwUFJ
# fn6Tvsv4O+S3Fb+0zj6lMVGEvL8CwYKiexcdFYmNcP7ntdAoGokLjzbaukz5m/8K
# 6TT4JDVnK+ANuOaMmdbhIurwJ0I9JZTmdHRbatGePu1+oDEzfbzL6Xu/OHBE0ZDx
# yKs6ijoIYn/ZcGNTTY3ugm2lBRDBcQZqELQdVTNYs6FwZvKhggLOMIICNwIBATCB
# +KGB0KSBzTCByjELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAO
# BgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEl
# MCMGA1UECxMcTWljcm9zb2Z0IEFtZXJpY2EgT3BlcmF0aW9uczEmMCQGA1UECxMd
# VGhhbGVzIFRTUyBFU046N0JGMS1FM0VBLUI4MDgxJTAjBgNVBAMTHE1pY3Jvc29m
# dCBUaW1lLVN0YW1wIFNlcnZpY2WiIwoBATAHBgUrDgMCGgMVAN/OE1C7xjU0ClID
# XQBiucAY7suyoIGDMIGApH4wfDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hp
# bmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jw
# b3JhdGlvbjEmMCQGA1UEAxMdTWljcm9zb2Z0IFRpbWUtU3RhbXAgUENBIDIwMTAw
# DQYJKoZIhvcNAQEFBQACBQDoD1Z1MCIYDzIwMjMwNTE3MjEzNDQ1WhgPMjAyMzA1
# MTgyMTM0NDVaMHcwPQYKKwYBBAGEWQoEATEvMC0wCgIFAOgPVnUCAQAwCgIBAAIC
# C8sCAf8wBwIBAAICFBswCgIFAOgQp/UCAQAwNgYKKwYBBAGEWQoEAjEoMCYwDAYK
# KwYBBAGEWQoDAqAKMAgCAQACAwehIKEKMAgCAQACAwGGoDANBgkqhkiG9w0BAQUF
# AAOBgQCZ+wVHvtUgRgs4yZzaP8+EfMg/k2Qzg/z9T2IoeT3GHW9va/ZoPYB663wk
# clhsYStL/tVZdDYWyI7E1vEOiAD4nWoXpXiIg1CpKEq4Gafsk/ktVYND8o9EZv8R
# Y3b/BLuhlgC+npH3kEDwrO1tlmx4VoI3Hc+hEceHtsDVqcQRiDGCBA0wggQJAgEB
# MIGTMHwxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQH
# EwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xJjAkBgNV
# BAMTHU1pY3Jvc29mdCBUaW1lLVN0YW1wIFBDQSAyMDEwAhMzAAAByPmw7mft6mtG
# AAEAAAHIMA0GCWCGSAFlAwQCAQUAoIIBSjAaBgkqhkiG9w0BCQMxDQYLKoZIhvcN
# AQkQAQQwLwYJKoZIhvcNAQkEMSIEIIAE86OqimRfPNS+SNt41uir2tF2d8V7vFXG
# L/HfwzcMMIH6BgsqhkiG9w0BCRACLzGB6jCB5zCB5DCBvQQgYgCYz80/baMvxw6j
# cqSvL0FW4TdvA09nxHfsPhuEA2YwgZgwgYCkfjB8MQswCQYDVQQGEwJVUzETMBEG
# A1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWlj
# cm9zb2Z0IENvcnBvcmF0aW9uMSYwJAYDVQQDEx1NaWNyb3NvZnQgVGltZS1TdGFt
# cCBQQ0EgMjAxMAITMwAAAcj5sO5n7eprRgABAAAByDAiBCCYz2zh+m6XI7lMnMCW
# XJuCdCC1yLSSA61OtEJ8Tz/bhzANBgkqhkiG9w0BAQsFAASCAgASRbgn28mJzIAy
# sixVtSKewJh6FgK2KU9S9U0Gaw0Uu2++Zxhubxa+4TfmGunL3Y6PuhxvtcyptvHz
# XETtLCAOe4QHVK6bk+WV48krfgZ/DcENq39K1hUGH/9oVyPYuhwxZdMQVhXvrkcS
# bAFNcImY9fgnJUOM1mpgu9w5Y7k7zNosmyhTktppyuv4V+UYyZp9b5lMlGNs6iu0
# ZEDztV/Y2I5PDxU4CJ7mIt78UdSy7907u9yIbqy7WlR5/WTWe5wv4K9PMYKfbSb4
# kZnGsB14FxUpDt8Qn3P3FZDbNRm5qhNB9Hhc/CvE1btJSZjIFbKNxAOVCQUnBbnN
# X5FIwpPQw6l491Nhs8r5kcIgk1f1DpHdnte4FfF2sOJgGWZaKDgQjwSAXCjKXT4Y
# swMpvKGVCblz6po6k4kb/yHHHN2IKJicUp3T58KG7qgV7aPbvz6rO+VqRl09vWZE
# bLo2GXinh4ts2DhbXp8YHgmFLZYEu+0VmMYlRAcKi0eGKoTTok3XWGcY4f2pk07O
# 2XgUwr2I1RD2AEJkzCbUiKSr3v497PECVc5zkBGRtovcSy+JDQmQt778cNwAW0As
# /fWsU+I0Pkj5vc3JXS0nsZ3bYU4YcQKQ1E3sEdZ/DiBR+ELyDLZuhjnLHhEue9Bx
# Ey59tg6ug70E3MYHGeI9dNOn5B0sMA==
# SIG # End signature block