public/Debug-LnvUpdate.ps1

function Debug-LnvUpdate {
    <#
        .SYNOPSIS
        Explains why an update is not offered for this computer.
 
        .DESCRIPTION
        Runs a detection pass with test tracing turned on and reports, per package, which
        applicability (Dependencies) and install-detection (DetectInstall) tests the machine did
        or did not satisfy, including the values that were compared. Use it when a customer
        expects an update to be offered and it is not, or when an update is reported as already
        installed and they believe it is not.
 
        Without -PackageID the report covers every package that was not offered, that is every
        package that is already installed or not applicable. With -PackageID it covers only the
        packages asked for, whatever their result. Package objects from Get-LnvUpdate can also be
        piped in.
 
        Note that a full detection pass is always performed, because the packages in a repository
        can depend on each other (Coreq tests) and an accurate answer for one package needs all
        of them. Expect this to take as long as a normal Get-LnvUpdate -All run.
 
        The report is written to the console, and to a log file as well when -LogFile or -LogPath
        is used.
 
        .PARAMETER PackageID
        One or more package IDs to report on. A package name or a part of a package title is also
        accepted. Accepts pipeline input from Get-LnvUpdate.
 
        .PARAMETER Proxy
        Specifies the URL of a proxy server to use for the connection to the update repository.
 
        .PARAMETER ProxyCredential
        Specifies a user account that has permission to use the proxy server.
 
        .PARAMETER ProxyUseDefaultCredentials
        Use the credentials of the current user to access the proxy server.
 
        .PARAMETER IncludePhantomDevices
        Consider currently disconnected (phantom) devices as well when evaluating packages. Use it
        to find out whether a _PnPID test is being decided by hardware that is not attached now.
 
        .PARAMETER ScratchDirectory
        The path to a directory where temporary files are downloaded to. Defaults to $env:TEMP.
 
        .PARAMETER Repository
        The path to a package repository, either an HTTP(S) URL or a filesystem path.
 
        .PARAMETER StatusMode
        Which package status to consider: Active (default), Test or All.
 
        .PARAMETER FailUnsupportedDependencies
        Treat applicability tests this module does not support as failed instead of passed. Useful
        here to find out whether an unsupported test is the reason a package is being offered.
 
        .PARAMETER PassUnsupportedInstallTests
        Treat install-detection tests this module does not support as passed instead of failed.
 
        .PARAMETER SkipSignatureCheck
        Do not verify that package files are signed by Lenovo.
 
        .PARAMETER LogFile
        Also write the report to a file in $env:ProgramData\Lenovo\Lenovo.Client.Update\Logs.
 
        .PARAMETER LogPath
        Like -LogFile, but writes to the file or directory specified here.
 
        .EXAMPLE
        # Explain everything that was not offered to this computer, and keep a log file
        PS> Debug-LnvUpdate -LogFile
 
        .EXAMPLE
        # Explain one specific package
        PS> Debug-LnvUpdate -PackageID r1jhh08w
 
        .EXAMPLE
        # Explain the packages that were reported as already installed
        PS> Get-LnvUpdate -All | Where-Object IsInstalled | Debug-LnvUpdate
    #>


    
    [CmdletBinding()]
    Param (
        [Parameter(Position = 0, ValueFromPipeline, ValueFromPipelineByPropertyName)]
        [Alias('ID')]
        [string[]]$PackageID,
        [Uri]$Proxy = $script:LnvUpdateConfiguration.Proxy,
        [PSCredential]$ProxyCredential = $script:LnvUpdateConfiguration.ProxyCredential,
        [switch]$ProxyUseDefaultCredentials = $script:LnvUpdateConfiguration.ProxyUseDefaultCredentials,
        [switch]$IncludePhantomDevices,
        [System.IO.DirectoryInfo]$ScratchDirectory = $env:TEMP,
        [string]$Repository = 'https://download.lenovo.com/catalog',
        [ValidateSet('Active', 'Test', 'All')]
        [string]$StatusMode = 'Active',
        [switch]$FailUnsupportedDependencies,
        [switch]$PassUnsupportedInstallTests,
        [switch]$SkipSignatureCheck,
        [string]$LogPath,
        [switch]$LogFile
    )

    begin {
        $RequestedIDs = [System.Collections.Generic.List[string]]::new()
    }

    process {
        foreach ($Requested in $PackageID) {
            if ($Requested) {
                $RequestedIDs.Add($Requested)
            }
        }
    }

    end {
        $PreviousLogPath = $script:LnvLogFilePath
        $PreviousQuietDetection = $script:LnvLogQuietDetection
        $logFileToUse = Resolve-LnvLogFilePath -LogFile:$LogFile -LogPath $LogPath -Prefix 'Debug'

        # Everything from the log setup onwards is inside the try, so the finally below always hands
        # the log file back
        try {
            if ($logFileToUse) {
                try {
                    # -Force truncates an existing file, which is intended for a fresh log
                    $null = New-Item -ItemType File -Path $logFileToUse -Force -ErrorAction Stop
                } catch {
                    Write-Warning "Could not create the log file '$logFileToUse': $($_.Exception.Message)"
                    $logFileToUse = $null
                }
                if ($logFileToUse) {
                    Write-Information "Logging to: $logFileToUse" -InformationAction Continue
                    # Get-LnvUpdate is called without -LogFile below: it appends its log lines to this
                    # file instead, so the detection detail and this report end up in one place.
                    $script:LnvLogFilePath = $logFileToUse
                    Write-LnvLogEnvironmentHeader -Component 'Debug-LnvUpdate'
                }
            }

            $GetLnvUpdateParams = @{
                'All'                         = $true
                'ExplainDependencies'         = $true
                'Repository'                  = $Repository
                'StatusMode'                  = $StatusMode
                'ScratchDirectory'            = $ScratchDirectory
                'IncludePhantomDevices'       = $IncludePhantomDevices
                'FailUnsupportedDependencies' = $FailUnsupportedDependencies
                'PassUnsupportedInstallTests' = $PassUnsupportedInstallTests
                'SkipSignatureCheck'          = $SkipSignatureCheck
            }

            if ($Proxy)                     { $GetLnvUpdateParams['Proxy'] = $Proxy }
            if ($ProxyCredential)           { $GetLnvUpdateParams['ProxyCredential'] = $ProxyCredential }
            if ($ProxyUseDefaultCredentials) { $GetLnvUpdateParams['ProxyUseDefaultCredentials'] = $true }


            $script:LnvLogQuietDetection = [bool]$logFileToUse -and $RequestedIDs.Count -gt 0

            Write-Information "Running a full detection pass with test tracing enabled, this takes a while..." -InformationAction Continue
            [array]$AllPackages = Get-LnvUpdate @GetLnvUpdateParams

            $script:LnvLogQuietDetection = $PreviousQuietDetection

            if (-not $AllPackages) {
                Write-Warning "No packages could be evaluated, so there is nothing to report on."
                return
            }

            $Targets = if ($RequestedIDs.Count -gt 0) {
                $Matched = foreach ($Requested in $RequestedIDs) {
                    $Found = @($AllPackages.Where({
                        $_.ID -eq $Requested -or $_.Name -eq $Requested -or $_.Title -like "*$Requested*"
                    }))
                    if (-not $Found) {
                        Write-Warning "No package matching '$Requested' was found for this model in repository '$Repository'."
                    }
                    $Found
                }
                @($Matched | Sort-Object -Property ID -Unique)
            } else {
                # Everything that was not offered: already installed, or not applicable
                @($AllPackages.Where({ $_.IsInstalled -eq $true -or $_.IsApplicable -ne $true }))
            }

            $Environment = Get-LnvEnvironmentInfo

            # Write-LnvLog -ToConsole: this report is meant to be read on screen, and writing it
            # through the logger puts it in the log file too without mixing report text into the
            # objects this cmdlet returns.
            Write-LnvLog -ToConsole -NoTimestamp -Message ''
            Write-LnvLog -ToConsole -NoTimestamp -Message ('=' * 78)
            Write-LnvLog -ToConsole -NoTimestamp -Message " Debug-LnvUpdate report - $($Targets.Count) of $($AllPackages.Count) evaluated packages"
            Write-LnvLog -ToConsole -NoTimestamp -Message " Model $($Environment.Model) ($($Environment.ProductName)), $($Environment.OSName) $($Environment.OSVersion), module $($Environment.ModuleVersion)"
            Write-LnvLog -ToConsole -NoTimestamp -Message ('=' * 78)

            # A package can carry dozens of Or-branches (some firmware packages list every UEFI
            # device GUID they support), so the report is capped on screen. The cap is the console's
            
            $MaxConsoleReportLines = 20
            function Write-ReportSection {
                param ([string]$Header, [string[]]$Lines, [string]$EmptyMessage)

                if (-not $Lines) {
                    if ($EmptyMessage) {
                        Write-LnvLog -ToConsole -NoTimestamp -Message " $EmptyMessage"
                    }
                    return
                }
                Write-LnvLog -ToConsole -NoTimestamp -Message " $Header"

                for ($LineIndex = 0; $LineIndex -lt $Lines.Count; $LineIndex++) {
                    if ($LineIndex -lt $MaxConsoleReportLines) {
                        Write-LnvLog -ToConsole -NoTimestamp -Message " $($Lines[$LineIndex])"
                    } else {
                        Write-LnvLog -Always -NoTimestamp -Message " $($Lines[$LineIndex])"
                    }
                }

                if ($Lines.Count -gt $MaxConsoleReportLines) {
                    # -ConsoleOnly: the log file holds every line, so in there this note would
                    # contradict the section printed directly above it
                    $Remaining = $Lines.Count - $MaxConsoleReportLines
                    $MoreNote = if ($script:LnvLogFilePath) {
                        " ... and $Remaining more, written in full to the log file"
                    } else {
                        " ... and $Remaining more, run again with -LogFile to get all of them"
                    }
                    Write-LnvLog -ConsoleOnly -NoTimestamp -Message $MoreNote
                }
            }

            foreach ($Package in $Targets) {
                [string[]]$FailedDependencyTests = @(Format-LnvDependencyTrace -Trace $Package.DependencyTests -FailedOnly)

                # Counted on the trace itself and not on its formatted lines: the formatter reports
                # only Test nodes and collapses runs of identical ones, so a package that does have
                # a DetectInstall section can format to nothing and would then be reported as having
                # none at all.
                [int]$DependencyTestCount = if ($null -ne $Package.DependencyTests) { @($Package.DependencyTests).Count } else { 0 }
                [int]$InstallTestCount    = if ($null -ne $Package.InstallTests)    { @($Package.InstallTests).Count }    else { 0 }
                [bool]$HasInstallTests    = $InstallTestCount -gt 0

                $Verdict = if ($Package.IsApplicable -eq $false) {
                    'NotApplicable'
                } elseif ($Package.IsInstalled -eq $true) {
                    'AlreadyInstalled'
                } elseif ($Package.IsApplicable -eq $true -and $Package.IsInstalled -eq $false) {
                    'Needed'
                } else {
                    'Undetermined'
                }

                Write-LnvLog -ToConsole -NoTimestamp -Message ''
                Write-LnvLog -ToConsole -NoTimestamp -Message " $($Package.ID) - $($Package.Title)"
                Write-LnvLog -ToConsole -NoTimestamp -Message (' {0,-18}: {1}' -f 'Verdict', $Verdict)
                Write-LnvLog -ToConsole -NoTimestamp -Message (' {0,-18}: {1}' -f 'Version', $Package.Version)
                Write-LnvLog -ToConsole -NoTimestamp -Message (' {0,-18}: {1}' -f 'Type / Severity', "$($Package.Type) / $($Package.Severity)")
                Write-LnvLog -ToConsole -NoTimestamp -Message (' {0,-18}: {1}' -f 'Released', $Package.ReleaseDate.ToString('yyyy-MM-dd'))
                Write-LnvLog -ToConsole -NoTimestamp -Message (' {0,-18}: {1}' -f 'IsApplicable', $Package.IsApplicable)
                Write-LnvLog -ToConsole -NoTimestamp -Message (' {0,-18}: {1}' -f 'IsInstalled', $Package.IsInstalled)
                Write-LnvLog -ToConsole -NoTimestamp -Message (' {0,-18}: {1}' -f 'Package XML', $Package.URL)
                Write-LnvLog -ToConsole -NoTimestamp -Message (' {0,-18}: {1}' -f 'Tests recorded', "$DependencyTestCount dependency, $InstallTestCount install")

                if ($Package.IsApplicable -eq $false) {
                    Write-ReportSection -Header 'Dependency tests that were not met:' -Lines $FailedDependencyTests
                } else {
                    Write-ReportSection -Header 'Dependency tests that are satisfied:' -Lines @(Format-LnvDependencyTrace -Trace $Package.DependencyTests -PassedOnly)
                }

                [string[]]$PassedInstallTests = @(Format-LnvDependencyTrace -Trace $Package.InstallTests -PassedOnly)
                [string[]]$FailedInstallTests = @(Format-LnvDependencyTrace -Trace $Package.InstallTests -FailedOnly)

                # -EmptyMessage: the install-detection block says something for every package, so a
                # trace that formats to no lines has to report that rather than print nothing.
                if (-not $HasInstallTests) {
                    Write-LnvLog -ToConsole -NoTimestamp -Message ' Install detection: the package has no DetectInstall section, so it is always treated as not installed'
                } elseif ($Package.IsInstalled -eq $true) {
                    Write-ReportSection -Header 'Install detection tests that are satisfied, so it is reported as installed:' -Lines $PassedInstallTests `
                        -EmptyMessage "Install detection: reported as installed, but none of the $InstallTestCount recorded entries formats to a test line - see the InstallTests property"
                } else {
                    Write-ReportSection -Header 'Install detection tests that were not met, so it is reported as not installed:' -Lines $FailedInstallTests `
                        -EmptyMessage "Install detection: reported as not installed, but none of the $InstallTestCount recorded entries formats to a test line - see the InstallTests property"
                }

                
            }

            Write-LnvLog -ToConsole -NoTimestamp -Message ''
            Write-LnvLog -ToConsole -NoTimestamp -Message ('=' * 78)
        }
        finally {
            if ($logFileToUse) {
                Write-Information "Log saved to: $logFileToUse" -InformationAction Continue
            }
            $script:LnvLogFilePath = $PreviousLogPath
            $script:LnvLogQuietDetection = $PreviousQuietDetection
        }
    }
}

