Private/AvailableReleases.ps1

function Assert-DotNetStewardPlatform {
    if ($env:OS -ne 'Windows_NT') {
        throw 'DotNetSteward manages official Windows EXE installers and can only run on Windows.'
    }

    if ($PSVersionTable.PSVersion -lt [version] '5.1') {
        throw 'PowerShell 5.1 or later is required.'
    }
}

function Get-NativeDotNetArchitecture {
    $architecture = $env:PROCESSOR_ARCHITEW6432
    if ([string]::IsNullOrWhiteSpace($architecture)) {
        $architecture = $env:PROCESSOR_ARCHITECTURE
    }

    switch -Regex ($architecture) {
        '^(?i:AMD64)$' { return 'x64' }
        '^(?i:ARM64)$' { return 'arm64' }
        '^(?i:X86)$' { return 'x86' }
        default {
            throw "The native Windows architecture '$architecture' is not supported."
        }
    }
}

function ConvertTo-DotNetChannels {
    param(
        [Parameter(Mandatory = $true)]
        [string[]] $Channels
    )

    foreach ($channel in $Channels) {
        if ($channel -match '^\d+$') {
            "$channel.0"
        }
        elseif ($channel -match '^\d+\.\d+$') {
            $channel
        }
        else {
            throw "Invalid .NET channel '$channel'. Use a major version such as 8 or a major/minor channel such as 8.0."
        }
    }
}

function Assert-SdkFeatureBands {
    param(
        [Parameter(Mandatory = $true)]
        [string[]] $VersionBands
    )

    foreach ($versionBand in $VersionBands) {
        if ($versionBand -notmatch '^\d+\.\d+\.\d+xx$') {
            throw "Invalid SDK feature band '$versionBand'. Use a feature band such as 8.0.4xx."
        }
    }
}

function Assert-ExactDotNetVersions {
    param(
        [Parameter(Mandatory = $true)]
        [string[]] $Versions
    )

    foreach ($version in $Versions) {
        [void] (New-SdkVersionInfo -Text $version)
    }
}

function Get-RequestedChannels {
    param(
        [string[]] $Channels,
        [string[]] $VersionBands,
        [string[]] $Versions
    )

    $requested = New-Object System.Collections.Generic.List[string]
    foreach ($channel in @($Channels)) {
        if ([string]::IsNullOrWhiteSpace($channel)) {
            continue
        }
        if (-not $requested.Contains($channel)) {
            $requested.Add($channel)
        }
    }
    foreach ($versionBand in @($VersionBands)) {
        if ([string]::IsNullOrWhiteSpace($versionBand)) {
            continue
        }
        $versionInfo = New-SdkVersionInfo -Text (
            $versionBand.Substring(0, $versionBand.Length - 2) + '00'
        )
        if (-not $requested.Contains($versionInfo.Channel)) {
            $requested.Add($versionInfo.Channel)
        }
    }
    foreach ($version in @($Versions)) {
        if ([string]::IsNullOrWhiteSpace($version)) {
            continue
        }
        $versionInfo = New-SdkVersionInfo -Text $version
        if (-not $requested.Contains($versionInfo.Channel)) {
            $requested.Add($versionInfo.Channel)
        }
        if ($versionInfo.Major -eq 1 -and $versionInfo.Minor -eq 0 -and
            -not $requested.Contains('1.1')) {
            $requested.Add('1.1')
        }
    }

    return $requested.ToArray()
}

function New-AvailableRelease {
    param(
        [Parameter(Mandatory = $true)]
        [object] $Installer,

        [Parameter(Mandatory = $true)]
        [object] $ChannelEntry,

        [Parameter(Mandatory = $true)]
        [string] $Architecture,

        [Parameter(Mandatory = $true)]
        [ValidateSet('Sdk', 'Runtime', 'AspNetCoreRuntime', 'WindowsDesktopRuntime')]
        [string] $ProductType
    )

    [pscustomobject] @{
        PSTypeName = 'DotNetSteward.AvailableRelease'
        ProductType = $ProductType
        ProductLabel = Get-DotNetProductLabel -ProductType $ProductType
        Version = $Installer.Version
        VersionInfo = $Installer.VersionInfo
        Channel = [string] $ChannelEntry.PSObject.Properties[
            'channel-version'
        ].Value
        FeatureBand = if ($ProductType -eq 'Sdk') {
            $Installer.VersionInfo.FeatureBandKey
        }
        else {
            $null
        }
        Architecture = $Architecture
        Rid = $Installer.Rid
        IsPrerelease = -not $Installer.VersionInfo.IsStable
        SupportPhase = Get-SupportPhase -ChannelEntry $ChannelEntry
        ReleaseType = Get-ReleaseType -ChannelEntry $ChannelEntry
        Url = $Installer.Url
        Hash = $Installer.Hash
        HashAlgorithm = $Installer.HashAlgorithm
    }
}

function Sort-AvailableReleases {
    param(
        [Parameter(Mandatory = $true)]
        [AllowEmptyCollection()]
        [object[]] $Releases
    )

    $sorted = New-Object System.Collections.Generic.List[object]
    foreach ($release in $Releases) {
        $insertAt = $sorted.Count
        for ($index = 0; $index -lt $sorted.Count; $index++) {
            $comparison = Compare-SdkVersion -Left $release.VersionInfo `
                -Right $sorted[$index].VersionInfo
            if ($comparison -gt 0) {
                $insertAt = $index
                break
            }
            if ($comparison -eq 0) {
                $productComparison = [string]::CompareOrdinal(
                    $release.ProductType,
                    $sorted[$index].ProductType
                )
                if ($productComparison -lt 0 -or
                    ($productComparison -eq 0 -and
                    [string]::CompareOrdinal(
                        $release.Architecture,
                        $sorted[$index].Architecture
                    ) -lt 0)) {
                    $insertAt = $index
                    break
                }
            }
        }
        $sorted.Insert($insertAt, $release)
    }

    return $sorted.ToArray()
}

function Select-AvailableReleases {
    param(
        [Parameter(Mandatory = $true)]
        [AllowEmptyCollection()]
        [object[]] $Releases,

        [string[]] $VersionBands,
        [string[]] $Versions,

        [Parameter(Mandatory = $true)]
        [bool] $IncludePreview,

        [Parameter(Mandatory = $true)]
        [bool] $AllVersions
    )

    $selected = @($Releases)
    $requestedVersions = @($Versions | Where-Object {
        -not [string]::IsNullOrWhiteSpace($_)
    })
    $requestedVersionBands = @($VersionBands | Where-Object {
        -not [string]::IsNullOrWhiteSpace($_)
    })
    if ($requestedVersions.Count -gt 0) {
        $selected = @($selected | Where-Object {
            $requestedVersions -contains $_.Version
        })
    }
    elseif ($requestedVersionBands.Count -gt 0) {
        $selected = @($selected | Where-Object {
            $requestedVersionBands -contains $_.VersionInfo.FeatureBandKey
        })
    }

    if ($requestedVersions.Count -eq 0 -and -not $IncludePreview) {
        $selected = @($selected | Where-Object { -not $_.IsPrerelease })
    }

    $unique = @{}
    foreach ($release in $selected) {
        $keyParts = @(
            $release.ProductType
            $release.Version
            $release.Rid
        )
        if ($requestedVersions.Count -eq 0) {
            $keyParts += $release.Channel
        }
        $key = $keyParts -join '|'
        if (-not $unique.ContainsKey($key)) {
            $unique[$key] = $release
        }
    }
    $selected = @($unique.Values)

    if ($AllVersions -or $requestedVersions.Count -gt 0) {
        return Sort-AvailableReleases -Releases $selected
    }

    $latestByGroup = @{}
    foreach ($release in $selected) {
        $groupParts = @(
            $release.ProductType
            $release.Channel
            $release.Rid
        )
        if ($requestedVersionBands.Count -gt 0) {
            $groupParts += $release.FeatureBand
        }
        $groupKey = $groupParts -join '|'
        if (-not $latestByGroup.ContainsKey($groupKey) -or
            (Compare-SdkVersion -Left $release.VersionInfo `
                -Right $latestByGroup[$groupKey].VersionInfo) -gt 0) {
            $latestByGroup[$groupKey] = $release
        }
    }

    return Sort-AvailableReleases -Releases @($latestByGroup.Values)
}

