#######################################################
###              Restore Admin Account             ####
#######################################################

PARAM (
    [Parameter(Mandatory=$true)]
    $log,

    [Parameter(Mandatory=$false)]
    $UserInfoTableName = "USERINFO"
)

# Import modules and initialize the log
Import-Module WebAdministration
Import-Module "$PSScriptRoot\CommonRollbackUtilities.psm1" -DisableNameChecking
Import-Module "$PSScriptRoot\AosCommon.psm1" -Force -DisableNameChecking
Initialize-Log $log

function Add-AdminAccount()
{
    $expectedAdminSID = Get-Sid -Email $AdminPrincipalName -Domain $AdminIdentityProvider
    Write-LogWithoutEmail "Inserting a new Admin account record with SID='$($expectedAdminSID)', NetworkDomain='$($AdminIdentityProvider)', and NetworkAlias='$($AdminPrincipalName)'..."
    $target_sqlParams.Query = @"
    INSERT INTO $($UserInfoTableName) (ID, NAME, ENABLE, STATUSLINEINFO, TOOLBARINFO, DEBUGINFO, AUTOINFO, AUTOUPDATE, GARBAGECOLLECTLIMIT, HISTORYLIMIT, MESSAGELIMIT, GENERALINFO, SHOWSTATUSLINE, SHOWTOOLBAR, SHOWAOTLAYER, CONFIRMDELETE, REPORTFONTSIZE, FORMFONTSIZE, PROPERTYFONTSIZE, COMPANY, COMPILERWARNINGLEVEL, SID, NETWORKDOMAIN, NETWORKALIAS, LANGUAGE, HELPLANGUAGE, PREFERREDTIMEZONE, NOTIFYTIMEZONEMISMATCH, ACCOUNTTYPE, DEFAULTPARTITION, INTERACTIVELOGON)  
    VALUES ('Admin', 'Admin', 1, -538365, -1, 12, -1, 6, 20, 5, 1000, -8209, 1, 1, 4, -1, 9, 9, 9, 'DAT', 3, '$($expectedAdminSID)', '$($AdminIdentityProvider)', '$($AdminPrincipalName)', 'en-US', 'en-us', 58, 1, 2, 1, 1)
"@
    Invoke-SqlQueryWithLog $target_sqlParams | out-null
    Write-LogWithoutEmail "Added a new Admin record to $($UserInfoTableName) table."
}

function Ensure-AdminAccountIsEnabled($AdminAccount)
{
    if ($AdminAccount.ENABLE -ne 1)
    {
        Write-LogWithoutEmail "Admin account is disabled. Enabling Admin account..."
        $target_sqlParams.Query = @"
            UPDATE $($UserInfoTableName) set ENABLE = 1 WHERE ID = 'Admin'
"@
        Invoke-SqlQueryWithLog $target_sqlParams | Out-Null
        Write-LogWithoutEmail "Finished enabling Admin account."
    }
    else
    {
        Write-LogWithoutEmail "Validated that Admin account is enabled."
    }
}

function Ensure-AdminAccountHasCorrectNetworkDomain($AdminAccount)
{
    if ($AdminAccount.NETWORKDOMAIN -ne $AdminIdentityProvider)
    {
        Write-LogWithoutEmail "The Admin account's NetworkDomain '$($AdminAccount.NETWORKDOMAIN)' in $($UserInfoTableName) does not match default provisioning admin identity provider '$($AdminIdentityProvider)'."
        $target_sqlParams.Query = @"
            UPDATE $($UserInfoTableName) set NETWORKDOMAIN = '$AdminIdentityProvider' WHERE ID = 'Admin'
"@
        Write-LogWithoutEmail "Updated the Admin account's NetworkDomain to '$($AdminIdentityProvider)' in $($UserInfoTableName)."
        Invoke-SqlQueryWithLog $target_sqlParams | Out-Null
    }
    else
    {
        Write-LogWithoutEmail "Admin network domain is correct."
    }
}

function Ensure-AdminAccountHasCorrectSID($AdminAccount)
{
    $expectedAdminSID = Get-Sid -Email $AdminPrincipalName -Domain $AdminIdentityProvider
    if ([string]::IsNullOrEmpty($expectedAdminSID))
    {
        Write-LogWithoutEmail "Expected admin SID is null or empty. Ignoring database check for admin SID."
    }
    elseif ($AdminAccount.SID -ne $expectedAdminSID)
    {
        Write-LogWithoutEmail "SID in database '$($AdminAccount.SID)' does not match generated SID '$($expectedAdminSID)'. Updating SID in database..."
        $target_sqlParams.Query = @"
            UPDATE $($UserInfoTableName) set SID = '$($expectedAdminSID)' WHERE ID = 'Admin'
"@
        Invoke-SqlQueryWithLog $target_sqlParams | Out-Null
        Write-LogWithoutEmail "Finished updating the SID."
    }
    else
    {
        Write-LogWithoutEmail "SID in database matches the generated SID."
    }
}

function Ensure-NoDuplicateAdminAccounts()
{
    $adminUserCount = Get-UserCount -Id "Admin"
    # Validate that ADMIN account is unique.
    if ($adminUserCount -gt 1)
    {
        Write-LogWithoutEmail "$($adminUserCount) admin records found. Removing duplicates."
        $target_sqlParams.Query = @"
        DECLARE @expectedCount int = 0,
        @adminPrincipalName varchar(100) = '$($AdminPrincipalName)'
            SELECT @expectedCount = COUNT(*) FROM $($UserInfoTableName) WHERE ID = 'Admin' and NETWORKALIAS = @adminPrincipalName;
    
                    IF @expectedCount >= 1 
                    BEGIN
                        DELETE $($UserInfoTableName) WHERE ID = 'Admin' and NETWORKALIAS != @adminPrincipalName;
                        IF @expectedCount > 1 
                        BEGIN
                            DELETE TOP(@expectedCount - 1) $($UserInfoTableName) WHERE ID = 'Admin'
                        END;
                    END;

                    ELSE
                    BEGIN
                        DELETE TOP($($adminUserCount) - 1) $($UserInfoTableName) WHERE ID = 'Admin'
                    END;
"@
        Invoke-SqlQueryWithLog $target_sqlParams | out-null
        Write-LogWithoutEmail "Removed the duplicate Admin records."
    }
    else
    {
        Write-LogWithoutEmail "No duplicate Admin records found in $($UserInfoTableName) table."
    }
}

function Ensure-NoDuplicateNetworkAliasAccounts($NetworkAlias)
{
    # Check if db has duplicate networkalias with admin account
    $adminUserCount = Get-UserCount -NetworkAlias $NetworkAlias

    # Validate that ADMIN networkalias account is not duplicated.
    if ($adminUserCount -gt 1)
    {
        $target_sqlParams.Query = @"
        DELETE $($UserInfoTableName) WHERE NETWORKALIAS = '$($NetworkAlias)' AND ID != 'Admin'
"@
        Invoke-SqlQueryWithLog $target_sqlParams | out-null
        Write-LogWithoutEmail "Removed the non Admin records where NetworkAlias was set to '$($NetworkAlias)'."
    }
}

function Get-AdminAccount()
{
    $target_sqlParams.Query = @"
    SELECT	ENABLE,
            NETWORKALIAS,
            IDENTITYPROVIDER,
            NETWORKDOMAIN,
            SID 
    FROM $($UserInfoTableName) WHERE ID = 'Admin'
"@
    return Invoke-SqlQueryWithLog $target_sqlParams
}

function Get-Sid($Email, $Domain)
{
    $sid = $null
    $dllPath = Join-Path $webrootBinPath "Microsoft.Dynamics.AX.Security.SidGenerator.dll"
    if (Test-Path $dllPath)
    {
        Write-LogWithoutEmail "Loading Microsoft.Dynamics.AX.Security.SidGenerator.dll from path '$($dllPath)' to generate SID..."
        $assembly = [Reflection.Assembly]::LoadFile($dllPath)

        Write-LogWithoutEmail "Loading SidGenerator type from assembly..."
        $sidGeneratorType = $assembly.GetType("Microsoft.Dynamics.Ax.Security.SidGenerator")

        Write-LogWithoutEmail "Attempting to find new SidGenerator method 'GenerateSIDByDefaultAlgo' (available in PU37+)..."
        $newGenerateSidMethod = $sidGeneratorType.GetMethod("GenerateSIDByDefaultAlgo")
        if ($null -ne $newGenerateSidMethod)
        {
            Write-LogWithoutEmail "New SidGenerator::GenerateSIDByDefaultAlgo(...) method found - using it."
            Write-LogWithoutEmail "Generating SID using email '$($Email)' and domain '$($Domain)'..."
            $sid = [Microsoft.Dynamics.Ax.Security.SidGenerator]::GenerateSIDByDefaultAlgo($Email, $Domain)
        }
        else
        {
            Write-LogWithoutEmail "Could not find method SidGenerator::GenerateSIDByDefaultAlgo(...) - will use old SidGenerator::Generate(email, domain) method instead."
            Write-LogWithoutEmail "Generating SID using email '$($Email)' and domain '$($Domain)'..."
            $sid = [Microsoft.Dynamics.Ax.Security.SidGenerator]::Generate($Email, $Domain)
        }

        Write-LogWithoutEmail "Generated SID: '$($sid)'"
    }
    else
    {
        Write-LogWithoutEmail "Unable to find SIDGenerator assembly '$($dllPath)'. Cannot generate SID."
    }

    return $sid
}

function Get-UserCount(
    [Parameter(Mandatory=$true, ParameterSetName="Id")]
    [String]
    $Id,

    [Parameter(Mandatory=$true, ParameterSetName="NetworkAlias")]
    [String]
    $NetworkAlias
)
{
    if (-not [string]::IsNullOrEmpty($Id))
    {
        $whereClause = "ID = '$($Id)'"
    }
    else
    {
        $whereClause = "NETWORKALIAS = '$($NetworkAlias)'"
    }

    $target_sqlParams.Query = @"
        SELECT COUNT(*) AS UserCount FROM $($UserInfoTableName) WHERE $($whereClause)
"@
    $userCountResults = Invoke-SqlQueryWithLog $target_sqlParams

    [int]$count = $userCountResults.UserCount
    Write-LogWithoutEmail "Number of users with $($whereClause): $($count)"
    return $count
}

function Initialize-Settings()
{
    $webroot = Get-AosWebSitePhysicalPath
    Write-LogWithoutEmail "The Service drive path of the webroot on the aos machine is: $($webroot)"

    $script:webrootBinPath = Join-Path $webroot 'bin'
    $environmentDllPath = Join-Path $webrootBinPath 'Microsoft.Dynamics.ApplicationPlatform.Environment.dll'
    Add-Type -Path $environmentDllPath

    # Load application configuration
    $script:config = [Microsoft.Dynamics.ApplicationPlatform.Environment.EnvironmentFactory]::GetApplicationEnvironment()

    $script:target_sqlParams = @{
        'Database'       = $($config.DataAccess.Database)
        'UserName'       = $($config.DataAccess.SqlUser)
        'Password'       = $($config.DataAccess.SqlPwd)
        'ServerInstance' = $($config.DataAccess.DbServer)
        'Query'          = ''
        'QueryTimeout'   = 0 }


    $script:TenantId = $($config.Aad.AADTenantId)
    $script:AdminPrincipalName = $($config.Provisioning.AdminPrincipalName)
    $script:AdminIdentityProvider = $($config.Provisioning.AdminIdentityProvider)
    if (-not $AdminIdentityProvider) { $script:AdminIdentityProvider = 'https://sts.windows.net/' }

    if ($AdminPrincipalName -eq $null)
    {
        throw "Admin principal name in web.config is null so stopping restore of Admin account. Please check Admin account in DB manually and update the web.config for Admin principal name."
    }
}

function Invoke-SqlQueryWithLog($params)
{
    Write-LogWithoutEmail "Invoking SQL query:
$($params.Query)"
    try
    {
        return Invoke-SqlCmd @params -ErrorAction Stop
    }
    catch
    {
        Write-LogWithoutEmail "An exception occurred: $($_.Exception)"
    }
}

function Remove-DuplicateNetworkAliasAccounts($UserCount, $NetworkAlias)
{
    # Validate that Admin networkalias account is not duplicated.
    if ($UserCount -gt 1)
    {
        Write-LogWithoutEmail "Found $($UserCount) accounts with NetworkAlias '$($AdminPrincipalName)'. Removing duplicates (leaving only one record)..."

        # Remove duplicated records
        $target_sqlParams.Query = @"
            DELETE TOP($($UserCount-1)) FROM $($UserInfoTableName) WHERE NETWORKALIAS = '$AdminPrincipalName' 
"@
        Invoke-SqlQueryWithLog $target_sqlParams | out-null
        Write-LogWithoutEmail "Removed duplicated records for NetworkAlias '$($AdminPrincipalName)'."
    }
}

