Classes/GraphSession.ps1
|
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidUsingConvertToSecureStringWithPlainText', '')] class GraphSession { static [string] $GraphEndpoint = 'https://graph.microsoft.com/v1.0' static [string] $PublicClientId = '14d82eec-204b-4c2f-b7e8-296a70dab67e' static [int] $MaxRetries = 5 static [int] $MaxRetrySeconds = 600 static [string[]] $RequiredScopes = @( 'Policy.Read.All','Policy.Read.AuthenticationMethod','Application.Read.All', 'GroupMember.Read.All','RoleManagement.Read.Directory','AuditLog.Read.All', 'User.Read.All','IdentityRiskyUser.Read.All','IdentityRiskEvent.Read.All' ) hidden [string] $_tenantId hidden [securestring] $_token hidden [datetime] $_tokenExpiry = [datetime]::MinValue hidden [int] $_totalResourceUnits = 0 # Plaintext cache (30s TTL) hidden [string] $_tokenPlainCache hidden [datetime] $_tokenCacheExpiry = [datetime]::MinValue # Response cache hidden [hashtable] $_responseCache = @{} GraphSession([string]$tenantId) { if ($tenantId -notmatch '^[a-zA-Z0-9][a-zA-Z0-9._-]*\.[a-zA-Z]{2,}$' -and $tenantId -notmatch '^[0-9a-fA-F]{8}-([0-9a-fA-F]{4}-){3}[0-9a-fA-F]{12}$') { throw [System.ArgumentException]::new( "TenantId must be a valid domain (contoso.onmicrosoft.com) or GUID.", 'tenantId') } $this._tenantId = $tenantId } [void] Authenticate() { $transcriptSuspended = $false try { $null = Stop-Transcript -ErrorAction Stop; $transcriptSuspended = $true } catch { } try { $this._AuthenticateCore() } finally { if ($transcriptSuspended) { Write-Warning 'Transcript was paused during authentication to protect the device code. Run Start-Transcript to resume.' } } } hidden [void] _AuthenticateCore() { $body = @{ client_id = [GraphSession]::PublicClientId scope = ([GraphSession]::RequiredScopes + @('offline_access')) -join ' ' } $dcResponse = Invoke-RestMethod -Method Post ` -Uri "https://login.microsoftonline.com/$($this._tenantId)/oauth2/v2.0/devicecode" ` -Body $body -ContentType 'application/x-www-form-urlencoded' -ErrorAction Stop # OS detection via .NET: automatic vars ($IsMacOS/$IsLinux) are not # accessible inside class methods, so resolve to local variables here. $isMac = [System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform([System.Runtime.InteropServices.OSPlatform]::OSX) $isLin = [System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform([System.Runtime.InteropServices.OSPlatform]::Linux) $clipboardOk = $false try { if ($isMac) { $dcResponse.user_code | & '/usr/bin/pbcopy'; $clipboardOk = $? } elseif ($isLin) { if (Get-Command xclip -ErrorAction SilentlyContinue) { $dcResponse.user_code | & xclip -selection clipboard; $clipboardOk = $? } elseif (Get-Command xsel -ErrorAction SilentlyContinue) { $dcResponse.user_code | & xsel --clipboard --input; $clipboardOk = $? } } else { Set-Clipboard -Value $dcResponse.user_code; $clipboardOk = $true } } catch { $clipboardOk = $false } if ($clipboardOk) { Write-Host "`n Code $($dcResponse.user_code) copied to clipboard." -ForegroundColor Cyan } else { Write-Host "`n Enter this code to sign in: $($dcResponse.user_code)" -ForegroundColor Cyan } Write-Host " Verify the URL is: $($dcResponse.verification_uri)" -ForegroundColor Yellow Write-Host " (Storm-2372 advisory: confirm the hostname before authenticating)" -ForegroundColor DarkGray Write-Host " Press Ctrl+C to cancel.`n" -ForegroundColor DarkGray try { if ($isMac) { & '/usr/bin/open' $dcResponse.verification_uri } elseif ($isLin) { & 'xdg-open' $dcResponse.verification_uri } else { Start-Process $dcResponse.verification_uri } } catch { Write-Host " Open this URL manually: $($dcResponse.verification_uri)" -ForegroundColor White } $interval = [math]::Max([int]$dcResponse.interval, 5) $maxWait = [math]::Min($dcResponse.expires_in, 300) $deadline = [datetime]::UtcNow.AddSeconds($maxWait) $pollBody = @{ grant_type = 'urn:ietf:params:oauth:grant-type:device_code' client_id = [GraphSession]::PublicClientId device_code = $dcResponse.device_code } $start = [datetime]::UtcNow while ([datetime]::UtcNow -lt $deadline) { $elapsed = [math]::Round(([datetime]::UtcNow - $start).TotalSeconds) $pct = [math]::Min(99, [math]::Round(($elapsed / $maxWait) * 100)) Write-Progress -Activity 'Waiting for authentication' -PercentComplete $pct Start-Sleep -Seconds $interval try { $tr = Invoke-RestMethod -Method Post ` -Uri "https://login.microsoftonline.com/$($this._tenantId)/oauth2/v2.0/token" ` -Body $pollBody -ContentType 'application/x-www-form-urlencoded' -ErrorAction Stop $this._token = ConvertTo-SecureString -String $tr.access_token -AsPlainText -Force $this._tokenExpiry = [datetime]::UtcNow.AddSeconds($tr.expires_in - 120) foreach ($prop in @('access_token','refresh_token','id_token')) { if ($tr.PSObject.Properties[$prop]) { $tr.$prop = $null } } Remove-Variable tr -ErrorAction SilentlyContinue Write-Progress -Activity 'Waiting for authentication' -Completed Write-Host ' Authenticated.' -ForegroundColor Green return } catch { $errMsg = if ($_.ErrorDetails -and $_.ErrorDetails.Message) { $_.ErrorDetails.Message } else { $null } $err = $null if ($errMsg) { try { $err = $errMsg | ConvertFrom-Json } catch { $err = $null } } if ($null -ne $err -and $err.error -eq 'authorization_pending') { continue } if ($null -ne $err -and $err.error -eq 'slow_down') { $interval += 5; continue } if ($null -ne $err -and $err.error -eq 'authorization_declined') { Write-Progress -Activity 'Waiting for authentication' -Completed throw 'Authentication was declined by the user.' } if ($null -ne $err -and $err.error -eq 'expired_token') { Write-Progress -Activity 'Waiting for authentication' -Completed throw 'Device code expired before authentication was completed.' } throw $_ } } Write-Progress -Activity 'Waiting for authentication' -Completed throw 'Authentication timed out. The device code was not completed in time.' } hidden [string] MarshalToken() { if ([datetime]::UtcNow -ge $this._tokenExpiry) { throw [System.InvalidOperationException]::new('Access token expired. Run Connect-NsSession to re-authenticate.') } if ($this._tokenPlainCache -and [datetime]::UtcNow -lt $this._tokenCacheExpiry) { return $this._tokenPlainCache } $bstr = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($this._token) try { $this._tokenPlainCache = [System.Runtime.InteropServices.Marshal]::PtrToStringBSTR($bstr) $this._tokenCacheExpiry = [datetime]::UtcNow.AddSeconds(30) return $this._tokenPlainCache } finally { [System.Runtime.InteropServices.Marshal]::ZeroFreeBSTR($bstr) } } hidden [hashtable] BuildHeaders() { return @{ Authorization = "Bearer $($this.MarshalToken())" ConsistencyLevel = 'eventual' 'client-request-id' = [guid]::NewGuid().ToString() } } hidden [object] InvokeWithRetry([string]$method, [string]$uri, [object]$body) { $attempt = 0; $totalWait = 0 while ($true) { $attempt++ $headers = $this.BuildHeaders() try { $params = @{ Method = $method; Uri = $uri; Headers = $headers; ErrorAction = 'Stop' } if ($body) { $params['Body'] = ($body | ConvertTo-Json -Depth 10 -Compress) $params['ContentType'] = 'application/json' } $respHeaders = $null $response = Invoke-RestMethod @params -ResponseHeadersVariable 'respHeaders' if ($respHeaders -and $respHeaders.ContainsKey('x-ms-resource-unit')) { $ru = [int]$respHeaders['x-ms-resource-unit'][0] $this._totalResourceUnits += $ru } Write-Debug "Graph $method $uri OK [request-id=$($headers['client-request-id'])]" return $response } catch { $status = 0 if ($_.Exception.Response) { $status = [int]$_.Exception.Response.StatusCode } $retryable = $status -in @(429, 503, 504) if (-not $retryable -or $attempt -gt [GraphSession]::MaxRetries) { throw } $waitSec = [math]::Pow(2, $attempt) if ($_.Exception.Response -and $_.Exception.Response.Headers) { try { $raValues = $_.Exception.Response.Headers.GetValues('Retry-After') if ($raValues -and $raValues.Count -gt 0) { $waitSec = [math]::Max($waitSec, [int]$raValues[0]) } } catch { } } $jitter = Get-Random -Minimum 100 -Maximum 800 $waitMs = ([int]($waitSec * 1000)) + $jitter $totalWait += ($waitMs / 1000) if ($totalWait -gt [GraphSession]::MaxRetrySeconds) { throw } Write-Verbose "Graph throttled ($status). Retry $attempt/$([GraphSession]::MaxRetries) in $([math]::Round($waitMs/1000,1))s" Start-Sleep -Milliseconds $waitMs } } return $null } # Cached GET [object] Get([string]$path) { $uri = if ($path.StartsWith('http')) { $path } else { "$([GraphSession]::GraphEndpoint)$path" } if ($this._responseCache.ContainsKey($uri)) { Write-Debug "Graph cache HIT: $uri" return $this._responseCache[$uri] } $result = $this.InvokeWithRetry('GET', $uri, $null) $this._responseCache[$uri] = $result return $result } # Uncached GET [object] GetFresh([string]$path) { $uri = if ($path.StartsWith('http')) { $path } else { "$([GraphSession]::GraphEndpoint)$path" } return $this.InvokeWithRetry('GET', $uri, $null) } [object[]] GetAll([string]$path) { $results = [System.Collections.ArrayList]::new() $uri = if ($path.StartsWith('http')) { $path } else { "$([GraphSession]::GraphEndpoint)$path" } while ($uri) { $response = $this.InvokeWithRetry('GET', $uri, $null) if ($response.value) { $results.AddRange([object[]]$response.value) } $uri = $response.'@odata.nextLink' } return $results.ToArray() } [void] GetAllPaged([string]$path, [scriptblock]$pageHandler) { $uri = if ($path.StartsWith('http')) { $path } else { "$([GraphSession]::GraphEndpoint)$path" } while ($uri) { $response = $this.InvokeWithRetry('GET', $uri, $null) if ($response.value) { & $pageHandler $response.value } $uri = $response.'@odata.nextLink' } } [object[]] BatchResolve([string[]]$ids) { if ($ids.Count -eq 0) { return @() } $resolved = [System.Collections.ArrayList]::new() for ($i = 0; $i -lt $ids.Count; $i += 1000) { $end = [math]::Min($i + 1000, $ids.Count) $chunk = $ids[$i..($end - 1)] $body = @{ ids = $chunk; types = @('user','group','servicePrincipal','application','device') } $response = $this.InvokeWithRetry('POST', "$([GraphSession]::GraphEndpoint)/directoryObjects/getByIds", $body) if ($response.value) { $resolved.AddRange([object[]]$response.value) } } return $resolved.ToArray() } [void] ClearCache() { $this._responseCache.Clear() } [string[]] GetGrantedScopes() { $plain = $this.MarshalToken() $parts = $plain.Split('.') if ($parts.Count -lt 2) { return @() } $payload = $parts[1] # Fix base64url padding switch ($payload.Length % 4) { 2 { $payload += '==' } 3 { $payload += '=' } } $payload = $payload.Replace('-','+').Replace('_','/') try { $json = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($payload)) | ConvertFrom-Json if ($json.scp) { return @($json.scp -split '\s+') } return @() } catch { return @() } } [void] Dispose() { $this._tokenPlainCache = $null $this._tokenCacheExpiry = [datetime]::MinValue $this._responseCache.Clear() if ($this._token) { $this._token.Dispose(); $this._token = $null } } } # SIG # Begin signature block # MII9FgYJKoZIhvcNAQcCoII9BzCCPQMCAQExDzANBglghkgBZQMEAgEFADB5Bgor # BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG # KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCA1gu4xMkggwy73 # 3H6l9NlGsD1pC625zx8p0+xK2aTdZ6CCIdwwggXMMIIDtKADAgECAhBUmNLR1FsZ # lUgTecgRwIeZMA0GCSqGSIb3DQEBDAUAMHcxCzAJBgNVBAYTAlVTMR4wHAYDVQQK # ExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xSDBGBgNVBAMTP01pY3Jvc29mdCBJZGVu # dGl0eSBWZXJpZmljYXRpb24gUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgMjAy # MDAeFw0yMDA0MTYxODM2MTZaFw00NTA0MTYxODQ0NDBaMHcxCzAJBgNVBAYTAlVT # MR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xSDBGBgNVBAMTP01pY3Jv # c29mdCBJZGVudGl0eSBWZXJpZmljYXRpb24gUm9vdCBDZXJ0aWZpY2F0ZSBBdXRo # b3JpdHkgMjAyMDCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBALORKgeD # Bmf9np3gx8C3pOZCBH8Ppttf+9Va10Wg+3cL8IDzpm1aTXlT2KCGhFdFIMeiVPvH # or+Kx24186IVxC9O40qFlkkN/76Z2BT2vCcH7kKbK/ULkgbk/WkTZaiRcvKYhOuD # PQ7k13ESSCHLDe32R0m3m/nJxxe2hE//uKya13NnSYXjhr03QNAlhtTetcJtYmrV # qXi8LW9J+eVsFBT9FMfTZRY33stuvF4pjf1imxUs1gXmuYkyM6Nix9fWUmcIxC70 # ViueC4fM7Ke0pqrrBc0ZV6U6CwQnHJFnni1iLS8evtrAIMsEGcoz+4m+mOJyoHI1 # vnnhnINv5G0Xb5DzPQCGdTiO0OBJmrvb0/gwytVXiGhNctO/bX9x2P29Da6SZEi3 # W295JrXNm5UhhNHvDzI9e1eM80UHTHzgXhgONXaLbZ7LNnSrBfjgc10yVpRnlyUK # xjU9lJfnwUSLgP3B+PR0GeUw9gb7IVc+BhyLaxWGJ0l7gpPKWeh1R+g/OPTHU3mg # trTiXFHvvV84wRPmeAyVWi7FQFkozA8kwOy6CXcjmTimthzax7ogttc32H83rwjj # O3HbbnMbfZlysOSGM1l0tRYAe1BtxoYT2v3EOYI9JACaYNq6lMAFUSw0rFCZE4e7 # swWAsk0wAly4JoNdtGNz764jlU9gKL431VulAgMBAAGjVDBSMA4GA1UdDwEB/wQE # AwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTIftJqhSobyhmYBAcnz1AQ # T2ioojAQBgkrBgEEAYI3FQEEAwIBADANBgkqhkiG9w0BAQwFAAOCAgEAr2rd5hnn # LZRDGU7L6VCVZKUDkQKL4jaAOxWiUsIWGbZqWl10QzD0m/9gdAmxIR6QFm3FJI9c # Zohj9E/MffISTEAQiwGf2qnIrvKVG8+dBetJPnSgaFvlVixlHIJ+U9pW2UYXeZJF # xBA2CFIpF8svpvJ+1Gkkih6PsHMNzBxKq7Kq7aeRYwFkIqgyuH4yKLNncy2RtNwx # AQv3Rwqm8ddK7VZgxCwIo3tAsLx0J1KH1r6I3TeKiW5niB31yV2g/rarOoDXGpc8 # FzYiQR6sTdWD5jw4vU8w6VSp07YEwzJ2YbuwGMUrGLPAgNW3lbBeUU0i/OxYqujY # lLSlLu2S3ucYfCFX3VVj979tzR/SpncocMfiWzpbCNJbTsgAlrPhgzavhgplXHT2 # 6ux6anSg8Evu75SjrFDyh+3XOjCDyft9V77l4/hByuVkrrOj7FjshZrM77nq81YY # uVxzmq/FdxeDWds3GhhyVKVB0rYjdaNDmuV3fJZ5t0GNv+zcgKCf0Xd1WF81E+Al # GmcLfc4l+gcK5GEh2NQc5QfGNpn0ltDGFf5Ozdeui53bFv0ExpK91IjmqaOqu/dk # ODtfzAzQNb50GQOmxapMomE2gj4d8yu8l13bS3g7LfU772Aj6PXsCyM2la+YZr9T # 03u4aUoqlmZpxJTG9F9urJh4iIAGXKKy7aIwggabMIIEg6ADAgECAhMzAAGSX9Z/ # ePB9sQgIAAAAAZJfMA0GCSqGSIb3DQEBDAUAMFoxCzAJBgNVBAYTAlVTMR4wHAYD # VQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xKzApBgNVBAMTIk1pY3Jvc29mdCBJ # RCBWZXJpZmllZCBDUyBFT0MgQ0EgMDQwHhcNMjYwNjAxMTc1MjU4WhcNMjYwNjA0 # MTc1MjU4WjBfMQswCQYDVQQGEwJDQTEQMA4GA1UECBMHQWxiZXJ0YTEQMA4GA1UE # BxMHQ2FsZ2FyeTEVMBMGA1UEChMMRGFycmVuIE1heWVzMRUwEwYDVQQDEwxEYXJy # ZW4gTWF5ZXMwggGiMA0GCSqGSIb3DQEBAQUAA4IBjwAwggGKAoIBgQC6vpd+d66I # l6cpo6XDaTIvujkV3rekVoeig10+dG/OTYmX57PD3Rum9xsPx2BdX8lzvGnQq7Pa # v6KacGC8N9f5XmVTJhc8k341QPXbSVsj61bYPVcV3ZnEr5zX2ciTGqXOgN/woD1A # QccrGB8mCfWn9sNyVRTzNtoJz3/BrZl2Au+4nK2clIPX1a1k/6r2wTeFiBFAh7fp # GZUHRNl0rcAzogwi5qYykxCDz7Wzu73tuUfhxcbn2XzoqfqKd83VSIN+osxnOmrS # 0vMT5gnJC4B8RAGoGIqOle4wexQOn1Zrx8B2l1ZaIyLWf8bhcugcvTDT6o/oC1VV # CVQqymqGTAhyIfIMSV31wMQDmEyXpa9SQFV3A4rUL+ILNDTGcca8GFZ6a1kqRe83 # xM/LTqupi6OSQ8ruxEHzJsW3No7J4rsNRljjSf7MGXFrKQjPBVFnjN2tHOPShdYB # Z60NS6q6pVj+xq5FBVGHzV8XtKdV0e3jigsEyXkEl0jcQ8/K2LIxphMCAwEAAaOC # AdMwggHPMAwGA1UdEwEB/wQCMAAwDgYDVR0PAQH/BAQDAgeAMDoGA1UdJQQzMDEG # CisGAQQBgjdhAQAGCCsGAQUFBwMDBhkrBgEEAYI3YYuPpXGB3qaBQNv/tAST5rkV # MB0GA1UdDgQWBBSvmzOJzfqlOfze0TuSX3fnqAlzZDAfBgNVHSMEGDAWgBSa8VR3 # dQyHFjdGoKzeefn0f8F46TBnBgNVHR8EYDBeMFygWqBYhlZodHRwOi8vd3d3Lm1p # Y3Jvc29mdC5jb20vcGtpb3BzL2NybC9NaWNyb3NvZnQlMjBJRCUyMFZlcmlmaWVk # JTIwQ1MlMjBFT0MlMjBDQSUyMDA0LmNybDB0BggrBgEFBQcBAQRoMGYwZAYIKwYB # BQUHMAKGWGh0dHA6Ly93d3cubWljcm9zb2Z0LmNvbS9wa2lvcHMvY2VydHMvTWlj # cm9zb2Z0JTIwSUQlMjBWZXJpZmllZCUyMENTJTIwRU9DJTIwQ0ElMjAwNC5jcnQw # VAYDVR0gBE0wSzBJBgRVHSAAMEEwPwYIKwYBBQUHAgEWM2h0dHA6Ly93d3cubWlj # cm9zb2Z0LmNvbS9wa2lvcHMvRG9jcy9SZXBvc2l0b3J5Lmh0bTANBgkqhkiG9w0B # AQwFAAOCAgEABRiO07jmU6SjeUNkagy4Me5BFFY3b/5L1BRn/Gf9C8kXZjlIyzMH # 7FcbslPw6ySkN3AIikz4rDwk8QQ+fc/dp+/ru35kqbbXm/bcK0AVjQ3ZOy8kRAjG # qmFJff56lydGk3ybw1KCBHYgSs9KXVxC45348w4T9pjSViDcGko8g4Z+m19GW7ov # 6srqiP72u5zVIwIHuxP/g08zaf2wynKz9duWzmZS8LftUawJI8il/5pLFjNBlCeJ # q4MWNfI4N4d1a2VCEhs12HLqax/C/PyQP3qRUI7PB5IfKYltajewMbYVw+rQDE4f # ugNEu14zUYPislGt36hd/Tk1Dn8uIT6P+9RyMyIX19bH9uTghE132/HEwuVNL34R # kxJYMIG+ESF6fs+G9RDkWyGAi1FlLWl6ptszZ8ThL22/Sc11b6FlR8s+pCnjSQ6T # KWnmWGEwoG43uqFXfLcchz2m8AEE3xvj+XpwkujUSrayTGy5E/olv946WtyEq4po # NlZsND6CbrWT6VNd4VvmrRbYZUThdX3wjrpBssSRY3a7T9ra9KyYFFeAFulbvdaq # o1DgPBVAWgbskiHEdkSrySbbhTHmCWltbGzlPU3kqTwSrjw0CUOfry9Ve7iYtitt # 6LVu6DqEOY/3TBfLnubeZyjd1LpkIQWPU4u9AA4d9L2SUKY5Ziyo+18wggabMIIE # g6ADAgECAhMzAAGSX9Z/ePB9sQgIAAAAAZJfMA0GCSqGSIb3DQEBDAUAMFoxCzAJ # BgNVBAYTAlVTMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xKzApBgNV # BAMTIk1pY3Jvc29mdCBJRCBWZXJpZmllZCBDUyBFT0MgQ0EgMDQwHhcNMjYwNjAx # MTc1MjU4WhcNMjYwNjA0MTc1MjU4WjBfMQswCQYDVQQGEwJDQTEQMA4GA1UECBMH # QWxiZXJ0YTEQMA4GA1UEBxMHQ2FsZ2FyeTEVMBMGA1UEChMMRGFycmVuIE1heWVz # MRUwEwYDVQQDEwxEYXJyZW4gTWF5ZXMwggGiMA0GCSqGSIb3DQEBAQUAA4IBjwAw # ggGKAoIBgQC6vpd+d66Il6cpo6XDaTIvujkV3rekVoeig10+dG/OTYmX57PD3Rum # 9xsPx2BdX8lzvGnQq7Pav6KacGC8N9f5XmVTJhc8k341QPXbSVsj61bYPVcV3ZnE # r5zX2ciTGqXOgN/woD1AQccrGB8mCfWn9sNyVRTzNtoJz3/BrZl2Au+4nK2clIPX # 1a1k/6r2wTeFiBFAh7fpGZUHRNl0rcAzogwi5qYykxCDz7Wzu73tuUfhxcbn2Xzo # qfqKd83VSIN+osxnOmrS0vMT5gnJC4B8RAGoGIqOle4wexQOn1Zrx8B2l1ZaIyLW # f8bhcugcvTDT6o/oC1VVCVQqymqGTAhyIfIMSV31wMQDmEyXpa9SQFV3A4rUL+IL # NDTGcca8GFZ6a1kqRe83xM/LTqupi6OSQ8ruxEHzJsW3No7J4rsNRljjSf7MGXFr # KQjPBVFnjN2tHOPShdYBZ60NS6q6pVj+xq5FBVGHzV8XtKdV0e3jigsEyXkEl0jc # Q8/K2LIxphMCAwEAAaOCAdMwggHPMAwGA1UdEwEB/wQCMAAwDgYDVR0PAQH/BAQD # AgeAMDoGA1UdJQQzMDEGCisGAQQBgjdhAQAGCCsGAQUFBwMDBhkrBgEEAYI3YYuP # pXGB3qaBQNv/tAST5rkVMB0GA1UdDgQWBBSvmzOJzfqlOfze0TuSX3fnqAlzZDAf # BgNVHSMEGDAWgBSa8VR3dQyHFjdGoKzeefn0f8F46TBnBgNVHR8EYDBeMFygWqBY # hlZodHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2NybC9NaWNyb3NvZnQl # MjBJRCUyMFZlcmlmaWVkJTIwQ1MlMjBFT0MlMjBDQSUyMDA0LmNybDB0BggrBgEF # BQcBAQRoMGYwZAYIKwYBBQUHMAKGWGh0dHA6Ly93d3cubWljcm9zb2Z0LmNvbS9w # a2lvcHMvY2VydHMvTWljcm9zb2Z0JTIwSUQlMjBWZXJpZmllZCUyMENTJTIwRU9D # JTIwQ0ElMjAwNC5jcnQwVAYDVR0gBE0wSzBJBgRVHSAAMEEwPwYIKwYBBQUHAgEW # M2h0dHA6Ly93d3cubWljcm9zb2Z0LmNvbS9wa2lvcHMvRG9jcy9SZXBvc2l0b3J5 # Lmh0bTANBgkqhkiG9w0BAQwFAAOCAgEABRiO07jmU6SjeUNkagy4Me5BFFY3b/5L # 1BRn/Gf9C8kXZjlIyzMH7FcbslPw6ySkN3AIikz4rDwk8QQ+fc/dp+/ru35kqbbX # m/bcK0AVjQ3ZOy8kRAjGqmFJff56lydGk3ybw1KCBHYgSs9KXVxC45348w4T9pjS # ViDcGko8g4Z+m19GW7ov6srqiP72u5zVIwIHuxP/g08zaf2wynKz9duWzmZS8Lft # UawJI8il/5pLFjNBlCeJq4MWNfI4N4d1a2VCEhs12HLqax/C/PyQP3qRUI7PB5If # KYltajewMbYVw+rQDE4fugNEu14zUYPislGt36hd/Tk1Dn8uIT6P+9RyMyIX19bH # 9uTghE132/HEwuVNL34RkxJYMIG+ESF6fs+G9RDkWyGAi1FlLWl6ptszZ8ThL22/ # Sc11b6FlR8s+pCnjSQ6TKWnmWGEwoG43uqFXfLcchz2m8AEE3xvj+XpwkujUSray # TGy5E/olv946WtyEq4poNlZsND6CbrWT6VNd4VvmrRbYZUThdX3wjrpBssSRY3a7 # T9ra9KyYFFeAFulbvdaqo1DgPBVAWgbskiHEdkSrySbbhTHmCWltbGzlPU3kqTwS # rjw0CUOfry9Ve7iYtitt6LVu6DqEOY/3TBfLnubeZyjd1LpkIQWPU4u9AA4d9L2S # UKY5Ziyo+18wggcoMIIFEKADAgECAhMzAAAAFydFCQuLh6/GAAAAAAAXMA0GCSqG # SIb3DQEBDAUAMGMxCzAJBgNVBAYTAlVTMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29y # cG9yYXRpb24xNDAyBgNVBAMTK01pY3Jvc29mdCBJRCBWZXJpZmllZCBDb2RlIFNp # Z25pbmcgUENBIDIwMjEwHhcNMjYwMzI2MTgxMTMxWhcNMzEwMzI2MTgxMTMxWjBa # MQswCQYDVQQGEwJVUzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSsw # KQYDVQQDEyJNaWNyb3NvZnQgSUQgVmVyaWZpZWQgQ1MgRU9DIENBIDA0MIICIjAN # BgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAgsdk/gMPZioBlcyfk6tDzJ+PRt4r # SLGKW8ewpS0kRxXtURC3T3GdbCKljobEn8ussqhGqQpRh/SXvRVwNXEIGb76UG5I # PkCJ1S6/9BD61QQsKzPepW0SNj8TXgsFxvS7MltoRuikIIp7Q5jQgaOM6QyK9++6 # ZVXUpYmZulAe6x8JrwZ0dNkE+rZ66lqtoocwepUSVUxM7odDmn8yDHjJ2DNPsfr3 # uRDix3X4qvh14jH/SW+2Cx7WIMhyIiQO201i6hUixmk4e2ZW8W7C1wPdTjq6BKb+ # zo8xbrt7ZKQvRX5QOA6dhLquPqj5sVKnxqfk19IC0SafTSTs8yC43Ew965BRRW8V # L9ccoOmr4rxQy7aCgYTNk3dd/LphNaTTmnGp7kmLTxyHkB5geoWhYuuGrywS8E0w # Jv0W4rfOtHBV0e9sKvuUIeIUpnsx6ilxEVj6VQXvgD6yeCKnPmj3jJiJKAlmUDtt # h5yzRVBUl44sMiG4L5R/yyACRKk2n088Q2YCoZS1O86+oMLKt1jaXGECOjbsVp8I # d1VQw8he6J0KirOS5e25XlTdGPFb6oBOOaacgW78Kjf0bp+XzAgkc92mDGNJGYSj # vdnj+7eMx6meW0DAIGdLRNj8/429MIspFBfz3KDqqpN71S4kQ2LLer3dxhDDczKV # FL0HLwRuOvgjiG8CAwEAAaOCAdwwggHYMA4GA1UdDwEB/wQEAwIBhjAQBgkrBgEE # AYI3FQEEAwIBADAdBgNVHQ4EFgQUmvFUd3UMhxY3RqCs3nn59H/BeOkwVAYDVR0g # BE0wSzBJBgRVHSAAMEEwPwYIKwYBBQUHAgEWM2h0dHA6Ly93d3cubWljcm9zb2Z0 # LmNvbS9wa2lvcHMvRG9jcy9SZXBvc2l0b3J5Lmh0bTAZBgkrBgEEAYI3FAIEDB4K # AFMAdQBiAEMAQTASBgNVHRMBAf8ECDAGAQH/AgEAMB8GA1UdIwQYMBaAFNlBKbAP # D2Ns72nX9c0pnqRIajDmMHAGA1UdHwRpMGcwZaBjoGGGX2h0dHA6Ly93d3cubWlj # cm9zb2Z0LmNvbS9wa2lvcHMvY3JsL01pY3Jvc29mdCUyMElEJTIwVmVyaWZpZWQl # MjBDb2RlJTIwU2lnbmluZyUyMFBDQSUyMDIwMjEuY3JsMH0GCCsGAQUFBwEBBHEw # bzBtBggrBgEFBQcwAoZhaHR0cDovL3d3dy5taWNyb3NvZnQuY29tL3BraW9wcy9j # ZXJ0cy9NaWNyb3NvZnQlMjBJRCUyMFZlcmlmaWVkJTIwQ29kZSUyMFNpZ25pbmcl # MjBQQ0ElMjAyMDIxLmNydDANBgkqhkiG9w0BAQwFAAOCAgEAkHVaGf1NJt/Jdoim # mRZbMWr6baaDi8mkdWvWStk0hdZDpxSYTA7HuipAoLL3qIhI101XOl7fOiCh5++j # ZOamQdAV79ojEUNoIgCZmL2XJrLaGanwdjNynecJyYVCTrRf2+h7KknpWOp4axdO # s6K9ZQ5g0IsQWXCwfc0dfkSkLKNY3pDcWLlJPh2jd5NUue6pNDv/2G5MFNJhCwlt # ODebyAjGceU+XOzav+7i721YQnQ+39m2aQOFO7zpAdaKAeAGhEd6Y6CdDGneSxco # ujWvafWbv4ay3jo1ORSLUuWMbKr5X18QE4Sde+gppGLLSkZsrUh2eyYSkX1envWX # 7ZPzg2/wiuKRlQFarDn+N9+20BqzhxwkNyLzfYJp1Lg4fCXb24XqFjx8SDdRgebF # ImOfOLVze8XQ/CwkrEaib0PHu2t4GVk4FYroEbNUFqvjdBvTY3uiR5TdQoyXoYHv # h+TxpLSY2vo7hhK9D/rpEpHC+qmmcRUE4d0gyO9Zb1vvt25fxM3ekjvDfVHcPq3q # Mr0Rwsk4krKZWUEgU1SXT5qN6gqRrshxbT6OQgZ9/xT04qiXdzPQR6KindBvSpoO # nxnALxcJyzVwNpKL+9u8EZYy98qX6i+4gE/2J6cbpekcB0ZXDn/XQxoNUUb6/djT # /wllVyG+vIHkdq71PzbH5rYxdcAwggeeMIIFhqADAgECAhMzAAAAB4ejNKN7pY4c # AAAAAAAHMA0GCSqGSIb3DQEBDAUAMHcxCzAJBgNVBAYTAlVTMR4wHAYDVQQKExVN # aWNyb3NvZnQgQ29ycG9yYXRpb24xSDBGBgNVBAMTP01pY3Jvc29mdCBJZGVudGl0 # eSBWZXJpZmljYXRpb24gUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgMjAyMDAe # Fw0yMTA0MDEyMDA1MjBaFw0zNjA0MDEyMDE1MjBaMGMxCzAJBgNVBAYTAlVTMR4w # HAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xNDAyBgNVBAMTK01pY3Jvc29m # dCBJRCBWZXJpZmllZCBDb2RlIFNpZ25pbmcgUENBIDIwMjEwggIiMA0GCSqGSIb3 # DQEBAQUAA4ICDwAwggIKAoICAQCy8MCvGYgo4t1UekxJbGkIVQm0Uv96SvjB6yUo # 92cXdylN65Xy96q2YpWCiTas7QPTkGnK9QMKDXB2ygS27EAIQZyAd+M8X+dmw6SD # tzSZXyGkxP8a8Hi6EO9Zcwh5A+wOALNQbNO+iLvpgOnEM7GGB/wm5dYnMEOguua1 # OFfTUITVMIK8faxkP/4fPdEPCXYyy8NJ1fmskNhW5HduNqPZB/NkWbB9xxMqowAe # WvPgHtpzyD3PLGVOmRO4ka0WcsEZqyg6efk3JiV/TEX39uNVGjgbODZhzspHvKFN # U2K5MYfmHh4H1qObU4JKEjKGsqqA6RziybPqhvE74fEp4n1tiY9/ootdU0vPxRp4 # BGjQFq28nzawuvaCqUUF2PWxh+o5/TRCb/cHhcYU8Mr8fTiS15kRmwFFzdVPZ3+J # V3s5MulIf3II5FXeghlAH9CvicPhhP+VaSFW3Da/azROdEm5sv+EUwhBrzqtxoYy # E2wmuHKws00x4GGIx7NTWznOm6x/niqVi7a/mxnnMvQq8EMse0vwX2CfqM7Le/sm # bRtsEeOtbnJBbtLfoAsC3TdAOnBbUkbUfG78VRclsE7YDDBUbgWt75lDk53yi7C3 # n0WkHFU4EZ83i83abd9nHWCqfnYa9qIHPqjOiuAgSOf4+FRcguEBXlD9mAInS7b6 # V0UaNwIDAQABo4ICNTCCAjEwDgYDVR0PAQH/BAQDAgGGMBAGCSsGAQQBgjcVAQQD # AgEAMB0GA1UdDgQWBBTZQSmwDw9jbO9p1/XNKZ6kSGow5jBUBgNVHSAETTBLMEkG # BFUdIAAwQTA/BggrBgEFBQcCARYzaHR0cDovL3d3dy5taWNyb3NvZnQuY29tL3Br # aW9wcy9Eb2NzL1JlcG9zaXRvcnkuaHRtMBkGCSsGAQQBgjcUAgQMHgoAUwB1AGIA # QwBBMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUyH7SaoUqG8oZmAQHJ89Q # EE9oqKIwgYQGA1UdHwR9MHsweaB3oHWGc2h0dHA6Ly93d3cubWljcm9zb2Z0LmNv # bS9wa2lvcHMvY3JsL01pY3Jvc29mdCUyMElkZW50aXR5JTIwVmVyaWZpY2F0aW9u # JTIwUm9vdCUyMENlcnRpZmljYXRlJTIwQXV0aG9yaXR5JTIwMjAyMC5jcmwwgcMG # CCsGAQUFBwEBBIG2MIGzMIGBBggrBgEFBQcwAoZ1aHR0cDovL3d3dy5taWNyb3Nv # ZnQuY29tL3BraW9wcy9jZXJ0cy9NaWNyb3NvZnQlMjBJZGVudGl0eSUyMFZlcmlm # aWNhdGlvbiUyMFJvb3QlMjBDZXJ0aWZpY2F0ZSUyMEF1dGhvcml0eSUyMDIwMjAu # Y3J0MC0GCCsGAQUFBzABhiFodHRwOi8vb25lb2NzcC5taWNyb3NvZnQuY29tL29j # c3AwDQYJKoZIhvcNAQEMBQADggIBAH8lKp7+1Kvq3WYK21cjTLpebJDjW4ZbOX3H # D5ZiG84vjsFXT0OB+eb+1TiJ55ns0BHluC6itMI2vnwc5wDW1ywdCq3TAmx0KWy7 # xulAP179qX6VSBNQkRXzReFyjvF2BGt6FvKFR/imR4CEESMAG8hSkPYso+GjlngM # 8JPn/ROUrTaeU/BRu/1RFESFVgK2wMz7fU4VTd8NXwGZBe/mFPZG6tWwkdmA/jLb # p0kNUX7elxu2+HtHo0QO5gdiKF+YTYd1BGrmNG8sTURvn09jAhIUJfYNotn7OlTh # tfQjXqe0qrimgY4Vpoq2MgDW9ESUi1o4pzC1zTgIGtdJ/IvY6nqa80jFOTg5qzAi # RNdsUvzVkoYP7bi4wLCj+ks2GftUct+fGUxXMdBUv5sdr0qFPLPB0b8vq516slCf # RwaktAxK1S40MCvFbbAXXpAZnU20FaAoDwqq/jwzwd8Wo2J83r7O3onQbDO9TyDS # tgaBNlHzMMQgl95nHBYMelLEHkUnVVVTUsgC0Huj09duNfMaJ9ogxhPNThgq3i8w # 3DAGZ61AMeF0C1M+mU5eucj1Ijod5O2MMPeJQ3/vKBtqGZg4eTtUHt/BPjN74SsJ # syHqAdXVS5c+ItyKWg3Eforhox9k3WgtWTpgV4gkSiS4+A09roSdOI4vrRw+p+fL # 4WrxSK5nMYIakDCCGowCAQEwcTBaMQswCQYDVQQGEwJVUzEeMBwGA1UEChMVTWlj # cm9zb2Z0IENvcnBvcmF0aW9uMSswKQYDVQQDEyJNaWNyb3NvZnQgSUQgVmVyaWZp # ZWQgQ1MgRU9DIENBIDA0AhMzAAGSX9Z/ePB9sQgIAAAAAZJfMA0GCWCGSAFlAwQC # AQUAoF4wEAYKKwYBBAGCNwIBDDECMAAwGQYJKoZIhvcNAQkDMQwGCisGAQQBgjcC # AQQwLwYJKoZIhvcNAQkEMSIEINGauvKA7hInZn4O5YPvuCsPCritFQ0WbqEqdPyP # r76FMA0GCSqGSIb3DQEBAQUABIIBgIeit0Qjj6vYvgTJUfdV+BGRjehEjoDcc84E # Q8nwgEBGJHB+uBc20zrKR1JLh/3cr5veEJPxC8CdvTB7e9xVoG8GfxlUvSe62VN1 # BddjLdcnXrBz2S+SLRgkQw1mZReS69dUgkNPRgHMPuoGpAxGOD/KxlCDRR4D0j8/ # 9Gs/1D2GFacxqMgIpkAiuu1TzoatuY8VC1XkadKn/WxMVEYfgrN0yjunIeGiKYZr # Lm9KNHgl7xvGtBHsLdJPqRaa3GbHNXwKb46r+5CICFmnqt0yjkN9spme8eTYoslZ # 3rkUdqabXFu4NOhcte8Ms5kOoTaOawqR5sunalixIvqKNG0W6TbKsDZ2zzpba4j4 # UJ6OSQ2aOClQUX6pzAZKVyFO6A+Zl5l4l5wU8SYVEyJgV3dZphm3ee+5gJxDTjEV # 75djNXFqGEoS9BRM0TeHRghNnm/ioKsU3BtqMcBzpqZ+9BqAucb/feE9rNlS+8aJ # IYiMVII2ghpLHdfHEVimx0UxxlU6w6GCGBAwghgMBgorBgEEAYI3AwMBMYIX/DCC # F/gGCSqGSIb3DQEHAqCCF+kwghflAgEDMQ8wDQYJYIZIAWUDBAIBBQAwggFhBgsq # hkiG9w0BCRABBKCCAVAEggFMMIIBSAIBAQYKKwYBBAGEWQoDATAxMA0GCWCGSAFl # AwQCAQUABCDmjwUlRXG2Ick/fDirtAu8fuy3ribl5qlzrHKixw2B2gIGagxE8Xu6 # GBIyMDI2MDYwMjAxNTU0NS42MlowBIACAfSggeGkgd4wgdsxCzAJBgNVBAYTAlVT # MRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQK # ExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xJTAjBgNVBAsTHE1pY3Jvc29mdCBBbWVy # aWNhIE9wZXJhdGlvbnMxJzAlBgNVBAsTHm5TaGllbGQgVFNTIEVTTjo3ODAwLTA1 # RTAtRDk0NzE1MDMGA1UEAxMsTWljcm9zb2Z0IFB1YmxpYyBSU0EgVGltZSBTdGFt # cGluZyBBdXRob3JpdHmggg8hMIIHgjCCBWqgAwIBAgITMwAAAAXlzw//Zi7JhwAA # AAAABTANBgkqhkiG9w0BAQwFADB3MQswCQYDVQQGEwJVUzEeMBwGA1UEChMVTWlj # cm9zb2Z0IENvcnBvcmF0aW9uMUgwRgYDVQQDEz9NaWNyb3NvZnQgSWRlbnRpdHkg # VmVyaWZpY2F0aW9uIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIwMjAwHhcN # MjAxMTE5MjAzMjMxWhcNMzUxMTE5MjA0MjMxWjBhMQswCQYDVQQGEwJVUzEeMBwG # A1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTIwMAYDVQQDEylNaWNyb3NvZnQg # UHVibGljIFJTQSBUaW1lc3RhbXBpbmcgQ0EgMjAyMDCCAiIwDQYJKoZIhvcNAQEB # BQADggIPADCCAgoCggIBAJ5851Jj/eDFnwV9Y7UGIqMcHtfnlzPREwW9ZUZHd5HB # XXBvf7KrQ5cMSqFSHGqg2/qJhYqOQxwuEQXG8kB41wsDJP5d0zmLYKAY8Zxv3lYk # uLDsfMuIEqvGYOPURAH+Ybl4SJEESnt0MbPEoKdNihwM5xGv0rGofJ1qOYSTNcc5 # 5EbBT7uq3wx3mXhtVmtcCEr5ZKTkKKE1CxZvNPWdGWJUPC6e4uRfWHIhZcgCsJ+s # ozf5EeH5KrlFnxpjKKTavwfFP6XaGZGWUG8TZaiTogRoAlqcevbiqioUz1Yt4FRK # 53P6ovnUfANjIgM9JDdJ4e0qiDRm5sOTiEQtBLGd9Vhd1MadxoGcHrRCsS5rO9yh # v2fjJHrmlQ0EIXmp4DhDBieKUGR+eZ4CNE3ctW4uvSDQVeSp9h1SaPV8UWEfyTxg # GjOsRpeexIveR1MPTVf7gt8hY64XNPO6iyUGsEgt8c2PxF87E+CO7A28TpjNq5eL # iiunhKbq0XbjkNoU5JhtYUrlmAbpxRjb9tSreDdtACpm3rkpxp7AQndnI0Shu/fk # 1/rE3oWsDqMX3jjv40e8KN5YsJBnczyWB4JyeeFMW3JBfdeAKhzohFe8U5w9Wuvc # P1E8cIxLoKSDzCCBOu0hWdjzKNu8Y5SwB1lt5dQhABYyzR3dxEO/T1K/BVF3rV69 # AgMBAAGjggIbMIICFzAOBgNVHQ8BAf8EBAMCAYYwEAYJKwYBBAGCNxUBBAMCAQAw # HQYDVR0OBBYEFGtpKDo1L0hjQM972K9J6T7ZPdshMFQGA1UdIARNMEswSQYEVR0g # ADBBMD8GCCsGAQUFBwIBFjNodHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpb3Bz # L0RvY3MvUmVwb3NpdG9yeS5odG0wEwYDVR0lBAwwCgYIKwYBBQUHAwgwGQYJKwYB # BAGCNxQCBAweCgBTAHUAYgBDAEEwDwYDVR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAW # gBTIftJqhSobyhmYBAcnz1AQT2ioojCBhAYDVR0fBH0wezB5oHegdYZzaHR0cDov # L3d3dy5taWNyb3NvZnQuY29tL3BraW9wcy9jcmwvTWljcm9zb2Z0JTIwSWRlbnRp # dHklMjBWZXJpZmljYXRpb24lMjBSb290JTIwQ2VydGlmaWNhdGUlMjBBdXRob3Jp # dHklMjAyMDIwLmNybDCBlAYIKwYBBQUHAQEEgYcwgYQwgYEGCCsGAQUFBzAChnVo # dHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2NlcnRzL01pY3Jvc29mdCUy # MElkZW50aXR5JTIwVmVyaWZpY2F0aW9uJTIwUm9vdCUyMENlcnRpZmljYXRlJTIw # QXV0aG9yaXR5JTIwMjAyMC5jcnQwDQYJKoZIhvcNAQEMBQADggIBAF+Idsd+bbVa # FXXnTHho+k7h2ESZJRWluLE0Oa/pO+4ge/XEizXvhs0Y7+KVYyb4nHlugBesnFqB # GEdC2IWmtKMyS1OWIviwpnK3aL5JedwzbeBF7POyg6IGG/XhhJ3UqWeWTO+Czb1c # 2NP5zyEh89F72u9UIw+IfvM9lzDmc2O2END7MPnrcjWdQnrLn1Ntday7JSyrDvBd # mgbNnCKNZPmhzoa8PccOiQljjTW6GePe5sGFuRHzdFt8y+bN2neF7Zu8hTO1I64X # NGqst8S+w+RUdie8fXC1jKu3m9KGIqF4aldrYBamyh3g4nJPj/LR2CBaLyD+2BuG # ZCVmoNR/dSpRCxlot0i79dKOChmoONqbMI8m04uLaEHAv4qwKHQ1vBzbV/nG89LD # KbRSSvijmwJwxRxLLpMQ/u4xXxFfR4f/gksSkbJp7oqLwliDm/h+w0aJ/U5ccnYh # Yb7vPKNMN+SZDWycU5ODIRfyoGl59BsXR/HpRGtiJquOYGmvA/pk5vC1lcnbeMrc # WD/26ozePQ/TWfNXKBOmkFpvPE8CH+EeGGWzqTCjdAsno2jzTeNSxlx3glDGJgcd # z5D/AAxw9Sdgq/+rY7jjgs7X6fqPTXPmaCAJKVHAP19oEjJIBwD1LyHbaEgBxFCo # gYSOiUIr0Xqcr1nJfiWG2GwYe6ZoAF1bMIIHlzCCBX+gAwIBAgITMwAAAFck05Xg # ounJMQAAAAAAVzANBgkqhkiG9w0BAQwFADBhMQswCQYDVQQGEwJVUzEeMBwGA1UE # ChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTIwMAYDVQQDEylNaWNyb3NvZnQgUHVi # bGljIFJTQSBUaW1lc3RhbXBpbmcgQ0EgMjAyMDAeFw0yNTEwMjMyMDQ2NTNaFw0y # NjEwMjIyMDQ2NTNaMIHbMQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3Rv # bjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0 # aW9uMSUwIwYDVQQLExxNaWNyb3NvZnQgQW1lcmljYSBPcGVyYXRpb25zMScwJQYD # VQQLEx5uU2hpZWxkIFRTUyBFU046NzgwMC0wNUUwLUQ5NDcxNTAzBgNVBAMTLE1p # Y3Jvc29mdCBQdWJsaWMgUlNBIFRpbWUgU3RhbXBpbmcgQXV0aG9yaXR5MIICIjAN # BgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAsWylCpMIfbizJLY1kPXO2cmX2HRW # vRbAmeKSZ5ex7/jCymdV7Eap+Ic2iqRtWDkKKe5gL6JV80wtn5C2qHJLPxUYFKNG # 3UkHkAI21MoCN+YWnhT8K/YuPib6+6970jdbeFKIiZMWwd5hnpX9J3jeteuEdXbp # /DfFBK15JuD3JOzWuF2suQCPgqYjQPk/gpq+3KCKtXJRbXSCSJ9YtITU2IHwmfdE # 7l2PfZ154w041po+fDeTj0gJOzcV/Jv56Q0M+w19jAKo/I5PEzrLV1IPQnmP4or1 # X4RbJXk8ONXyOOfXOxK2VLpNxgklK1yAezbFP2uzqihaXkW1h9GQLGENKESnezwg # dRaLNNaYtm8AT/pZHYJ35mZVqkZdMIckpQHJk/F1fSLyDKeKtH4TC4cc3ESKUMgI # tq07ZZm74JCsfhmrQ1ijVNDi1Sln+QBamgC7WviZbkQnceQRq9DY+6hANwOrasAZ # UiVr2kPuj1jHDOXzUG4O9QTK70P/oXSqZAN1oTv3UfF8JTGmAxg+l1ZPOz50MY96 # HBDw/3bI/wBGNvLk6fLVnrxGN5B5unF/lYvjjWbIUdyBPVQnPOKXu08SRHbY19M1 # HoWX6PNZv+vzSeqVeWWHKdKjC3GjVjbbGpi+JLbiyaKRSwEqo49tJLvu69cQ7dWs # bksai4TURnVj2mMCAwEAAaOCAcswggHHMB0GA1UdDgQWBBSOg8leLTUOAglIZ+bj # XpiD7RKSpzAfBgNVHSMEGDAWgBRraSg6NS9IY0DPe9ivSek+2T3bITBsBgNVHR8E # ZTBjMGGgX6BdhltodHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2NybC9N # aWNyb3NvZnQlMjBQdWJsaWMlMjBSU0ElMjBUaW1lc3RhbXBpbmclMjBDQSUyMDIw # MjAuY3JsMHkGCCsGAQUFBwEBBG0wazBpBggrBgEFBQcwAoZdaHR0cDovL3d3dy5t # aWNyb3NvZnQuY29tL3BraW9wcy9jZXJ0cy9NaWNyb3NvZnQlMjBQdWJsaWMlMjBS # U0ElMjBUaW1lc3RhbXBpbmclMjBDQSUyMDIwMjAuY3J0MAwGA1UdEwEB/wQCMAAw # FgYDVR0lAQH/BAwwCgYIKwYBBQUHAwgwDgYDVR0PAQH/BAQDAgeAMGYGA1UdIARf # MF0wUQYMKwYBBAGCN0yDfQEBMEEwPwYIKwYBBQUHAgEWM2h0dHA6Ly93d3cubWlj # cm9zb2Z0LmNvbS9wa2lvcHMvRG9jcy9SZXBvc2l0b3J5Lmh0bTAIBgZngQwBBAIw # DQYJKoZIhvcNAQEMBQADggIBAHJ1wHY86Zk5SUBDPY25d/u9YJVaaNa71uxjX4cy # O/XJ4uPENCSOwkRTnNogPLxTD0Fg3z4TFf/2T/0IFSxdtWVtTjhzrn+WLInzeRaw # UhTCFVrPBJKEWVshm+Ig7/nB7JbJN88+ltImBbL5kT1StBLfG6UksAcDbNSQww90 # CUXhGueBxlnSvjkAX1ohiN16y1bB2s0rvQx8Csepl2CuBefTfDrMGzW/tzNx5YaK # 2D8OWweqTWZcGlJO4YjZNI83cTrQghfHl/8AXOHj8cWL3wEFltQQs2xeRYAb3Kdn # l7oIWKKXWaBYJY5P3QPsiC+DTMp7ejdYKTrb396f3gr+wL/Ms5/Z3vIWZPJJv18q # Nw40fUNveRnwzMQnx8dM2bGuXXQZ5y7P8aXT4HJMo349qZtn4XQwiUE/DDp++MUL # 0kgjvd/Deo7Xr371PFPPYb4TboZhjV1x9+wCHDoOpNCBt+VuXU78ytJdKzQ1Jv2c # EP1F9H9/wSLsMDUvWME7u9mGElOPDZPMVr8AuBEuLdbTSEdaLwsZBplzxLBcgxhZ # /Cs30yBhuE3QhqT1YDZ2pa56RexPA2SasPcToT6gJgJ6E06BmZ2zQTNvWOjs5XQq # HbYuXcoeDcwe2UaC7EDOGD8GmLE9LiqtQsuQCM7v7I2xR+sPZT2Ax/85HjIkM+3M # zTK1MYIHQzCCBz8CAQEweDBhMQswCQYDVQQGEwJVUzEeMBwGA1UEChMVTWljcm9z # b2Z0IENvcnBvcmF0aW9uMTIwMAYDVQQDEylNaWNyb3NvZnQgUHVibGljIFJTQSBU # aW1lc3RhbXBpbmcgQ0EgMjAyMAITMwAAAFck05XgounJMQAAAAAAVzANBglghkgB # ZQMEAgEFAKCCBJwwEQYLKoZIhvcNAQkQAg8xAgUAMBoGCSqGSIb3DQEJAzENBgsq # hkiG9w0BCRABBDAcBgkqhkiG9w0BCQUxDxcNMjYwNjAyMDE1NTQ1WjAvBgkqhkiG # 9w0BCQQxIgQgl9I2rR/6hKBnINU7FTVZrsFQnXuL+WTTzbXUP+TLXx0wgbkGCyqG # SIb3DQEJEAIvMYGpMIGmMIGjMIGgBCD1PJ9ktQVuTGWIbKLO4f1VUOlUU29ARCEp # DZmFTHjbUjB8MGWkYzBhMQswCQYDVQQGEwJVUzEeMBwGA1UEChMVTWljcm9zb2Z0 # IENvcnBvcmF0aW9uMTIwMAYDVQQDEylNaWNyb3NvZnQgUHVibGljIFJTQSBUaW1l # c3RhbXBpbmcgQ0EgMjAyMAITMwAAAFck05XgounJMQAAAAAAVzCCA14GCyqGSIb3 # DQEJEAISMYIDTTCCA0mhggNFMIIDQTCCAikCAQEwggEJoYHhpIHeMIHbMQswCQYD # VQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEe # MBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSUwIwYDVQQLExxNaWNyb3Nv # ZnQgQW1lcmljYSBPcGVyYXRpb25zMScwJQYDVQQLEx5uU2hpZWxkIFRTUyBFU046 # NzgwMC0wNUUwLUQ5NDcxNTAzBgNVBAMTLE1pY3Jvc29mdCBQdWJsaWMgUlNBIFRp # bWUgU3RhbXBpbmcgQXV0aG9yaXR5oiMKAQEwBwYFKw4DAhoDFQD9LzE5nEJRAUE2 # Ss3xaKKPXHnLw6BnMGWkYzBhMQswCQYDVQQGEwJVUzEeMBwGA1UEChMVTWljcm9z # b2Z0IENvcnBvcmF0aW9uMTIwMAYDVQQDEylNaWNyb3NvZnQgUHVibGljIFJTQSBU # aW1lc3RhbXBpbmcgQ0EgMjAyMDANBgkqhkiG9w0BAQsFAAIFAO3Ij48wIhgPMjAy # NjA2MDEyMzA5MDNaGA8yMDI2MDYwMjIzMDkwM1owdDA6BgorBgEEAYRZCgQBMSww # KjAKAgUA7ciPjwIBADAHAgEAAgIVRTAHAgEAAgISSTAKAgUA7cnhDwIBADA2Bgor # BgEEAYRZCgQCMSgwJjAMBgorBgEEAYRZCgMCoAowCAIBAAIDB6EgoQowCAIBAAID # AYagMA0GCSqGSIb3DQEBCwUAA4IBAQBNKZXhNEhXkxpO/lbxR3O+XZwer5GHiMEV # n+tx2Pe+4o2LjmMWLS4gvkAvxwadgn/PWJNTnrE9cBxqvuR4botN4bC1yiRpBrQs # KUgDgnqoCXhqXDzhwIVmMoqB2FuB7doAuMgoBhZdxKen4LywkRPPbzCf4SJsLoWc # 2KvJTZtuBUWaGzljc/SZppv6tTJ1Iwcp2esHj53ZvaN7oxVHdUjC13XHHqxUsn7z # yeGGs6yPPUC4fD0cFhw2aq+WeAMHxCCsmNpEm2VvIrSIhK0h6Q1HLBJl3303YKgF # sT9N4uXjMylFksHjZearxku+W1y+zJ08JKE5S4FXuJ+3IdaktmhTMA0GCSqGSIb3 # DQEBAQUABIICAG/nlDspg4MmniF/5aDjKm0P0uIDpTj4TDjSdJRz71MPuHhQZLLb # WaKj6QCNWX22lljJBsx2jzWgtFAreISTR5xtKouKr+mQulhw8InE8xUR+TdN43FS # KuicvPLEq13E5XN87IcOtlSf8WpQeQ4NHnTPaOqk3RZT7RArwTzMbV9B4rn1X/MR # 2EyjolMKcitIeMjzyfBaHQKP+ApWM6FYidd9gOZCgrXgVJHkD01E1w37PCZoxYD9 # GEYjyTZgWg28oPyKj5Sl/58tpxsl8rvHGlF4GnzX+8KNDMJ2eY8NbZckO+b3uIwL # hCT5n7T/DXHAPrudwjHe5nErKHMTWNzRzvS87Nr8JmnI9SvNgHwcYQ1O5phnYUZH # JPjTiDfRe3jTFfupuuCbNMG7iCgWL+PzwKc3kKSn5exFugc00ogQwgMNoEwtUSsG # 216Wa2bsCOoUWiWnbOgNwlAufPPYYmhVvWYOZKaWBdM9Qjynu+4uogJNohs/arxV # 5wS5z2jTzuJOMBjh6F6gYULho6NFAkWorBmAixuXB+ABMXudylZTdyE1mdFkx0+5 # 4OmIak+rDfJ3nDmb7cBtNJr4TjW7dWKEBvO8djO+x2FHJok6BmzZTkXngZpB/4LC # zrdIzv+QERBszK5TiEgGr16+iGvtK9MlYhHugUM7zcUX6YWAdSuOkHG/ # SIG # End signature block |