function Get-AvailableSdkReleases {
    param(
        [Parameter(Mandatory = $true)]
        [object[]] $ReleaseIndex,

        [Parameter(Mandatory = $true)]
        [string[]] $Architectures,

        [string[]] $Channels,
        [string[]] $VersionBands,
        [string[]] $Versions,

        [Parameter(Mandatory = $true)]
        [bool] $IncludePreview,

        [Parameter(Mandatory = $true)]
        [bool] $AllVersions
    )

    $requestedChannels = @(Get-RequestedChannels -Channels $Channels `
        -VersionBands $VersionBands -Versions $Versions)
    $metadataCache = @{}
    $available = New-Object System.Collections.Generic.List[object]

    foreach ($channelEntry in $ReleaseIndex) {
        $channelProperty = $channelEntry.PSObject.Properties['channel-version']
        if ($null -eq $channelProperty) {
            continue
        }
        $channel = [string] $channelProperty.Value
        if ($requestedChannels.Count -gt 0 -and
            $requestedChannels -notcontains $channel) {
            continue
        }

        foreach ($architecture in $Architectures) {
            $installers = @(Get-ChannelSdkInstallers -ChannelEntry $channelEntry `
                -Rid "win-$architecture" -MetadataCache $metadataCache)
            foreach ($installer in $installers) {
                $available.Add((New-AvailableRelease -Installer $installer `
                    -ChannelEntry $channelEntry -Architecture $architecture `
                    -ProductType Sdk))
            }
        }
    }

    return Select-AvailableReleases -Releases $available.ToArray() `
        -VersionBands $VersionBands -Versions $Versions `
        -IncludePreview $IncludePreview -AllVersions $AllVersions
}

