AI/Agent/Export-ToolboxFunctions.ps1

<#
.SYNOPSIS
    Exports all public (and optionally private) functions from the TechToolbox module with comprehensive parameter metadata as JSON.
 
.DESCRIPTION
    This script is called by the Python agent to auto-discover available tools.
    It outputs a JSON array describing each function with:
    - Function name and aliases
    - Module name, version, and source path
    - Parameters (name, type, mandatory, default value, allowed values, parameter description)
    - Full help text sections (Synopsis, Description, Examples, Notes)
    - Auto-classified safety status (destructive vs. safe)
 
.PARAMETER ModuleName
    The name of the module to export functions from. Defaults to "TechToolbox".
 
.PARAMETER IncludePrivate
    When specified, includes private/internal functions (those with underscores in their names) in addition to public functions.
    By default, only public functions are exported for backward compatibility.
 
.NOTES
    Designed for AI agent consumption. Depth 10 ensures full nesting of parameter metadata and examples.
#>


param(
    [string]$ModuleName = "TechToolbox",
    [bool]$IncludePrivate = $true
)

# ============================================================
# Configuration
# ============================================================
$script:DestructiveVerbs = @(
    'Remove-', 'Clear-', 'Disable-', 'Stop-', 'Restart-',
    'Delete-', 'Drop-', 'Erase-', 'Purge-', 'Kill-',
    'Close-', 'Break-'
)

# ============================================================
# Import Module
# ============================================================
try {
    $importedModule = Import-Module $ModuleName -PassThru -ErrorAction Stop
}
catch {
    Write-Error "Unable to import module '$ModuleName': $_"
    exit 1
}

if (-not $importedModule) {
    Write-Error "Import of module '$ModuleName' returned null."
    exit 1
}

# ============================================================
# Gather Aliases Map (for resolving function aliases)
# ============================================================
$aliasMap = @{}
try {
    $allAliases = Get-Alias -ErrorAction SilentlyContinue
    foreach ($a in $allAliases) {
        if ($a.Definition -match '^Microsoft\.PowerShell\.Core\\?') {
            $target = $a.Definition -replace '^Microsoft\.PowerShell\.Core\\?'
            if (-not $aliasMap.ContainsKey($target)) {
                $aliasMap[$target] = @()
            }
            $aliasMap[$target] += $a.Name
        }
        else {
            # Module-scoped aliases
            $aliasMap[$a.Definition] += $a.Name
        }
    }
}
catch {
    Write-Warning "Could not build alias map: $_"
}

