Microsoft.FastTrack.Migration.psm1

$location = (Get-ChildItem $($SCRIPT:MyInvocation.MyCommand.Path)).DirectoryName
Import-Module $location\Microsoft.FastTrack.Migration.Security.dll -WarningAction:Continue

$SelectedAuthorizationRole = "Production"
$DevApplicationID = "47bbabd4-d4ef-4842-922f-835839488d7c"
$UatApplicationID = "606a4358-ad5a-42fc-b178-603ed0e1740a"
$ProdApplicationID = "a6f3096b-d6ba-4b0c-b73b-b5b0e358285b"

$DevResourceUri = "https://microsoft.com/2505d69d-c321-44f1-a6ac-4ea35139d37a"
$UatResourceUri = "https://microsoft.com/60798afa-9459-421f-864f-93faf9956111"
$ProdResourceUri = "https://microsoft.com/5c0ba7b1-60bb-4b68-b7e8-1fe485344d5a"

$global:CsiApiBaseUriFormat = "https://msft-{0}-{1}.azurewebsites.net/api/{2}"
$global:v3BaseUrl = "https://msft-{0}-{1}.azurewebsites.net/api/v3"
$global:v3ApiKey = ""
$global:v3Headers = {}
$global:MsftApiKey = ""
$global:MsftAccessToken = ""
$global:MsoAdminProperties = @{ }
$global:MsoSovereignCloud = "AzureCloud"
$global:MsoComOrGov = "Commercial"
$global:UseVerbose = $false