function Get-AvailableRuntimeReleases {
    param(
        [Parameter(Mandatory = $true)]
        [object[]] $ReleaseIndex,

        [Parameter(Mandatory = $true)]
        [ValidateSet('Runtime', 'AspNetCoreRuntime', 'WindowsDesktopRuntime')]
        [string[]] $ProductTypes,

        [Parameter(Mandatory = $true)]
        [string[]] $Architectures,

        [string[]] $Channels,
        [string[]] $Versions,

        [Parameter(Mandatory = $true)]
        [bool] $IncludePreview,

        [Parameter(Mandatory = $true)]
        [bool] $AllVersions
    )

    $requestedChannels = @(Get-RequestedChannels -Channels $Channels `
        -Versions $Versions)
    $metadataCache = @{}
    $available = New-Object System.Collections.Generic.List[object]

    foreach ($channelEntry in $ReleaseIndex) {
        $channelProperty = $channelEntry.PSObject.Properties['channel-version']
        if ($null -eq $channelProperty) {
            continue
        }
        $channel = [string] $channelProperty.Value
        if ($requestedChannels.Count -gt 0 -and
            $requestedChannels -notcontains $channel) {
            continue
        }

        foreach ($architecture in $Architectures) {
            foreach ($productType in $ProductTypes) {
                $installers = @(Get-ChannelRuntimeInstallers `
                    -ChannelEntry $channelEntry -Rid "win-$architecture" `
                    -ProductType $productType -MetadataCache $metadataCache)
                foreach ($installer in $installers) {
                    $available.Add((New-AvailableRelease -Installer $installer `
                        -ChannelEntry $channelEntry -Architecture $architecture `
                        -ProductType $productType))
                }
            }
        }
    }

    return Select-AvailableReleases -Releases $available.ToArray() `
        -Versions $Versions -IncludePreview $IncludePreview `
        -AllVersions $AllVersions
}

function ConvertTo-DotNetInstallCandidates {
    param(
        [Parameter(Mandatory = $true)]
        [object[]] $Releases
    )

    foreach ($release in $Releases) {
        [pscustomobject] @{
            ProductType = $release.ProductType
            ProductLabel = $release.ProductLabel
            Architecture = $release.Architecture
            Band = if ($release.ProductType -eq 'Sdk') {
                $release.FeatureBand
            }
            else {
                $release.Channel
            }
            CurrentVersion = $null
            InstalledVersions = @()
            TargetVersion = $release.Version
            TargetVersionInfo = $release.VersionInfo
            Channel = $release.Channel
            SupportPhase = $release.SupportPhase
            Url = $release.Url
            Hash = $release.Hash
            HashAlgorithm = $release.HashAlgorithm
            Rid = $release.Rid
        }
    }
}

function Assert-RequestedReleasesResolved {
    param(
        [Parameter(Mandatory = $true)]
        [AllowEmptyCollection()]
        [object[]] $Releases,

        [Parameter(Mandatory = $true)]
        [ValidateSet('Channel', 'VersionBand', 'Version')]
        [string] $SelectorKind,

        [Parameter(Mandatory = $true)]
        [string[]] $Selectors,

        [Parameter(Mandatory = $true)]
        [string[]] $Architectures,

        [Parameter(Mandatory = $true)]
        [string[]] $ProductTypes
    )

    foreach ($productType in $ProductTypes) {
        foreach ($architecture in $Architectures) {
            foreach ($selector in $Selectors) {
                $match = @($Releases | Where-Object {
                    $release = $_
                    if ($release.ProductType -ne $productType -or
                        $release.Architecture -ne $architecture) {
                        return $false
                    }

                    switch ($SelectorKind) {
                        'Channel' { return $release.Channel -eq $selector }
                        'VersionBand' {
                            return $release.FeatureBand -eq $selector
                        }
                        'Version' { return $release.Version -eq $selector }
                    }
                })
                if ($match.Count -eq 0) {
                    $label = Get-DotNetProductLabel -ProductType $productType
                    throw "No official $architecture $label EXE installer was found for $SelectorKind '$selector'."
                }
            }
        }
    }
}

# SIG # Begin signature block
# MII9JwYJKoZIhvcNAQcCoII9GDCCPRQCAQExDzANBglghkgBZQMEAgEFADB5Bgor
# BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG
# KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCBg0y/+oR40K5kg
# L3voaaFZa/g6AEhNcWRryj4IT+8UxaCCIewwggXMMIIDtKADAgECAhBUmNLR1FsZ
# lUgTecgRwIeZMA0GCSqGSIb3DQEBDAUAMHcxCzAJBgNVBAYTAlVTMR4wHAYDVQQK
# ExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xSDBGBgNVBAMTP01pY3Jvc29mdCBJZGVu
# dGl0eSBWZXJpZmljYXRpb24gUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgMjAy
# MDAeFw0yMDA0MTYxODM2MTZaFw00NTA0MTYxODQ0NDBaMHcxCzAJBgNVBAYTAlVT
# MR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xSDBGBgNVBAMTP01pY3Jv
# c29mdCBJZGVudGl0eSBWZXJpZmljYXRpb24gUm9vdCBDZXJ0aWZpY2F0ZSBBdXRo
# b3JpdHkgMjAyMDCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBALORKgeD
# Bmf9np3gx8C3pOZCBH8Ppttf+9Va10Wg+3cL8IDzpm1aTXlT2KCGhFdFIMeiVPvH
# or+Kx24186IVxC9O40qFlkkN/76Z2BT2vCcH7kKbK/ULkgbk/WkTZaiRcvKYhOuD
# PQ7k13ESSCHLDe32R0m3m/nJxxe2hE//uKya13NnSYXjhr03QNAlhtTetcJtYmrV
# qXi8LW9J+eVsFBT9FMfTZRY33stuvF4pjf1imxUs1gXmuYkyM6Nix9fWUmcIxC70
# ViueC4fM7Ke0pqrrBc0ZV6U6CwQnHJFnni1iLS8evtrAIMsEGcoz+4m+mOJyoHI1
# vnnhnINv5G0Xb5DzPQCGdTiO0OBJmrvb0/gwytVXiGhNctO/bX9x2P29Da6SZEi3
# W295JrXNm5UhhNHvDzI9e1eM80UHTHzgXhgONXaLbZ7LNnSrBfjgc10yVpRnlyUK
# xjU9lJfnwUSLgP3B+PR0GeUw9gb7IVc+BhyLaxWGJ0l7gpPKWeh1R+g/OPTHU3mg
# trTiXFHvvV84wRPmeAyVWi7FQFkozA8kwOy6CXcjmTimthzax7ogttc32H83rwjj
# O3HbbnMbfZlysOSGM1l0tRYAe1BtxoYT2v3EOYI9JACaYNq6lMAFUSw0rFCZE4e7
# swWAsk0wAly4JoNdtGNz764jlU9gKL431VulAgMBAAGjVDBSMA4GA1UdDwEB/wQE
# AwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTIftJqhSobyhmYBAcnz1AQ
# T2ioojAQBgkrBgEEAYI3FQEEAwIBADANBgkqhkiG9w0BAQwFAAOCAgEAr2rd5hnn
# LZRDGU7L6VCVZKUDkQKL4jaAOxWiUsIWGbZqWl10QzD0m/9gdAmxIR6QFm3FJI9c
# Zohj9E/MffISTEAQiwGf2qnIrvKVG8+dBetJPnSgaFvlVixlHIJ+U9pW2UYXeZJF
# xBA2CFIpF8svpvJ+1Gkkih6PsHMNzBxKq7Kq7aeRYwFkIqgyuH4yKLNncy2RtNwx
# AQv3Rwqm8ddK7VZgxCwIo3tAsLx0J1KH1r6I3TeKiW5niB31yV2g/rarOoDXGpc8
# FzYiQR6sTdWD5jw4vU8w6VSp07YEwzJ2YbuwGMUrGLPAgNW3lbBeUU0i/OxYqujY
# lLSlLu2S3ucYfCFX3VVj979tzR/SpncocMfiWzpbCNJbTsgAlrPhgzavhgplXHT2
# 6ux6anSg8Evu75SjrFDyh+3XOjCDyft9V77l4/hByuVkrrOj7FjshZrM77nq81YY
# uVxzmq/FdxeDWds3GhhyVKVB0rYjdaNDmuV3fJZ5t0GNv+zcgKCf0Xd1WF81E+Al
# GmcLfc4l+gcK5GEh2NQc5QfGNpn0ltDGFf5Ozdeui53bFv0ExpK91IjmqaOqu/dk
# ODtfzAzQNb50GQOmxapMomE2gj4d8yu8l13bS3g7LfU772Aj6PXsCyM2la+YZr9T
# 03u4aUoqlmZpxJTG9F9urJh4iIAGXKKy7aIwggajMIIEi6ADAgECAhMzAAgr2Z9x
# i8O7kaQ7AAAACCvZMA0GCSqGSIb3DQEBDAUAMFoxCzAJBgNVBAYTAlVTMR4wHAYD
# VQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xKzApBgNVBAMTIk1pY3Jvc29mdCBJ
# RCBWZXJpZmllZCBDUyBFT0MgQ0EgMDQwHhcNMjYxMDEyMDYyMjUxWhcNMjYxMDE1
# MDYyMjUxWjBnMQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjERMA8G
# A1UEBxMISXNzYXF1YWgxFzAVBgNVBAoTDkRhbWlhbiBFZHdhcmRzMRcwFQYDVQQD
# Ew5EYW1pYW4gRWR3YXJkczCCAaIwDQYJKoZIhvcNAQEBBQADggGPADCCAYoCggGB
# AIomJ3JmdXDfPb8TVKcrN5Y31yAowbFp5k4YkCdSKhMWDwW6XDnESb3/RCAd1qze
# WoysMqJFCUpXsEosbCOLgGk43Xfcd+Gisik1Gh1LI3fuTUO7rUY+qASVFGcMGfaG
# cpHur3a9ozx4XvKfz+wAWOjlRWfAQ8L/LDAgGq95N7QNu60AtK04AzQ3h60jjFWc
# IEjqA0ow7Po/4Ck627qOO8Ypi7r4tyBXT/5YduFcoSoFXnmw3LOamy1tD55micXo
# +6wkiXlHPpP/q+0/v11l7srgX23fHUzjYK4K+NGftC0KCF/OEOuCVS8+htao4xMH
# MQDJiiTDDtx2yVRTDlwTde9BOn5CHMFY6K7f62L8aIJD9RqMfy0wSUf5QgLjxnat
# zaeObQiIIwy3LIjuHqUyB4ARTCK1iLAbS1rYs7bFiXZYqsnZUJzI6Tt5nBn2S5bN
# ij1mkCsj7khlrjJ1lCHD16cYiGeAz1bbM+HPqjX/7np+BIf79B+fVXp/jnrUe0yA
# 9QIDAQABo4IB0zCCAc8wDAYDVR0TAQH/BAIwADAOBgNVHQ8BAf8EBAMCB4AwOgYD
# VR0lBDMwMQYKKwYBBAGCN2EBAAYIKwYBBQUHAwMGGSsGAQQBgjdh8PiHLKGwwBPl
# htEVg5ShoiEwHQYDVR0OBBYEFO695zvjoAP+VYZjonSFbhHTvX5UMB8GA1UdIwQY
# MBaAFJrxVHd1DIcWN0agrN55+fR/wXjpMGcGA1UdHwRgMF4wXKBaoFiGVmh0dHA6
# Ly93d3cubWljcm9zb2Z0LmNvbS9wa2lvcHMvY3JsL01pY3Jvc29mdCUyMElEJTIw
# VmVyaWZpZWQlMjBDUyUyMEVPQyUyMENBJTIwMDQuY3JsMHQGCCsGAQUFBwEBBGgw
# ZjBkBggrBgEFBQcwAoZYaHR0cDovL3d3dy5taWNyb3NvZnQuY29tL3BraW9wcy9j
# ZXJ0cy9NaWNyb3NvZnQlMjBJRCUyMFZlcmlmaWVkJTIwQ1MlMjBFT0MlMjBDQSUy
# MDA0LmNydDBUBgNVHSAETTBLMEkGBFUdIAAwQTA/BggrBgEFBQcCARYzaHR0cDov
# L3d3dy5taWNyb3NvZnQuY29tL3BraW9wcy9Eb2NzL1JlcG9zaXRvcnkuaHRtMA0G
# CSqGSIb3DQEBDAUAA4ICAQAe7jGXSeClV2q/CGYfsh5QN4FXvDeuvJ5+gaxekkck
# o/tCXLqRgyj4u2J7tWB0eAMsxwiFeIAxeG5BKAMZVw4k5xwIziQ8xFc73Frbb0iw
# EQoIFpoOFq9nh0rdhok7xfYw0DpXIQEFi49wnorMdofEwHQhUF/U7eXwyC9acDTK
# f4Ks4o8wZ7t6R/O+mKikIU9pkWzx33jjIU/tbMieg/9yS4L4GD3bN3jNtYu+JLw2
# 5eTOtvMp5lkoLC7ESfX9UR7EzV5YLIhleaw0yBwQAOwsGl22gpesoydw4loQM92/
# 8gqlIu96o5bgew60dY5SpV1YnAFzM9wnNCB3gG1I9BtqQ9BeQHN3eA/QhwC8TbYJ
# uuCX58uvfrOpctQ+mN3FzhTd0xN16RgbdNUWNh23Es1A2ztpVRWz22tOvYCMEeOo
# kOAEIxuIt9WIXg8mPT7Wmitg6HYyygQmxCysAVlm5jXc6l+CAKRHgb5lpIJOQjWI
# czMDOSV9aSsvwTJc6qF/2aG797G5uyGjHb5qQgx7QDbciqnvuW8JfYT4bl/4vS2b
# TlA3kSHTDVusbMEa8ddvnr4xtNjyCYzy52uHxUcwt7rE0H7o/W8tDANQ0PkWwihf
# CJnpooi1GLvVAGz09LDQHqTJ12ROwLp0DGJmhGclR4B4c5lcx4CnZ+F9zBZVpQfb
# ADCCBqMwggSLoAMCAQICEzMACCvZn3GLw7uRpDsAAAAIK9kwDQYJKoZIhvcNAQEM
# BQAwWjELMAkGA1UEBhMCVVMxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlv
# bjErMCkGA1UEAxMiTWljcm9zb2Z0IElEIFZlcmlmaWVkIENTIEVPQyBDQSAwNDAe
# Fw0yNjEwMTIwNjIyNTFaFw0yNjEwMTUwNjIyNTFaMGcxCzAJBgNVBAYTAlVTMRMw
# EQYDVQQIEwpXYXNoaW5ndG9uMREwDwYDVQQHEwhJc3NhcXVhaDEXMBUGA1UEChMO
# RGFtaWFuIEVkd2FyZHMxFzAVBgNVBAMTDkRhbWlhbiBFZHdhcmRzMIIBojANBgkq
# hkiG9w0BAQEFAAOCAY8AMIIBigKCAYEAiiYncmZ1cN89vxNUpys3ljfXICjBsWnm
# ThiQJ1IqExYPBbpcOcRJvf9EIB3WrN5ajKwyokUJSlewSixsI4uAaTjdd9x34aKy
# KTUaHUsjd+5NQ7utRj6oBJUUZwwZ9oZyke6vdr2jPHhe8p/P7ABY6OVFZ8BDwv8s
# MCAar3k3tA27rQC0rTgDNDeHrSOMVZwgSOoDSjDs+j/gKTrbuo47ximLuvi3IFdP
# /lh24VyhKgVeebDcs5qbLW0PnmaJxej7rCSJeUc+k/+r7T+/XWXuyuBfbd8dTONg
# rgr40Z+0LQoIX84Q64JVLz6G1qjjEwcxAMmKJMMO3HbJVFMOXBN170E6fkIcwVjo
# rt/rYvxogkP1Gox/LTBJR/lCAuPGdq3Np45tCIgjDLcsiO4epTIHgBFMIrWIsBtL
# WtiztsWJdliqydlQnMjpO3mcGfZLls2KPWaQKyPuSGWuMnWUIcPXpxiIZ4DPVtsz
# 4c+qNf/uen4Eh/v0H59Ven+OetR7TID1AgMBAAGjggHTMIIBzzAMBgNVHRMBAf8E
# AjAAMA4GA1UdDwEB/wQEAwIHgDA6BgNVHSUEMzAxBgorBgEEAYI3YQEABggrBgEF
# BQcDAwYZKwYBBAGCN2Hw+IcsobDAE+WG0RWDlKGiITAdBgNVHQ4EFgQU7r3nO+Og
# A/5VhmOidIVuEdO9flQwHwYDVR0jBBgwFoAUmvFUd3UMhxY3RqCs3nn59H/BeOkw
# ZwYDVR0fBGAwXjBcoFqgWIZWaHR0cDovL3d3dy5taWNyb3NvZnQuY29tL3BraW9w
# cy9jcmwvTWljcm9zb2Z0JTIwSUQlMjBWZXJpZmllZCUyMENTJTIwRU9DJTIwQ0El
# MjAwNC5jcmwwdAYIKwYBBQUHAQEEaDBmMGQGCCsGAQUFBzAChlhodHRwOi8vd3d3
# Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2NlcnRzL01pY3Jvc29mdCUyMElEJTIwVmVy
# aWZpZWQlMjBDUyUyMEVPQyUyMENBJTIwMDQuY3J0MFQGA1UdIARNMEswSQYEVR0g
# ADBBMD8GCCsGAQUFBwIBFjNodHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpb3Bz
# L0RvY3MvUmVwb3NpdG9yeS5odG0wDQYJKoZIhvcNAQEMBQADggIBAB7uMZdJ4KVX
# ar8IZh+yHlA3gVe8N668nn6BrF6SRySj+0JcupGDKPi7Ynu1YHR4AyzHCIV4gDF4
# bkEoAxlXDiTnHAjOJDzEVzvcWttvSLARCggWmg4Wr2eHSt2GiTvF9jDQOlchAQWL
# j3Ceisx2h8TAdCFQX9Tt5fDIL1pwNMp/gqzijzBnu3pH876YqKQhT2mRbPHfeOMh
# T+1syJ6D/3JLgvgYPds3eM21i74kvDbl5M628ynmWSgsLsRJ9f1RHsTNXlgsiGV5
# rDTIHBAA7CwaXbaCl6yjJ3DiWhAz3b/yCqUi73qjluB7DrR1jlKlXVicAXMz3Cc0
# IHeAbUj0G2pD0F5Ac3d4D9CHALxNtgm64Jfny69+s6ly1D6Y3cXOFN3TE3XpGBt0
# 1RY2HbcSzUDbO2lVFbPba069gIwR46iQ4AQjG4i31YheDyY9PtaaK2DodjLKBCbE
# LKwBWWbmNdzqX4IApEeBvmWkgk5CNYhzMwM5JX1pKy/BMlzqoX/Zobv3sbm7IaMd
# vmpCDHtANtyKqe+5bwl9hPhuX/i9LZtOUDeRIdMNW6xswRrx12+evjG02PIJjPLn
# a4fFRzC3usTQfuj9by0MA1DQ+RbCKF8ImemiiLUYu9UAbPT0sNAepMnXZE7AunQM
# YmaEZyVHgHhzmVzHgKdn4X3MFlWlB9sAMIIHKDCCBRCgAwIBAgITMwAAABcnRQkL
# i4evxgAAAAAAFzANBgkqhkiG9w0BAQwFADBjMQswCQYDVQQGEwJVUzEeMBwGA1UE
# ChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTQwMgYDVQQDEytNaWNyb3NvZnQgSUQg
# VmVyaWZpZWQgQ29kZSBTaWduaW5nIFBDQSAyMDIxMB4XDTI2MDMyNjE4MTEzMVoX
# DTMxMDMyNjE4MTEzMVowWjELMAkGA1UEBhMCVVMxHjAcBgNVBAoTFU1pY3Jvc29m
# dCBDb3Jwb3JhdGlvbjErMCkGA1UEAxMiTWljcm9zb2Z0IElEIFZlcmlmaWVkIENT
# IEVPQyBDQSAwNDCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAILHZP4D
# D2YqAZXMn5OrQ8yfj0beK0ixilvHsKUtJEcV7VEQt09xnWwipY6GxJ/LrLKoRqkK
# UYf0l70VcDVxCBm++lBuSD5AidUuv/QQ+tUELCsz3qVtEjY/E14LBcb0uzJbaEbo
# pCCKe0OY0IGjjOkMivfvumVV1KWJmbpQHusfCa8GdHTZBPq2euparaKHMHqVElVM
# TO6HQ5p/Mgx4ydgzT7H697kQ4sd1+Kr4deIx/0lvtgse1iDIciIkDttNYuoVIsZp
# OHtmVvFuwtcD3U46ugSm/s6PMW67e2SkL0V+UDgOnYS6rj6o+bFSp8an5NfSAtEm
# n00k7PMguNxMPeuQUUVvFS/XHKDpq+K8UMu2goGEzZN3Xfy6YTWk05pxqe5Ji08c
# h5AeYHqFoWLrhq8sEvBNMCb9FuK3zrRwVdHvbCr7lCHiFKZ7MeopcRFY+lUF74A+
# sngipz5o94yYiSgJZlA7bYecs0VQVJeOLDIhuC+Uf8sgAkSpNp9PPENmAqGUtTvO
# vqDCyrdY2lxhAjo27FafCHdVUMPIXuidCoqzkuXtuV5U3RjxW+qATjmmnIFu/Co3
# 9G6fl8wIJHPdpgxjSRmEo73Z4/u3jMepnltAwCBnS0TY/P+NvTCLKRQX89yg6qqT
# e9UuJENiy3q93cYQw3MylRS9By8Ebjr4I4hvAgMBAAGjggHcMIIB2DAOBgNVHQ8B
# Af8EBAMCAYYwEAYJKwYBBAGCNxUBBAMCAQAwHQYDVR0OBBYEFJrxVHd1DIcWN0ag
# rN55+fR/wXjpMFQGA1UdIARNMEswSQYEVR0gADBBMD8GCCsGAQUFBwIBFjNodHRw
# Oi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpb3BzL0RvY3MvUmVwb3NpdG9yeS5odG0w
# GQYJKwYBBAGCNxQCBAweCgBTAHUAYgBDAEEwEgYDVR0TAQH/BAgwBgEB/wIBADAf
# BgNVHSMEGDAWgBTZQSmwDw9jbO9p1/XNKZ6kSGow5jBwBgNVHR8EaTBnMGWgY6Bh
# hl9odHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2NybC9NaWNyb3NvZnQl
# MjBJRCUyMFZlcmlmaWVkJTIwQ29kZSUyMFNpZ25pbmclMjBQQ0ElMjAyMDIxLmNy
# bDB9BggrBgEFBQcBAQRxMG8wbQYIKwYBBQUHMAKGYWh0dHA6Ly93d3cubWljcm9z
# b2Z0LmNvbS9wa2lvcHMvY2VydHMvTWljcm9zb2Z0JTIwSUQlMjBWZXJpZmllZCUy
# MENvZGUlMjBTaWduaW5nJTIwUENBJTIwMjAyMS5jcnQwDQYJKoZIhvcNAQEMBQAD
# ggIBAJB1Whn9TSbfyXaIppkWWzFq+m2mg4vJpHVr1krZNIXWQ6cUmEwOx7oqQKCy
# 96iISNdNVzpe3zogoefvo2TmpkHQFe/aIxFDaCIAmZi9lyay2hmp8HYzcp3nCcmF
# Qk60X9voeypJ6VjqeGsXTrOivWUOYNCLEFlwsH3NHX5EpCyjWN6Q3Fi5ST4do3eT
# VLnuqTQ7/9huTBTSYQsJbTg3m8gIxnHlPlzs2r/u4u9tWEJ0Pt/ZtmkDhTu86QHW
# igHgBoRHemOgnQxp3ksXKLo1r2n1m7+Gst46NTkUi1LljGyq+V9fEBOEnXvoKaRi
# y0pGbK1IdnsmEpF9Xp71l+2T84Nv8IrikZUBWqw5/jffttAas4ccJDci832CadS4
# OHwl29uF6hY8fEg3UYHmxSJjnzi1c3vF0PwsJKxGom9Dx7treBlZOBWK6BGzVBar
# 43Qb02N7okeU3UKMl6GB74fk8aS0mNr6O4YSvQ/66RKRwvqppnEVBOHdIMjvWW9b
# 77duX8TN3pI7w31R3D6t6jK9EcLJOJKymVlBIFNUl0+ajeoKka7IcW0+jkIGff8U
# 9OKol3cz0Eeiop3Qb0qaDp8ZwC8XCcs1cDaSi/vbvBGWMvfKl+ovuIBP9ienG6Xp
# HAdGVw5/10MaDVFG+v3Y0/8JZVchvryB5Hau9T82x+a2MXXAMIIHnjCCBYagAwIB
# AgITMwAAAAeHozSje6WOHAAAAAAABzANBgkqhkiG9w0BAQwFADB3MQswCQYDVQQG
# EwJVUzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMUgwRgYDVQQDEz9N
# aWNyb3NvZnQgSWRlbnRpdHkgVmVyaWZpY2F0aW9uIFJvb3QgQ2VydGlmaWNhdGUg
# QXV0aG9yaXR5IDIwMjAwHhcNMjEwNDAxMjAwNTIwWhcNMzYwNDAxMjAxNTIwWjBj
# MQswCQYDVQQGEwJVUzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTQw
# MgYDVQQDEytNaWNyb3NvZnQgSUQgVmVyaWZpZWQgQ29kZSBTaWduaW5nIFBDQSAy
# MDIxMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAsvDArxmIKOLdVHpM
# SWxpCFUJtFL/ekr4weslKPdnF3cpTeuV8veqtmKVgok2rO0D05BpyvUDCg1wdsoE
# tuxACEGcgHfjPF/nZsOkg7c0mV8hpMT/GvB4uhDvWXMIeQPsDgCzUGzTvoi76YDp
# xDOxhgf8JuXWJzBDoLrmtThX01CE1TCCvH2sZD/+Hz3RDwl2MsvDSdX5rJDYVuR3
# bjaj2QfzZFmwfccTKqMAHlrz4B7ac8g9zyxlTpkTuJGtFnLBGasoOnn5NyYlf0xF
# 9/bjVRo4Gzg2Yc7KR7yhTVNiuTGH5h4eB9ajm1OCShIyhrKqgOkc4smz6obxO+Hx
# KeJ9bYmPf6KLXVNLz8UaeARo0BatvJ82sLr2gqlFBdj1sYfqOf00Qm/3B4XGFPDK
# /H04kteZEZsBRc3VT2d/iVd7OTLpSH9yCORV3oIZQB/Qr4nD4YT/lWkhVtw2v2s0
# TnRJubL/hFMIQa86rcaGMhNsJrhysLNNMeBhiMezU1s5zpusf54qlYu2v5sZ5zL0
# KvBDLHtL8F9gn6jOy3v7Jm0bbBHjrW5yQW7S36ALAt03QDpwW1JG1Hxu/FUXJbBO
# 2AwwVG4Fre+ZQ5Od8ouwt59FpBxVOBGfN4vN2m3fZx1gqn52GvaiBz6ozorgIEjn
# +PhUXILhAV5Q/ZgCJ0u2+ldFGjcCAwEAAaOCAjUwggIxMA4GA1UdDwEB/wQEAwIB
# hjAQBgkrBgEEAYI3FQEEAwIBADAdBgNVHQ4EFgQU2UEpsA8PY2zvadf1zSmepEhq
# MOYwVAYDVR0gBE0wSzBJBgRVHSAAMEEwPwYIKwYBBQUHAgEWM2h0dHA6Ly93d3cu
# bWljcm9zb2Z0LmNvbS9wa2lvcHMvRG9jcy9SZXBvc2l0b3J5Lmh0bTAZBgkrBgEE
# AYI3FAIEDB4KAFMAdQBiAEMAQTAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaA
# FMh+0mqFKhvKGZgEByfPUBBPaKiiMIGEBgNVHR8EfTB7MHmgd6B1hnNodHRwOi8v
# d3d3Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2NybC9NaWNyb3NvZnQlMjBJZGVudGl0
# eSUyMFZlcmlmaWNhdGlvbiUyMFJvb3QlMjBDZXJ0aWZpY2F0ZSUyMEF1dGhvcml0
# eSUyMDIwMjAuY3JsMIHDBggrBgEFBQcBAQSBtjCBszCBgQYIKwYBBQUHMAKGdWh0
# dHA6Ly93d3cubWljcm9zb2Z0LmNvbS9wa2lvcHMvY2VydHMvTWljcm9zb2Z0JTIw
# SWRlbnRpdHklMjBWZXJpZmljYXRpb24lMjBSb290JTIwQ2VydGlmaWNhdGUlMjBB
# dXRob3JpdHklMjAyMDIwLmNydDAtBggrBgEFBQcwAYYhaHR0cDovL29uZW9jc3Au
# bWljcm9zb2Z0LmNvbS9vY3NwMA0GCSqGSIb3DQEBDAUAA4ICAQB/JSqe/tSr6t1m
# CttXI0y6XmyQ41uGWzl9xw+WYhvOL47BV09Dgfnm/tU4ieeZ7NAR5bguorTCNr58
# HOcA1tcsHQqt0wJsdClsu8bpQD9e/al+lUgTUJEV80Xhco7xdgRrehbyhUf4pkeA
# hBEjABvIUpD2LKPho5Z4DPCT5/0TlK02nlPwUbv9URREhVYCtsDM+31OFU3fDV8B
# mQXv5hT2RurVsJHZgP4y26dJDVF+3pcbtvh7R6NEDuYHYihfmE2HdQRq5jRvLE1E
# b59PYwISFCX2DaLZ+zpU4bX0I16ntKq4poGOFaaKtjIA1vRElItaOKcwtc04CBrX
# SfyL2Op6mvNIxTk4OaswIkTXbFL81ZKGD+24uMCwo/pLNhn7VHLfnxlMVzHQVL+b
# Ha9KhTyzwdG/L6uderJQn0cGpLQMStUuNDArxW2wF16QGZ1NtBWgKA8Kqv48M8Hf
# FqNifN6+zt6J0GwzvU8g0rYGgTZR8zDEIJfeZxwWDHpSxB5FJ1VVU1LIAtB7o9PX
# bjXzGifaIMYTzU4YKt4vMNwwBmetQDHhdAtTPplOXrnI9SI6HeTtjDD3iUN/7ygb
# ahmYOHk7VB7fwT4ze+ErCbMh6gHV1UuXPiLciloNxH6K4aMfZN1oLVk6YFeIJEok
# uPgNPa6EnTiOL60cPqfny+Fq8UiuZzGCGpEwghqNAgEBMHEwWjELMAkGA1UEBhMC
# VVMxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjErMCkGA1UEAxMiTWlj
# cm9zb2Z0IElEIFZlcmlmaWVkIENTIEVPQyBDQSAwNAITMwAIK9mfcYvDu5GkOwAA
# AAgr2TANBglghkgBZQMEAgEFAKBeMBAGCisGAQQBgjcCAQwxAjAAMBkGCSqGSIb3
# DQEJAzEMBgorBgEEAYI3AgEEMC8GCSqGSIb3DQEJBDEiBCDDfgfpvuxk1mqzG+nv
# CMSoRra5R2Owpid0hzgC39whaTANBgkqhkiG9w0BAQEFAASCAYAHwCAZ1ymYTfOR
# aVAEWZcuOlQKxm++qd3tkrvsIspsvwuYbJCcRSWe2wHehblwYxK7MqecUBZOCXdz
# mC+XDGBeHmpUAhbU9EmnfKqODFWb97S8VROkZKFN1vwpjQRlsu2Uf1ZTqohMjwPk
# hREpNqMdtaj/eWQq9HZaeyhF2YBdZPgaBzTCgEK2dkd2Dz3Z7aCKFYxr3Ok3IUr0
# thxvF2yjnoigjD/7glZFFRfk8dTg1d3j918xXIdAk+Bi5Aj+7Ij4ItBPQikVPDUJ
# 5HH0C9ojM7ep9WskhTBRyDbx81YZMJLUuWbctlVA0hyTZQa+Urc+s8IeXitR2GTU
# nuXn7XHxlLHVOXmvT6rCR6XL7pOzmKf6HHtpDKeSJSiafCEyoA/yDKsjOLSFRX+t
# Kfz6GPxcheCi2YI8+uCwqaoFOiX3RIAVM/R7V9p6ADlaF3Q4QOfz7r9EIxw0yR4e
# zhlUB6MkTShd+aS20rmWWmicQY+P7msz8oBCdySc+nC3IPldC56hghgRMIIYDQYK
# KwYBBAGCNwMDATGCF/0wghf5BgkqhkiG9w0BBwKgghfqMIIX5gIBAzEPMA0GCWCG
# SAFlAwQCAQUAMIIBYgYLKoZIhvcNAQkQAQSgggFRBIIBTTCCAUkCAQEGCisGAQQB
# hFkKAwEwMTANBglghkgBZQMEAgEFAAQgNm/eS3l5TuAHi9js0ztSTcNE3KEw2Fbt
# JLUi+sJe7RICBmrI9B05IRgTMjAyNjEwMTMyMjExNTQuMzQxWjAEgAIB9KCB4aSB
# 3jCB2zELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcT
# B1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjElMCMGA1UE
# CxMcTWljcm9zb2Z0IEFtZXJpY2EgT3BlcmF0aW9uczEnMCUGA1UECxMeblNoaWVs
# ZCBUU1MgRVNOOjdBMDAtMDVFMC1EOTQ3MTUwMwYDVQQDEyxNaWNyb3NvZnQgUHVi
# bGljIFJTQSBUaW1lIFN0YW1waW5nIEF1dGhvcml0eaCCDyEwggeCMIIFaqADAgEC
# AhMzAAAABeXPD/9mLsmHAAAAAAAFMA0GCSqGSIb3DQEBDAUAMHcxCzAJBgNVBAYT
# AlVTMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xSDBGBgNVBAMTP01p
# Y3Jvc29mdCBJZGVudGl0eSBWZXJpZmljYXRpb24gUm9vdCBDZXJ0aWZpY2F0ZSBB
# dXRob3JpdHkgMjAyMDAeFw0yMDExMTkyMDMyMzFaFw0zNTExMTkyMDQyMzFaMGEx
# CzAJBgNVBAYTAlVTMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xMjAw
# BgNVBAMTKU1pY3Jvc29mdCBQdWJsaWMgUlNBIFRpbWVzdGFtcGluZyBDQSAyMDIw
# MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAnnznUmP94MWfBX1jtQYi
# oxwe1+eXM9ETBb1lRkd3kcFdcG9/sqtDlwxKoVIcaqDb+omFio5DHC4RBcbyQHjX
# CwMk/l3TOYtgoBjxnG/eViS4sOx8y4gSq8Zg49REAf5huXhIkQRKe3Qxs8Sgp02K
# HAznEa/Ssah8nWo5hJM1xznkRsFPu6rfDHeZeG1Wa1wISvlkpOQooTULFm809Z0Z
# YlQ8Lp7i5F9YciFlyAKwn6yjN/kR4fkquUWfGmMopNq/B8U/pdoZkZZQbxNlqJOi
# BGgCWpx69uKqKhTPVi3gVErnc/qi+dR8A2MiAz0kN0nh7SqINGbmw5OIRC0EsZ31
# WF3Uxp3GgZwetEKxLms73KG/Z+MkeuaVDQQheangOEMGJ4pQZH55ngI0Tdy1bi69
# INBV5Kn2HVJo9XxRYR/JPGAaM6xGl57Ei95HUw9NV/uC3yFjrhc087qLJQawSC3x
# zY/EXzsT4I7sDbxOmM2rl4uKK6eEpurRduOQ2hTkmG1hSuWYBunFGNv21Kt4N20A
# KmbeuSnGnsBCd2cjRKG79+TX+sTehawOoxfeOO/jR7wo3liwkGdzPJYHgnJ54Uxb
# ckF914AqHOiEV7xTnD1a69w/UTxwjEugpIPMIIE67SFZ2PMo27xjlLAHWW3l1CEA
# FjLNHd3EQ79PUr8FUXetXr0CAwEAAaOCAhswggIXMA4GA1UdDwEB/wQEAwIBhjAQ
# BgkrBgEEAYI3FQEEAwIBADAdBgNVHQ4EFgQUa2koOjUvSGNAz3vYr0npPtk92yEw
# VAYDVR0gBE0wSzBJBgRVHSAAMEEwPwYIKwYBBQUHAgEWM2h0dHA6Ly93d3cubWlj
# cm9zb2Z0LmNvbS9wa2lvcHMvRG9jcy9SZXBvc2l0b3J5Lmh0bTATBgNVHSUEDDAK
# BggrBgEFBQcDCDAZBgkrBgEEAYI3FAIEDB4KAFMAdQBiAEMAQTAPBgNVHRMBAf8E
# BTADAQH/MB8GA1UdIwQYMBaAFMh+0mqFKhvKGZgEByfPUBBPaKiiMIGEBgNVHR8E
# fTB7MHmgd6B1hnNodHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2NybC9N
# aWNyb3NvZnQlMjBJZGVudGl0eSUyMFZlcmlmaWNhdGlvbiUyMFJvb3QlMjBDZXJ0
# aWZpY2F0ZSUyMEF1dGhvcml0eSUyMDIwMjAuY3JsMIGUBggrBgEFBQcBAQSBhzCB
# hDCBgQYIKwYBBQUHMAKGdWh0dHA6Ly93d3cubWljcm9zb2Z0LmNvbS9wa2lvcHMv
# Y2VydHMvTWljcm9zb2Z0JTIwSWRlbnRpdHklMjBWZXJpZmljYXRpb24lMjBSb290
# JTIwQ2VydGlmaWNhdGUlMjBBdXRob3JpdHklMjAyMDIwLmNydDANBgkqhkiG9w0B
# AQwFAAOCAgEAX4h2x35ttVoVdedMeGj6TuHYRJklFaW4sTQ5r+k77iB79cSLNe+G
# zRjv4pVjJviceW6AF6ycWoEYR0LYhaa0ozJLU5Yi+LCmcrdovkl53DNt4EXs87KD
# ogYb9eGEndSpZ5ZM74LNvVzY0/nPISHz0Xva71QjD4h+8z2XMOZzY7YQ0Psw+ety
# NZ1CesufU211rLslLKsO8F2aBs2cIo1k+aHOhrw9xw6JCWONNboZ497mwYW5EfN0
# W3zL5s3ad4Xtm7yFM7Ujrhc0aqy3xL7D5FR2J7x9cLWMq7eb0oYioXhqV2tgFqbK
# HeDick+P8tHYIFovIP7YG4ZkJWag1H91KlELGWi3SLv10o4KGag42pswjybTi4to
# QcC/irAodDW8HNtX+cbz0sMptFJK+KObAnDFHEsukxD+7jFfEV9Hh/+CSxKRsmnu
# iovCWIOb+H7DRon9TlxydiFhvu88o0w35JkNbJxTk4MhF/KgaXn0GxdH8elEa2Im
# q45gaa8D+mTm8LWVydt4ytxYP/bqjN49D9NZ81coE6aQWm88TwIf4R4YZbOpMKN0
# CyejaPNN41LGXHeCUMYmBx3PkP8ADHD1J2Cr/6tjuOOCztfp+o9Nc+ZoIAkpUcA/
# X2gSMkgHAPUvIdtoSAHEUKiBhI6JQivRepyvWcl+JYbYbBh7pmgAXVswggeXMIIF
# f6ADAgECAhMzAAAAXcY5eE9AfTP9AAAAAABdMA0GCSqGSIb3DQEBDAUAMGExCzAJ
# BgNVBAYTAlVTMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xMjAwBgNV
# BAMTKU1pY3Jvc29mdCBQdWJsaWMgUlNBIFRpbWVzdGFtcGluZyBDQSAyMDIwMB4X
# DTI2MDkxNzE4NTcyMVoXDTI3MDkxNDE4NTcyMVowgdsxCzAJBgNVBAYTAlVTMRMw
# EQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVN
# aWNyb3NvZnQgQ29ycG9yYXRpb24xJTAjBgNVBAsTHE1pY3Jvc29mdCBBbWVyaWNh
# IE9wZXJhdGlvbnMxJzAlBgNVBAsTHm5TaGllbGQgVFNTIEVTTjo3QTAwLTA1RTAt
# RDk0NzE1MDMGA1UEAxMsTWljcm9zb2Z0IFB1YmxpYyBSU0EgVGltZSBTdGFtcGlu
# ZyBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCd96jc
# 8RQPiazqg7HGevnT7FexggLz24QaPYwyNeHCyaTfUhE3u7t2JFbFSvU99WplRBLC
# knQ2UHg2nkialDbCKjsxsAS7sZP1/DZWUYkF1qcbzuA0opGv3WKlTpH4dLa+yYZI
# CRfW4qD8sC5S21n0cyTghk+3aPI/9SxTE0HwwSwNv7WNU4NKSwMZnK03YiYXzlRt
# nziwAbOQjBqkeNWMsg5wjTud+6en/ymxgP6XgbpNNX5Aj0rIEqkcaD3jnEXkGO7y
# Ojtq48+ce8xKPaHMZ+dkrDwWU+qYB6m5cKVlG+m+2oc8vN7puAwtEjL1H9IbJv9P
# vvbeL0Jq8XlXEzXVEQG8Fw1C1fVC9nfNaow+mT27iwqCdpxVWsHpXb7PWCXk+JoR
# tDqT/uyKL3Sbtu7KnWeE/G1Vq6ne6nbm+zSQA5o4k86fMbi5kKwHQ0fz4QQ0BYIM
# /o/PEudWZsonB3J0JFbRDyov5LIh0lcysrHzlzgxM2vSGaeOZq1FY/yUyKPp50hh
# Y8vEhbHl0k5ifhpUSYXkZ4UChlErHM9DDWN9RCcQDvEnT6iWkds99BvGLyTYE4tK
# VDMdHm8Brarhf5fso+BdX89Eg5gmdS4pKqaTRLLYsSR8Gt9n2/fmqm/lBgUfwNYa
# 9KEaCVmwG4kwhdUsjJPWyIQnz19iYCwwzf2MzQIDAQABo4IByzCCAccwHQYDVR0O
# BBYEFEPbCl2ZTvB+Hlbt/eWoaMh/Wue5MB8GA1UdIwQYMBaAFGtpKDo1L0hjQM97
# 2K9J6T7ZPdshMGwGA1UdHwRlMGMwYaBfoF2GW2h0dHA6Ly93d3cubWljcm9zb2Z0
# LmNvbS9wa2lvcHMvY3JsL01pY3Jvc29mdCUyMFB1YmxpYyUyMFJTQSUyMFRpbWVz
# dGFtcGluZyUyMENBJTIwMjAyMC5jcmwweQYIKwYBBQUHAQEEbTBrMGkGCCsGAQUF
# BzAChl1odHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2NlcnRzL01pY3Jv
# c29mdCUyMFB1YmxpYyUyMFJTQSUyMFRpbWVzdGFtcGluZyUyMENBJTIwMjAyMC5j
# cnQwDAYDVR0TAQH/BAIwADAWBgNVHSUBAf8EDDAKBggrBgEFBQcDCDAOBgNVHQ8B
# Af8EBAMCB4AwZgYDVR0gBF8wXTBRBgwrBgEEAYI3TIN9AQEwQTA/BggrBgEFBQcC
# ARYzaHR0cDovL3d3dy5taWNyb3NvZnQuY29tL3BraW9wcy9Eb2NzL1JlcG9zaXRv
# cnkuaHRtMAgGBmeBDAEEAjANBgkqhkiG9w0BAQwFAAOCAgEAQshE8CnDLtduJOHh
# aG1DqAp8l4oLX+kclQ1f4Iy+92BXwV6DujiloDib+kKzT683EH8tJAutLONmAmuG
# lFoBNOLaKHaNpRyfXYprF9r4GNUczKx8hiMZj0aEiVplHWb6w9qS2J6ml/ysjP+V
# fz5bHujOBoURidTTvpHq0JsXdXE7n8HJtStccwgyhw21Bnt5C0dzATbCCi2gbObP
# S5TaAmIvuda+Xh9q0JRy05YEJg4f3StO91Q43T5W0AGlqz+aFe6tDKkFVZshM+Kt
# 1weISoB7YpxQcwJ5rMGxS+Ed8ixDQrEd4g8AOlgmRVE0zEEKKCEOiK2wctBfvj/h
# wiTzEo+joJDl5jUBQi5ZjoOJdDgWaNU6D6AgQyJ4PI5CK6SYxN0xzpgreRgf9dvL
# GRJQrOzoavweSQFmJTezIuR7cJp168p2j+EVdI9m4tZa9XmGOjdp3zHg+Dehai4f
# 28/7CausPNUpr+mcdFhGQKJz6UkoIxz7ggVzzD2DlIKShT6ficLGDAI7ryo/Jpyz
# U4bGVWrfjB/DB0IgsxHty0zm+gJ8/qvsbrtfg9R9dbkMnCjpkd53XOuhGPiMhrFn
# kv0g2e5L1xVqV3Cv41gibmeTmxAAnMGnu7pRu/IZu1Zdg823HYm+/xE1hNPM+poV
# onZjOZpg62zkBsO/JEfa82HJk0oxggdDMIIHPwIBATB4MGExCzAJBgNVBAYTAlVT
# MR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xMjAwBgNVBAMTKU1pY3Jv
# c29mdCBQdWJsaWMgUlNBIFRpbWVzdGFtcGluZyBDQSAyMDIwAhMzAAAAXcY5eE9A
# fTP9AAAAAABdMA0GCWCGSAFlAwQCAQUAoIIEnDARBgsqhkiG9w0BCRACDzECBQAw
# GgYJKoZIhvcNAQkDMQ0GCyqGSIb3DQEJEAEEMBwGCSqGSIb3DQEJBTEPFw0yNjEw
# MTMyMjExNTRaMC8GCSqGSIb3DQEJBDEiBCAP/j+F1YJrzQzYXrh/cjkdYx0eRRAB
# a4RvZQeY5Bc9xzCBuQYLKoZIhvcNAQkQAi8xgakwgaYwgaMwgaAEIC01ZEtv6fPu
# QmKhZadGormGhQBDXm/cy+sXvdzEAkpdMHwwZaRjMGExCzAJBgNVBAYTAlVTMR4w
# HAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xMjAwBgNVBAMTKU1pY3Jvc29m
# dCBQdWJsaWMgUlNBIFRpbWVzdGFtcGluZyBDQSAyMDIwAhMzAAAAXcY5eE9AfTP9
# AAAAAABdMIIDXgYLKoZIhvcNAQkQAhIxggNNMIIDSaGCA0UwggNBMIICKQIBATCC
# AQmhgeGkgd4wgdsxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAw
# DgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24x
# JTAjBgNVBAsTHE1pY3Jvc29mdCBBbWVyaWNhIE9wZXJhdGlvbnMxJzAlBgNVBAsT
# Hm5TaGllbGQgVFNTIEVTTjo3QTAwLTA1RTAtRDk0NzE1MDMGA1UEAxMsTWljcm9z
# b2Z0IFB1YmxpYyBSU0EgVGltZSBTdGFtcGluZyBBdXRob3JpdHmiIwoBATAHBgUr
# DgMCGgMVAL2nurW1sYDPB2jAbA8RxJrMlpD1oGcwZaRjMGExCzAJBgNVBAYTAlVT
# MR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xMjAwBgNVBAMTKU1pY3Jv
# c29mdCBQdWJsaWMgUlNBIFRpbWVzdGFtcGluZyBDQSAyMDIwMA0GCSqGSIb3DQEB
# CwUAAgUA7ni4mTAiGA8yMDI2MTAxMzE0MDMwNVoYDzIwMjYxMDE0MTQwMzA1WjB0
# MDoGCisGAQQBhFkKBAExLDAqMAoCBQDueLiZAgEAMAcCAQACAg3oMAcCAQACAhJH
# MAoCBQDuegoZAgEAMDYGCisGAQQBhFkKBAIxKDAmMAwGCisGAQQBhFkKAwKgCjAI
# AgEAAgMHoSChCjAIAgEAAgMBhqAwDQYJKoZIhvcNAQELBQADggEBAFyWZuFUYZ7E
# 4aFu/PTMUtrXTvLSfWHchDErn/micM90OpeWBFTsjGxDJcDwNWsIWMmAAn+YowjE
# +2PNb+uVwytOb3ALJlPrBh/aizKsMUjmKcg8PEQ+znIb/pQbp7kdqC0PWE1ltEv6
# LetYzFgRCp6vam8zzuAR4IDlNObZ20jFUra1sIve+aeGQh9CKu1HJ0Zp9cU/YIFj
# nTMhBcGWxwuRQBPwS3wZ0W+9E0ZVjYxwnnuAfszmwEapszL31c+7exsWabK5CuLQ
# UiTtoZ9Yi9pd70UwuZDeK1VaPsjnAENv54tjBh6RFcOFgquLMeQ4jkM2M6Ff397o
# iR8xzUB9m28wDQYJKoZIhvcNAQEBBQAEggIARLrjBWsG9Sscfn5AkyPc9rW85P4K
# SJZpHOAhIFNf/ywNVPf4NPvKWOEDndIfQ+ppliQUs4RpvcHucA4LGlAqSSgyX5ym
# SU7wIRGOgpzEYZQpr2hXj4zjRpLfzHQ4F8dkxlBuC7pG89g0+vijp0VI6oL1jbd/
# pQjhATTNuN7H5jSTcYiCY6nIPEc8rI6KfcU8ldPirXCr0OAU3uF/GfFEVH7zP6v3
# Bm1GVlz/RrAnXfmDQBdDoMbNIb+mAaNdNqNsY+01ryeaTo4M7WSK9cO+VX+Ggirk
# +96yFJAgcvcRY4Z+btN2A3qM5FLzAQcspCU9z/+F9rbdzyalgBTqqmlj1O7q+KTx
# lSAXZLvWeUjXe7IkGvdS7f9NzF7HE99G9Mz9tH0VfUM5SQmZoMLlUJ1cxyBey27E
# KAXEsLPYY7ZVCRuCHwp+hTEd1olYx1j/XcEAP94JN1qfiVNeulhJlhoqlNTuQdPz
# 2L3kaYC+1LrwHu11HEedmAyptVQIONRqJNYYhR+NBvA/BQXz1zjFSa25hlkTbxwq
# HrV+AwBtFQa0Ij14EY7f4G/Y6fhTl6zBEsrPMs87bdIH21lun7zqpbDZru+vgAzk
# DHx54ozBN0IdCky6ajK5S7X5tNg32qyG/3+Kn4UJC1O1CGR4mWLEYmpNbGKROOJ3
# ZyqQtDbbyWRHdGs=
# SIG # End signature block