Modules/Providers/ExportEXOProvider.psm1
function Export-EXOProvider { <# .Description Gets the Exchange Online (EXO) settings that are relevant to the SCuBA EXO baselines using the EXO PowerShell Module .Functionality Internal #> [CmdletBinding()] [OutputType([String])] param() # Manually importing the module name here to bypass cmdlet name conflicts # There are conflicting PowerShell Cmdlet names in EXO and Power Platform Import-Module ExchangeOnlineManagement Import-Module $PSScriptRoot/ProviderHelpers/CommandTracker.psm1 $Tracker = Get-CommandTracker <# MS.EXO.1.1v2 #> $RemoteDomains = ConvertTo-Json @($Tracker.TryCommand("Get-RemoteDomain")) <# MS.EXO.2.1v1 SPF #> $domains = $Tracker.TryCommand("Get-AcceptedDomain") $SPFRecords = ConvertTo-Json @($Tracker.TryCommand("Get-ScubaSpfRecord", @{"Domains"=$domains})) -Depth 4 <# MS.EXO.3.1v1 DKIM #> $DKIMConfig = ConvertTo-Json @($Tracker.TryCommand("Get-DkimSigningConfig")) $DKIMRecords = ConvertTo-Json @($Tracker.TryCommand("Get-ScubaDkimRecord", @{"Domains"=$domains})) -Depth 4 <# MS.EXO.4.1v1 DMARC #> $DMARCRecords = ConvertTo-Json @($Tracker.TryCommand("Get-ScubaDmarcRecord", @{"Domains"=$domains})) -Depth 4 <# MS.EXO.5.1v1 #> $TransportConfig = ConvertTo-Json @($Tracker.TryCommand("Get-TransportConfig")) <# MS.EXO.6.1v1 #> $SharingPolicy = ConvertTo-Json @($Tracker.TryCommand("Get-SharingPolicy")) <# MS.EXO.7.1v1 #> $TransportRules = ConvertTo-Json @($Tracker.TryCommand("Get-TransportRule")) <# MS.EXO.12.1v1 #> $ConnectionFilter = ConvertTo-Json @($Tracker.TryCommand("Get-HostedConnectionFilterPolicy")) <# MS.EXO.13.1v1 #> $Config = $Tracker.TryCommand("Get-OrganizationConfig") | Select-Object Name, DisplayName, AuditDisabled $Config = ConvertTo-Json @($Config) # Used in the reporter to check successful cmdlet invocation $SuccessfulCommands = ConvertTo-Json @($Tracker.GetSuccessfulCommands()) $UnSuccessfulCommands = ConvertTo-Json @($Tracker.GetUnSuccessfulCommands()) # Note the spacing and the last comma in the json is important $json = @" "remote_domains": $RemoteDomains, "spf_records": $SPFRecords, "dkim_config": $DKIMConfig, "dkim_records": $DKIMRecords, "dmarc_records": $DMARCRecords, "transport_config": $TransportConfig, "sharing_policy": $SharingPolicy, "transport_rule": $TransportRules, "conn_filter": $ConnectionFilter, "org_config": $Config, "exo_successful_commands": $SuccessfulCommands, "exo_unsuccessful_commands": $UnSuccessfulCommands, "@ $json } function Get-EXOTenantDetail { <# .Description Gets the tenant details using the EXO PowerShell Module .Functionality Internal #> [CmdletBinding()] param ( [Parameter(Mandatory = $true)] [ValidateSet("commercial", "gcc", "gcchigh", "dod", IgnoreCase = $false)] [ValidateNotNullOrEmpty()] [string] $M365Environment ) try { Import-Module ExchangeOnlineManagement $OrgConfig = Get-OrganizationConfig -ErrorAction "Stop" $DomainName = $OrgConfig.Name $TenantId = "Error retrieving Tenant ID" $Uri = "https://login.microsoftonline.com/$($DomainName)/.well-known/openid-configuration" if (($M365Environment -eq "gcchigh") -or ($M365Environment -eq "dod")) { $TLD = ".us" $Uri = "https://login.microsoftonline$($TLD)/$($DomainName)/.well-known/openid-configuration" } try { $Content = (Invoke-WebRequest -Uri $Uri -UseBasicParsing -ErrorAction "Stop").Content $TenantId = (ConvertFrom-Json $Content).token_endpoint.Split("/")[3] } catch { Write-Warning "Unable to retrieve EXO Tenant ID with URI. This may be caused by proxy error see 'Running the Script Behind Some Proxies' in the README for a solution: $($_.Exception.Message)`n$($_.ScriptStackTrace)" } $EXOTenantInfo = @{ "DisplayName"= $OrgConfig.DisplayName; "DomainName" = $DomainName; "TenantId" = $TenantId; "EXOAdditionalData" = "Unable to safely retrieve due to EXO API changes"; } $EXOTenantInfo = ConvertTo-Json @($EXOTenantInfo) -Depth 4 $EXOTenantInfo } catch { Write-Warning "Error retrieving Tenant details using Get-EXOTenantDetail: $($_.Exception.Message)`n$($_.ScriptStackTrace)" $EXOTenantInfo = @{ "DisplayName" = "Error retrieving Display name"; "DomainName" = "Error retrieving Domain name"; "TenantId" = "Error retrieving Tenant ID"; "EXOAdditionalData" = "Error retrieving additional data"; } $EXOTenantInfo = ConvertTo-Json @($EXOTenantInfo) -Depth 4 $EXOTenantInfo } } # A $script:scoped variable used to indicate the preferred DoH server. # Initialize to empty string to indicate that we don't yet know the # preferred server. Will be set when the Select-DohServer function is # called. $DohServer = "" function Select-DohServer { <# .Description Iterates through several DoH servers. Returns the first successful server. If none are successful, returns $null. .Functionality Internal #> $DoHServers = @("cloudflare-dns.com", "[2606:4700:4700::1111]", "1.1.1.1") $PreferredServer = $null foreach ($Server in $DoHServers) { try { # Attempt to resolve a.root-servers.net over DoH. The domain chosen is somewhat # arbitrary, as we don't care what the answer is, only if the query succeeds/fails. # a.root-servers.net, the address of one of the DNS root servers, was chosen as a # benign, highly-available domain. $Uri = "https://$($Server)/dns-query?name=a.root-servers.net" Invoke-WebRequest -Headers @{"accept"="application/dns-json"} -Uri $Uri ` -TimeoutSec 2 -UseBasicParsing -ErrorAction "Stop" | Out-Null # No error was thrown, return this server $PreferredServer = $Server break } catch { # This server didn't work, try the next one continue } } $PreferredServer } function Invoke-RobustDnsTxt { <# .Description Requests the TXT record for the given qname. First tries to make the query over traditional DNS but retries over DoH in the event of failure. .Parameter Qname The fully-qualified domain name to request. .Parameter MaxTries The number of times to retry each kind of query. If all queries are unsuccessful, the traditional queries and the DoH queries will each be made $MaxTries times. Default is 2. .Functionality Internal #> [CmdletBinding()] [OutputType([System.Collections.Hashtable])] param ( [Parameter(Mandatory=$true)] [ValidateNotNullOrEmpty()] [string] $Qname, [Parameter(Mandatory=$false)] [ValidateRange(1, [int]::MaxValue)] [int] $MaxTries = 2 ) $Results = @{ "Answers" = @(); "NXDomain" = $false; "LogEntries" = @(); "Errors" = @() } $TradResult = Invoke-TraditionalDns -Qname $Qname -MaxTries $MaxTries $Results['Answers'] += $TradResult['Answers'] $Results['NXDomain'] = $TradResult['NXDomain'] $Results['LogEntries'] += $TradResult['LogEntries'] $Results['Errors'] += $TradResult['Errors'] if ($Results.Answers.Length -eq 0) { # The traditional DNS query(ies) failed. Retry with DoH $DoHResult = Invoke-DoH -Qname $Qname -MaxTries $MaxTries $Results['Answers'] += $DoHResult['Answers'] $Results['NXDomain'] = $DoHResult['NXDomain'] $Results['LogEntries'] += $DoHResult['LogEntries'] $Results['Errors'] += $DoHResult['Errors'] } $Results } function Invoke-TraditionalDns { <# .Description Requests the TXT record for the given qname over traditional DNS. .Parameter Qname The fully-qualified domain name to request. .Parameter MaxTries The number of times to retry the query. .Functionality Internal #> [CmdletBinding()] [OutputType([System.Collections.Hashtable])] param ( [Parameter(Mandatory=$true)] [ValidateNotNullOrEmpty()] [string] $Qname, [Parameter(Mandatory=$false)] [ValidateRange(1, [int]::MaxValue)] [int] $MaxTries = 2 ) $Answers = @() $NXDomain = $false $Errors = @() $LogEntries = @() $TryNumber = 0 while ($TryNumber -lt $MaxTries) { $TryNumber += 1 try { $Response = Resolve-DnsName $Qname txt -ErrorAction Stop | Where-Object {$_.Section -eq "Answer"} if ($Response.Strings.Length -gt 0) { # We got our answer, so break out of the retry loop, no # need to retry the traditional query or retry with DoH. # Resolve-DnsName breaks long answers into multiple strings, we need to # join them back together $StringsJoined = ($Response | ForEach-Object { $_.Strings -Join "" } ) if ($StringsJoined -is [String]) { $NAnswers = 1 } else { $NAnswers = $StringsJoined.Length } $LogEntries += @{ "query_name"=$Qname; "query_method"="traditional"; "query_result"="Query returned $NAnswers txt records"; "query_answers"=$StringsJoined; } $Answers += $StringsJoined break } else { # The answer section was empty. This usually means that while the domain exists, but # there are no records of the requested type. No need to retry the traditional query, # this was not a transient failure. Don't set $Success to $true though, as we want to # retry this query from a public resolver, in case the internal DNS server returns a # different answer than what is served to the public (i.e., split horizon DNS). $LogEntries += @{ "query_name"=$Qname; "query_method"="traditional"; "query_result"="Query returned 0 txt records"; "query_answers"=@(); } break } } catch { if ($_.FullyQualifiedErrorId -eq "DNS_ERROR_RCODE_NAME_ERROR,Microsoft.DnsClient.Commands.ResolveDnsName") { # The server returned NXDomain, no need to retry the traditional query, # this was not a transient failure. $LogEntries += @{ "query_name"=$Qname; "query_method"="traditional"; "query_result"="Query returned NXDomain"; "query_answers"=@(); } $NXDomain = $True break } else { # The query failed, possibly a transient failure. Retry if we haven't reached $MaxsTries. $LogEntries += @{ "query_name"=$Qname; "query_method"="traditional"; "query_result"="Query resulted in exception, $($_.FullyQualifiedErrorId)"; "query_answers"=@(); } $Errors += $_.FullyQualifiedErrorId } } } @{ "Answers" = $Answers; "NXDomain" = $NXDomain; "LogEntries" = $LogEntries; "Errors" = $Errors; } } function Invoke-DoH { <# .Description Requests the TXT record for the given qname over traditional DNS. .Parameter Qname The fully-qualified domain name to request. .Parameter MaxTries The number of times to retry the query. .Functionality Internal #> [CmdletBinding()] [OutputType([System.Collections.Hashtable])] param ( [Parameter(Mandatory=$true)] [ValidateNotNullOrEmpty()] [string] $Qname, [Parameter(Mandatory=$false)] [ValidateRange(1, [int]::MaxValue)] [int] $MaxTries = 2 ) $Answers = @() $NXDomain = $false $Errors = @() $LogEntries = @() if ($script:DohServer -eq "") { # We haven't determined if DoH is available yet, select the first server that works $script:DohServer = Select-DohServer } if ($null -eq $script:DohServer) { # None of the DoH servers are accessible $LogEntries += @{"query_name"=$Qname; "query_method"="DoH"; "query_result"="NA, DoH servers unreachable"} return @{ "Answers" = $Answers; "NXDomain" = $NXDomain; "LogEntries" = $LogEntries; "Errors" = $Errors; } } # DoH is available, query for the domain $TryNumber = 0 while ($TryNumber -lt $MaxTries) { $TryNumber += 1 try { $Uri = "https://$($script:DohServer)/dns-query?name=$($Qname)&type=txt" $Headers = @{"accept"="application/dns-json"} $RawResponse = $(Invoke-WebRequest -Headers $Headers -Uri $Uri -UseBasicParsing -ErrorAction "Stop").RawContent $ResponseLines = $RawResponse -Split "`n" $LastLine = $ResponseLines[$ResponseLines.Length - 1] $ResponseBody = ConvertFrom-Json $LastLine if ($ResponseBody.Status -eq 0) { # 0 indicates there was no error if ($null -eq $ResponseBody.Answer) { # Edge case where the domain exists but there are no txt records available $LogEntries += @{ "query_name"=$Qname; "query_method"="DoH"; "query_result"="Query returned 0 txt records"; "query_answers"=@(); } } else { if ($ResponseBody.Answer.data -is [String]) { $Length = 1 } else { $Length = $ResponseBody.Answer.data.Length } $LogEntries += @{ "query_name"=$Qname; "query_method"="DoH"; "query_result"="Query returned $Length txt records"; "query_answers"=($ResponseBody.Answer.data | ForEach-Object {$_.Replace('"', '')}); } $Answers += ($ResponseBody.Answer.data | ForEach-Object {$_.Replace('"', '')}) } break } elseif ($ResponseBody.Status -eq 3) { # 3 indicates NXDomain. The DNS query succeeded, but the domain did not exist. $LogEntries += @{ "query_name"=$Qname; "query_method"="DoH"; "query_result"="Query returned NXDomain"; "query_answers"=@(); } $NXDomain = $true break } else { # The remainder of the response codes indicate that the query did not succeed. # Retry if we haven't reached $MaxTries. $LogEntries += @{ "query_name"=$Qname; "query_method"="DoH"; "query_result"="Query returned response code $($ResponseBody.Status)"; "query_answers"=@(); } } } catch { # The DoH query failed, likely due to a network issue. Retry if we haven't reached # $MaxTries. $LogEntries += @{ "query_name"=$Qname; "query_method"="DoH"; "query_result"="Query resulted in exception, $($_.FullyQualifiedErrorId)"; "query_answers"=@(); } $Errors += $_.FullyQualifiedErrorId } } @{ "Answers" = $Answers; "NXDomain" = $NXDomain; "LogEntries" = $LogEntries; "Errors" = $Errors; } } function Get-ScubaSpfRecord { <# .Description Gets the SPF records for each domain in $Domains .Functionality Internal #> [CmdletBinding()] param ( [Parameter(Mandatory=$true)] [ValidateNotNullOrEmpty()] [System.Object[]] $Domains ) $SPFRecords = @() foreach ($d in $Domains) { $Compliant = $false $Response = Invoke-RobustDnsTxt $d.DomainName $DomainName = $d.DomainName if ($Response.Answers.Length -gt 0) { # We got some answers - are they SPF records? $SPFAnswers = ($Response.Answers | Where-Object { $_.StartsWith("v=spf1 ") } ) if ($SPFAnswers.Length -gt 0) { # We have an SPF record - does it hardfail? $SPFReject = ($SPFAnswers | Where-Object { $_.Contains("-all") -or $_.Contains("redirect") } ) if ($SPFReject.Length -gt 0) { # Yes! This is the "good" case $Message = "SPF record found." $Compliant = $true } else { # There is an SPF record but it doesn't hardfail $Message = "SPF record found, but it does not hardfail (`"-all`") or redirect to one that does." } } else { # An answer was returned but it didn't start with "v=spf1 " $Message = "Domain name exists but no SPF records returned." } } # For the three remaining cases, we didn't get an answer elseif ($Response.NXDomain) { $Message = "Domain does not exist." } elseif ($Response.Errors -gt 0) { $Message = "Exceptions other than NXDOMAIN returned." } else { $Message = "Domain name exists but no answers returned." } $SPFRecords += [PSCustomObject]@{ "domain" = $DomainName; "compliant" = $Compliant; "message" = $Message; "rdata" = @($Response.Answers); "log" = $Response.LogEntries; } } $SPFRecords } function Get-ScubaDkimRecord { <# .Description Gets the DKIM records for each domain in $Domains .Functionality Internal #> [CmdletBinding()] param ( [Parameter(Mandatory=$true)] [ValidateNotNullOrEmpty()] [System.Object[]] $Domains ) $DKIMRecords = @() foreach ($d in $domains) { if ($d.IsCoexistenceDomain) { # Skip the coexistence domain (e.g., contoso.mail.onmicrosoft.com). # It's not actually possible to publish custom DNS records for this # domain. continue } $DomainName = $d.DomainName $selectors = "selector1", "selector2" $selectors += "selector1.$DomainName" -replace "\.", "-" $selectors += "selector2.$DomainName" -replace "\.", "-" $LogEntries = @() foreach ($s in $selectors) { $Response = Invoke-RobustDnsTxt "$s._domainkey.$DomainName" $LogEntries += $Response.LogEntries if ($Response.Answers.Length -eq 0) { # The DKIM record does not exist with this selector, we need to try again with # a different one continue } else { # The DKIM record exists with this selector, no need to try the rest break } } $DKIMRecords += [PSCustomObject]@{ "domain" = $DomainName; "rdata" = @($Response.Answers); "log" = $LogEntries; } } $DKIMRecords } function Get-ScubaDmarcRecord { <# .Description Gets the DMARC records for each domain in $Domains .Functionality Internal #> [CmdletBinding()] param ( [Parameter(Mandatory=$true)] [ValidateNotNullOrEmpty()] [System.Object[]] $Domains ) $DMARCRecords = @() foreach ($d in $Domains) { if ($d.IsCoexistenceDomain) { # Skip the coexistence domain (e.g., contoso.mail.onmicrosoft.com). # See https://github.com/cisagov/ScubaGear/issues/1514. continue } $LogEntries = @() # First check to see if the record is available at the full domain level $DomainName = $d.DomainName $Response = Invoke-RobustDnsTxt "_dmarc.$DomainName" $LogEntries += $Response.LogEntries if ($Response.Answers.Length -eq 0) { # The domain does not exist. If the record is not available at the full domain # level, we need to check at the organizational domain level. $Labels = $d.DomainName.Split(".") $Labels = $d.DomainName.Split(".") $OrgDomain = $Labels[-2] + "." + $Labels[-1] $Response = Invoke-RobustDnsTxt "_dmarc.$OrgDomain" $LogEntries += $Response.LogEntries } $DomainName = $d.DomainName $DMARCRecords += [PSCustomObject]@{ "domain" = $DomainName; "rdata" = @($Response.Answers); "log" = $LogEntries; } } $DMARCRecords } # SIG # Begin signature block # MIIuuQYJKoZIhvcNAQcCoIIuqjCCLqYCAQExDzANBglghkgBZQMEAgEFADB5Bgor # BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG # KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCBZ8Eny75nVjpSP # GQKPQKJgUKbj3PVR9/gPx6IgjtS2BaCCE6MwggWQMIIDeKADAgECAhAFmxtXno4h # MuI5B72nd3VcMA0GCSqGSIb3DQEBDAUAMGIxCzAJBgNVBAYTAlVTMRUwEwYDVQQK # EwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xITAfBgNV # BAMTGERpZ2lDZXJ0IFRydXN0ZWQgUm9vdCBHNDAeFw0xMzA4MDExMjAwMDBaFw0z # ODAxMTUxMjAwMDBaMGIxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJ # bmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xITAfBgNVBAMTGERpZ2lDZXJ0 # IFRydXN0ZWQgUm9vdCBHNDCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIB # AL/mkHNo3rvkXUo8MCIwaTPswqclLskhPfKK2FnC4SmnPVirdprNrnsbhA3EMB/z # G6Q4FutWxpdtHauyefLKEdLkX9YFPFIPUh/GnhWlfr6fqVcWWVVyr2iTcMKyunWZ # anMylNEQRBAu34LzB4TmdDttceItDBvuINXJIB1jKS3O7F5OyJP4IWGbNOsFxl7s # Wxq868nPzaw0QF+xembud8hIqGZXV59UWI4MK7dPpzDZVu7Ke13jrclPXuU15zHL # 2pNe3I6PgNq2kZhAkHnDeMe2scS1ahg4AxCN2NQ3pC4FfYj1gj4QkXCrVYJBMtfb # BHMqbpEBfCFM1LyuGwN1XXhm2ToxRJozQL8I11pJpMLmqaBn3aQnvKFPObURWBf3 # JFxGj2T3wWmIdph2PVldQnaHiZdpekjw4KISG2aadMreSx7nDmOu5tTvkpI6nj3c # AORFJYm2mkQZK37AlLTSYW3rM9nF30sEAMx9HJXDj/chsrIRt7t/8tWMcCxBYKqx # YxhElRp2Yn72gLD76GSmM9GJB+G9t+ZDpBi4pncB4Q+UDCEdslQpJYls5Q5SUUd0 # viastkF13nqsX40/ybzTQRESW+UQUOsxxcpyFiIJ33xMdT9j7CFfxCBRa2+xq4aL # T8LWRV+dIPyhHsXAj6KxfgommfXkaS+YHS312amyHeUbAgMBAAGjQjBAMA8GA1Ud # EwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBTs1+OC0nFdZEzf # Lmc/57qYrhwPTzANBgkqhkiG9w0BAQwFAAOCAgEAu2HZfalsvhfEkRvDoaIAjeNk # aA9Wz3eucPn9mkqZucl4XAwMX+TmFClWCzZJXURj4K2clhhmGyMNPXnpbWvWVPjS # PMFDQK4dUPVS/JA7u5iZaWvHwaeoaKQn3J35J64whbn2Z006Po9ZOSJTROvIXQPK # 7VB6fWIhCoDIc2bRoAVgX+iltKevqPdtNZx8WorWojiZ83iL9E3SIAveBO6Mm0eB # cg3AFDLvMFkuruBx8lbkapdvklBtlo1oepqyNhR6BvIkuQkRUNcIsbiJeoQjYUIp # 5aPNoiBB19GcZNnqJqGLFNdMGbJQQXE9P01wI4YMStyB0swylIQNCAmXHE/A7msg # dDDS4Dk0EIUhFQEI6FUy3nFJ2SgXUE3mvk3RdazQyvtBuEOlqtPDBURPLDab4vri # RbgjU2wGb2dVf0a1TD9uKFp5JtKkqGKX0h7i7UqLvBv9R0oN32dmfrJbQdA75PQ7 # 9ARj6e/CVABRoIoqyc54zNXqhwQYs86vSYiv85KZtrPmYQ/ShQDnUBrkG5WdGaG5 # nLGbsQAe79APT0JsyQq87kP6OnGlyE0mpTX9iV28hWIdMtKgK1TtmlfB2/oQzxm3 # i0objwG2J5VT6LaJbVu8aNQj6ItRolb58KaAoNYes7wPD1N1KarqE3fk3oyBIa0H # EEcRrYc9B9F1vM/zZn4wggawMIIEmKADAgECAhAIrUCyYNKcTJ9ezam9k67ZMA0G # CSqGSIb3DQEBDAUAMGIxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJ # bmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xITAfBgNVBAMTGERpZ2lDZXJ0 # IFRydXN0ZWQgUm9vdCBHNDAeFw0yMTA0MjkwMDAwMDBaFw0zNjA0MjgyMzU5NTla # MGkxCzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5EaWdpQ2VydCwgSW5jLjFBMD8GA1UE # AxM4RGlnaUNlcnQgVHJ1c3RlZCBHNCBDb2RlIFNpZ25pbmcgUlNBNDA5NiBTSEEz # ODQgMjAyMSBDQTEwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDVtC9C # 0CiteLdd1TlZG7GIQvUzjOs9gZdwxbvEhSYwn6SOaNhc9es0JAfhS0/TeEP0F9ce # 2vnS1WcaUk8OoVf8iJnBkcyBAz5NcCRks43iCH00fUyAVxJrQ5qZ8sU7H/Lvy0da # E6ZMswEgJfMQ04uy+wjwiuCdCcBlp/qYgEk1hz1RGeiQIXhFLqGfLOEYwhrMxe6T # SXBCMo/7xuoc82VokaJNTIIRSFJo3hC9FFdd6BgTZcV/sk+FLEikVoQ11vkunKoA # FdE3/hoGlMJ8yOobMubKwvSnowMOdKWvObarYBLj6Na59zHh3K3kGKDYwSNHR7Oh # D26jq22YBoMbt2pnLdK9RBqSEIGPsDsJ18ebMlrC/2pgVItJwZPt4bRc4G/rJvmM # 1bL5OBDm6s6R9b7T+2+TYTRcvJNFKIM2KmYoX7BzzosmJQayg9Rc9hUZTO1i4F4z # 8ujo7AqnsAMrkbI2eb73rQgedaZlzLvjSFDzd5Ea/ttQokbIYViY9XwCFjyDKK05 # huzUtw1T0PhH5nUwjewwk3YUpltLXXRhTT8SkXbev1jLchApQfDVxW0mdmgRQRNY # mtwmKwH0iU1Z23jPgUo+QEdfyYFQc4UQIyFZYIpkVMHMIRroOBl8ZhzNeDhFMJlP # /2NPTLuqDQhTQXxYPUez+rbsjDIJAsxsPAxWEQIDAQABo4IBWTCCAVUwEgYDVR0T # AQH/BAgwBgEB/wIBADAdBgNVHQ4EFgQUaDfg67Y7+F8Rhvv+YXsIiGX0TkIwHwYD # VR0jBBgwFoAU7NfjgtJxXWRM3y5nP+e6mK4cD08wDgYDVR0PAQH/BAQDAgGGMBMG # A1UdJQQMMAoGCCsGAQUFBwMDMHcGCCsGAQUFBwEBBGswaTAkBggrBgEFBQcwAYYY # aHR0cDovL29jc3AuZGlnaWNlcnQuY29tMEEGCCsGAQUFBzAChjVodHRwOi8vY2Fj # ZXJ0cy5kaWdpY2VydC5jb20vRGlnaUNlcnRUcnVzdGVkUm9vdEc0LmNydDBDBgNV # HR8EPDA6MDigNqA0hjJodHRwOi8vY3JsMy5kaWdpY2VydC5jb20vRGlnaUNlcnRU # cnVzdGVkUm9vdEc0LmNybDAcBgNVHSAEFTATMAcGBWeBDAEDMAgGBmeBDAEEATAN # BgkqhkiG9w0BAQwFAAOCAgEAOiNEPY0Idu6PvDqZ01bgAhql+Eg08yy25nRm95Ry # sQDKr2wwJxMSnpBEn0v9nqN8JtU3vDpdSG2V1T9J9Ce7FoFFUP2cvbaF4HZ+N3HL # IvdaqpDP9ZNq4+sg0dVQeYiaiorBtr2hSBh+3NiAGhEZGM1hmYFW9snjdufE5Btf # Q/g+lP92OT2e1JnPSt0o618moZVYSNUa/tcnP/2Q0XaG3RywYFzzDaju4ImhvTnh # OE7abrs2nfvlIVNaw8rpavGiPttDuDPITzgUkpn13c5UbdldAhQfQDN8A+KVssIh # dXNSy0bYxDQcoqVLjc1vdjcshT8azibpGL6QB7BDf5WIIIJw8MzK7/0pNVwfiThV # 9zeKiwmhywvpMRr/LhlcOXHhvpynCgbWJme3kuZOX956rEnPLqR0kq3bPKSchh/j # wVYbKyP/j7XqiHtwa+aguv06P0WmxOgWkVKLQcBIhEuWTatEQOON8BUozu3xGFYH # Ki8QxAwIZDwzj64ojDzLj4gLDb879M4ee47vtevLt/B3E+bnKD+sEq6lLyJsQfmC # XBVmzGwOysWGw/YmMwwHS6DTBwJqakAwSEs0qFEgu60bhQjiWQ1tygVQK+pKHJ6l # /aCnHwZ05/LWUpD9r4VIIflXO7ScA+2GRfS0YW6/aOImYIbqyK+p/pQd52MbOoZW # eE4wggdXMIIFP6ADAgECAhAP1uYgxSr4joyBpB/eZOIuMA0GCSqGSIb3DQEBCwUA # MGkxCzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5EaWdpQ2VydCwgSW5jLjFBMD8GA1UE # AxM4RGlnaUNlcnQgVHJ1c3RlZCBHNCBDb2RlIFNpZ25pbmcgUlNBNDA5NiBTSEEz # ODQgMjAyMSBDQTEwHhcNMjUwMjA4MDAwMDAwWhcNMjYwMTE1MjM1OTU5WjBfMQsw # CQYDVQQGEwJVUzEdMBsGA1UECBMURGlzdHJpY3Qgb2YgQ29sdW1iaWExEzARBgNV # BAcTCldhc2hpbmd0b24xDTALBgNVBAoTBENJU0ExDTALBgNVBAMTBENJU0EwggIi # MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCXm3O0IOQzt0tbPPKAv4IrrzOf # QjE4Mb9j1zLL1GehaE35ddnoitE7l8OmVEeTLwPH+UpI7DfynUCjLb8HGcsuHO0H # aUuVFR3FNyvGByYATUTA+bQ9UgcwCoPyL48cDmdqFzheQ/KsC+FhI4uEpYiB/6Jp # Q0UL0SUVfC8O8+1ioUXAwdMt3G8bT3x6WaEmAbGqM5yC5fd7rKZEmpLzpA6bP2Xc # QMwi6Jn1m4AvL/jJrXvPyVUK9UlbjobKjiVg6a/UBgFrq8cU7Q1w/e5ijy6XA+aC # Z7SICqimtCW4wbrvodZL0yFeZIxN9qJ24hvrVGf7P/ANTzkoGHuHLwpMIOjBrpA+ # ig3jBTjY1xE2DYgHWcKHsSHEbOxStk+qHsn2J5i9GK+nwS7GmMqIRaEwy+dbfh6l # Q2jI4PO6kPk0ePnB3jTD/bEkdbRXpuq3aUAMS4ZSESer+CnzeBLEXvHrVVs4yHrf # RPmLOX+T43FEf6iAY7Ta3ahn0icLtCtauJ9/jmMigM/l1IfaAF6E/SoCHc6G6S9F # 1ECU/nBkpThU5u2kufiGWBC8rV2V8D50QERbohnv3yWR5BTG8dX+NYjd7HdctRAj # 9al3sQ/tdyVgOHUp+9KseYJthuNnh8WCoDeho/GX65QJDSJwh5uDcvNUfpeebANU # U1GwatZ4l+EWfOc05QIDAQABo4ICAzCCAf8wHwYDVR0jBBgwFoAUaDfg67Y7+F8R # hvv+YXsIiGX0TkIwHQYDVR0OBBYEFJIsiVnihq62MAlpq96K9lNX9UCGMD4GA1Ud # IAQ3MDUwMwYGZ4EMAQQBMCkwJwYIKwYBBQUHAgEWG2h0dHA6Ly93d3cuZGlnaWNl # cnQuY29tL0NQUzAOBgNVHQ8BAf8EBAMCB4AwEwYDVR0lBAwwCgYIKwYBBQUHAwMw # gbUGA1UdHwSBrTCBqjBToFGgT4ZNaHR0cDovL2NybDMuZGlnaWNlcnQuY29tL0Rp # Z2lDZXJ0VHJ1c3RlZEc0Q29kZVNpZ25pbmdSU0E0MDk2U0hBMzg0MjAyMUNBMS5j # cmwwU6BRoE+GTWh0dHA6Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydFRydXN0 # ZWRHNENvZGVTaWduaW5nUlNBNDA5NlNIQTM4NDIwMjFDQTEuY3JsMIGUBggrBgEF # BQcBAQSBhzCBhDAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQuY29t # MFwGCCsGAQUFBzAChlBodHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vRGlnaUNl # cnRUcnVzdGVkRzRDb2RlU2lnbmluZ1JTQTQwOTZTSEEzODQyMDIxQ0ExLmNydDAJ # BgNVHRMEAjAAMA0GCSqGSIb3DQEBCwUAA4ICAQChGHY/dRc2BtvGT6mHR4bqoakC # N9hyjDA+bbxJE73T2HgI5wKVmhu2JmFZ/FHmoXE4ngnLnGS+zMEoeTEfzb/MmAxF # H+Ca/JGMDsbVf+rP+aVc1NkSpUd6u5rsR01Dimcs+pHGwpEUF1HCDFrFcl10Smcj # b8Z+tPbIETe3yvdRyoJL2Lm6k8wvC7xfgPoMzdbKWRzTCEnVQ+B53vHBSLT4D5wW # dq3yv6oj2fQ381wZQm16fLIedmiStUYfp0ZICqI3T6UiQ5w/DXYy05Z/1Njqu3PQ # l2Sy/JLDZc7hBu5YH5ia1G2IFC6S9gN34jm8qhkkoo8kihsxRBbBLiiNB0z/eH7y # jsNgyRR+Vje51Jcgte18zVQH6fRkl+HDp2nMgdgzShlKYXZzVFQvgmMu76x72P5f # bOgzmOxCZNZh0AQUo16DdbnGvloqHCbEND2JA/0QpeB0dlWKkWiotu/MaJE8/4uU # sxw5JSZPj8ya4WnrntJaY73TxXBHSd9CezT7lDShTgB1FkCSAov3aFwqyGH4hC+2 # MGp3Wzn03rkqVCzjmgNSIkCxQzJ+hEIvbk6GVK2yk+Q9eZQCkjRKY+EYwJNDsB9I # w75dWMsi2S9PFBEkKZYZFgxwVaBvnWgrfxlZMOooNADSdmq5fvTH/tjR3vIEd4QP # Dlzb9f7QLX+cvb0MjjGCGmwwghpoAgEBMH0waTELMAkGA1UEBhMCVVMxFzAVBgNV # BAoTDkRpZ2lDZXJ0LCBJbmMuMUEwPwYDVQQDEzhEaWdpQ2VydCBUcnVzdGVkIEc0 # IENvZGUgU2lnbmluZyBSU0E0MDk2IFNIQTM4NCAyMDIxIENBMQIQD9bmIMUq+I6M # gaQf3mTiLjANBglghkgBZQMEAgEFAKCBhDAYBgorBgEEAYI3AgEMMQowCKACgACh # AoAAMBkGCSqGSIb3DQEJAzEMBgorBgEEAYI3AgEEMBwGCisGAQQBgjcCAQsxDjAM # BgorBgEEAYI3AgEVMC8GCSqGSIb3DQEJBDEiBCAnXPYpM5KlsiWYrvPQVXBdRqEd # HYq+bOnS3Tp9RvdTIzANBgkqhkiG9w0BAQEFAASCAgBPZDu3b0szozzZlQsh4GYu # K7f+NuyhZFsQNHWsOpTuJaGW2owxlv9fgJp0TFGLh8llQofcRPFKn6eBr01Vi7+m # w6OE1M/MjeeEeX0aVqb2zIvxXIUGzF7ycvuJAQ3tS6U4OLN/WhVy1KzZgCYO3E6m # LHCgR0zN2yuvWGeYijAHtjjf2kii4GGpJ5YD9SV1YVJ/2Hcgyt8RApEk9cUap2UK # Vr+k9bo+5mWT7h/toMA/Qgd+stpjDWFfzAn8ZKfmPnvuHO7wsYfSdOE18O9URCfI # o8tqAqIrvNYdpX/GUYjsobIehZGs0GZfh8WnLGKza7oEqlz6H/l9RdRtrV4+akkB # JRjNWck6dVUiQ6gFV0Z9j/5s2shdofuhM09hfuGFX54gxlPdor9DFd+xIeTbOcM9 # /D+FzF5zNTpQIxib3AymbUGftbrHVL5Db4Hkw4Jc93n4/MxeojwTd2gqCrSRAhCy # qr8PF5sR9CLG8PSXCd8OSvKWl44N3xfKns6FpArlU2eyYXvH+aQ5+F9r4uv7MA3b # 4QSETMH0WhTnpl2PCSLlblRfQqLIdfyK74WnEq4VL5LOmQ5HHKcaoZgf+eQ1h4aF # KJA4+xuBFh2j6DwDqiDV94d56QjrNc1g4+B1aJHoYCvwk04Tt0GaR3HJg5vc6mHN # h0KBlNP1KifxEzWkYJIWjaGCFzkwghc1BgorBgEEAYI3AwMBMYIXJTCCFyEGCSqG # SIb3DQEHAqCCFxIwghcOAgEDMQ8wDQYJYIZIAWUDBAIBBQAwdwYLKoZIhvcNAQkQ # AQSgaARmMGQCAQEGCWCGSAGG/WwHATAxMA0GCWCGSAFlAwQCAQUABCC9vHlyblU/ # a1xtIFABLZi6pZdXAcMgNYaSEMTN6VPtEQIQFZTQACdmlKPuaFjoOJXAUBgPMjAy # NTA3MDkwMDU1MjBaoIITAzCCBrwwggSkoAMCAQICEAuuZrxaun+Vh8b56QTjMwQw # DQYJKoZIhvcNAQELBQAwYzELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDkRpZ2lDZXJ0 # LCBJbmMuMTswOQYDVQQDEzJEaWdpQ2VydCBUcnVzdGVkIEc0IFJTQTQwOTYgU0hB # MjU2IFRpbWVTdGFtcGluZyBDQTAeFw0yNDA5MjYwMDAwMDBaFw0zNTExMjUyMzU5 # NTlaMEIxCzAJBgNVBAYTAlVTMREwDwYDVQQKEwhEaWdpQ2VydDEgMB4GA1UEAxMX # RGlnaUNlcnQgVGltZXN0YW1wIDIwMjQwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAw # ggIKAoICAQC+anOf9pUhq5Ywultt5lmjtej9kR8YxIg7apnjpcH9CjAgQxK+CMR0 # Rne/i+utMeV5bUlYYSuuM4vQngvQepVHVzNLO9RDnEXvPghCaft0djvKKO+hDu6O # bS7rJcXa/UKvNminKQPTv/1+kBPgHGlP28mgmoCw/xi6FG9+Un1h4eN6zh926SxM # e6We2r1Z6VFZj75MU/HNmtsgtFjKfITLutLWUdAoWle+jYZ49+wxGE1/UXjWfISD # mHuI5e/6+NfQrxGFSKx+rDdNMsePW6FLrphfYtk/FLihp/feun0eV+pIF496OVh4 # R1TvjQYpAztJpVIfdNsEvxHofBf1BWkadc+Up0Th8EifkEEWdX4rA/FE1Q0rqViT # bLVZIqi6viEk3RIySho1XyHLIAOJfXG5PEppc3XYeBH7xa6VTZ3rOHNeiYnY+V4j # 1XbJ+Z9dI8ZhqcaDHOoj5KGg4YuiYx3eYm33aebsyF6eD9MF5IDbPgjvwmnAalNE # eJPvIeoGJXaeBQjIK13SlnzODdLtuThALhGtyconcVuPI8AaiCaiJnfdzUcb3dWn # qUnjXkRFwLtsVAxFvGqsxUA2Jq/WTjbnNjIUzIs3ITVC6VBKAOlb2u29Vwgfta8b # 2ypi6n2PzP0nVepsFk8nlcuWfyZLzBaZ0MucEdeBiXL+nUOGhCjl+QIDAQABo4IB # izCCAYcwDgYDVR0PAQH/BAQDAgeAMAwGA1UdEwEB/wQCMAAwFgYDVR0lAQH/BAww # CgYIKwYBBQUHAwgwIAYDVR0gBBkwFzAIBgZngQwBBAIwCwYJYIZIAYb9bAcBMB8G # A1UdIwQYMBaAFLoW2W1NhS9zKXaaL3WMaiCPnshvMB0GA1UdDgQWBBSfVywDdw4o # FZBmpWNe7k+SH3agWzBaBgNVHR8EUzBRME+gTaBLhklodHRwOi8vY3JsMy5kaWdp # Y2VydC5jb20vRGlnaUNlcnRUcnVzdGVkRzRSU0E0MDk2U0hBMjU2VGltZVN0YW1w # aW5nQ0EuY3JsMIGQBggrBgEFBQcBAQSBgzCBgDAkBggrBgEFBQcwAYYYaHR0cDov # L29jc3AuZGlnaWNlcnQuY29tMFgGCCsGAQUFBzAChkxodHRwOi8vY2FjZXJ0cy5k # aWdpY2VydC5jb20vRGlnaUNlcnRUcnVzdGVkRzRSU0E0MDk2U0hBMjU2VGltZVN0 # YW1waW5nQ0EuY3J0MA0GCSqGSIb3DQEBCwUAA4ICAQA9rR4fdplb4ziEEkfZQ5H2 # EdubTggd0ShPz9Pce4FLJl6reNKLkZd5Y/vEIqFWKt4oKcKz7wZmXa5VgW9B76k9 # NJxUl4JlKwyjUkKhk3aYx7D8vi2mpU1tKlY71AYXB8wTLrQeh83pXnWwwsxc1Mt+ # FWqz57yFq6laICtKjPICYYf/qgxACHTvypGHrC8k1TqCeHk6u4I/VBQC9VK7iSpU # 5wlWjNlHlFFv/M93748YTeoXU/fFa9hWJQkuzG2+B7+bMDvmgF8VlJt1qQcl7YFU # MYgZU1WM6nyw23vT6QSgwX5Pq2m0xQ2V6FJHu8z4LXe/371k5QrN9FQBhLLISZi2 # yemW0P8ZZfx4zvSWzVXpAb9k4Hpvpi6bUe8iK6WonUSV6yPlMwerwJZP/Gtbu3CK # ldMnn+LmmRTkTXpFIEB06nXZrDwhCGED+8RsWQSIXZpuG4WLFQOhtloDRWGoCwwc # 6ZpPddOFkM2LlTbMcqFSzm4cd0boGhBq7vkqI1uHRz6Fq1IX7TaRQuR+0BGOzISk # cqwXu7nMpFu3mgrlgbAW+BzikRVQ3K2YHcGkiKjA4gi4OA/kz1YCsdhIBHXqBzR0 # /Zd2QwQ/l4Gxftt/8wY3grcc/nS//TVkej9nmUYu83BDtccHHXKibMs/yXHhDXNk # oPIdynhVAku7aRZOwqw6pDCCBq4wggSWoAMCAQICEAc2N7ckVHzYR6z9KGYqXlsw # DQYJKoZIhvcNAQELBQAwYjELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0 # IEluYzEZMBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTEhMB8GA1UEAxMYRGlnaUNl # cnQgVHJ1c3RlZCBSb290IEc0MB4XDTIyMDMyMzAwMDAwMFoXDTM3MDMyMjIzNTk1 # OVowYzELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDkRpZ2lDZXJ0LCBJbmMuMTswOQYD # VQQDEzJEaWdpQ2VydCBUcnVzdGVkIEc0IFJTQTQwOTYgU0hBMjU2IFRpbWVTdGFt # cGluZyBDQTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMaGNQZJs8E9 # cklRVcclA8TykTepl1Gh1tKD0Z5Mom2gsMyD+Vr2EaFEFUJfpIjzaPp985yJC3+d # H54PMx9QEwsmc5Zt+FeoAn39Q7SE2hHxc7Gz7iuAhIoiGN/r2j3EF3+rGSs+Qtxn # jupRPfDWVtTnKC3r07G1decfBmWNlCnT2exp39mQh0YAe9tEQYncfGpXevA3eZ9d # rMvohGS0UvJ2R/dhgxndX7RUCyFobjchu0CsX7LeSn3O9TkSZ+8OpWNs5KbFHc02 # DVzV5huowWR0QKfAcsW6Th+xtVhNef7Xj3OTrCw54qVI1vCwMROpVymWJy71h6aP # TnYVVSZwmCZ/oBpHIEPjQ2OAe3VuJyWQmDo4EbP29p7mO1vsgd4iFNmCKseSv6De # 4z6ic/rnH1pslPJSlRErWHRAKKtzQ87fSqEcazjFKfPKqpZzQmiftkaznTqj1QPg # v/CiPMpC3BhIfxQ0z9JMq++bPf4OuGQq+nUoJEHtQr8FnGZJUlD0UfM2SU2LINIs # VzV5K6jzRWC8I41Y99xh3pP+OcD5sjClTNfpmEpYPtMDiP6zj9NeS3YSUZPJjAw7 # W4oiqMEmCPkUEBIDfV8ju2TjY+Cm4T72wnSyPx4JduyrXUZ14mCjWAkBKAAOhFTu # zuldyF4wEr1GnrXTdrnSDmuZDNIztM2xAgMBAAGjggFdMIIBWTASBgNVHRMBAf8E # CDAGAQH/AgEAMB0GA1UdDgQWBBS6FtltTYUvcyl2mi91jGogj57IbzAfBgNVHSME # GDAWgBTs1+OC0nFdZEzfLmc/57qYrhwPTzAOBgNVHQ8BAf8EBAMCAYYwEwYDVR0l # BAwwCgYIKwYBBQUHAwgwdwYIKwYBBQUHAQEEazBpMCQGCCsGAQUFBzABhhhodHRw # Oi8vb2NzcC5kaWdpY2VydC5jb20wQQYIKwYBBQUHMAKGNWh0dHA6Ly9jYWNlcnRz # LmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydFRydXN0ZWRSb290RzQuY3J0MEMGA1UdHwQ8 # MDowOKA2oDSGMmh0dHA6Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydFRydXN0 # ZWRSb290RzQuY3JsMCAGA1UdIAQZMBcwCAYGZ4EMAQQCMAsGCWCGSAGG/WwHATAN # BgkqhkiG9w0BAQsFAAOCAgEAfVmOwJO2b5ipRCIBfmbW2CFC4bAYLhBNE88wU86/ # GPvHUF3iSyn7cIoNqilp/GnBzx0H6T5gyNgL5Vxb122H+oQgJTQxZ822EpZvxFBM # Yh0MCIKoFr2pVs8Vc40BIiXOlWk/R3f7cnQU1/+rT4osequFzUNf7WC2qk+RZp4s # nuCKrOX9jLxkJodskr2dfNBwCnzvqLx1T7pa96kQsl3p/yhUifDVinF2ZdrM8HKj # I/rAJ4JErpknG6skHibBt94q6/aesXmZgaNWhqsKRcnfxI2g55j7+6adcq/Ex8HB # anHZxhOACcS2n82HhyS7T6NJuXdmkfFynOlLAlKnN36TU6w7HQhJD5TNOXrd/yVj # mScsPT9rp/Fmw0HNT7ZAmyEhQNC3EyTN3B14OuSereU0cZLXJmvkOHOrpgFPvT87 # eK1MrfvElXvtCl8zOYdBeHo46Zzh3SP9HSjTx/no8Zhf+yvYfvJGnXUsHicsJttv # FXseGYs2uJPU5vIXmVnKcPA3v5gA3yAWTyf7YGcWoWa63VXAOimGsJigK+2VQbc6 # 1RWYMbRiCQ8KvYHZE/6/pNHzV9m8BPqC3jLfBInwAM1dwvnQI38AC+R2AibZ8GV2 # QqYphwlHK+Z/GqSFD/yYlvZVVCsfgPrA8g4r5db7qS9EFUrnEw4d2zc4GqEr9u3W # fPwwggWNMIIEdaADAgECAhAOmxiO+dAt5+/bUOIIQBhaMA0GCSqGSIb3DQEBDAUA # MGUxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsT # EHd3dy5kaWdpY2VydC5jb20xJDAiBgNVBAMTG0RpZ2lDZXJ0IEFzc3VyZWQgSUQg # Um9vdCBDQTAeFw0yMjA4MDEwMDAwMDBaFw0zMTExMDkyMzU5NTlaMGIxCzAJBgNV # BAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdp # Y2VydC5jb20xITAfBgNVBAMTGERpZ2lDZXJ0IFRydXN0ZWQgUm9vdCBHNDCCAiIw # DQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAL/mkHNo3rvkXUo8MCIwaTPswqcl # LskhPfKK2FnC4SmnPVirdprNrnsbhA3EMB/zG6Q4FutWxpdtHauyefLKEdLkX9YF # PFIPUh/GnhWlfr6fqVcWWVVyr2iTcMKyunWZanMylNEQRBAu34LzB4TmdDttceIt # DBvuINXJIB1jKS3O7F5OyJP4IWGbNOsFxl7sWxq868nPzaw0QF+xembud8hIqGZX # V59UWI4MK7dPpzDZVu7Ke13jrclPXuU15zHL2pNe3I6PgNq2kZhAkHnDeMe2scS1 # ahg4AxCN2NQ3pC4FfYj1gj4QkXCrVYJBMtfbBHMqbpEBfCFM1LyuGwN1XXhm2Tox # RJozQL8I11pJpMLmqaBn3aQnvKFPObURWBf3JFxGj2T3wWmIdph2PVldQnaHiZdp # ekjw4KISG2aadMreSx7nDmOu5tTvkpI6nj3cAORFJYm2mkQZK37AlLTSYW3rM9nF # 30sEAMx9HJXDj/chsrIRt7t/8tWMcCxBYKqxYxhElRp2Yn72gLD76GSmM9GJB+G9 # t+ZDpBi4pncB4Q+UDCEdslQpJYls5Q5SUUd0viastkF13nqsX40/ybzTQRESW+UQ # UOsxxcpyFiIJ33xMdT9j7CFfxCBRa2+xq4aLT8LWRV+dIPyhHsXAj6KxfgommfXk # aS+YHS312amyHeUbAgMBAAGjggE6MIIBNjAPBgNVHRMBAf8EBTADAQH/MB0GA1Ud # DgQWBBTs1+OC0nFdZEzfLmc/57qYrhwPTzAfBgNVHSMEGDAWgBRF66Kv9JLLgjEt # UYunpyGd823IDzAOBgNVHQ8BAf8EBAMCAYYweQYIKwYBBQUHAQEEbTBrMCQGCCsG # AQUFBzABhhhodHRwOi8vb2NzcC5kaWdpY2VydC5jb20wQwYIKwYBBQUHMAKGN2h0 # dHA6Ly9jYWNlcnRzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJRFJvb3RD # QS5jcnQwRQYDVR0fBD4wPDA6oDigNoY0aHR0cDovL2NybDMuZGlnaWNlcnQuY29t # L0RpZ2lDZXJ0QXNzdXJlZElEUm9vdENBLmNybDARBgNVHSAECjAIMAYGBFUdIAAw # DQYJKoZIhvcNAQEMBQADggEBAHCgv0NcVec4X6CjdBs9thbX979XB72arKGHLOyF # XqkauyL4hxppVCLtpIh3bb0aFPQTSnovLbc47/T/gLn4offyct4kvFIDyE7QKt76 # LVbP+fT3rDB6mouyXtTP0UNEm0Mh65ZyoUi0mcudT6cGAxN3J0TU53/oWajwvy8L # punyNDzs9wPHh6jSTEAZNUZqaVSwuKFWjuyk1T3osdz9HNj0d1pcVIxv76FQPfx2 # CWiEn2/K2yCNNWAcAgPLILCsWKAOQGPFmCLBsln1VWvPJ6tsds5vIy30fnFqI2si # /xK4VC0nftg62fC2h5b9W9FcrBjDTZ9ztwGpn1eqXijiuZQxggN2MIIDcgIBATB3 # MGMxCzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5EaWdpQ2VydCwgSW5jLjE7MDkGA1UE # AxMyRGlnaUNlcnQgVHJ1c3RlZCBHNCBSU0E0MDk2IFNIQTI1NiBUaW1lU3RhbXBp # bmcgQ0ECEAuuZrxaun+Vh8b56QTjMwQwDQYJYIZIAWUDBAIBBQCggdEwGgYJKoZI # hvcNAQkDMQ0GCyqGSIb3DQEJEAEEMBwGCSqGSIb3DQEJBTEPFw0yNTA3MDkwMDU1 # MjBaMCsGCyqGSIb3DQEJEAIMMRwwGjAYMBYEFNvThe5i29I+e+T2cUhQhyTVhltF # MC8GCSqGSIb3DQEJBDEiBCAsIMPE3E2t1DckdpUWSSla8EamLp8JHCnimq+1Llby # 5TA3BgsqhkiG9w0BCRACLzEoMCYwJDAiBCB2dp+o8mMvH0MLOiMwrtZWdf7Xc9sF # 1mW5BZOYQ4+a2zANBgkqhkiG9w0BAQEFAASCAgCYTEompgCP/MCDCT8D2tD3zDBA # pxHF+SqkWUBlKXY2/bIE8g4XeDRIjPsdF1tdVCY1nafz3PhQxQc/lzeuWj4EOEuy # SNjshTjA8bfc7an3JlsrgnFa/HxAzMKvuD7bCAHwJUEQ+TCTE9wjwsCkXySPX2MF # 7qhH210dyFl6l2RvAh2s8BRaXz8RXTuKgW9vDyXfxrGdAWgC1veVYxITpwuO36QD # akU9SHdCiQFi05hOqF2yy7KVA9iHR21tktd4TfEs8ON8LtLfquzwgOyOk1ToZ2Fh # cn9rC03OEz3+Irxpops6WKtdTb74ARxWixhxNP/n1aPb6dRZ4foPtXpQGpbVlKB4 # q3tAOznn4lMdoMd+X+AtDBNOTkdPMZEWNXLSiyQrxilrK7O/Y5qYbS1BMQj0AXjE # nn9ak28eOXK9/LUo8zUjRHGBMLMk/5qftZ1+ZJHnU9EEVfD+K+uRxmRYnv6W63r6 # i9ZwQ6jOAn4+XHN6tjvnhEN3jLeE6Q07zk+G3+xBCqba0ej8pGNcGp9TvEzDYRyq # q7IClywciLIQxCYUSCi9yOF4B/gyL++9euBV5uxs6SpTddSYzypCgVTZ9CvnxIqG # J4fDhXZNvHQw2XcpRG6UcTIdsf6TsekVBnqh9S5QwQrmVqm4weEpOXTrQeTpxEYK # Ur/ljiztuH+SBG3IRQ== # SIG # End signature block |