function Rename-AdminAccount()
{
    $PreviousAdminId = "OldAdmin{0:yyyyMMddHHmm}" -f [DateTime]::UtcNow

    # Update id of current admin account to different id
    $target_sqlParams.Query = @"
    UPDATE $($UserInfoTableName) set ID = '$PreviousAdminId' WHERE ID = 'Admin'
"@
    Invoke-SqlQueryWithLog $target_sqlParams | Out-Null
    Write-LogWithoutEmail "Updated id of existing Admin account. New id is '$($PreviousAdminId)'."
}

function Set-AccountAsAdmin($NetworkAlias)
{
    Write-LogWithoutEmail "Updating ID (to 'Admin') and enabling account with NetworkAlias '$($NetworkAlias)'..."

    # Enable and update id of the user with networkalias of admin principal name to 'Admin' 
    $target_sqlParams.Query = @"
        UPDATE $($UserInfoTableName) set Enable = 1, ID = 'Admin' WHERE NETWORKALIAS = '$NetworkAlias'
"@
    Invoke-SqlQueryWithLog $target_sqlParams | Out-Null
    Write-LogWithoutEmail "Updated id of account with NetworkAlias '$($NetworkAlias)'."
}

function Test-DoesNetworkAliasMatchTenantId($NetworkAlias)
{
    if (-not [string]::IsNullOrEmpty($NetworkAlias))
    {
        $NetworkAliasDomainSuffix = $NetworkAlias.SubString($NetworkAlias.IndexOf('@') + 1)

        # Validate that admin is the same provisioning admin and has the same domain as the tenant
        if ($NetworkAliasDomainSuffix -ne $TenantId)
        {
            Write-LogWithoutEmail "Admin in $($UserInfoTableName) has domain '$($NetworkAliasDomainSuffix)' in the NetworkAlias field, which doesn't match the 'Aad.AADTenantId' value in web.config: '$($TenantId)'."
        }
    }
}

function Write-LogWithoutEmail($LogMessage)
{
    # Regular expression from http://www.regular-expressions.info/email.html
    # Except we're not allowing ' to be the first character in the email address
    # since that messes with logging where we have a string like '<email address>' (single quotes included)
    # $1 in <email>@$1 is for the <Domain> capture group
    # meaning an email username@domain.com will be replaced with <email>@domain.com
    $LogMessageWithoutEmail = $LogMessage -replace "[a-z0-9!#\$%&*+/=?^_`{|}~-]+(?:\.[a-z0-9!#\$%&'*+/=?^_`{|}~-]+)*@(?<Domain>(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9]))?", '<email>@$1'
    Write-Log $LogMessageWithoutEmail
}

try
{
    Write-LogWithoutEmail "Restore Admin Account: Start"
    $error.Clear()

    Initialize-Settings

    Ensure-NoDuplicateAdminAccounts

    $adminUserCount = Get-UserCount -Id "Admin"
    if ($adminUserCount -eq 0)
    {
        Write-LogWithoutEmail "$($UserInfoTableName) has no Admin account. Need to create Admin account."
        Add-AdminAccount
    }
    else
    {
        Write-LogWithoutEmail "Validated that Admin account exists."
        
        $adminAccount = Get-AdminAccount
        $adminAccountNetworkAlias = $adminAccount.NETWORKALIAS
        Test-DoesNetworkAliasMatchTenantId -NetworkAlias $adminAccountNetworkAlias

        if ($adminAccountNetworkAlias -eq $AdminPrincipalName)
        {
            Write-LogWithoutEmail "Validated that admin network alias '$($adminAccountNetworkAlias)' matches the admin principal name '$($AdminPrincipalName)' in the config."
            Ensure-NoDuplicateNetworkAliasAccounts -NetworkAlias $AdminPrincipalName
        }
        else
        {
            Write-LogWithoutEmail "Admin network alias '$($adminAccountNetworkAlias)' in $($UserInfoTableName) is not the same as default provisioning admin principal name '$($AdminPrincipalName)'. Will update id of existing Admin account."
            Rename-AdminAccount

            $adminNetworkAliasUserCount = Get-UserCount -NetworkAlias $AdminPrincipalName

            # Validate if there is non admin account in USERINFO has same NETWORKALIAS with default provisioning admin principal name.
            if ($adminNetworkAliasUserCount -ge 1)
            {
                Remove-DuplicateNetworkAliasAccounts -UserCount $adminNetworkAliasUserCount -NetworkAlias $AdminPrincipalName
                Set-AccountAsAdmin -NetworkAlias $AdminPrincipalName
            }
            else
            {
                Write-LogWithoutEmail "No account found with NetworkAlias '$($AdminPrincipalName)'. Will create new Admin account record."
                Add-AdminAccount
            }
        }
    }

    $adminAccount = Get-AdminAccount
    Ensure-AdminAccountIsEnabled -AdminAccount $adminAccount
    Ensure-AdminAccountHasCorrectSID -AdminAccount $adminAccount
    Ensure-AdminAccountHasCorrectNetworkDomain -AdminAccount $adminAccount
}
Catch
{
    # Write the exception and that this process failed.  
    # Do not throw as this should not cause the deployment or update to fail.
    Write-Exception $_
    Write-LogWithoutEmail "Restore Admin Account failed, see $log for details."
}
Finally
{
    Write-LogWithoutEmail "Restore Admin Account: Stop"
}

