Modules/ScubaConfigApp/ScubaConfigAnalyzerHelpers/ScubaConfigAnalyzerTenantGovernanceHelper.psm1
|
<#
.SYNOPSIS Generates Microsoft 365 tenant governance configuration from analyzer CA policies. .NOTES Imported with the other Scuba Config Analyzer helpers. Conversion is kept separate from UI actions so imported and live policy collections use the same implementation. #> function Get-ScATenantGovernanceValue { param( [Parameter(Mandatory)]$InputObject, [Parameter(Mandatory)][string]$Path ) $value = $InputObject # Traverse the path segments to retrieve the nested value from the input object. foreach ($part in $Path -split '\.') { if ($null -eq $value -or -not ($value.PSObject.Properties.Name -contains $part)) { return $null } $value = $value.$part } # Return the retrieved value, which may be $null if any path segment was missing. return $value } function Add-ScATenantGovernanceProperty { param( [Parameter(Mandatory)][System.Collections.IDictionary]$Properties, [Parameter(Mandatory)][string]$Name, $Value ) if ($null -eq $Value) { return } # Skip adding the property if the value is null, empty, or whitespace. if ($Value -is [string] -and [string]::IsNullOrWhiteSpace($Value)) { return } if ($Value -is [System.Collections.IEnumerable] -and $Value -isnot [string] -and @($Value).Count -eq 0) { return } # Add the property to the properties hashtable if it passes the null, empty, or whitespace checks. $Properties[$Name] = $Value } function ConvertTo-ScATenantGovernancePolicy { <# .SYNOPSIS Maps one Conditional Access policy to a tenant governance resource (microsoft.entra.conditionalaccesspolicy). Returns $null when the policy has no display name. Object ids (users/groups/roles/apps) are translated to display names via -DisplayNameLookup because the governance monitor compares those references by name, not by id. #> param( [Parameter(Mandatory)]$Policy, [System.Collections.IDictionary]$DisplayNameLookup = @{}, [System.Collections.IDictionary]$UserPrincipalNameLookup = @{} ) # Retrieve the display name of the policy. If it is null or whitespace, return $null. $displayName = [string](Get-ScATenantGovernanceValue -InputObject $Policy -Path 'DisplayName') if ([string]::IsNullOrWhiteSpace($displayName)) { return $null } # Initialize the properties and property map for the tenant governance resource. $properties = [ordered]@{ DisplayName = $displayName } # The properties will be populated based on the mappings defined in $propertyMap. $propertyMap = [ordered]@{ Id = 'Id' State = 'State' IncludeApplications = 'Conditions.Applications.IncludeApplications' ApplicationsFilter = 'Conditions.Applications.ApplicationFilter.Rule' ApplicationsFilterMode = 'Conditions.Applications.ApplicationFilter.Mode' ExcludeApplications = 'Conditions.Applications.ExcludeApplications' IncludeUserActions = 'Conditions.Applications.IncludeUserActions' IncludeUsers = 'Conditions.Users.IncludeUsers' ExcludeUsers = 'Conditions.Users.ExcludeUsers' IncludeGroups = 'Conditions.Users.IncludeGroups' ExcludeGroups = 'Conditions.Users.ExcludeGroups' IncludeRoles = 'Conditions.Users.IncludeRoles' ExcludeRoles = 'Conditions.Users.ExcludeRoles' IncludeGuestOrExternalUserTypes = 'Conditions.Users.IncludeGuestsOrExternalUsers.GuestOrExternalUserTypes' IncludeExternalTenantsMembershipKind = 'Conditions.Users.IncludeGuestsOrExternalUsers.ExternalTenants.MembershipKind' IncludeExternalTenantsMembers = 'Conditions.Users.IncludeGuestsOrExternalUsers.ExternalTenants.AdditionalProperties.Members' ExcludeGuestOrExternalUserTypes = 'Conditions.Users.ExcludeGuestsOrExternalUsers.GuestOrExternalUserTypes' ExcludeExternalTenantsMembershipKind = 'Conditions.Users.ExcludeGuestsOrExternalUsers.ExternalTenants.MembershipKind' ExcludeExternalTenantsMembers = 'Conditions.Users.ExcludeGuestsOrExternalUsers.ExternalTenants.AdditionalProperties.Members' IncludePlatforms = 'Conditions.Platforms.IncludePlatforms' ExcludePlatforms = 'Conditions.Platforms.ExcludePlatforms' IncludeLocations = 'Conditions.Locations.IncludeLocations' ExcludeLocations = 'Conditions.Locations.ExcludeLocations' DeviceFilterMode = 'Conditions.Devices.DeviceFilter.Mode' DeviceFilterRule = 'Conditions.Devices.DeviceFilter.Rule' UserRiskLevels = 'Conditions.UserRiskLevels' SignInRiskLevels = 'Conditions.SignInRiskLevels' ClientAppTypes = 'Conditions.ClientAppTypes' GrantControlOperator = 'GrantControls.Operator' BuiltInControls = 'GrantControls.BuiltInControls' ApplicationEnforcedRestrictionsIsEnabled = 'SessionControls.ApplicationEnforcedRestrictions.IsEnabled' CloudAppSecurityIsEnabled = 'SessionControls.CloudAppSecurity.IsEnabled' CloudAppSecurityType = 'SessionControls.CloudAppSecurity.CloudAppSecurityType' SignInFrequencyValue = 'SessionControls.SignInFrequency.Value' TermsOfUse = 'GrantControls.TermsOfUse' CustomAuthenticationFactors = 'GrantControls.CustomAuthenticationFactors' SignInFrequencyType = 'SessionControls.SignInFrequency.Type' SignInFrequencyIsEnabled = 'SessionControls.SignInFrequency.IsEnabled' SignInFrequencyInterval = 'SessionControls.SignInFrequency.FrequencyInterval' PersistentBrowserIsEnabled = 'SessionControls.PersistentBrowser.IsEnabled' PersistentBrowserMode = 'SessionControls.PersistentBrowser.Mode' AuthenticationStrength = 'GrantControls.AuthenticationStrength.DisplayName' AuthenticationContexts = 'Conditions.Applications.IncludeAuthenticationContextClassReferences' } # Iterate over each entry in the property map to populate the properties based on the policy values. foreach ($entry in $propertyMap.GetEnumerator()) { $value = Get-ScATenantGovernanceValue -InputObject $Policy -Path $entry.Value # Ensure that the properties hashtable contains the 'Ensure' key set to 'Present' to indicate the policy is active. $arrayProperties = @( 'IncludeApplications', 'ExcludeApplications', 'IncludeUserActions', 'IncludeUsers', 'ExcludeUsers', 'IncludeGroups', 'ExcludeGroups', 'IncludeRoles', 'ExcludeRoles', 'IncludeGuestOrExternalUserTypes', 'IncludeExternalTenantsMembers', 'ExcludeGuestOrExternalUserTypes', 'ExcludeExternalTenantsMembers', 'IncludePlatforms', 'ExcludePlatforms', 'IncludeLocations', 'ExcludeLocations', 'UserRiskLevels', 'SignInRiskLevels', 'ClientAppTypes', 'BuiltInControls', 'CustomAuthenticationFactors', 'AuthenticationContexts' ) # If the policy is active, set the 'Ensure' key to 'Present' in the properties hashtable. if ($null -ne $value -and $arrayProperties -contains $entry.Key) { $value = @($value) } # Add the property to the properties hashtable, handling array conversion for specific fields. Add-ScATenantGovernanceProperty -Properties $properties -Name $entry.Key -Value $value } # Exclusion field metadata; allows future exclusion types to be emitted without # hardcoded field arrays in the YAML builder. Populate the exclusion definitions from the analyzer schema. # name); fall back to the id only when the policy exposes no strength display name. if (-not $properties.Contains('AuthenticationStrength')) { $authStrengthId = Get-ScATenantGovernanceValue -InputObject $Policy -Path 'GrantControls.AuthenticationStrength.Id' # If the authentication strength ID is not found, set it to an empty string to avoid null values. Add-ScATenantGovernanceProperty -Properties $properties -Name 'AuthenticationStrength' -Value $authStrengthId } # The governance monitor represents groups, roles, apps and locations by DISPLAY NAME, but # users by USER PRINCIPAL NAME. Translate the collected object ids accordingly; unresolved # ids and non-id literals ('All', 'None', 'GuestsOrExternalUsers', ...) are left unchanged. if (($DisplayNameLookup -and $DisplayNameLookup.Count -gt 0) -or ($UserPrincipalNameLookup -and $UserPrincipalNameLookup.Count -gt 0)) { $userFields = @('IncludeUsers', 'ExcludeUsers') # User fields represent the user principal names of the users included or excluded in the policy. $nameFields = @( 'IncludeGroups', 'ExcludeGroups', 'IncludeRoles', 'ExcludeRoles', 'IncludeApplications', 'ExcludeApplications', 'IncludeLocations', 'ExcludeLocations' ) # Translate the object ids for users, groups, roles, apps, and locations to their display names using the provided lookups. foreach ($field in ($userFields + $nameFields)) { if (-not $properties.Contains($field)) { continue } $isUser = $userFields -contains $field $properties[$field] = @(@($properties[$field]) | ForEach-Object { $key = [string]$_ if ($isUser -and $UserPrincipalNameLookup -and $UserPrincipalNameLookup.Contains($key)) { $UserPrincipalNameLookup[$key] } elseif ($DisplayNameLookup -and $DisplayNameLookup.Contains($key)) { $DisplayNameLookup[$key] } else { $_ } }) } } # Ensure that the properties hashtable contains the 'Ensure' key set to 'Present' to indicate the policy is active. $properties.Ensure = 'Present' # Return the final ordered hashtable representing the policy for the tenant governance baseline. return [ordered]@{ displayName = $displayName resourceType = 'microsoft.entra.conditionalaccesspolicy' properties = $properties } } function ConvertTo-ScATenantGovernanceJson { <# .SYNOPSIS Builds the tenant governance baseline JSON document from the collected Conditional Access policies. #> [CmdletBinding()] [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', 'TenantId', Justification = 'Kept for signature/caller compatibility; the baseline document is tenant-agnostic.')] [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', 'SchemaUrl', Justification = 'Kept for signature/caller compatibility; the governance API expects the baseline object without a $schema wrapper.')] param( [Parameter(Mandatory)][AllowEmptyCollection()][object[]]$ConditionalAccessPolicies, [string]$TenantId, [string]$DisplayName = 'ScubaGear Entra ID tenant governance baseline', [string]$SchemaUrl = 'https://www.schemastore.org/utcm-monitor.json', [System.Collections.IDictionary]$DisplayNameLookup = @{}, [System.Collections.IDictionary]$UserPrincipalNameLookup = @{}, [string[]]$IncludePolicyId = @() ) # When policy ids are supplied, scope the document to just those (the analyzer passes the # policies it matched to a ScubaGear baseline); otherwise every collected policy is emitted. $policies = @($ConditionalAccessPolicies) if (@($IncludePolicyId).Count -gt 0) { # Create a hash set to store the included policy ids for efficient lookups. $idSet = New-Object System.Collections.Generic.HashSet[string] ([System.StringComparer]::OrdinalIgnoreCase) # Populate the hash set with the policy ids to include. foreach ($id in $IncludePolicyId) { if (-not [string]::IsNullOrWhiteSpace([string]$id)) { [void]$idSet.Add([string]$id) } } # Filter the policies to include only those whose ids are in the hash set. $policies = @($policies | Where-Object { $_ -and $idSet.Contains([string]$_.Id) }) } $resources = @($policies | ForEach-Object { ConvertTo-ScATenantGovernancePolicy -Policy $_ -DisplayNameLookup $DisplayNameLookup -UserPrincipalNameLookup $UserPrincipalNameLookup } | Where-Object { $null -ne $_ }) # The tenant governance API expects the baseline object itself (parameters as an array), not a wrapper. $document = [ordered]@{ displayName = $DisplayName description = 'Tenant governance baseline generated by the ScubaGear Config Analyzer from collected Entra ID Conditional Access policies.' parameters = @() resources = $resources } # Convert the baseline document to JSON with a depth of 30 to ensure all nested structures are included. return ($document | ConvertTo-Json -Depth 30) } function Get-ScATenantGovernanceMatchedPolicyId { <# .SYNOPSIS Returns the distinct Conditional Access policy ids the analysis identified as the best match for a ScubaGear baseline (one per finding), so the governance monitor JSON can be scoped to just the ScubaGear-mapped policies. #> param([Parameter(Mandatory)][AllowNull()]$Findings) $ids = New-Object System.Collections.Generic.HashSet[string] ([System.StringComparer]::OrdinalIgnoreCase) foreach ($finding in @($Findings)) { # The single policy ScubaGear identified as implementing (or closest to) this baseline - # its best match. Merely-relevant candidates are excluded so the set stays the mapped # policies, not every policy that touches a baseline area. $matchId = if (-not [string]::IsNullOrWhiteSpace([string]$finding.SelectedPolicyId)) { [string]$finding.SelectedPolicyId } elseif ($finding.BestMatch -and $finding.BestMatch.Id) { [string]$finding.BestMatch.Id } else { $null } # Add the matched policy id to the set if it exists. if ($matchId) { [void]$ids.Add($matchId) } } # Return the collected policy ids as an array. return @($ids) } function Update-ScubaAnalyzerTenantGovernanceJson { <# .SYNOPSIS Refreshes the Tenant Governance JSON text box from the current analysis; no-op unless generation is enabled. The 'ScubaGear baseline policies only' checkbox scopes the output to the analyzer-matched policies. #> if (-not $syncHash.GenerateTenantGovernanceConfig -or -not $syncHash.TenantGovernanceJson_TextBox -or -not $syncHash.Analysis) { return } # Prepare a lookup table for display names, defaulting to an empty dictionary if not available. $displayNameLookup = if ($syncHash.Analysis.DisplayNameLookup -is [System.Collections.IDictionary]) { $syncHash.Analysis.DisplayNameLookup } else { @{} } # Prepare a lookup table for user principal names, defaulting to an empty dictionary if not available. $userUpnLookup = if ($syncHash.Analysis.UserUpnLookup -is [System.Collections.IDictionary]) { $syncHash.Analysis.UserUpnLookup } else { @{} } $includePolicyId = @() # Determine which policy ids to include based on the 'ScubaGear baseline policies only' checkbox. if ($syncHash.TenantGovernanceScubaOnly_CheckBox -and $syncHash.TenantGovernanceScubaOnly_CheckBox.IsChecked) { $includePolicyId = @(Get-ScATenantGovernanceMatchedPolicyId -Findings $syncHash.Analysis.Findings) } # If the 'ScubaGear baseline policies only' checkbox is not checked, include all policy ids by default. $syncHash.TenantGovernanceJson_TextBox.Text = ConvertTo-ScATenantGovernanceJson ` -ConditionalAccessPolicies @($syncHash.Analysis.ConditionalAccessPolicies) ` -TenantId ([string]$syncHash.Analysis.MetaData.TenantId) ` -SchemaUrl ([string]$syncHash.TenantGovernanceSchemaUrl) ` -DisplayNameLookup $displayNameLookup ` -UserPrincipalNameLookup $userUpnLookup ` -IncludePolicyId $includePolicyId } function Copy-ScubaAnalyzerTenantGovernanceJson { <# .SYNOPSIS Copies the generated Tenant Governance JSON to the clipboard. #> try { # Rebuild first so Copy always reflects the current 'ScubaGear baseline policies only' # selection, even if the checkbox toggle didn't refresh the preview. Update-ScubaAnalyzerTenantGovernanceJson # Copy the current Tenant Governance JSON to the clipboard. [System.Windows.Clipboard]::SetText($syncHash.TenantGovernanceJson_TextBox.Text) Set-ScubaAnalyzerStatus (Get-ScubaAnalyzerText 'TenantGovernanceCopied') } catch { Set-ScubaAnalyzerStatus (Get-ScubaAnalyzerText 'TenantGovernanceCopyFailed' $_.Exception.Message) } } function Export-ScubaAnalyzerTenantGovernanceJson { <# .SYNOPSIS Prompts for a path and writes the generated Tenant Governance JSON to a UTF-8 (no BOM) file. #> try { # Rebuild first so the export always reflects the current 'ScubaGear baseline policies # only' selection, even if the checkbox toggle didn't refresh the preview. Update-ScubaAnalyzerTenantGovernanceJson if ([string]::IsNullOrWhiteSpace($syncHash.TenantGovernanceJson_TextBox.Text)) { Set-ScubaAnalyzerStatus (Get-ScubaAnalyzerText 'NothingToExport') return } # Prompt the user to select a file path for exporting the Tenant Governance JSON. $dialog = New-Object Microsoft.Win32.SaveFileDialog $dialog.Filter = 'JSON files (*.json)|*.json|All files (*.*)|*.*' $dialog.FileName = 'ScubaGear-TenantGovernance.json' # Set the default file name for the export dialog. if ($dialog.ShowDialog() -eq $true) { [System.IO.File]::WriteAllText($dialog.FileName, $syncHash.TenantGovernanceJson_TextBox.Text, [System.Text.UTF8Encoding]::new($false)) Set-ScubaAnalyzerStatus (Get-ScubaAnalyzerText 'TenantGovernanceExported' $dialog.FileName) } } catch { Set-ScubaAnalyzerStatus (Get-ScubaAnalyzerText 'ExportFailed' $_.Exception.Message) } } Export-ModuleMember -Function @( 'ConvertTo-ScATenantGovernancePolicy', 'ConvertTo-ScATenantGovernanceJson', 'Get-ScATenantGovernanceMatchedPolicyId', 'Update-ScubaAnalyzerTenantGovernanceJson', 'Copy-ScubaAnalyzerTenantGovernanceJson', 'Export-ScubaAnalyzerTenantGovernanceJson' ) # SIG # Begin signature block # MIIu9gYJKoZIhvcNAQcCoIIu5zCCLuMCAQExDzANBglghkgBZQMEAgEFADB5Bgor # BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG # KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCCFr8Kbosn2KVF6 # BBGwrZ+2CCXtu+yKg4YdOzejVqSXPKCCE6MwggWQMIIDeKADAgECAhAFmxtXno4h # 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 # eE4wggdXMIIFP6ADAgECAhAMM6tnPejLgA9WVhXroQvSMA0GCSqGSIb3DQEBCwUA # MGkxCzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5EaWdpQ2VydCwgSW5jLjFBMD8GA1UE # AxM4RGlnaUNlcnQgVHJ1c3RlZCBHNCBDb2RlIFNpZ25pbmcgUlNBNDA5NiBTSEEz # ODQgMjAyMSBDQTEwHhcNMjYwMTE0MDAwMDAwWhcNMjcwMTEzMjM1OTU5WjBfMQsw # CQYDVQQGEwJVUzEdMBsGA1UECBMURGlzdHJpY3Qgb2YgQ29sdW1iaWExEzARBgNV # BAcTCldhc2hpbmd0b24xDTALBgNVBAoTBENJU0ExDTALBgNVBAMTBENJU0EwggIi # MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCuXYolNHqlh6smLTE592waXheZ # 8VHzxeds4pMaepGuwmjf8d1jG9wUNuJX9/qb0a1dgGz5D/EAz5NRTIin4SZYQEE8 # qvdl2yQJ5uWxXIjsFbrOyc1fWscUXw0Kt7OPLOafcEkdDoe8K0tO4h2GL3RWRzjp # uLfQhhnAmD6NT1l+ughnfmarV/ODgIn/RFR4YORlu4YP2xQX6KRxeTDslg7F+z6X # +t87/U8m8gQ9XTm5kBmteP4GcE/ytnyI+ScIxNRybzGomWIBm848XDE5yYhlYQ2R # SnCoo6M4CRqp9WFGVyoLkoPP0OlxzryKWaE1/nuPbYG/kf/rUB1OhqxvSSGwmNhs # vkkjsC0Z9H5Jy6heFdoxOu/+ZQksKoP/fMvHxuCCtkIJbV8tk0oT6MQ8EJbgsWDZ # TKhui1wxW6JIZyBOMPWoZUOouOzo2h5Cz7LBPKME5FkcUzcs47lpRlDkJco4PLcj # wJSo4XPnx3G/2DIjNEFNyfKCWfH8uW6nJjmDBiveFZ2j0YvgdQ+7MOjQnw7R/MAD # DTagrKl3rLV60+X2TY6/onKhCUuU3pMAjVbOwZ3PkzDLZnsEGRfm6hgp6014aXml # t8h4nu+uC41U8vUSGHl0vqKuzvmShLmnI+Iv0l95pmnqomuCZzRDrjEoaLPx7OxL # Dy/Id9E7yQDip4jBdQIDAQABo4ICAzCCAf8wHwYDVR0jBBgwFoAUaDfg67Y7+F8R # hvv+YXsIiGX0TkIwHQYDVR0OBBYEFN30sVU+fpfQQfPQWMhkO1qd+MxoMD4GA1Ud # IAQ3MDUwMwYGZ4EMAQQBMCkwJwYIKwYBBQUHAgEWG2h0dHA6Ly93d3cuZGlnaWNl # cnQuY29tL0NQUzAOBgNVHQ8BAf8EBAMCB4AwEwYDVR0lBAwwCgYIKwYBBQUHAwMw # gbUGA1UdHwSBrTCBqjBToFGgT4ZNaHR0cDovL2NybDMuZGlnaWNlcnQuY29tL0Rp # Z2lDZXJ0VHJ1c3RlZEc0Q29kZVNpZ25pbmdSU0E0MDk2U0hBMzg0MjAyMUNBMS5j # cmwwU6BRoE+GTWh0dHA6Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydFRydXN0 # ZWRHNENvZGVTaWduaW5nUlNBNDA5NlNIQTM4NDIwMjFDQTEuY3JsMIGUBggrBgEF # BQcBAQSBhzCBhDAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQuY29t # MFwGCCsGAQUFBzAChlBodHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vRGlnaUNl # cnRUcnVzdGVkRzRDb2RlU2lnbmluZ1JTQTQwOTZTSEEzODQyMDIxQ0ExLmNydDAJ # BgNVHRMEAjAAMA0GCSqGSIb3DQEBCwUAA4ICAQA77T42YiOx5wWPItgo+kvB+Gzb # ZFCRHRFfTAZZNQt9o/0CqNmyA2xFklX4t5Z9VNdiIOx14AnmJdQkcRdk3vsU5gby # jKEup7LTWtvcWrl6hQwGNt3l892BgUbPKsPBE+AriktVqn5yMSXVVzeboqsqAG8e # Syei0B54/QdgR4whfHvQ/qpCACsJTlJgAykXVgDPJNKnQ7wc17loLQutqF1JUcbO # XKWt1AA9Zas5q30LDZzZeK4B56yojK68CTQXN7toSRFIuZDMKKDfIZpCX8cmbaaO # DFOOu44/QWMv+Xc6+ISYGkrTTzqWhOqiXgLVBeXGn/WrOJJ8R29mZMneCpBesCLs # YII1gCFOo7Vt6mvOKxAPQ3KhJYBFEHkp+GI65koaQkO2xv50iLS0+/j2YC66uviU # MFe0JEOdXuE7Rn/OmWNSzQ+6kPNYDJQASQ974C3wUejJoMtGZEzoTbly/HufQTrd # rhcL2aC69CxSN+idTXPLC9UT3xo4sFdOw+hXkmbXtoB1GDsd5p1TWFgRbnTXDkbM # YMBWYVB6/Tk1bzwj4iTp4g0YrtB628FXPX/ko+JWZlv0Ea865S23w1uGlnDNVxIi # +8oi74G5DM66Q6ENt6+3WoRGRrdoyE6uCh1haY+oPYSgumb0ozzrp8tw89TRKVrK # KSXGBxlExEvjQ6dYwjGCGqkwghqlAgEBMH0waTELMAkGA1UEBhMCVVMxFzAVBgNV # BAoTDkRpZ2lDZXJ0LCBJbmMuMUEwPwYDVQQDEzhEaWdpQ2VydCBUcnVzdGVkIEc0 # IENvZGUgU2lnbmluZyBSU0E0MDk2IFNIQTM4NCAyMDIxIENBMQIQDDOrZz3oy4AP # VlYV66EL0jANBglghkgBZQMEAgEFAKCBhDAYBgorBgEEAYI3AgEMMQowCKACgACh # AoAAMBkGCSqGSIb3DQEJAzEMBgorBgEEAYI3AgEEMBwGCisGAQQBgjcCAQsxDjAM # BgorBgEEAYI3AgEVMC8GCSqGSIb3DQEJBDEiBCBpq0dhZbTV8cbpiti7myB6MsGR # jGMbO+BxeD/bElnXWTANBgkqhkiG9w0BAQEFAASCAgAoi5Q8POuxXSujutzfv2r5 # cWw6lj1hEq89nZIaEDDVyl5CAPpBm6iqQ9lmtdaT7UR/Y9RxsSDOc6kk2L2Fk8ZX # wQocd6WDHoXNwwJzg96C8gm1EV7ay0Xtf9lVpu+bUrgCbi9i89OkG21b7H4Jpydj # c3nUGON3o5bzXsEeBfU84TLE+AQR0nvHcReWq8NW9yZGv+7bNVtOYlxdvV5SDHMr # A+lYTaQt//pTZH7SpZnWEC1JweJ/MjfI+8yjUQtXIT2s9xxB9mEAKbJ5QbOpsP4H # 7WJylK0jGkRchICqGF67B4lfj/tFBZORRSXkBScNogLWU2+sy4k4unsi3fW1H0JY # x0bj7gOL5gj8nHpSPRniyKxAhaqYYv9eFVc0NCnuIp9xDXcdK0lWrvBYhVtiPaCc # NAkjIOi/pxcfJF+/vTC3FUy4EH5t0M1t0XpNzmB1gQ6YKa8h/S+fSDN7Kbt74/IW # vYUMnFPcYMkaSgNf+IYksPcEeAlGHY2fsndJpbMil3sUSuWJS6PEm3C6iDWL62XW # 8aU8gYPXJm3RocjEH9JF+vrrm3cvEMatbj0lr+u2TcMCLiUtKiPO2haXPYYGTeOj # cj6aiXmE9jTYVhk7PBpDa/w6ZtJbxhcDPOcImWc3W2SxaOnW6UxOgM4zwumxmUjd # oLazleNiAx3cdnU2U/SlnKGCF3YwghdyBgorBgEEAYI3AwMBMYIXYjCCF14GCSqG # SIb3DQEHAqCCF08wghdLAgEDMQ8wDQYJYIZIAWUDBAIBBQAwdwYLKoZIhvcNAQkQ # AQSgaARmMGQCAQEGCWCGSAGG/WwHATAxMA0GCWCGSAFlAwQCAQUABCCnSXyQZsxM # qU/GeRElpDS/btCIHW2Uvi7WQnAsqwrTBAIQY6ZiQLPUhsxoybFw2M7jRRgPMjAy # NjEwMDgxOTE0MjBaoIITOjCCBu0wggTVoAMCAQICEAhP3DNPfkVO28MPj/mSGDUw # DQYJKoZIhvcNAQELBQAwaTELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDkRpZ2lDZXJ0 # LCBJbmMuMUEwPwYDVQQDEzhEaWdpQ2VydCBUcnVzdGVkIEc0IFRpbWVTdGFtcGlu # ZyBSU0E0MDk2IFNIQTI1NiAyMDI1IENBMTAeFw0yNjA4MDUwMDAwMDBaFw0zNzEx # MDQyMzU5NTlaMGMxCzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5EaWdpQ2VydCwgSW5j # LjE7MDkGA1UEAxMyRGlnaUNlcnQgU0hBMjU2IFJTQTQwOTYgVGltZXN0YW1wIFJl # c3BvbmRlciAyMDI2IDEwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC2 # e6byyf7NSvjUm0xls/04xjD4fAkOkbnGQi7+Wpx81iYxfzViaxSIctuH3KSl5YEY # pMuFgGsA31N2D9ATMbfZdw5uaAhuWevQKhDdZIB4NnqcfpfpWQXJiQnDdAElETC+ # bhSEvNLGbA8DtwUpFMQ4yyYQSPqomT92osQAv6hBi47ATZS6JfVWe6XxhF4jJZ3i # SAuf2Cros1czRSmWRHqMv9AfGZvp8ygYElhudpQjtcPpwoOl6QrZJUyV3iINvN4c # O05prGV0fkjG426xDr2d3z9lcSIHkdvGPdGUrXdxfVbgOUVcp2/8ISEzwKPW++Wa # +E2ujI91EZtukGWDJ/xZ27k3oHKEXBRGfRTqjOU+jE3ba/5++JSE/7oNHnjs5mek # ExYN96LV/mxUbCKJb8pBNY4r3uD7hEmk/M81XhVgwDA7aMzYC3LZBg9WY5BMmbSa # y5ecmtJuXaB/0nKWmQmVZeqTVDgsmzHP5MQuhAJkiWNuC9MmCg9TZHXbJ2/yLVSo # v9p16UDTLtT0+aa1vN71fHeu1qMLlLNB3WOB/ADCxr3S/1hxI92Z6jKgEED/btwI # vbfuXkNNhg8MtDg43c4tMZae9FvqMOt/9PvmAxF9TNIsIFB8G6yb36ZJZGUL8N/p # L971DyLXcK6HM5PYnH5X+eVtczhCgHCVQCF6XDAlPQIDAQABo4IBlTCCAZEwDAYD # VR0TAQH/BAIwADAdBgNVHQ4EFgQUFMljijAu1Er7bpTz5uNAfvXszeIwHwYDVR0j # BBgwFoAU729TSunkBnx6yuKQVvYv1Ensy04wDgYDVR0PAQH/BAQDAgeAMBYGA1Ud # JQEB/wQMMAoGCCsGAQUFBwMIMIGVBggrBgEFBQcBAQSBiDCBhTAkBggrBgEFBQcw # AYYYaHR0cDovL29jc3AuZGlnaWNlcnQuY29tMF0GCCsGAQUFBzAChlFodHRwOi8v # Y2FjZXJ0cy5kaWdpY2VydC5jb20vRGlnaUNlcnRUcnVzdGVkRzRUaW1lU3RhbXBp # bmdSU0E0MDk2U0hBMjU2MjAyNUNBMS5jcnQwXwYDVR0fBFgwVjBUoFKgUIZOaHR0 # cDovL2NybDMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0VHJ1c3RlZEc0VGltZVN0YW1w # aW5nUlNBNDA5NlNIQTI1NjIwMjVDQTEuY3JsMCAGA1UdIAQZMBcwCAYGZ4EMAQQC # MAsGCWCGSAGG/WwHATANBgkqhkiG9w0BAQsFAAOCAgEAjcU6YR6dUgrfmawJgH59 # KECxa9Ji8sEi2g10CBDaMiqsaxWyW5cwlT/6ZF5sFznazqVsoC85U9dqLOYqQwst # +UQQoNlDHgKRLa3xoc+OReFreFhnTXSG0Vrd2E2CZqUfm+5a+He1MJ/h+tNLuA+0 # Zzhn/Fo+FDYAHWZHx4R79ZsfRFYe9UiXpXBDf6DkUo183Y38NYmR/XfDYf7YZ+oR # 9t3flbDwK+hgGMs0gNNp1w9Z2CyOyI5or/sSwomAuNQ0hWC9xoU4stD8aWsD7Rkc # mgVRs6vlIk3zPKQ+ylcheWkMlj+CoVRlFE55pv0ZWCaFt04lwP/rdGHE9qEVQZty # RE42ox7oNgC/r+Y4bSlZ3dw9K2x1xLtu6PkPKeLBFjzKigwfqm3Hm+k/+lnME8F5 # kPZTgiy2HLEHklpryqs6QHnPXrRNeIzkAMyylnRN8P0wmirS0WkU+ywpEWFZ4QNg # +9xS43tTuW9x0eXh7NDc1P/sV+zWxHXKH8tFt1ncHdVzqrZaYPyYMLSn2TOXajve # JW1L3joiQSPsWRGxkbDDW15jERFE4LvjnGu2O9zD1nLJSMdlYZEikl4w2w+q4IN/ # R+TIe0H4ngCI1moJCTbevGH4punIxM1Uoi0nmX3ZK+XbRT01uowE5ViXWHng0Rgs # mrX/EdYUo80r3TfMlkD0/YMwgga0MIIEnKADAgECAhANx6xXBf8hmS5AQyIMOkmG # MA0GCSqGSIb3DQEBCwUAMGIxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2Vy # dCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xITAfBgNVBAMTGERpZ2lD # ZXJ0IFRydXN0ZWQgUm9vdCBHNDAeFw0yNTA1MDcwMDAwMDBaFw0zODAxMTQyMzU5 # NTlaMGkxCzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5EaWdpQ2VydCwgSW5jLjFBMD8G # A1UEAxM4RGlnaUNlcnQgVHJ1c3RlZCBHNCBUaW1lU3RhbXBpbmcgUlNBNDA5NiBT # SEEyNTYgMjAyNSBDQTEwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC0 # eDHTCphBcr48RsAcrHXbo0ZodLRRF51NrY0NlLWZloMsVO1DahGPNRcybEKq+Ruw # OnPhof6pvF4uGjwjqNjfEvUi6wuim5bap+0lgloM2zX4kftn5B1IpYzTqpyFQ/4B # t0mAxAHeHYNnQxqXmRinvuNgxVBdJkf77S2uPoCj7GH8BLuxBG5AvftBdsOECS1U # kxBvMgEdgkFiDNYiOTx4OtiFcMSkqTtF2hfQz3zQSku2Ws3IfDReb6e3mmdglTca # arps0wjUjsZvkgFkriK9tUKJm/s80FiocSk1VYLZlDwFt+cVFBURJg6zMUjZa/zb # CclF83bRVFLeGkuAhHiGPMvSGmhgaTzVyhYn4p0+8y9oHRaQT/aofEnS5xLrfxnG # pTXiUOeSLsJygoLPp66bkDX1ZlAeSpQl92QOMeRxykvq6gbylsXQskBBBnGy3tW/ # AMOMCZIVNSaz7BX8VtYGqLt9MmeOreGPRdtBx3yGOP+rx3rKWDEJlIqLXvJWnY0v # 5ydPpOjL6s36czwzsucuoKs7Yk/ehb//Wx+5kMqIMRvUBDx6z1ev+7psNOdgJMoi # wOrUG2ZdSoQbU2rMkpLiQ6bGRinZbI4OLu9BMIFm1UUl9VnePs6BaaeEWvjJSjNm # 2qA+sdFUeEY0qVjPKOWug/G6X5uAiynM7Bu2ayBjUwIDAQABo4IBXTCCAVkwEgYD # VR0TAQH/BAgwBgEB/wIBADAdBgNVHQ4EFgQU729TSunkBnx6yuKQVvYv1Ensy04w # HwYDVR0jBBgwFoAU7NfjgtJxXWRM3y5nP+e6mK4cD08wDgYDVR0PAQH/BAQDAgGG # MBMGA1UdJQQMMAoGCCsGAQUFBwMIMHcGCCsGAQUFBwEBBGswaTAkBggrBgEFBQcw # AYYYaHR0cDovL29jc3AuZGlnaWNlcnQuY29tMEEGCCsGAQUFBzAChjVodHRwOi8v # Y2FjZXJ0cy5kaWdpY2VydC5jb20vRGlnaUNlcnRUcnVzdGVkUm9vdEc0LmNydDBD # BgNVHR8EPDA6MDigNqA0hjJodHRwOi8vY3JsMy5kaWdpY2VydC5jb20vRGlnaUNl # cnRUcnVzdGVkUm9vdEc0LmNybDAgBgNVHSAEGTAXMAgGBmeBDAEEAjALBglghkgB # hv1sBwEwDQYJKoZIhvcNAQELBQADggIBABfO+xaAHP4HPRF2cTC9vgvItTSmf83Q # h8WIGjB/T8ObXAZz8OjuhUxjaaFdleMM0lBryPTQM2qEJPe36zwbSI/mS83afsl3 # YTj+IQhQE7jU/kXjjytJgnn0hvrV6hqWGd3rLAUt6vJy9lMDPjTLxLgXf9r5nWMQ # wr8Myb9rEVKChHyfpzee5kH0F8HABBgr0UdqirZ7bowe9Vj2AIMD8liyrukZ2iA/ # wdG2th9y1IsA0QF8dTXqvcnTmpfeQh35k5zOCPmSNq1UH410ANVko43+Cdmu4y81 # hjajV/gxdEkMx1NKU4uHQcKfZxAvBAKqMVuqte69M9J6A47OvgRaPs+2ykgcGV00 # TYr2Lr3ty9qIijanrUR3anzEwlvzZiiyfTPjLbnFRsjsYg39OlV8cipDoq7+qNNj # qFzeGxcytL5TTLL4ZaoBdqbhOhZ3ZRDUphPvSRmMThi0vw9vODRzW6AxnJll38F0 # cuJG7uEBYTptMSbhdhGQDpOXgpIUsWTjd6xpR6oaQf/DJbg3s6KCLPAlZ66RzIg9 # sC+NJpud/v4+7RWsWCiKi9EOLLHfMR2ZyJ/+xhCx9yHbxtl5TPau1j/1MIDpMPx0 # LckTetiSuEtQvLsNz3Qbp7wGWqbIiOWCnb5WqxL3/BAPvIXKUjPSxyZsq8WhbaM2 # tszWkPZPubdcMIIFjTCCBHWgAwIBAgIQDpsYjvnQLefv21DiCEAYWjANBgkqhkiG # 9w0BAQwFADBlMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkw # FwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1 # cmVkIElEIFJvb3QgQ0EwHhcNMjIwODAxMDAwMDAwWhcNMzExMTA5MjM1OTU5WjBi # MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 # d3cuZGlnaWNlcnQuY29tMSEwHwYDVQQDExhEaWdpQ2VydCBUcnVzdGVkIFJvb3Qg # RzQwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC/5pBzaN675F1KPDAi # MGkz7MKnJS7JIT3yithZwuEppz1Yq3aaza57G4QNxDAf8xukOBbrVsaXbR2rsnny # yhHS5F/WBTxSD1Ifxp4VpX6+n6lXFllVcq9ok3DCsrp1mWpzMpTREEQQLt+C8weE # 5nQ7bXHiLQwb7iDVySAdYyktzuxeTsiT+CFhmzTrBcZe7FsavOvJz82sNEBfsXpm # 7nfISKhmV1efVFiODCu3T6cw2Vbuyntd463JT17lNecxy9qTXtyOj4DatpGYQJB5 # w3jHtrHEtWoYOAMQjdjUN6QuBX2I9YI+EJFwq1WCQTLX2wRzKm6RAXwhTNS8rhsD # dV14Ztk6MUSaM0C/CNdaSaTC5qmgZ92kJ7yhTzm1EVgX9yRcRo9k98FpiHaYdj1Z # XUJ2h4mXaXpI8OCiEhtmmnTK3kse5w5jrubU75KSOp493ADkRSWJtppEGSt+wJS0 # 0mFt6zPZxd9LBADMfRyVw4/3IbKyEbe7f/LVjHAsQWCqsWMYRJUadmJ+9oCw++hk # pjPRiQfhvbfmQ6QYuKZ3AeEPlAwhHbJUKSWJbOUOUlFHdL4mrLZBdd56rF+NP8m8 # 00ERElvlEFDrMcXKchYiCd98THU/Y+whX8QgUWtvsauGi0/C1kVfnSD8oR7FwI+i # sX4KJpn15GkvmB0t9dmpsh3lGwIDAQABo4IBOjCCATYwDwYDVR0TAQH/BAUwAwEB # /zAdBgNVHQ4EFgQU7NfjgtJxXWRM3y5nP+e6mK4cD08wHwYDVR0jBBgwFoAUReui # r/SSy4IxLVGLp6chnfNtyA8wDgYDVR0PAQH/BAQDAgGGMHkGCCsGAQUFBwEBBG0w # azAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQuY29tMEMGCCsGAQUF # BzAChjdodHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vRGlnaUNlcnRBc3N1cmVk # SURSb290Q0EuY3J0MEUGA1UdHwQ+MDwwOqA4oDaGNGh0dHA6Ly9jcmwzLmRpZ2lj # ZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJRFJvb3RDQS5jcmwwEQYDVR0gBAowCDAG # BgRVHSAAMA0GCSqGSIb3DQEBDAUAA4IBAQBwoL9DXFXnOF+go3QbPbYW1/e/Vwe9 # mqyhhyzshV6pGrsi+IcaaVQi7aSId229GhT0E0p6Ly23OO/0/4C5+KH38nLeJLxS # A8hO0Cre+i1Wz/n096wwepqLsl7Uz9FDRJtDIeuWcqFItJnLnU+nBgMTdydE1Od/ # 6Fmo8L8vC6bp8jQ87PcDx4eo0kxAGTVGamlUsLihVo7spNU96LHc/RzY9HdaXFSM # b++hUD38dglohJ9vytsgjTVgHAIDyyCwrFigDkBjxZgiwbJZ9VVrzyerbHbObyMt # 9H5xaiNrIv8SuFQtJ37YOtnwtoeW/VvRXKwYw02fc7cBqZ9Xql4o4rmUMYIDfDCC # A3gCAQEwfTBpMQswCQYDVQQGEwJVUzEXMBUGA1UEChMORGlnaUNlcnQsIEluYy4x # QTA/BgNVBAMTOERpZ2lDZXJ0IFRydXN0ZWQgRzQgVGltZVN0YW1waW5nIFJTQTQw # OTYgU0hBMjU2IDIwMjUgQ0ExAhAIT9wzT35FTtvDD4/5khg1MA0GCWCGSAFlAwQC # AQUAoIHRMBoGCSqGSIb3DQEJAzENBgsqhkiG9w0BCRABBDAcBgkqhkiG9w0BCQUx # DxcNMjYxMDA4MTkxNDIwWjArBgsqhkiG9w0BCRACDDEcMBowGDAWBBRR2avaA0lz # 2E9CZqykgkjms2nEOTAvBgkqhkiG9w0BCQQxIgQgNuPbIEi5kA2pjtPwv6ODGaVx # u6OOGAl2Vtts0Saj5BAwNwYLKoZIhvcNAQkQAi8xKDAmMCQwIgQgLaCdp/QTH5/n # LbbF5unJZWdVrwQ/HqdCzA0hIOFB6/wwDQYJKoZIhvcNAQEBBQAEggIAKO0aycPM # 4Hy+O6E9ojZZkst/kmLn1HAeFV0kOFjQJXHM3qlCyYChe/niu3e246ocRsvdITTX # C8UIsd1NP2Sd9HjHjrg/9zunpI1GFS9HCZaGol4vic3tR2ZhACLBHGHhlucOscNr # /8+Jemc81aVU45n2JRY1zukYR3nFQzPPwROKQ/UCmwIIv9oxYg6kHsHKLx4CWoMb # pSUJgYUyp/Kj32TCLB+LLfTmzrXUD4kIux/Tkxlwlyo08ubPXbE6eMSCRDqyJFaj # gfusaRNXXcb5ahSzt1QXIayrZ522SjSqDfLNxP5S4Z6pzF+sgbnTTWim+YdfyoH3 # yVTBoEIYEF1D378fRBfeZhuW7outhK+wlPAlIihRyLWR2zqbRkAXMn6UiHcYP/Mh # ctSloLuWCsKFPurnd9WjXOuiAwVYinLKdU+I/jsSbWz5l6wJHNHa5CN/7mhOHttS # FppRIygWeQ7UK/o4YSEh9b0cES0kBAQpVKAadblFmW2l0MUDRftA2/rLhdBpai5b # G91LLT9vIuAuqE9E1C6Bt0q0doapGzzDDJdQ2XNKg7DBlpYkYT59z1n7YmhWNsV5 # gfoKNB1xK0999rTP1c1LmWQbXBdl9NEyVzVinE8E2WxVdaCB/wMzK3MOEgHQ+wAz # ixCaRH2rudsZ+4Cfnb4Dsw/mrjRkmj8D9k4= # SIG # End signature block |