Private/Get-Utils.ps1
|
# # © Copyright 2018-2021, 2026 Hewlett Packard Enterprise Development LP # All Rights Reserved # $JSON_HEADER = 'application/vnd.simplivity.v1.10+json' $JSON_API15_HEADER = 'application/vnd.simplivity.v1.15+json' $JSON_API16_HEADER = 'application/vnd.simplivity.v1.16+json' $JSON_API17_HEADER = 'application/vnd.simplivity.v1.17+json' $BEGIN_CERTIFICATE = '-----BEGIN CERTIFICATE-----' $END_CERTIFICATE = '-----END CERTIFICATE-----' $CRED_XML_PATH = Join-Path $HOME HPESvtCertificate.ps1.credential $VALID_RBAC_ROLES = 'Administrator', 'BackupUser' # Module-level flag to track certificate bypass initialization $script:SvtCertBypassReady = $false function SetCredXml { param( $configObject ) if (!(Get-IsPowerShellCore)) { #Export/Import-Clixml with encrypted content not supported on PowerShell Core $configObject.AccessToken = ConvertTo-SecureString $configObject.AccessToken -AsPlainText -Force } $configObject | Export-Clixml $CRED_XML_PATH -Force return $CRED_XML_PATH } function GetCredXml { if (![System.IO.File]::Exists($CRED_XML_PATH)) { throw "Could not authenticate. Run Get-HPESvtAuthToken to authenticate." } $configObject = Import-Clixml $CRED_XML_PATH if (!(Get-IsPowerShellCore)) { #Export/Import-Clixml with encrypted content not supported on PowerShell Core $configObject.AccessToken = (New-Object PSCredential "user",$configObject.AccessToken).GetNetworkCredential().Password } return $configObject } function Get-IsPowerShellCore { $PSVersionTable.PSEdition -and $PsVersionTable.PSEdition -eq 'Core' } function Get-BaseUrl { param( [string] $hostname ) 'https://' + $hostname + '/api' } function Get-CertificateUrl { param( [string] $hostname ) $baseUrl = Get-BaseUrl $hostname return $baseUrl + '/certificates' } function Get-RbacUrl { param( [string] $hostname ) $baseUrl = Get-BaseUrl $hostname return $baseUrl + '/security/rbac' } function Get-RbacRoleAssignmentUrl { param( [string] $hostname ) $baseUrl = Get-RbacUrl $hostname return $baseUrl + '/policies/role_assignments' } function Get-RbacRoleRemovalUrl { param( [string] $hostname ) $baseUrl = Get-RbacUrl $hostname return $baseUrl + '/policies/role_assignments/remove' } function Get-Header { param( [string] $accessToken ) @{ 'Authorization' = ("Bearer {0}" -f $accessToken); 'Accept'=$JSON_HEADER } } # Add -SkipCertificateCheck flag if on PowerShell Core. This flag only exists in PowerShell 6.0 or later. # There is an alternate way to do this on earlier versions of PowerShell, so just set this for PowerShell Core. function Get-SkipCertificateFlag { $skipCertificateFlag = @{} if (Get-IsPowerShellCore) { $skipCertificateFlag.add("SkipCertificateCheck", $true) } $skipCertificateFlag } # Skip certificate checking for 5.1. For some reason the standard way of disabling certificate checking does not # work when connecting to the VmWare HMS, but this snippet of C# does. # Force Tls version to 1.2. This fixes a defect when connecting to a system with Tls 1.0 disabled. # Version-aware certificate validation bypass # PS 7.x+: No-op (uses -SkipCertificateCheck cmdlet parameter) # PS 5.1: Uses legacy callback mechanism function Skip-CertificateCheck { # PowerShell Core handles this via -SkipCertificateCheck parameter if (Get-IsPowerShellCore) { Write-Verbose "HPESvtCmdlets: Certificate validation handled via cmdlet parameter" return } # Already configured for this session if ($script:SvtCertBypassReady) { Write-Verbose "HPESvtCmdlets: Certificate bypass already configured" return } Write-Warning "Bypassing certificate validation. Use only in trusted environments." # PowerShell 5.1 - configure legacy bypass try { # Search for existing type in loaded assemblies $typeFound = $false foreach ($asm in [System.AppDomain]::CurrentDomain.GetAssemblies()) { try { $testType = $asm.GetType('SvtTlsValidationBypass', $false, $false) if ($null -ne $testType) { $typeFound = $true Write-Verbose "Found SvtTlsValidationBypass in assembly: $($asm.FullName)" break } } catch { # Some assemblies don't support type lookup } } if (-not $typeFound) { $tlsBypassDefinition = @' using System; using System.Net; using System.Net.Security; using System.Security.Cryptography.X509Certificates; public sealed class SvtTlsValidationBypass { private static readonly object SyncRoot = new object(); private static bool Configured = false; public static void Configure() { lock (SyncRoot) { if (Configured) return; ServicePointManager.ServerCertificateValidationCallback = TrustAllCallback; Configured = true; } } private static bool TrustAllCallback( object requestSender, X509Certificate serverCert, X509Chain certChain, SslPolicyErrors policyErrors) { return true; } } '@ Add-Type -TypeDefinition $tlsBypassDefinition -Language CSharp -ErrorAction Stop } [SvtTlsValidationBypass]::Configure() $script:SvtCertBypassReady = $true } catch { Write-Warning "HPESvtCmdlets: TLS bypass setup failed - $($_.Exception.Message)" } # Ensure TLS 1.2 is enabled for PS 5.1 try { $currentProtocols = [System.Net.ServicePointManager]::SecurityProtocol $tls12 = [System.Net.SecurityProtocolType]::Tls12 if (-not ($currentProtocols -band $tls12)) { [System.Net.ServicePointManager]::SecurityProtocol = $currentProtocols -bor $tls12 } } catch { Write-Verbose "HPESvtCmdlets: Protocol configuration skipped" } } # Get X509Certificate2 from base64 encoded string from the server. # This will include Begin/End Certificate strings and newlines that need to be trimmed. function Get-CertificateFromBase64String { param( [string] $base64String ) $base64String = $base64String.Trim() $base64String = $base64String.Trim($BEGIN_CERTIFICATE) $base64String = $base64String.Trim($END_CERTIFICATE) $byteArray = [System.Convert]::FromBase64String($base64String) $cert = [System.Security.Cryptography.X509Certificates.X509Certificate2]::New($byteArray) Write-Output $cert } # see table at https://docs.microsoft.com/en-us/dotnet/framework/migration-guide/how-to-determine-which-versions-are-installed function Get-IsRunningNet47 { # Core has everything we need for 4.7 interop if (Get-IsPowerShellCore) { return; } $running = Get-CheckDotNetVersion -version 460805 if ($running -eq $false) { throw "This cmdlet requires .net 4.7" } } function Get-CheckDotNetVersion { param( [int] $version ) try { $installed = (Get-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full') if ($version -gt $installed.Release) { return $false } return $true } catch { Write-Error "Error while determining .NET version" } return $false } function Copy-Hashtable { param( [Parameter(Mandatory=$true)] [ValidateNotNull()] [hashtable]$DeepCopyObject ) # JSON-based deep copy - works on both PS 5.1 and PS 7.x # Replaces BinaryFormatter which was removed in .NET 9 try { $json = $DeepCopyObject | ConvertTo-Json -Depth 10 -Compress if (Get-IsPowerShellCore) { # PS 6.0+ supports -AsHashtable parameter return ($json | ConvertFrom-Json -AsHashtable) } else { # PS 5.1: ConvertFrom-Json returns PSCustomObject, convert to hashtable $obj = $json | ConvertFrom-Json $hashtable = @{} $obj.PSObject.Properties | ForEach-Object { $hashtable[$_.Name] = $_.Value } return $hashtable } } catch { throw "Failed to clone hashtable: $($_.Exception.Message)" } } function Approve-HostOAuthToken { param( [Parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] [HashTable] $HostOAuthToken ) # Validate the 'Hostname' portion of the Host OAuth Token composite. $hostname = $HostOAuthToken['Hostname'] if (-not $hostname) { throw "HostOAuthToken hash table missing 'Hostname' key" } if ([string]::IsNullOrWhiteSpace($hostname)) { throw "HostOAuthToken hash table 'Hostname' value contains only white space" } # Validate the 'OAuthHeader' portion of the Host OAuth Token composite. if (-not $HostOAuthToken['OAuthHeader']) { throw "HostOAuthToken hash table missing 'OAuthHeader' key" } if ($HostOAuthToken['OAuthHeader'].GetType().FullName -ne 'System.Collections.Hashtable') { throw "HostOAuthToken hash table 'OAuthHeader' value is not a hash table" } if ($HostOAuthToken['OAuthHeader'].Count -lt 1) { throw "HostOAuthToken hash table 'OAuthHeader' value is expected to have at least one entry" } if (-not ($HostOAuthToken['OAuthHeader']['Authorization'])) { throw "HostOAuthToken hash table 'OAuthHeader' value is missing the 'Authorization' key" } if ([string]::IsNullOrWhiteSpace($HostOAuthToken['OAuthHeader']['Authorization'])) { throw "HostOAuthToken hash table 'OAuthHeader' value hash table 'Authorization' value contains only white space" } if (-not ($HostOAuthToken['OAuthHeader']['Authorization']).StartsWith("Bearer ")) { throw "HostOAuthToken hash table 'OAuthHeader' value hash table 'Authorization' value is invalid" } } function Get-PkiUrl { param( [string] $hostname ) $baseUrl = Get-BaseUrl $hostname return $baseUrl + '/security/pki/ca' } function Get-HostsUrl { param( [string] $hostname ) $baseUrl = Get-BaseUrl $hostname return $baseUrl + '/hosts' } function Get-VersionUrl { param( [string] $hostname ) $baseUrl = Get-BaseUrl $hostname return $baseUrl + '/version' } function Get-TokenUrl { param( [string] $hostname ) $baseUrl = Get-BaseUrl $hostname return $baseUrl + '/oauth/token' } function Get-TokenRevokeUrl { param( [string] $hostname ) $baseUrl = Get-BaseUrl $hostname return $baseUrl + '/oauth/revoke' } function Get-MvaNodeUrl { param( [string] $hostname ) $baseUrl = Get-BaseUrl $hostname return $baseUrl + '/configuration/mva/nodes' } # Helper function to return the embedded error message in the body of the response from the API, rather # than a generic runtime (404) error. function Get-SvtError { [CmdletBinding()] Param ( [Parameter(Mandatory = $true, Position = 0)] [System.Object]$Err ) #$VerbosePreference = 'Continue' if (-not (Get-IsPowerShellCore)) { if ($Err.Exception.Response) { $Result = $Err.Exception.Response.GetResponseStream() $Reader = New-Object System.IO.StreamReader($Result) $Reader.BaseStream.Position = 0 $Reader.DiscardBufferedData() $ResponseBody = $Reader.ReadToEnd() Write-Verbose $ResponseBody if ($ResponseBody.StartsWith('{')) { $ResponseBody = $ResponseBody | ConvertFrom-Json } return $ResponseBody.Message } else { return $Err.Exception.Message #This return incase there is no response or host is not not reachable } } else { # PowerShell V6 doesn't support GetResponseStream(), so return the generic runtime error return $Err.Exception.Message } } # Helper function for Invoke-RestMethod to handle REST errors in one place. The calling function # then re-throws the error, generated here. This cmdlet either outputs a custom task object if the # REST API response is a task object, or otherwise the raw JSON. function Invoke-SvtRestMethod { [CmdletBinding()] param ( [ValidateNotNullOrEmpty()] [Parameter(Mandatory=$true, Position = 0, HelpMessage='Input a valid host OAuth token composite')] [HashTable] $HostOAuthToken, [Parameter(Mandatory = $true, Position = 1)] [System.Object]$Uri, [Parameter(Mandatory = $false, Position = 2)] [System.Collections.IDictionary]$Header, [Parameter(Mandatory = $true, Position = 3)] [ValidateSet('get', 'post', 'delete', 'put')] [System.String]$Method, [Parameter(Mandatory = $false, Position = 4)] [System.Object]$Body ) [System.int32]$Retrycount = 0 [bool]$Stoploop = $false do { try { $skipCertParam = Get-SkipCertificateFlag if ($PSBoundParameters.ContainsKey('Body')) { $Response = Invoke-RestMethod -Uri $Uri -Headers $Header -Body $Body -Method $Method @skipCertParam } else { $Response = Invoke-RestMethod -Uri $Uri -Headers $Header -Method $Method @skipCertParam } $Stoploop = $true } catch [System.Management.Automation.RuntimeException] { if ($_.Exception.Message -match "Unauthorized") { if ($Retrycount -ge 3) { # Exit after 3 retries throw "Runtime error: Session expired and could not reconnect" } else { $Retrycount += 1 Write-Verbose "Session expired, reconnecting..." Renew-SvtSession -HostOAuthToken $HostOAuthToken $Header.Authorization = "Bearer " + $HostOAuthToken.AccessToken } } else { throw "Runtime error: $(Get-SvtError($_))" } } catch { throw "An unexpected error occurred: $($_.Exception.Message)" } } until ($Stoploop -eq $true) # If the JSON output is a task, convert it to a custom object of type 'HPE.SimpliVity.Task' and pass this # back to the calling cmdlet. A lot of cmdlets produce task object types, so this cuts out repetition # in the module. # Note: $Response.task is incorrectly true with /api/omnistack_clusters/throughput, so added a check for this. if ($Response.task -and $URI -notmatch '/api/omnistack_clusters/throughput') { $LocalFormat = Get-SvtLocalDateFormat $Response.task | ForEach-Object { if ($_.start_time -as [datetime]) { $StartTime = Get-Date -Date $_.start_time -Format $LocalFormat } else { $StartTime = $null } if ($_.end_time -as [datetime]) { $EndTime = Get-Date -Date $_.end_time -Format $LocalFormat } else { $EndTime = $null } [PSCustomObject]@{ StartTime = $StartTime TaskResult = $_.task_results AffectedObjects = $_.affected_objects OwnerId = $_.owner_id DestinationId = $_.destination_id Name = $_.name EndTime = $EndTime ErrorCode = $_.error_code ErrorMessage = $_.error_message State = $_.state TaskId = $_.id Type = $_.type PercentComplete = $_.percent_complete SubTasks = $_.sub_tasks } } } else { # For all other object types, return the raw JSON output for the calling cmdlet to deal with $Response } } # Helper function that returns the local date format. Used by cmdlets that return date properties function Get-SvtLocalDateFormat { $Culture = (Get-Culture).DateTimeFormat $LocalDate = "$($Culture.ShortDatePattern)" -creplace '^d/', 'dd/' -creplace '^M/', 'MM/' -creplace '/d/', '/dd/' $LocalTime = "$($Culture.LongTimePattern)" -creplace '^h:mm', 'hh:mm' -creplace '^H:mm', 'HH:mm' return "$LocalDate $LocalTime" } #Helper function to identify the IP/Hostname provided is an MVA or SVA function Identify-Host { [CmdletBinding()] param ( [Parameter(Mandatory = $true)] [string] $Hostname ) $response = Get-SvtVersion -Hostname $Hostname $response | ForEach-Object { if ($_.Aggregator_Version) { return "MVA" } elseif ($_.SVTFS_Version) { return "SVA" } else { throw "The provided IP/hostname is not an SVA/MVA" } } } #Helper function to get the version information from the SVA/MVA IP/hostname provided. function Get-SvtVersion { [CmdletBinding()] param ( [Parameter(Mandatory = $true, HelpMessage = "Input the MVA/SVA Hostname/IP")] [Alias("mva", "ovc")] [string] $Hostname ) $url = Get-VersionUrl -hostname "$Hostname" $skipCertParam = Get-SkipCertificateFlag try { $response = Invoke-RestMethod -Uri $url -Method Get @skipCertParam } catch { throw "The host $Hostname is not reachable or not a MVA or SVA" + $_.Exception.Message } return $response } function Get-SvtVersionUrl { param( [string] $hostname ) $baseUrl = Get-BaseUrl $hostname return $baseUrl + '/version' } function Get-SvtPolicyUrl { param( [string] $hostname ) $baseUrl = Get-BaseUrl $hostname return $baseUrl + '/policies' } function Check-ClusterTopology { param( [ValidateNotNullOrEmpty()] [Parameter(Mandatory=$true, HelpMessage='Input a valid host OAuth token composite')] [HashTable] $HostOAuthToken ) $Url = Get-MvaNodeUrl -Hostname $HostOAuthToken.Hostname $Header = @{ 'Authorization' = "Bearer " + $HostOAuthToken.AccessToken 'Accept' = 'application/json' } #Multifed check try { $Response = Invoke-SvtRestMethod -HostOAuthToken $HostOAuthToken -Uri $Url -Header $Header -Method Get -ErrorAction Stop } catch { throw ($_) } if ($Response.cluster_topology -eq "MULTI_FED") { return $true } return $false } #Function to pick a single cluster from a list of Cluster objects. #This will be used to select a cluster where there are more than one cluster with same name function Select-Cluster { param ( [Parameter(Mandatory = $true)] $ClusterList #List of HPE Simplivity cluster object from Get-Omnistack cluster list ) $ClusterCount = ($ClusterList | Measure-Object).count Write-Warning ("There are multiple HPE SimpliVity clusters with the Name $ClusterName") -WarningAction "Continue" foreach ($Count in 0..($ClusterCount - 1)) { Write-host (($Count + 1).ToString() + ". " + $ClusterList[$Count].HypervisorManagementName + "/" + $ClusterList[$Count].DataCenterName + "/" + $ClusterList[$Count].ClusterName) } if ($ClusterCount -gt 9) { throw("There are more than nine HPE SimpliVity clusters with the name $ClusterName. Use HPE SimpliVity cluster id instead of cluster name in the command line") } Write-host ("Select a HPE SimpliVity cluster from the above list to apply configuration changes (Select between 1 to $ClusterCount)") do { [Int]$Selection = Get-KeyStroke if (($Selection -lt 1) -or ($Selection -gt $ClusterCount)) { Write-Warning ("Input a valid number from 1 to $ClusterCount") } } while (($Selection -lt 1) -or ($Selection -gt $ClusterCount)) Write-Host ("Selected Cluster is : " + $ClusterList[($Selection - 1)].HypervisorManagementName + "/" + $ClusterList[($Selection - 1)].DataCenterName + "/" + $ClusterList[($Selection - 1)].ClusterName) return $ClusterList[($Selection - 1)] } #Helper function to take the key stroke from the command line with default timeout of 60 seconds. function Get-KeyStroke { param ( [Int]$Timeout = 60, [Int]$SleepTime = 1 ) [int]$KeyOut = 0 $Timer = [Diagnostics.Stopwatch]::StartNew() do { $TotalSecs = [Math]::Round($Timer.Elapsed.TotalSeconds, 0) if ([Console]::KeyAvailable){ $Key = $Host.UI.RawUI.ReadKey("IncludeKeyDown") Write-host("`n") if ([int]::TryParse($Key.Character, [ref]$KeyOut)) { break } else { Write-Warning ("Invalid input") } } Start-Sleep $SleepTime } while($Timer.Elapsed.TotalSeconds -lt $Timeout) $Timer.Stop() if($Timer.Elapsed.TotalSeconds -gt $Timeout) { throw ("Timed out for the user input") } return $KeyOut } function Invoke-SvtRestMethodWithRetry { [CmdletBinding()] param ( [Parameter(Mandatory = $true, Position = 1)] [ValidateSet('get', 'post', 'delete', 'put')] [String]$Method, [Parameter(Mandatory = $true, Position = 2)] [String]$Uri, [Parameter(Mandatory = $false, Position = 3)] [Hashtable]$Headers, [Parameter(Mandatory = $false, Position = 4)] [Object]$Body, [Parameter(Mandatory = $false, Position = 5)] [Int32]$MaximumRetries = 12, [Parameter(Mandatory = $false, Position = 6)] [Int32]$SleepIntervalInSecs = 10, [Parameter(Mandatory = $false, Position = 7)] [Int32[]]$ErrorCodesOnRetry = @(503) ) [Int32]$Retrycount = 0 [bool]$Stoploop = $false do { try { $skipCertParam = Get-SkipCertificateFlag $Response = Invoke-RestMethod -Uri $Uri -Headers $Headers -Body $Body -Method $Method @skipCertParam $Stoploop = $true Write-Output $Response } catch { $Stoploop = $true if ($Retrycount -lt $MaximumRetries) { if ($_.Exception.Response) { $errorCode = $_.Exception.Response.StatusCode.value__; if ($ErrorCodesOnRetry.contains($errorCode)) { $Retrycount = $Retrycount + 1 Write-Host "Server ($Method $Uri) unavailable! will reconnect after $SleepIntervalInSecs seconds, attempt #$Retrycount/$MaximumRetries" Start-Sleep -Seconds $SleepIntervalInSecs $Stoploop = $false } else { throw $_.Exception } } else { throw $_.Exception } } else { throw $_.Exception } } } While ($Stoploop -eq $false) } function Get-GenerateCSRUrl { param( [string] $hostname ) $baseUrl = Get-BaseUrl $hostname return $baseUrl + '/security/pki/generate_csr' } function Get-TLSCertChainUrl { param( [string] $hostname ) $baseUrl = Get-BaseUrl $hostname return $baseUrl + '/security/pki/import_tls_cert_chain' } function Get-VerifyCRLUrl { param( [string] $hostname ) $baseUrl = Get-BaseUrl $hostname return $baseUrl + '/security/pki/verify_crl' } # SIG # Begin signature block # MIIungYJKoZIhvcNAQcCoIIujzCCLosCAQExDzANBglghkgBZQMEAgEFADB5Bgor # BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG # KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCDCqJMAAn/HzMD5 # uhqwGWPeNWyF5ciOxbU6iqMIjDAv3KCCEfYwggVvMIIEV6ADAgECAhBI/JO0YFWU # jTanyYqJ1pQWMA0GCSqGSIb3DQEBDAUAMHsxCzAJBgNVBAYTAkdCMRswGQYDVQQI # DBJHcmVhdGVyIE1hbmNoZXN0ZXIxEDAOBgNVBAcMB1NhbGZvcmQxGjAYBgNVBAoM # EUNvbW9kbyBDQSBMaW1pdGVkMSEwHwYDVQQDDBhBQUEgQ2VydGlmaWNhdGUgU2Vy # dmljZXMwHhcNMjEwNTI1MDAwMDAwWhcNMjgxMjMxMjM1OTU5WjBWMQswCQYDVQQG # EwJHQjEYMBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMS0wKwYDVQQDEyRTZWN0aWdv # IFB1YmxpYyBDb2RlIFNpZ25pbmcgUm9vdCBSNDYwggIiMA0GCSqGSIb3DQEBAQUA # A4ICDwAwggIKAoICAQCN55QSIgQkdC7/FiMCkoq2rjaFrEfUI5ErPtx94jGgUW+s # hJHjUoq14pbe0IdjJImK/+8Skzt9u7aKvb0Ffyeba2XTpQxpsbxJOZrxbW6q5KCD # J9qaDStQ6Utbs7hkNqR+Sj2pcaths3OzPAsM79szV+W+NDfjlxtd/R8SPYIDdub7 # P2bSlDFp+m2zNKzBenjcklDyZMeqLQSrw2rq4C+np9xu1+j/2iGrQL+57g2extme # me/G3h+pDHazJyCh1rr9gOcB0u/rgimVcI3/uxXP/tEPNqIuTzKQdEZrRzUTdwUz # T2MuuC3hv2WnBGsY2HH6zAjybYmZELGt2z4s5KoYsMYHAXVn3m3pY2MeNn9pib6q # RT5uWl+PoVvLnTCGMOgDs0DGDQ84zWeoU4j6uDBl+m/H5x2xg3RpPqzEaDux5mcz # mrYI4IAFSEDu9oJkRqj1c7AGlfJsZZ+/VVscnFcax3hGfHCqlBuCF6yH6bbJDoEc # QNYWFyn8XJwYK+pF9e+91WdPKF4F7pBMeufG9ND8+s0+MkYTIDaKBOq3qgdGnA2T # OglmmVhcKaO5DKYwODzQRjY1fJy67sPV+Qp2+n4FG0DKkjXp1XrRtX8ArqmQqsV/ # AZwQsRb8zG4Y3G9i/qZQp7h7uJ0VP/4gDHXIIloTlRmQAOka1cKG8eOO7F/05QID # AQABo4IBEjCCAQ4wHwYDVR0jBBgwFoAUoBEKIz6W8Qfs4q8p74Klf9AwpLQwHQYD # VR0OBBYEFDLrkpr/NZZILyhAQnAgNpFcF4XmMA4GA1UdDwEB/wQEAwIBhjAPBgNV # HRMBAf8EBTADAQH/MBMGA1UdJQQMMAoGCCsGAQUFBwMDMBsGA1UdIAQUMBIwBgYE # VR0gADAIBgZngQwBBAEwQwYDVR0fBDwwOjA4oDagNIYyaHR0cDovL2NybC5jb21v # ZG9jYS5jb20vQUFBQ2VydGlmaWNhdGVTZXJ2aWNlcy5jcmwwNAYIKwYBBQUHAQEE # KDAmMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5jb21vZG9jYS5jb20wDQYJKoZI # hvcNAQEMBQADggEBABK/oe+LdJqYRLhpRrWrJAoMpIpnuDqBv0WKfVIHqI0fTiGF # OaNrXi0ghr8QuK55O1PNtPvYRL4G2VxjZ9RAFodEhnIq1jIV9RKDwvnhXRFAZ/ZC # J3LFI+ICOBpMIOLbAffNRk8monxmwFE2tokCVMf8WPtsAO7+mKYulaEMUykfb9gZ # pk+e96wJ6l2CxouvgKe9gUhShDHaMuwV5KZMPWw5c9QLhTkg4IUaaOGnSDip0TYl # d8GNGRbFiExmfS9jzpjoad+sPKhdnckcW67Y8y90z7h+9teDnRGWYpquRRPaf9xH # +9/DUp/mBlXpnYzyOmJRvOwkDynUWICE5EV7WtgwggYaMIIEAqADAgECAhBiHW0M # UgGeO5B5FSCJIRwKMA0GCSqGSIb3DQEBDAUAMFYxCzAJBgNVBAYTAkdCMRgwFgYD # VQQKEw9TZWN0aWdvIExpbWl0ZWQxLTArBgNVBAMTJFNlY3RpZ28gUHVibGljIENv # ZGUgU2lnbmluZyBSb290IFI0NjAeFw0yMTAzMjIwMDAwMDBaFw0zNjAzMjEyMzU5 # NTlaMFQxCzAJBgNVBAYTAkdCMRgwFgYDVQQKEw9TZWN0aWdvIExpbWl0ZWQxKzAp # BgNVBAMTIlNlY3RpZ28gUHVibGljIENvZGUgU2lnbmluZyBDQSBSMzYwggGiMA0G # CSqGSIb3DQEBAQUAA4IBjwAwggGKAoIBgQCbK51T+jU/jmAGQ2rAz/V/9shTUxjI # ztNsfvxYB5UXeWUzCxEeAEZGbEN4QMgCsJLZUKhWThj/yPqy0iSZhXkZ6Pg2A2NV # DgFigOMYzB2OKhdqfWGVoYW3haT29PSTahYkwmMv0b/83nbeECbiMXhSOtbam+/3 # 6F09fy1tsB8je/RV0mIk8XL/tfCK6cPuYHE215wzrK0h1SWHTxPbPuYkRdkP05Zw # mRmTnAO5/arnY83jeNzhP06ShdnRqtZlV59+8yv+KIhE5ILMqgOZYAENHNX9SJDm # +qxp4VqpB3MV/h53yl41aHU5pledi9lCBbH9JeIkNFICiVHNkRmq4TpxtwfvjsUe # dyz8rNyfQJy/aOs5b4s+ac7IH60B+Ja7TVM+EKv1WuTGwcLmoU3FpOFMbmPj8pz4 # 4MPZ1f9+YEQIQty/NQd/2yGgW+ufflcZ/ZE9o1M7a5Jnqf2i2/uMSWymR8r2oQBM # dlyh2n5HirY4jKnFH/9gRvd+QOfdRrJZb1sCAwEAAaOCAWQwggFgMB8GA1UdIwQY # MBaAFDLrkpr/NZZILyhAQnAgNpFcF4XmMB0GA1UdDgQWBBQPKssghyi47G9IritU # pimqF6TNDDAOBgNVHQ8BAf8EBAMCAYYwEgYDVR0TAQH/BAgwBgEB/wIBADATBgNV # HSUEDDAKBggrBgEFBQcDAzAbBgNVHSAEFDASMAYGBFUdIAAwCAYGZ4EMAQQBMEsG # A1UdHwREMEIwQKA+oDyGOmh0dHA6Ly9jcmwuc2VjdGlnby5jb20vU2VjdGlnb1B1 # YmxpY0NvZGVTaWduaW5nUm9vdFI0Ni5jcmwwewYIKwYBBQUHAQEEbzBtMEYGCCsG # AQUFBzAChjpodHRwOi8vY3J0LnNlY3RpZ28uY29tL1NlY3RpZ29QdWJsaWNDb2Rl # U2lnbmluZ1Jvb3RSNDYucDdjMCMGCCsGAQUFBzABhhdodHRwOi8vb2NzcC5zZWN0 # aWdvLmNvbTANBgkqhkiG9w0BAQwFAAOCAgEABv+C4XdjNm57oRUgmxP/BP6YdURh # w1aVcdGRP4Wh60BAscjW4HL9hcpkOTz5jUug2oeunbYAowbFC2AKK+cMcXIBD0Zd # OaWTsyNyBBsMLHqafvIhrCymlaS98+QpoBCyKppP0OcxYEdU0hpsaqBBIZOtBajj # cw5+w/KeFvPYfLF/ldYpmlG+vd0xqlqd099iChnyIMvY5HexjO2AmtsbpVn0OhNc # WbWDRF/3sBp6fWXhz7DcML4iTAWS+MVXeNLj1lJziVKEoroGs9Mlizg0bUMbOalO # hOfCipnx8CaLZeVme5yELg09Jlo8BMe80jO37PU8ejfkP9/uPak7VLwELKxAMcJs # zkyeiaerlphwoKx1uHRzNyE6bxuSKcutisqmKL5OTunAvtONEoteSiabkPVSZ2z7 # 6mKnzAfZxCl/3dq3dUNw4rg3sTCggkHSRqTqlLMS7gjrhTqBmzu1L90Y1KWN/Y5J # KdGvspbOrTfOXyXvmPL6E52z1NZJ6ctuMFBQZH3pwWvqURR8AgQdULUvrxjUYbHH # j95Ejza63zdrEcxWLDX6xWls/GDnVNueKjWUH3fTv1Y8Wdho698YADR7TNx8X8z2 # Bev6SivBBOHY+uqiirZtg0y9ShQoPzmCcn63Syatatvx157YK9hlcPmVoa1oDE5/ # L9Uo2bC5a4CH2RwwggZhMIIEyaADAgECAhEAyDHh+zCQwUNyJV9S6gqqvTANBgkq # hkiG9w0BAQwFADBUMQswCQYDVQQGEwJHQjEYMBYGA1UEChMPU2VjdGlnbyBMaW1p # dGVkMSswKQYDVQQDEyJTZWN0aWdvIFB1YmxpYyBDb2RlIFNpZ25pbmcgQ0EgUjM2 # MB4XDTI1MDUyMDAwMDAwMFoXDTI4MDUxOTIzNTk1OVowdzELMAkGA1UEBhMCVVMx # DjAMBgNVBAgMBVRleGFzMSswKQYDVQQKDCJIZXdsZXR0IFBhY2thcmQgRW50ZXJw # cmlzZSBDb21wYW55MSswKQYDVQQDDCJIZXdsZXR0IFBhY2thcmQgRW50ZXJwcmlz # ZSBDb21wYW55MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA37AD03qw # cmuCQyxRB2VBM7SfUf0SmpQb8iaPvGmxw5uoDBY3gdC/3Xq/rfM3ndCn03hNdGyu # cpC7tD4zmel6yYqxyXDVr45Jd2cz9jFXoYTOMcuDV6I6CvU/EnbFxWhv0VCp+2Ip # z4+uJGI6aVlMpFpLbgPjhp9ogd/89HEyi1FkSFoarnvxxaXm93S81k7FD/4Edtvu # muGI4V8p39GfbCiMuHku8BzSQ2g86gWFnOaVhY6h4XWvEmE8LPYkU/STrej28Flg # kSt9f/Jg6+dvRKm92uN2Z760Eql9+DTWkGmGe4YrIyD25XDa07sS9tIpVWzLrGOy # ecaVpJwVVBqCadXDgkgTYKw/UlS+cEqsviT6wREGl4aX/GbeNO6Y4oDTTYkabW3p # eg1ku0v90oDqzoTaWEE5ly2UajvXIgzpFLLXqpR6GYkv/y3ZJV0chBqRtAObebH7 # XOBa5a2kqMBw0gkIZBJHd8+PCPH/U7eJkeKXtGGj2uTudcGjZgOjVcFYdCRnufJd # isrV7bj0Hzghcv3QyRXL3rRjcNb4ccKNnSgF/8cmiTVpvFHTfUKsYdkbM6wsbjXR # dJNADjGOYRms7tKsii3/oXO+2S1Um7yomBZQ2+wVRCY6MrRX1onDKid5t5AyWFtR # u0aQcdBmHG6JeDiQ3Hrb2g9kZhuFkgABVBkCAwEAAaOCAYkwggGFMB8GA1UdIwQY # MBaAFA8qyyCHKLjsb0iuK1SmKaoXpM0MMB0GA1UdDgQWBBQH4rUE0gsy8LW2G3vm # oYtOnZ8zEjAOBgNVHQ8BAf8EBAMCB4AwDAYDVR0TAQH/BAIwADATBgNVHSUEDDAK # BggrBgEFBQcDAzBKBgNVHSAEQzBBMDUGDCsGAQQBsjEBAgEDAjAlMCMGCCsGAQUF # BwIBFhdodHRwczovL3NlY3RpZ28uY29tL0NQUzAIBgZngQwBBAEwSQYDVR0fBEIw # QDA+oDygOoY4aHR0cDovL2NybC5zZWN0aWdvLmNvbS9TZWN0aWdvUHVibGljQ29k # ZVNpZ25pbmdDQVIzNi5jcmwweQYIKwYBBQUHAQEEbTBrMEQGCCsGAQUFBzAChjho # dHRwOi8vY3J0LnNlY3RpZ28uY29tL1NlY3RpZ29QdWJsaWNDb2RlU2lnbmluZ0NB # UjM2LmNydDAjBggrBgEFBQcwAYYXaHR0cDovL29jc3Auc2VjdGlnby5jb20wDQYJ # KoZIhvcNAQEMBQADggGBAIax+Yaj5EciDlztft4iAfD2CtIWEF0cxR+UbbvJEs86 # 5wyoO3ZQoujr0FJ+P5fjDKLbamHrEWmyoD2YC4lzecmnFOnY0y4uJ9zBY8B6X6TU # 9e6+TfZtlXd44YffXYAfoLX+uYjVJcZOaMuXF61+CFpjLJjepsD8m1gdj5QUz2sH # 6GOfU6mEm8SHvKpgPMV/yhEKqgjlenY6Ao49RkxnDuvRlMP8SFPB+8bxiLegEdGa # ei8nSr/j5YeDZFevUJ696T4W45QGrwAhBBpbKDz6CzlImC1b2C8Bp02XBAsOQs/u # CIaQv5XxUmVxmb85tDJkd7QfqHo2z1T2NYMkvXUcSClYRuVxxC/frpqcrxS9O9xE # v65BoUztAJSXsTdfpUjWeNOnhq8lrwa2XAD3fbagNF6ElsBiNDSbwHCG/iY4kAya # VpbAYtaa6TfzdI/I0EaCX5xYRW56ccI2AnbaEVKz9gVjzi8hBLALlRhrs1uMFtPj # nZ+oA+rbZZyGZkz3xbUYKTGCG/4wghv6AgEBMGkwVDELMAkGA1UEBhMCR0IxGDAW # BgNVBAoTD1NlY3RpZ28gTGltaXRlZDErMCkGA1UEAxMiU2VjdGlnbyBQdWJsaWMg # Q29kZSBTaWduaW5nIENBIFIzNgIRAMgx4fswkMFDciVfUuoKqr0wDQYJYIZIAWUD # BAIBBQCgfDAQBgorBgEEAYI3AgEMMQIwADAZBgkqhkiG9w0BCQMxDAYKKwYBBAGC # NwIBBDAcBgorBgEEAYI3AgELMQ4wDAYKKwYBBAGCNwIBFTAvBgkqhkiG9w0BCQQx # IgQgE6HgGhBKHBeUiQ3lJ3kOEkNnR3Oa4OstJws845HSv+YwDQYJKoZIhvcNAQEB # BQAEggIAcuPQmhCMc8U+nsxYY8Yd63h5C3OMO3nS2Kg87m3h20w/p8ieDWPWGoYL # zo5uyCvDnp3RSlwO5x3+nJzUN86L3Fxbh43QFXH1G6Ohfrm+169dhxa8JMEPgaeh # I3+jJ6GGCeA5cj2Ewrg74K/N+cxpNZgDqibvf5fgchujC66P3zU7/VQ5QxBtNnnm # OWlWbhm5bF1ArR/c6rXqcqraZcFKDdAMN3Ibbym/da/8BOxyzgyJF9aqhoSOdLNM # o5/dB3WhJcRCgM+yw46nh49D5zK/y0bXnrlZh4z0gTkOXPTX5amzVsPeGl5m7IJr # t1FKp9kcMUB4wWNCKwTNj5gkTdtT7trXO4T6jWhcfqgsJ8yG/H90n3mTb1es1i7j # pkFQFVHbIk49FWClXvebJfKivkkTHD/zI6pVjOu69CXjuI6yK9Q8HynKnF4w56s8 # CXyhLXJO04wulLFbplbf7sQpRP40FMx5R1wSFOXNK3RJdkW3wR+T32KmOeWOqTtm # TS1WrL+4CjCNYR2gT9LSf5szB1W56hs275fC6qOylgD07jqyBNw+aBP2b4A+fPPI # gK7pAH+Jv7WRmSx+J4iuQb3w8x7bjQjx/kI/qpdMZbeEDCV8JVWN4fouDpUUlDCt # Vb2rPDXw764sqyhyOv8/um5F4DfYn52JR/dGRuUsJuo6itLFAQGhghjoMIIY5AYK # KwYBBAGCNwMDATGCGNQwghjQBgkqhkiG9w0BBwKgghjBMIIYvQIBAzEPMA0GCWCG # SAFlAwQCAgUAMIIBBwYLKoZIhvcNAQkQAQSggfcEgfQwgfECAQEGCisGAQQBsjEC # AQEwQTANBglghkgBZQMEAgIFAAQwMhewWztSyCbwWccRnEHAzTu7+qMDZBosqfzw # SO4wk5Vx8yIk5UznnLOVvwLNtZS1AhQT4e5HGUwZtSmncKrR+9E+7Ue2hhgPMjAy # NjAzMTYwODExMjhaoHakdDByMQswCQYDVQQGEwJHQjEXMBUGA1UECBMOV2VzdCBZ # b3Jrc2hpcmUxGDAWBgNVBAoTD1NlY3RpZ28gTGltaXRlZDEwMC4GA1UEAxMnU2Vj # dGlnbyBQdWJsaWMgVGltZSBTdGFtcGluZyBTaWduZXIgUjM2oIITBDCCBmIwggTK # oAMCAQICEQCkKTtuHt3XpzQIh616TrckMA0GCSqGSIb3DQEBDAUAMFUxCzAJBgNV # BAYTAkdCMRgwFgYDVQQKEw9TZWN0aWdvIExpbWl0ZWQxLDAqBgNVBAMTI1NlY3Rp # Z28gUHVibGljIFRpbWUgU3RhbXBpbmcgQ0EgUjM2MB4XDTI1MDMyNzAwMDAwMFoX # DTM2MDMyMTIzNTk1OVowcjELMAkGA1UEBhMCR0IxFzAVBgNVBAgTDldlc3QgWW9y # a3NoaXJlMRgwFgYDVQQKEw9TZWN0aWdvIExpbWl0ZWQxMDAuBgNVBAMTJ1NlY3Rp # Z28gUHVibGljIFRpbWUgU3RhbXBpbmcgU2lnbmVyIFIzNjCCAiIwDQYJKoZIhvcN # AQEBBQADggIPADCCAgoCggIBANOElfRupFN48j0QS3gSBzzclIFTZ2Gsn7BjsmBF # 659/kpA2Ey7NXK3MP6JdrMBNU8wdmkf+SSIyjX++UAYWtg3Y/uDRDyg8RxHeHRJ+ # 0U1jHEyH5uPdk1ttiPC3x/gOxIc9P7Gn3OgW7DQc4x07exZ4DX4XyaGDq5LoEmk/ # BdCM1IelVMKB3WA6YpZ/XYdJ9JueOXeQObSQ/dohQCGyh0FhmwkDWKZaqQBWrBwZ # ++zqlt+z/QYTgEnZo6dyIo2IhXXANFkCHutL8765NBxvolXMFWY8/reTnFxk3Maj # gM5NX6wzWdWsPJxYRhLxtJLSUJJ5yWRNw+NBqH1ezvFs4GgJ2ZqFJ+Dwqbx9+rw+ # F2gBdgo4j7CVomP49sS7CbqsdybbiOGpB9DJhs5QVMpYV73TVV3IwLiBHBECrTgU # fZVOMF0KSEq2zk/LsfvehswavE3W4aBXJmGjgWSpcDz+6TqeTM8f1DIcgQPdz0IY # gnT3yFTgiDbFGOFNt6eCidxdR6j9x+kpcN5RwApy4pRhE10YOV/xafBvKpRuWPjO # PWRBlKdm53kS2aMh08spx7xSEqXn4QQldCnUWRz3Lki+TgBlpwYwJUbR77DAayNw # AANE7taBrz2v+MnnogMrvvct0iwvfIA1W8kp155Lo44SIfqGmrbJP6Mn+Udr3MR2 # oWozAgMBAAGjggGOMIIBijAfBgNVHSMEGDAWgBRfWO1MMXqiYUKNUoC6s2GXGaIy # mzAdBgNVHQ4EFgQUiGGMoSo3ZIEoYKGbMdCM/SwCzk8wDgYDVR0PAQH/BAQDAgbA # MAwGA1UdEwEB/wQCMAAwFgYDVR0lAQH/BAwwCgYIKwYBBQUHAwgwSgYDVR0gBEMw # QTA1BgwrBgEEAbIxAQIBAwgwJTAjBggrBgEFBQcCARYXaHR0cHM6Ly9zZWN0aWdv # LmNvbS9DUFMwCAYGZ4EMAQQCMEoGA1UdHwRDMEEwP6A9oDuGOWh0dHA6Ly9jcmwu # c2VjdGlnby5jb20vU2VjdGlnb1B1YmxpY1RpbWVTdGFtcGluZ0NBUjM2LmNybDB6 # BggrBgEFBQcBAQRuMGwwRQYIKwYBBQUHMAKGOWh0dHA6Ly9jcnQuc2VjdGlnby5j # b20vU2VjdGlnb1B1YmxpY1RpbWVTdGFtcGluZ0NBUjM2LmNydDAjBggrBgEFBQcw # AYYXaHR0cDovL29jc3Auc2VjdGlnby5jb20wDQYJKoZIhvcNAQEMBQADggGBAAKB # PqSGclEh+WWpLj1SiuHlm8xLE0SThI2yLuq+75s11y6SceBchpnKpxWaGtXc8dya # 1Aq3RuW//y3wMThsvT4fSba2AoSWlR67rA4fTYGMIhgzocsids0ct/pHaocLVJSw # nTYxY2pE0hPoZAvRebctbsTqENmZHyOVjOFlwN2R3DRweFeNs4uyZN5LRJ5EnVYl # cTOq3bl1tI5poru9WaQRWQ4eynXp7Pj0Fz4DKr86HYECRJMWiDjeV0QqAcQMFsIj # JtrYTw7mU81qf4FBc4u4swphLeKRNyn9DDrd3HIMJ+CpdhSHEGleeZ5I79YDg3B3 # A/fmVY2GaMik1Vm+FajEMv4/EN2mmHf4zkOuhYZNzVm4NrWJeY4UAriLBOeVYODd # A1GxFr1ycbcUEGlUecc4RCPgYySs4d00NNuicR4a9n7idJlevAJbha/arIYMEuUq # TeRRbWkhJwMKmb9yEvppRudKyu1t6l21sIuIZqcpVH8oLWCxHS0LpDRF9Y4jijCC # BhQwggP8oAMCAQICEHojrtpTaZYPkcg+XPTH4z8wDQYJKoZIhvcNAQEMBQAwVzEL # MAkGA1UEBhMCR0IxGDAWBgNVBAoTD1NlY3RpZ28gTGltaXRlZDEuMCwGA1UEAxMl # U2VjdGlnbyBQdWJsaWMgVGltZSBTdGFtcGluZyBSb290IFI0NjAeFw0yMTAzMjIw # MDAwMDBaFw0zNjAzMjEyMzU5NTlaMFUxCzAJBgNVBAYTAkdCMRgwFgYDVQQKEw9T # ZWN0aWdvIExpbWl0ZWQxLDAqBgNVBAMTI1NlY3RpZ28gUHVibGljIFRpbWUgU3Rh # bXBpbmcgQ0EgUjM2MIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIBigKCAYEAzZjY # Q0GrboIr7PYzfiY05ImM0+8iEoBUPu8mr4wOgYPjoiIz5vzf7d5wu8GFK1JWN5hc # iN9rdqOhbdxLcSVwnOTJmUGfAMQm4eXOls3iQwfapEFWuOsYmBKXPNSpwZAFoLGl # 5y1EaGGc5LByM8wjcbSF52/Z42YaJRsPXY545E3QAPN2mxDh0OLozhiGgYT1xtjX # VfEzYBVmfQaI5QL35cTTAjsJAp85R+KAsOfuL9Z7LFnjdcuPkZWjssMETFIueH69 # rxbFOUD64G+rUo7xFIdRAuDNvWBsv0iGDPGaR2nZlY24tz5fISYk1sPY4gir99aX # AGnoo0vX3Okew4MsiyBn5ZnUDMKzUcQrpVavGacrIkmDYu/bcOUR1mVBIZ0X7P4b # Kf38JF7Mp7tY3LFF/h7hvBS2tgTYXlD7TnIMPrxyXCfB5yQq3FFoXRXM3/DvqQ4s # hoVWF/mwwz9xoRku05iphp22fTfjKRIVpm4gFT24JKspEpM8mFa9eTgKWWCvAgMB # AAGjggFcMIIBWDAfBgNVHSMEGDAWgBT2d2rdP/0BE/8WoWyCAi/QCj0UJTAdBgNV # HQ4EFgQUX1jtTDF6omFCjVKAurNhlxmiMpswDgYDVR0PAQH/BAQDAgGGMBIGA1Ud # EwEB/wQIMAYBAf8CAQAwEwYDVR0lBAwwCgYIKwYBBQUHAwgwEQYDVR0gBAowCDAG # BgRVHSAAMEwGA1UdHwRFMEMwQaA/oD2GO2h0dHA6Ly9jcmwuc2VjdGlnby5jb20v # U2VjdGlnb1B1YmxpY1RpbWVTdGFtcGluZ1Jvb3RSNDYuY3JsMHwGCCsGAQUFBwEB # BHAwbjBHBggrBgEFBQcwAoY7aHR0cDovL2NydC5zZWN0aWdvLmNvbS9TZWN0aWdv # UHVibGljVGltZVN0YW1waW5nUm9vdFI0Ni5wN2MwIwYIKwYBBQUHMAGGF2h0dHA6 # Ly9vY3NwLnNlY3RpZ28uY29tMA0GCSqGSIb3DQEBDAUAA4ICAQAS13sgrQ41WAye # gR0lWP1MLWd0r8diJiH2VVRpxqFGhnZbaF+IQ7JATGceTWOS+kgnMAzGYRzpm8jI # cjlSQ8JtcqymKhgx1s6cFZBSfvfeoyigF8iCGlH+SVSo3HHr98NepjSFJTU5KSRK # K+3nVSWYkSVQgJlgGh3MPcz9IWN4I/n1qfDGzqHCPWZ+/Mb5vVyhgaeqxLPbBIqv # 6cM74Nvyo1xNsllECJJrOvsrJQkajVz4xJwZ8blAdX5umzwFfk7K/0K3fpjgiXpq # NOpXaJ+KSRW0HdE0FSDC7+ZKJJSJx78mn+rwEyT+A3z7Ss0gT5CpTrcmhUwIw9jb # vnYuYRKxFVWjKklW3z83epDVzoWJttxFpujdrNmRwh1YZVIB2guAAjEQoF42H0BA # 7WBCueHVMDyV1e4nM9K4As7PVSNvQ8LI1WRaTuGSFUd9y8F8jw22BZC6mJoB40d7 # SlZIYfaildlgpgbgtu6SDsek2L8qomG57Yp5qTqof0DwJ4Q4HsShvRl/59T4IJBo # vRwmqWafH0cIPEX7cEttS5+tXrgRtMjjTOp6A9l0D6xcKZtxnLqiTH9KPCy6xZEi # 0UDcMTww5Fl4VvoGbMG2oonuX3f1tsoHLaO/Fwkj3xVr3lDkmeUqivebQTvGkx5h # GuJaSVQ+x60xJ/Y29RBr8Tm9XJ59AjCCBoIwggRqoAMCAQICEDbCsL18Gzrno7Pd # NsvJdWgwDQYJKoZIhvcNAQEMBQAwgYgxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpO # ZXcgSmVyc2V5MRQwEgYDVQQHEwtKZXJzZXkgQ2l0eTEeMBwGA1UEChMVVGhlIFVT # RVJUUlVTVCBOZXR3b3JrMS4wLAYDVQQDEyVVU0VSVHJ1c3QgUlNBIENlcnRpZmlj # YXRpb24gQXV0aG9yaXR5MB4XDTIxMDMyMjAwMDAwMFoXDTM4MDExODIzNTk1OVow # VzELMAkGA1UEBhMCR0IxGDAWBgNVBAoTD1NlY3RpZ28gTGltaXRlZDEuMCwGA1UE # AxMlU2VjdGlnbyBQdWJsaWMgVGltZSBTdGFtcGluZyBSb290IFI0NjCCAiIwDQYJ # KoZIhvcNAQEBBQADggIPADCCAgoCggIBAIid2LlFZ50d3ei5JoGaVFTAfEkFm8xa # FQ/ZlBBEtEFAgXcUmanU5HYsyAhTXiDQkiUvpVdYqZ1uYoZEMgtHES1l1Cc6HaqZ # zEbOOp6YiTx63ywTon434aXVydmhx7Dx4IBrAou7hNGsKioIBPy5GMN7KmgYmuu4 # f92sKKjbxqohUSfjk1mJlAjthgF7Hjx4vvyVDQGsd5KarLW5d73E3ThobSkob2SL # 48LpUR/O627pDchxll+bTSv1gASn/hp6IuHJorEu6EopoB1CNFp/+HpTXeNARXUm # dRMKbnXWflq+/g36NJXB35ZvxQw6zid61qmrlD/IbKJA6COw/8lFSPQwBP1ityZd # wuCysCKZ9ZjczMqbUcLFyq6KdOpuzVDR3ZUwxDKL1wCAxgL2Mpz7eZbrb/JWXiOc # NzDpQsmwGQ6Stw8tTCqPumhLRPb7YkzM8/6NnWH3T9ClmcGSF22LEyJYNWCHrQqY # ubNeKolzqUbCqhSqmr/UdUeb49zYHr7ALL8bAJyPDmubNqMtuaobKASBqP84uhqc # RY/pjnYd+V5/dcu9ieERjiRKKsxCG1t6tG9oj7liwPddXEcYGOUiWLm742st50jG # wTzxbMpepmOP1mLnJskvZaN5e45NuzAHteORlsSuDt5t4BBRCJL+5EZnnw0ezntk # 9R8QJyAkL6/bAgMBAAGjggEWMIIBEjAfBgNVHSMEGDAWgBRTeb9aqitKz1SA4dib # wJ3ysgNmyzAdBgNVHQ4EFgQU9ndq3T/9ARP/FqFsggIv0Ao9FCUwDgYDVR0PAQH/ # BAQDAgGGMA8GA1UdEwEB/wQFMAMBAf8wEwYDVR0lBAwwCgYIKwYBBQUHAwgwEQYD # VR0gBAowCDAGBgRVHSAAMFAGA1UdHwRJMEcwRaBDoEGGP2h0dHA6Ly9jcmwudXNl # cnRydXN0LmNvbS9VU0VSVHJ1c3RSU0FDZXJ0aWZpY2F0aW9uQXV0aG9yaXR5LmNy # bDA1BggrBgEFBQcBAQQpMCcwJQYIKwYBBQUHMAGGGWh0dHA6Ly9vY3NwLnVzZXJ0 # cnVzdC5jb20wDQYJKoZIhvcNAQEMBQADggIBAA6+ZUHtaES45aHF1BGH5Lc7JYzr # ftrIF5Ht2PFDxKKFOct/awAEWgHQMVHol9ZLSyd/pYMbaC0IZ+XBW9xhdkkmUV/K # bUOiL7g98M/yzRyqUOZ1/IY7Ay0YbMniIibJrPcgFp73WDnRDKtVutShPSZQZAdt # FwXnuiWl8eFARK3PmLqEm9UsVX+55DbVIz33Mbhba0HUTEYv3yJ1fwKGxPBsP/Mg # TECimh7eXomvMm0/GPxX2uhwCcs/YLxDnBdVVlxvDjHjO1cuwbOpkiJGHmLXXVNb # sdXUC2xBrq9fLrfe8IBsA4hopwsCj8hTuwKXJlSTrZcPRVSccP5i9U28gZ7OMzoJ # GlxZ5384OKm0r568Mo9TYrqzKeKZgFo0fj2/0iHbj55hc20jfxvK3mQi+H7xpbzx # ZOFGm/yVQkpo+ffv5gdhp+hv1GDsvJOtJinJmgGbBFZIThbqI+MHvAmMmkfb3fTx # mSkop2mSJL1Y2x/955S29Gu0gSJIkc3z30vU/iXrMpWx2tS7UVfVP+5tKuzGtgkP # 7d/doqDrLF1u6Ci3TpjAZdeLLlRQZm867eVeXED58LXd1Dk6UvaAhvmWYXoiLz4J # A5gPBcz7J311uahxCweNxE+xxxR3kT0WKzASo5G/PyDez6NHdIUKBeE3jDPs2ACc # 6CkJ1Sji4PKWVT0/MYIEkjCCBI4CAQEwajBVMQswCQYDVQQGEwJHQjEYMBYGA1UE # ChMPU2VjdGlnbyBMaW1pdGVkMSwwKgYDVQQDEyNTZWN0aWdvIFB1YmxpYyBUaW1l # IFN0YW1waW5nIENBIFIzNgIRAKQpO24e3denNAiHrXpOtyQwDQYJYIZIAWUDBAIC # BQCgggH5MBoGCSqGSIb3DQEJAzENBgsqhkiG9w0BCRABBDAcBgkqhkiG9w0BCQUx # DxcNMjYwMzE2MDgxMTI4WjA/BgkqhkiG9w0BCQQxMgQwVIwfRZkx4Ea4Tc+Qaq1s # SBo57YSMZjK/HhZBi6w0mr0yaD7G4VxBgv2Pv8JxG3qsMIIBegYLKoZIhvcNAQkQ # AgwxggFpMIIBZTCCAWEwFgQUOMkUgRBEtNxmPpPUdEuBQYaptbEwgYcEFMauVOR4 # hvF8PVUSSIxpw0p6+cLdMG8wW6RZMFcxCzAJBgNVBAYTAkdCMRgwFgYDVQQKEw9T # ZWN0aWdvIExpbWl0ZWQxLjAsBgNVBAMTJVNlY3RpZ28gUHVibGljIFRpbWUgU3Rh # bXBpbmcgUm9vdCBSNDYCEHojrtpTaZYPkcg+XPTH4z8wgbwEFIU9Yy2TgoJhfNCQ # NcSR3pLBQtrHMIGjMIGOpIGLMIGIMQswCQYDVQQGEwJVUzETMBEGA1UECBMKTmV3 # IEplcnNleTEUMBIGA1UEBxMLSmVyc2V5IENpdHkxHjAcBgNVBAoTFVRoZSBVU0VS # VFJVU1QgTmV0d29yazEuMCwGA1UEAxMlVVNFUlRydXN0IFJTQSBDZXJ0aWZpY2F0 # aW9uIEF1dGhvcml0eQIQNsKwvXwbOuejs902y8l1aDANBgkqhkiG9w0BAQEFAASC # AgCgF6Qa7p6Cpr41ZUOgPGciV/HioGdqMApwNN4EmKY+t1zA5dtQQ7+GxkBwuFW0 # RBzNfEunhI5A6QNOBLmWuC8Azl2wdvDdr6THaQS6zCLp8V2lCWzaa1qS8oJt73WF # ++BuNsVZMGK3kFQHpl5EhDoGFVFuYHHmyHSIINfwHLKQymhqUACNGW5+uXYjfVLz # a3PXPM1J10GTpXYqelCXhYv7XVy+hsdwQJC71OySVmHetucoMIajaXxiF0hY15jp # Euxp0QSWZzwXnJtUqUibH5WrgzaMvJqSERIphcpthXVHNzSEtzFpO7aUgnwhubFt # 6wNtGfgd6t4cGVRV/I+qHHNogAC5WMElUkitxGeaDX4mGX2W3UKI7D/z4xZkrC/v # wNNX1fEcPUNt1LX41iujtfBA19BVAHh2JTy7xQ2E/SUUns6Efzbcn+l3D4TfJcdi # /6D4tKBn3qHFdZLKIj3V91mkQIx9Zyy2uusa/cNEWcZF1FBi+ZrNLKD5mRv54jI6 # b7QIYMhjZHKi8SnoB21vMRagy5VTS6Vx0ST2/xaL4Wa7bcKF5V7mXKUmM6NwNLBc # CG8xHVRdFn6Pb8Cgbjnj7/CIjvpeNk1qiCmExEEJZkUldl4Th+wvsFM+6l10VGv3 # G2z2facRUHoceqQcd+KB26g+ORtcXIg4xG1211WnR1rAcw== # SIG # End signature block |