Public/New-ECMA2ConnectorDocumentation.ps1

function New-ECMA2ConnectorDocumentation {
    <#
    .SYNOPSIS
        Generates markdown documentation for ECMA2 connectors.
 
    .DESCRIPTION
        Creates detailed markdown documentation for one or more ECMA2 connectors
        including configuration, parameters, run profiles, and operational details.
 
    .PARAMETER ConnectorName
        The name of the connector to document. Supports wildcards. If not specified, documents all connectors.
 
    .PARAMETER Path
        The file path where the markdown documentation will be saved.
        If not specified, outputs to the pipeline.
 
    .PARAMETER ConfigurationPath
        Path to the Configuration.xml file. Defaults to the standard ECMA2Host location.
 
    .PARAMETER ComputerName
        The name of the computer where the connector is hosted.
 
    .PARAMETER IncludeParameters
        Include detailed parameter information in the documentation. Default is $true.
 
    .PARAMETER IncludeSecrets
        Include decrypted secret values in the documentation. Use with caution.
        Default is $false for security.
 
    .PARAMETER InputObject
        Connector objects from Get-ECMA2Connector to document via pipeline.
 
    .EXAMPLE
        New-ECMA2ConnectorDocumentation -ConnectorName "ADConnector" -Path "C:\Docs\ADConnector.md"
        Generates markdown documentation for ADConnector.
 
    .EXAMPLE
        Get-ECMA2Connector | New-ECMA2ConnectorDocumentation -Path "C:\Docs\AllConnectors.md"
        Generates documentation for all connectors via pipeline.
 
    .EXAMPLE
        New-ECMA2ConnectorDocumentation -ConnectorName "SQL*" -IncludeSecrets
        Generates documentation for all SQL connectors including decrypted secrets (output to pipeline).
 
    .EXAMPLE
        New-ECMA2ConnectorDocumentation
        Generates documentation for all connectors and outputs to pipeline.
    #>

    [CmdletBinding(DefaultParameterSetName = 'ByName')]
    param(
        [Parameter(ParameterSetName = 'ByName')]
        [SupportsWildcards()]
        [string]$ConnectorName = '*',

        [Parameter()]
        [string]$Path,

        [Parameter(ParameterSetName = 'ByName')]
        [string]$ConfigurationPath,

        [Parameter(ParameterSetName = 'ByName')]
        [string]$ComputerName = $env:COMPUTERNAME,

        [Parameter()]
        [bool]$IncludeParameters = $true,

        [Parameter()]
        [switch]$IncludeSecrets,

        [Parameter(ParameterSetName = 'FromPipeline', ValueFromPipeline, Mandatory)]
        [PSTypeName('ECMA2Host.Connector')]
        [object[]]$InputObject
    )

    begin {
        Write-Verbose "Starting ECMA2 connector documentation generation"
        $connectors = @()
        $markdown = New-Object System.Text.StringBuilder
    }

    process {
        if ($PSCmdlet.ParameterSetName -eq 'FromPipeline') {
            $connectors += $InputObject
        }
        else {
            # Get connectors by name
            $getParams = @{
                Name = $ConnectorName
                ComputerName = $ComputerName
            }
            if ($ConfigurationPath) {
                $getParams['ConfigurationPath'] = $ConfigurationPath
            }
            
            $connectors += Get-ECMA2Connector @getParams
        }
    }

    end {
        try {
            if (-not $connectors -or $connectors.Count -eq 0) {
                Write-Warning "No connectors found to document"
                return
            }

            Write-Verbose "Generating documentation for $($connectors.Count) connector(s)"

            # Document header
            [void]$markdown.AppendLine("# ECMA2Host Connector Documentation")
            [void]$markdown.AppendLine()
            [void]$markdown.AppendLine("**Generated:** $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')")
            [void]$markdown.AppendLine("**Generated By:** $env:USERNAME")
            [void]$markdown.AppendLine("**Computer:** $env:COMPUTERNAME")
            [void]$markdown.AppendLine("**Total Connectors:** $($connectors.Count)")
            [void]$markdown.AppendLine()
            [void]$markdown.AppendLine("---")
            [void]$markdown.AppendLine()

            # Table of contents if multiple connectors
            if ($connectors.Count -gt 1) {
                [void]$markdown.AppendLine("## Table of Contents")
                [void]$markdown.AppendLine()
                foreach ($connector in $connectors) {
                    $anchor = $connector.Name -replace '\s', '-' -replace '[^a-zA-Z0-9-]', ''
                    [void]$markdown.AppendLine("- [$($connector.Name)](#$($anchor.ToLower()))")
                }
                [void]$markdown.AppendLine()
                [void]$markdown.AppendLine("---")
                [void]$markdown.AppendLine()
            }

            # Document each connector
            foreach ($connector in $connectors) {
                Write-Verbose "Documenting connector: $($connector.Name)"

                [void]$markdown.AppendLine("## $($connector.Name)")
                [void]$markdown.AppendLine()

                # Overview section
                [void]$markdown.AppendLine("### Overview")
                [void]$markdown.AppendLine()
                [void]$markdown.AppendLine("| Property | Value |")
                [void]$markdown.AppendLine("|----------|-------|")
                [void]$markdown.AppendLine("| **Name** | $($connector.Name) |")
                [void]$markdown.AppendLine("| **Description** | $($connector.Description) |")
                [void]$markdown.AppendLine("| **Library** | $($connector.LibraryName) |")
                [void]$markdown.AppendLine("| **Folder Path** | ``$($connector.ECMAFolderPath)`` |")
                [void]$markdown.AppendLine("| **Autosync Timer** | $($connector.AutosyncTimer) minutes |")
                [void]$markdown.AppendLine("| **Validated** | $($connector.Validated) |")
                [void]$markdown.AppendLine("| **Created** | $($connector.CreationDateTime) |")
                [void]$markdown.AppendLine("| **Modified** | $($connector.ModificationDateTime) |")
                [void]$markdown.AppendLine()

                # Capabilities section
                [void]$markdown.AppendLine("### Capabilities")
                [void]$markdown.AppendLine()
                [void]$markdown.AppendLine("| Capability | Supported |")
                [void]$markdown.AppendLine("|------------|-----------|")
                [void]$markdown.AppendLine("| **Export** | $($connector.IsExportSupported) |")
                [void]$markdown.AppendLine("| **Full Import** | $($connector.IsFullImportSupported) |")
                [void]$markdown.AppendLine("| **Delta Import** | $($connector.IsDeltaImportSupported) |")
                [void]$markdown.AppendLine("| **Export Only** | $($connector.IsExportOnly) |")
                [void]$markdown.AppendLine()

                # Run Profiles section
                [void]$markdown.AppendLine("### Run Profiles")
                [void]$markdown.AppendLine()
                if ($connector.RunProfiles -and $connector.RunProfiles.Count -gt 0) {
                    foreach ($profile in $connector.RunProfiles) {
                        [void]$markdown.AppendLine("- $profile")
                    }
                }
                else {
                    [void]$markdown.AppendLine("*No run profiles configured*")
                }
                [void]$markdown.AppendLine()

                # Object Types section
                [void]$markdown.AppendLine("### Object Types")
                [void]$markdown.AppendLine()
                if ($connector.ObjectTypes -and $connector.ObjectTypes.Count -gt 0) {
                    foreach ($objType in $connector.ObjectTypes) {
                        [void]$markdown.AppendLine("- ``$objType``")
                    }
                }
                else {
                    [void]$markdown.AppendLine("*No object types defined*")
                }
                [void]$markdown.AppendLine()

                # Parameters section
                if ($IncludeParameters -and $connector.Parameters -and $connector.Parameters.Count -gt 0) {
                    [void]$markdown.AppendLine("### Parameters")
                    [void]$markdown.AppendLine()
                    [void]$markdown.AppendLine("| Name | Type | Use | Value | Encrypted |")
                    [void]$markdown.AppendLine("|------|------|-----|-------|-----------|")

                    foreach ($paramName in ($connector.Parameters.Keys | Sort-Object)) {
                        $param = $connector.Parameters[$paramName]
                        
                        # Get decrypted value if requested and parameter is encrypted
                        $displayValue = $param.Value
                        if ($IncludeSecrets -and $param.Encrypted) {
                            try {
                                Write-Verbose "Attempting to decrypt parameter: $paramName"
                                $secrets = Get-ECMA2ConnectorSecret -Name $connector.Name -WarningAction SilentlyContinue -ErrorAction SilentlyContinue
                                if ($secrets -and $secrets.EncryptedParameters) {
                                    $decryptedParam = if ($secrets.EncryptedParameters -is [hashtable]) {
                                        $secrets.EncryptedParameters[$paramName]
                                    } else {
                                        $secrets.EncryptedParameters.$paramName
                                    }
                                    if ($decryptedParam) {
                                        $displayValue = "``$($decryptedParam.Value)`` ⚠️"
                                    }
                                }
                            }
                            catch {
                                Write-Verbose "Could not decrypt parameter $paramName : $_"
                            }
                        }
                        
                        # Escape special markdown characters in value
                        $displayValue = $displayValue -replace '\|', '\|' -replace '\[', '\[' -replace '\]', '\]'
                        
                        # Truncate long values
                        if ($displayValue.Length -gt 100) {
                            $displayValue = "$($displayValue.Substring(0, 97))..."
                        }

                        [void]$markdown.AppendLine("| $($param.Name) | $($param.Type) | $($param.Use) | $displayValue | $($param.Encrypted) |")
                    }
                    [void]$markdown.AppendLine()
                    
                    if ($IncludeSecrets) {
                        [void]$markdown.AppendLine("> ⚠️ **Warning:** This documentation includes decrypted secrets. Store securely.")
                        [void]$markdown.AppendLine()
                    }
                }

                # Separator between connectors
                if ($connectors.Count -gt 1 -and $connector -ne $connectors[-1]) {
                    [void]$markdown.AppendLine("---")
                    [void]$markdown.AppendLine()
                }
            }

            # Footer
            [void]$markdown.AppendLine()
            [void]$markdown.AppendLine("---")
            [void]$markdown.AppendLine()
            [void]$markdown.AppendLine("*Generated by ECMA2HostTools PowerShell Module*")

            $markdownContent = $markdown.ToString()

            # Output to file or pipeline
            if ($Path) {
                # Ensure directory exists
                $directory = Split-Path -Path $Path -Parent
                if ($directory -and -not (Test-Path $directory)) {
                    New-Item -Path $directory -ItemType Directory -Force | Out-Null
                }

                Set-Content -Path $Path -Value $markdownContent -Force
                Write-Verbose "Documentation saved to: $Path"

                # Return summary
                [PSCustomObject]@{
                    PSTypeName = 'ECMA2Host.DocumentationGenerated'
                    Path = $Path
                    ConnectorCount = $connectors.Count
                    ConnectorNames = @($connectors.Name)
                    GeneratedDate = Get-Date
                    IncludedSecrets = $IncludeSecrets
                    FileSizeKB = [Math]::Round((Get-Item $Path).Length / 1KB, 2)
                }
            }
            else {
                # Output to pipeline
                Write-Output $markdownContent
            }
        }
        catch {
            Write-Error "Failed to generate connector documentation: $_"
        }
    }
}

