modules/Get-TechToolboxEnvironmentHealth.ps1

<#
.SYNOPSIS
    Checks the local TechToolbox environment for common issues that block
    automation.
.DESCRIPTION
    Performs a pre-flight diagnostic check on the local system to identify
    potential blockers for TechToolbox agent sessions. Specifically addresses
    recurrent failures seen in recent history:
 
    1. OneDrive sync locks causing 'Permission denied' errors on C:\TechToolbox.
    2. PSReadLine prediction source crashes (specifically 'HistoryAndPlugin')
       during tool execution.
    3. Missing or inaccessible TechToolbox module root directory.
 
.PARAMETER AsObject
    Returns results as PSCustomObjects instead of formatted tables for pipeline
    processing.
 
.EXAMPLE
    Get-TechToolboxEnvironmentHealth
 
.EXAMPLE
    Get-TechToolboxEnvironmentHealth -AsObject | Where-Object Status -eq 'FAIL'
#>


function Get-TechToolboxEnvironmentHealth {
    [CmdletBinding()]
    param(
        [switch]$AsObject
    )

    $results = @()

    # --- Fix 1: Missing Environment Fallback ---
    # If $env:TT_Home is not set, fallback to the known TechToolbox root path.
    $ttRoot = $env:TT_Home
    if (-not $ttRoot) {
        $ttRoot = "C:\Users\dan\OneDrive\TechStuff\TechToolbox"
    }

    # --- Check 1: TechToolbox Root Directory Existence & Writability ---
    try {
        if (Test-Path -Path $ttRoot -PathType Container) {
            # Test writability by attempting to create and remove a temporary file
            $writable = $false
            try {
                $tempFile = Join-Path $ttRoot "TTHealthCheck.tmp"
                [io.file]::Create($tempFile).Close()
                Remove-Item $tempFile -ErrorAction Stop
                $writable = $true
            }
            catch [System.UnauthorizedAccessException], [System.IO.IOException] {
                $writable = $false
            }

            if ($writable) {
                $results += [PSCustomObject]@{
                    Category = "Environment"
                    Check    = "TechToolbox Root Writability"
                    Status   = "PASS"
                    Detail   = "$ttRoot exists and is writable."
                }
            }
            else {
                $results += [PSCustomObject]@{
                    Category = "Environment"
                    Check    = "TechToolbox Root Writability"
                    Status   = "FAIL"
                    Detail   = "$ttRoot exists but cannot be written to. Check permissions or OneDrive sync."
                }
            }
        }
        else {
            $results += [PSCustomObject]@{
                Category = "Environment"
                Check    = "TechToolbox Root Existence"
                Status   = "FAIL"
                Detail   = "$ttRoot does not exist. Automation cannot proceed."
            }
        }
    }
    catch {
        $results += [PSCustomObject]@{
            Category = "Environment"
            Check    = "TechToolbox Root Existence"
            Status   = "ERROR"
            Detail   = $_.Exception.Message
        }
    }

    # --- Check 2: OneDrive Service & Sync Status ---
    try {
        $oneDriveSvc = Get-Service -Name OneDrive -ErrorAction SilentlyContinue
        if ($oneDriveSvc) {
            if ($oneDriveSvc.Status -eq 'Running') {
                # --- Fix 2: Hardcoded OneDrive Path ---
                # Use dynamic $ttRoot instead of hardcoded "C:\TechToolbox"
                $results += [PSCustomObject]@{
                    Category = "Sync Interference"
                    Check    = "OneDrive Active Sync"
                    Status   = "WARNING"
                    Detail   = "OneDrive is running. Monitor for file lock contention on `$ttRoot paths."
                }
            }
            else {
                $results += [PSCustomObject]@{
                    Category = "Sync Interference"
                    Check    = "OneDrive Service Status"
                    Status   = "PASS"
                    Detail   = "OneDrive service is stopped or paused. Safe for automated file writes."
                }
            }
        }
        else {
            $results += [PSCustomObject]@{
                Category = "Sync Interference"
                Check    = "OneDrive Presence"
                Status   = "INFO"
                Detail   = "OneDrive service not found on this system."
            }
        }
    }
    catch {
        $results += [PSCustomObject]@{
            Category = "Sync Interference"
            Check    = "OneDrive Service Status"
            Status   = "ERROR"
            Detail   = $_.Exception.Message
        }
    }

    # --- Check 3: PSReadLine Configuration (Critical for Tool Execution) ---
    try {
        $psOpt = Get-PSReadlineOption -ErrorAction SilentlyContinue
        if ($psOpt) {
            $predSource = $psOpt.PredictionSource

            # --- Fix 3: PSReadLine Check Robustness ---
            # Avoid [Enum]::ToObject which can crash if the assembly is not loaded.
            # Use string comparison instead for safety in constrained contexts.
            if ([string]$predSource -eq 'HistoryAndPlugin') {
                $results += [PSCustomObject]@{
                    Category = "PowerShell Runtime"
                    Check    = "PSReadLine Prediction Source"
                    Status   = "WARNING"
                    Detail   = "Set to 'HistoryAndPlugin'. This is known to crash in constrained tool execution contexts. Consider using 'HistoryOnly'."
                }
            }
            else {
                $results += [PSCustomObject]@{
                    Category = "PowerShell Runtime"
                    Check    = "PSReadLine Prediction Source"
                    Status   = "PASS"
                    Detail   = "Set to '$predSource'. Compatible with constrained execution contexts."
                }
            }
        }
        else {
            $results += [PSCustomObject]@{
                Category = "PowerShell Runtime"
                Check    = "PSReadLine Configuration"
                Status   = "INFO"
                Detail   = "Could not retrieve PSReadline options."
            }
        }
    }
    catch {
        $results += [PSCustomObject]@{
            Category = "PowerShell Runtime"
            Check    = "PSReadLine Configuration"
            Status   = "ERROR"
            Detail   = $_.Exception.Message
        }
    }

    # --- Check 4: PowerShell Version ---
    $psVer = $PSVersionTable.PSVersion
    if ($psVer.Major -ge 5) {
        $results += [PSCustomObject]@{
            Category = "Runtime"
            Check    = "PowerShell Version"
            Status   = "PASS"
            Detail   = "Running PowerShell $($psVer.ToString()) (Major version >= 5 required)."
        }
    }
    else {
        $results += [PSCustomObject]@{
            Category = "Runtime"
            Check    = "PowerShell Version"
            Status   = "FAIL"
            Detail   = "PowerShell major version is $($psVer.Major). Minimum version 5 required."
        }
    }

    if ($AsObject) { return $results }

    # Formatting output
    Write-Output "`n=== TechToolbox Environment Health Check ===`n"
    $results | Format-Table -AutoSize
    $failCount = ($results | Where-Object Status -eq 'FAIL').Count
    $warnCount = ($results | Where-Object Status -eq 'WARNING').Count

    if ($failCount -gt 0) {
        Write-Warning "$failCount check(s) FAILED. Automation may be blocked."
    }
    elseif ($warnCount -gt 0) {
        Write-Warning "$warnCount check(s) WARNED. Review before proceeding."
    }
    else {
        Write-Host "All checks PASSED. Environment is healthy." -ForegroundColor Green
    }
}