# SIG # Begin signature block
# MIItugYJKoZIhvcNAQcCoIItqzCCLacCAQExCzAJBgUrDgMCGgUAMGkGCisGAQQB
# gjcCAQSgWzBZMDQGCisGAQQBgjcCAR4wJgIDAQAABBAfzDtgWUsITrck0sYpfvNR
# AgEAAgEAAgEAAgEAAgEAMCEwCQYFKw4DAhoFAAQUfabIB/UmUN86x3tot3EtE2Ph
# 3g+ggibcMIIFjTCCBHWgAwIBAgIQDpsYjvnQLefv21DiCEAYWjANBgkqhkiG9w0B
# AQwFADBlMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYD
# VQQLExB3d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVk
# IElEIFJvb3QgQ0EwHhcNMjIwODAxMDAwMDAwWhcNMzExMTA5MjM1OTU5WjBiMQsw
# CQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cu
# ZGlnaWNlcnQuY29tMSEwHwYDVQQDExhEaWdpQ2VydCBUcnVzdGVkIFJvb3QgRzQw
# ggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC/5pBzaN675F1KPDAiMGkz
# 7MKnJS7JIT3yithZwuEppz1Yq3aaza57G4QNxDAf8xukOBbrVsaXbR2rsnnyyhHS
# 5F/WBTxSD1Ifxp4VpX6+n6lXFllVcq9ok3DCsrp1mWpzMpTREEQQLt+C8weE5nQ7
# bXHiLQwb7iDVySAdYyktzuxeTsiT+CFhmzTrBcZe7FsavOvJz82sNEBfsXpm7nfI
# SKhmV1efVFiODCu3T6cw2Vbuyntd463JT17lNecxy9qTXtyOj4DatpGYQJB5w3jH
# trHEtWoYOAMQjdjUN6QuBX2I9YI+EJFwq1WCQTLX2wRzKm6RAXwhTNS8rhsDdV14
# Ztk6MUSaM0C/CNdaSaTC5qmgZ92kJ7yhTzm1EVgX9yRcRo9k98FpiHaYdj1ZXUJ2
# h4mXaXpI8OCiEhtmmnTK3kse5w5jrubU75KSOp493ADkRSWJtppEGSt+wJS00mFt
# 6zPZxd9LBADMfRyVw4/3IbKyEbe7f/LVjHAsQWCqsWMYRJUadmJ+9oCw++hkpjPR
# iQfhvbfmQ6QYuKZ3AeEPlAwhHbJUKSWJbOUOUlFHdL4mrLZBdd56rF+NP8m800ER
# ElvlEFDrMcXKchYiCd98THU/Y+whX8QgUWtvsauGi0/C1kVfnSD8oR7FwI+isX4K
# Jpn15GkvmB0t9dmpsh3lGwIDAQABo4IBOjCCATYwDwYDVR0TAQH/BAUwAwEB/zAd
# BgNVHQ4EFgQU7NfjgtJxXWRM3y5nP+e6mK4cD08wHwYDVR0jBBgwFoAUReuir/SS
# y4IxLVGLp6chnfNtyA8wDgYDVR0PAQH/BAQDAgGGMHkGCCsGAQUFBwEBBG0wazAk
# BggrBgEFBQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQuY29tMEMGCCsGAQUFBzAC
# hjdodHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vRGlnaUNlcnRBc3N1cmVkSURS
# b290Q0EuY3J0MEUGA1UdHwQ+MDwwOqA4oDaGNGh0dHA6Ly9jcmwzLmRpZ2ljZXJ0
# LmNvbS9EaWdpQ2VydEFzc3VyZWRJRFJvb3RDQS5jcmwwEQYDVR0gBAowCDAGBgRV
# HSAAMA0GCSqGSIb3DQEBDAUAA4IBAQBwoL9DXFXnOF+go3QbPbYW1/e/Vwe9mqyh
# hyzshV6pGrsi+IcaaVQi7aSId229GhT0E0p6Ly23OO/0/4C5+KH38nLeJLxSA8hO
# 0Cre+i1Wz/n096wwepqLsl7Uz9FDRJtDIeuWcqFItJnLnU+nBgMTdydE1Od/6Fmo
# 8L8vC6bp8jQ87PcDx4eo0kxAGTVGamlUsLihVo7spNU96LHc/RzY9HdaXFSMb++h
# UD38dglohJ9vytsgjTVgHAIDyyCwrFigDkBjxZgiwbJZ9VVrzyerbHbObyMt9H5x
# aiNrIv8SuFQtJ37YOtnwtoeW/VvRXKwYw02fc7cBqZ9Xql4o4rmUMIIFkDCCA3ig
# AwIBAgIQBZsbV56OITLiOQe9p3d1XDANBgkqhkiG9w0BAQwFADBiMQswCQYDVQQG
# EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNl
# cnQuY29tMSEwHwYDVQQDExhEaWdpQ2VydCBUcnVzdGVkIFJvb3QgRzQwHhcNMTMw
# ODAxMTIwMDAwWhcNMzgwMTE1MTIwMDAwWjBiMQswCQYDVQQGEwJVUzEVMBMGA1UE
# ChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSEwHwYD
# VQQDExhEaWdpQ2VydCBUcnVzdGVkIFJvb3QgRzQwggIiMA0GCSqGSIb3DQEBAQUA
# A4ICDwAwggIKAoICAQC/5pBzaN675F1KPDAiMGkz7MKnJS7JIT3yithZwuEppz1Y
# q3aaza57G4QNxDAf8xukOBbrVsaXbR2rsnnyyhHS5F/WBTxSD1Ifxp4VpX6+n6lX
# FllVcq9ok3DCsrp1mWpzMpTREEQQLt+C8weE5nQ7bXHiLQwb7iDVySAdYyktzuxe
# TsiT+CFhmzTrBcZe7FsavOvJz82sNEBfsXpm7nfISKhmV1efVFiODCu3T6cw2Vbu
# yntd463JT17lNecxy9qTXtyOj4DatpGYQJB5w3jHtrHEtWoYOAMQjdjUN6QuBX2I
# 9YI+EJFwq1WCQTLX2wRzKm6RAXwhTNS8rhsDdV14Ztk6MUSaM0C/CNdaSaTC5qmg
# Z92kJ7yhTzm1EVgX9yRcRo9k98FpiHaYdj1ZXUJ2h4mXaXpI8OCiEhtmmnTK3kse
# 5w5jrubU75KSOp493ADkRSWJtppEGSt+wJS00mFt6zPZxd9LBADMfRyVw4/3IbKy
# Ebe7f/LVjHAsQWCqsWMYRJUadmJ+9oCw++hkpjPRiQfhvbfmQ6QYuKZ3AeEPlAwh
# HbJUKSWJbOUOUlFHdL4mrLZBdd56rF+NP8m800ERElvlEFDrMcXKchYiCd98THU/
# Y+whX8QgUWtvsauGi0/C1kVfnSD8oR7FwI+isX4KJpn15GkvmB0t9dmpsh3lGwID
# AQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4E
# FgQU7NfjgtJxXWRM3y5nP+e6mK4cD08wDQYJKoZIhvcNAQEMBQADggIBALth2X2p
# bL4XxJEbw6GiAI3jZGgPVs93rnD5/ZpKmbnJeFwMDF/k5hQpVgs2SV1EY+CtnJYY
# ZhsjDT156W1r1lT40jzBQ0CuHVD1UvyQO7uYmWlrx8GnqGikJ9yd+SeuMIW59mdN
# Oj6PWTkiU0TryF0Dyu1Qen1iIQqAyHNm0aAFYF/opbSnr6j3bTWcfFqK1qI4mfN4
# i/RN0iAL3gTujJtHgXINwBQy7zBZLq7gcfJW5GqXb5JQbZaNaHqasjYUegbyJLkJ
# EVDXCLG4iXqEI2FCKeWjzaIgQdfRnGTZ6iahixTXTBmyUEFxPT9NcCOGDErcgdLM
# MpSEDQgJlxxPwO5rIHQw0uA5NBCFIRUBCOhVMt5xSdkoF1BN5r5N0XWs0Mr7QbhD
# parTwwVETyw2m+L64kW4I1NsBm9nVX9GtUw/bihaeSbSpKhil9Ie4u1Ki7wb/UdK
# Dd9nZn6yW0HQO+T0O/QEY+nvwlQAUaCKKsnOeMzV6ocEGLPOr0mIr/OSmbaz5mEP
# 0oUA51Aa5BuVnRmhuZyxm7EAHu/QD09CbMkKvO5D+jpxpchNJqU1/YldvIViHTLS
# oCtU7ZpXwdv6EM8Zt4tKG48BtieVU+i2iW1bvGjUI+iLUaJW+fCmgKDWHrO8Dw9T
# dSmq6hN35N6MgSGtBxBHEa2HPQfRdbzP82Z+MIIGsDCCBJigAwIBAgIQCK1AsmDS
# nEyfXs2pvZOu2TANBgkqhkiG9w0BAQwFADBiMQswCQYDVQQGEwJVUzEVMBMGA1UE
# ChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSEwHwYD
# VQQDExhEaWdpQ2VydCBUcnVzdGVkIFJvb3QgRzQwHhcNMjEwNDI5MDAwMDAwWhcN
# MzYwNDI4MjM1OTU5WjBpMQswCQYDVQQGEwJVUzEXMBUGA1UEChMORGlnaUNlcnQs
# IEluYy4xQTA/BgNVBAMTOERpZ2lDZXJ0IFRydXN0ZWQgRzQgQ29kZSBTaWduaW5n
# IFJTQTQwOTYgU0hBMzg0IDIwMjEgQ0ExMIICIjANBgkqhkiG9w0BAQEFAAOCAg8A
# MIICCgKCAgEA1bQvQtAorXi3XdU5WRuxiEL1M4zrPYGXcMW7xIUmMJ+kjmjYXPXr
# NCQH4UtP03hD9BfXHtr50tVnGlJPDqFX/IiZwZHMgQM+TXAkZLON4gh9NH1MgFcS
# a0OamfLFOx/y78tHWhOmTLMBICXzENOLsvsI8IrgnQnAZaf6mIBJNYc9URnokCF4
# RS6hnyzhGMIazMXuk0lwQjKP+8bqHPNlaJGiTUyCEUhSaN4QvRRXXegYE2XFf7JP
# hSxIpFaENdb5LpyqABXRN/4aBpTCfMjqGzLmysL0p6MDDnSlrzm2q2AS4+jWufcx
# 4dyt5Big2MEjR0ezoQ9uo6ttmAaDG7dqZy3SvUQakhCBj7A7CdfHmzJawv9qYFSL
# ScGT7eG0XOBv6yb5jNWy+TgQ5urOkfW+0/tvk2E0XLyTRSiDNipmKF+wc86LJiUG
# soPUXPYVGUztYuBeM/Lo6OwKp7ADK5GyNnm+960IHnWmZcy740hQ83eRGv7bUKJG
# yGFYmPV8AhY8gyitOYbs1LcNU9D4R+Z1MI3sMJN2FKZbS110YU0/EpF23r9Yy3IQ
# KUHw1cVtJnZoEUETWJrcJisB9IlNWdt4z4FKPkBHX8mBUHOFECMhWWCKZFTBzCEa
# 6DgZfGYczXg4RTCZT/9jT0y7qg0IU0F8WD1Hs/q27IwyCQLMbDwMVhECAwEAAaOC
# AVkwggFVMBIGA1UdEwEB/wQIMAYBAf8CAQAwHQYDVR0OBBYEFGg34Ou2O/hfEYb7
# /mF7CIhl9E5CMB8GA1UdIwQYMBaAFOzX44LScV1kTN8uZz/nupiuHA9PMA4GA1Ud
# DwEB/wQEAwIBhjATBgNVHSUEDDAKBggrBgEFBQcDAzB3BggrBgEFBQcBAQRrMGkw
# JAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBBBggrBgEFBQcw
# AoY1aHR0cDovL2NhY2VydHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0VHJ1c3RlZFJv
# b3RHNC5jcnQwQwYDVR0fBDwwOjA4oDagNIYyaHR0cDovL2NybDMuZGlnaWNlcnQu
# Y29tL0RpZ2lDZXJ0VHJ1c3RlZFJvb3RHNC5jcmwwHAYDVR0gBBUwEzAHBgVngQwB
# AzAIBgZngQwBBAEwDQYJKoZIhvcNAQEMBQADggIBADojRD2NCHbuj7w6mdNW4AIa
# pfhINPMstuZ0ZveUcrEAyq9sMCcTEp6QRJ9L/Z6jfCbVN7w6XUhtldU/SfQnuxaB
# RVD9nL22heB2fjdxyyL3WqqQz/WTauPrINHVUHmImoqKwba9oUgYftzYgBoRGRjN
# YZmBVvbJ43bnxOQbX0P4PpT/djk9ntSZz0rdKOtfJqGVWEjVGv7XJz/9kNF2ht0c
# sGBc8w2o7uCJob054ThO2m67Np375SFTWsPK6Wrxoj7bQ7gzyE84FJKZ9d3OVG3Z
# XQIUH0AzfAPilbLCIXVzUstG2MQ0HKKlS43Nb3Y3LIU/Gs4m6Ri+kAewQ3+ViCCC
# cPDMyu/9KTVcH4k4Vfc3iosJocsL6TEa/y4ZXDlx4b6cpwoG1iZnt5LmTl/eeqxJ
# zy6kdJKt2zyknIYf48FWGysj/4+16oh7cGvmoLr9Oj9FpsToFpFSi0HASIRLlk2r
# REDjjfAVKM7t8RhWByovEMQMCGQ8M4+uKIw8y4+ICw2/O/TOHnuO77Xry7fwdxPm
# 5yg/rBKupS8ibEH5glwVZsxsDsrFhsP2JjMMB0ug0wcCampAMEhLNKhRILutG4UI
# 4lkNbcoFUCvqShyepf2gpx8GdOfy1lKQ/a+FSCH5Vzu0nAPthkX0tGFuv2jiJmCG
# 6sivqf6UHedjGzqGVnhOMIIGtDCCBJygAwIBAgIQDcesVwX/IZkuQEMiDDpJhjAN
# BgkqhkiG9w0BAQsFADBiMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQg
# SW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSEwHwYDVQQDExhEaWdpQ2Vy
# dCBUcnVzdGVkIFJvb3QgRzQwHhcNMjUwNTA3MDAwMDAwWhcNMzgwMTE0MjM1OTU5
# WjBpMQswCQYDVQQGEwJVUzEXMBUGA1UEChMORGlnaUNlcnQsIEluYy4xQTA/BgNV
# BAMTOERpZ2lDZXJ0IFRydXN0ZWQgRzQgVGltZVN0YW1waW5nIFJTQTQwOTYgU0hB
# MjU2IDIwMjUgQ0ExMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAtHgx
# 0wqYQXK+PEbAHKx126NGaHS0URedTa2NDZS1mZaDLFTtQ2oRjzUXMmxCqvkbsDpz
# 4aH+qbxeLho8I6jY3xL1IusLopuW2qftJYJaDNs1+JH7Z+QdSKWM06qchUP+AbdJ
# gMQB3h2DZ0Mal5kYp77jYMVQXSZH++0trj6Ao+xh/AS7sQRuQL37QXbDhAktVJMQ
# bzIBHYJBYgzWIjk8eDrYhXDEpKk7RdoX0M980EpLtlrNyHw0Xm+nt5pnYJU3Gmq6
# bNMI1I7Gb5IBZK4ivbVCiZv7PNBYqHEpNVWC2ZQ8BbfnFRQVESYOszFI2Wv82wnJ
# RfN20VRS3hpLgIR4hjzL0hpoYGk81coWJ+KdPvMvaB0WkE/2qHxJ0ucS638ZxqU1
# 4lDnki7CcoKCz6eum5A19WZQHkqUJfdkDjHkccpL6uoG8pbF0LJAQQZxst7VvwDD
# jAmSFTUms+wV/FbWBqi7fTJnjq3hj0XbQcd8hjj/q8d6ylgxCZSKi17yVp2NL+cn
# T6Toy+rN+nM8M7LnLqCrO2JP3oW//1sfuZDKiDEb1AQ8es9Xr/u6bDTnYCTKIsDq
# 1BtmXUqEG1NqzJKS4kOmxkYp2WyODi7vQTCBZtVFJfVZ3j7OgWmnhFr4yUozZtqg
# PrHRVHhGNKlYzyjlroPxul+bgIspzOwbtmsgY1MCAwEAAaOCAV0wggFZMBIGA1Ud
# EwEB/wQIMAYBAf8CAQAwHQYDVR0OBBYEFO9vU0rp5AZ8esrikFb2L9RJ7MtOMB8G
# A1UdIwQYMBaAFOzX44LScV1kTN8uZz/nupiuHA9PMA4GA1UdDwEB/wQEAwIBhjAT
# BgNVHSUEDDAKBggrBgEFBQcDCDB3BggrBgEFBQcBAQRrMGkwJAYIKwYBBQUHMAGG
# GGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBBBggrBgEFBQcwAoY1aHR0cDovL2Nh
# Y2VydHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0VHJ1c3RlZFJvb3RHNC5jcnQwQwYD
# VR0fBDwwOjA4oDagNIYyaHR0cDovL2NybDMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0
# VHJ1c3RlZFJvb3RHNC5jcmwwIAYDVR0gBBkwFzAIBgZngQwBBAIwCwYJYIZIAYb9
# bAcBMA0GCSqGSIb3DQEBCwUAA4ICAQAXzvsWgBz+Bz0RdnEwvb4LyLU0pn/N0IfF
# iBowf0/Dm1wGc/Do7oVMY2mhXZXjDNJQa8j00DNqhCT3t+s8G0iP5kvN2n7Jd2E4
# /iEIUBO41P5F448rSYJ59Ib61eoalhnd6ywFLerycvZTAz40y8S4F3/a+Z1jEMK/
# DMm/axFSgoR8n6c3nuZB9BfBwAQYK9FHaoq2e26MHvVY9gCDA/JYsq7pGdogP8HR
# trYfctSLANEBfHU16r3J05qX3kId+ZOczgj5kjatVB+NdADVZKON/gnZruMvNYY2
# o1f4MXRJDMdTSlOLh0HCn2cQLwQCqjFbqrXuvTPSegOOzr4EWj7PtspIHBldNE2K
# 9i697cvaiIo2p61Ed2p8xMJb82Yosn0z4y25xUbI7GIN/TpVfHIqQ6Ku/qjTY6hc
# 3hsXMrS+U0yy+GWqAXam4ToWd2UQ1KYT70kZjE4YtL8Pbzg0c1ugMZyZZd/BdHLi
# Ru7hAWE6bTEm4XYRkA6Tl4KSFLFk43esaUeqGkH/wyW4N7OigizwJWeukcyIPbAv
# jSabnf7+Pu0VrFgoiovRDiyx3zEdmcif/sYQsfch28bZeUz2rtY/9TCA6TD8dC3J
# E3rYkrhLULy7Dc90G6e8BlqmyIjlgp2+VqsS9/wQD7yFylIz0scmbKvFoW2jNrbM
# 1pD2T7m3XDCCBu0wggTVoAMCAQICEAhP3DNPfkVO28MPj/mSGDUwDQYJKoZIhvcN
# AQELBQAwaTELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDkRpZ2lDZXJ0LCBJbmMuMUEw
# PwYDVQQDEzhEaWdpQ2VydCBUcnVzdGVkIEc0IFRpbWVTdGFtcGluZyBSU0E0MDk2
# IFNIQTI1NiAyMDI1IENBMTAeFw0yNjA4MDUwMDAwMDBaFw0zNzExMDQyMzU5NTla
# MGMxCzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5EaWdpQ2VydCwgSW5jLjE7MDkGA1UE
# AxMyRGlnaUNlcnQgU0hBMjU2IFJTQTQwOTYgVGltZXN0YW1wIFJlc3BvbmRlciAy
# MDI2IDEwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC2e6byyf7NSvjU
# m0xls/04xjD4fAkOkbnGQi7+Wpx81iYxfzViaxSIctuH3KSl5YEYpMuFgGsA31N2
# D9ATMbfZdw5uaAhuWevQKhDdZIB4NnqcfpfpWQXJiQnDdAElETC+bhSEvNLGbA8D
# twUpFMQ4yyYQSPqomT92osQAv6hBi47ATZS6JfVWe6XxhF4jJZ3iSAuf2Cros1cz
# RSmWRHqMv9AfGZvp8ygYElhudpQjtcPpwoOl6QrZJUyV3iINvN4cO05prGV0fkjG
# 426xDr2d3z9lcSIHkdvGPdGUrXdxfVbgOUVcp2/8ISEzwKPW++Wa+E2ujI91EZtu
# kGWDJ/xZ27k3oHKEXBRGfRTqjOU+jE3ba/5++JSE/7oNHnjs5mekExYN96LV/mxU
# bCKJb8pBNY4r3uD7hEmk/M81XhVgwDA7aMzYC3LZBg9WY5BMmbSay5ecmtJuXaB/
# 0nKWmQmVZeqTVDgsmzHP5MQuhAJkiWNuC9MmCg9TZHXbJ2/yLVSov9p16UDTLtT0
# +aa1vN71fHeu1qMLlLNB3WOB/ADCxr3S/1hxI92Z6jKgEED/btwIvbfuXkNNhg8M
# tDg43c4tMZae9FvqMOt/9PvmAxF9TNIsIFB8G6yb36ZJZGUL8N/pL971DyLXcK6H
# M5PYnH5X+eVtczhCgHCVQCF6XDAlPQIDAQABo4IBlTCCAZEwDAYDVR0TAQH/BAIw
# ADAdBgNVHQ4EFgQUFMljijAu1Er7bpTz5uNAfvXszeIwHwYDVR0jBBgwFoAU729T
# SunkBnx6yuKQVvYv1Ensy04wDgYDVR0PAQH/BAQDAgeAMBYGA1UdJQEB/wQMMAoG
# CCsGAQUFBwMIMIGVBggrBgEFBQcBAQSBiDCBhTAkBggrBgEFBQcwAYYYaHR0cDov
# L29jc3AuZGlnaWNlcnQuY29tMF0GCCsGAQUFBzAChlFodHRwOi8vY2FjZXJ0cy5k
# aWdpY2VydC5jb20vRGlnaUNlcnRUcnVzdGVkRzRUaW1lU3RhbXBpbmdSU0E0MDk2
# U0hBMjU2MjAyNUNBMS5jcnQwXwYDVR0fBFgwVjBUoFKgUIZOaHR0cDovL2NybDMu
# ZGlnaWNlcnQuY29tL0RpZ2lDZXJ0VHJ1c3RlZEc0VGltZVN0YW1waW5nUlNBNDA5
# NlNIQTI1NjIwMjVDQTEuY3JsMCAGA1UdIAQZMBcwCAYGZ4EMAQQCMAsGCWCGSAGG
# /WwHATANBgkqhkiG9w0BAQsFAAOCAgEAjcU6YR6dUgrfmawJgH59KECxa9Ji8sEi
# 2g10CBDaMiqsaxWyW5cwlT/6ZF5sFznazqVsoC85U9dqLOYqQwst+UQQoNlDHgKR
# La3xoc+OReFreFhnTXSG0Vrd2E2CZqUfm+5a+He1MJ/h+tNLuA+0Zzhn/Fo+FDYA
# HWZHx4R79ZsfRFYe9UiXpXBDf6DkUo183Y38NYmR/XfDYf7YZ+oR9t3flbDwK+hg
# GMs0gNNp1w9Z2CyOyI5or/sSwomAuNQ0hWC9xoU4stD8aWsD7RkcmgVRs6vlIk3z
# PKQ+ylcheWkMlj+CoVRlFE55pv0ZWCaFt04lwP/rdGHE9qEVQZtyRE42ox7oNgC/
# r+Y4bSlZ3dw9K2x1xLtu6PkPKeLBFjzKigwfqm3Hm+k/+lnME8F5kPZTgiy2HLEH
# klpryqs6QHnPXrRNeIzkAMyylnRN8P0wmirS0WkU+ywpEWFZ4QNg+9xS43tTuW9x
# 0eXh7NDc1P/sV+zWxHXKH8tFt1ncHdVzqrZaYPyYMLSn2TOXajveJW1L3joiQSPs
# WRGxkbDDW15jERFE4LvjnGu2O9zD1nLJSMdlYZEikl4w2w+q4IN/R+TIe0H4ngCI
# 1moJCTbevGH4punIxM1Uoi0nmX3ZK+XbRT01uowE5ViXWHng0RgsmrX/EdYUo80r
# 3TfMlkD0/YMwggdWMIIFPqADAgECAhAFfARoFtaNDha0m0G6FxiVMA0GCSqGSIb3
# DQEBCwUAMGkxCzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5EaWdpQ2VydCwgSW5jLjFB
# MD8GA1UEAxM4RGlnaUNlcnQgVHJ1c3RlZCBHNCBDb2RlIFNpZ25pbmcgUlNBNDA5
# NiBTSEEzODQgMjAyMSBDQTEwHhcNMjYwNTE0MDAwMDAwWhcNMjcwNjE3MjM1OTU5
# WjBeMQswCQYDVQQGEwJVUzEXMBUGA1UECBMOTm9ydGggQ2Fyb2xpbmExFDASBgNV
# BAcTC01vcnJpc3ZpbGxlMQ8wDQYDVQQKEwZMZW5vdm8xDzANBgNVBAMTBkxlbm92
# bzCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBALVacqHydjmqo6bF2tHw
# cETPkOZLgPv1tJeIerpLcfmxLoX40GsUiY5l96B13bcfKjKBJQvHsj5D08RfGnif
# K+sGsAX8xCgaYNLxq0COKn51GgLLMNgzlE4rR/8mUMuWK2fKXs24dmn7teE2+e+2
# dz/GfHXgrAIPvIr4PN+dZAFeoj6/wfpLLHZXtQLxKVmtDFc7gQZkM6Z8o0HrH2eX
# 2MVNQwbZZWvSQhqRN66/LMcXxbLP8SAb6nKRCExflbI5i+MpEq+xOdiJxkP5dC5s
# rQ31JGLDdhbuAcUJEdXATzgP1pT9is3uWZm3fro71Kvfa0XLwBZWR2ut8sQ6KUhd
# 0Nsmd5c0f2PiD2uTd9mDWHQ34bu9mDunZaeWZrIlUP9MJ8TMM82ao/4tjFNK5m3T
# hZUbCGwoepenXq8yjbKMKqHHvcoJY0SmkAIlUzWoRBbRC+uN0TwcR048sZDPo+ZC
# gdONLPrjnsIU+NxuhfDMnj4UYbkRbtvnJ+U0O4Eu+ajRS87Li+jN2jHrABvAUXtP
# J7DkkxTTfaspzlfxueoqVKcGLnu4PUAthKg3g4hleGgeo7s+krEDAzyvdBnY+b8U
# dRH/BCxDr7G5ys/bCMPEzcUFT5LrrVBHO6N2U65iYkamzEo4okrrCNFDJPZC1G/p
# NleTeiIadSPTT0tJGPK+nDo1AgMBAAGjggIDMIIB/zAfBgNVHSMEGDAWgBRoN+Dr
# tjv4XxGG+/5hewiIZfROQjAdBgNVHQ4EFgQU7R8eucYUNncCkcWYWfCltSt/mxYw
# PgYDVR0gBDcwNTAzBgZngQwBBAEwKTAnBggrBgEFBQcCARYbaHR0cDovL3d3dy5k
# aWdpY2VydC5jb20vQ1BTMA4GA1UdDwEB/wQEAwIHgDATBgNVHSUEDDAKBggrBgEF
# BQcDAzCBtQYDVR0fBIGtMIGqMFOgUaBPhk1odHRwOi8vY3JsMy5kaWdpY2VydC5j
# b20vRGlnaUNlcnRUcnVzdGVkRzRDb2RlU2lnbmluZ1JTQTQwOTZTSEEzODQyMDIx
# Q0ExLmNybDBToFGgT4ZNaHR0cDovL2NybDQuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0
# VHJ1c3RlZEc0Q29kZVNpZ25pbmdSU0E0MDk2U0hBMzg0MjAyMUNBMS5jcmwwgZQG
# CCsGAQUFBwEBBIGHMIGEMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdpY2Vy
# dC5jb20wXAYIKwYBBQUHMAKGUGh0dHA6Ly9jYWNlcnRzLmRpZ2ljZXJ0LmNvbS9E
# aWdpQ2VydFRydXN0ZWRHNENvZGVTaWduaW5nUlNBNDA5NlNIQTM4NDIwMjFDQTEu
# Y3J0MAkGA1UdEwQCMAAwDQYJKoZIhvcNAQELBQADggIBAC0PiOF1B8Qdp2pcfb3P
# 6MuzaeTUw77bfMSCcnwY8xFtkyRRp9H6X4ZaSTdAQge3d6NG7OcHnGQ3FKraZqT3
# ugjNEXvH1MXr8SNgFb7t7TyKDK0RmRK9idsycLJfRsmbj0FSTL12jqrzyHrQqkTq
# KaDqYfIVan7VxP2On8gq3/OT368z1YJbRgfu/rNpXoYpXTKSfxaIXNE7rEiUwu+T
# vi8wgfLqC/a7ujC8vbYRWgaHHsz3bjFVN/h1p78adds2GdxPzYFoS12+JKq2cKGe
# Ma5Hbr2YQfHsbpQlzZglB3mGCci+uhN5YGaHleo3Ohd0BHci32RFOA1xdD8fS9TD
# pGRMGLKF9z5WTmiGZVR4x54Qwtf4clbA5V0P9d4ppmLZJKdeaHd/JKONVJ9nYV1H
# NA52CgvgRWpUc+jxnPL5A3J9qIvUXp98ZQifEyHBFX2VqWTdu9MldzklRo/eAT1k
# MUVheRAcd32yLDiFvn7lp2nasJs8Hh+6bUxfHKbKBrNrw7CmcTDzFK119BkykWS0
# vL7xsbCEbavLIhW/ZqEjWA9k/v2FS2wbBQ9YOC8F3magnslxWlZWsym3Dxdm0Hr1
# WKHbnFcBscMiBQ+fhLDAqIG8tPPnNhc7QhOOlxQlbfEDh8QmQbUo2H9hJJEGiHJS
# VwuAKbcWembFyAgLV02ASxS7MYIGSDCCBkQCAQEwfTBpMQswCQYDVQQGEwJVUzEX
# MBUGA1UEChMORGlnaUNlcnQsIEluYy4xQTA/BgNVBAMTOERpZ2lDZXJ0IFRydXN0
# ZWQgRzQgQ29kZSBTaWduaW5nIFJTQTQwOTYgU0hBMzg0IDIwMjEgQ0ExAhAFfARo
# FtaNDha0m0G6FxiVMAkGBSsOAwIaBQCgeDAYBgorBgEEAYI3AgEMMQowCKACgACh
# AoAAMBkGCSqGSIb3DQEJAzEMBgorBgEEAYI3AgEEMBwGCisGAQQBgjcCAQsxDjAM
# BgorBgEEAYI3AgEVMCMGCSqGSIb3DQEJBDEWBBQFiszM0yIe5DFb8jWNxhWY7BeG
# wjANBgkqhkiG9w0BAQEFAASCAgAqgwqBbypv6+opryGYW0ytPl0sAH94pawInBXd
# GKrD2KYCk0yjMMoNiH4No4kD/DVVy+UY/iy7AAPmNl9KR4wsVxbKyrMxrn8LrlWc
# 15dN5Z+E3tMEdtCY5VyjQhlf5ECbGdNLIAWmHciwVZoTd4Od8UeVtfrNJvwETakg
# C1GNB6LkRl332pcf8/cUYz1Gmo4eRmI+LnWj1YSz7TsaXy/CQ2zSMS66sYnWJVgY
# 6GmV/BGkHHWefglVFZiHWg9n/4sHog6BZZ5RSVNXmsJZytG282vtao4Qhm9uD0Hz
# lcrqsvqkRRx++Hv/7V9fAsvTSiF9q8R1LSXaJr967QjeTPHk/QBVfTZ10qKpxTcu
# PMxD4yxCG+0QVOPVQ6kY6OI8MiTXQy1jEDuIvWFi6V/Yk0Sc+0Mke1e1nwS2WVfP
# +elI18hnOc9XrFQO0xE1djrcRlkG9Y2/kRb3Iso2wweBj2A9o2167ohEAGXgC2O5
# EHKvT9VfM91CzJlurdSYypfd9Ap5c0pa7tV5MTTZ9BRlBjwfEbMMXlXtsSyEJYTi
# +h43v2OGw0M2Yz9tEnfnDoTcqAicuJI16vChFkAqSzgifuX1WkZb9yIrYypPO0Ln
# zwKQBtfT4mH27qOpX5uhN3tiuHSgxL4wNrK13KUAbpNhuYHK7f4Kq90rolc3lssc
# szIjx6GCAyYwggMiBgkqhkiG9w0BCQYxggMTMIIDDwIBATB9MGkxCzAJBgNVBAYT
# AlVTMRcwFQYDVQQKEw5EaWdpQ2VydCwgSW5jLjFBMD8GA1UEAxM4RGlnaUNlcnQg
# VHJ1c3RlZCBHNCBUaW1lU3RhbXBpbmcgUlNBNDA5NiBTSEEyNTYgMjAyNSBDQTEC
# EAhP3DNPfkVO28MPj/mSGDUwDQYJYIZIAWUDBAIBBQCgaTAYBgkqhkiG9w0BCQMx
# CwYJKoZIhvcNAQcBMBwGCSqGSIb3DQEJBTEPFw0yNjA5MjQxODEzNTNaMC8GCSqG
# SIb3DQEJBDEiBCDUUuAJY5stvE6xhrclpNGkG8PH0Io/9FIovKbNiocOOTANBgkq
# hkiG9w0BAQEFAASCAgA3Efl/Jdx3ivg3wr6m8q8hBHHVaTGe0731mw1msHRLmFgI
# al1kQa33wSKmY+/Pt1gW9VXHolACTcMCg0pa/YaxW0Lz6S++QEWcxx9gcibKK2RG
# FvuncDi3PBIO4aIEjnxnhf52BZZavcACEP6KMomYGucVmx0iuepKhiFESJxfDOW9
# XT8n0a0yirZw1OicAnzCackO3gzHzRhwP9V01ZVOSEIEviDMqLioPeLr7oTOVRe8
# 9xbhsQNdRFANglnMlG/krtFp3SvHmwD7Hb1KBKzBxldYur4hsxjzYnN+Cvb5QGpD
# uS+ij95Z1j+RRQLCUca5Ly2mOQDJLb5HTa9CW/eucfsLmhZPDJtUthdGa1qmX75B
# PUcrJqnVRZJCZ1Bmec3RsjxPkF8HN6i/Oz7+4ImVeleTHHNRv+4qJlb9kU0L0rdR
# b1WJMflx/SIV4fC68vWi29GVdAr1V1X2vIQO9TeAzH/cJxNOhD5LIjHWN7WKVTAo
# NAkY9K7z5vVK0KoXlR9yOa00ZWri66TmhJnVIMk5M1FiMAUqb2Jf7HDkJPWEH2Yu
# S+ONfQh+Cg4PJ6YZkqI+l2UbFWtr02pOoU4XUj17eDklafjPTF1M/Qh74d/ppBZt
# 2soI9ew/W8od0p4ly4Qvmw3BPGkaSr6ZYeUQQxGF4Q/zj2wIxY3EfWtWFcmp/g==
# SIG # End signature block