# SIG # Begin signature block
# MIIoYgYJKoZIhvcNAQcCoIIoUzCCKE8CAQExDzANBglghkgBZQMEAgEFADB5Bgor
# BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG
# KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCAbd8yNO6mm8IhH
# sqQxPobHLd3Mp1lySxJibyTfNoBFTKCCIV8wggWNMIIEdaADAgECAhAOmxiO+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
# twGpn1eqXijiuZQwggawMIIEmKADAgECAhAIrUCyYNKcTJ9ezam9k67ZMA0GCSqG
# SIb3DQEBDAUAMGIxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMx
# GTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xITAfBgNVBAMTGERpZ2lDZXJ0IFRy
# dXN0ZWQgUm9vdCBHNDAeFw0yMTA0MjkwMDAwMDBaFw0zNjA0MjgyMzU5NTlaMGkx
# CzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5EaWdpQ2VydCwgSW5jLjFBMD8GA1UEAxM4
# RGlnaUNlcnQgVHJ1c3RlZCBHNCBDb2RlIFNpZ25pbmcgUlNBNDA5NiBTSEEzODQg
# MjAyMSBDQTEwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDVtC9C0Cit
# eLdd1TlZG7GIQvUzjOs9gZdwxbvEhSYwn6SOaNhc9es0JAfhS0/TeEP0F9ce2vnS
# 1WcaUk8OoVf8iJnBkcyBAz5NcCRks43iCH00fUyAVxJrQ5qZ8sU7H/Lvy0daE6ZM
# swEgJfMQ04uy+wjwiuCdCcBlp/qYgEk1hz1RGeiQIXhFLqGfLOEYwhrMxe6TSXBC
# Mo/7xuoc82VokaJNTIIRSFJo3hC9FFdd6BgTZcV/sk+FLEikVoQ11vkunKoAFdE3
# /hoGlMJ8yOobMubKwvSnowMOdKWvObarYBLj6Na59zHh3K3kGKDYwSNHR7OhD26j
# q22YBoMbt2pnLdK9RBqSEIGPsDsJ18ebMlrC/2pgVItJwZPt4bRc4G/rJvmM1bL5
# OBDm6s6R9b7T+2+TYTRcvJNFKIM2KmYoX7BzzosmJQayg9Rc9hUZTO1i4F4z8ujo
# 7AqnsAMrkbI2eb73rQgedaZlzLvjSFDzd5Ea/ttQokbIYViY9XwCFjyDKK05huzU
# tw1T0PhH5nUwjewwk3YUpltLXXRhTT8SkXbev1jLchApQfDVxW0mdmgRQRNYmtwm
# KwH0iU1Z23jPgUo+QEdfyYFQc4UQIyFZYIpkVMHMIRroOBl8ZhzNeDhFMJlP/2NP
# TLuqDQhTQXxYPUez+rbsjDIJAsxsPAxWEQIDAQABo4IBWTCCAVUwEgYDVR0TAQH/
# BAgwBgEB/wIBADAdBgNVHQ4EFgQUaDfg67Y7+F8Rhvv+YXsIiGX0TkIwHwYDVR0j
# BBgwFoAU7NfjgtJxXWRM3y5nP+e6mK4cD08wDgYDVR0PAQH/BAQDAgGGMBMGA1Ud
# JQQMMAoGCCsGAQUFBwMDMHcGCCsGAQUFBwEBBGswaTAkBggrBgEFBQcwAYYYaHR0
# cDovL29jc3AuZGlnaWNlcnQuY29tMEEGCCsGAQUFBzAChjVodHRwOi8vY2FjZXJ0
# cy5kaWdpY2VydC5jb20vRGlnaUNlcnRUcnVzdGVkUm9vdEc0LmNydDBDBgNVHR8E
# PDA6MDigNqA0hjJodHRwOi8vY3JsMy5kaWdpY2VydC5jb20vRGlnaUNlcnRUcnVz
# dGVkUm9vdEc0LmNybDAcBgNVHSAEFTATMAcGBWeBDAEDMAgGBmeBDAEEATANBgkq
# hkiG9w0BAQwFAAOCAgEAOiNEPY0Idu6PvDqZ01bgAhql+Eg08yy25nRm95RysQDK
# r2wwJxMSnpBEn0v9nqN8JtU3vDpdSG2V1T9J9Ce7FoFFUP2cvbaF4HZ+N3HLIvda
# qpDP9ZNq4+sg0dVQeYiaiorBtr2hSBh+3NiAGhEZGM1hmYFW9snjdufE5BtfQ/g+
# lP92OT2e1JnPSt0o618moZVYSNUa/tcnP/2Q0XaG3RywYFzzDaju4ImhvTnhOE7a
# brs2nfvlIVNaw8rpavGiPttDuDPITzgUkpn13c5UbdldAhQfQDN8A+KVssIhdXNS
# y0bYxDQcoqVLjc1vdjcshT8azibpGL6QB7BDf5WIIIJw8MzK7/0pNVwfiThV9zeK
# iwmhywvpMRr/LhlcOXHhvpynCgbWJme3kuZOX956rEnPLqR0kq3bPKSchh/jwVYb
# KyP/j7XqiHtwa+aguv06P0WmxOgWkVKLQcBIhEuWTatEQOON8BUozu3xGFYHKi8Q
# xAwIZDwzj64ojDzLj4gLDb879M4ee47vtevLt/B3E+bnKD+sEq6lLyJsQfmCXBVm
# zGwOysWGw/YmMwwHS6DTBwJqakAwSEs0qFEgu60bhQjiWQ1tygVQK+pKHJ6l/aCn
# HwZ05/LWUpD9r4VIIflXO7ScA+2GRfS0YW6/aOImYIbqyK+p/pQd52MbOoZWeE4w
# gga0MIIEnKADAgECAhANx6xXBf8hmS5AQyIMOkmGMA0GCSqGSIb3DQEBCwUAMGIx
# CzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3
# dy5kaWdpY2VydC5jb20xITAfBgNVBAMTGERpZ2lDZXJ0IFRydXN0ZWQgUm9vdCBH
# NDAeFw0yNTA1MDcwMDAwMDBaFw0zODAxMTQyMzU5NTlaMGkxCzAJBgNVBAYTAlVT
# MRcwFQYDVQQKEw5EaWdpQ2VydCwgSW5jLjFBMD8GA1UEAxM4RGlnaUNlcnQgVHJ1
# c3RlZCBHNCBUaW1lU3RhbXBpbmcgUlNBNDA5NiBTSEEyNTYgMjAyNSBDQTEwggIi
# MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC0eDHTCphBcr48RsAcrHXbo0Zo
# dLRRF51NrY0NlLWZloMsVO1DahGPNRcybEKq+RuwOnPhof6pvF4uGjwjqNjfEvUi
# 6wuim5bap+0lgloM2zX4kftn5B1IpYzTqpyFQ/4Bt0mAxAHeHYNnQxqXmRinvuNg
# xVBdJkf77S2uPoCj7GH8BLuxBG5AvftBdsOECS1UkxBvMgEdgkFiDNYiOTx4OtiF
# cMSkqTtF2hfQz3zQSku2Ws3IfDReb6e3mmdglTcaarps0wjUjsZvkgFkriK9tUKJ
# m/s80FiocSk1VYLZlDwFt+cVFBURJg6zMUjZa/zbCclF83bRVFLeGkuAhHiGPMvS
# GmhgaTzVyhYn4p0+8y9oHRaQT/aofEnS5xLrfxnGpTXiUOeSLsJygoLPp66bkDX1
# ZlAeSpQl92QOMeRxykvq6gbylsXQskBBBnGy3tW/AMOMCZIVNSaz7BX8VtYGqLt9
# MmeOreGPRdtBx3yGOP+rx3rKWDEJlIqLXvJWnY0v5ydPpOjL6s36czwzsucuoKs7
# Yk/ehb//Wx+5kMqIMRvUBDx6z1ev+7psNOdgJMoiwOrUG2ZdSoQbU2rMkpLiQ6bG
# RinZbI4OLu9BMIFm1UUl9VnePs6BaaeEWvjJSjNm2qA+sdFUeEY0qVjPKOWug/G6
# X5uAiynM7Bu2ayBjUwIDAQABo4IBXTCCAVkwEgYDVR0TAQH/BAgwBgEB/wIBADAd
# BgNVHQ4EFgQU729TSunkBnx6yuKQVvYv1Ensy04wHwYDVR0jBBgwFoAU7NfjgtJx
# XWRM3y5nP+e6mK4cD08wDgYDVR0PAQH/BAQDAgGGMBMGA1UdJQQMMAoGCCsGAQUF
# BwMIMHcGCCsGAQUFBwEBBGswaTAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuZGln
# aWNlcnQuY29tMEEGCCsGAQUFBzAChjVodHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5j
# b20vRGlnaUNlcnRUcnVzdGVkUm9vdEc0LmNydDBDBgNVHR8EPDA6MDigNqA0hjJo
# dHRwOi8vY3JsMy5kaWdpY2VydC5jb20vRGlnaUNlcnRUcnVzdGVkUm9vdEc0LmNy
# bDAgBgNVHSAEGTAXMAgGBmeBDAEEAjALBglghkgBhv1sBwEwDQYJKoZIhvcNAQEL
# BQADggIBABfO+xaAHP4HPRF2cTC9vgvItTSmf83Qh8WIGjB/T8ObXAZz8OjuhUxj
# aaFdleMM0lBryPTQM2qEJPe36zwbSI/mS83afsl3YTj+IQhQE7jU/kXjjytJgnn0
# hvrV6hqWGd3rLAUt6vJy9lMDPjTLxLgXf9r5nWMQwr8Myb9rEVKChHyfpzee5kH0
# F8HABBgr0UdqirZ7bowe9Vj2AIMD8liyrukZ2iA/wdG2th9y1IsA0QF8dTXqvcnT
# mpfeQh35k5zOCPmSNq1UH410ANVko43+Cdmu4y81hjajV/gxdEkMx1NKU4uHQcKf
# ZxAvBAKqMVuqte69M9J6A47OvgRaPs+2ykgcGV00TYr2Lr3ty9qIijanrUR3anzE
# wlvzZiiyfTPjLbnFRsjsYg39OlV8cipDoq7+qNNjqFzeGxcytL5TTLL4ZaoBdqbh
# OhZ3ZRDUphPvSRmMThi0vw9vODRzW6AxnJll38F0cuJG7uEBYTptMSbhdhGQDpOX
# gpIUsWTjd6xpR6oaQf/DJbg3s6KCLPAlZ66RzIg9sC+NJpud/v4+7RWsWCiKi9EO
# LLHfMR2ZyJ/+xhCx9yHbxtl5TPau1j/1MIDpMPx0LckTetiSuEtQvLsNz3Qbp7wG
# WqbIiOWCnb5WqxL3/BAPvIXKUjPSxyZsq8WhbaM2tszWkPZPubdcMIIG7TCCBNWg
# AwIBAgIQCoDvGEuN8QWC0cR2p5V0aDANBgkqhkiG9w0BAQsFADBpMQswCQYDVQQG
# EwJVUzEXMBUGA1UEChMORGlnaUNlcnQsIEluYy4xQTA/BgNVBAMTOERpZ2lDZXJ0
# IFRydXN0ZWQgRzQgVGltZVN0YW1waW5nIFJTQTQwOTYgU0hBMjU2IDIwMjUgQ0Ex
# MB4XDTI1MDYwNDAwMDAwMFoXDTM2MDkwMzIzNTk1OVowYzELMAkGA1UEBhMCVVMx
# FzAVBgNVBAoTDkRpZ2lDZXJ0LCBJbmMuMTswOQYDVQQDEzJEaWdpQ2VydCBTSEEy
# NTYgUlNBNDA5NiBUaW1lc3RhbXAgUmVzcG9uZGVyIDIwMjUgMTCCAiIwDQYJKoZI
# hvcNAQEBBQADggIPADCCAgoCggIBANBGrC0Sxp7Q6q5gVrMrV7pvUf+GcAoB38o3
# zBlCMGMyqJnfFNZx+wvA69HFTBdwbHwBSOeLpvPnZ8ZN+vo8dE2/pPvOx/Vj8Tch
# TySA2R4QKpVD7dvNZh6wW2R6kSu9RJt/4QhguSssp3qome7MrxVyfQO9sMx6ZAWj
# FDYOzDi8SOhPUWlLnh00Cll8pjrUcCV3K3E0zz09ldQ//nBZZREr4h/GI6Dxb2Uo
# yrN0ijtUDVHRXdmncOOMA3CoB/iUSROUINDT98oksouTMYFOnHoRh6+86Ltc5zjP
# KHW5KqCvpSduSwhwUmotuQhcg9tw2YD3w6ySSSu+3qU8DD+nigNJFmt6LAHvH3KS
# uNLoZLc1Hf2JNMVL4Q1OpbybpMe46YceNA0LfNsnqcnpJeItK/DhKbPxTTuGoX7w
# JNdoRORVbPR1VVnDuSeHVZlc4seAO+6d2sC26/PQPdP51ho1zBp+xUIZkpSFA8vW
# doUoHLWnqWU3dCCyFG1roSrgHjSHlq8xymLnjCbSLZ49kPmk8iyyizNDIXj//cOg
# rY7rlRyTlaCCfw7aSUROwnu7zER6EaJ+AliL7ojTdS5PWPsWeupWs7NpChUk555K
# 096V1hE0yZIXe+giAwW00aHzrDchIc2bQhpp0IoKRR7YufAkprxMiXAJQ1XCmnCf
# gPf8+3mnAgMBAAGjggGVMIIBkTAMBgNVHRMBAf8EAjAAMB0GA1UdDgQWBBTkO/zy
# Me39/dfzkXFjGVBDz2GM6DAfBgNVHSMEGDAWgBTvb1NK6eQGfHrK4pBW9i/USezL
# TjAOBgNVHQ8BAf8EBAMCB4AwFgYDVR0lAQH/BAwwCgYIKwYBBQUHAwgwgZUGCCsG
# AQUFBwEBBIGIMIGFMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdpY2VydC5j
# b20wXQYIKwYBBQUHMAKGUWh0dHA6Ly9jYWNlcnRzLmRpZ2ljZXJ0LmNvbS9EaWdp
# Q2VydFRydXN0ZWRHNFRpbWVTdGFtcGluZ1JTQTQwOTZTSEEyNTYyMDI1Q0ExLmNy
# dDBfBgNVHR8EWDBWMFSgUqBQhk5odHRwOi8vY3JsMy5kaWdpY2VydC5jb20vRGln
# aUNlcnRUcnVzdGVkRzRUaW1lU3RhbXBpbmdSU0E0MDk2U0hBMjU2MjAyNUNBMS5j
# cmwwIAYDVR0gBBkwFzAIBgZngQwBBAIwCwYJYIZIAYb9bAcBMA0GCSqGSIb3DQEB
# CwUAA4ICAQBlKq3xHCcEua5gQezRCESeY0ByIfjk9iJP2zWLpQq1b4URGnwWBdEZ
# D9gBq9fNaNmFj6Eh8/YmRDfxT7C0k8FUFqNh+tshgb4O6Lgjg8K8elC4+oWCqnU/
# ML9lFfim8/9yJmZSe2F8AQ/UdKFOtj7YMTmqPO9mzskgiC3QYIUP2S3HQvHG1FDu
# +WUqW4daIqToXFE/JQ/EABgfZXLWU0ziTN6R3ygQBHMUBaB5bdrPbF6MRYs03h4o
# bEMnxYOX8VBRKe1uNnzQVTeLni2nHkX/QqvXnNb+YkDFkxUGtMTaiLR9wjxUxu2h
# ECZpqyU1d0IbX6Wq8/gVutDojBIFeRlqAcuEVT0cKsb+zJNEsuEB7O7/cuvTQasn
# M9AWcIQfVjnzrvwiCZ85EE8LUkqRhoS3Y50OHgaY7T/lwd6UArb+BOVAkg2oOvol
# /DJgddJ35XTxfUlQ+8Hggt8l2Yv7roancJIFcbojBcxlRcGG0LIhp6GvReQGgMgY
# xQbV1S3CrWqZzBt1R9xJgKf47CdxVRd/ndUlQ05oxYy2zRWVFjF7mcr4C34Mj3oc
# CVccAvlKV9jEnstrniLvUxxVZE/rptb7IRE2lskKPIJgbaP5t2nGj/ULLi49xTcB
# ZU8atufk+EMF/cWuiC7POGT75qaL6vdCvHlshtjdNXOCIUjsarfNZzCCB20wggVV
# oAMCAQICEAnI7Fw0fQcgWcyoNeinb/gwDQYJKoZIhvcNAQELBQAwaTELMAkGA1UE
# BhMCVVMxFzAVBgNVBAoTDkRpZ2lDZXJ0LCBJbmMuMUEwPwYDVQQDEzhEaWdpQ2Vy
# dCBUcnVzdGVkIEc0IENvZGUgU2lnbmluZyBSU0E0MDk2IFNIQTM4NCAyMDIxIENB
# MTAeFw0yMzAzMjkwMDAwMDBaFw0yNjA2MjIyMzU5NTlaMHUxCzAJBgNVBAYTAkFV
# MRgwFgYDVQQIEw9OZXcgU291dGggV2FsZXMxFDASBgNVBAcTC0NoZXJyeWJyb29r
# MRowGAYDVQQKExFEYXJyZW4gSiBSb2JpbnNvbjEaMBgGA1UEAxMRRGFycmVuIEog
# Um9iaW5zb24wggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDHrKfntVGe
# XaDp6S/nqZuiKuhmIqivGTXM9VwXuzO3gV8FcuLWD+QciGujTkWBLHpVViPV5jtT
# PnD0uo0TK6WW/cbVB/jaSmTvnkrYYEwLZxDtXVmgCumOwB/2VY5oDk1mVwVYm4wB
# PyUCiH2cseB5uRTh+oat27JQPkVEKaNzUMTb9gLs3JCkMG1uwKFyDbnY9HbmAog2
# LIZ//Zh884C9FaTWEaZoBGu1loHNSR9e1fkmJWn+qjFqWKFrjg8Lg5bUh9qee6gC
# Nv+Ceq1GBL57O0GfbICFHRpVK+fen6dGOI7sqclRhO0a9GvD7Qci1lLqcle2eZCj
# 6/zEY3q1wJgZ3+gHYSN5GOho89+en2ZDwOPVLgiFxYMk2U/OAKOipcPtEaie9CQ7
# eOPVJMu4XWvofIdj4lHX+610Gplee5mOufpRwJnOPlIE7lrJ6cJ07jZZG2cUZwsN
# g/lt6raNmgYQ3m3Iimc4r34gFpVn03B7QqcveoDOS/jgeOXsw6VOigB9YcEUozkV
# JVucqBU11Gz1AUX5VNztm2dMHQCXslGGh1gGsjaMhX7ina5gi7SMe9ujtOnc/SoP
# nCX/tWXSeynFL2YEdnfBdfRVeRtQlTJzs4TGUdnZyHieYdBIHDijR5d4TChXVUce
# JYVvLXK0EDeGU9hIBnyPXwXNItxl0xQNMQIDAQABo4ICAzCCAf8wHwYDVR0jBBgw
# FoAUaDfg67Y7+F8Rhvv+YXsIiGX0TkIwHQYDVR0OBBYEFAUxVql07mJzafndN3rN
# ijPSXRlIMA4GA1UdDwEB/wQEAwIHgDATBgNVHSUEDDAKBggrBgEFBQcDAzCBtQYD
# VR0fBIGtMIGqMFOgUaBPhk1odHRwOi8vY3JsMy5kaWdpY2VydC5jb20vRGlnaUNl
# cnRUcnVzdGVkRzRDb2RlU2lnbmluZ1JTQTQwOTZTSEEzODQyMDIxQ0ExLmNybDBT
# oFGgT4ZNaHR0cDovL2NybDQuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0VHJ1c3RlZEc0
# Q29kZVNpZ25pbmdSU0E0MDk2U0hBMzg0MjAyMUNBMS5jcmwwPgYDVR0gBDcwNTAz
# BgZngQwBBAEwKTAnBggrBgEFBQcCARYbaHR0cDovL3d3dy5kaWdpY2VydC5jb20v
# Q1BTMIGUBggrBgEFBQcBAQSBhzCBhDAkBggrBgEFBQcwAYYYaHR0cDovL29jc3Au
# ZGlnaWNlcnQuY29tMFwGCCsGAQUFBzAChlBodHRwOi8vY2FjZXJ0cy5kaWdpY2Vy
# dC5jb20vRGlnaUNlcnRUcnVzdGVkRzRDb2RlU2lnbmluZ1JTQTQwOTZTSEEzODQy
# MDIxQ0ExLmNydDAJBgNVHRMEAjAAMA0GCSqGSIb3DQEBCwUAA4ICAQBYQAlozzK3
# Gn8A32eZnv51K5L+MmICIud+XHXTwJv9rMBg07s0lQVRyDAafC1i5s1zwNRm8QTp
# gOC/L7w4IxKUBfSPT4eTDWIGIYNMUqQCKffygKHODkJ8JckRjzfgo2smONMcU8+P
# 4R6IVoOK5yTCLlRI5DLSpzHU26Z6lPOcO/AEJXw+/b/4FkNnS9U959fBzhI07fFU
# rq8ZBIUOSN0h/Aq/WIVL/eDm1iFGzilLeUhu5v3fstpn5CkUjpkZbi0qGCz1m8d+
# aQK7GJGj6Y3+WJeY4iT2NxkMxFP0kVVtK68AwG7SkjdIClrWcYozw27PGkFGAoox
# X43ujlhheEZ5j0kIdBX/AMsz0HMfS40P/Fu4FBC7BOiBblz+W49ouoHi8uuS0XuO
# kGZWA6v2zGs1KGUE5Y3v4bOqZDi+H9Sr+7WyWZjBDVVVESTZng0Xo7zZYh2mhhAL
# /4hdGaO6ar4+MAgghht4/7DUeVkkWJ8X+cUOK/YvYGapOMo8JPwyQltq5ijQlKMT
# SGVodhCJTEg88NwzCpNspWXYmPywIuRpmwshi7erE8/yBNcNTWMK6f8+r+CPdZQ4
# HV4Pn05IYcbeO4VpozDg92WFUhc0JoPGpdYkP/ukWCoH7MMOuLSJMvCTjmV/97LP
# 7ocSlIzycWCZDsEMFMqAGM43LvwBOwctKzGCBlkwggZVAgEBMH0waTELMAkGA1UE
# BhMCVVMxFzAVBgNVBAoTDkRpZ2lDZXJ0LCBJbmMuMUEwPwYDVQQDEzhEaWdpQ2Vy
# dCBUcnVzdGVkIEc0IENvZGUgU2lnbmluZyBSU0E0MDk2IFNIQTM4NCAyMDIxIENB
# MQIQCcjsXDR9ByBZzKg16Kdv+DANBglghkgBZQMEAgEFAKCBhDAYBgorBgEEAYI3
# AgEMMQowCKACgAChAoAAMBkGCSqGSIb3DQEJAzEMBgorBgEEAYI3AgEEMBwGCisG
# AQQBgjcCAQsxDjAMBgorBgEEAYI3AgEVMC8GCSqGSIb3DQEJBDEiBCDxOFZ0DsT/
# ZeMpNvL49rjWMn4Npnv1WlpWd/XMYR+CUDANBgkqhkiG9w0BAQEFAASCAgANGtCm
# NoPsVWFk6LjQ5SMseR5PVn3NgWaK9NsWLM1nglcnDGlP1ip4Lf3wsq2BbtAmH23/
# aLvUPibocVu9171iqlVV72H3j/pHY1G3QoOMIt2P7tSyqDiACmzsx0m8A4ixpRue
# bFmluh/08EJJy5+nUP5EquEzFhsFcckK6dLdx/vWFPml65iSIH5p4J6YBGlZV6/Z
# fDAhBR9AfDWdZoIR2arg6Xen/QGy+6rWxqa0gBgg+vNbHTnBB6M2TSH1lnMmmHy0
# GBOcD3I39F1rYrJm1GgP119vRe3VXlpxmZ4XIDVfqsvoyNS7SQWbepp4p0K7adu5
# lkKIu7RsLTPHPjGD1+OYECoSERjOuAdfduL6nbc+VZsvn+OdK4RteQ+JMblHYTAR
# TYWiD7jUN5jM5J5O2bWZjJTiQy/SzvDTKx8Hmy4drARN8vpqFODwohfkHdMADRFs
# NrY7hhu9wvl/Io0AViGsf+UGNvuKjNaZram6mxEV4QjwtnTlZN2KQ00p44paqgWy
# LozrH7YsUwFUCXbAhCjLonz6+ipsPY6rW7RXwowIsBCtWwPBAGXoRPHJcyTOBf+2
# rq/G/hmZw/ho3Ll1mEjshAot9jJxCFMupRXTSuAerxQ4bCz7EACJp8/oEmMnmKVS
# QW6icnxYTLe5RfxS+HmOujKG5BxLKuVYdug4hKGCAyYwggMiBgkqhkiG9w0BCQYx
# ggMTMIIDDwIBATB9MGkxCzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5EaWdpQ2VydCwg
# SW5jLjFBMD8GA1UEAxM4RGlnaUNlcnQgVHJ1c3RlZCBHNCBUaW1lU3RhbXBpbmcg
# UlNBNDA5NiBTSEEyNTYgMjAyNSBDQTECEAqA7xhLjfEFgtHEdqeVdGgwDQYJYIZI
# AWUDBAIBBQCgaTAYBgkqhkiG9w0BCQMxCwYJKoZIhvcNAQcBMBwGCSqGSIb3DQEJ
# BTEPFw0yNTEyMDkwMTEyNDdaMC8GCSqGSIb3DQEJBDEiBCDqfQIRFWG+nzxcpgE/
# Rnijh5vQ0fIivuKCf1jwcOyhMDANBgkqhkiG9w0BAQEFAASCAgDLvzSTj4T97DbB
# RXAay+6ZiVW12OnvsXYlVcpQyp/FJK6WzfF+3IEDHnlC0Xbi/8nxDDQUvGTUiIvt
# KWFCD/wWlkMxOK8rQXB5mckxsdWRfKIBHHCla/btwOoF0n30Lkrgn3pQqRAoAj2Z
# VuNOpVvDVmigtlQQNZacr62U0o3WUnMCZAl4up3d0osdZcT7sgDy71wClBMNuDSC
# OdPBpL5ZnTqUDq00ejTWDsA3Du/DvmpY+25Kx6EfyD5QBAx1OF3BH7XEs/wcHmi/
# 8rdY7RqOZ4rPTZcPPlj760uEfkZxkZ2ruFxZJoDzXBMv7E4zX9KAWIhTkS/+9+3p
# XV6sRXQ+zL2CEfH+WTAkyy7kKxvXhAqeaHVDrkX8NjXrN1WQEJ+Zj+dfB3oTKcqJ
# UYwOz7vh2sSHt0HHbvt2bjO29C/2Chwa0W8JPzckT55NWsdnOV/MK0yQxiWavbQw
# f1olX4SXeyTXeu3erIoJnYu3XxGKT/UNrPNEx6xschHWhmXAFFjsVnNQGr4Cu5aU
# QVtPFFWFQDIBdSN0gXWFelpt+X6LmYLeBnKru9KZ+6wdo7VFiTcEkzYXfYJZY7HZ
# kFL/8m/n+tQUwGjafIvepBSdU7C1iKh8tG+avbdG2eb/6KZBhhXw/e6HHKVj58xP
# Et9AfEg6POQq/dVdh9ZATOOEdUAjLg==
# SIG # End signature block