Export-ModuleMember -Function Get-TechToolboxEnvironmentHealth

# SIG # Begin signature block
# MIIfAgYJKoZIhvcNAQcCoIIe8zCCHu8CAQExDzANBglghkgBZQMEAgEFADB5Bgor
# BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG
# KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCBK1FZN2QLA3DZr
# nR+2djGqFoDGVArGf7JZekaL4DGqv6CCGEowggUMMIIC9KADAgECAhAR+U4xG7FH
# qkyqS9NIt7l5MA0GCSqGSIb3DQEBCwUAMB4xHDAaBgNVBAMME1ZBRFRFSyBDb2Rl
# IFNpZ25pbmcwHhcNMjUxMjE5MTk1NDIxWhcNMjYxMjE5MjAwNDIxWjAeMRwwGgYD
# VQQDDBNWQURURUsgQ29kZSBTaWduaW5nMIICIjANBgkqhkiG9w0BAQEFAAOCAg8A
# MIICCgKCAgEA3pzzZIUEY92GDldMWuzvbLeivHOuMupgpwbezoG5v90KeuN03S5d
# nM/eom/PcIz08+fGZF04ueuCS6b48q1qFnylwg/C/TkcVRo0WFcKoFGT8yGxdfXi
# caHtapZfbSRh73r7qR7w0CioVveNBVgfMsTgE0WKcuwxemvIe/ptmkfzwAiw/IAC
# Ib0E0BjiX4PySbwWy/QKy/qMXYY19xpRItVTKNBtXzADUtzPzUcFqJU83vM2gZFs
# Or0MhPvM7xEVkOWZFBAWAubbMCJ3rmwyVv9keVDJChhCeLSz2XR11VGDOEA2OO90
# Y30WfY9aOI2sCfQcKMeJ9ypkHl0xORdhUwZ3Wz48d3yJDXGkduPm2vl05RvnA4T6
# 29HVZTmMdvP2475/8nLxCte9IB7TobAOGl6P1NuwplAMKM8qyZh62Br23vcx1fXZ
# TJlKCxBFx1nTa6VlIJk+UbM4ZPm954peB/fIqEacm8LkZ0cPwmLE5ckW7hfK4Trs
# o+RaudU1sKeA+FvpOWgsPccVRWcEYyGkwbyTB3xrIBXA+YckbANZ0XL7fv7x29hn
# gXbZipGu3DnTISiFB43V4MhNDKZYfbWdxze0SwLe8KzIaKnwlwRgvXDMwXgk99Mi
# EbYa3DvA/5ZWikLW9PxBFD7Vdr8ZiG/tRC9I2Y6fnb+PVoZKc/2xsW0CAwEAAaNG
# MEQwDgYDVR0PAQH/BAQDAgeAMBMGA1UdJQQMMAoGCCsGAQUFBwMDMB0GA1UdDgQW
# BBRfYLVE8caSc990rnrIHUjoB7X/KjANBgkqhkiG9w0BAQsFAAOCAgEAiGB2Wmk3
# QBtd1LcynmxHzmu+X4Y5DIpMMNC2ahsqZtPUVcGqmb5IFbVuAdQphL6PSrDjaAR8
# 1S8uTfUnMa119LmIb7di7TlH2F5K3530h5x8JMj5EErl0xmZyJtSg7BTiBA/UrMz
# 6WCf8wWIG2/4NbV6aAyFwIojfAcKoO8ng44Dal/oLGzLO3FDE5AWhcda/FbqVjSJ
# 1zMfiW8odd4LgbmoyEI024KkwOkkPyJQ2Ugn6HMqlFLazAmBBpyS7wxdaAGrl18n
# 6bS7QuAwCd9hitdMMitG8YyWL6tKeRSbuTP5E+ASbu0Ga8/fxRO5ZSQhO6/5ro1j
# PGe1/Kr49Uyuf9VSCZdNIZAyjjeVAoxmV0IfxQLKz6VOG0kGDYkFGskvllIpQbQg
# WLuPLJxoskJsoJllk7MjZJwrpr08+3FQnLkRuisjDOc3l4VxFUsUe4fnJhMUONXT
# Sk7vdspgxirNbLmXU4yYWdsizz3nMUR0zebUW29A+HYme16hzrMPOeyoQjy4I5XX
# 3wXAFdworfPEr/ozDFrdXKgbLwZopymKbBwv6wtT7+1zVhJXr+jGVQ1TWr6R+8ea
# tIOFnY7HqGaxe5XB7HzOwJKdj+bpHAfXft1vUoiKr16VajLigcYCG8MdwC3sngO3
# JDyv2V+YMfsYBmItMGBwvizlQ6557NbK95EwggWNMIIEdaADAgECAhAOmxiO+dAt
# 5+/bUOIIQBhaMA0GCSqGSIb3DQEBDAUAMGUxCzAJBgNVBAYTAlVTMRUwEwYDVQQK
# EwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xJDAiBgNV
# BAMTG0RpZ2lDZXJ0IEFzc3VyZWQgSUQgUm9vdCBDQTAeFw0yMjA4MDEwMDAwMDBa
# Fw0zMTExMDkyMzU5NTlaMGIxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2Vy
# dCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xITAfBgNVBAMTGERpZ2lD
# ZXJ0IFRydXN0ZWQgUm9vdCBHNDCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoC
# ggIBAL/mkHNo3rvkXUo8MCIwaTPswqclLskhPfKK2FnC4SmnPVirdprNrnsbhA3E
# MB/zG6Q4FutWxpdtHauyefLKEdLkX9YFPFIPUh/GnhWlfr6fqVcWWVVyr2iTcMKy
# unWZanMylNEQRBAu34LzB4TmdDttceItDBvuINXJIB1jKS3O7F5OyJP4IWGbNOsF
# xl7sWxq868nPzaw0QF+xembud8hIqGZXV59UWI4MK7dPpzDZVu7Ke13jrclPXuU1
# 5zHL2pNe3I6PgNq2kZhAkHnDeMe2scS1ahg4AxCN2NQ3pC4FfYj1gj4QkXCrVYJB
# MtfbBHMqbpEBfCFM1LyuGwN1XXhm2ToxRJozQL8I11pJpMLmqaBn3aQnvKFPObUR
# WBf3JFxGj2T3wWmIdph2PVldQnaHiZdpekjw4KISG2aadMreSx7nDmOu5tTvkpI6
# nj3cAORFJYm2mkQZK37AlLTSYW3rM9nF30sEAMx9HJXDj/chsrIRt7t/8tWMcCxB
# YKqxYxhElRp2Yn72gLD76GSmM9GJB+G9t+ZDpBi4pncB4Q+UDCEdslQpJYls5Q5S
# UUd0viastkF13nqsX40/ybzTQRESW+UQUOsxxcpyFiIJ33xMdT9j7CFfxCBRa2+x
# q4aLT8LWRV+dIPyhHsXAj6KxfgommfXkaS+YHS312amyHeUbAgMBAAGjggE6MIIB
# NjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTs1+OC0nFdZEzfLmc/57qYrhwP
# TzAfBgNVHSMEGDAWgBRF66Kv9JLLgjEtUYunpyGd823IDzAOBgNVHQ8BAf8EBAMC
# AYYweQYIKwYBBQUHAQEEbTBrMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdp
# Y2VydC5jb20wQwYIKwYBBQUHMAKGN2h0dHA6Ly9jYWNlcnRzLmRpZ2ljZXJ0LmNv
# bS9EaWdpQ2VydEFzc3VyZWRJRFJvb3RDQS5jcnQwRQYDVR0fBD4wPDA6oDigNoY0
# aHR0cDovL2NybDMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEUm9vdENB
# LmNybDARBgNVHSAECjAIMAYGBFUdIAAwDQYJKoZIhvcNAQEMBQADggEBAHCgv0Nc
# Vec4X6CjdBs9thbX979XB72arKGHLOyFXqkauyL4hxppVCLtpIh3bb0aFPQTSnov
# Lbc47/T/gLn4offyct4kvFIDyE7QKt76LVbP+fT3rDB6mouyXtTP0UNEm0Mh65Zy
# oUi0mcudT6cGAxN3J0TU53/oWajwvy8LpunyNDzs9wPHh6jSTEAZNUZqaVSwuKFW
# juyk1T3osdz9HNj0d1pcVIxv76FQPfx2CWiEn2/K2yCNNWAcAgPLILCsWKAOQGPF
# mCLBsln1VWvPJ6tsds5vIy30fnFqI2si/xK4VC0nftg62fC2h5b9W9FcrBjDTZ9z
# twGpn1eqXijiuZQwgga0MIIEnKADAgECAhANx6xXBf8hmS5AQyIMOkmGMA0GCSqG
# SIb3DQEBCwUAMGIxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMx
# GTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xITAfBgNVBAMTGERpZ2lDZXJ0IFRy
# dXN0ZWQgUm9vdCBHNDAeFw0yNTA1MDcwMDAwMDBaFw0zODAxMTQyMzU5NTlaMGkx
# CzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5EaWdpQ2VydCwgSW5jLjFBMD8GA1UEAxM4
# RGlnaUNlcnQgVHJ1c3RlZCBHNCBUaW1lU3RhbXBpbmcgUlNBNDA5NiBTSEEyNTYg
# MjAyNSBDQTEwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC0eDHTCphB
# cr48RsAcrHXbo0ZodLRRF51NrY0NlLWZloMsVO1DahGPNRcybEKq+RuwOnPhof6p
# vF4uGjwjqNjfEvUi6wuim5bap+0lgloM2zX4kftn5B1IpYzTqpyFQ/4Bt0mAxAHe
# HYNnQxqXmRinvuNgxVBdJkf77S2uPoCj7GH8BLuxBG5AvftBdsOECS1UkxBvMgEd
# gkFiDNYiOTx4OtiFcMSkqTtF2hfQz3zQSku2Ws3IfDReb6e3mmdglTcaarps0wjU
# jsZvkgFkriK9tUKJm/s80FiocSk1VYLZlDwFt+cVFBURJg6zMUjZa/zbCclF83bR
# VFLeGkuAhHiGPMvSGmhgaTzVyhYn4p0+8y9oHRaQT/aofEnS5xLrfxnGpTXiUOeS
# LsJygoLPp66bkDX1ZlAeSpQl92QOMeRxykvq6gbylsXQskBBBnGy3tW/AMOMCZIV
# NSaz7BX8VtYGqLt9MmeOreGPRdtBx3yGOP+rx3rKWDEJlIqLXvJWnY0v5ydPpOjL
# 6s36czwzsucuoKs7Yk/ehb//Wx+5kMqIMRvUBDx6z1ev+7psNOdgJMoiwOrUG2Zd
# SoQbU2rMkpLiQ6bGRinZbI4OLu9BMIFm1UUl9VnePs6BaaeEWvjJSjNm2qA+sdFU
# eEY0qVjPKOWug/G6X5uAiynM7Bu2ayBjUwIDAQABo4IBXTCCAVkwEgYDVR0TAQH/
# BAgwBgEB/wIBADAdBgNVHQ4EFgQU729TSunkBnx6yuKQVvYv1Ensy04wHwYDVR0j
# BBgwFoAU7NfjgtJxXWRM3y5nP+e6mK4cD08wDgYDVR0PAQH/BAQDAgGGMBMGA1Ud
# JQQMMAoGCCsGAQUFBwMIMHcGCCsGAQUFBwEBBGswaTAkBggrBgEFBQcwAYYYaHR0
# cDovL29jc3AuZGlnaWNlcnQuY29tMEEGCCsGAQUFBzAChjVodHRwOi8vY2FjZXJ0
# cy5kaWdpY2VydC5jb20vRGlnaUNlcnRUcnVzdGVkUm9vdEc0LmNydDBDBgNVHR8E
# PDA6MDigNqA0hjJodHRwOi8vY3JsMy5kaWdpY2VydC5jb20vRGlnaUNlcnRUcnVz
# dGVkUm9vdEc0LmNybDAgBgNVHSAEGTAXMAgGBmeBDAEEAjALBglghkgBhv1sBwEw
# DQYJKoZIhvcNAQELBQADggIBABfO+xaAHP4HPRF2cTC9vgvItTSmf83Qh8WIGjB/
# T8ObXAZz8OjuhUxjaaFdleMM0lBryPTQM2qEJPe36zwbSI/mS83afsl3YTj+IQhQ
# E7jU/kXjjytJgnn0hvrV6hqWGd3rLAUt6vJy9lMDPjTLxLgXf9r5nWMQwr8Myb9r
# EVKChHyfpzee5kH0F8HABBgr0UdqirZ7bowe9Vj2AIMD8liyrukZ2iA/wdG2th9y
# 1IsA0QF8dTXqvcnTmpfeQh35k5zOCPmSNq1UH410ANVko43+Cdmu4y81hjajV/gx
# dEkMx1NKU4uHQcKfZxAvBAKqMVuqte69M9J6A47OvgRaPs+2ykgcGV00TYr2Lr3t
# y9qIijanrUR3anzEwlvzZiiyfTPjLbnFRsjsYg39OlV8cipDoq7+qNNjqFzeGxcy
# tL5TTLL4ZaoBdqbhOhZ3ZRDUphPvSRmMThi0vw9vODRzW6AxnJll38F0cuJG7uEB
# YTptMSbhdhGQDpOXgpIUsWTjd6xpR6oaQf/DJbg3s6KCLPAlZ66RzIg9sC+NJpud
# /v4+7RWsWCiKi9EOLLHfMR2ZyJ/+xhCx9yHbxtl5TPau1j/1MIDpMPx0LckTetiS
# uEtQvLsNz3Qbp7wGWqbIiOWCnb5WqxL3/BAPvIXKUjPSxyZsq8WhbaM2tszWkPZP
# ubdcMIIG7TCCBNWgAwIBAgIQCoDvGEuN8QWC0cR2p5V0aDANBgkqhkiG9w0BAQsF
# ADBpMQswCQYDVQQGEwJVUzEXMBUGA1UEChMORGlnaUNlcnQsIEluYy4xQTA/BgNV
# BAMTOERpZ2lDZXJ0IFRydXN0ZWQgRzQgVGltZVN0YW1waW5nIFJTQTQwOTYgU0hB
# MjU2IDIwMjUgQ0ExMB4XDTI1MDYwNDAwMDAwMFoXDTM2MDkwMzIzNTk1OVowYzEL
# MAkGA1UEBhMCVVMxFzAVBgNVBAoTDkRpZ2lDZXJ0LCBJbmMuMTswOQYDVQQDEzJE
# aWdpQ2VydCBTSEEyNTYgUlNBNDA5NiBUaW1lc3RhbXAgUmVzcG9uZGVyIDIwMjUg
# MTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANBGrC0Sxp7Q6q5gVrMr
# V7pvUf+GcAoB38o3zBlCMGMyqJnfFNZx+wvA69HFTBdwbHwBSOeLpvPnZ8ZN+vo8
# dE2/pPvOx/Vj8TchTySA2R4QKpVD7dvNZh6wW2R6kSu9RJt/4QhguSssp3qome7M
# rxVyfQO9sMx6ZAWjFDYOzDi8SOhPUWlLnh00Cll8pjrUcCV3K3E0zz09ldQ//nBZ
# ZREr4h/GI6Dxb2UoyrN0ijtUDVHRXdmncOOMA3CoB/iUSROUINDT98oksouTMYFO
# nHoRh6+86Ltc5zjPKHW5KqCvpSduSwhwUmotuQhcg9tw2YD3w6ySSSu+3qU8DD+n
# igNJFmt6LAHvH3KSuNLoZLc1Hf2JNMVL4Q1OpbybpMe46YceNA0LfNsnqcnpJeIt
# K/DhKbPxTTuGoX7wJNdoRORVbPR1VVnDuSeHVZlc4seAO+6d2sC26/PQPdP51ho1
# zBp+xUIZkpSFA8vWdoUoHLWnqWU3dCCyFG1roSrgHjSHlq8xymLnjCbSLZ49kPmk
# 8iyyizNDIXj//cOgrY7rlRyTlaCCfw7aSUROwnu7zER6EaJ+AliL7ojTdS5PWPsW
# eupWs7NpChUk555K096V1hE0yZIXe+giAwW00aHzrDchIc2bQhpp0IoKRR7YufAk
# prxMiXAJQ1XCmnCfgPf8+3mnAgMBAAGjggGVMIIBkTAMBgNVHRMBAf8EAjAAMB0G
# A1UdDgQWBBTkO/zyMe39/dfzkXFjGVBDz2GM6DAfBgNVHSMEGDAWgBTvb1NK6eQG
# fHrK4pBW9i/USezLTjAOBgNVHQ8BAf8EBAMCB4AwFgYDVR0lAQH/BAwwCgYIKwYB
# BQUHAwgwgZUGCCsGAQUFBwEBBIGIMIGFMCQGCCsGAQUFBzABhhhodHRwOi8vb2Nz
# cC5kaWdpY2VydC5jb20wXQYIKwYBBQUHMAKGUWh0dHA6Ly9jYWNlcnRzLmRpZ2lj
# ZXJ0LmNvbS9EaWdpQ2VydFRydXN0ZWRHNFRpbWVTdGFtcGluZ1JTQTQwOTZTSEEy
# NTYyMDI1Q0ExLmNydDBfBgNVHR8EWDBWMFSgUqBQhk5odHRwOi8vY3JsMy5kaWdp
# Y2VydC5jb20vRGlnaUNlcnRUcnVzdGVkRzRUaW1lU3RhbXBpbmdSU0E0MDk2U0hB
# MjU2MjAyNUNBMS5jcmwwIAYDVR0gBBkwFzAIBgZngQwBBAIwCwYJYIZIAYb9bAcB
# MA0GCSqGSIb3DQEBCwUAA4ICAQBlKq3xHCcEua5gQezRCESeY0ByIfjk9iJP2zWL
# pQq1b4URGnwWBdEZD9gBq9fNaNmFj6Eh8/YmRDfxT7C0k8FUFqNh+tshgb4O6Lgj
# g8K8elC4+oWCqnU/ML9lFfim8/9yJmZSe2F8AQ/UdKFOtj7YMTmqPO9mzskgiC3Q
# YIUP2S3HQvHG1FDu+WUqW4daIqToXFE/JQ/EABgfZXLWU0ziTN6R3ygQBHMUBaB5
# bdrPbF6MRYs03h4obEMnxYOX8VBRKe1uNnzQVTeLni2nHkX/QqvXnNb+YkDFkxUG
# tMTaiLR9wjxUxu2hECZpqyU1d0IbX6Wq8/gVutDojBIFeRlqAcuEVT0cKsb+zJNE
# suEB7O7/cuvTQasnM9AWcIQfVjnzrvwiCZ85EE8LUkqRhoS3Y50OHgaY7T/lwd6U
# Arb+BOVAkg2oOvol/DJgddJ35XTxfUlQ+8Hggt8l2Yv7roancJIFcbojBcxlRcGG
# 0LIhp6GvReQGgMgYxQbV1S3CrWqZzBt1R9xJgKf47CdxVRd/ndUlQ05oxYy2zRWV
# FjF7mcr4C34Mj3ocCVccAvlKV9jEnstrniLvUxxVZE/rptb7IRE2lskKPIJgbaP5
# t2nGj/ULLi49xTcBZU8atufk+EMF/cWuiC7POGT75qaL6vdCvHlshtjdNXOCIUjs
# arfNZzGCBg4wggYKAgEBMDIwHjEcMBoGA1UEAwwTVkFEVEVLIENvZGUgU2lnbmlu
# ZwIQEflOMRuxR6pMqkvTSLe5eTANBglghkgBZQMEAgEFAKCBhDAYBgorBgEEAYI3
# AgEMMQowCKACgAChAoAAMBkGCSqGSIb3DQEJAzEMBgorBgEEAYI3AgEEMBwGCisG
# AQQBgjcCAQsxDjAMBgorBgEEAYI3AgEVMC8GCSqGSIb3DQEJBDEiBCBMdZnD/Ty+
# O1UBRlzbdmz9CaTVCRc2SzfKcOM0TGlyIzANBgkqhkiG9w0BAQEFAASCAgCMx2gN
# mub2YwA8PCcq0BHC5mRBDMz/Au7WxDHTVoVzWy1NDG/AK8RNvyOgRMxiETG3fwQq
# m6J3ehlLFBqJkBEbppEsrD88/nYxbTJ2Ep1hWc3mnM3+1xU31iFw7zWWtNFMLwac
# LhLsWNETNjiwMO/hHPSTHSbuZB2kZDHNryV4F8tma7T36sVHjO25UTx98//mJKGX
# t/X3zzohY2+GIeJDTQFBRoF5V5HeHf1GxrzDG9NeQP3A690dDgRdTJQbx5Ebwoeo
# r7WcDUHXj6cwH6oddRGZX9RznsDGJGOpKe2EHINUIWQfvcrAfWEvZwDS9iXyt/QD
# f+z/Eqviq0A9buzWlAB4ptmaoELZHv4c8v7h6ydf5qlNSAqMUgy1nqVlV9DHWOyQ
# stV/em1o5QROEun4GsEZ6WrpSPyG5RQfkCviO4hnnk+T33QesWlJMnSGpe+eS2gV
# I9iSpBXNdGREu+c0Z+S6U1cs0Wr06/DKMsuL8sat/8hah9I4okU8XM4f4pnViKWu
# zo4twgCflOUtV0CzCAwsIjtct/xTLOhkAQpRroxH513pmYuAx8R2zRZaeI5yYiqm
# IY+dxLtkLcKay9tx/RNbplsTbUUreex+DJcER+8INWmpjUPxTZO3tLkjn5aKXNb7
# oA48ZyCjuYhxvcesp1HmD1zY4xXzQ3KjmSuzWKGCAyYwggMiBgkqhkiG9w0BCQYx
# ggMTMIIDDwIBATB9MGkxCzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5EaWdpQ2VydCwg
# SW5jLjFBMD8GA1UEAxM4RGlnaUNlcnQgVHJ1c3RlZCBHNCBUaW1lU3RhbXBpbmcg
# UlNBNDA5NiBTSEEyNTYgMjAyNSBDQTECEAqA7xhLjfEFgtHEdqeVdGgwDQYJYIZI
# AWUDBAIBBQCgaTAYBgkqhkiG9w0BCQMxCwYJKoZIhvcNAQcBMBwGCSqGSIb3DQEJ
# BTEPFw0yNjA2MDkyMzIwMTJaMC8GCSqGSIb3DQEJBDEiBCBAlavNUcMOQhXX2dou
# 6I7JEPXLn/kGtuy7kR29eeQP5DANBgkqhkiG9w0BAQEFAASCAgCJ4nt/MXyT1ygX
# R9zQ2jZakWQGHDhzoJY1/MvRGzxtTJ8FK8X2Eu3UANjlu57N0BHsFPSln3iXAr5W
# EH3L8y9oshYLheLsUH4rEbqGCe5rMFXDffh+8OAgYz7JcivvLM7AXZKZYJbSNDfz
# bUDmd3JpOwkRjwcAT+TSDRTajfAZi5bxPBk9EbDUfSwpT1UkTFGcxbbRmLnXvfIJ
# z9B8ZtYkrrhBC/UM9zeU929rb6fE4VRp/iVTitYF8VIR4lvJ3S1M6UHdVZdteXA3
# uaeBbopDAxWOl3pP9EiDaHSbbvtyou0pIR6eL0J1WpuDmAkvNKpDxlxCfGJ26DZv
# UQdVmGyhJIHLUDPKgR0Y89qKW9HB/fMOe35aSu+v8OXDNaDAYN9Z+raNEvm+HCZw
# 0RO4GJP6RL/zXu3oWZlnErFC/ZZd6KuUE+dq9Ttu/ATlxZ95O4uo89fcpOYPNvyv
# 52bt7C53OxdeoYFEIDV3z6HecNh9TyTMwI9bUknp4zlUQ7IukzcvXrIovi92lTT5
# msCNMZ4WdwCMYUhwUVttTgCRfqSCA00evISBNSc7fz9zh8YGBzV2ub9JRT9vwUSL
# fF9yLu8etMIkHs819uzDzc4cI6ULPzUg6Ev7845gYwzHLGFAchVDc9vBa/OYiGM2
# Urbn/l2j7bPh85l2AtpBJFzXWyhFKw==
# SIG # End signature block