# SIG # Begin signature block
# MIIr5AYJKoZIhvcNAQcCoIIr1TCCK9ECAQExDzANBglghkgBZQMEAgEFADB5Bgor
# BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG
# KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCBixKloG51Xld+P
# iHfYWRDWZcIge70qnkaDkV/xoMTj2KCCEW4wggh+MIIHZqADAgECAhM2AAACAO38
# jbec3qFIAAIAAAIAMA0GCSqGSIb3DQEBCwUAMEExEzARBgoJkiaJk/IsZAEZFgNH
# QkwxEzARBgoJkiaJk/IsZAEZFgNBTUUxFTATBgNVBAMTDEFNRSBDUyBDQSAwMTAe
# Fw0yNDExMDgxMjQzMjhaFw0yNTExMDgxMjQzMjhaMCQxIjAgBgNVBAMTGU1pY3Jv
# c29mdCBBenVyZSBDb2RlIFNpZ24wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK
# AoIBAQC5L/UPrOpwYjxcoZC0TqqvMF1WUELvwXN+k27SrA5rohJknn7Cgbxg4hGT
# XKqpcdbtsVTN3ZY896SJ20uQ+INL5OVLzpW408nCNTPYg2LtGJbqHUjpNm0hLCJ+
# gO5Jn2T8DDzIJoUijGXj1m+hRLKb2nOIicCED2GuYBmuWXnaY7INmVEaU3peryty
# ZjDuxdyGDuiPURz8lW1SUiDzoszNp1oswVr+WjDvLDUx4HlxPsG8zUjIst0NnJ6o
# z4tNFKaUBDCetcMjQxpCETn29a1CuRddxZLjPHZHfcotr5sh1S6bNQdzVaMNsxV8
# L3wjHb7XJ6ZVm662mHEiPgpyNcLhAgMBAAGjggWKMIIFhjApBgkrBgEEAYI3FQoE
# HDAaMAwGCisGAQQBgjdbAQEwCgYIKwYBBQUHAwMwPQYJKwYBBAGCNxUHBDAwLgYm
# KwYBBAGCNxUIhpDjDYTVtHiE8Ys+hZvdFs6dEoFgg93NZoaUjDICAWQCAQ4wggJ2
# BggrBgEFBQcBAQSCAmgwggJkMGIGCCsGAQUFBzAChlZodHRwOi8vY3JsLm1pY3Jv
# c29mdC5jb20vcGtpaW5mcmEvQ2VydHMvQlkyUEtJQ1NDQTAxLkFNRS5HQkxfQU1F
# JTIwQ1MlMjBDQSUyMDAxKDIpLmNydDBSBggrBgEFBQcwAoZGaHR0cDovL2NybDEu
# YW1lLmdibC9haWEvQlkyUEtJQ1NDQTAxLkFNRS5HQkxfQU1FJTIwQ1MlMjBDQSUy
# MDAxKDIpLmNydDBSBggrBgEFBQcwAoZGaHR0cDovL2NybDIuYW1lLmdibC9haWEv
# QlkyUEtJQ1NDQTAxLkFNRS5HQkxfQU1FJTIwQ1MlMjBDQSUyMDAxKDIpLmNydDBS
# BggrBgEFBQcwAoZGaHR0cDovL2NybDMuYW1lLmdibC9haWEvQlkyUEtJQ1NDQTAx
# LkFNRS5HQkxfQU1FJTIwQ1MlMjBDQSUyMDAxKDIpLmNydDBSBggrBgEFBQcwAoZG
# aHR0cDovL2NybDQuYW1lLmdibC9haWEvQlkyUEtJQ1NDQTAxLkFNRS5HQkxfQU1F
# JTIwQ1MlMjBDQSUyMDAxKDIpLmNydDCBrQYIKwYBBQUHMAKGgaBsZGFwOi8vL0NO
# PUFNRSUyMENTJTIwQ0ElMjAwMSxDTj1BSUEsQ049UHVibGljJTIwS2V5JTIwU2Vy
# dmljZXMsQ049U2VydmljZXMsQ049Q29uZmlndXJhdGlvbixEQz1BTUUsREM9R0JM
# P2NBQ2VydGlmaWNhdGU/YmFzZT9vYmplY3RDbGFzcz1jZXJ0aWZpY2F0aW9uQXV0
# aG9yaXR5MB0GA1UdDgQWBBST/HE52ZUlmsYqZcZBdrXZ5u4ZnzAOBgNVHQ8BAf8E
# BAMCB4AwRQYDVR0RBD4wPKQ6MDgxHjAcBgNVBAsTFU1pY3Jvc29mdCBDb3Jwb3Jh
# dGlvbjEWMBQGA1UEBRMNMjM2MTY3KzUwMzE1NTCCAeYGA1UdHwSCAd0wggHZMIIB
# 1aCCAdGgggHNhj9odHRwOi8vY3JsLm1pY3Jvc29mdC5jb20vcGtpaW5mcmEvQ1JM
# L0FNRSUyMENTJTIwQ0ElMjAwMSgyKS5jcmyGMWh0dHA6Ly9jcmwxLmFtZS5nYmwv
# Y3JsL0FNRSUyMENTJTIwQ0ElMjAwMSgyKS5jcmyGMWh0dHA6Ly9jcmwyLmFtZS5n
# YmwvY3JsL0FNRSUyMENTJTIwQ0ElMjAwMSgyKS5jcmyGMWh0dHA6Ly9jcmwzLmFt
# ZS5nYmwvY3JsL0FNRSUyMENTJTIwQ0ElMjAwMSgyKS5jcmyGMWh0dHA6Ly9jcmw0
# LmFtZS5nYmwvY3JsL0FNRSUyMENTJTIwQ0ElMjAwMSgyKS5jcmyGgb1sZGFwOi8v
# L0NOPUFNRSUyMENTJTIwQ0ElMjAwMSgyKSxDTj1CWTJQS0lDU0NBMDEsQ049Q0RQ
# LENOPVB1YmxpYyUyMEtleSUyMFNlcnZpY2VzLENOPVNlcnZpY2VzLENOPUNvbmZp
# Z3VyYXRpb24sREM9QU1FLERDPUdCTD9jZXJ0aWZpY2F0ZVJldm9jYXRpb25MaXN0
# P2Jhc2U/b2JqZWN0Q2xhc3M9Y1JMRGlzdHJpYnV0aW9uUG9pbnQwHwYDVR0jBBgw
# FoAUllGE4Gtve/7YBqvD8oXmKa5q+dQwHwYDVR0lBBgwFgYKKwYBBAGCN1sBAQYI
# KwYBBQUHAwMwDQYJKoZIhvcNAQELBQADggEBAEDd8Wf5RkHsB64vgn2slxDtHzSo
# It9xN/Dm3RdFjNZ0diTUPMgSPYQlSk8nIAfudnB9FLavGlvZLlyUpfrPSuikepj3
# i3pqNEFn6fNdNFv/wHMxv7hQTIDCmuoR1v1rX+w3oeleBPMnN3QmH4ff1NsynyV4
# dZdYgN9Cw9sC/S3pWZpJrbOs7YOM3vqyU6DciHhC4D9i2zByHCF2pu9nYfiQf5A2
# iUZenRvyo1E5rC+UP2VZXa4k7g66W20+zAajIKKIqEmRtWahekMkCcOIHFBY4RDA
# ybgPRSGur4VDAiZPjTXS90wQXrX9CwU20cfiCC6e76F4H95KtQjKYpzuNVAwggjo
# MIIG0KADAgECAhMfAAAAUeqP9pxzDKg7AAAAAABRMA0GCSqGSIb3DQEBCwUAMDwx
# EzARBgoJkiaJk/IsZAEZFgNHQkwxEzARBgoJkiaJk/IsZAEZFgNBTUUxEDAOBgNV
# BAMTB2FtZXJvb3QwHhcNMjEwNTIxMTg0NDE0WhcNMjYwNTIxMTg1NDE0WjBBMRMw
# EQYKCZImiZPyLGQBGRYDR0JMMRMwEQYKCZImiZPyLGQBGRYDQU1FMRUwEwYDVQQD
# EwxBTUUgQ1MgQ0EgMDEwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDJ
# mlIJfQGejVbXKpcyFPoFSUllalrinfEV6JMc7i+bZDoL9rNHnHDGfJgeuRIYO1LY
# /1f4oMTrhXbSaYRCS5vGc8145WcTZG908bGDCWr4GFLc411WxA+Pv2rteAcz0eHM
# H36qTQ8L0o3XOb2n+x7KJFLokXV1s6pF/WlSXsUBXGaCIIWBXyEchv+sM9eKDsUO
# LdLTITHYJQNWkiryMSEbxqdQUTVZjEz6eLRLkofDAo8pXirIYOgM770CYOiZrcKH
# K7lYOVblx22pdNawY8Te6a2dfoCaWV1QUuazg5VHiC4p/6fksgEILptOKhx9c+ia
# piNhMrHsAYx9pUtppeaFAgMBAAGjggTcMIIE2DASBgkrBgEEAYI3FQEEBQIDAgAC
# MCMGCSsGAQQBgjcVAgQWBBQSaCRCIUfL1Gu+Mc8gpMALI38/RzAdBgNVHQ4EFgQU
# llGE4Gtve/7YBqvD8oXmKa5q+dQwggEEBgNVHSUEgfwwgfkGBysGAQUCAwUGCCsG
# AQUFBwMBBggrBgEFBQcDAgYKKwYBBAGCNxQCAQYJKwYBBAGCNxUGBgorBgEEAYI3
# CgMMBgkrBgEEAYI3FQYGCCsGAQUFBwMJBggrBgEFBQgCAgYKKwYBBAGCN0ABAQYL
# KwYBBAGCNwoDBAEGCisGAQQBgjcKAwQGCSsGAQQBgjcVBQYKKwYBBAGCNxQCAgYK
# KwYBBAGCNxQCAwYIKwYBBQUHAwMGCisGAQQBgjdbAQEGCisGAQQBgjdbAgEGCisG
# AQQBgjdbAwEGCisGAQQBgjdbBQEGCisGAQQBgjdbBAEGCisGAQQBgjdbBAIwGQYJ
# KwYBBAGCNxQCBAweCgBTAHUAYgBDAEEwCwYDVR0PBAQDAgGGMBIGA1UdEwEB/wQI
# MAYBAf8CAQAwHwYDVR0jBBgwFoAUKV5RXmSuNLnrrJwNp4x1AdEJCygwggFoBgNV
# HR8EggFfMIIBWzCCAVegggFToIIBT4YxaHR0cDovL2NybC5taWNyb3NvZnQuY29t
# L3BraWluZnJhL2NybC9hbWVyb290LmNybIYjaHR0cDovL2NybDIuYW1lLmdibC9j
# cmwvYW1lcm9vdC5jcmyGI2h0dHA6Ly9jcmwzLmFtZS5nYmwvY3JsL2FtZXJvb3Qu
# Y3JshiNodHRwOi8vY3JsMS5hbWUuZ2JsL2NybC9hbWVyb290LmNybIaBqmxkYXA6
# Ly8vQ049YW1lcm9vdCxDTj1BTUVSb290LENOPUNEUCxDTj1QdWJsaWMlMjBLZXkl
# MjBTZXJ2aWNlcyxDTj1TZXJ2aWNlcyxDTj1Db25maWd1cmF0aW9uLERDPUFNRSxE
# Qz1HQkw/Y2VydGlmaWNhdGVSZXZvY2F0aW9uTGlzdD9iYXNlP29iamVjdENsYXNz
# PWNSTERpc3RyaWJ1dGlvblBvaW50MIIBqwYIKwYBBQUHAQEEggGdMIIBmTBHBggr
# BgEFBQcwAoY7aHR0cDovL2NybC5taWNyb3NvZnQuY29tL3BraWluZnJhL2NlcnRz
# L0FNRVJvb3RfYW1lcm9vdC5jcnQwNwYIKwYBBQUHMAKGK2h0dHA6Ly9jcmwyLmFt
# ZS5nYmwvYWlhL0FNRVJvb3RfYW1lcm9vdC5jcnQwNwYIKwYBBQUHMAKGK2h0dHA6
# Ly9jcmwzLmFtZS5nYmwvYWlhL0FNRVJvb3RfYW1lcm9vdC5jcnQwNwYIKwYBBQUH
# MAKGK2h0dHA6Ly9jcmwxLmFtZS5nYmwvYWlhL0FNRVJvb3RfYW1lcm9vdC5jcnQw
# gaIGCCsGAQUFBzAChoGVbGRhcDovLy9DTj1hbWVyb290LENOPUFJQSxDTj1QdWJs
# aWMlMjBLZXklMjBTZXJ2aWNlcyxDTj1TZXJ2aWNlcyxDTj1Db25maWd1cmF0aW9u
# LERDPUFNRSxEQz1HQkw/Y0FDZXJ0aWZpY2F0ZT9iYXNlP29iamVjdENsYXNzPWNl
# cnRpZmljYXRpb25BdXRob3JpdHkwDQYJKoZIhvcNAQELBQADggIBAFAQI7dPD+jf
# XtGt3vJp2pyzA/HUu8hjKaRpM3opya5G3ocprRd7vdTHb8BDfRN+AD0YEmeDB5HK
# QoG6xHPI5TXuIi5sm/LeADbV3C2q0HQOygS/VT+m1W7a/752hMIn+L4ZuyxVeSBp
# fwf7oQ4YSZPh6+ngZvBHgfBaVz4O9/wcfw91QDZnTgK9zAh9yRKKls2bziPEnxeO
# ZMVNaxyV0v152PY2xjqIafIkUjK6vY9LtVFjJXenVUAmn3WCPWNFC1YTIIHw/mD2
# cTfPy7QA1pT+GPARAKt0bKtq9aCd/Ym0b5tPbpgCiRtzyb7fbNS1dE740re0COE6
# 7YV2wbeo2sXixzvLftH8L7s9xv9wV+G22qyKt6lmKLjFK1yMw4Ni5fMabcgmzRvS
# jAcbqgp3tk4a8emaaH0rz8MuuIP+yrxtREPXSqL/C5bzMzsikuDW9xH10graZzSm
# PjilzpRfRdu20/9UQmC7eVPZ4j1WNa1oqPHfzET3ChIzJ6Q9G3NPCB+7KwX0OQmK
# yv7IDimj8U/GlsHD1z+EF/fYMf8YXG15LamaOAohsw/ywO6SYSreVW+5Y0mzJutn
# BC9Cm9ozj1+/4kqksrlhZgR/CSxhFH3BTweH8gP2FEISRtShDZbuYymynY1un+Ry
# fiK9+iVTLdD1h/SxyxDpZMtimb4CgJQlMYIZzDCCGcgCAQEwWDBBMRMwEQYKCZIm
# iZPyLGQBGRYDR0JMMRMwEQYKCZImiZPyLGQBGRYDQU1FMRUwEwYDVQQDEwxBTUUg
# Q1MgQ0EgMDECEzYAAAIA7fyNt5zeoUgAAgAAAgAwDQYJYIZIAWUDBAIBBQCgga4w
# GQYJKoZIhvcNAQkDMQwGCisGAQQBgjcCAQQwHAYKKwYBBAGCNwIBCzEOMAwGCisG
# AQQBgjcCARUwLwYJKoZIhvcNAQkEMSIEICY7wWrP9D9SZq7vFUcRARSzevphmZdf
# 9xgkaTHZOL7+MEIGCisGAQQBgjcCAQwxNDAyoBSAEgBNAGkAYwByAG8AcwBvAGYA
# dKEagBhodHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20wDQYJKoZIhvcNAQEBBQAEggEA
# t9n1sIX2oPdoulH4Wp8IrKvsmIP7Ug3aQsxI3UgQTL3uG3FZ1lo5qFaoLovcn/nQ
# 4UzlvU2KOKH5HDXLMPfPdC0EbArcQ5xWsrgjlAulMfp4Cj0c+WFrrZIirzyxwRbC
# 9J3JrWYJ28SYcHn+wvN6FWauiv4kqt3baYv9YsUELYsTCupMGugUq8R/pVlXqpLG
# /BvZwf3Bazza0kLbQPq7lF5Oto7OkT6XeIaeyhkTorwG30L6giQotP9lE4beXGR8
# VYgMjQPq5SDhWhdVT8ulofnY4u91h4dQWzYkoCx9gmzzgbltNS4T7bDfXJWTDl+g
# VO4u1B8r6S1sL/dArvIp3qGCF5QwgheQBgorBgEEAYI3AwMBMYIXgDCCF3wGCSqG
# SIb3DQEHAqCCF20wghdpAgEDMQ8wDQYJYIZIAWUDBAIBBQAwggFSBgsqhkiG9w0B
# CRABBKCCAUEEggE9MIIBOQIBAQYKKwYBBAGEWQoDATAxMA0GCWCGSAFlAwQCAQUA
# BCAK7BwmIvXg2tEY+g2cR4NaMGRxB5l+l/UysK4n/qU8mgIGaBjD3p6/GBMyMDI1
# MDUwOTExMjIwMS45MDFaMASAAgH0oIHRpIHOMIHLMQswCQYDVQQGEwJVUzETMBEG
# A1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWlj
# cm9zb2Z0IENvcnBvcmF0aW9uMSUwIwYDVQQLExxNaWNyb3NvZnQgQW1lcmljYSBP
# cGVyYXRpb25zMScwJQYDVQQLEx5uU2hpZWxkIFRTUyBFU046RjAwMi0wNUUwLUQ5
# NDcxJTAjBgNVBAMTHE1pY3Jvc29mdCBUaW1lLVN0YW1wIFNlcnZpY2WgghHqMIIH
# IDCCBQigAwIBAgITMwAAAgU8dWyCRIfN/gABAAACBTANBgkqhkiG9w0BAQsFADB8
# MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVk
# bW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSYwJAYDVQQDEx1N
# aWNyb3NvZnQgVGltZS1TdGFtcCBQQ0EgMjAxMDAeFw0yNTAxMzAxOTQyNDlaFw0y
# NjA0MjIxOTQyNDlaMIHLMQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3Rv
# bjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0
# aW9uMSUwIwYDVQQLExxNaWNyb3NvZnQgQW1lcmljYSBPcGVyYXRpb25zMScwJQYD
# VQQLEx5uU2hpZWxkIFRTUyBFU046RjAwMi0wNUUwLUQ5NDcxJTAjBgNVBAMTHE1p
# Y3Jvc29mdCBUaW1lLVN0YW1wIFNlcnZpY2UwggIiMA0GCSqGSIb3DQEBAQUAA4IC
# DwAwggIKAoICAQCSkvLfd7gF1r2wGdy85CFYXHUC8ywEyD4LRLv0WYEXeeZ0u5Yu
# K7p2cXVzQmZPOHTN8TWqG2SPlUb+7PldzFDDAlR3vU8piOjmhu9rHW43M2dbor9j
# l9gluhzwUd2SciVGa7f9t67tM3KFKRSMXFtHKF3KwBB7aVo+b1qy5p9DWlo2N5FG
# rBqHMEVlNyzreHYoDLL+m8fSsqMu/iYUqxzK5F4S7IY5NemAB8B+A3QgwVIi64KJ
# IfeKZUeiWKCTf4odUgP3AQilxh48P6z7AT4IA0dMEtKhYLFs4W/KNDMsYr7KpQPK
# VCcC5E8uDHdKewubyzenkTxy4ff1N3g8yho5Pi9BfjR0VytrkmpDfep8JPwcb4BN
# OIXOo1pfdHZ8EvnR7JFZFQiqpMZFlO5CAuTYH8ujc5PUHlaMAJ8NEa9TFJTOSBrB
# 7PRgeh/6NJ2xu9yxPh/kVN9BGss93MC6UjpoxeM4x70bwbwiK8SNHIO8D8cql7VS
# evUYbjN4NogFFwhBClhodE/zeGPq6y6ixD4z65IHY3zwFQbBVX/w+L/VHNn/BMGs
# 2PGHnlRjO/Kk8NIpN4shkFQqA1fM08frrDSNEY9VKDtpsUpAF51Y1oQ6tJhWM1d3
# neCXh6b/6N+XeHORCwnY83K+pFMMhg8isXQb6KRl65kg8XYBd4JwkbKoVQIDAQAB
# o4IBSTCCAUUwHQYDVR0OBBYEFHR6Wrs27b6+yJ3bEZ9o5NdL1bLwMB8GA1UdIwQY
# MBaAFJ+nFV0AXmJdg/Tl0mWnG1M1GelyMF8GA1UdHwRYMFYwVKBSoFCGTmh0dHA6
# Ly93d3cubWljcm9zb2Z0LmNvbS9wa2lvcHMvY3JsL01pY3Jvc29mdCUyMFRpbWUt
# U3RhbXAlMjBQQ0ElMjAyMDEwKDEpLmNybDBsBggrBgEFBQcBAQRgMF4wXAYIKwYB
# BQUHMAKGUGh0dHA6Ly93d3cubWljcm9zb2Z0LmNvbS9wa2lvcHMvY2VydHMvTWlj
# cm9zb2Z0JTIwVGltZS1TdGFtcCUyMFBDQSUyMDIwMTAoMSkuY3J0MAwGA1UdEwEB
# /wQCMAAwFgYDVR0lAQH/BAwwCgYIKwYBBQUHAwgwDgYDVR0PAQH/BAQDAgeAMA0G
# CSqGSIb3DQEBCwUAA4ICAQAOuxk47b1i75V81Tx6xo10xNIr4zZxYVfkF5TFq2kn
# dPHgzVyLnssw/HKkEZRCgZVpkKEJ6Y4jvG5tugMi+Wjt7hUMSipk+RpB5gFQvh1x
# mAEL2flegzTWEsnj0wrESplI5Z3vgf2eGXAr/RcqGjSpouHbD2HY9Y3F0Ol6FRDC
# V/HEGKRHzn2M5rQpFGSjacT4DkqVYmem/ArOfSvVojnKEIW914UxGtuhJSr9jOo5
# RqTX7GIqbtvN7zhWld+i3XxdhdNcflQz9YhoFqQexBenoIRgAPAtwH68xczr9LMC
# 3l9ALEpnsvO0RiKPXF4l22/OfcFffaphnl/TDwkiJfxOyAMfUF3xI9+3izT1WX2C
# Fs2RaOAq3dcohyJw+xRG0E8wkCHqkV57BbUBEzLX8L9lGJ1DoxYNpoDX7iQzJ9Qd
# kypi5fv773E3Ch8A+toxeFp6FifQZyCc8IcIBlHyak6MbT6YTVQNgQ/h8FF+S5Oq
# P7CECFvIH2Kt2P0GlOu9C0BfashnTjodmtZFZsptUvirk/2HOLLjBiMjDwJsQAFA
# zJuz4ZtTyorrvER10Gl/mbmViHqhvNACfTzPiLfjDgyvp9s7/bHu/CalKmeiJULG
# jh/lwAj5319pggsGJqbhJ4FbFc+oU5zffbm/rKjVZ8kxND3im10Qp41n2t/qpyP6
# ETCCB3EwggVZoAMCAQICEzMAAAAVxedrngKbSZkAAAAAABUwDQYJKoZIhvcNAQEL
# BQAwgYgxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQH
# EwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xMjAwBgNV
# BAMTKU1pY3Jvc29mdCBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAyMDEwMB4X
# DTIxMDkzMDE4MjIyNVoXDTMwMDkzMDE4MzIyNVowfDELMAkGA1UEBhMCVVMxEzAR
# BgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1p
# Y3Jvc29mdCBDb3Jwb3JhdGlvbjEmMCQGA1UEAxMdTWljcm9zb2Z0IFRpbWUtU3Rh
# bXAgUENBIDIwMTAwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDk4aZM
# 57RyIQt5osvXJHm9DtWC0/3unAcH0qlsTnXIyjVX9gF/bErg4r25PhdgM/9cT8dm
# 95VTcVrifkpa/rg2Z4VGIwy1jRPPdzLAEBjoYH1qUoNEt6aORmsHFPPFdvWGUNzB
# RMhxXFExN6AKOG6N7dcP2CZTfDlhAnrEqv1yaa8dq6z2Nr41JmTamDu6GnszrYBb
# fowQHJ1S/rboYiXcag/PXfT+jlPP1uyFVk3v3byNpOORj7I5LFGc6XBpDco2LXCO
# Mcg1KL3jtIckw+DJj361VI/c+gVVmG1oO5pGve2krnopN6zL64NF50ZuyjLVwIYw
# XE8s4mKyzbnijYjklqwBSru+cakXW2dg3viSkR4dPf0gz3N9QZpGdc3EXzTdEonW
# /aUgfX782Z5F37ZyL9t9X4C626p+Nuw2TPYrbqgSUei/BQOj0XOmTTd0lBw0gg/w
# EPK3Rxjtp+iZfD9M269ewvPV2HM9Q07BMzlMjgK8QmguEOqEUUbi0b1qGFphAXPK
# Z6Je1yh2AuIzGHLXpyDwwvoSCtdjbwzJNmSLW6CmgyFdXzB0kZSU2LlQ+QuJYfM2
# BjUYhEfb3BvR/bLUHMVr9lxSUV0S2yW6r1AFemzFER1y7435UsSFF5PAPBXbGjfH
# CBUYP3irRbb1Hode2o+eFnJpxq57t7c+auIurQIDAQABo4IB3TCCAdkwEgYJKwYB
# BAGCNxUBBAUCAwEAATAjBgkrBgEEAYI3FQIEFgQUKqdS/mTEmr6CkTxGNSnPEP8v
# BO4wHQYDVR0OBBYEFJ+nFV0AXmJdg/Tl0mWnG1M1GelyMFwGA1UdIARVMFMwUQYM
# KwYBBAGCN0yDfQEBMEEwPwYIKwYBBQUHAgEWM2h0dHA6Ly93d3cubWljcm9zb2Z0
# LmNvbS9wa2lvcHMvRG9jcy9SZXBvc2l0b3J5Lmh0bTATBgNVHSUEDDAKBggrBgEF
# BQcDCDAZBgkrBgEEAYI3FAIEDB4KAFMAdQBiAEMAQTALBgNVHQ8EBAMCAYYwDwYD
# VR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAWgBTV9lbLj+iiXGJo0T2UkFvXzpoYxDBW
# BgNVHR8ETzBNMEugSaBHhkVodHRwOi8vY3JsLm1pY3Jvc29mdC5jb20vcGtpL2Ny
# bC9wcm9kdWN0cy9NaWNSb29DZXJBdXRfMjAxMC0wNi0yMy5jcmwwWgYIKwYBBQUH
# AQEETjBMMEoGCCsGAQUFBzAChj5odHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtp
# L2NlcnRzL01pY1Jvb0NlckF1dF8yMDEwLTA2LTIzLmNydDANBgkqhkiG9w0BAQsF
# AAOCAgEAnVV9/Cqt4SwfZwExJFvhnnJL/Klv6lwUtj5OR2R4sQaTlz0xM7U518Jx
# Nj/aZGx80HU5bbsPMeTCj/ts0aGUGCLu6WZnOlNN3Zi6th542DYunKmCVgADsAW+
# iehp4LoJ7nvfam++Kctu2D9IdQHZGN5tggz1bSNU5HhTdSRXud2f8449xvNo32X2
# pFaq95W2KFUn0CS9QKC/GbYSEhFdPSfgQJY4rPf5KYnDvBewVIVCs/wMnosZiefw
# C2qBwoEZQhlSdYo2wh3DYXMuLGt7bj8sCXgU6ZGyqVvfSaN0DLzskYDSPeZKPmY7
# T7uG+jIa2Zb0j/aRAfbOxnT99kxybxCrdTDFNLB62FD+CljdQDzHVG2dY3RILLFO
# Ry3BFARxv2T5JL5zbcqOCb2zAVdJVGTZc9d/HltEAY5aGZFrDZ+kKNxnGSgkujhL
# mm77IVRrakURR6nxt67I6IleT53S0Ex2tVdUCbFpAUR+fKFhbHP+CrvsQWY9af3L
# wUFJfn6Tvsv4O+S3Fb+0zj6lMVGEvL8CwYKiexcdFYmNcP7ntdAoGokLjzbaukz5
# m/8K6TT4JDVnK+ANuOaMmdbhIurwJ0I9JZTmdHRbatGePu1+oDEzfbzL6Xu/OHBE
# 0ZDxyKs6ijoIYn/ZcGNTTY3ugm2lBRDBcQZqELQdVTNYs6FwZvKhggNNMIICNQIB
# ATCB+aGB0aSBzjCByzELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24x
# EDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlv
# bjElMCMGA1UECxMcTWljcm9zb2Z0IEFtZXJpY2EgT3BlcmF0aW9uczEnMCUGA1UE
# CxMeblNoaWVsZCBUU1MgRVNOOkYwMDItMDVFMC1EOTQ3MSUwIwYDVQQDExxNaWNy
# b3NvZnQgVGltZS1TdGFtcCBTZXJ2aWNloiMKAQEwBwYFKw4DAhoDFQDVsH9p1tJn
# +krwCMvqOhVvXrbetKCBgzCBgKR+MHwxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpX
# YXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQg
# Q29ycG9yYXRpb24xJjAkBgNVBAMTHU1pY3Jvc29mdCBUaW1lLVN0YW1wIFBDQSAy
# MDEwMA0GCSqGSIb3DQEBCwUAAgUA68ffTTAiGA8yMDI1MDUwOTAxNTYyOVoYDzIw
# MjUwNTEwMDE1NjI5WjB0MDoGCisGAQQBhFkKBAExLDAqMAoCBQDrx99NAgEAMAcC
# AQACAkGrMAcCAQACAhLWMAoCBQDryTDNAgEAMDYGCisGAQQBhFkKBAIxKDAmMAwG
# CisGAQQBhFkKAwKgCjAIAgEAAgMHoSChCjAIAgEAAgMBhqAwDQYJKoZIhvcNAQEL
# BQADggEBAIW7RxRLVNQF2y7+6B3QaEQyiWCRXThSbQ2siM6HS2uiP1BXYQjPXm14
# j0v0505LEW3HpIUy2HBG9MjBI8KHRtkTDiB75OPhFndFFgfvuhY7v8foFo6X6yEc
# JZNixbotp6GBf7/oXHH+QdBkwbQMboAaf7YvmQtFBBOmkje0FMb81dJjrPQQVA37
# uLf/flNZiyaF6t6rEstW+4mh8RukAuA7nqho62t9pQVc0apyr5W1M57rdTQrX+WN
# bYqPiaKDtZnUleMly9zWo2OCKvhUVMQ4LOWyOilYhY9gK0mWTV+Gd2QRA2+4SdAv
# UUN1E9P0eh6ZDyu8Z/qY6gUUBWoYB6IxggQNMIIECQIBATCBkzB8MQswCQYDVQQG
# EwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwG
# A1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSYwJAYDVQQDEx1NaWNyb3NvZnQg
# VGltZS1TdGFtcCBQQ0EgMjAxMAITMwAAAgU8dWyCRIfN/gABAAACBTANBglghkgB
# ZQMEAgEFAKCCAUowGgYJKoZIhvcNAQkDMQ0GCyqGSIb3DQEJEAEEMC8GCSqGSIb3
# DQEJBDEiBCBKNRAbtAymUTfOUV+axYE45loFr89dgcY9Ln3h3ws5zzCB+gYLKoZI
# hvcNAQkQAi8xgeowgecwgeQwgb0EIIANAz3ceY0umhdWLR2sJpq0OPqtJDTAYRmj
# HVkwEW9IMIGYMIGApH4wfDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0
# b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3Jh
# dGlvbjEmMCQGA1UEAxMdTWljcm9zb2Z0IFRpbWUtU3RhbXAgUENBIDIwMTACEzMA
# AAIFPHVsgkSHzf4AAQAAAgUwIgQg34+t7cId4HpPjH+/ybVUQK32uKP6nACeUjC0
# g6kjUNYwDQYJKoZIhvcNAQELBQAEggIADdH3Yd2OKSzCIGz/2G7Dgdu2RdAOS5yh
# DkmreKQdKWW9W/iEe9V4n/cdvqYd4TXs3o7AUwBNGCIRqAlmK1EvUHTi006X3hsN
# Bj7Rcf1e1Tf8C3u4007kAwF01LhNCfICbQtuglHGf3uUpmaMGdXbuoAfe/NbWfBP
# 0ttuN5YcIurdViJFQWyiIF5Oo0RyFiaY8ha2B5cNTkPP7BMjg1umYds6SO10aCaG
# F8FSc+lrFzIy2pC/+FWtja9bnd0L9y16YtJ39t9Ys6hINxxz37duwIeiFGKVheM5
# z2PiB4MaPLBF0Y2398c7gCH9sJc0Q1UnvtVjYitGRMoAKacNIJlzftv0QHnVE2MJ
# BH3PLb41ALNnzNrko64D03zT7Wdsa1cNbWvj8z91RO0C5h3j+P5mk0v2j4+e91Gy
# lXg5CkYMWWb7q6tWI0APt9kJ3U9+uFRN+LmVupBtGNfSqr0HDvK73AcQvSqaosnW
# UHkMDWY+FO24A1/bQ6zVo3wBfZWYe5M6flT6uPP7soWxA76i/5sz4b8YYKkAiC5E
# TNyX7aex5EiG1TlysCUveG17s3F3i4BLMv5hWlv98KmdRvdxlYhgeNZl8gpeAn3A
# X7uP4vaDvgRnm0ys/bV6Z+Ts0G1bDf9EV2AWHCy6EqbW6j63bFgJ1/Qwiaf1U2BH
# zVGoE5IWfao=
# SIG # End signature block