Function VersionCheck {
    if ( $SCRIPT:SelectedAuthorizationRole.Equals("Production", [System.StringComparison]::CurrentCultureIgnoreCase) -ne $true) {
        Write-Host "Checking module's published version for ALPHA..." -ForegroundColor Cyan
        $publishedVersion = Find-Module -Name "Microsoft.FastTrack.Migration" -AllowPrerelease
        Write-Host "Checking module's installed version for ALPHA..." -ForegroundColor Cyan
        $currentVersion = Get-InstalledModule -Name "Microsoft.FastTrack.Migration" -AllowPrerelease
    }
    else {
        Write-Host "Checking module's published version..." -ForegroundColor Cyan
        $publishedVersion = Find-Module -Name "Microsoft.FastTrack.Migration"
        Write-Host "Checking module's installed version..." -ForegroundColor Cyan
        $currentVersion = Get-InstalledModule -Name "Microsoft.FastTrack.Migration"
    }

    if ($publishedVersion.Version -gt $currentVersion.Version) {
        Write-Warning "The current installed version [ $($currentVersion.Version) ] is older than the published version [ $($publishedVersion.Version) ]!"
        Write-Warning "It is required that you update to the current published version before continuing"
        Write-Warning "Please close this PowerShell session and restart in administrator mode then call `"Update-Module Microsoft.FastTrack.Migration`""
        $false
    }
    else { $true }
}

Function SetAccessTokenHash {
    param
    (
        [string] $ApiKey,
        [string] $TenantID
    )
    $StringBuilder = [System.Text.StringBuilder]::new()
    [System.Security.Cryptography.HashAlgorithm]::Create("SHA512").ComputeHash([System.Text.Encoding]::UTF8.GetBytes($TenantId + $ApiKey)) | ForEach-Object {
        [Void] $StringBuilder.Append($_.ToString("x2"))
    }

    return $StringBuilder.ToString().ToUpper()
}

Function SetAzureEnvironmentProperties {
    <#
.SYNOPSIS
    Set environment for user
.DESCRIPTION
    The Set-FastTrackEnvironment cmdlet sets the properties for the cloud environment in which to connect.
 
    The default environment is AzureCloud. If your organization is within another Azure environment, use the -Environment switch and select the appropriate environment.
.PARAMETER Azure Environment to utilize for all API calls and program environment specific requirements.
.EXAMPLE
    SetAzureEnvironmentProperties -AzureEnvironment $AzureEnvironment
.INPUTS
    System.String
.OUTPUTS
    None
.LINK
#>

    param
    (
        [string] $AzureEnvironment
    )

    switch ( $AzureEnvironment ) {
        "AzureCloud" {
            $global:MsoSovereignCloud = 'AzureCloud'
            $global:MsoComOrGov = "Commercial"
        }
        "AzureGermanCloud" {
            $global:MsoSovereignCloud = 'AzureGermanyCloud'
            $global:MsoComOrGov = "AzureGermanyCloud"
        }
    }
}

Function Login-FastTrackAccount {
    <#
.SYNOPSIS
    Connect to Azure with an authenticated account for use with FastTrack Customer Service cmdlet requests.
.DESCRIPTION
    The Login-FasttrackAccount cmdlet connects to Azure with an authenticated account for use with FastTrack Customer Service cmdlet requests.
 
    The default Azure environment is AzureCloud. If your organization is within another Azure environment, use the -Environment switch and select the appropriate environment.
.PARAMETER Environment
    Specifies the organizations Azure Cloud environment. "AzureCloud" is the default.
    Valid options: AzureCloud | AzureGermanCloud
    System.String
.OUTPUTS
    System.Management.Automation.PSObject
        This cmdlet generates a System.Management.Automation.PSObject.
.EXAMPLE
    Login-FastTrackAccount
.LINK
    Set-FastTrackEnvironment
#>

    param
    (
        [Parameter(Mandatory = $false, ValueFromPipeline = $true)]
        [string] $Environment = "AzureCloud"
    )

    [array]$environments = "AzureCloud", "AzureGermanCloud"

    $ApiKey = "0000000000"
    $isCurrent = VersionCheck

    if ($isCurrent -ne $true) { return; }

    if ($global:MsoAdminProperties.Count -gt 0) {
        Write-Warning "Unable to authenticate for Office 365 credentials!"
        Write-Warning "You must first remove the current PowerShell session before attempting another login..."
        return
    }

    if ($Environment -ne $null) {
        if ($environments.Contains($Environment)) {
            SetAzureEnvironmentProperties -AzureEnvironment $Environment
        }
        else {
            Write-Warning "Invalid [Environment] provided."
            Write-Warning "Please use one of the following options [AzureCloud | AzureGermanCloud]"
            return
        }
    }

    InitiateAzureADConnect

    if ($global:MsoAdminProperties.Count -eq 0) {
        Write-Warning "Unable to retrieve Office 365 credentials!"
        Write-Warning "If you are attempting to login to an alternate Azure cloud environment, you must first call function [Set-FastTrackEnvironment]"
    }
    else {
        $ApiKey = "0000000000" 
        $global:MsftApiKey = $ApiKey
        $global:MsftAccessToken = (SetAccessTokenHash -ApiKey: $ApiKey -TenantID: $global:MsoAdminProperties["MSO-CompanyTenantInfo"])
        
        Write-Host -ForegroundColor:Green "You have successfully logged into Office 365 as Tenant: $($global:MsoAdminProperties["MSO-CompanyInfo"].DisplayName)"
        Write-Host -ForegroundColor:Green "Run the following command to see a list of available functions."
        Write-Host -ForegroundColor:Green " Get-Command *FastTrack*"
    }
}

Function Set-FastTrackAuthorizationRole {
    <#
.SYNOPSIS
    Set the Azure Active Directory corresponding to environment - DEFAULT is production
.DESCRIPTION
    The default environment is Production. If you are wanting to test within another DEV or UAT, use the -AuthorizationRole switch and select the appropriate role.
.PARAMETER AuthorizationRole
    Specifies the AuthorizationRole. "Production" is the default.
    Valid options: Development | UserAcceptanceTesting | Production
.INPUTS
    System.String
.OUTPUTS
    void
.EXAMPLE
    Set-FastTrackAuthorizationRole
.LINK
    Login-FastTrackAccount
#>

    param(
        [Parameter(Mandatory = $false, ValueFromPipeline = $true)]
        [ValidateSet("Development", "UserAcceptanceTesting", "Production")]
        [string] $AuthorizationRole = "Production"
    )

    $SCRIPT:SelectedAuthorizationRole = $AuthorizationRole
    Write-Host "The Authorization Role has been set to [$SCRIPT:SelectedAuthorizationRole]" -ForegroundColor:Green
}

Function Set-FastTrackEnvironment {
    <#
.SYNOPSIS
    Set the Azure cloud corresponding to your subscription
.DESCRIPTION
    The Set-FastTrackEnvironment cmdlet sets the properties for the cloud environment in which to connect.
 
    The default environment is AzureCloud. If your organization is within another Azure environment, use the -Environment switch and select the appropriate environment.
.PARAMETER AzureEnvironment
    Specifies the organizations Azure Cloud environment. "AzureCloud" is the default.
    Valid options: AzureCloud | AzureGermanCloud
.INPUTS
    System.String
.OUTPUTS
    System.Management.Automation.PSObject
        This cmdlet generates a System.Management.Automation.PSObject object that represents the Transaction ID.
.EXAMPLE
    Set-FastTrackEnvironment
.LINK
    Login-FastTrackAccount
#>

    param(
        [Parameter(Mandatory = $false, ValueFromPipeline = $true)]
        [ValidateSet("AzureCloud", "AzureGermanCloud")]
        [string] $AzureEnvironment = "AzureCloud"
    )

    SetAzureEnvironmentProperties -AzureEnvironment $AzureEnvironment
}

function InitiateAzureADConnect {
    <#
.SYNOPSIS
    Login for Azure AD
.DESCRIPTION
    The InitiateAzureADConnect cmdlet performs login operations for Azure AD.
.PARAMETER Credential used for Azure login and requires username and password information
.EXAMPLE
    InitiateAzureADConnect -Credential $credentials
.INPUTS
    PScredential
.OUTPUTS
    None
.LINK
#>

    param
    (
        [Parameter(Mandatory = $false, ValueFromPipeline = $true)]
        [pscredential] $Credential
    )

    try {
        $resourceUri = ""
        $applicationId = ""

        switch ($SCRIPT:SelectedAuthorizationRole) {
            "Development" {
                $resourceUri = $DevResourceUri
                $applicationId = $DevApplicationID
            }
            "UserAcceptanceTesting" {
                $resourceUri = $UatResourceUri
                $applicationId = $UatApplicationID
            }
            "Production" {
                $resourceUri = $ProdResourceUri
                $applicationId = $ProdApplicationID
            }
        }

        if ($SCRIPT:SelectedAuthorizationRole -eq "Development" -or $SCRIPT:SelectedAuthorizationRole -eq "UserAcceptanceTesting") {
            $apiVersion = "v2/"

            if ($SCRIPT:SelectedAuthorizationRole -eq "Development") {
                $global:CsiApiBaseUriFormat = [System.String]::Format($global:CsiApiBaseUriFormat, "cssp", "dev", $apiVersion)
                $global:v3BaseUrl  = [System.String]::Format($global:v3BaseUrl, "cssp", "dev")
                $global:v3ApiKey = "7c4451076e137d3dab32eb3db87925884243ce29263e88f952b9e7669a918b20"

                $global:v3Headers = @{}
                $global:v3Headers.Add("API_KEY", $global:v3ApiKey)
            }
            else {
                $global:CsiApiBaseUriFormat = [System.String]::Format($global:CsiApiBaseUriFormat, "csi", "uat", $apiVersion)
                $global:v3BaseUrl  = [System.String]::Format($global:v3BaseUrl, "csi", "uat")
                $global:v3ApiKey = "7c4451076e137d3dab32eb3db87925884243ce29263e88f952b9e7669a918b20"
                $global:v3Headers = @{}
                $global:v3Headers.Add("API_KEY", $global:v3ApiKey)
            }
            
        }
        else {
            $apiVersion = "v2/"

            $global:CsiApiBaseUriFormat = [System.String]::Format($global:CsiApiBaseUriFormat, "cssp", "prod", $apiVersion)
            $global:v3BaseUrl  = [System.String]::Format($global:v3BaseUrl, "cssp", "prod")
            $global:v3ApiKey = "7c4451076e137d3dab32eb3db87925884243ce29263e88f952b9e7669a918b20"
            $global:v3Headers = @{}
            $global:v3Headers.Add("API_KEY", $global:v3ApiKey)
        }

        $multiTenantAuth = Connect-FastTrackLogin `
            -ResourceUri $resourceUri `
            -ApplicationReplyUrl:"https://login.live.com/oauth20_desktop.srf" `
            -ApplicationID $applicationId `
            -Verbose: $global:UseVerbose

        #We need to solve for GOV here still...
        $tenantInfo = $multiTenantAuth.UserInfo.IdentityProvider.Split("/")[$multiTenantAuth.UserInfo.IdentityProvider.Split("/").Count - 2]
        $companyInfo = (New-Object PSObject | Add-Member -PassThru NoteProperty DisplayName ($multiTenantAuth.UserInfo.DisplayableId.Split("@".ToCharArray())[1]))
        $adminUser = $multiTenantAuth.UserInfo.DisplayableId

        $global:MsoAdminProperties.Add("AuthorizationResult", $multiTenantAuth)
        $global:MsoAdminProperties.Add("MSO-CompanyInfo", $companyInfo)
        $global:MsoAdminProperties.Add("MSO-CompanyTenantInfo", $tenantInfo.ToString().ToUpper())
        $global:MsoAdminProperties.Add("MSO-AdminUser", $adminUser)
        $global:MsoAdminProperties.Add("MSO-LoggedOnUser", (New-Object PSObject | Add-Member -PassThru NoteProperty Account $multiTenantAuth.UserInfo.DisplayableId ))
    }
    catch {
        #Swallow exception - let parent method handle...
    }
}
# SIG # Begin signature block
# MIIjhAYJKoZIhvcNAQcCoIIjdTCCI3ECAQExDzANBglghkgBZQMEAgEFADB5Bgor
# BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG
# KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCDts+V0J5MY1YSe
# +dsoZxpMYJ/Yvr0Ioqvw2xGn0Co93aCCDYEwggX/MIID56ADAgECAhMzAAABUZ6N
# j0Bxow5BAAAAAAFRMA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNVBAYTAlVTMRMwEQYD
# VQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNy
# b3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMTH01pY3Jvc29mdCBDb2RlIFNpZ25p
# bmcgUENBIDIwMTEwHhcNMTkwNTAyMjEzNzQ2WhcNMjAwNTAyMjEzNzQ2WjB0MQsw
# CQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9u
# ZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMR4wHAYDVQQDExVNaWNy
# b3NvZnQgQ29ycG9yYXRpb24wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
# AQCVWsaGaUcdNB7xVcNmdfZiVBhYFGcn8KMqxgNIvOZWNH9JYQLuhHhmJ5RWISy1
# oey3zTuxqLbkHAdmbeU8NFMo49Pv71MgIS9IG/EtqwOH7upan+lIq6NOcw5fO6Os
# +12R0Q28MzGn+3y7F2mKDnopVu0sEufy453gxz16M8bAw4+QXuv7+fR9WzRJ2CpU
# 62wQKYiFQMfew6Vh5fuPoXloN3k6+Qlz7zgcT4YRmxzx7jMVpP/uvK6sZcBxQ3Wg
# B/WkyXHgxaY19IAzLq2QiPiX2YryiR5EsYBq35BP7U15DlZtpSs2wIYTkkDBxhPJ
# IDJgowZu5GyhHdqrst3OjkSRAgMBAAGjggF+MIIBejAfBgNVHSUEGDAWBgorBgEE
# AYI3TAgBBggrBgEFBQcDAzAdBgNVHQ4EFgQUV4Iarkq57esagu6FUBb270Zijc8w
# UAYDVR0RBEkwR6RFMEMxKTAnBgNVBAsTIE1pY3Jvc29mdCBPcGVyYXRpb25zIFB1
# ZXJ0byBSaWNvMRYwFAYDVQQFEw0yMzAwMTIrNDU0MTM1MB8GA1UdIwQYMBaAFEhu
# ZOVQBdOCqhc3NyK1bajKdQKVMFQGA1UdHwRNMEswSaBHoEWGQ2h0dHA6Ly93d3cu
# bWljcm9zb2Z0LmNvbS9wa2lvcHMvY3JsL01pY0NvZFNpZ1BDQTIwMTFfMjAxMS0w
# Ny0wOC5jcmwwYQYIKwYBBQUHAQEEVTBTMFEGCCsGAQUFBzAChkVodHRwOi8vd3d3
# Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2NlcnRzL01pY0NvZFNpZ1BDQTIwMTFfMjAx
# MS0wNy0wOC5jcnQwDAYDVR0TAQH/BAIwADANBgkqhkiG9w0BAQsFAAOCAgEAWg+A
# rS4Anq7KrogslIQnoMHSXUPr/RqOIhJX+32ObuY3MFvdlRElbSsSJxrRy/OCCZdS
# se+f2AqQ+F/2aYwBDmUQbeMB8n0pYLZnOPifqe78RBH2fVZsvXxyfizbHubWWoUf
# NW/FJlZlLXwJmF3BoL8E2p09K3hagwz/otcKtQ1+Q4+DaOYXWleqJrJUsnHs9UiL
# crVF0leL/Q1V5bshob2OTlZq0qzSdrMDLWdhyrUOxnZ+ojZ7UdTY4VnCuogbZ9Zs
# 9syJbg7ZUS9SVgYkowRsWv5jV4lbqTD+tG4FzhOwcRQwdb6A8zp2Nnd+s7VdCuYF
# sGgI41ucD8oxVfcAMjF9YX5N2s4mltkqnUe3/htVrnxKKDAwSYliaux2L7gKw+bD
# 1kEZ/5ozLRnJ3jjDkomTrPctokY/KaZ1qub0NUnmOKH+3xUK/plWJK8BOQYuU7gK
# YH7Yy9WSKNlP7pKj6i417+3Na/frInjnBkKRCJ/eYTvBH+s5guezpfQWtU4bNo/j
# 8Qw2vpTQ9w7flhH78Rmwd319+YTmhv7TcxDbWlyteaj4RK2wk3pY1oSz2JPE5PNu
# Nmd9Gmf6oePZgy7Ii9JLLq8SnULV7b+IP0UXRY9q+GdRjM2AEX6msZvvPCIoG0aY
# HQu9wZsKEK2jqvWi8/xdeeeSI9FN6K1w4oVQM4Mwggd6MIIFYqADAgECAgphDpDS
# AAAAAAADMA0GCSqGSIb3DQEBCwUAMIGIMQswCQYDVQQGEwJVUzETMBEGA1UECBMK
# V2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0
# IENvcnBvcmF0aW9uMTIwMAYDVQQDEylNaWNyb3NvZnQgUm9vdCBDZXJ0aWZpY2F0
# ZSBBdXRob3JpdHkgMjAxMTAeFw0xMTA3MDgyMDU5MDlaFw0yNjA3MDgyMTA5MDla
# MH4xCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdS
# ZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMT
# H01pY3Jvc29mdCBDb2RlIFNpZ25pbmcgUENBIDIwMTEwggIiMA0GCSqGSIb3DQEB
# AQUAA4ICDwAwggIKAoICAQCr8PpyEBwurdhuqoIQTTS68rZYIZ9CGypr6VpQqrgG
# OBoESbp/wwwe3TdrxhLYC/A4wpkGsMg51QEUMULTiQ15ZId+lGAkbK+eSZzpaF7S
# 35tTsgosw6/ZqSuuegmv15ZZymAaBelmdugyUiYSL+erCFDPs0S3XdjELgN1q2jz
# y23zOlyhFvRGuuA4ZKxuZDV4pqBjDy3TQJP4494HDdVceaVJKecNvqATd76UPe/7
# 4ytaEB9NViiienLgEjq3SV7Y7e1DkYPZe7J7hhvZPrGMXeiJT4Qa8qEvWeSQOy2u
# M1jFtz7+MtOzAz2xsq+SOH7SnYAs9U5WkSE1JcM5bmR/U7qcD60ZI4TL9LoDho33
# X/DQUr+MlIe8wCF0JV8YKLbMJyg4JZg5SjbPfLGSrhwjp6lm7GEfauEoSZ1fiOIl
# XdMhSz5SxLVXPyQD8NF6Wy/VI+NwXQ9RRnez+ADhvKwCgl/bwBWzvRvUVUvnOaEP
# 6SNJvBi4RHxF5MHDcnrgcuck379GmcXvwhxX24ON7E1JMKerjt/sW5+v/N2wZuLB
# l4F77dbtS+dJKacTKKanfWeA5opieF+yL4TXV5xcv3coKPHtbcMojyyPQDdPweGF
# RInECUzF1KVDL3SV9274eCBYLBNdYJWaPk8zhNqwiBfenk70lrC8RqBsmNLg1oiM
# CwIDAQABo4IB7TCCAekwEAYJKwYBBAGCNxUBBAMCAQAwHQYDVR0OBBYEFEhuZOVQ
# BdOCqhc3NyK1bajKdQKVMBkGCSsGAQQBgjcUAgQMHgoAUwB1AGIAQwBBMAsGA1Ud
# DwQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFHItOgIxkEO5FAVO
# 4eqnxzHRI4k0MFoGA1UdHwRTMFEwT6BNoEuGSWh0dHA6Ly9jcmwubWljcm9zb2Z0
# LmNvbS9wa2kvY3JsL3Byb2R1Y3RzL01pY1Jvb0NlckF1dDIwMTFfMjAxMV8wM18y
# Mi5jcmwwXgYIKwYBBQUHAQEEUjBQME4GCCsGAQUFBzAChkJodHRwOi8vd3d3Lm1p
# Y3Jvc29mdC5jb20vcGtpL2NlcnRzL01pY1Jvb0NlckF1dDIwMTFfMjAxMV8wM18y
# Mi5jcnQwgZ8GA1UdIASBlzCBlDCBkQYJKwYBBAGCNy4DMIGDMD8GCCsGAQUFBwIB
# FjNodHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2RvY3MvcHJpbWFyeWNw
# cy5odG0wQAYIKwYBBQUHAgIwNB4yIB0ATABlAGcAYQBsAF8AcABvAGwAaQBjAHkA
# XwBzAHQAYQB0AGUAbQBlAG4AdAAuIB0wDQYJKoZIhvcNAQELBQADggIBAGfyhqWY
# 4FR5Gi7T2HRnIpsLlhHhY5KZQpZ90nkMkMFlXy4sPvjDctFtg/6+P+gKyju/R6mj
# 82nbY78iNaWXXWWEkH2LRlBV2AySfNIaSxzzPEKLUtCw/WvjPgcuKZvmPRul1LUd
# d5Q54ulkyUQ9eHoj8xN9ppB0g430yyYCRirCihC7pKkFDJvtaPpoLpWgKj8qa1hJ
# Yx8JaW5amJbkg/TAj/NGK978O9C9Ne9uJa7lryft0N3zDq+ZKJeYTQ49C/IIidYf
# wzIY4vDFLc5bnrRJOQrGCsLGra7lstnbFYhRRVg4MnEnGn+x9Cf43iw6IGmYslmJ
# aG5vp7d0w0AFBqYBKig+gj8TTWYLwLNN9eGPfxxvFX1Fp3blQCplo8NdUmKGwx1j
# NpeG39rz+PIWoZon4c2ll9DuXWNB41sHnIc+BncG0QaxdR8UvmFhtfDcxhsEvt9B
# xw4o7t5lL+yX9qFcltgA1qFGvVnzl6UJS0gQmYAf0AApxbGbpT9Fdx41xtKiop96
# eiL6SJUfq/tHI4D1nvi/a7dLl+LrdXga7Oo3mXkYS//WsyNodeav+vyL6wuA6mk7
# r/ww7QRMjt/fdW1jkT3RnVZOT7+AVyKheBEyIXrvQQqxP/uozKRdwaGIm1dxVk5I
# RcBCyZt2WwqASGv9eZ/BvW1taslScxMNelDNMYIVWTCCFVUCAQEwgZUwfjELMAkG
# A1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQx
# HjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEoMCYGA1UEAxMfTWljcm9z
# b2Z0IENvZGUgU2lnbmluZyBQQ0EgMjAxMQITMwAAAVGejY9AcaMOQQAAAAABUTAN
# BglghkgBZQMEAgEFAKCBrjAZBgkqhkiG9w0BCQMxDAYKKwYBBAGCNwIBBDAcBgor
# BgEEAYI3AgELMQ4wDAYKKwYBBAGCNwIBFTAvBgkqhkiG9w0BCQQxIgQgRGzX4zs0
# FtDH1eOBomDsGzuRxIfldkRRwFtdD2s2oIgwQgYKKwYBBAGCNwIBDDE0MDKgFIAS
# AE0AaQBjAHIAbwBzAG8AZgB0oRqAGGh0dHA6Ly93d3cubWljcm9zb2Z0LmNvbTAN
# BgkqhkiG9w0BAQEFAASCAQA0XbrCHPBzGvKMJykzJ5vltz8KBWyXh2rOsf2TUqyU
# PxdmBzNXhqr3pQqKgqCr661hBl6HYS4h3c46Zzc68qtZKCRSXGByg6a5oPMXdB7g
# m/cuj3ooQREAm9+JZgsfEYKyvBXqkSg01RcoXrvY4qQd5CSLeWANEcby8Ja6NGRm
# khhIDcCit5bD4sCm83+tmdG596z6X72MIWg7/2CXOnbtDURUJnWTVyDuoBQGv+W+
# DiXSm+jAZkT2DsqKiSUJrlQRiYW/dSdYrMLGqN93I73UnvlrtlAsQaZM6ropnD2x
# +22+ZdsLR+C6PbT/3K5713PVA/NPRw1BgFl+A2OVEu51oYIS4zCCEt8GCisGAQQB
# gjcDAwExghLPMIISywYJKoZIhvcNAQcCoIISvDCCErgCAQMxDzANBglghkgBZQME
# AgEFADCCAU8GCyqGSIb3DQEJEAEEoIIBPgSCATowggE2AgEBBgorBgEEAYRZCgMB
# MDEwDQYJYIZIAWUDBAIBBQAEIKKVhtvZxBpA4nO9ifRo4RNI2FXpmfCylbasBsbp
# 09N2AgZd++byG8MYETIwMjAwMTIwMTIzODU1LjhaMASAAgH0oIHQpIHNMIHKMQsw
# CQYDVQQGEwJVUzELMAkGA1UECBMCV0ExEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNV
# BAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEtMCsGA1UECxMkTWljcm9zb2Z0IEly
# ZWxhbmQgT3BlcmF0aW9ucyBMaW1pdGVkMSYwJAYDVQQLEx1UaGFsZXMgVFNTIEVT
# TjpBQjQxLTRCMjctRjAyNjElMCMGA1UEAxMcTWljcm9zb2Z0IFRpbWUtU3RhbXAg
# U2VydmljZaCCDjwwggTxMIID2aADAgECAhMzAAABDfUzh+rQjjj1AAAAAAENMA0G
# CSqGSIb3DQEBCwUAMHwxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9u
# MRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRp
# b24xJjAkBgNVBAMTHU1pY3Jvc29mdCBUaW1lLVN0YW1wIFBDQSAyMDEwMB4XDTE5
# MTAyMzIzMTkxN1oXDTIxMDEyMTIzMTkxN1owgcoxCzAJBgNVBAYTAlVTMQswCQYD
# VQQIEwJXQTEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENv
# cnBvcmF0aW9uMS0wKwYDVQQLEyRNaWNyb3NvZnQgSXJlbGFuZCBPcGVyYXRpb25z
# IExpbWl0ZWQxJjAkBgNVBAsTHVRoYWxlcyBUU1MgRVNOOkFCNDEtNEIyNy1GMDI2
# MSUwIwYDVQQDExxNaWNyb3NvZnQgVGltZS1TdGFtcCBTZXJ2aWNlMIIBIjANBgkq
# hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxN5OBIcVhfvfDvphu7GSTeHPHiDsIHl3
# tzzqdMQe28AWAoqzN7N8m/cJ4XBiz63nbGYjQ4UUwM5+sDldVphn3EJHGS1iEJSK
# 1KNheuxbx6IIbDf2vkX9nDrSD61gGDgtwbs6gi0KzXT3IqcAurCxwRodNizGT0Ih
# kmNcGF9w7uDt6TGe8Fwi3f0Hm5WJi++jP0TziBfxvVGiaEzM+vTYp7k+aHkBydVF
# XYb+9p7GNwjxkIwJz9YhaNxK4NlOjGNAXJad8CGvcgD1QhRSjVAfP0bc3epiIGNG
# Q0yA//qUyvdMwfz96hhq0VRgVVYU6e1vxbkw28ZZoYX46RUWxxQdvQIDAQABo4IB
# GzCCARcwHQYDVR0OBBYEFC8D+HeCF5sgtk4/nNw27b3CQnCeMB8GA1UdIwQYMBaA
# FNVjOlyKMZDzQ3t8RhvFM2hahW1VMFYGA1UdHwRPME0wS6BJoEeGRWh0dHA6Ly9j
# cmwubWljcm9zb2Z0LmNvbS9wa2kvY3JsL3Byb2R1Y3RzL01pY1RpbVN0YVBDQV8y
# MDEwLTA3LTAxLmNybDBaBggrBgEFBQcBAQROMEwwSgYIKwYBBQUHMAKGPmh0dHA6
# Ly93d3cubWljcm9zb2Z0LmNvbS9wa2kvY2VydHMvTWljVGltU3RhUENBXzIwMTAt
# MDctMDEuY3J0MAwGA1UdEwEB/wQCMAAwEwYDVR0lBAwwCgYIKwYBBQUHAwgwDQYJ
# KoZIhvcNAQELBQADggEBAH69eOAniNjYeid1syS0GQmT6dlf80wTgovbXdjshKB3
# CA9sLsmwHn7i0KHv0SChvgm6rPMdtUhSI2TieDroCvIsmLpTzyhHTAPRCCrJMmZB
# Q4j8gJ1yZzvptO1JigHqPOlW40Zcd1t156k/Y7oWbuek77M/geNt8j3jjgz1zPmV
# iT3NsGybwfyXr7DoHsI2y5vZXZK9TA05VGn1YvHm/+FmVhfGl0oa5tdmYmI/KEhz
# 0jZu53NdCrxs0FUL40lpS9eXOOXAjsSZhXT6y7nn7hSJMN57PXYICOMmokIybvlj
# MZpI+i8Fi9Fu/+WNkWXVRVs57j6EmYctHUf7j05pa24wggZxMIIEWaADAgECAgph
# CYEqAAAAAAACMA0GCSqGSIb3DQEBCwUAMIGIMQswCQYDVQQGEwJVUzETMBEGA1UE
# CBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9z
# b2Z0IENvcnBvcmF0aW9uMTIwMAYDVQQDEylNaWNyb3NvZnQgUm9vdCBDZXJ0aWZp
# Y2F0ZSBBdXRob3JpdHkgMjAxMDAeFw0xMDA3MDEyMTM2NTVaFw0yNTA3MDEyMTQ2
# NTVaMHwxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQH
# EwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xJjAkBgNV
# BAMTHU1pY3Jvc29mdCBUaW1lLVN0YW1wIFBDQSAyMDEwMIIBIjANBgkqhkiG9w0B
# AQEFAAOCAQ8AMIIBCgKCAQEAqR0NvHcRijog7PwTl/X6f2mUa3RUENWlCgCChfvt
# fGhLLF/Fw+Vhwna3PmYrW/AVUycEMR9BGxqVHc4JE458YTBZsTBED/FgiIRUQwzX
# Tbg4CLNC3ZOs1nMwVyaCo0UN0Or1R4HNvyRgMlhgRvJYR4YyhB50YWeRX4FUsc+T
# TJLBxKZd0WETbijGGvmGgLvfYfxGwScdJGcSchohiq9LZIlQYrFd/XcfPfBXday9
# ikJNQFHRD5wGPmd/9WbAA5ZEfu/QS/1u5ZrKsajyeioKMfDaTgaRtogINeh4HLDp
# mc085y9Euqf03GS9pAHBIAmTeM38vMDJRF1eFpwBBU8iTQIDAQABo4IB5jCCAeIw
# EAYJKwYBBAGCNxUBBAMCAQAwHQYDVR0OBBYEFNVjOlyKMZDzQ3t8RhvFM2hahW1V
# MBkGCSsGAQQBgjcUAgQMHgoAUwB1AGIAQwBBMAsGA1UdDwQEAwIBhjAPBgNVHRMB
# Af8EBTADAQH/MB8GA1UdIwQYMBaAFNX2VsuP6KJcYmjRPZSQW9fOmhjEMFYGA1Ud
# HwRPME0wS6BJoEeGRWh0dHA6Ly9jcmwubWljcm9zb2Z0LmNvbS9wa2kvY3JsL3By
# b2R1Y3RzL01pY1Jvb0NlckF1dF8yMDEwLTA2LTIzLmNybDBaBggrBgEFBQcBAQRO
# MEwwSgYIKwYBBQUHMAKGPmh0dHA6Ly93d3cubWljcm9zb2Z0LmNvbS9wa2kvY2Vy
# dHMvTWljUm9vQ2VyQXV0XzIwMTAtMDYtMjMuY3J0MIGgBgNVHSABAf8EgZUwgZIw
# gY8GCSsGAQQBgjcuAzCBgTA9BggrBgEFBQcCARYxaHR0cDovL3d3dy5taWNyb3Nv
# ZnQuY29tL1BLSS9kb2NzL0NQUy9kZWZhdWx0Lmh0bTBABggrBgEFBQcCAjA0HjIg
# HQBMAGUAZwBhAGwAXwBQAG8AbABpAGMAeQBfAFMAdABhAHQAZQBtAGUAbgB0AC4g
# HTANBgkqhkiG9w0BAQsFAAOCAgEAB+aIUQ3ixuCYP4FxAz2do6Ehb7Prpsz1Mb7P
# BeKp/vpXbRkws8LFZslq3/Xn8Hi9x6ieJeP5vO1rVFcIK1GCRBL7uVOMzPRgEop2
# zEBAQZvcXBf/XPleFzWYJFZLdO9CEMivv3/Gf/I3fVo/HPKZeUqRUgCvOA8X9S95
# gWXZqbVr5MfO9sp6AG9LMEQkIjzP7QOllo9ZKby2/QThcJ8ySif9Va8v/rbljjO7
# Yl+a21dA6fHOmWaQjP9qYn/dxUoLkSbiOewZSnFjnXshbcOco6I8+n99lmqQeKZt
# 0uGc+R38ONiU9MalCpaGpL2eGq4EQoO4tYCbIjggtSXlZOz39L9+Y1klD3ouOVd2
# onGqBooPiRa6YacRy5rYDkeagMXQzafQ732D8OE7cQnfXXSYIghh2rBQHm+98eEA
# 3+cxB6STOvdlR3jo+KhIq/fecn5ha293qYHLpwmsObvsxsvYgrRyzR30uIUBHoD7
# G4kqVDmyW9rIDVWZeodzOwjmmC3qjeAzLhIp9cAvVCch98isTtoouLGp25ayp0Ki
# yc8ZQU3ghvkqmqMRZjDTu3QyS99je/WZii8bxyGvWbWu3EQ8l1Bx16HSxVXjad5X
# wdHeMMD9zOZN+w2/XU/pnR4ZOC+8z1gFLu8NoFA12u8JJxzVs341Hgi62jbb01+P
# 3nSISRKhggLOMIICNwIBATCB+KGB0KSBzTCByjELMAkGA1UEBhMCVVMxCzAJBgNV
# BAgTAldBMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29y
# cG9yYXRpb24xLTArBgNVBAsTJE1pY3Jvc29mdCBJcmVsYW5kIE9wZXJhdGlvbnMg
# TGltaXRlZDEmMCQGA1UECxMdVGhhbGVzIFRTUyBFU046QUI0MS00QjI3LUYwMjYx
# JTAjBgNVBAMTHE1pY3Jvc29mdCBUaW1lLVN0YW1wIFNlcnZpY2WiIwoBATAHBgUr
# DgMCGgMVAABqjVsBZr4WvW409iyoeqCzNblKoIGDMIGApH4wfDELMAkGA1UEBhMC
# VVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNV
# BAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEmMCQGA1UEAxMdTWljcm9zb2Z0IFRp
# bWUtU3RhbXAgUENBIDIwMTAwDQYJKoZIhvcNAQEFBQACBQDhz+xGMCIYDzIwMjAw
# MTIwMTcwNzE4WhgPMjAyMDAxMjExNzA3MThaMHcwPQYKKwYBBAGEWQoEATEvMC0w
# CgIFAOHP7EYCAQAwCgIBAAICE5UCAf8wBwIBAAICEaEwCgIFAOHRPcYCAQAwNgYK
# KwYBBAGEWQoEAjEoMCYwDAYKKwYBBAGEWQoDAqAKMAgCAQACAwehIKEKMAgCAQAC
# AwGGoDANBgkqhkiG9w0BAQUFAAOBgQBTkgxx23JlyAeisMSvw5W7VuZSx8pHM0FN
# X7pbXOH+YriSFNaF0/VBjLirLFoxqQt/lVap9gbgdx86or0qMtkhm5sj2SZzgJMe
# 5aN62RrVqLRo7aWCcJhNed4uQbLruS2CDLwtUJL94kFufbEVJhWXJCDwH52bNkk1
# 1tSwPobfZjGCAw0wggMJAgEBMIGTMHwxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpX
# YXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQg
# Q29ycG9yYXRpb24xJjAkBgNVBAMTHU1pY3Jvc29mdCBUaW1lLVN0YW1wIFBDQSAy
# MDEwAhMzAAABDfUzh+rQjjj1AAAAAAENMA0GCWCGSAFlAwQCAQUAoIIBSjAaBgkq
# hkiG9w0BCQMxDQYLKoZIhvcNAQkQAQQwLwYJKoZIhvcNAQkEMSIEIOPaJb4NsS4X
# NW5Zls9uHG0Oys5w2pawvgXWdRWGPZkRMIH6BgsqhkiG9w0BCRACLzGB6jCB5zCB
# 5DCBvQQgYBSjauehxUWsQrtNg/vKNKEvV0XiQiEt4Y0f+6tapCkwgZgwgYCkfjB8
# MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVk
# bW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSYwJAYDVQQDEx1N
# aWNyb3NvZnQgVGltZS1TdGFtcCBQQ0EgMjAxMAITMwAAAQ31M4fq0I449QAAAAAB
# DTAiBCCOe01xO0BnGGKeMVBX9ZBACZlruMgZCglr8/UecGc7xjANBgkqhkiG9w0B
# AQsFAASCAQB2K/VLURIaJTA+zuqre6TGG7FEQxLE4YbxFXIurbRFOKPDUNubkilY
# SDm+P+lJRM0BSddXWeXAQ1gOkb4u6gOSQO7+aUvOTlc39TxHjBVSu+Hlw939BK4Q
# 559K5L4csIeBOSAJZ4E4OLcHw+RFtSdDnKGA/3Hy09VGhW+wlov5z2OsLrBFKaEH
# f0nOgHc8Mz3AmIGNweDnU8wuiHm4YR8HbeLUW6L2sBaOcnt9k5VNKG3lp5szB8fh
# eg7HqY+Zp8r0O7RKJPfY082q1GNySKt1MT2G9QVpi7lQ41gt63rdxaUa/CdbeZdn
# GiNyRHUHTNfPNu1QI4ZTHRosw75bfl+3
# SIG # End signature block