Modules/Providers/ProviderHelpers/AADRiskyPermissionsHelper.psm1
Import-Module -Name $PSScriptRoot/../../Utility/Utility.psm1 -Function Invoke-GraphDirectly, ConvertFrom-GraphHashtable function Get-ResourcePermissions { param( [ValidateNotNullOrEmpty()] [string] $M365Environment, [hashtable] $ResourcePermissionCache, [string] $ResourceAppId ) try { if ($null -eq $ResourcePermissionCache) { $ResourcePermissionCache = @{} } if (-not $ResourcePermissionCache.ContainsKey($ResourceAppId)) { # v1.0 Graph endpoint is used here because it contains the oauth2PermissionScopes property $result = ( Invoke-GraphDirectly ` -Commandlet "Get-MgServicePrincipal" ` -M365Environment $M365Environment ` -QueryParams @{ '$filter' = "appId eq '$ResourceAppId'" '$select' = "appRoles,oauth2PermissionScopes" } ).Value $ResourcePermissionCache[$ResourceAppId] = $result } return $ResourcePermissionCache[$ResourceAppId] } catch { Write-Warning "An error occurred in Get-ResourcePermissions: $($_.Exception.Message)" Write-Warning "Stack trace: $($_.ScriptStackTrace)" throw $_ } } function Get-RiskyPermissionsJson { process { try { $PermissionsPath = Join-Path -Path ((Get-Item -Path $PSScriptRoot).Parent.Parent.FullName) -ChildPath "Permissions" $PermissionsJson = Get-Content -Path ( Join-Path -Path (Get-Item -Path $PermissionsPath) -ChildPath "RiskyPermissions.json" ) | ConvertFrom-Json } catch { Write-Warning "An error occurred in Get-RiskyPermissionsJson: $($_.Exception.Message)" Write-Warning "Stack trace: $($_.ScriptStackTrace)" throw $_ } return $PermissionsJson } } function Format-Permission { <# .Description Returns an API permission from either application/service principal which maps to the list of permissions declared in RiskyPermissions.json .Functionality #Internal ##> param ( [ValidateNotNullOrEmpty()] [PSCustomObject] $Json, [ValidateNotNullOrEmpty()] [string] $AppDisplayName, [ValidateNotNullOrEmpty()] [string] $Id, [string] $RoleType, [string] $RoleDisplayName, [ValidateNotNullOrEmpty()] [boolean] $IsAdminConsented ) $RiskyPermissions = $Json.permissions.$AppDisplayName.PSObject.Properties.Name $Map = @() $IsRisky = $RiskyPermissions -contains $Id $Map += [PSCustomObject]@{ RoleId = $Id RoleType = if ($null -ne $RoleType) { $RoleType } else { $null } RoleDisplayName = if ($null -ne $RoleDisplayName) { $RoleDisplayName } else { $null } ApplicationDisplayName = $AppDisplayName IsAdminConsented = $IsAdminConsented IsRisky = $IsRisky } return $Map } function Format-Credentials { <# .Description Returns an array of valid/expired credentials .Functionality #Internal ##> [Diagnostics.CodeAnalysis.SuppressMessageAttribute( "PSReviewUnusedParameter", "IsFromApplication", Justification = "False positive due to variable scoping" )] param ( [Object[]] $AccessKeys, [ValidateNotNullOrEmpty()] [boolean] $IsFromApplication ) process { $ValidCredentials = @() $RequiredKeys = @("KeyId", "DisplayName", "StartDateTime", "EndDateTime") foreach ($Credential in $AccessKeys) { # Only format credentials with the correct keys $MissingKeys = $RequiredKeys | Where-Object { -not ($Credential.PSObject.Properties.Name -contains $_) } if ($MissingKeys.Count -eq 0) { # $Credential is of type PSCredential which is immutable, create a copy $CredentialCopy = $Credential | Select-Object -Property ` KeyId, DisplayName, StartDateTime, EndDateTime, ` @{ Name = "IsFromApplication"; Expression = { $IsFromApplication }} $ValidCredentials += $CredentialCopy } } if ($null -eq $AccessKeys -or $AccessKeys.Count -eq 0 -or $ValidCredentials.Count -eq 0) { return $null } return $ValidCredentials } } function Merge-Credentials { <# .Description Merge credentials from multiple resources into a single resource .Functionality #Internal ##> param ( [Object[]] $ApplicationAccessKeys, [Object[]] $ServicePrincipalAccessKeys ) # Both application/sp objects have key and federated credentials. # Conditionally merge the two together, select only application/service principal creds, or none. $MergedCredentials = @() if ($null -ne $ServicePrincipalAccessKeys -and $null -ne $ApplicationAccessKeys) { # Both objects valid $MergedCredentials = @($ServicePrincipalAccessKeys) + @($ApplicationAccessKeys) } elseif ($null -eq $ServicePrincipalAccessKeys -and $null -ne $ApplicationAccessKeys) { # Only application credentials valid $MergedCredentials = @($ApplicationAccessKeys) } elseif ($null -ne $ServicePrincipalAccessKeys -and $null -eq $ApplicationAccessKeys) { # Only service principal credentials valid $MergedCredentials = @($ServicePrincipalAccessKeys) } else { # Neither credentials are valid $MergedCredentials = $null } return $MergedCredentials } function Get-ServicePrincipalAll { <# .Description Returns all service principals in the tenant, this is used to determine if they have risky permissions. .PARAMETER M365Environment The M365 environment to use for the Graph API call. This is used to determine the correct endpoint for the API call. .EXAMPLE Get-ServicePrincipalAll -M365Environment commercial Returns all service principals in the tenant for the commercial environment. #> param ( [ValidateNotNullOrEmpty()] [string] $M365Environment ) # Initialize an empty array to store all service principals $allServicePrincipals = @() # Get the first page of results $result = Invoke-GraphDirectly -commandlet "Get-MgBetaServicePrincipal" -M365Environment $M365Environment # Add the current page of service principals to our collection if ($result.Value) { $allServicePrincipals += $result.Value } # Continue fetching next pages as long as there's a nextLink while ($result.'@odata.nextLink') { # Extract the URI from the nextLink $nextLink = $result.'@odata.nextLink' # Use the URI directly for the next request $result = Invoke-MgGraphRequest -Uri $nextLink -Method "GET" # Add the new page of results to our collection if ($result.Value) { $allServicePrincipals += $result.Value } } return $allServicePrincipals } function Get-ApplicationsWithRiskyPermissions { <# .Description Returns an array of applications where each item contains its Object ID, App ID, Display Name, Key/Password/Federated Credentials, and risky API permissions. .Functionality #Internal ##> param ( [ValidateNotNullOrEmpty()] [string] $M365Environment, [hashtable] $ResourcePermissionCache ) process { try { $RiskyPermissionsJson = Get-RiskyPermissionsJson # Get all applications in the tenant $Applications = (Invoke-GraphDirectly -commandlet "Get-MgBetaApplication" -M365Environment $M365Environment).Value $ApplicationResults = @() foreach ($App in $Applications) { # `AzureADMyOrg` = single tenant; `AzureADMultipleOrgs` = multi tenant $IsMultiTenantEnabled = $false if ($App.SignInAudience -eq "AzureADMultipleOrgs") { $IsMultiTenantEnabled = $true } # Map application permissions against RiskyPermissions.json $MappedPermissions = @() foreach ($Resource in $App.RequiredResourceAccess) { # Returns both application and delegated permissions $Roles = $Resource.ResourceAccess $ResourceAppId = $Resource.ResourceAppId $ResourceAppPermissions = Get-ResourcePermissions ` -M365Environment $M365Environment ` -ResourcePermissionCache $ResourcePermissionCache ` -ResourceAppId $ResourceAppId if ($null -eq $ResourceAppPermissions) { Write-Warning "No permissions found for resource app ID: $ResourceAppId" continue } # Additional processing is required to determine if a permission is admin consented. # Initially assume admin consent is false since we reference the application's manifest, # then update the value later when its compared to service principal permissions. $IsAdminConsented = $false # Only map on resources stored in RiskyPermissions.json file if ($RiskyPermissionsJson.resources.PSObject.Properties.Name -contains $ResourceAppId) { foreach ($Role in $Roles) { $ResourceDisplayName = $RiskyPermissionsJson.resources.$ResourceAppId $RoleId = $Role.Id if ($Role.Type -eq "Role") { $ReadableRoleType = "Application" $RoleDisplayName = ($ResourceAppPermissions.appRoles | Where-Object { $_.id -eq $RoleId }).value } else { $ReadableRoleType = "Delegated" $RoleDisplayName = ($ResourceAppPermissions.oauth2PermissionScopes | Where-Object { $_.id -eq $RoleId }).value } $MappedPermissions += Format-Permission ` -Json $RiskyPermissionsJson ` -AppDisplayName $ResourceDisplayName ` -Id $RoleId ` -RoleType $ReadableRoleType ` -RoleDisplayName $RoleDisplayName ` -IsAdminConsented $IsAdminConsented } } } # Get the application credentials via Invoke-GraphDirectly $FederatedCredentials = (Invoke-GraphDirectly -commandlet "Get-MgBetaApplicationFederatedIdentityCredential" -M365Environment $M365Environment -Id $App.Id).Value $FederatedCredentialsResults = @() if ($null -ne $FederatedCredentials) { foreach ($FederatedCredential in $FederatedCredentials) { $FederatedCredentialsResults += [PSCustomObject]@{ Id = $FederatedCredential.Id Name = $FederatedCredential.Name Description = $FederatedCredential.Description Issuer = $FederatedCredential.Issuer Subject = $FederatedCredential.Subject Audiences = $FederatedCredential.Audiences | Out-String } } } else { $FederatedCredentialsResults = $null } # Exclude applications without risky permissions if ($MappedPermissions.Count -gt 0) { $ApplicationResults += [PSCustomObject]@{ ObjectId = $App.Id AppId = $App.AppId DisplayName = $App.DisplayName IsMultiTenantEnabled = $IsMultiTenantEnabled # Credentials from application and service principal objects may get merged in other cmdlets. # Differentiate between the two by setting IsFromApplication=$true KeyCredentials = Format-Credentials -AccessKeys $App.KeyCredentials -IsFromApplication $true PasswordCredentials = Format-Credentials -AccessKeys $App.PasswordCredentials -IsFromApplication $true FederatedCredentials = $FederatedCredentialsResults Permissions = $MappedPermissions } } } } catch { Write-Warning "An error occurred in Get-ApplicationsWithRiskyPermissions: $($_.Exception.Message)" Write-Warning "Stack trace: $($_.ScriptStackTrace)" throw $_ } return $ApplicationResults } } function Get-ServicePrincipalsWithRiskyPermissions { <# .Description Returns an array of service principals where each item contains its Object ID, App ID, Display Name, Key/Password Credentials, and risky API permissions. .Functionality #Internal ##> param ( [ValidateNotNullOrEmpty()] [string] $M365Environment, [hashtable] $ResourcePermissionCache ) process { try { $RiskyPermissionsJson = Get-RiskyPermissionsJson $ServicePrincipalResults = @() # Get all service principals including ones owned by Microsoft $ServicePrincipals = Get-ServicePrincipalAll -M365Environment $M365Environment # Prepare service principal IDs for batch processing $ServicePrincipalIds = $ServicePrincipals.Id # Split the service principal IDs into chunks of 20 $Chunks = [System.Collections.Generic.List[System.Object]]::new() $ChunkSize = 20 for ($i = 0; $i -lt $ServicePrincipalIds.Count; $i += $ChunkSize) { $Chunks.Add($ServicePrincipalIds[$i..([math]::Min($i + $ChunkSize - 1, $ServicePrincipalIds.Count - 1))]) } $endpoint = '/beta/$batch' $endpoint = (Get-ScubaGearPermissions -CmdletName Connect-MgGraph -Environment $M365Environment -OutAs endpoint) + $endpoint # Process each chunk foreach ($Chunk in $Chunks) { $BatchBody = @{ Requests = @() } foreach ($ServicePrincipalId in $Chunk) { $BatchBody.Requests += @{ id = $ServicePrincipalId method = "GET" url = "/servicePrincipals/$ServicePrincipalId/appRoleAssignments" } } # Send the batch request $Response = Invoke-MgGraphRequest -Method POST -Uri $endpoint -Body ( $BatchBody | ConvertTo-Json -Depth 5 ) # Check the response if ($Response.responses) { foreach ($Result in $Response.responses) { $ServicePrincipalId = $Result.id $ServicePrincipal = $ServicePrincipals | Where-Object { $_.Id -eq $ServicePrincipalId } $MappedPermissions = @() if ($Result.status -eq 200) { $AppRoleAssignments = $Result.body.value if ($AppRoleAssignments.Count -gt 0) { foreach ($Role in $AppRoleAssignments) { $ResourceDisplayName = $Role.ResourceDisplayName $RoleId = $Role.AppRoleId # Default to true, # `Get-MgBetaServicePrincipalAppRoleAssignment` only returns admin consented permissions $IsAdminConsented = $true # Only map on resources stored in RiskyPermissions.json file if ($RiskyPermissionsJson.permissions.PSObject.Properties.Name -contains $ResourceDisplayName) { $ResourceAppId = $RiskyPermissionsJson.resources.PSObject.Properties | Where-Object { $_.Value -eq $ResourceDisplayName } | Select-Object -ExpandProperty Name $ResourceAppPermissions = Get-ResourcePermissions ` -M365Environment $M365Environment ` -ResourcePermissionCache $ResourcePermissionCache ` -ResourceAppId $ResourceAppId if ($null -eq $ResourceAppPermissions) { Write-Warning "No permissions found for resource app ID: $ResourceAppId" continue } $ReadableRoleType = $null $RoleDisplayName = $null $AppRole = $ResourceAppPermissions.appRoles | Where-Object { $_.id -eq $RoleId } if ($null -ne $AppRole) { $ReadableRoleType = "Application" $RoleDisplayName = $AppRole.value } else { $OauthScope = $ResourceAppPermissions.oauth2PermissionScopes | Where-Object { $_.id -eq $RoleId } if ($null -ne $OauthScope) { $ReadableRoleType = "Delegated" $RoleDisplayName = $OauthScope.value } } $MappedPermissions += Format-Permission ` -Json $RiskyPermissionsJson ` -AppDisplayName $ResourceDisplayName ` -Id $RoleId ` -RoleType $ReadableRoleType ` -RoleDisplayName $RoleDisplayName ` -IsAdminConsented $IsAdminConsented } } } } else { Write-Warning "Error for service principal $($Result.id): $($Result.status)" } # Exclude service principals without risky permissions if ($MappedPermissions.Count -gt 0) { $ServicePrincipalResults += [PSCustomObject]@{ ObjectId = $ServicePrincipal.Id AppId = $ServicePrincipal.AppId DisplayName = $ServicePrincipal.DisplayName SignInAudience = $ServicePrincipal.SignInAudience # Credentials from application and service principal objects may get merged in other cmdlets. # Differentiate between the two by setting IsFromApplication=$false KeyCredentials = Format-Credentials -AccessKeys $ServicePrincipal.KeyCredentials -IsFromApplication $false PasswordCredentials = Format-Credentials -AccessKeys $ServicePrincipal.PasswordCredentials -IsFromApplication $false FederatedCredentials = $ServicePrincipal.FederatedIdentityCredentials Permissions = $MappedPermissions AppOwnerOrganizationId = $ServicePrincipal.AppOwnerOrganizationId } } } } } } catch { Write-Warning "An error occurred in Get-ServicePrincipalsWithRiskyPermissions: $($_.Exception.Message)" Write-Warning "Stack trace: $($_.ScriptStackTrace)" throw $_ } return $ServicePrincipalResults } } function Format-RiskyApplications { <# .Description Returns an aggregated JSON dataset of application objects, combining data from both applications and service principal objects. Key/Password/Federated credentials are combined into a single array, and admin consent is reflected in each object's list of associated risky permissions. .Functionality #Internal ##> param ( [ValidateNotNullOrEmpty()] [Object[]] $RiskyApps, [ValidateNotNullOrEmpty()] [Object[]] $RiskySPs ) process { try { $Applications = @() foreach ($App in $RiskyApps) { $MatchedServicePrincipal = $RiskySPs | Where-Object { $_.AppId -eq $App.AppId } # Merge objects if an application and service principal exist with the same AppId $MergedObject = @{} if ($MatchedServicePrincipal) { # Determine if each risky permission was admin consented or not foreach ($Permission in $App.Permissions) { $ServicePrincipalRoleIds = $MatchedServicePrincipal.Permissions | Select-Object -ExpandProperty RoleId if ($ServicePrincipalRoleIds -contains $Permission.RoleId) { $Permission.IsAdminConsented = $true } } $ObjectIds = [PSCustomObject]@{ Application = $App.ObjectId ServicePrincipal = $MatchedServicePrincipal.ObjectId } $MergedKeyCredentials = Merge-Credentials ` -ApplicationAccessKeys $App.KeyCredentials ` -ServicePrincipalAccessKeys $MatchedServicePrincipal.KeyCredentials $MergedPasswordCredentials = Merge-Credentials ` -ApplicationAccessKeys $App.PasswordCredentials ` -ServicePrincipalAccessKeys $MatchedServicePrincipal.PasswordCredentials $MergedFederatedCredentials = Merge-Credentials ` -ApplicationAccessKeys $App.FederatedCredentials ` -ServicePrincipalAccessKeys $MatchedServicePrincipal.FederatedCredentials $MergedObject = [PSCustomObject]@{ ObjectId = $ObjectIds AppId = $App.AppId DisplayName = $App.DisplayName IsMultiTenantEnabled = $App.IsMultiTenantEnabled KeyCredentials = $MergedKeyCredentials PasswordCredentials = $MergedPasswordCredentials FederatedCredentials = $MergedFederatedCredentials Permissions = $App.Permissions } } else { $MergedObject = $App } $Applications += $MergedObject } } catch { Write-Warning "An error occurred in Format-RiskyApplications: $($_.Exception.Message)" Write-Warning "Stack trace: $($_.ScriptStackTrace)" throw $_ } return $Applications } } function Format-RiskyThirdPartyServicePrincipals { <# .Description Returns a JSON dataset of service principal objects owned by external organizations. .Functionality #Internal ##> param ( [ValidateNotNullOrEmpty()] [Object[]] $RiskySPs, [ValidateNotNullOrEmpty()] [string] $M365Environment ) process { try { $ServicePrincipals = @() $OrgInfo = (Invoke-GraphDirectly -Commandlet "Get-MgBetaOrganization" -M365Environment $M365Environment).Value foreach ($ServicePrincipal in $RiskySPs) { if ($null -eq $ServicePrincipal) { continue } # If the service principal's owner id is not the same as this tenant then it is a 3rd party principal if ($ServicePrincipal.AppOwnerOrganizationId -ne $OrgInfo.Id) { $ServicePrincipals += $ServicePrincipal } } } catch { Write-Warning "An error occurred in Format-RiskyThirdPartyServicePrincipals: $($_.Exception.Message)" Write-Warning "Stack trace: $($_.ScriptStackTrace)" throw $_ } return $ServicePrincipals } } Export-ModuleMember -Function @( "Get-ApplicationsWithRiskyPermissions", "Get-ServicePrincipalsWithRiskyPermissions", "Format-RiskyApplications", "Format-RiskyThirdPartyServicePrincipals" ) # SIG # Begin signature block # MIIuuQYJKoZIhvcNAQcCoIIuqjCCLqYCAQExDzANBglghkgBZQMEAgEFADB5Bgor # BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG # KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCCrCLbWHcOp9hrF # PLBnV+MpbAOXKlSrYvYCgoYnU1cAJ6CCE6MwggWQMIIDeKADAgECAhAFmxtXno4h # 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 # BgorBgEEAYI3AgEVMC8GCSqGSIb3DQEJBDEiBCAqkTYeAAPDMAoRR+NTNfO8eP3u # gaYWkSMEqw1fcRqxqjANBgkqhkiG9w0BAQEFAASCAgBUXZ3fcCm4EbHedmUAJ/pI # SFe9avzO4abknQpdKotm8XakTqQaz9U2SDbMx27/KBAc8J8HSUhX+EKzP/84QKF0 # moJeaMbTMCpkLKsTy2XH6p5KiyaBD0Kw3B6lTKgUbaZ9ketIcQ61BtuFaCpmJya/ # CqV25Lb0d6rPJqd0fT5RH8svhjYgv22n73Ahvvd0n90HkFLHV7hho5gmrnS9dI9L # 0nnhTejqiSMTN3NDaHIrKxAyC4XkgAJcccanckXsCpJBlEW536VV/6PRz3kbdVX6 # X3iitD5uBXQs65beqJmB3yd95Jrq6NGBbuyClOEyKQg22Cq2Z0PHbkeW+LGmxeab # 2K/438R/XvI/faa3iNyMgxolrd7n5hMPzXxTQaTMhDed5BW2gnhHhS9ZO9cmD41V # SjC1fUsn/yB3PGnnhoZ81HVht0nzNPLbAEvadIiCwtb5iEunJAf6re5efUJQHED3 # 9sc+XDMYFb3h+EyRvs4VHtyV6NPRdg/v620ebr2kYw4Cow5DzFRqK6bivYSVCjO4 # XKJfOiRAM/MHQXC0DKxTd2RGrCHfYXPxU/j9ROgDWi2X5CzAzFnvUGPqCWpOKCCQ # DwVWOxn1FCO0IpZ4WNOtZiyDNxpna8r9tg9FFN3XX+1PQEfR+c+Bd44X5ass9IJN # ZzMpAy78VD0+1HQj/e3dnKGCFzkwghc1BgorBgEEAYI3AwMBMYIXJTCCFyEGCSqG # SIb3DQEHAqCCFxIwghcOAgEDMQ8wDQYJYIZIAWUDBAIBBQAwdwYLKoZIhvcNAQkQ # AQSgaARmMGQCAQEGCWCGSAGG/WwHATAxMA0GCWCGSAFlAwQCAQUABCDMco1fEeDA # NXTium1Wbi84GQEVYC22SdFR7+qPVScowAIQb86RozCVRXyYpd+4DKrsqBgPMjAy # NTA3MDgxODI0NDJaoIITAzCCBrwwggSkoAMCAQICEAuuZrxaun+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 # hvcNAQkDMQ0GCyqGSIb3DQEJEAEEMBwGCSqGSIb3DQEJBTEPFw0yNTA3MDgxODI0 # NDJaMCsGCyqGSIb3DQEJEAIMMRwwGjAYMBYEFNvThe5i29I+e+T2cUhQhyTVhltF # MC8GCSqGSIb3DQEJBDEiBCDCSBJcn5b98aUmJ5/g4y/fJnU7lgKm5zPZ3EAl1/IP # vTA3BgsqhkiG9w0BCRACLzEoMCYwJDAiBCB2dp+o8mMvH0MLOiMwrtZWdf7Xc9sF # 1mW5BZOYQ4+a2zANBgkqhkiG9w0BAQEFAASCAgBFyhBQh8HLWDboDBEVpMxK/Gej # 6SY4dsZNWvOLctjpAfbJCw2+VBTJdKqjzmEKKtk5S66umFcoISC1PBvBQ7nvy1rv # vC60m/yKAH5JGROowa5lDDBJxnj6bJgCrTRBbgNYEEl8xG6R5Zo31hd44SrIP/u6 # bBZN9ZLhX89uHu/QEC7NBEFG+2awTdF8tXscNZvr2N+C7kFMk8Nb/q+c9rwh2fbn # JjijWi/3l7lgXCJIYI1H0gFs5Mlkf5rO1j487Uz+cpK4DTnSf7i03BhTaq7RhaxN # I5B0axF25HXT4Ya/dmVWdwXm8HUmuaFFPxEz6f+gF3uhAMc2Jl9HLPKRxYPyl2aK # 0hnOzXcA9XzGXmVvOp66ZTzg3G3Rn4rWsEQdkNwJAHVR3MCUR5wHfZt1Xa2qnxJ3 # mmh0nw3Cg39ooqv4Twt+0JPqSciWSPAQHKrkGJSJ05oeXFcHcnNwSS5hhc7trSGS # lRnu35bkX82SBYNPFmj7L8DrZBBI327ABDtCxE7tKE2JlT3t2jlYtEAkDOLowGfV # AHVKGEXQckQHXRuOzlgUwv5JorFuLwi3rWV536bcnCVYbJ+1YVjzq6XmNHld+RkN # 8aFDlY7yEJ/lYY8xafrJZ04/I0h57o6+n/3x9R+FAJRqMquKot5V7y4NhI2FSQB3 # vwxxUAFLyRa0lpfqBg== # SIG # End signature block |