private/Start-DscUpdate.ps1
function Start-DscUpdate { [CmdletBinding()] param ( [Parameter(Mandatory)] [psobject]$ComputerName, [PSCredential]$Credential, [PSCredential]$PSDscRunAsCredential, [Parameter(ValueFromPipelineByPropertyName)] [Alias("Name", "KBUpdate", "Id")] [string]$HotfixId, [Alias("Path")] [string]$FilePath, [string]$RepositoryPath, [Parameter(ValueFromPipelineByPropertyName)] [Alias("UpdateId")] [string]$Guid, [Parameter(ValueFromPipelineByPropertyName)] [string]$Title, [string]$ArgumentList, [Parameter(ValueFromPipeline)] [pscustomobject[]]$InputObject, [switch]$AllNeeded, [switch]$NoMultithreading, [switch]$EnableException, [bool]$IsLocalHost, [string]$VerbosePreference ) begin { # Ignore this # function Invoke-Command2 # load up if a job if (-not (Get-Module kbupdate)) { $null = Import-Module PSSQLite 4>$null $null = Import-Module PSFramework 4>$null $null = Import-Module kbupdate 4>$null if ($PSVersionTable.PSVersion.Major -gt 5) { $null = Import-Module -UseWindowsPowerShell PSDesiredStateConfiguration -MaximumVersion 1.1 *>$null } } # No idea why this sometimes happens if ($ComputerName -is [hashtable]) { $hashtable = $ComputerName.PsObject.Copy() $null = Remove-Variable -Name ComputerName foreach ($key in $hashtable.keys) { Set-Variable -Name $key -Value $hashtable[$key] } } if ($EnableException) { $PSDefaultParameterValues["*:EnableException"] = $true } else { $PSDefaultParameterValues["*:EnableException"] = $false } if ($ComputerName.ComputerName) { $hostname = $ComputerName.ComputerName } else { $hostname = $ComputerName } if ($AllNeeded) { $InputObject = Get-KbNeededUpdate -ComputerName $ComputerName } if ($FilePath) { $InputObject += Get-ChildItem -Path $FilePath } $script:ModuleRoot = Split-Path -Path ((Get-Module -ListAvailable -Name kbupdate | Sort-Object Version -Descending).Path | Select-Object -First 1) # null out a couple things to be safe $remotefileexists = $programhome = $remotesession = $null # Method is DSC if ($PSDefaultParameterValues["Invoke-Command2:ComputerName"]) { $null = $PSDefaultParameterValues.Remove("Invoke-Command2:ComputerName") } $PSDefaultParameterValues["Invoke-Command2:ComputerName"] = $ComputerName if ($IsLocalHost) { # a lot of the file copy work will be done in the $home dir $programhome = Invoke-Command2 -ScriptBlock { $home } } else { Write-PSFMessage -Level Verbose -Message "Adding $hostname to PSDefaultParameterValues for Invoke-Command2:ComputerName" $PSDefaultParameterValues["Invoke-Command2:ComputerName"] = $ComputerName Write-PSFMessage -Level Verbose -Message "Initializing remote session to $hostname and also getting the remote home directory" $programhome = Invoke-Command2 -ScriptBlock { $home } if (-not $remotesession) { $remotesession = Get-PSSession -ComputerName $ComputerName -Verbose | Where-Object { $PsItem.Availability -eq 'Available' -and ($PsItem.Name -match 'WinRM' -or $PsItem.Name -match 'Runspace') } | Select-Object -First 1 } if (-not $remotesession) { $remotesession = Get-PSSession -ComputerName $ComputerName | Where-Object { $PsItem.Availability -eq 'Available' } | Select-Object -First 1 } if (-not $remotesession) { Stop-PSFFunction -Message "Session for $hostname can't be found or no runspaces are available. Please file an issue on the GitHub repo at https://github.com/potatoqualitee/kbupdate/issues" -Continue } } # fix for SYSTEM which doesn't have a downloads directory by default Write-PSFMessage -Level Verbose -Message "Checking for home downloads directory" Invoke-Command2 -ScriptBlock { if (-not (Test-Path -Path "$home\Downloads")) { Write-Warning "Creating Downloads directory at $home\Downloads" $null = New-Item -ItemType Directory -Force -Path "$home\Downloads" } } $hasxhotfix = Invoke-Command2 -ScriptBlock { Get-Module -ListAvailable xWindowsUpdate -ErrorAction Ignore | Where-Object Version -eq 3.0.0 } if (-not $hasxhotfix) { try { # Copy xWindowsUpdate to Program Files. The module is pretty much required to be in the PS Modules directory. $oldpref = $ProgressPreference $ProgressPreference = "SilentlyContinue" $programfiles = Invoke-Command2 -ScriptBlock { $env:ProgramFiles } if ($IsLocalHost) { Write-PSFMessage -Level Verbose -Message "Copying xWindowsUpdate to $hostname (local to $programfiles\WindowsPowerShell\Modules\xWindowsUpdate)" $null = Copy-Item -Path "$script:ModuleRoot\library\xWindowsUpdate" -Destination "$programfiles\WindowsPowerShell\Modules" -Recurse -Force } else { Write-PSFMessage -Level Verbose -Message "Copying xWindowsUpdate to $hostname (remote to $programfiles\WindowsPowerShell\Modules\xWindowsUpdate)" $null = Copy-Item -Path "$script:ModuleRoot\library\xWindowsUpdate" -Destination "$programfiles\WindowsPowerShell\Modules" -ToSession $remotesession -Recurse -Force } $ProgressPreference = $oldpref } catch { Stop-PSFFunction -Message "Couldn't auto-install xHotfix on $hostname. Please Install-Module xWindowsUpdate on $hostname to continue." -Continue } } $hasxdsc = Invoke-Command2 -ScriptBlock { Get-Module -ListAvailable xPSDesiredStateConfiguration -ErrorAction Ignore | Where-Object Version -eq 9.2.0 } if (-not $hasxdsc) { try { Write-PSFMessage -Level Verbose -Message "Adding xPSDesiredStateConfiguration to $hostname" # Copy xWindowsUpdate to Program Files. The module is pretty much required to be in the PS Modules directory. $oldpref = $ProgressPreference $ProgressPreference = "SilentlyContinue" $programfiles = Invoke-Command2 -ScriptBlock { $env:ProgramFiles } if ($IsLocalHost) { Write-PSFMessage -Level Verbose -Message "Copying xPSDesiredStateConfiguration to $hostname (local to $programfiles\WindowsPowerShell\Modules\xPSDesiredStateConfiguration)" $null = Copy-Item -Path "$script:ModuleRoot\library\xPSDesiredStateConfiguration" -Destination "$programfiles\WindowsPowerShell\Modules" -Recurse -Force } else { Write-PSFMessage -Level Verbose -Message "Copying xPSDesiredStateConfiguration to $hostname (remote)" $null = Copy-Item -Path "$script:ModuleRoot\library\xPSDesiredStateConfiguration" -Destination "$programfiles\WindowsPowerShell\Modules" -ToSession $remotesession -Recurse -Force } $ProgressPreference = $oldpref } catch { Stop-PSFFunction -Message "Couldn't auto-install newer DSC resources on $hostname. Please Install-Module xPSDesiredStateConfiguration version 9.2.0 on $hostname to continue." -Continue } } } process { if (-not $InputObject) { Write-PSFMessage -Level Verbose -Message "Nothing to install on $hostname, moving on" } foreach ($object in $InputObject) { if ($object.Link -and $RepositoryPath) { $filename = Split-Path -Path $object.Link -Leaf Write-PSFMessage -Level Verbose -Message "Adding $filename" $FilePath = Join-Path -Path $RepositoryPath -ChildPath $filename $FilePath = Join-Path -Path $RepositoryPath -ChildPath $filename Write-PSFMessage -Level Verbose -Message "Adding $($FilePath)" } if ($FilePath) { $remotefileexists = $updatefile = Invoke-Command2 -ArgumentList $FilePath -ScriptBlock { Get-ChildItem -Path $args -ErrorAction SilentlyContinue } } if (-not $remotefileexists) { if ($FilePath) { # try really hard to find it locally $updatefile = Get-ChildItem -Path $FilePath -ErrorAction SilentlyContinue if (-not $updatefile) { Write-PSFMessage -Level Verbose -Message "Update file not found, try in Downloads" $filename = Split-Path -Path $FilePath -Leaf $updatefile = Get-ChildItem -Path "$home\Downloads\$filename" -ErrorAction SilentlyContinue } } if (-not $updatefile) { Write-PSFMessage -Level Verbose -Message "Update file not found, download it for them" if ($HotfixId) { $Pattern = $HotfixId } elseif ($Guid) { $Pattern = $Guid } elseif ($object.UpdateId) { $Pattern = $object.UpdateId } elseif ($object.Id) { $Pattern = $object.Id } elseif ($object.Id) { $Pattern = $object.Id } elseif ($filename) { $number = "$filename".Split('KB') | Select-Object -Last 1 $number = $number.Split(" ") | Select-Object -First 1 $Pattern = "KB$number".Trim().Replace(")", "") } elseif ($FilePath) { $number = "$(Split-Path $FilePath -Leaf)".Split('KB') | Select-Object -Last 1 $number = $number.Split(" ") | Select-Object -First 1 $Pattern = "KB$number".Trim().Replace(")", "") } # try to automatically download it for them if (-not $object -and $Pattern) { $object = Get-KbUpdate -ComputerName $ComputerName -Pattern $Pattern | Where-Object { $PSItem.Link -and $PSItem.Title -match $Pattern } } # note to reader: if this picks the wrong one, please download the required file manually. if ($object.Link) { if ($object.Link -match 'x64') { $file = $object | Where-Object Link -match 'x64' | Select-Object -ExpandProperty Link -Last 1 | Split-Path -Leaf } else { $file = Split-Path $object.Link -Leaf | Select-Object -Last 1 } } else { Stop-PSFFunction -Message "Could not find file on $hostname and couldn't find it online. Try piping in exactly what you'd like from Get-KbUpdate." -Continue } if ((Test-Path -Path "$home\Downloads\$file")) { $updatefile = Get-ChildItem -Path "$home\Downloads\$file" } else { Write-PSFMessage -Level Verbose -Message "File not detected on $hostname, downloading now to $home\Downloads and copying to remote computer" $warnatbottom = $true # fix for SYSTEM which doesn't have a downloads directory by default Write-PSFMessage -Level Verbose -Message "Checking for home downloads directory" if (-not (Test-Path -Path "$home\Downloads")) { Write-PSFMessage -Level Warning -Message "Creating Downloads directory at $home\Downloads" $null = New-Item -ItemType Directory -Force -Path "$home\Downloads" } $updatefile = $object | Select-Object -First 1 | Save-KbUpdate -Path "$home\Downloads" } } if (-not $FilePath) { $FilePath = "$programhome\Downloads\$(Split-Path -Leaf $updateFile)" } if ($IsLocalHost) { $remotefile = $updatefile } else { $remotefile = "$programhome\Downloads\$(Split-Path -Leaf $updateFile)" } # copy over to destination server unless # it's local or it's on a network share if (-not "$($FilePath)".StartsWith("\\") -and -not $IsLocalHost) { Write-PSFMessage -Level Verbose -Message "Update is not located on a file server and not local, copying over the remote server" try { $exists = Invoke-Command2 -ComputerName $ComputerName -ArgumentList $remotefile -ScriptBlock { Get-ChildItem -Path $args -ErrorAction SilentlyContinue } if (-not $exists) { $null = Copy-Item -Path $updatefile -Destination $remotefile -ToSession $remotesession -ErrorAction Stop $deleteremotefile = $remotefile } } catch { $null = Invoke-Command2 -ComputerName $ComputerName -ArgumentList $remotefile -ScriptBlock { Remove-Item $args -Force -ErrorAction SilentlyContinue } try { Write-PSFMessage -Level Warning -Message "Copy failed, trying again" $null = Copy-Item -Path $updatefile -Destination $remotefile -ToSession $remotesession -ErrorAction Stop $deleteremotefile = $remotefile } catch { $null = Invoke-Command2 -ComputerName $ComputerName -ArgumentList $remotefile -ScriptBlock { Remove-Item $args -Force -ErrorAction SilentlyContinue } Stop-PSFFunction -Message "Could not copy $updatefile to $remotefile" -ErrorRecord $PSItem -Continue } } } } # if user doesnt add kb, try to find it for them from the provided filename if (-not $HotfixId) { $HotfixId = $FilePath.ToUpper() -split "\-" | Where-Object { $psitem.Startswith("KB") } } # i probably need to fix some logic but until then, check a few things if ($IsLocalHost) { if ($updatefile) { $FilePath = $updatefile } else { $updatefile = Get-ChildItem -Path $FilePath } if (-not $Title) { Write-PSFMessage -Level Verbose -Message "Trying to get Title from $($updatefile.FullName)" $Title = $updatefile.VersionInfo.ProductName } } elseif ($remotefile) { $FilePath = $remotefile } if ("$FilePath".EndsWith("exe")) { Write-PSFMessage -Level Verbose -Message "It's an exe" if (-not $ArgumentList -and $FilePath -match "sql") { $ArgumentList = "/action=patch /AllInstances /quiet /IAcceptSQLServerLicenseTerms" } else { # Setting a default argumentlist that hopefully works for most things? $ArgumentList = "/install /quiet /notrestart" } if (-not $Guid) { if ($object) { if ($object.UpdateId) { $Guid = $object.UpdateId } else { $Guid = $object.Guid } $Title = $object.Title } else { try { $hotfixid = $guid = $null Write-PSFMessage -Level Verbose -Message "Trying to get Title from $($updatefile.FullName)" $updatefile = Get-ChildItem -Path $updatefile.FullName -ErrorAction SilentlyContinue $Title = $updatefile.VersionInfo.ProductName Write-PSFMessage -Level Verbose -Message "Trying to get GUID from $($updatefile.FullName)" <# The reason you want to find the GUID is to save time, mostly, I guess? It saves time because it won't even attempt the install if there are GUID matches in the registry. If you pass a fake but compliant GUID, it attempts the install and fails, no big deal. Overall, it just seems like a good idea to get a GUID if it's required. #> <# It's better to just read from memory but I can't get this to work $cab = New-Object Microsoft.Deployment.Compression.Cab.Cabinfo "C:\path\path.exe" $file = New-Object Microsoft.Deployment.Compression.Cab.CabFileInfo($cab, "0") $content = $file.OpenRead() #> $cab = New-Object Microsoft.Deployment.Compression.Cab.Cabinfo $updatefile.FullName $files = $cab.GetFiles("*") $index = $files | Where-Object Name -eq 0 if (-not $index) { $index = $files | Where-Object Name -match "none.xml| ParameterInfo.xml" } $temp = Get-PSFPath -Name Temp $indexfilename = $index.Name $xmlfile = Join-Path -Path $temp -ChildPath "$($updatefile.BaseName).xml" $null = $cab.UnpackFile($indexfilename, $xmlfile) if ((Test-Path -Path $xmlfile)) { $xml = [xml](Get-Content -Path $xmlfile) $tempguid = $xml.BurnManifest.Registration.Id } if (-not $tempguid -and $xml.MsiPatch.PatchGUID) { $tempguid = $xml.MsiPatch.PatchGUID } if (-not $tempguid -and $xml.Setup.Items.Patches.MSP.PatchCode) { $tempguid = $xml.Setup.Items.Patches.MSP.PatchCode } Get-ChildItem -Path $xmlfile -ErrorAction SilentlyContinue | Remove-Item -Confirm:$false -ErrorAction SilentlyContinue # if we can't find the guid, use one that we know # is valid but not associated with any hotfix if (-not $tempguid) { $tempguid = "DAADB00F-DAAD-B00F-B00F-DAADB00FB00F" } $guid = ([guid]$tempguid).Guid } catch { $guid = "DAADB00F-DAAD-B00F-B00F-DAADB00FB00F" } Write-PSFMessage -Level Verbose -Message "GUID is $guid" } } # this takes care of things like SQL Server updates $hotfix = @{ Name = 'xPackage' ModuleName = @{ ModuleName = "xPSDesiredStateConfiguration" ModuleVersion = "9.2.0" } Property = @{ Ensure = 'Present' ProductId = $Guid Name = $Title Path = $FilePath Arguments = $ArgumentList ReturnCode = 0, 3010 } } } elseif ("$FilePath".EndsWith("cab")) { Write-PSFMessage -Level Verbose -Message "It's a cab file" $basename = Split-Path -Path $FilePath -Leaf $logfile = Join-Path -Path $env:windir -ChildPath ($basename + ".log") $hotfix = @{ Name = 'xWindowsPackageCab' ModuleName = @{ ModuleName = "xPSDesiredStateConfiguration" ModuleVersion = "9.2.0" } Property = @{ Ensure = 'Present' Name = $basename SourcePath = $FilePath # adding a directory will add other msus in the dir LogPath = $logfile } } } else { Write-PSFMessage -Level Verbose -Message "It's a WSU file" # this takes care of WSU files $hotfix = @{ Name = 'xHotFix' ModuleName = @{ ModuleName = "xWindowsUpdate" ModuleVersion = "3.0.0" } Property = @{ Ensure = 'Present' Id = $HotfixId Path = $FilePath } } if ($PSDscRunAsCredential) { $hotfix.Property.PSDscRunAsCredential = $PSDscRunAsCredential } } try { $parms = @{ ArgumentList = $hotfix, $VerbosePreference, $FileName EnableException = $true WarningAction = "SilentlyContinue" WarningVariable = "dscwarnings" } $null = Invoke-Command2 @parms -ScriptBlock { param ( $Hotfix, $VerbosePreference, $ManualFileName ) if ($PSVersionTable.PSVersion.Major -gt 5) { Import-Module -UseWindowsPowerShell PSDesiredStateConfiguration -MaximumVersion 1.1 *>$null } else { Import-Module PSDesiredStateConfiguration 4>$null } Import-Module xPSDesiredStateConfiguration -RequiredVersion 9.2.0 4>$null Import-Module xWindowsUpdate -RequiredVersion 3.0.0 4>$null $PSDefaultParameterValues.Remove("Invoke-WebRequest:ErrorAction") $PSDefaultParameterValues['*:ErrorAction'] = 'SilentlyContinue' $ErrorActionPreference = "Stop" $oldpref = $ProgressPreference $ProgressPreference = "SilentlyContinue" if (-not (Get-Command Invoke-DscResource)) { throw "Invoke-DscResource not found on $env:ComputerName" } $null = Import-Module xWindowsUpdate -Force 4>$null $hotfixpath = $hotfix.property.path if (-not $hotfixpath) { $hotfixpath = $hotfix.property.sourcepath } $hotfixnameid = $hotfix.property.name if (-not $hotfixnameid) { $hotfixnameid = $hotfix.property.id } Write-Verbose -Message "Installing $hotfixnameid from $hotfixpath" try { $ProgressPreference = "SilentlyContinue" if (-not (Invoke-DscResource @hotfix -Method Test 4>$null)) { $msgs = Invoke-DscResource @hotfix -Method Set -ErrorAction Stop 4>&1 if ($msgs) { foreach ($msg in $msgs) { # too many extra spaces, baw while ("$msg" -match " ") { $msg = "$msg" -replace " ", " " } $msg | Write-Verbose } } } $ProgressPreference = $oldpref } catch { $message = "$_".TrimStart().TrimEnd().Trim() # Unsure how to figure out params, try another way if ($message -match "The return code 1 was not expected.") { try { Write-Verbose -Message "Retrying install with /quit parameter" $hotfix.Property.Arguments = "/quiet" $msgs = Invoke-DscResource @hotfix -Method Set -ErrorAction Stop 4>&1 if ($msgs) { write-warning HELLO foreach ($msg in $msgs) { # too many extra spaces, baw while ("$msg" -match " ") { $msg = "$msg" -replace " ", " " } $msg | Write-Verbose } } } catch { $message = "$_".TrimStart().TrimEnd().Trim() } } switch ($message) { # some things can be ignored { $message -match "Serialized XML is nested too deeply" -or $message -match "Name does not match package details" } { $null = 1 } { $message -match "2359302" } { throw "Error 2359302: update is already installed on $env:ComputerName" } { $message -match "could not be started" } { throw "The install coult not initiate. The $($hotfix.Property.Path) on $env:ComputerName may be corrupt or only partially downloaded. Delete it and try again." } { $message -match "2042429437" } { throw "Error -2042429437. Configuration is likely not correct. The requested features may not be installed or features are already at a higher patch level." } { $message -match "2068709375" } { throw "Error -2068709375. The exit code suggests that something is corrupt. See if this tutorial helps: http://www.sqlcoffee.com/Tips0026.htm" } { $message -match "2067919934" } { throw "Error -2067919934 You likely need to reboot $env:ComputerName." } { $message -match "2147942402" } { throw "System can't find the file specified for some reason." } default { throw $message } } } } if ($dscwarnings) { foreach ($warning in $dscwarnings) { # too many extra spaces, baw while ("$warning" -match " ") { $warning = "$warning" -replace " ", " " } Write-PSFMessage -Level Warning -Message $warning } } if ($deleteremotefile) { Write-PSFMessage -Level Verbose -Message "Deleting $deleteremotefile" $null = Invoke-Command2 -ComputerName $ComputerName -ArgumentList $deleteremotefile -ScriptBlock { Get-ChildItem -ErrorAction SilentlyContinue $args | Remove-Item -Force -ErrorAction SilentlyContinue -Confirm:$false } } Write-PSFMessage -Level Verbose -Message "Finished installing, checking status" $exists = Get-KbInstalledSoftware -ComputerName $ComputerName -Pattern $hotfix.property.id -IncludeHidden if ($exists.Summary -match "restart") { $status = "This update requires a restart" } else { $status = "Install successful" } if ($HotfixId) { $id = $HotfixId } else { $id = $guid } if ($id -eq "DAADB00F-DAAD-B00F-B00F-DAADB00FB00F") { $id = $null } if ($object.Title) { $filetitle = $object.Title } else { $filetitle = $updatefile.VersionInfo.ProductName } if ($message) { $status = "sucks" } [pscustomobject]@{ ComputerName = $hostname Title = $filetitle ID = $id Status = $status FileName = $updatefile.Name } } catch { if ("$PSItem" -match "Serialized XML is nested too deeply") { Write-PSFMessage -Level Verbose -Message "Serialized XML is nested too deeply. Forcing output." $exists = Get-KbInstalledSoftware -ComputerName $ComputerName -HotfixId $hotfix.property.id if ($exists.Summary -match "restart") { $status = "This update requires a restart" } else { $status = "Install successful" } if ($HotfixId) { $id = $HotfixId } else { $id = $guid } if ($id -eq "DAADB00F-DAAD-B00F-B00F-DAADB00FB00F") { $id = $null } if ($object.Title) { $filetitle = $object.Title } else { $filetitle = $updatefile.VersionInfo.ProductName } [pscustomobject]@{ ComputerName = $hostname Title = $filetitle ID = $id Status = $Status FileName = $updatefile.Name } } else { Stop-PSFFunction -Message "Failure on $hostname" -ErrorRecord $PSitem -Continue -EnableException:$EnableException } } } if ($warnatbottom) { Write-PSFMessage -Level Output -Message "Downloaded files may still exist on your local drive and other servers as well, in the Downloads directory." Write-PSFMessage -Level Output -Message "If you ran this as SYSTEM, the downloads will be in windows\system32\config\systemprofile." } } } # SIG # Begin signature block # MIIjYAYJKoZIhvcNAQcCoIIjUTCCI00CAQExDzANBglghkgBZQMEAgEFADB5Bgor # BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG # KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCBL9bpD/Uyzvyko # oj4YvRj5BGFtsdCVmQeQ3/TlvilAEaCCHVkwggUaMIIEAqADAgECAhADBbuGIbCh # Y1+/3q4SBOdtMA0GCSqGSIb3DQEBCwUAMHIxCzAJBgNVBAYTAlVTMRUwEwYDVQQK # EwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xMTAvBgNV # BAMTKERpZ2lDZXJ0IFNIQTIgQXNzdXJlZCBJRCBDb2RlIFNpZ25pbmcgQ0EwHhcN # MjAwNTEyMDAwMDAwWhcNMjMwNjA4MTIwMDAwWjBXMQswCQYDVQQGEwJVUzERMA8G # A1UECBMIVmlyZ2luaWExDzANBgNVBAcTBlZpZW5uYTERMA8GA1UEChMIZGJhdG9v # bHMxETAPBgNVBAMTCGRiYXRvb2xzMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB # CgKCAQEAvL9je6vjv74IAbaY5rXqHxaNeNJO9yV0ObDg+kC844Io2vrHKGD8U5hU # iJp6rY32RVprnAFrA4jFVa6P+sho7F5iSVAO6A+QZTHQCn7oquOefGATo43NAadz # W2OWRro3QprMPZah0QFYpej9WaQL9w/08lVaugIw7CWPsa0S/YjHPGKQ+bYgI/kr # EUrk+asD7lvNwckR6pGieWAyf0fNmSoevQBTV6Cd8QiUfj+/qWvLW3UoEX9ucOGX # 2D8vSJxL7JyEVWTHg447hr6q9PzGq+91CO/c9DWFvNMjf+1c5a71fEZ54h1mNom/ # XoWZYoKeWhKnVdv1xVT1eEimibPEfQIDAQABo4IBxTCCAcEwHwYDVR0jBBgwFoAU # WsS5eyoKo6XqcQPAYPkt9mV1DlgwHQYDVR0OBBYEFPDAoPu2A4BDTvsJ193ferHL # 454iMA4GA1UdDwEB/wQEAwIHgDATBgNVHSUEDDAKBggrBgEFBQcDAzB3BgNVHR8E # cDBuMDWgM6Axhi9odHRwOi8vY3JsMy5kaWdpY2VydC5jb20vc2hhMi1hc3N1cmVk # LWNzLWcxLmNybDA1oDOgMYYvaHR0cDovL2NybDQuZGlnaWNlcnQuY29tL3NoYTIt # YXNzdXJlZC1jcy1nMS5jcmwwTAYDVR0gBEUwQzA3BglghkgBhv1sAwEwKjAoBggr # BgEFBQcCARYcaHR0cHM6Ly93d3cuZGlnaWNlcnQuY29tL0NQUzAIBgZngQwBBAEw # gYQGCCsGAQUFBwEBBHgwdjAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuZGlnaWNl # cnQuY29tME4GCCsGAQUFBzAChkJodHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5jb20v # RGlnaUNlcnRTSEEyQXNzdXJlZElEQ29kZVNpZ25pbmdDQS5jcnQwDAYDVR0TAQH/ # BAIwADANBgkqhkiG9w0BAQsFAAOCAQEAj835cJUMH9Y2pBKspjznNJwcYmOxeBcH # Ji+yK0y4bm+j44OGWH4gu/QJM+WjZajvkydJKoJZH5zrHI3ykM8w8HGbYS1WZfN4 # oMwi51jKPGZPw9neGS2PXrBcKjzb7rlQ6x74Iex+gyf8z1ZuRDitLJY09FEOh0BM # LaLh+UvJ66ghmfIyjP/g3iZZvqwgBhn+01fObqrAJ+SagxJ/21xNQJchtUOWIlxR # kuUn9KkuDYrMO70a2ekHODcAbcuHAGI8wzw4saK1iPPhVTlFijHS+7VfIt/d/18p # MLHHArLQQqe1Z0mTfuL4M4xCUKpebkH8rI3Fva62/6osaXLD0ymERzCCBTAwggQY # oAMCAQICEAQJGBtf1btmdVNDtW+VUAgwDQYJKoZIhvcNAQELBQAwZTELMAkGA1UE # BhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3LmRpZ2lj # ZXJ0LmNvbTEkMCIGA1UEAxMbRGlnaUNlcnQgQXNzdXJlZCBJRCBSb290IENBMB4X # DTEzMTAyMjEyMDAwMFoXDTI4MTAyMjEyMDAwMFowcjELMAkGA1UEBhMCVVMxFTAT # BgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTEx # MC8GA1UEAxMoRGlnaUNlcnQgU0hBMiBBc3N1cmVkIElEIENvZGUgU2lnbmluZyBD # QTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAPjTsxx/DhGvZ3cH0wsx # SRnP0PtFmbE620T1f+Wondsy13Hqdp0FLreP+pJDwKX5idQ3Gde2qvCchqXYJawO # eSg6funRZ9PG+yknx9N7I5TkkSOWkHeC+aGEI2YSVDNQdLEoJrskacLCUvIUZ4qJ # RdQtoaPpiCwgla4cSocI3wz14k1gGL6qxLKucDFmM3E+rHCiq85/6XzLkqHlOzEc # z+ryCuRXu0q16XTmK/5sy350OTYNkO/ktU6kqepqCquE86xnTrXE94zRICUj6whk # PlKWwfIPEvTFjg/BougsUfdzvL2FsWKDc0GCB+Q4i2pzINAPZHM8np+mM6n9Gd8l # k9ECAwEAAaOCAc0wggHJMBIGA1UdEwEB/wQIMAYBAf8CAQAwDgYDVR0PAQH/BAQD # AgGGMBMGA1UdJQQMMAoGCCsGAQUFBwMDMHkGCCsGAQUFBwEBBG0wazAkBggrBgEF # BQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQuY29tMEMGCCsGAQUFBzAChjdodHRw # Oi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vRGlnaUNlcnRBc3N1cmVkSURSb290Q0Eu # Y3J0MIGBBgNVHR8EejB4MDqgOKA2hjRodHRwOi8vY3JsNC5kaWdpY2VydC5jb20v # RGlnaUNlcnRBc3N1cmVkSURSb290Q0EuY3JsMDqgOKA2hjRodHRwOi8vY3JsMy5k # aWdpY2VydC5jb20vRGlnaUNlcnRBc3N1cmVkSURSb290Q0EuY3JsME8GA1UdIARI # MEYwOAYKYIZIAYb9bAACBDAqMCgGCCsGAQUFBwIBFhxodHRwczovL3d3dy5kaWdp # Y2VydC5jb20vQ1BTMAoGCGCGSAGG/WwDMB0GA1UdDgQWBBRaxLl7KgqjpepxA8Bg # +S32ZXUOWDAfBgNVHSMEGDAWgBRF66Kv9JLLgjEtUYunpyGd823IDzANBgkqhkiG # 9w0BAQsFAAOCAQEAPuwNWiSz8yLRFcgsfCUpdqgdXRwtOhrE7zBh134LYP3DPQ/E # r4v97yrfIFU3sOH20ZJ1D1G0bqWOWuJeJIFOEKTuP3GOYw4TS63XX0R58zYUBor3 # nEZOXP+QsRsHDpEV+7qvtVHCjSSuJMbHJyqhKSgaOnEoAjwukaPAJRHinBRHoXpo # aK+bp1wgXNlxsQyPu6j4xRJon89Ay0BEpRPw5mQMJQhCMrI2iiQC/i9yfhzXSUWW # 6Fkd6fp0ZGuy62ZD2rOwjNXpDd32ASDOmTFjPQgaGLOBm0/GkxAG/AeB+ova+YJJ # 92JuoVP6EpQYhS6SkepobEQysmah5xikmmRR7zCCBY0wggR1oAMCAQICEA6bGI75 # 0C3n79tQ4ghAGFowDQYJKoZIhvcNAQEMBQAwZTELMAkGA1UEBhMCVVMxFTATBgNV # BAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTEkMCIG # A1UEAxMbRGlnaUNlcnQgQXNzdXJlZCBJRCBSb290IENBMB4XDTIyMDgwMTAwMDAw # MFoXDTMxMTEwOTIzNTk1OVowYjELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lD # ZXJ0IEluYzEZMBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTEhMB8GA1UEAxMYRGln # aUNlcnQgVHJ1c3RlZCBSb290IEc0MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC # CgKCAgEAv+aQc2jeu+RdSjwwIjBpM+zCpyUuySE98orYWcLhKac9WKt2ms2uexuE # DcQwH/MbpDgW61bGl20dq7J58soR0uRf1gU8Ug9SH8aeFaV+vp+pVxZZVXKvaJNw # wrK6dZlqczKU0RBEEC7fgvMHhOZ0O21x4i0MG+4g1ckgHWMpLc7sXk7Ik/ghYZs0 # 6wXGXuxbGrzryc/NrDRAX7F6Zu53yEioZldXn1RYjgwrt0+nMNlW7sp7XeOtyU9e # 5TXnMcvak17cjo+A2raRmECQecN4x7axxLVqGDgDEI3Y1DekLgV9iPWCPhCRcKtV # gkEy19sEcypukQF8IUzUvK4bA3VdeGbZOjFEmjNAvwjXWkmkwuapoGfdpCe8oU85 # tRFYF/ckXEaPZPfBaYh2mHY9WV1CdoeJl2l6SPDgohIbZpp0yt5LHucOY67m1O+S # kjqePdwA5EUlibaaRBkrfsCUtNJhbesz2cXfSwQAzH0clcOP9yGyshG3u3/y1Yxw # LEFgqrFjGESVGnZifvaAsPvoZKYz0YkH4b235kOkGLimdwHhD5QMIR2yVCkliWzl # DlJRR3S+Jqy2QXXeeqxfjT/JvNNBERJb5RBQ6zHFynIWIgnffEx1P2PsIV/EIFFr # b7GrhotPwtZFX50g/KEexcCPorF+CiaZ9eRpL5gdLfXZqbId5RsCAwEAAaOCATow # ggE2MA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFOzX44LScV1kTN8uZz/nupiu # HA9PMB8GA1UdIwQYMBaAFEXroq/0ksuCMS1Ri6enIZ3zbcgPMA4GA1UdDwEB/wQE # AwIBhjB5BggrBgEFBQcBAQRtMGswJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRp # Z2ljZXJ0LmNvbTBDBggrBgEFBQcwAoY3aHR0cDovL2NhY2VydHMuZGlnaWNlcnQu # Y29tL0RpZ2lDZXJ0QXNzdXJlZElEUm9vdENBLmNydDBFBgNVHR8EPjA8MDqgOKA2 # hjRodHRwOi8vY3JsMy5kaWdpY2VydC5jb20vRGlnaUNlcnRBc3N1cmVkSURSb290 # Q0EuY3JsMBEGA1UdIAQKMAgwBgYEVR0gADANBgkqhkiG9w0BAQwFAAOCAQEAcKC/ # Q1xV5zhfoKN0Gz22Ftf3v1cHvZqsoYcs7IVeqRq7IviHGmlUIu2kiHdtvRoU9BNK # ei8ttzjv9P+Aufih9/Jy3iS8UgPITtAq3votVs/59PesMHqai7Je1M/RQ0SbQyHr # lnKhSLSZy51PpwYDE3cnRNTnf+hZqPC/Lwum6fI0POz3A8eHqNJMQBk1RmppVLC4 # oVaO7KTVPeix3P0c2PR3WlxUjG/voVA9/HYJaISfb8rbII01YBwCA8sgsKxYoA5A # Y8WYIsGyWfVVa88nq2x2zm8jLfR+cWojayL/ErhULSd+2DrZ8LaHlv1b0VysGMNN # n3O3AamfV6peKOK5lDCCBq4wggSWoAMCAQICEAc2N7ckVHzYR6z9KGYqXlswDQYJ # KoZIhvcNAQELBQAwYjELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IElu # YzEZMBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTEhMB8GA1UEAxMYRGlnaUNlcnQg # VHJ1c3RlZCBSb290IEc0MB4XDTIyMDMyMzAwMDAwMFoXDTM3MDMyMjIzNTk1OVow # YzELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDkRpZ2lDZXJ0LCBJbmMuMTswOQYDVQQD # EzJEaWdpQ2VydCBUcnVzdGVkIEc0IFJTQTQwOTYgU0hBMjU2IFRpbWVTdGFtcGlu # ZyBDQTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMaGNQZJs8E9cklR # VcclA8TykTepl1Gh1tKD0Z5Mom2gsMyD+Vr2EaFEFUJfpIjzaPp985yJC3+dH54P # Mx9QEwsmc5Zt+FeoAn39Q7SE2hHxc7Gz7iuAhIoiGN/r2j3EF3+rGSs+QtxnjupR # PfDWVtTnKC3r07G1decfBmWNlCnT2exp39mQh0YAe9tEQYncfGpXevA3eZ9drMvo # hGS0UvJ2R/dhgxndX7RUCyFobjchu0CsX7LeSn3O9TkSZ+8OpWNs5KbFHc02DVzV # 5huowWR0QKfAcsW6Th+xtVhNef7Xj3OTrCw54qVI1vCwMROpVymWJy71h6aPTnYV # VSZwmCZ/oBpHIEPjQ2OAe3VuJyWQmDo4EbP29p7mO1vsgd4iFNmCKseSv6De4z6i # c/rnH1pslPJSlRErWHRAKKtzQ87fSqEcazjFKfPKqpZzQmiftkaznTqj1QPgv/Ci # PMpC3BhIfxQ0z9JMq++bPf4OuGQq+nUoJEHtQr8FnGZJUlD0UfM2SU2LINIsVzV5 # K6jzRWC8I41Y99xh3pP+OcD5sjClTNfpmEpYPtMDiP6zj9NeS3YSUZPJjAw7W4oi # qMEmCPkUEBIDfV8ju2TjY+Cm4T72wnSyPx4JduyrXUZ14mCjWAkBKAAOhFTuzuld # yF4wEr1GnrXTdrnSDmuZDNIztM2xAgMBAAGjggFdMIIBWTASBgNVHRMBAf8ECDAG # AQH/AgEAMB0GA1UdDgQWBBS6FtltTYUvcyl2mi91jGogj57IbzAfBgNVHSMEGDAW # gBTs1+OC0nFdZEzfLmc/57qYrhwPTzAOBgNVHQ8BAf8EBAMCAYYwEwYDVR0lBAww # CgYIKwYBBQUHAwgwdwYIKwYBBQUHAQEEazBpMCQGCCsGAQUFBzABhhhodHRwOi8v # b2NzcC5kaWdpY2VydC5jb20wQQYIKwYBBQUHMAKGNWh0dHA6Ly9jYWNlcnRzLmRp # Z2ljZXJ0LmNvbS9EaWdpQ2VydFRydXN0ZWRSb290RzQuY3J0MEMGA1UdHwQ8MDow # OKA2oDSGMmh0dHA6Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydFRydXN0ZWRS # b290RzQuY3JsMCAGA1UdIAQZMBcwCAYGZ4EMAQQCMAsGCWCGSAGG/WwHATANBgkq # hkiG9w0BAQsFAAOCAgEAfVmOwJO2b5ipRCIBfmbW2CFC4bAYLhBNE88wU86/GPvH # UF3iSyn7cIoNqilp/GnBzx0H6T5gyNgL5Vxb122H+oQgJTQxZ822EpZvxFBMYh0M # CIKoFr2pVs8Vc40BIiXOlWk/R3f7cnQU1/+rT4osequFzUNf7WC2qk+RZp4snuCK # rOX9jLxkJodskr2dfNBwCnzvqLx1T7pa96kQsl3p/yhUifDVinF2ZdrM8HKjI/rA # J4JErpknG6skHibBt94q6/aesXmZgaNWhqsKRcnfxI2g55j7+6adcq/Ex8HBanHZ # xhOACcS2n82HhyS7T6NJuXdmkfFynOlLAlKnN36TU6w7HQhJD5TNOXrd/yVjmScs # PT9rp/Fmw0HNT7ZAmyEhQNC3EyTN3B14OuSereU0cZLXJmvkOHOrpgFPvT87eK1M # rfvElXvtCl8zOYdBeHo46Zzh3SP9HSjTx/no8Zhf+yvYfvJGnXUsHicsJttvFXse # GYs2uJPU5vIXmVnKcPA3v5gA3yAWTyf7YGcWoWa63VXAOimGsJigK+2VQbc61RWY # MbRiCQ8KvYHZE/6/pNHzV9m8BPqC3jLfBInwAM1dwvnQI38AC+R2AibZ8GV2QqYp # hwlHK+Z/GqSFD/yYlvZVVCsfgPrA8g4r5db7qS9EFUrnEw4d2zc4GqEr9u3WfPww # ggbAMIIEqKADAgECAhADyzT9Pf8SETOf8HxLIVfHMA0GCSqGSIb3DQEBCwUAMGMx # CzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5EaWdpQ2VydCwgSW5jLjE7MDkGA1UEAxMy # RGlnaUNlcnQgVHJ1c3RlZCBHNCBSU0E0MDk2IFNIQTI1NiBUaW1lU3RhbXBpbmcg # Q0EwHhcNMjIwODMwMDAwMDAwWhcNMjMwODI5MjM1OTU5WjBGMQswCQYDVQQGEwJV # UzERMA8GA1UEChMIRGlnaUNlcnQxJDAiBgNVBAMTG0RpZ2lDZXJ0IFRpbWVzdGFt # cCAyMDIyIC0gMjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAM/spSY6 # xqnya7uNwQ2a26HoFIV0MxomrNAcVR4eNm28klUMYfSdCXc9FZYIL2tkpP0GgxbX # kZI4HDEClvtysZc6Va8z7GGK6aYo25BjXL2JU+A6LYyHQq4mpOS7eHi5ehbhVsbA # umRTuyoW51BIu4hpDIjG8b7gL307scpTjUCDHufLckkoHkyAHoVW54Xt8mG8qjoH # ffarbuVm3eJc9S/tjdRNlYRo44DLannR0hCRRinrPibytIzNTLlmyLuqUDgN5YyU # XRlav/V7QG5vFqianJVHhoV5PgxeZowaCiS+nKrSnLb3T254xCg/oxwPUAY3ugjZ # Naa1Htp4WB056PhMkRCWfk3h3cKtpX74LRsf7CtGGKMZ9jn39cFPcS6JAxGiS7uY # v/pP5Hs27wZE5FX/NurlfDHn88JSxOYWe1p+pSVz28BqmSEtY+VZ9U0vkB8nt9Kr # FOU4ZodRCGv7U0M50GT6Vs/g9ArmFG1keLuY/ZTDcyHzL8IuINeBrNPxB9Thvdld # S24xlCmL5kGkZZTAWOXlLimQprdhZPrZIGwYUWC6poEPCSVT8b876asHDmoHOWIZ # ydaFfxPZjXnPYsXs4Xu5zGcTB5rBeO3GiMiwbjJ5xwtZg43G7vUsfHuOy2SJ8bHE # uOdTXl9V0n0ZKVkDTvpd6kVzHIR+187i1Dp3AgMBAAGjggGLMIIBhzAOBgNVHQ8B # Af8EBAMCB4AwDAYDVR0TAQH/BAIwADAWBgNVHSUBAf8EDDAKBggrBgEFBQcDCDAg # BgNVHSAEGTAXMAgGBmeBDAEEAjALBglghkgBhv1sBwEwHwYDVR0jBBgwFoAUuhbZ # bU2FL3MpdpovdYxqII+eyG8wHQYDVR0OBBYEFGKK3tBh/I8xFO2XC809KpQU31Kc # MFoGA1UdHwRTMFEwT6BNoEuGSWh0dHA6Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9EaWdp # Q2VydFRydXN0ZWRHNFJTQTQwOTZTSEEyNTZUaW1lU3RhbXBpbmdDQS5jcmwwgZAG # CCsGAQUFBwEBBIGDMIGAMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdpY2Vy # dC5jb20wWAYIKwYBBQUHMAKGTGh0dHA6Ly9jYWNlcnRzLmRpZ2ljZXJ0LmNvbS9E # aWdpQ2VydFRydXN0ZWRHNFJTQTQwOTZTSEEyNTZUaW1lU3RhbXBpbmdDQS5jcnQw # DQYJKoZIhvcNAQELBQADggIBAC0UyaEGSS3dimxaHgXjrMnYnjeKsKYhIj9EyjE9 # ywwM33xT5ZRqdiX3Isk7nEIElPWCRN5u4oTo7k5EGGktx3ZsrHpzf0siEEmEdDfy # gtNBlXYxLvlZab8HVrslWfexM+66XRCFK19PgSnudu0gC3XaxWbC6eAeWmgBTLRk # tDRpqbY9fj1d6REtuXxf4RNrN0MDT+kVDdt1BVTHDTlfGDbA6HAXR1Vc+khF8cv4 # RMJ8vvP3p6z05qFttPe3RMWPCC+d8hKtJI+2C3hBwdKChzJizkfq60Vrqqj+dEeB # nrUYhUcYIIz6WeVYk72r/31a9SowYPuTzNCktU59LF6Y2/bMPIpHeHhsBAvg2RMx # DzH4TfzgKkGM8F8VDpTAKUXe8vlzzsNjJ4m+oeGi72Kj6if/M07iiT4kMEQV5Fg8 # BotKdIqx7a1Cf+aqpZq5+DAcFhPwo4uoKtSLAWY0aIACxRKSFqIHngiuc2t9n+vB # /oM/rtlQNnnlt8E2hvC3yQl5+M/7sqzX4vI3BBv6ASmOsDaYOGrb90BA77kpxccg # avKscb/UdmJ+yGZjMyuuUzjPpKpGxMG95S9ATieDVuDFi68taSY81PJVmxBD/MrB # bfTZ9JBLS5F1s0ecKEr6OOY1PvLIry+8TrgnFUP5KT019GjiRV2GVCOBx9aBB9M+ # oTliMYIFXTCCBVkCAQEwgYYwcjELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lD # ZXJ0IEluYzEZMBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTExMC8GA1UEAxMoRGln # aUNlcnQgU0hBMiBBc3N1cmVkIElEIENvZGUgU2lnbmluZyBDQQIQAwW7hiGwoWNf # v96uEgTnbTANBglghkgBZQMEAgEFAKCBhDAYBgorBgEEAYI3AgEMMQowCKACgACh # AoAAMBkGCSqGSIb3DQEJAzEMBgorBgEEAYI3AgEEMBwGCisGAQQBgjcCAQsxDjAM # BgorBgEEAYI3AgEVMC8GCSqGSIb3DQEJBDEiBCB0MGuOMBQsY+9QhN2yLPhDEBe8 # gLppyJe9j1j44wDNtDANBgkqhkiG9w0BAQEFAASCAQB215VwjTC9Yfh2hloJPv3b # imysylQIl8gYnN9nzP/OY3HZp5lqX6O4y0+0bd/2Pljsd366LuAnkoj1dp9g5/kx # NKxa/IjRZmw2lGa/2JPpI+2DXq99UEpDMvjpwS0o5PkANiDqn1XpjBZg9o0BMIDI # bzS7YGIV2vNdzEA1sPxrBUA/sIT5qWk/CO0FLM/sBj0F/LwiMxPBwyzM4rAmrpSO # vcf98qMWkt8BVLsH2+s52Oq9Iap5cQ5OltZotW3Q+vXc9RedZT25VN6L3/gu+Or5 # 9hCaA7PqjGDSMJ//zHT/m1Haa7dEMhbbrvGZwFAiYkLeBHUrlWIP8JXzRxDC3KTb # oYIDIDCCAxwGCSqGSIb3DQEJBjGCAw0wggMJAgEBMHcwYzELMAkGA1UEBhMCVVMx # FzAVBgNVBAoTDkRpZ2lDZXJ0LCBJbmMuMTswOQYDVQQDEzJEaWdpQ2VydCBUcnVz # dGVkIEc0IFJTQTQwOTYgU0hBMjU2IFRpbWVTdGFtcGluZyBDQQIQA8s0/T3/EhEz # n/B8SyFXxzANBglghkgBZQMEAgEFAKBpMBgGCSqGSIb3DQEJAzELBgkqhkiG9w0B # BwEwHAYJKoZIhvcNAQkFMQ8XDTIyMDkyMTA5MzczM1owLwYJKoZIhvcNAQkEMSIE # IIyzJIVk7ST5iiS7zgInd2GcSZKDl8xrGltIPQn3/H9yMA0GCSqGSIb3DQEBAQUA # BIICAAaU5BjXHZ4NXVCeaxpS6TzrcSfAtES/XQh7dysoYfzkhUMqVOf1ri5Y/wUR # wLO0b3XHw4tXmtSUwd8AXhVdCNq0n3Nn/DephOzNh1oZHBAtRk947ZUjzs6PZq+Y # EcWjj9w20sV4BOdue2W7mP0EhoIOJDqslcDceJLWxWtmC7L2PpU8lmskguObNO9C # 1QNjkYudjFMI82PvHdaVzZTdFafmF0gnFphNpAwbUpg1WOT8+wxswIswYP49U20Y # +SXseEqsFaHy2MRRDBoXOau77qVrpfNdDPoVM8O2rZYGBbSWUgZcSLwpp+n2UFY2 # dEuWcJGg4iSBYhJhhmZ64VhFlkjN7bbmxCCa6w5dQj2VGJWeIdKuQ2HAHr0A3Rfn # N7P8Y+4PHYPH5yMaQk2hSsQrQ27vnTVHgX77fTaLOzzCj4l60HqWbeU892LkvOPP # gUZb/JhGTyRXOdUXHhpunud87KTt54JJuslh1UYo/6xr9yFzv0692Gntkwgs4FCG # a8ytYvlys7b+gihkBLUQW6vnfMxiYvK7ETHqQmpDTIwbO+1QMHVc1aLtothy0N8W # NUY0xrw1DwsWilp5Q+5hgQAtlrbvwKmmwb99gquiJ9rvC3Nmexy+sMovhkpwLA1G # W4vJEkPcUeths08HSczFjq350aMJWoZOGelSAZ1LK6ezahti # SIG # End signature block |