# ============================================================
# Process Each Function
# ============================================================
$functions = Get-Command -Module $importedModule.Name -CommandType Function | Where-Object {
    # Exclude private/internal functions unless IncludePrivate is specified
    if ($IncludePrivate) {
        $true  # Include all functions when the switch is set
    }
    else {
        # Default behavior: exclude names containing underscores (private convention)
        $_.Name -notlike '*_*'
    }
} | ForEach-Object {

    $funcName = $_.Name
    $isDestructive = $false

    foreach ($dv in $script:DestructiveVerbs) {
        if ($funcName -like "${dv}*") {
            $isDestructive = $true
            break
        }
    }

    # --------------------------------------------------------
    # Resolve aliases for this function
    # --------------------------------------------------------
    $resolvedAliases = @()
    $fullTarget = "Microsoft.PowerShell.Core\$funcName"
    if ($aliasMap.ContainsKey($fullTarget)) {
        $resolvedAliases += $aliasMap[$fullTarget]
    }
    # Also check by module-qualified name
    $modQualified = "${importedModule.Name}\$funcName"
    if ($aliasMap.ContainsKey($modQualified)) {
        $resolvedAliases += $aliasMap[$modQualified]
    }

    # --------------------------------------------------------
    # Extract full help (Full mode for Description, Examples, Notes)
    # --------------------------------------------------------
    $helpObj = Get-Help $funcName -Full -ErrorAction SilentlyContinue

    $synopsis = if ($helpObj?.Synopsis) { $helpObj.Synopsis }                    else { '' }
    $description = if ($helpObj?.Description.Text) { (@($helpObj.Description.Text) -join "`n") } else { '' }

    $examples = ''
    try {
        $exampleList = @($helpObj.Examples.Example)
        if ($exampleList.Count -gt 0) {
            $exampleStrings = $exampleList | ForEach-Object {
                $_.code + "`n" + (($_.remarks | Where-Object { $_ }) -join "`n")
            }
            $examples = $exampleStrings -join "`n`n"
        }
    }
    catch {
        Write-Verbose "Could not extract examples for $funcName"
    }

    $notes = ''
    try {
        $remarkBlocks = @($helpObj.Remarks.Text | Where-Object { $_ })
        if ($remarkBlocks.Count -gt 0) {
            $notes = $remarkBlocks -join "`n"
        }
    }
    catch {
        Write-Verbose "Could not extract notes for $funcName"
    }

    # --------------------------------------------------------
    # Extract enhanced parameter metadata
    # --------------------------------------------------------
    $params = @{}
    foreach ($p in $_.Parameters.Values) {

        $isMandatory = $false
        $defaultValue = $null
        $allowedValues = $null

        foreach ($attr in $p.Attributes) {
            if ($attr -is [System.Management.Automation.ParameterAttribute]) {
                if ($attr.Mandatory) { $isMandatory = $true }
                if (-not [string]::IsNullOrEmpty($attr.DefaultValue)) {
                    $defaultValue = $attr.DefaultValue.ToString()
                }
            }
            elseif ($attr -is [System.Management.Automation.ValidateSetAttribute]) {
                $allowedValues = @($attr.ValidValues)
            }
        }

        # Get parameter description from help
        $paramDescription = ''
        try {
            $paramHelpObj = Get-Help $funcName -Parameter $p.Name -ErrorAction SilentlyContinue
            if ($paramHelpObj?.Description) {
                $paramDescription = @($paramHelpObj.Description.Text | Where-Object { $_ }) -join "`n"
            }
        }
        catch {
            # Silently skip -- many params don't have individual help entries
        }

        # Get aliases for the parameter
        $paramAliases = try {
            if ($p.Aliases) { @($p.Aliases) } else { @() }
        }
        catch {
            @()
        }

        $params[$p.Name] = [PSCustomObject]@{
            Type          = $p.ParameterType.FullName
            Mandatory     = $isMandatory
            DefaultValue  = $defaultValue
            AllowedValues = $allowedValues
            Description   = $paramDescription
            Aliases       = $paramAliases
        }
    }

    # --------------------------------------------------------
    # Build final function descriptor
    # --------------------------------------------------------
    [PSCustomObject]@{
        Name          = $funcName
        Aliases       = if ($resolvedAliases) { @($resolvedAliases | Select-Object -Unique) } else { @() }
        Module        = $importedModule.Name
        ModuleVersion = $importedModule.Version.ToString()
        Source        = if ($_.Source) { $_.Source } else { 'built-in' }
        Parameters    = $params
        Synopsis      = $synopsis
        Description   = $description
        Examples      = $examples
        Notes         = $notes
        IsDestructive = $isDestructive
        SafetyWarning = if ($isDestructive) {
            "This function may delete, remove, or disable data. Requires explicit confirmation before execution."
        }
        else { '' }
    }
}

# ============================================================
# Output JSON
# ============================================================
$functions | ConvertTo-Json -Depth 10

# SIG # Begin signature block
# MIIfAgYJKoZIhvcNAQcCoIIe8zCCHu8CAQExDzANBglghkgBZQMEAgEFADB5Bgor
# BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG
# KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCAfflynSqtrMNjW
# IogCAOH6TzcEr75j7tVjd6cnNJftDaCCGEowggUMMIIC9KADAgECAhAR+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
# AQQBgjcCAQsxDjAMBgorBgEEAYI3AgEVMC8GCSqGSIb3DQEJBDEiBCAn5/OTgfUj
# w0RpavyLreHdeYkvXI8TjYk/1I3ntc/ZPjANBgkqhkiG9w0BAQEFAASCAgAZ0ArG
# SGfmVhztFBONLO0ETuok/sBPnuJ3pY6Ajk9tgFwPuIIr5pLUw2LnneA+RNcjt//1
# je4WbpYb/J3AuOEVJtedUuP2SSSK5sMayAfbLe2Kwswq3NxqxIlOlLBFDgvfxY1T
# VEkeJsQ/961mCxlbTa2TWIQgYuetd5zvBoKKJKu1lBgG9pc4+Z/HjDUVieSiXKkE
# R8EBplhSvHF/bKiHesa2qXvkk8NM0jDXhwtfqEYUC/OPg3X89B+KuJFcB7OrC/Wc
# AYMNTOaeyEskaPsc6QxKagFC7NCJxVy5iZZGHyP13mmYivRwaq5aRyH+o9hOMikE
# NJXaXigIYpz1OhMOgZ9AHXGY4DE8/vFkGw4Q9AsSNO4Xgz0RCjrqQ8ghm8KXdhAF
# dsbeOZG20CxqH2PS5hiyJgdEWM3ezlRzTyAJif0o72EsTv7mzY+g3V0KugJsG9c9
# 8C5PqYDZQWLjtYuho2+1GPrQ6o5dmI9tkaSo7wrlSczQ7VkJzpUWqZsJg3jiG885
# o8+rjA706ZVAElkhpIaE88wAOKeLgRlyDLrp0or8Ipug73W2TH/hrrWCUh6Facuv
# TUYHnx0osI9bEJ7beTrnGmTchpobcs6N3ejng5mqkWIPGVniXLDwuWS997np5tJZ
# USrH3eXXUGzgXWL0se+Ab66wZe0jj79x9qWe+qGCAyYwggMiBgkqhkiG9w0BCQYx
# ggMTMIIDDwIBATB9MGkxCzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5EaWdpQ2VydCwg
# SW5jLjFBMD8GA1UEAxM4RGlnaUNlcnQgVHJ1c3RlZCBHNCBUaW1lU3RhbXBpbmcg
# UlNBNDA5NiBTSEEyNTYgMjAyNSBDQTECEAqA7xhLjfEFgtHEdqeVdGgwDQYJYIZI
# AWUDBAIBBQCgaTAYBgkqhkiG9w0BCQMxCwYJKoZIhvcNAQcBMBwGCSqGSIb3DQEJ
# BTEPFw0yNjA2MTEwNjMxMDNaMC8GCSqGSIb3DQEJBDEiBCCZxEEkkb6XqCASnXkG
# tlO7UJmnRaRgSntUOZ3qk9M8rDANBgkqhkiG9w0BAQEFAASCAgAEnOe1TNaBKcAL
# iun9Zh3rQFLTDIgE2A3DZak+Jx0FzARgJvarDB6XQucEJLA2xrZkLGEOJztPtnaL
# lgeIxeXJK55o+TDbjzSe7rJweLFxl4JC64c9V6lz2HScvor3jhgQDbaT2AF+woIa
# oQ7ocfVyOHQCqCuyxH30k+DuL3UdC7iz2KORy+8tOK3Bm1/5JCm3yWIYebJ79nN1
# l3GIq3eut6LUr7zcrGOvtHNhTZZiDcYNErT8pxbxUq9TM+9liYo1qeOv4CecQsoO
# yN/QiKlUR1zQA++oxliPaeyaNFXobTrr7WKoEFv6aYjXKTRWDa0n37G0O3DwTRxN
# 36pmFYgCnHGvrX30zHswcVs1TdoeomDAlyP5H/2M9yHuwBmoJAH791B6/nWLPBI5
# 7EPrQOIKzPXakzDHqml26MC1cWx2utzrrjDk/6OgYJBPW0v/s0WY+MfoN+ucOG3f
# OKGVAtSVd+jzvjXJT1X582w3uryMNHNvaGGgH+DOtx2L7Lj0CyV8ThrhsOEfortR
# 5qmiqFjmI99a7uwKXThRWlwoeA3gmJlntnBoirAGyUX9/aetmUPVtYi0cwN2jZ3/
# pp7p1f/DsMNpIjZRhw0oPQ9pmlwfLWVGkcD+8jRoxR5+/XI4BnNRo0h8kHscjd15
# 5Avfexky+FUMH24TikxGZ/FohOrhbA==
# SIG # End signature block