Created
September 20, 2018 17:35
-
-
Save Diederikjh/2ca3c158d679481c338581c59d125e77 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# PowerShell Editor Services Bootstrapper Script | |
# ---------------------------------------------- | |
# This script contains startup logic for the PowerShell Editor Services | |
# module when launched by an editor. It handles the following tasks: | |
# | |
# - Verifying the existence of dependencies like PowerShellGet | |
# - Verifying that the expected version of the PowerShellEditorServices module is installed | |
# - Installing the PowerShellEditorServices module if confirmed by the user | |
# - Creating named pipes for the language and debug services to use (if using named pipes) | |
# - Starting the language and debug services from the PowerShellEditorServices module | |
# | |
# NOTE: If editor integration authors make modifications to this | |
# script, please consider contributing changes back to the | |
# canonical version of this script at the PowerShell Editor | |
# Services GitHub repository: | |
# | |
# https://github.com/PowerShell/PowerShellEditorServices/blob/master/module/PowerShellEditorServices/Start-EditorServices.ps1 | |
param( | |
[Parameter(Mandatory=$true)] | |
[ValidateNotNullOrEmpty()] | |
[string] | |
$HostName, | |
[Parameter(Mandatory=$true)] | |
[ValidateNotNullOrEmpty()] | |
[string] | |
$HostProfileId, | |
[Parameter(Mandatory=$true)] | |
[ValidateNotNullOrEmpty()] | |
[string] | |
$HostVersion, | |
[ValidateNotNullOrEmpty()] | |
[string] | |
$BundledModulesPath, | |
[ValidateNotNullOrEmpty()] | |
$LogPath, | |
[ValidateSet("Diagnostic", "Normal", "Verbose", "Error")] | |
$LogLevel, | |
[Parameter(Mandatory=$true)] | |
[ValidateNotNullOrEmpty()] | |
[string] | |
$SessionDetailsPath, | |
[switch] | |
$EnableConsoleRepl, | |
[switch] | |
$DebugServiceOnly, | |
[string[]] | |
$AdditionalModules, | |
[string[]] | |
$FeatureFlags, | |
[switch] | |
$WaitForDebugger, | |
[switch] | |
$ConfirmInstall, | |
[switch] | |
$Stdio, | |
[string] | |
$LanguageServicePipeName = $null, | |
[string] | |
$DebugServicePipeName = $null | |
) | |
$DEFAULT_USER_MODE = "600" | |
if ($LogLevel -eq "Diagnostic") { | |
if (!$Stdio.IsPresent) { | |
$VerbosePreference = 'Continue' | |
} | |
$scriptName = [System.IO.Path]::GetFileNameWithoutExtension($MyInvocation.MyCommand.Name) | |
$logFileName = [System.IO.Path]::GetFileName($LogPath) | |
Start-Transcript (Join-Path (Split-Path $LogPath -Parent) "$scriptName-$logFileName") -Force | Out-Null | |
} | |
function LogSection([string]$msg) { | |
Write-Verbose "`n#-- $msg $('-' * ([Math]::Max(0, 73 - $msg.Length)))" | |
} | |
function Log([string[]]$msg) { | |
$msg | Write-Verbose | |
} | |
function ExitWithError($errorString) { | |
Write-Host -ForegroundColor Red "`n`n$errorString" | |
# Sleep for a while to make sure the user has time to see and copy the | |
# error message | |
Start-Sleep -Seconds 300 | |
exit 1; | |
} | |
function WriteSessionFile($sessionInfo) { | |
$sessionInfoJson = Microsoft.PowerShell.Utility\ConvertTo-Json -InputObject $sessionInfo -Compress | |
Log "Writing session file with contents:" | |
Log $sessionInfoJson | |
$sessionInfoJson | Microsoft.PowerShell.Management\Set-Content -Force -Path "$SessionDetailsPath" -ErrorAction Stop | |
} | |
# Are we running in PowerShell 2 or earlier? | |
if ($PSVersionTable.PSVersion.Major -le 2) { | |
# No ConvertTo-Json on PSv2 and below, so write out the JSON manually | |
"{`"status`": `"failed`", `"reason`": `"unsupported`", `"powerShellVersion`": `"$($PSVersionTable.PSVersion.ToString())`"}" | | |
Microsoft.PowerShell.Management\Set-Content -Force -Path "$SessionDetailsPath" -ErrorAction Stop | |
ExitWithError "Unsupported PowerShell version $($PSVersionTable.PSVersion), language features are disabled." | |
} | |
if ($host.Runspace.LanguageMode -eq 'ConstrainedLanguage') { | |
WriteSessionFile @{ | |
"status" = "failed" | |
"reason" = "languageMode" | |
"detail" = $host.Runspace.LanguageMode.ToString() | |
} | |
ExitWithError "PowerShell is configured with an unsupported LanguageMode (ConstrainedLanguage), language features are disabled." | |
} | |
# Are we running in PowerShell 5 or later? | |
$isPS5orLater = $PSVersionTable.PSVersion.Major -ge 5 | |
# If PSReadline is present in the session, remove it so that runspace | |
# management is easier | |
if ((Microsoft.PowerShell.Core\Get-Module PSReadline).Count -gt 0) { | |
LogSection "Removing PSReadLine module" | |
Microsoft.PowerShell.Core\Remove-Module PSReadline -ErrorAction SilentlyContinue | |
} | |
# This variable will be assigned later to contain information about | |
# what happened while attempting to launch the PowerShell Editor | |
# Services host | |
$resultDetails = $null; | |
function Test-ModuleAvailable($ModuleName, $ModuleVersion) { | |
Log "Testing module availability $ModuleName $ModuleVersion" | |
$modules = Microsoft.PowerShell.Core\Get-Module -ListAvailable $moduleName | |
if ($modules -ne $null) { | |
if ($ModuleVersion -ne $null) { | |
foreach ($module in $modules) { | |
if ($module.Version.Equals($moduleVersion)) { | |
Log "$ModuleName $ModuleVersion found" | |
return $true; | |
} | |
} | |
} | |
else { | |
Log "$ModuleName $ModuleVersion found" | |
return $true; | |
} | |
} | |
Log "$ModuleName $ModuleVersion NOT found" | |
return $false; | |
} | |
function New-NamedPipeName { | |
# We try 10 times to find a valid pipe name | |
for ($i = 0; $i -lt 10; $i++) { | |
# add a guid to make the pipe unique | |
$PipeName = "PSES_$([guid]::NewGuid())" | |
if ((Test-NamedPipeName -PipeName $PipeName)) { | |
return $PipeName | |
} | |
} | |
ExitWithError "Could not find valid a pipe name." | |
} | |
function Get-NamedPipePath { | |
param( | |
[Parameter(Mandatory=$true)] | |
[ValidateNotNullOrEmpty()] | |
[string] | |
$PipeName | |
) | |
if (-not $IsLinux -and -not $IsMacOS) { | |
return "\\.\pipe\$PipeName"; | |
} | |
else { | |
# Windows uses NamedPipes where non-Windows platforms use Unix Domain Sockets. | |
# the Unix Domain Sockets live in the tmp directory and are prefixed with "CoreFxPipe_" | |
return (Join-Path -Path ([System.IO.Path]::GetTempPath()) -ChildPath "CoreFxPipe_$PipeName") | |
} | |
} | |
# Returns True if it's a valid pipe name | |
# A valid pipe name is a file that does not exist either | |
# in the temp directory (macOS & Linux) or in the pipe directory (Windows) | |
function Test-NamedPipeName { | |
param( | |
[Parameter(Mandatory=$true)] | |
[ValidateNotNullOrEmpty()] | |
[string] | |
$PipeName | |
) | |
$path = Get-NamedPipePath -PipeName $PipeName | |
return -not (Test-Path $path) | |
} | |
function Set-NamedPipeMode { | |
param( | |
[Parameter(Mandatory=$true)] | |
[ValidateNotNullOrEmpty()] | |
[string] | |
$PipeFile | |
) | |
if ($IsWindows) { | |
return | |
} | |
chmod $DEFAULT_USER_MODE $PipeFile | |
if ($IsLinux) { | |
$mode = /usr/bin/stat -c "%a" $PipeFile | |
} | |
elseif ($IsMacOS) { | |
$mode = /usr/bin/stat -f "%A" $PipeFile | |
} | |
if ($mode -ne $DEFAULT_USER_MODE) { | |
ExitWithError "Permissions to the pipe file were not set properly. Expected: $DEFAULT_USER_MODE Actual: $mode for file: $PipeFile" | |
} | |
} | |
# Add BundledModulesPath to $env:PSModulePath | |
if ($BundledModulesPath) { | |
$env:PSModulePath = $env:PSModulePath.TrimEnd([System.IO.Path]::PathSeparator) + [System.IO.Path]::PathSeparator + $BundledModulesPath | |
LogSection "Updated PSModulePath to:" | |
Log ($env:PSModulePath -split [System.IO.Path]::PathSeparator) | |
} | |
LogSection "Check required modules available" | |
# Check if PowerShellGet module is available | |
if ((Test-ModuleAvailable "PowerShellGet") -eq $false) { | |
Log "Failed to find PowerShellGet module" | |
# TODO: WRITE ERROR | |
} | |
try { | |
LogSection "Start up PowerShellEditorServices" | |
Log "Importing PowerShellEditorServices" | |
Microsoft.PowerShell.Core\Import-Module PowerShellEditorServices -ErrorAction Stop | |
# Locate available port numbers for services | |
# There could be only one service on Stdio channel | |
$languageServiceTransport = $null | |
$debugServiceTransport = $null | |
if ($Stdio.IsPresent) { | |
$languageServiceTransport = "Stdio" | |
$debugServiceTransport = "Stdio" | |
} | |
else { | |
$languageServiceTransport = "NamedPipe" | |
$debugServiceTransport = "NamedPipe" | |
if (-not $LanguageServicePipeName) { | |
$LanguageServicePipeName = New-NamedPipeName | |
} | |
else { | |
if (-not (Test-NamedPipeName -PipeName $LanguageServicePipeName)) { | |
ExitWithError "Pipe name supplied is already taken: $LanguageServicePipeName" | |
} | |
} | |
if (-not $DebugServicePipeName) { | |
$DebugServicePipeName = New-NamedPipeName | |
} | |
else { | |
if (-not (Test-NamedPipeName -PipeName $DebugServicePipeName)) { | |
ExitWithError "Pipe name supplied is already taken: $DebugServicePipeName" | |
} | |
} | |
} | |
if ($EnableConsoleRepl) { | |
Write-Host "PowerShell Integrated Console`n" | |
} | |
# Create the Editor Services host | |
Log "Invoking Start-EditorServicesHost" | |
$editorServicesHost = | |
Start-EditorServicesHost ` | |
-HostName $HostName ` | |
-HostProfileId $HostProfileId ` | |
-HostVersion $HostVersion ` | |
-LogPath $LogPath ` | |
-LogLevel $LogLevel ` | |
-AdditionalModules $AdditionalModules ` | |
-LanguageServiceNamedPipe $LanguageServicePipeName ` | |
-DebugServiceNamedPipe $DebugServicePipeName ` | |
-Stdio:$Stdio.IsPresent` | |
-BundledModulesPath $BundledModulesPath ` | |
-EnableConsoleRepl:$EnableConsoleRepl.IsPresent ` | |
-DebugServiceOnly:$DebugServiceOnly.IsPresent ` | |
-WaitForDebugger:$WaitForDebugger.IsPresent | |
# TODO: Verify that the service is started | |
Log "Start-EditorServicesHost returned $editorServicesHost" | |
$resultDetails = @{ | |
"status" = "started"; | |
"languageServiceTransport" = $languageServiceTransport; | |
"debugServiceTransport" = $debugServiceTransport; | |
}; | |
if ($LanguageServicePipeName) { | |
$resultDetails["languageServicePipeName"] = Get-NamedPipePath -PipeName $LanguageServicePipeName | |
if ($IsLinux -or $IsMacOS) { | |
Set-NamedPipeMode -PipeFile $resultDetails["languageServicePipeName"] | |
} | |
} | |
if ($DebugServicePipeName) { | |
$resultDetails["debugServicePipeName"] = Get-NamedPipePath -PipeName $DebugServicePipeName | |
if ($IsLinux -or $IsMacOS) { | |
Set-NamedPipeMode -PipeFile $resultDetails["debugServicePipeName"] | |
} | |
} | |
# Notify the client that the services have started | |
WriteSessionFile $resultDetails | |
Log "Wrote out session file" | |
} | |
catch [System.Exception] { | |
$e = $_.Exception; | |
$errorString = "" | |
Log "ERRORS caught starting up EditorServicesHost" | |
while ($e -ne $null) { | |
$errorString = $errorString + ($e.Message + "`r`n" + $e.StackTrace + "`r`n") | |
$e = $e.InnerException; | |
Log $errorString | |
} | |
ExitWithError ("An error occurred while starting PowerShell Editor Services:`r`n`r`n" + $errorString) | |
} | |
try { | |
# Wait for the host to complete execution before exiting | |
LogSection "Waiting for EditorServicesHost to complete execution" | |
$editorServicesHost.WaitForCompletion() | |
Log "EditorServicesHost has completed execution" | |
} | |
catch [System.Exception] { | |
$e = $_.Exception; | |
$errorString = "" | |
Log "ERRORS caught while waiting for EditorServicesHost to complete execution" | |
while ($e -ne $null) { | |
$errorString = $errorString + ($e.Message + "`r`n" + $e.StackTrace + "`r`n") | |
$e = $e.InnerException; | |
Log $errorString | |
} | |
} | |
# SIG # Begin signature block | |
# MIIkLwYJKoZIhvcNAQcCoIIkIDCCJBwCAQExDzANBglghkgBZQMEAgEFADB5Bgor | |
# BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG | |
# KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCBwileeMySDbqVS | |
# n6rlTA8GWCF4Qt7yFBWvlyoH+HkSXKCCDYEwggX/MIID56ADAgECAhMzAAABA14l | |
# HJkfox64AAAAAAEDMA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNVBAYTAlVTMRMwEQYD | |
# VQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNy | |
# b3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMTH01pY3Jvc29mdCBDb2RlIFNpZ25p | |
# bmcgUENBIDIwMTEwHhcNMTgwNzEyMjAwODQ4WhcNMTkwNzI2MjAwODQ4WjB0MQsw | |
# CQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9u | |
# ZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMR4wHAYDVQQDExVNaWNy | |
# b3NvZnQgQ29ycG9yYXRpb24wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB | |
# AQDRlHY25oarNv5p+UZ8i4hQy5Bwf7BVqSQdfjnnBZ8PrHuXss5zCvvUmyRcFrU5 | |
# 3Rt+M2wR/Dsm85iqXVNrqsPsE7jS789Xf8xly69NLjKxVitONAeJ/mkhvT5E+94S | |
# nYW/fHaGfXKxdpth5opkTEbOttU6jHeTd2chnLZaBl5HhvU80QnKDT3NsumhUHjR | |
# hIjiATwi/K+WCMxdmcDt66VamJL1yEBOanOv3uN0etNfRpe84mcod5mswQ4xFo8A | |
# DwH+S15UD8rEZT8K46NG2/YsAzoZvmgFFpzmfzS/p4eNZTkmyWPU78XdvSX+/Sj0 | |
# NIZ5rCrVXzCRO+QUauuxygQjAgMBAAGjggF+MIIBejAfBgNVHSUEGDAWBgorBgEE | |
# AYI3TAgBBggrBgEFBQcDAzAdBgNVHQ4EFgQUR77Ay+GmP/1l1jjyA123r3f3QP8w | |
# UAYDVR0RBEkwR6RFMEMxKTAnBgNVBAsTIE1pY3Jvc29mdCBPcGVyYXRpb25zIFB1 | |
# ZXJ0byBSaWNvMRYwFAYDVQQFEw0yMzAwMTIrNDM3OTY1MB8GA1UdIwQYMBaAFEhu | |
# ZOVQBdOCqhc3NyK1bajKdQKVMFQGA1UdHwRNMEswSaBHoEWGQ2h0dHA6Ly93d3cu | |
# bWljcm9zb2Z0LmNvbS9wa2lvcHMvY3JsL01pY0NvZFNpZ1BDQTIwMTFfMjAxMS0w | |
# Ny0wOC5jcmwwYQYIKwYBBQUHAQEEVTBTMFEGCCsGAQUFBzAChkVodHRwOi8vd3d3 | |
# Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2NlcnRzL01pY0NvZFNpZ1BDQTIwMTFfMjAx | |
# MS0wNy0wOC5jcnQwDAYDVR0TAQH/BAIwADANBgkqhkiG9w0BAQsFAAOCAgEAn/XJ | |
# Uw0/DSbsokTYDdGfY5YGSz8eXMUzo6TDbK8fwAG662XsnjMQD6esW9S9kGEX5zHn | |
# wya0rPUn00iThoj+EjWRZCLRay07qCwVlCnSN5bmNf8MzsgGFhaeJLHiOfluDnjY | |
# DBu2KWAndjQkm925l3XLATutghIWIoCJFYS7mFAgsBcmhkmvzn1FFUM0ls+BXBgs | |
# 1JPyZ6vic8g9o838Mh5gHOmwGzD7LLsHLpaEk0UoVFzNlv2g24HYtjDKQ7HzSMCy | |
# RhxdXnYqWJ/U7vL0+khMtWGLsIxB6aq4nZD0/2pCD7k+6Q7slPyNgLt44yOneFuy | |
# bR/5WcF9ttE5yXnggxxgCto9sNHtNr9FB+kbNm7lPTsFA6fUpyUSj+Z2oxOzRVpD | |
# MYLa2ISuubAfdfX2HX1RETcn6LU1hHH3V6qu+olxyZjSnlpkdr6Mw30VapHxFPTy | |
# 2TUxuNty+rR1yIibar+YRcdmstf/zpKQdeTr5obSyBvbJ8BblW9Jb1hdaSreU0v4 | |
# 6Mp79mwV+QMZDxGFqk+av6pX3WDG9XEg9FGomsrp0es0Rz11+iLsVT9qGTlrEOla | |
# P470I3gwsvKmOMs1jaqYWSRAuDpnpAdfoP7YO0kT+wzh7Qttg1DO8H8+4NkI6Iwh | |
# SkHC3uuOW+4Dwx1ubuZUNWZncnwa6lL2IsRyP64wggd6MIIFYqADAgECAgphDpDS | |
# AAAAAAADMA0GCSqGSIb3DQEBCwUAMIGIMQswCQYDVQQGEwJVUzETMBEGA1UECBMK | |
# V2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0 | |
# IENvcnBvcmF0aW9uMTIwMAYDVQQDEylNaWNyb3NvZnQgUm9vdCBDZXJ0aWZpY2F0 | |
# ZSBBdXRob3JpdHkgMjAxMTAeFw0xMTA3MDgyMDU5MDlaFw0yNjA3MDgyMTA5MDla | |
# MH4xCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdS | |
# ZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMT | |
# H01pY3Jvc29mdCBDb2RlIFNpZ25pbmcgUENBIDIwMTEwggIiMA0GCSqGSIb3DQEB | |
# AQUAA4ICDwAwggIKAoICAQCr8PpyEBwurdhuqoIQTTS68rZYIZ9CGypr6VpQqrgG | |
# OBoESbp/wwwe3TdrxhLYC/A4wpkGsMg51QEUMULTiQ15ZId+lGAkbK+eSZzpaF7S | |
# 35tTsgosw6/ZqSuuegmv15ZZymAaBelmdugyUiYSL+erCFDPs0S3XdjELgN1q2jz | |
# y23zOlyhFvRGuuA4ZKxuZDV4pqBjDy3TQJP4494HDdVceaVJKecNvqATd76UPe/7 | |
# 4ytaEB9NViiienLgEjq3SV7Y7e1DkYPZe7J7hhvZPrGMXeiJT4Qa8qEvWeSQOy2u | |
# M1jFtz7+MtOzAz2xsq+SOH7SnYAs9U5WkSE1JcM5bmR/U7qcD60ZI4TL9LoDho33 | |
# X/DQUr+MlIe8wCF0JV8YKLbMJyg4JZg5SjbPfLGSrhwjp6lm7GEfauEoSZ1fiOIl | |
# XdMhSz5SxLVXPyQD8NF6Wy/VI+NwXQ9RRnez+ADhvKwCgl/bwBWzvRvUVUvnOaEP | |
# 6SNJvBi4RHxF5MHDcnrgcuck379GmcXvwhxX24ON7E1JMKerjt/sW5+v/N2wZuLB | |
# l4F77dbtS+dJKacTKKanfWeA5opieF+yL4TXV5xcv3coKPHtbcMojyyPQDdPweGF | |
# RInECUzF1KVDL3SV9274eCBYLBNdYJWaPk8zhNqwiBfenk70lrC8RqBsmNLg1oiM | |
# CwIDAQABo4IB7TCCAekwEAYJKwYBBAGCNxUBBAMCAQAwHQYDVR0OBBYEFEhuZOVQ | |
# BdOCqhc3NyK1bajKdQKVMBkGCSsGAQQBgjcUAgQMHgoAUwB1AGIAQwBBMAsGA1Ud | |
# DwQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFHItOgIxkEO5FAVO | |
# 4eqnxzHRI4k0MFoGA1UdHwRTMFEwT6BNoEuGSWh0dHA6Ly9jcmwubWljcm9zb2Z0 | |
# LmNvbS9wa2kvY3JsL3Byb2R1Y3RzL01pY1Jvb0NlckF1dDIwMTFfMjAxMV8wM18y | |
# Mi5jcmwwXgYIKwYBBQUHAQEEUjBQME4GCCsGAQUFBzAChkJodHRwOi8vd3d3Lm1p | |
# Y3Jvc29mdC5jb20vcGtpL2NlcnRzL01pY1Jvb0NlckF1dDIwMTFfMjAxMV8wM18y | |
# Mi5jcnQwgZ8GA1UdIASBlzCBlDCBkQYJKwYBBAGCNy4DMIGDMD8GCCsGAQUFBwIB | |
# FjNodHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2RvY3MvcHJpbWFyeWNw | |
# cy5odG0wQAYIKwYBBQUHAgIwNB4yIB0ATABlAGcAYQBsAF8AcABvAGwAaQBjAHkA | |
# XwBzAHQAYQB0AGUAbQBlAG4AdAAuIB0wDQYJKoZIhvcNAQELBQADggIBAGfyhqWY | |
# 4FR5Gi7T2HRnIpsLlhHhY5KZQpZ90nkMkMFlXy4sPvjDctFtg/6+P+gKyju/R6mj | |
# 82nbY78iNaWXXWWEkH2LRlBV2AySfNIaSxzzPEKLUtCw/WvjPgcuKZvmPRul1LUd | |
# d5Q54ulkyUQ9eHoj8xN9ppB0g430yyYCRirCihC7pKkFDJvtaPpoLpWgKj8qa1hJ | |
# Yx8JaW5amJbkg/TAj/NGK978O9C9Ne9uJa7lryft0N3zDq+ZKJeYTQ49C/IIidYf | |
# wzIY4vDFLc5bnrRJOQrGCsLGra7lstnbFYhRRVg4MnEnGn+x9Cf43iw6IGmYslmJ | |
# aG5vp7d0w0AFBqYBKig+gj8TTWYLwLNN9eGPfxxvFX1Fp3blQCplo8NdUmKGwx1j | |
# NpeG39rz+PIWoZon4c2ll9DuXWNB41sHnIc+BncG0QaxdR8UvmFhtfDcxhsEvt9B | |
# xw4o7t5lL+yX9qFcltgA1qFGvVnzl6UJS0gQmYAf0AApxbGbpT9Fdx41xtKiop96 | |
# eiL6SJUfq/tHI4D1nvi/a7dLl+LrdXga7Oo3mXkYS//WsyNodeav+vyL6wuA6mk7 | |
# r/ww7QRMjt/fdW1jkT3RnVZOT7+AVyKheBEyIXrvQQqxP/uozKRdwaGIm1dxVk5I | |
# RcBCyZt2WwqASGv9eZ/BvW1taslScxMNelDNMYIWBDCCFgACAQEwgZUwfjELMAkG | |
# A1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQx | |
# HjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEoMCYGA1UEAxMfTWljcm9z | |
# b2Z0IENvZGUgU2lnbmluZyBQQ0EgMjAxMQITMwAAAQNeJRyZH6MeuAAAAAABAzAN | |
# BglghkgBZQMEAgEFAKCBrjAZBgkqhkiG9w0BCQMxDAYKKwYBBAGCNwIBBDAcBgor | |
# BgEEAYI3AgELMQ4wDAYKKwYBBAGCNwIBFTAvBgkqhkiG9w0BCQQxIgQgN0ZvyTaq | |
# fbQEBZ8PLlwPVg6mdC0WSJufOHC2R5t6mMUwQgYKKwYBBAGCNwIBDDE0MDKgFIAS | |
# AE0AaQBjAHIAbwBzAG8AZgB0oRqAGGh0dHA6Ly93d3cubWljcm9zb2Z0LmNvbTAN | |
# BgkqhkiG9w0BAQEFAASCAQC4gyENu0Ucoi3fP3bhca3TGzGHxbyoOzHon9VRQHLR | |
# b45sv955RDmbqYPIcMICE7f6Czk0pZC8g1hwD1zi+Cxx49KhBa5BDyep7gwtUfw4 | |
# lTyTfTR0juT9Z5CP4SPFvqeLILX94eLU841GE1Wk9Vmk575y094psWlfFay+SOOM | |
# lp3dKnEx5Qh8zLuRpSvT927EWWC6py3uuwZA5KH+pMoIFg31uY0wZ5vHD39GBuGf | |
# fMbdsRZiONNdBTYaVqvJm/yd8yvsgN2HKdIecJ6fvWviHC3QYiHcyrWHDLbctYAU | |
# MY3CN+1GxQ6cBq2fcIExawaCsEwGHzKp6SRdVzO3oPrroYITjjCCE4oGCisGAQQB | |
# gjcDAwExghN6MIITdgYJKoZIhvcNAQcCoIITZzCCE2MCAQMxDzANBglghkgBZQME | |
# AgEFADCCAVQGCyqGSIb3DQEJEAEEoIIBQwSCAT8wggE7AgEBBgorBgEEAYRZCgMB | |
# MDEwDQYJYIZIAWUDBAIBBQAEIKS1hr51Ek/tX5YBx3MVzAuOoSS/O5LJ9ioqsRAQ | |
# YBqBAgZbgGDe/EQYEzIwMTgwODMxMDUxMDA3LjYxOVowBwIBAYACAfSggdCkgc0w | |
# gcoxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdS | |
# ZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xJTAjBgNVBAsT | |
# HE1pY3Jvc29mdCBBbWVyaWNhIE9wZXJhdGlvbnMxJjAkBgNVBAsTHVRoYWxlcyBU | |
# U1MgRVNOOjIxMzctMzdBMC00QUFBMSUwIwYDVQQDExxNaWNyb3NvZnQgVGltZS1T | |
# dGFtcCBTZXJ2aWNloIIO+jCCBnEwggRZoAMCAQICCmEJgSoAAAAAAAIwDQYJKoZI | |
# hvcNAQELBQAwgYgxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAw | |
# DgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24x | |
# MjAwBgNVBAMTKU1pY3Jvc29mdCBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAy | |
# MDEwMB4XDTEwMDcwMTIxMzY1NVoXDTI1MDcwMTIxNDY1NVowfDELMAkGA1UEBhMC | |
# VVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNV | |
# BAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEmMCQGA1UEAxMdTWljcm9zb2Z0IFRp | |
# bWUtU3RhbXAgUENBIDIwMTAwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB | |
# AQCpHQ28dxGKOiDs/BOX9fp/aZRrdFQQ1aUKAIKF++18aEssX8XD5WHCdrc+Zitb | |
# 8BVTJwQxH0EbGpUdzgkTjnxhMFmxMEQP8WCIhFRDDNdNuDgIs0Ldk6zWczBXJoKj | |
# RQ3Q6vVHgc2/JGAyWGBG8lhHhjKEHnRhZ5FfgVSxz5NMksHEpl3RYRNuKMYa+YaA | |
# u99h/EbBJx0kZxJyGiGKr0tkiVBisV39dx898Fd1rL2KQk1AUdEPnAY+Z3/1ZsAD | |
# lkR+79BL/W7lmsqxqPJ6Kgox8NpOBpG2iAg16HgcsOmZzTznL0S6p/TcZL2kAcEg | |
# CZN4zfy8wMlEXV4WnAEFTyJNAgMBAAGjggHmMIIB4jAQBgkrBgEEAYI3FQEEAwIB | |
# ADAdBgNVHQ4EFgQU1WM6XIoxkPNDe3xGG8UzaFqFbVUwGQYJKwYBBAGCNxQCBAwe | |
# CgBTAHUAYgBDAEEwCwYDVR0PBAQDAgGGMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0j | |
# BBgwFoAU1fZWy4/oolxiaNE9lJBb186aGMQwVgYDVR0fBE8wTTBLoEmgR4ZFaHR0 | |
# cDovL2NybC5taWNyb3NvZnQuY29tL3BraS9jcmwvcHJvZHVjdHMvTWljUm9vQ2Vy | |
# QXV0XzIwMTAtMDYtMjMuY3JsMFoGCCsGAQUFBwEBBE4wTDBKBggrBgEFBQcwAoY+ | |
# aHR0cDovL3d3dy5taWNyb3NvZnQuY29tL3BraS9jZXJ0cy9NaWNSb29DZXJBdXRf | |
# MjAxMC0wNi0yMy5jcnQwgaAGA1UdIAEB/wSBlTCBkjCBjwYJKwYBBAGCNy4DMIGB | |
# MD0GCCsGAQUFBwIBFjFodHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vUEtJL2RvY3Mv | |
# Q1BTL2RlZmF1bHQuaHRtMEAGCCsGAQUFBwICMDQeMiAdAEwAZQBnAGEAbABfAFAA | |
# bwBsAGkAYwB5AF8AUwB0AGEAdABlAG0AZQBuAHQALiAdMA0GCSqGSIb3DQEBCwUA | |
# A4ICAQAH5ohRDeLG4Jg/gXEDPZ2joSFvs+umzPUxvs8F4qn++ldtGTCzwsVmyWrf | |
# 9efweL3HqJ4l4/m87WtUVwgrUYJEEvu5U4zM9GASinbMQEBBm9xcF/9c+V4XNZgk | |
# Vkt070IQyK+/f8Z/8jd9Wj8c8pl5SpFSAK84Dxf1L3mBZdmptWvkx872ynoAb0sw | |
# RCQiPM/tA6WWj1kpvLb9BOFwnzJKJ/1Vry/+tuWOM7tiX5rbV0Dp8c6ZZpCM/2pi | |
# f93FSguRJuI57BlKcWOdeyFtw5yjojz6f32WapB4pm3S4Zz5Hfw42JT0xqUKloak | |
# vZ4argRCg7i1gJsiOCC1JeVk7Pf0v35jWSUPei45V3aicaoGig+JFrphpxHLmtgO | |
# R5qAxdDNp9DvfYPw4TtxCd9ddJgiCGHasFAeb73x4QDf5zEHpJM692VHeOj4qEir | |
# 995yfmFrb3epgcunCaw5u+zGy9iCtHLNHfS4hQEegPsbiSpUObJb2sgNVZl6h3M7 | |
# COaYLeqN4DMuEin1wC9UJyH3yKxO2ii4sanblrKnQqLJzxlBTeCG+SqaoxFmMNO7 | |
# dDJL32N79ZmKLxvHIa9Zta7cRDyXUHHXodLFVeNp3lfB0d4wwP3M5k37Db9dT+md | |
# Hhk4L7zPWAUu7w2gUDXa7wknHNWzfjUeCLraNtvTX4/edIhJEjCCBPEwggPZoAMC | |
# AQICEzMAAADKCsYkwjkTpv8AAAAAAMowDQYJKoZIhvcNAQELBQAwfDELMAkGA1UE | |
# BhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAc | |
# BgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEmMCQGA1UEAxMdTWljcm9zb2Z0 | |
# IFRpbWUtU3RhbXAgUENBIDIwMTAwHhcNMTgwODIzMjAyNjE5WhcNMTkxMTIzMjAy | |
# NjE5WjCByjELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNV | |
# BAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjElMCMG | |
# A1UECxMcTWljcm9zb2Z0IEFtZXJpY2EgT3BlcmF0aW9uczEmMCQGA1UECxMdVGhh | |
# bGVzIFRTUyBFU046MjEzNy0zN0EwLTRBQUExJTAjBgNVBAMTHE1pY3Jvc29mdCBU | |
# aW1lLVN0YW1wIFNlcnZpY2UwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB | |
# AQCSuAkY8/XpD+g5nTH4DeAiYqAHeZBta9YN63SN+rgmOUi6DyLeAaiWRDoWuyyx | |
# /UmH1Mk70pRsmvertXmYSZNp7f8RgQGWwD1BHaONJVAVK5l23f4Q6o1Kyr6IfxdM | |
# lV38ECTjRUwTIlTkb5AILv0VlDZhMG19GDlJicAQDjYrnYF6BZkGGyhHYtIWERyg | |
# Z0ZmmhRKyWoTJhrMBAfYbmKR27ATFChOP1COebz98u1kqg1JDxlCqUSq8No9UHkB | |
# 5RC/fyLNH+71RJaO8JgTuXYFmiSXDp2Oz5FaVBI+ebDMrAR82X9YleaqP8iwbGym | |
# QPf577TCC6WLPsHgFAYTbN8VAgMBAAGjggEbMIIBFzAdBgNVHQ4EFgQUKOkNoaSp | |
# cMadIyV2e/vNkvWwsvQwHwYDVR0jBBgwFoAU1WM6XIoxkPNDe3xGG8UzaFqFbVUw | |
# VgYDVR0fBE8wTTBLoEmgR4ZFaHR0cDovL2NybC5taWNyb3NvZnQuY29tL3BraS9j | |
# cmwvcHJvZHVjdHMvTWljVGltU3RhUENBXzIwMTAtMDctMDEuY3JsMFoGCCsGAQUF | |
# BwEBBE4wTDBKBggrBgEFBQcwAoY+aHR0cDovL3d3dy5taWNyb3NvZnQuY29tL3Br | |
# aS9jZXJ0cy9NaWNUaW1TdGFQQ0FfMjAxMC0wNy0wMS5jcnQwDAYDVR0TAQH/BAIw | |
# ADATBgNVHSUEDDAKBggrBgEFBQcDCDANBgkqhkiG9w0BAQsFAAOCAQEARf15Dk/7 | |
# pDRCruTFsMV02+rA4RQDtNLJTYmPTkr/n2wS+ygOywjz6a8Zq8aK+H5YgigwMYBG | |
# JOp+w/XhTYvhvBa1xAmtAbbYUZEzs9mvtF57d6k4/MQ7sO8xYXFA2NFT0xkI06/W | |
# DEvP8gCu60DE/gmRRC9bidasRPE7Fa988/4W+5d8r8QvgRQ20NAuj5bjchHNtqiB | |
# t9QoL2mgKxTWuhKTdfft8SsB1tP010FiAUKDUMqyXACCkMxXWi1fJGAb/nRosKoY | |
# AqqRRd7A0A3dksnbTjacn8BKc2CABZicSfLy+qcoKHzoIPuGJay5sFOteb3ChHJn | |
# +pIhZ0lmpRzshqGCA4wwggJ0AgEBMIH6oYHQpIHNMIHKMQswCQYDVQQGEwJVUzET | |
# MBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMV | |
# TWljcm9zb2Z0IENvcnBvcmF0aW9uMSUwIwYDVQQLExxNaWNyb3NvZnQgQW1lcmlj | |
# YSBPcGVyYXRpb25zMSYwJAYDVQQLEx1UaGFsZXMgVFNTIEVTTjoyMTM3LTM3QTAt | |
# NEFBQTElMCMGA1UEAxMcTWljcm9zb2Z0IFRpbWUtU3RhbXAgU2VydmljZaIlCgEB | |
# MAkGBSsOAwIaBQADFQBbDTPvmGoKSV8bhE4v5n1EbgzsrqCBwTCBvqSBuzCBuDEL | |
# MAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1v | |
# bmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEMMAoGA1UECxMDQU9D | |
# MScwJQYDVQQLEx5uQ2lwaGVyIE5UUyBFU046MjY2NS00QzNGLUM1REUxKzApBgNV | |
# BAMTIk1pY3Jvc29mdCBUaW1lIFNvdXJjZSBNYXN0ZXIgQ2xvY2swDQYJKoZIhvcN | |
# AQEFBQACBQDfMjSEMCIYDzIwMTgwODMwMDkxNjUyWhgPMjAxODA4MzEwOTE2NTJa | |
# MHQwOgYKKwYBBAGEWQoEATEsMCowCgIFAN8yNIQCAQAwBwIBAAICL+EwBwIBAAIC | |
# GbgwCgIFAN8zhgQCAQAwNgYKKwYBBAGEWQoEAjEoMCYwDAYKKwYBBAGEWQoDAaAK | |
# MAgCAQACAxbjYKEKMAgCAQACAx6EgDANBgkqhkiG9w0BAQUFAAOCAQEAKqwVyyy3 | |
# VZExVvxNU//I/l+tZb3ssHr3lRa2/nzz5FCSyMvbkSftNIsIbc9EtbbHWN9GbqTc | |
# +eoWHRB/bBChkW4V+H5qH5K01CaV65cLranZwX03GGoPZfKZmAj1D52DrpupaDOa | |
# mMjCtI2cgSi4lehXzKakY0Gds4CPFoly84KQRFitc6HjYOMsnYfST8rpzskd2E/J | |
# 4aOkwkPqEYwXtRG+nD8Hr3rNyOSSXTpLJH5jb0iPHgkVMHzYEbkRW49BYZaRNDdj | |
# IFf2xZXbftZF8LgZS9D8FsIlWlCHYsWFvCiCoV206TBfDlxYrTvPNQT05gT/8WAc | |
# g96GOtwAjf+t5jGCAvUwggLxAgEBMIGTMHwxCzAJBgNVBAYTAlVTMRMwEQYDVQQI | |
# EwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3Nv | |
# ZnQgQ29ycG9yYXRpb24xJjAkBgNVBAMTHU1pY3Jvc29mdCBUaW1lLVN0YW1wIFBD | |
# QSAyMDEwAhMzAAAAygrGJMI5E6b/AAAAAADKMA0GCWCGSAFlAwQCAQUAoIIBMjAa | |
# BgkqhkiG9w0BCQMxDQYLKoZIhvcNAQkQAQQwLwYJKoZIhvcNAQkEMSIEIOR1YOXW | |
# BcUpgQL58k1GBjpPGnrli66pu82SH6RS6QjgMIHiBgsqhkiG9w0BCRACDDGB0jCB | |
# zzCBzDCBsQQUWw0z75hqCklfG4ROL+Z9RG4M7K4wgZgwgYCkfjB8MQswCQYDVQQG | |
# EwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwG | |
# A1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSYwJAYDVQQDEx1NaWNyb3NvZnQg | |
# VGltZS1TdGFtcCBQQ0EgMjAxMAITMwAAAMoKxiTCOROm/wAAAAAAyjAWBBQ25BIn | |
# +8+UO2ffzbIftGeQAiR16DANBgkqhkiG9w0BAQsFAASCAQBSaCBkujpGdbvf7a1K | |
# nLOzb3/GIHWuv/KvhqDraNoeqcdFpdiQG49Y6shtMTnIQur3L3UrQJRvjvOAhZOo | |
# Y788aufX2XiLlxjPAz2EUY6CvazMX28UrdIo9gxm0CmSrthwvtCTi7nYJ4ErxboZ | |
# gOZF+YJ4OWWyUe1uxRy2CO3yvx6zactDQkxlSMAEDWfxS+bNKTtH6pJpddOnE8VR | |
# OTcLfVccGxyVxDr1MsxAjjWyazTzZyFtANmj1J+R92cGVrilKR4oGlDfj0W4Ofu1 | |
# 1AVqUSaGvk//uaEL/CcYmbX93GtBJksVXKErWpQS2y/1PJDY/ndqcS3RXrDmK6pP | |
# dXQX | |
# SIG # End signature block |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment