Internal/Helper/Format-MarkdownTableTableStyle.ps1
<#
.SYNOPSIS Formats the output as a Format-Table style markdown table. .DESCRIPTION The Format-MarkdownTableTableStyle cmdlet formats the output of a command as a Format-Table style markdown table which each property is displayed on a separate row. Markdown text will be copied to the clipboard. .PARAMETER InputObject Specifies the objects to be formatted. Enter a variable that contains the objects or type a command or expression that gets the objects. .PARAMETER HideStandardOutput Indicates that the cmdlet hides the standard Format-Table style output. .PARAMETER ShowMarkdown Indicates that the cmdlet outputs the markdown text to the console. .PARAMETER DoNotCopyToClipboard Indicates the the cmdlet does not copy the markdown text to the clipboard. .PARAMETER Property Specifies the object properties that appear in the display and the order in which they appear. Wildcards are permitted. If you omit this parameter, the properties that appear in the display depend on the object being displayed. The parameter name "Property" is optional. .EXAMPLE Get-Process notepad | Format-MarkdownTableTableStyle .EXAMPLE Get-Process notepad | fmt Name,Path .NOTES You can also refer to Format-MarkdownTableTableStyle by its built-in alias, FMT. # Copyright (c) Microsoft Corporation. # Licensed under the MIT license. See LICENSE file in the project root for full license information. # https://github.com/microsoft/FormatPowerShellToMarkdownTable #> function Format-MarkdownTableTableStyle { [CmdletBinding()] [Alias("fmt")] param ( [Parameter(Mandatory = $true, ValueFromPipeline = $true)] [object] $InputObject, [Parameter(Mandatory = $false, ValueFromPipeline = $false)] [switch] $HideStandardOutput, [Parameter(Mandatory = $false, ValueFromPipeline = $false)] [switch] $ShowMarkdown, [Parameter(Mandatory = $false, ValueFromPipeline = $false)] [switch] $DoNotCopyToClipboard, [Parameter(Mandatory = $false, Position = 0, ValueFromPipeline = $false)] [string[]] $Property = @() ) Begin { ## Internal Function function UseAllProperty([object]$InputObject) { try { if ($null -eq $InputObject) { return $true } $DataType = ($InputObject | Get-Member)[0].TypeName if ($DataType.StartsWith("Selected.")) { return $true } elseif ($DataType.StartsWith("Deserialized.")) { $DataType = $DataType.Remove(0, 13) } $FormatData = Get-FormatData -TypeName $DataType -ErrorAction SilentlyContinue if ($null -eq $FormatData) { return $true } return $false } catch { return $true } } if ($null -ne $InputObject -and $InputObject.GetType().BaseType -eq [System.Array]) { Write-Error "InputObject must not be System.Array. Don't use InputObject, but use the pipeline to pass the array object." $NeedToReturn = $true return } $LastCommandLine = (Get-PSCallStack)[1].Position.Text $Result = "" $HeadersForFormatTableStyle = New-Object System.Collections.Generic.List[string] $ContentsForFormatTableStyle = New-Object System.Collections.Generic.List[object] $TempOutputList = New-Object System.Collections.Generic.List[object] } Process { if ($NeedToReturn) { return } $CurrentObject = $null if ($_ -eq $null) { $CurrentObject = $InputObject } else { $CurrentObject = $_ } if ($CurrentObject.GetType().Name.ToLower() -eq "string") { # CurrentObject is a simple String object $Props = @("") } elseif (($Property.Length -eq 0) -or ($Property.Length -eq 1 -and $Property[0] -eq "")) { if (UseAllProperty($CurrentObject)) { $Property = @("*") $CurrentObject = $CurrentObject | Select-Object -Property $Property $Props = $CurrentObject | Get-Member -Name $Property -MemberType Property, NoteProperty } else { $DataType = ($CurrentObject | Get-Member)[0].TypeName if ($DataType.StartsWith("Deserialized.")) { $DataType = $DataType.Remove(0, 13) } $FormatData = Get-FormatData -TypeName $DataType -ErrorAction SilentlyContinue $TempPSObject = New-Object PSCustomObject $TempHeaderList = New-Object System.Collections.Generic.List[string] if ($FormatData.FormatViewDefinition.Control.Headers) { for ($i = 0; $i -lt $FormatData.FormatViewDefinition.Control.Headers.Count; $i++) { $HeaderName = $FormatData.FormatViewDefinition.Control.Headers[$i].Label if ($null -eq $HeaderName -or $HeaderName -eq "") { $HeaderName = $FormatData.FormatViewDefinition.Control.Rows.Columns[$i].DisplayEntry.Value } $TempSelectedObject = $null if ($FormatData.FormatViewDefinition.Control.Rows.Columns[$i].DisplayEntry.ValueType -eq "ScriptBlock") { $TempSelectedObject = $CurrentObject | Select-Object @{ n = $HeaderName; e = ([scriptblock]::Create($FormatData.FormatViewDefinition.Control.Rows.Columns[$i].DisplayEntry.Value)) } } else { $PropertyName = $FormatData.FormatViewDefinition.Control.Rows.Columns[$i].DisplayEntry.Value $TempSelectedObject = $CurrentObject | Select-Object @{ n = $HeaderName; e = {$_.$($PropertyName)} } } $Value = $TempSelectedObject.$($HeaderName) $TempPSObject | Add-Member -MemberType NoteProperty $HeaderName -Value $Value $TempHeaderList.Add($HeaderName) } } else { for ($i = 0; $i -lt $FormatData.FormatViewDefinition.Control.Entries.Items.Count; $i++) { $HeaderName = $FormatData.FormatViewDefinition.Control.Entries.Items[$i].DisplayEntry.Value $TempSelectedObject = $null $TempSelectedObject = $CurrentObject | Select-Object @{ n = $HeaderName; e = {$_.$($HeaderName)} } $Value = $TempSelectedObject.$($HeaderName) $TempPSObject | Add-Member -MemberType NoteProperty $HeaderName -Value $Value $TempHeaderList.Add($HeaderName) } } $CurrentObject = $TempPSObject | Select-Object -Property $TempHeaderList $Props = $CurrentObject | Get-Member -Name $TempHeaderList -MemberType Property, NoteProperty } } else { $CurrentObject = $CurrentObject | Select-Object -Property $Property -ErrorAction SilentlyContinue $Props = $CurrentObject | Get-Member -Name $Property -MemberType Property, NoteProperty } foreach ($Prop in $Props) { if ($HeadersForFormatTableStyle.Contains($Prop.Name) -eq $false) { $HeadersForFormatTableStyle.Add($Prop.Name) } } $ContentsForFormatTableStyle.Add($CurrentObject) } End { if ($NeedToReturn) { return } $HeaderRow = "|" $SeparatorRow = "|" $ContentRow = "" foreach ($Prop in $HeadersForFormatTableStyle) { $HeaderRow += "$(Invoke-EscapeMarkdown($Prop))|" $SeparatorRow += ":--|" } foreach ($Content in $ContentsForFormatTableStyle) { $TempOutput = New-Object PSCustomObject $ContentRow += "|" if ($HeadersForFormatTableStyle.Count -eq "1" -and $HeadersForFormatTableStyle[0] -eq "") { # Content is an array of simple data type, like String. $ContentRow += "$(Invoke-EscapeMarkdown($Content))|" $TempOutput = $null $TempOutput = $Content } else { foreach ($Prop in $HeadersForFormatTableStyle) { $ContentRow += "$(Invoke-EscapeMarkdown($Content.($($Prop))))|" $TempOutput | Add-Member -MemberType NoteProperty $Prop -Value $Content.($($Prop)) } } $ContentRow += "`r`n" $TempOutputList.Add($TempOutput) } $Result = $HeaderRow + "`r`n" + $SeparatorRow + "`r`n" + $ContentRow $ResultForConsole = $Result $Result = "**" + (Invoke-EscapeMarkdown($LastCommandLine)) + "**`r`n`r`n" + $Result if ($HideStandardOutput.IsPresent -eq $false) { $TempOutputList | Format-Table * -AutoSize } if ($ShowMarkdown.IsPresent) { Write-Output $ResultForConsole } if ($DoNotCopyToClipboard.IsPresent -eq $false) { Set-Clipboard $Result Write-Warning "Markdown text has been copied to the clipboard." } } } # SIG # Begin signature block # MIIoLAYJKoZIhvcNAQcCoIIoHTCCKBkCAQExDzANBglghkgBZQMEAgEFADB5Bgor # BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG # KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCCkhIWJHScqoNrn # fgrGSE69ghDPBZUPp/YT9k6Nt+aLY6CCIS8wggWNMIIEdaADAgECAhAOmxiO+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 # twGpn1eqXijiuZQwggauMIIElqADAgECAhAHNje3JFR82Ees/ShmKl5bMA0GCSqG # SIb3DQEBCwUAMGIxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMx # GTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xITAfBgNVBAMTGERpZ2lDZXJ0IFRy # dXN0ZWQgUm9vdCBHNDAeFw0yMjAzMjMwMDAwMDBaFw0zNzAzMjIyMzU5NTlaMGMx # CzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5EaWdpQ2VydCwgSW5jLjE7MDkGA1UEAxMy # RGlnaUNlcnQgVHJ1c3RlZCBHNCBSU0E0MDk2IFNIQTI1NiBUaW1lU3RhbXBpbmcg # Q0EwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDGhjUGSbPBPXJJUVXH # JQPE8pE3qZdRodbSg9GeTKJtoLDMg/la9hGhRBVCX6SI82j6ffOciQt/nR+eDzMf # UBMLJnOWbfhXqAJ9/UO0hNoR8XOxs+4rgISKIhjf69o9xBd/qxkrPkLcZ47qUT3w # 1lbU5ygt69OxtXXnHwZljZQp09nsad/ZkIdGAHvbREGJ3HxqV3rwN3mfXazL6IRk # tFLydkf3YYMZ3V+0VAshaG43IbtArF+y3kp9zvU5EmfvDqVjbOSmxR3NNg1c1eYb # qMFkdECnwHLFuk4fsbVYTXn+149zk6wsOeKlSNbwsDETqVcplicu9Yemj052FVUm # cJgmf6AaRyBD40NjgHt1biclkJg6OBGz9vae5jtb7IHeIhTZgirHkr+g3uM+onP6 # 5x9abJTyUpURK1h0QCirc0PO30qhHGs4xSnzyqqWc0Jon7ZGs506o9UD4L/wojzK # QtwYSH8UNM/STKvvmz3+DrhkKvp1KCRB7UK/BZxmSVJQ9FHzNklNiyDSLFc1eSuo # 80VgvCONWPfcYd6T/jnA+bIwpUzX6ZhKWD7TA4j+s4/TXkt2ElGTyYwMO1uKIqjB # Jgj5FBASA31fI7tk42PgpuE+9sJ0sj8eCXbsq11GdeJgo1gJASgADoRU7s7pXche # MBK9Rp6103a50g5rmQzSM7TNsQIDAQABo4IBXTCCAVkwEgYDVR0TAQH/BAgwBgEB # /wIBADAdBgNVHQ4EFgQUuhbZbU2FL3MpdpovdYxqII+eyG8wHwYDVR0jBBgwFoAU # 7NfjgtJxXWRM3y5nP+e6mK4cD08wDgYDVR0PAQH/BAQDAgGGMBMGA1UdJQQMMAoG # CCsGAQUFBwMIMHcGCCsGAQUFBwEBBGswaTAkBggrBgEFBQcwAYYYaHR0cDovL29j # c3AuZGlnaWNlcnQuY29tMEEGCCsGAQUFBzAChjVodHRwOi8vY2FjZXJ0cy5kaWdp # Y2VydC5jb20vRGlnaUNlcnRUcnVzdGVkUm9vdEc0LmNydDBDBgNVHR8EPDA6MDig # NqA0hjJodHRwOi8vY3JsMy5kaWdpY2VydC5jb20vRGlnaUNlcnRUcnVzdGVkUm9v # dEc0LmNybDAgBgNVHSAEGTAXMAgGBmeBDAEEAjALBglghkgBhv1sBwEwDQYJKoZI # hvcNAQELBQADggIBAH1ZjsCTtm+YqUQiAX5m1tghQuGwGC4QTRPPMFPOvxj7x1Bd # 4ksp+3CKDaopafxpwc8dB+k+YMjYC+VcW9dth/qEICU0MWfNthKWb8RQTGIdDAiC # qBa9qVbPFXONASIlzpVpP0d3+3J0FNf/q0+KLHqrhc1DX+1gtqpPkWaeLJ7giqzl # /Yy8ZCaHbJK9nXzQcAp876i8dU+6WvepELJd6f8oVInw1YpxdmXazPByoyP6wCeC # RK6ZJxurJB4mwbfeKuv2nrF5mYGjVoarCkXJ38SNoOeY+/umnXKvxMfBwWpx2cYT # gAnEtp/Nh4cku0+jSbl3ZpHxcpzpSwJSpzd+k1OsOx0ISQ+UzTl63f8lY5knLD0/ # a6fxZsNBzU+2QJshIUDQtxMkzdwdeDrknq3lNHGS1yZr5Dhzq6YBT70/O3itTK37 # xJV77QpfMzmHQXh6OOmc4d0j/R0o08f56PGYX/sr2H7yRp11LB4nLCbbbxV7HhmL # NriT1ObyF5lZynDwN7+YAN8gFk8n+2BnFqFmut1VwDophrCYoCvtlUG3OtUVmDG0 # YgkPCr2B2RP+v6TR81fZvAT6gt4y3wSJ8ADNXcL50CN/AAvkdgIm2fBldkKmKYcJ # RyvmfxqkhQ/8mJb2VVQrH4D6wPIOK+XW+6kvRBVK5xMOHds3OBqhK/bt1nz8MIIG # sDCCBJigAwIBAgIQCK1AsmDSnEyfXs2pvZOu2TANBgkqhkiG9w0BAQwFADBiMQsw # CQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cu # ZGlnaWNlcnQuY29tMSEwHwYDVQQDExhEaWdpQ2VydCBUcnVzdGVkIFJvb3QgRzQw # HhcNMjEwNDI5MDAwMDAwWhcNMzYwNDI4MjM1OTU5WjBpMQswCQYDVQQGEwJVUzEX # MBUGA1UEChMORGlnaUNlcnQsIEluYy4xQTA/BgNVBAMTOERpZ2lDZXJ0IFRydXN0 # ZWQgRzQgQ29kZSBTaWduaW5nIFJTQTQwOTYgU0hBMzg0IDIwMjEgQ0ExMIICIjAN # BgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA1bQvQtAorXi3XdU5WRuxiEL1M4zr # PYGXcMW7xIUmMJ+kjmjYXPXrNCQH4UtP03hD9BfXHtr50tVnGlJPDqFX/IiZwZHM # gQM+TXAkZLON4gh9NH1MgFcSa0OamfLFOx/y78tHWhOmTLMBICXzENOLsvsI8Irg # nQnAZaf6mIBJNYc9URnokCF4RS6hnyzhGMIazMXuk0lwQjKP+8bqHPNlaJGiTUyC # EUhSaN4QvRRXXegYE2XFf7JPhSxIpFaENdb5LpyqABXRN/4aBpTCfMjqGzLmysL0 # p6MDDnSlrzm2q2AS4+jWufcx4dyt5Big2MEjR0ezoQ9uo6ttmAaDG7dqZy3SvUQa # khCBj7A7CdfHmzJawv9qYFSLScGT7eG0XOBv6yb5jNWy+TgQ5urOkfW+0/tvk2E0 # XLyTRSiDNipmKF+wc86LJiUGsoPUXPYVGUztYuBeM/Lo6OwKp7ADK5GyNnm+960I # HnWmZcy740hQ83eRGv7bUKJGyGFYmPV8AhY8gyitOYbs1LcNU9D4R+Z1MI3sMJN2 # FKZbS110YU0/EpF23r9Yy3IQKUHw1cVtJnZoEUETWJrcJisB9IlNWdt4z4FKPkBH # X8mBUHOFECMhWWCKZFTBzCEa6DgZfGYczXg4RTCZT/9jT0y7qg0IU0F8WD1Hs/q2 # 7IwyCQLMbDwMVhECAwEAAaOCAVkwggFVMBIGA1UdEwEB/wQIMAYBAf8CAQAwHQYD # VR0OBBYEFGg34Ou2O/hfEYb7/mF7CIhl9E5CMB8GA1UdIwQYMBaAFOzX44LScV1k # TN8uZz/nupiuHA9PMA4GA1UdDwEB/wQEAwIBhjATBgNVHSUEDDAKBggrBgEFBQcD # AzB3BggrBgEFBQcBAQRrMGkwJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRpZ2lj # ZXJ0LmNvbTBBBggrBgEFBQcwAoY1aHR0cDovL2NhY2VydHMuZGlnaWNlcnQuY29t # L0RpZ2lDZXJ0VHJ1c3RlZFJvb3RHNC5jcnQwQwYDVR0fBDwwOjA4oDagNIYyaHR0 # cDovL2NybDMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0VHJ1c3RlZFJvb3RHNC5jcmww # HAYDVR0gBBUwEzAHBgVngQwBAzAIBgZngQwBBAEwDQYJKoZIhvcNAQEMBQADggIB # ADojRD2NCHbuj7w6mdNW4AIapfhINPMstuZ0ZveUcrEAyq9sMCcTEp6QRJ9L/Z6j # fCbVN7w6XUhtldU/SfQnuxaBRVD9nL22heB2fjdxyyL3WqqQz/WTauPrINHVUHmI # moqKwba9oUgYftzYgBoRGRjNYZmBVvbJ43bnxOQbX0P4PpT/djk9ntSZz0rdKOtf # JqGVWEjVGv7XJz/9kNF2ht0csGBc8w2o7uCJob054ThO2m67Np375SFTWsPK6Wrx # oj7bQ7gzyE84FJKZ9d3OVG3ZXQIUH0AzfAPilbLCIXVzUstG2MQ0HKKlS43Nb3Y3 # LIU/Gs4m6Ri+kAewQ3+ViCCCcPDMyu/9KTVcH4k4Vfc3iosJocsL6TEa/y4ZXDlx # 4b6cpwoG1iZnt5LmTl/eeqxJzy6kdJKt2zyknIYf48FWGysj/4+16oh7cGvmoLr9 # Oj9FpsToFpFSi0HASIRLlk2rREDjjfAVKM7t8RhWByovEMQMCGQ8M4+uKIw8y4+I # Cw2/O/TOHnuO77Xry7fwdxPm5yg/rBKupS8ibEH5glwVZsxsDsrFhsP2JjMMB0ug # 0wcCampAMEhLNKhRILutG4UI4lkNbcoFUCvqShyepf2gpx8GdOfy1lKQ/a+FSCH5 # Vzu0nAPthkX0tGFuv2jiJmCG6sivqf6UHedjGzqGVnhOMIIGvDCCBKSgAwIBAgIQ # C65mvFq6f5WHxvnpBOMzBDANBgkqhkiG9w0BAQsFADBjMQswCQYDVQQGEwJVUzEX # MBUGA1UEChMORGlnaUNlcnQsIEluYy4xOzA5BgNVBAMTMkRpZ2lDZXJ0IFRydXN0 # ZWQgRzQgUlNBNDA5NiBTSEEyNTYgVGltZVN0YW1waW5nIENBMB4XDTI0MDkyNjAw # MDAwMFoXDTM1MTEyNTIzNTk1OVowQjELMAkGA1UEBhMCVVMxETAPBgNVBAoTCERp # Z2lDZXJ0MSAwHgYDVQQDExdEaWdpQ2VydCBUaW1lc3RhbXAgMjAyNDCCAiIwDQYJ # KoZIhvcNAQEBBQADggIPADCCAgoCggIBAL5qc5/2lSGrljC6W23mWaO16P2RHxjE # iDtqmeOlwf0KMCBDEr4IxHRGd7+L660x5XltSVhhK64zi9CeC9B6lUdXM0s71EOc # Re8+CEJp+3R2O8oo76EO7o5tLuslxdr9Qq82aKcpA9O//X6QE+AcaU/byaCagLD/ # GLoUb35SfWHh43rOH3bpLEx7pZ7avVnpUVmPvkxT8c2a2yC0WMp8hMu60tZR0Cha # V76Nhnj37DEYTX9ReNZ8hIOYe4jl7/r419CvEYVIrH6sN00yx49boUuumF9i2T8U # uKGn9966fR5X6kgXj3o5WHhHVO+NBikDO0mlUh902wS/Eeh8F/UFaRp1z5SnROHw # SJ+QQRZ1fisD8UTVDSupWJNstVkiqLq+ISTdEjJKGjVfIcsgA4l9cbk8Smlzddh4 # EfvFrpVNnes4c16Jidj5XiPVdsn5n10jxmGpxoMc6iPkoaDhi6JjHd5ibfdp5uzI # Xp4P0wXkgNs+CO/CacBqU0R4k+8h6gYldp4FCMgrXdKWfM4N0u25OEAuEa3Jyidx # W48jwBqIJqImd93NRxvd1aepSeNeREXAu2xUDEW8aqzFQDYmr9ZONuc2MhTMizch # NULpUEoA6Vva7b1XCB+1rxvbKmLqfY/M/SdV6mwWTyeVy5Z/JkvMFpnQy5wR14GJ # cv6dQ4aEKOX5AgMBAAGjggGLMIIBhzAOBgNVHQ8BAf8EBAMCB4AwDAYDVR0TAQH/ # BAIwADAWBgNVHSUBAf8EDDAKBggrBgEFBQcDCDAgBgNVHSAEGTAXMAgGBmeBDAEE # AjALBglghkgBhv1sBwEwHwYDVR0jBBgwFoAUuhbZbU2FL3MpdpovdYxqII+eyG8w # HQYDVR0OBBYEFJ9XLAN3DigVkGalY17uT5IfdqBbMFoGA1UdHwRTMFEwT6BNoEuG # SWh0dHA6Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydFRydXN0ZWRHNFJTQTQw # OTZTSEEyNTZUaW1lU3RhbXBpbmdDQS5jcmwwgZAGCCsGAQUFBwEBBIGDMIGAMCQG # CCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdpY2VydC5jb20wWAYIKwYBBQUHMAKG # TGh0dHA6Ly9jYWNlcnRzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydFRydXN0ZWRHNFJT # QTQwOTZTSEEyNTZUaW1lU3RhbXBpbmdDQS5jcnQwDQYJKoZIhvcNAQELBQADggIB # AD2tHh92mVvjOIQSR9lDkfYR25tOCB3RKE/P09x7gUsmXqt40ouRl3lj+8QioVYq # 3igpwrPvBmZdrlWBb0HvqT00nFSXgmUrDKNSQqGTdpjHsPy+LaalTW0qVjvUBhcH # zBMutB6HzeledbDCzFzUy34VarPnvIWrqVogK0qM8gJhh/+qDEAIdO/KkYesLyTV # OoJ4eTq7gj9UFAL1UruJKlTnCVaM2UeUUW/8z3fvjxhN6hdT98Vr2FYlCS7Mbb4H # v5swO+aAXxWUm3WpByXtgVQxiBlTVYzqfLDbe9PpBKDBfk+rabTFDZXoUke7zPgt # d7/fvWTlCs30VAGEsshJmLbJ6ZbQ/xll/HjO9JbNVekBv2Tgem+mLptR7yIrpaid # RJXrI+UzB6vAlk/8a1u7cIqV0yef4uaZFORNekUgQHTqddmsPCEIYQP7xGxZBIhd # mm4bhYsVA6G2WgNFYagLDBzpmk9104WQzYuVNsxyoVLObhx3RugaEGru+SojW4dH # PoWrUhftNpFC5H7QEY7MhKRyrBe7ucykW7eaCuWBsBb4HOKRFVDcrZgdwaSIqMDi # CLg4D+TPVgKx2EgEdeoHNHT9l3ZDBD+XgbF+23/zBjeCtxz+dL/9NWR6P2eZRi7z # cEO1xwcdcqJsyz/JceENc2Sg8h3KeFUCS7tpFk7CrDqkMIIHdDCCBVygAwIBAgIQ # BPG5oE62GYY8FB/9PX286TANBgkqhkiG9w0BAQsFADBpMQswCQYDVQQGEwJVUzEX # MBUGA1UEChMORGlnaUNlcnQsIEluYy4xQTA/BgNVBAMTOERpZ2lDZXJ0IFRydXN0 # ZWQgRzQgQ29kZSBTaWduaW5nIFJTQTQwOTYgU0hBMzg0IDIwMjEgQ0ExMB4XDTIz # MTAwOTAwMDAwMFoXDTI2MTEyMDIzNTk1OVowfDELMAkGA1UEBhMCQ0gxEjAQBgNV # BAgTCVNvbG90aHVybjEOMAwGA1UEBxMFT2x0ZW4xFjAUBgNVBAoTDWJhc2VWSVNJ # T04gQUcxGTAXBgNVBAsTEEludGVybmFsIFNjcmlwdHMxFjAUBgNVBAMTDWJhc2VW # SVNJT04gQUcwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC59opyk0SC # GVo7wUn0nEzHJa2NgMzMro0Rz/YTL2Pd4Mqzky1INofqMJnBUijLSCFUzupCniYO # rtXFPL4sX4S8o5RntwEUAz0EX57SvtbKmrTOWgQEH//tglyeqDDN1ygVva2/U15X # CATmHNuOmn1ka2n5Y6vQ+INBPu4jtYczPsKPJ5nIF/TrCSe2fCd64rI3dcvNadsl # vAZHSS765ZnLGeL8io7oCJ/6vl90553aCKLMVWsM8lFny272h34OYAnsHwCbkqLc # SfGUTIcveg6iWKCeStmW35PIUMA4bIDZ/XBX7cyFgKeAYMiX6yNxAgEDw5sBQsxT # buIWB21aY9zk1qeJsdGRR1eBedZzMwWalMGdvAlXkIkYwPAG1JTxOdt506akXqIi # H6cpvEsQ5UX3RY+sbzqunqi7gGMfP52O5r0Y79bdHceYYKykyXnf6vzvjPH4HTVB # EDvwkMp0Q1prpb1U4gIe1nyzUIhKuPDt28jjlybCikgGK9XB4Kjk5eavV4FwoVuw # fbC0Z2g7mHXZpbvJcSbSypgxYdGw38NeAJtbkCrujW/sJI2lxJlb7AE1x/2y6t0w # vPBPq9ujcbCptLGuN4tsc6Kef1xX17ZE4DgTs8xAuXI+999xef1BYC+RNib+Axul # d6lABNy6l8TNOdKYcwnARsCo/Reptx+1yQIDAQABo4ICAzCCAf8wHwYDVR0jBBgw # FoAUaDfg67Y7+F8Rhvv+YXsIiGX0TkIwHQYDVR0OBBYEFGbzURuqIENghe4I9LYT # oJoHVFfKMD4GA1UdIAQ3MDUwMwYGZ4EMAQQBMCkwJwYIKwYBBQUHAgEWG2h0dHA6 # Ly93d3cuZGlnaWNlcnQuY29tL0NQUzAOBgNVHQ8BAf8EBAMCB4AwEwYDVR0lBAww # CgYIKwYBBQUHAwMwgbUGA1UdHwSBrTCBqjBToFGgT4ZNaHR0cDovL2NybDMuZGln # aWNlcnQuY29tL0RpZ2lDZXJ0VHJ1c3RlZEc0Q29kZVNpZ25pbmdSU0E0MDk2U0hB # Mzg0MjAyMUNBMS5jcmwwU6BRoE+GTWh0dHA6Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9E # aWdpQ2VydFRydXN0ZWRHNENvZGVTaWduaW5nUlNBNDA5NlNIQTM4NDIwMjFDQTEu # Y3JsMIGUBggrBgEFBQcBAQSBhzCBhDAkBggrBgEFBQcwAYYYaHR0cDovL29jc3Au # ZGlnaWNlcnQuY29tMFwGCCsGAQUFBzAChlBodHRwOi8vY2FjZXJ0cy5kaWdpY2Vy # dC5jb20vRGlnaUNlcnRUcnVzdGVkRzRDb2RlU2lnbmluZ1JTQTQwOTZTSEEzODQy # MDIxQ0ExLmNydDAJBgNVHRMEAjAAMA0GCSqGSIb3DQEBCwUAA4ICAQB4Nu0DwKMW # ZISOOreOAzu60c6E3nojAhXIvhG5ULE/JHBnWqD1FHMrot61HBD3r09NJd8kU0/U # lYYdGSSYpQf/KTkB1PPy9MUtZ5hBKt1jm1/bjocwXONqywZCdEx05Ssg5/7J4YNH # LuS0FkZYIjFFla1P+doiXWWCmUvHc75rmJFXp5MarbSezWZeckfKNDhig9bvtiKA # oWp4nRJz/szPE72yiqvfulEeuAKO5liyjoTFGiu/LxxcUg0sX7ZzKiJdeKKZZsoD # qDFa175nJGAZuCZiBMIOoZIftsLIgnLugeFxJTmY5q5fhvUiABXAkN9+tmlCFwOA # DLfDhRKU7zCZnrXop2+PX8Ubr/taHX/d/LF018MbHyHYcDoLnCNuYw81rHBLgK5r # swi2BVCAfHcWsotSQZlmg2iBIpfe9cCQXV7MM55zyQ54mAejXjx6wBWnL2YxZYFv # ABs6fHKIL24yzXfnFLESRqLYAWN81hsgqaYQLqXbV013HPdFEsnNuwExxZn8gce8 # PYvvTaw0OjDg3Xe8Otl9PYb5NtGDMp+raIIDc5dIzDCh/PbhFPGQOh8EpvvJIqec # ToVnB7i7c0ehQ6R+uwzLGma6Cc6kWJF/aUrRDO671bixbT7g8Q+eiQya/KaWkOV0 # 7kAiq53Sq5B927vRyZPOkdU88zP3AINHcDGCBlMwggZPAgEBMH0waTELMAkGA1UE # BhMCVVMxFzAVBgNVBAoTDkRpZ2lDZXJ0LCBJbmMuMUEwPwYDVQQDEzhEaWdpQ2Vy # dCBUcnVzdGVkIEc0IENvZGUgU2lnbmluZyBSU0E0MDk2IFNIQTM4NCAyMDIxIENB # MQIQBPG5oE62GYY8FB/9PX286TANBglghkgBZQMEAgEFAKCBhDAYBgorBgEEAYI3 # AgEMMQowCKACgAChAoAAMBkGCSqGSIb3DQEJAzEMBgorBgEEAYI3AgEEMBwGCisG # AQQBgjcCAQsxDjAMBgorBgEEAYI3AgEVMC8GCSqGSIb3DQEJBDEiBCBAp2WDi2MZ # 7TdL3VK80JBLG8QTwGe6Pwu770PA9pFS1TANBgkqhkiG9w0BAQEFAASCAgBW/IMu # dnfGzk/lj4sx7QR2vRovHBkE9qWBpVFcIg6/AHLggYBOm7HBehzvAuiuVu6g/XRM # 50J4ZCz4lxgwF52RY1JPGYxR6DfhonZ2v+fuKB/j6eN4hgHHzuIYiMmsSTw3pc+C # QTNuEPoqDN6KtoDzo++oyFNCWAdxAWPsNQsAQZx/OwBHXGzWMgsadBxnBJXs0R38 # IB5kWQIlcXSBRK09Cjs1tFGHtehH4Pkwnv6YK/7ixhSojAmGBRabofp+KKBYW1O/ # 53LXFxfXFUI+wAdCmfdB4vgbYLWo7BOAb2Ik2FCzsra7ln2nOTtNKoTIdKMDm4Zb # BCi3idadYznWAjBbMYxdwa22dtn3HSni++JKkQcGrfeIAINWLGrvrgDSw1oNWtMN # ee/NXjgPRkr5ULNb9SJc1FvUF/U4xE3o8gxMVOpBLs8mrNRIhG3B2jNgEDgZVqpm # glbAZCEcCftP3td8OegExrpl2+v4FPcbZDKYB6Is/Ntsw8lId3STn9OxCvntZ00K # gt60ZvxBUueZHqbOiFXpUizIoNpNLdrbD1BF9s1qtjy30P/Ob8j+w/ZFJj7QNwuA # Yl52TWTuYPoVDYDWb13M+J1g2pjATf6GikRxiOvYY2wdJG4Xf9doZHGlXF9G9wal # 2XZqpe5071jCHqMjYftKZQAorKeCHn37IFzGHqGCAyAwggMcBgkqhkiG9w0BCQYx # ggMNMIIDCQIBATB3MGMxCzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5EaWdpQ2VydCwg # SW5jLjE7MDkGA1UEAxMyRGlnaUNlcnQgVHJ1c3RlZCBHNCBSU0E0MDk2IFNIQTI1 # NiBUaW1lU3RhbXBpbmcgQ0ECEAuuZrxaun+Vh8b56QTjMwQwDQYJYIZIAWUDBAIB # BQCgaTAYBgkqhkiG9w0BCQMxCwYJKoZIhvcNAQcBMBwGCSqGSIb3DQEJBTEPFw0y # NTAzMjgwNDAwMDJaMC8GCSqGSIb3DQEJBDEiBCBTnzID0k02SlSY6SH5c2wfWhhZ # kyl2QMxX9L8DDDp2qTANBgkqhkiG9w0BAQEFAASCAgAxJIHb9Vvj6pWqcdlN3pAy # i+cQyoJF3afp71m7sVUQFmMNFbXnN3WN1rvx2UPPLzgA7ycakIPnxC97QpASDwO7 # mhb1G1SF3ksREzOWrqqL2kow8aGcnPvCuUY1ympNdRU6xzORM2ia/JHZa9SDNBW8 # P1QKK09V8lh2D+XID+6VqLCwqKQayAT+v7H8KduEMvMA5YeS1/GV9GIIJ2AGpZpd # SnfKYElcTfXVU2GxEJR8wqr0cZZXC52YSJCqy815jnPMbOGRGGF14H4r7714eXsh # Wlfn3GXX2rVTH9yhIluTuAkkU9SEppwlB6Jms6TXhtYbI03xtbsTfTDLMWgULa6R # KudL+qWQluRwNQ/FT1Pwf8DB9MBLatD+iPCCE+bgZqHwtmsaWnDdGFZqNj5d0prD # FO3Vnb82cIy0WdedMZZp5C7o3bpEh9NPHKXpaI5aLGig1RcEaOQag1NHWCWADhdI # +X9LOF+WRiZvXtUdv6TTgHNK7S5u7qqIzDS1F0QkqQjhNZC645sv6Nc7bm+Ct/AN # DlNgyEjmZFOMN2NbsIyCTBSzJODkRwl3xv+6w8bDkr0wyeJydrUWD9e/625yDbfs # W046CJLeOh1vP6q3Kv/H7TdvA7y4NjRCs/y7kXx+laaRvhC8JJI5xBXDX1udqOX0 # TOKviIcxNxbf5EYQ6N6hNg== # SIG # End signature block |