Framework/Core/SubscriptionSecurity/Alerts.ps1
using namespace System.Management.Automation Set-StrictMode -Version Latest # Class to implement Subscription alert controls class Alerts: CommandBase { hidden [PSObject[]] $Policy = $null; hidden [PSObject[]] $ApplicableAlerts = $null; hidden [string] $TargetResourceGroup; hidden [string] $ResourceGroup = "AzSDKAlertsRG"; hidden [string] $ResourceGroupLocation = "East US"; Alerts([string] $subscriptionId, [InvocationInfo] $invocationContext, [string] $tags): Base($subscriptionId, $invocationContext) { if($invocationContext.BoundParameters["Preview"]) { $this.Policy = [array] $this.LoadServerConfigFile("Subscription.InsARMAlerts.json"); } else { $this.Policy = [array] $this.LoadServerConfigFile("Subscription.InsAlerts.json"); } $this.FilterTags = $this.ConvertToStringArray($tags); } hidden [PSObject[]] GetApplicableAlerts([string[]] $alertNames) { if($null -eq $this.ApplicableAlerts) { $this.ApplicableAlerts = @(); if($alertNames -and $alertNames.Count -ne 0) { $this.ApplicableAlerts += $this.Policy | Where-Object { $alertNames -Contains $_.Name }; } elseif(($this.FilterTags | Measure-Object).Count -ne 0) { $this.Policy | ForEach-Object { $currentItem = $_; if(($currentItem.Tags | Where-Object { $this.FilterTags -Contains $_ } | Measure-Object).Count -ne 0) { $this.ApplicableAlerts += $currentItem; } } } } return $this.ApplicableAlerts; } hidden [PSObject[]] GetApplicableARMAlerts([string[]] $alertNames) { if($null -eq $this.ApplicableAlerts) { $this.ApplicableAlerts = @(); if($alertNames -and $alertNames.Count -ne 0) { $this.ApplicableAlerts += $this.Policy | Where-Object { $alertNames -Contains $_.Name }; } elseif(($this.FilterTags | Measure-Object).Count -ne 0) { $this.Policy | ForEach-Object { $currentResourceTypeItem = $_; $applicableAlert = @{ Name=$currentResourceTypeItem.Name;Description = $currentResourceTypeItem.Description; ResourceType = $currentResourceTypeItem.ResourceType; OperationNameList =@(); Enabled = $currentResourceTypeItem.Enabled } $currentResourceTypeItem.AlertList | ForEach-Object{ $currentItem = $_ if(($currentItem.Tags | Where-Object { $this.FilterTags -Contains $_ } | Measure-Object).Count -ne 0) { $applicableAlert.OperationNameList += $currentItem.OperationName; } } if(($applicableAlert.OperationNameList | Measure-Object).Count -gt 0 ) { $this.ApplicableAlerts += $applicableAlert } } } } return $this.ApplicableAlerts; } hidden [PSObject[]] GetApplicableAlerts() { return $this.GetApplicableAlerts(@()); } hidden [PSObject[]] GetApplicableARMAlerts() { return $this.GetApplicableARMAlerts(@()); } [MessageData[]] SetAlerts([string] $targetResourceGroup, [string] $securityContactEmails, [string] $alertResourceGroupLocation) { # Parameter validation if([string]::IsNullOrWhiteSpace($securityContactEmails)) { throw [System.ArgumentException] ("The argument 'securityContactEmails' is null or empty"); } $allEmails = @(); $allEmails += $this.ConvertToStringArray($securityContactEmails); if($allEmails.Count -eq 0) { throw [System.ArgumentException] ("Please provide valid email address(es)"); } if(-not [string]::IsNullOrWhiteSpace($alertResourceGroupLocation)) { $this.ResourceGroupLocation = $alertResourceGroupLocation; } [MessageData[]] $messages = @(); if(($this.Policy | Measure-Object).Count -ne 0) { if($this.GetApplicableAlerts() -ne 0) { $startMessage = [MessageData]::new("Processing AzSDK alerts. Total alerts: $($this.GetApplicableAlerts().Count)"); $messages += $startMessage; $this.PublishCustomMessage($startMessage); $this.PublishCustomMessage("Note: Configuring alerts can take about 10-12 minutes depending on number of alerts to be processed...", [MessageType]::Warning); $disabledAlerts = $this.GetApplicableAlerts() | Where-Object { -not $_.Enabled }; if(($disabledAlerts | Measure-Object).Count -ne 0) { $disabledMessage = "Found alerts which are disabled. This is intentional. Total disabled alerts: $($disabledAlerts.Count)"; $messages += [MessageData]::new($disabledMessage, $disabledAlerts); } $enabledAlerts = @(); $enabledAlerts += $this.GetApplicableAlerts() | Where-Object { $_.Enabled }; if($enabledAlerts.Count -ne 0) { $messages += [MessageData]::new([Constants]::SingleDashLine + "`r`nAdding following alerts to the subscription. Total alerts: $($enabledAlerts.Count)", $enabledAlerts); # Check if Resource Group exists $existingRG = Get-AzureRmResourceGroup -Name $this.ResourceGroup -ErrorAction SilentlyContinue if(-not $existingRG) { New-AzureRmResourceGroup -Name $this.ResourceGroup -Location $this.ResourceGroupLocation -Tag @{ "AzSDKVersion" = $this.GetCurrentModuleVersion(); "CreationTime" = $this.RunIdentifier; "AzSDKFeature" = "Alerts" } -ErrorAction Stop | Out-Null } $messages += [MessageData]::new("All the alerts registered by this script will be placed in a resource group named: $($this.ResourceGroup)"); #Remove Resource Lock on Resource Group if any $messages += $this.RemoveAllResourceGroupLocks(); #Add-OutputLogEvent -OutputLogFilePath $outputLogFilePath -EventData ("A resource lock will be deployed on this resource group to protect from accidental deletion.") -RawOutput $isTargetResourceGroup = -not [string]::IsNullOrWhiteSpace($targetResourceGroup); [Helpers]::RegisterResourceProviderIfNotRegistered("microsoft.insights"); # Accepting only first email address because of Azure issue in creating Alert rule with multiple emails $emailAction = New-AzureRmAlertRuleEmail -CustomEmails $allEmails[0] -WarningAction SilentlyContinue $errorCount = 0; $currentCount = 0; $enabledAlerts | ForEach-Object { $alertName = $_.Name; $currentCount += 1; # Add alert try { if($isTargetResourceGroup) { Add-AzureRmLogAlertRule -Name $_.Name -Location $this.ResourceGroupLocation -ResourceGroup $this.ResourceGroup ` -TargetResourceGroup $targetResourceGroup -OperationName $_.OperationName ` -Actions $emailAction -Description $_.Description -WarningAction Ignore } else { Add-AzureRmLogAlertRule -Name $_.Name -Location $this.ResourceGroupLocation -ResourceGroup $this.ResourceGroup ` -OperationName $_.OperationName ` -Actions $emailAction -Description $_.Description -WarningAction Ignore } } catch { $messages += [MessageData]::new("Error while adding alert [$alertName] to the subscription", $_, [MessageType]::Error); $errorCount += 1; } $this.CommandProgress($enabledAlerts.Count, $currentCount, 20); }; [MessageData[]] $resultMessages = @(); #Logic to validate if Alerts are configured. $configuredAlerts = @(); $configuredAlerts = Get-AzureRmAlertRule -ResourceGroup $this.ResourceGroup -WarningAction SilentlyContinue $actualConfiguredAlertsCount = ($configuredAlerts | Measure-Object).Count $notConfiguredAlertsCount = $enabledAlerts.Count - $actualConfiguredAlertsCount if($errorCount -eq 0 -and $actualConfiguredAlertsCount -eq $enabledAlerts.Count) { $resultMessages += [MessageData]::new("All AzSDK alerts have been configured successfully.`r`n" + [Constants]::SingleDashLine, [MessageType]::Update); } elseif($errorCount -eq $enabledAlerts.Count) { $resultMessages += [MessageData]::new("No alerts have been added to the subscription due to error occurred. Please add the alerts manually.`r`n" + [Constants]::SingleDashLine, [MessageType]::Error); } else { $resultMessages += [MessageData]::new("$notConfiguredAlertsCount/$($enabledAlerts.Count) alert(s) have not been added to the subscription. Please add the alerts manually.", [MessageType]::Error); $resultMessages += [MessageData]::new("$actualConfiguredAlertsCount/$($enabledAlerts.Count) alert(s) have been added to the subscription successfully`r`n" + [Constants]::SingleDashLine, [MessageType]::Update); } $messages += $resultMessages; $this.PublishCustomMessage($resultMessages); # Create the lock $messages += $this.AddResourceGroupLock(); } } else { $this.PublishCustomMessage("No alerts have been found that matches the specified tags. Tags:[$([string]::Join(",", $this.FilterTags))].", [MessageType]::Warning); } } else { $this.PublishCustomMessage("No alerts found in the alert policy file", [MessageType]::Warning); } return $messages; } [MessageData[]] RemoveAlerts([bool] $deleteResourceGroup, [string] $alertNames) { [MessageData[]] $messages = @(); # Check for existence of resource group $existingRG = Get-AzureRmResourceGroup -Name $this.ResourceGroup -ErrorAction SilentlyContinue if($existingRG) { $startMessage = [MessageData]::new("Found AzSDK alerts resource group: $($this.ResourceGroup)"); $messages += $startMessage; $this.PublishCustomMessage($startMessage); # Remove all locks $messages += $this.RemoveAllResourceGroupLocks(); # Check if user wants to remove resource group if($deleteResourceGroup) { $messages += [MessageData]::new("Removing all AzSDK configured alerts by removing resource group: $($this.ResourceGroup)"); # Remove entire RG (containing all alerts). Remove-AzureRmResourceGroup -Name $this.ResourceGroup -Force $resultMessage = [MessageData]::new("All AzSDK configured alerts removed successfully"); $messages += $resultMessage; $this.PublishCustomMessage($resultMessage); } else { $alertNameArray = @(); if(-not [string]::IsNullOrWhiteSpace($alertNames)) { $alertNameArray += $this.ConvertToStringArray($alertNames); if($alertNameArray.Count -eq 0) { throw [System.ArgumentException] ("The argument 'alertNames' is null or empty"); } } # User wants to remove only specific alerts if(($this.Policy | Measure-Object).Count -ne 0) { if($this.GetApplicableAlerts($alertNameArray) -ne 0) { $startMessage = [MessageData]::new("Removing alerts. Tags:[$([string]::Join(",", $this.FilterTags))]. Total alerts: $($this.GetApplicableAlerts($alertNameArray).Count)"); $messages += $startMessage; $this.PublishCustomMessage($startMessage); $this.PublishCustomMessage("Note: Removing alerts can take few minutes depending on number of alerts to be processed...", [MessageType]::Warning); $disabledAlerts = $this.GetApplicableAlerts($alertNameArray) | Where-Object { -not $_.Enabled }; if(($disabledAlerts | Measure-Object).Count -ne 0) { $disabledMessage = "Found alerts which are disabled and will not be removed. This is intentional. Total disabled alerts: $($disabledAlerts.Count)"; $messages += [MessageData]::new($disabledMessage, $disabledAlerts); #$this.PublishCustomMessage($disabledMessage, [MessageType]::Warning); } $enabledAlerts = @(); $enabledAlerts += $this.GetApplicableAlerts($alertNameArray) | Where-Object { $_.Enabled }; if($enabledAlerts.Count -ne 0) { $messages += [MessageData]::new([Constants]::SingleDashLine + "`r`nRemoving following alerts from the subscription. Total alerts: $($enabledAlerts.Count)", $enabledAlerts); $errorCount = 0; $currentCount = 0; $enabledAlerts | ForEach-Object { $alertName = $_.Name; $currentCount += 1; # Remove alert try { Remove-AzureRmAlertRule -ResourceGroup $this.ResourceGroup -Name $alertName -WarningAction SilentlyContinue } catch { $messages += [MessageData]::new("Error while removing alert [$alertName] from the subscription", $_, [MessageType]::Error); $errorCount += 1; } $this.CommandProgress($enabledAlerts.Count, $currentCount, 20); }; [MessageData[]] $resultMessages = @(); if($errorCount -eq 0) { $resultMessages += [MessageData]::new("All alerts have been removed from the subscription successfully`r`n" + [Constants]::SingleDashLine, [MessageType]::Update); } elseif($errorCount -eq $enabledAlerts.Count) { $resultMessages += [MessageData]::new("No alerts have been removed from the subscription due to error occurred. Please add the alerts manually.`r`n" + [Constants]::SingleDashLine, [MessageType]::Error); } else { $resultMessages += [MessageData]::new("$errorCount/$($enabledAlerts.Count) alert(s) have not been removed from the subscription. Please remove the alerts manually.", [MessageType]::Error); $resultMessages += [MessageData]::new("$($enabledAlerts.Count - $errorCount)/$($enabledAlerts.Count) alert(s) have been removed from the subscription successfully`r`n" + [Constants]::SingleDashLine, [MessageType]::Update); } $messages += $resultMessages; $this.PublishCustomMessage($resultMessages); # Create the lock $messages += $this.AddResourceGroupLock(); } } else { $this.PublishCustomMessage("No alerts have been found that matches the specified tags. Tags:[$([string]::Join(",", $this.FilterTags))].", [MessageType]::Warning); } } else { $this.PublishCustomMessage("No alerts found in the alert policy file", [MessageType]::Warning); } } } else { $this.PublishCustomMessage("No AzSDK configured alerts found in the subscription. Resource group not found: $($this.ResourceGroup)", [MessageType]::Warning); } return $messages; } hidden [MessageData[]] RemoveAllResourceGroupLocks() { $messages = @(); #Remove Resource Lock on Resource Group if any $locks = @(); $locks += Get-AzureRmResourceLock -ResourceGroupName $this.ResourceGroup if($locks.Count -ne 0) { $messages += [MessageData]::new("Removing following existing resource group locks so that alerts can be processed. Total: $($locks.Count)", $locks); $locks | ForEach-Object { Remove-AzureRmResourceLock -LockId $_.LockId -Force | Out-Null } Start-Sleep -Seconds 60 } return $messages; } hidden [MessageData[]] AddResourceGroupLock() { $messages = @(); # Create the lock $lockName = "AzSDKAlertLock"; $lockObject = New-AzureRmResourceLock -ResourceGroupName $this.ResourceGroup -LockName $lockName -LockLevel ReadOnly -LockNotes "Lock created by AzSDK to protect alert objects" -Force $messages += [MessageData]::new("Created ResourceGroup lock to protect the alert objects. Lock name: $lockName", $lockObject); return $messages; } [MessageData[]] SetAlertsPreview([string] $targetResourceGroup, [string] $securityContactEmails, [string] $alertResourceGroupLocation) { # Parameter validation if([string]::IsNullOrWhiteSpace($securityContactEmails)) { throw [System.ArgumentException] ("The argument 'securityContactEmails' is null or empty"); } $allEmails = @(); $allEmails += $this.ConvertToStringArray($securityContactEmails); if($allEmails.Count -eq 0) { throw [System.ArgumentException] ("Please provide valid email address(es)"); } if(-not [string]::IsNullOrWhiteSpace($alertResourceGroupLocation)) { $this.ResourceGroupLocation = $alertResourceGroupLocation; } [MessageData[]] $messages = @(); if(($this.Policy | Measure-Object).Count -ne 0) { $alertList = $this.GetApplicableARMAlerts(); if($alertList -ne 0) { $this.PublishCustomMessage("Warning: Preview mode will configure alerts with critical severity only.",[MessageType]::Warning); $criticalAlerts = $alertList $startMessage = [MessageData]::new("Processing AzSDK alerts. Total alerts: $($criticalAlerts.Count)"); $messages += $startMessage; $this.PublishCustomMessage($startMessage); $this.PublishCustomMessage("Note: Configuring alerts can take about 10-12 minutes depending on number of alerts to be processed...", [MessageType]::Warning); $disabledAlerts = $criticalAlerts | Where-Object { -not $_.Enabled }; if(($disabledAlerts | Measure-Object).Count -ne 0) { $disabledMessage = "Found alerts which are disabled. This is intentional. Total disabled alerts: $($disabledAlerts.Count)"; $messages += [MessageData]::new($disabledMessage, $disabledAlerts); } $enabledAlerts = @(); $enabledAlerts += $criticalAlerts | Where-Object { $_.Enabled }; if($enabledAlerts.Count -ne 0) { $messages += [MessageData]::new([Constants]::SingleDashLine + "`r`nAdding following alerts to the subscription. Total alerts: $($enabledAlerts.Count)", $enabledAlerts); # Check if Resource Group exists $existingRG = Get-AzureRmResourceGroup -Name $this.ResourceGroup -ErrorAction SilentlyContinue if(-not $existingRG) { New-AzureRmResourceGroup -Name $this.ResourceGroup -Location $this.ResourceGroupLocation -Tag @{ "AzSDKVersion" = $this.GetCurrentModuleVersion(); "CreationTime" = $this.RunIdentifier; "AzSDKFeature" = "Alerts" } -ErrorAction Stop | Out-Null } $messages += [MessageData]::new("All the alerts registered by this script will be placed in a resource group named: $($this.ResourceGroup)"); #Remove Resource Lock on Resource Group if any $messages += $this.RemoveAllResourceGroupLocks(); #Add-OutputLogEvent -OutputLogFilePath $outputLogFilePath -EventData ("A resource lock will be deployed on this resource group to protect from accidental deletion.") -RawOutput $isTargetResourceGroup = -not [string]::IsNullOrWhiteSpace($targetResourceGroup); # Accepting only first email address because of Azure issue in creating Alert rule with multiple emails $actionGroupResourceId = $this.SetupAlertActionGroup($allEmails) try { $criticalAlertList = @() $alertArm = $this.LoadServerConfigFile("Subscription.AlertARM.json"); $alert = ($alertArm.resources | Select -First 1).PSObject.Copy() $enabledAlerts | ForEach-Object { $alertObj = [Helpers]::DeepCopy($alert) $alertObj.name = $_.Name $alertObj.properties.description = $_.Description $alertObj.properties.condition.allOf += @{ field = "resourceType"; equals =$_.ResourceType } #$operationDetails.equals = $_.ResourceType $alertObj.properties.condition.allOf[1].anyOf =@() $_.OperationNameList | ForEach-Object { $alertObj.properties.condition.allOf[1].anyOf += @{ field = "operationName"; equals =$_ } } $alertObj.properties.actions.actionGroups[0].actionGroupId = $actionGroupResourceId $criticalAlertList += $alertObj } $alertArm.resources = $criticalAlertList $armTemplatePath = "$env:TEMP/Subscription.AlertARM.json" $alertArm | ConvertTo-Json -Depth 100 | Out-File $armTemplatePath -Force $alertDeployment = New-AzureRmResourceGroupDeployment -Name "AzSDKAlertsDeployment" -ResourceGroupName $this.ResourceGroup -TemplateFile $armTemplatePath -ErrorAction Stop Remove-Item $armTemplatePath -ErrorAction SilentlyContinue } catch { $messages += [MessageData]::new("Error while deploying alerts to the subscription", $_, [MessageType]::Error); } [MessageData[]] $resultMessages = @(); #Logic to validate if Alerts are configured. $configuredAlerts = @(); $configuredAlerts = Get-AzureRmResource -ResourceType "Microsoft.Insights/activityLogAlerts" -ResourceGroupName $this.ResourceGroup $actualConfiguredAlertsCount = ($configuredAlerts | Measure-Object).Count $notConfiguredAlertsCount = $enabledAlerts.Count - $actualConfiguredAlertsCount if( $actualConfiguredAlertsCount -eq $enabledAlerts.Count) { $resultMessages += [MessageData]::new("All AzSDK alerts have been configured successfully.`r`n" + [Constants]::SingleDashLine, [MessageType]::Update); } else { $resultMessages += [MessageData]::new("$notConfiguredAlertsCount/$($enabledAlerts.Count) alert(s) have not been added to the subscription. Please add the alerts manually.", [MessageType]::Error); $resultMessages += [MessageData]::new("$actualConfiguredAlertsCount/$($enabledAlerts.Count) alert(s) have been added to the subscription successfully`r`n" + [Constants]::SingleDashLine, [MessageType]::Update); } $messages += $resultMessages; $this.PublishCustomMessage($resultMessages); # Create the lock $messages += $this.AddResourceGroupLock(); } } else { $this.PublishCustomMessage("No alerts have been found that matches the specified tags. Tags:[$([string]::Join(",", $this.FilterTags))].", [MessageType]::Warning); } } else { $this.PublishCustomMessage("No alerts found in the alert policy file", [MessageType]::Warning); } return $messages; } hidden [string] SetupAlertActionGroup([string[]] $securityContactEmails) { $actionGroupResourceId = $null try{ #Get ARM template for action group $actionGroupArm = $this.LoadServerConfigFile("Subscription.AlertActionGroup.json"); $actionGroupArmResource = $actionGroupArm.resources | Where-Object { $_.Name -eq "AzSDKAlertActionGroup" } $emailReceivers = $actionGroupArmResource.properties.emailReceivers | Select-Object -first 1 $emailReceiversList = @(); $securityContactEmails | ForEach-Object { if(-not [string]::IsNullOrWhiteSpace($securityContactEmails)) { $email = $emailReceivers.PsObject.Copy() $email.name = $_.Split('@')[0] $email.emailAddress = $_ $emailReceiversList += $email } } $actionGroupArmResource.properties.emailReceivers = $emailReceiversList $armTemplatePath = "$env:TEMP/Subscription.AlertActionGroup.json" $actionGroupArm | ConvertTo-Json -Depth 100 | Out-File $armTemplatePath $actionGroupResource = New-AzureRmResourceGroupDeployment -Name "AzSDKAlertActionGroupDeployment" -ResourceGroupName $this.ResourceGroup -TemplateFile $armTemplatePath -ErrorAction Stop $actionGroupId = $actionGroupResource.Outputs | Where-Object actionGroupId $actionGroupResourceId = $actionGroupId.Values | Select -ExpandProperty Value Remove-Item $armTemplatePath -ErrorAction SilentlyContinue } catch { $messages += [MessageData]::new("Error while deploying alerts action group to the subscription", $_, [MessageType]::Error); } return $actionGroupResourceId } } # SIG # Begin signature block # MIIkAgYJKoZIhvcNAQcCoIIj8zCCI+8CAQExDzANBglghkgBZQMEAgEFADB5Bgor # BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG # KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCAwoVHTTddNL5lB # 38mE02GVIs+bvq4LOcnQf+62T0Pj26CCDZMwggYRMIID+aADAgECAhMzAAAAjoeR # pFcaX8o+AAAAAACOMA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNVBAYTAlVTMRMwEQYD # VQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNy # b3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMTH01pY3Jvc29mdCBDb2RlIFNpZ25p # bmcgUENBIDIwMTEwHhcNMTYxMTE3MjIwOTIxWhcNMTgwMjE3MjIwOTIxWjCBgzEL # MAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1v # bmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjENMAsGA1UECxMETU9Q # UjEeMBwGA1UEAxMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMIIBIjANBgkqhkiG9w0B # AQEFAAOCAQ8AMIIBCgKCAQEA0IfUQit+ndnGetSiw+MVktJTnZUXyVI2+lS/qxCv # 6cnnzCZTw8Jzv23WAOUA3OlqZzQw9hYXtAGllXyLuaQs5os7efYjDHmP81LfQAEc # wsYDnetZz3Pp2HE5m/DOJVkt0slbCu9+1jIOXXQSBOyeBFOmawJn+E1Zi3fgKyHg # 78CkRRLPA3sDxjnD1CLcVVx3Qv+csuVVZ2i6LXZqf2ZTR9VHCsw43o17lxl9gtAm # +KWO5aHwXmQQ5PnrJ8by4AjQDfJnwNjyL/uJ2hX5rg8+AJcH0Qs+cNR3q3J4QZgH # uBfMorFf7L3zUGej15Tw0otVj1OmlZPmsmbPyTdo5GPHzwIDAQABo4IBgDCCAXww # HwYDVR0lBBgwFgYKKwYBBAGCN0wIAQYIKwYBBQUHAwMwHQYDVR0OBBYEFKvI1u2y # FdKqjvHM7Ww490VK0Iq7MFIGA1UdEQRLMEmkRzBFMQ0wCwYDVQQLEwRNT1BSMTQw # MgYDVQQFEysyMzAwMTIrYjA1MGM2ZTctNzY0MS00NDFmLWJjNGEtNDM0ODFlNDE1 # ZDA4MB8GA1UdIwQYMBaAFEhuZOVQBdOCqhc3NyK1bajKdQKVMFQGA1UdHwRNMEsw # SaBHoEWGQ2h0dHA6Ly93d3cubWljcm9zb2Z0LmNvbS9wa2lvcHMvY3JsL01pY0Nv # ZFNpZ1BDQTIwMTFfMjAxMS0wNy0wOC5jcmwwYQYIKwYBBQUHAQEEVTBTMFEGCCsG # AQUFBzAChkVodHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2NlcnRzL01p # Y0NvZFNpZ1BDQTIwMTFfMjAxMS0wNy0wOC5jcnQwDAYDVR0TAQH/BAIwADANBgkq # hkiG9w0BAQsFAAOCAgEARIkCrGlT88S2u9SMYFPnymyoSWlmvqWaQZk62J3SVwJR # avq/m5bbpiZ9CVbo3O0ldXqlR1KoHksWU/PuD5rDBJUpwYKEpFYx/KCKkZW1v1rO # qQEfZEah5srx13R7v5IIUV58MwJeUTub5dguXwJMCZwaQ9px7eTZ56LadCwXreUM # tRj1VAnUvhxzzSB7pPrI29jbOq76kMWjvZVlrkYtVylY1pLwbNpj8Y8zon44dl7d # 8zXtrJo7YoHQThl8SHywC484zC281TllqZXBA+KSybmr0lcKqtxSCy5WJ6PimJdX # jrypWW4kko6C4glzgtk1g8yff9EEjoi44pqDWLDUmuYx+pRHjn2m4k5589jTajMW # UHDxQruYCen/zJVVWwi/klKoCMTx6PH/QNf5mjad/bqQhdJVPlCtRh/vJQy4njpI # BGPveJiiXQMNAtjcIKvmVrXe7xZmw9dVgh5PgnjJnlQaEGC3F6tAE5GusBnBmjOd # 7jJyzWXMT0aYLQ9RYB58+/7b6Ad5B/ehMzj+CZrbj3u2Or2FhrjMvH0BMLd7Hald # G73MTRf3bkcz1UDfasouUbi1uc/DBNM75ePpEIzrp7repC4zaikvFErqHsEiODUF # he/CBAANa8HYlhRIFa9+UrC4YMRStUqCt4UqAEkqJoMnWkHevdVmSbwLnHhwCbww # ggd6MIIFYqADAgECAgphDpDSAAAAAAADMA0GCSqGSIb3DQEBCwUAMIGIMQswCQYD # VQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEe # MBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTIwMAYDVQQDEylNaWNyb3Nv # ZnQgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgMjAxMTAeFw0xMTA3MDgyMDU5 # MDlaFw0yNjA3MDgyMTA5MDlaMH4xCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNo # aW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29y # cG9yYXRpb24xKDAmBgNVBAMTH01pY3Jvc29mdCBDb2RlIFNpZ25pbmcgUENBIDIw # MTEwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCr8PpyEBwurdhuqoIQ # TTS68rZYIZ9CGypr6VpQqrgGOBoESbp/wwwe3TdrxhLYC/A4wpkGsMg51QEUMULT # iQ15ZId+lGAkbK+eSZzpaF7S35tTsgosw6/ZqSuuegmv15ZZymAaBelmdugyUiYS # L+erCFDPs0S3XdjELgN1q2jzy23zOlyhFvRGuuA4ZKxuZDV4pqBjDy3TQJP4494H # DdVceaVJKecNvqATd76UPe/74ytaEB9NViiienLgEjq3SV7Y7e1DkYPZe7J7hhvZ # PrGMXeiJT4Qa8qEvWeSQOy2uM1jFtz7+MtOzAz2xsq+SOH7SnYAs9U5WkSE1JcM5 # bmR/U7qcD60ZI4TL9LoDho33X/DQUr+MlIe8wCF0JV8YKLbMJyg4JZg5SjbPfLGS # rhwjp6lm7GEfauEoSZ1fiOIlXdMhSz5SxLVXPyQD8NF6Wy/VI+NwXQ9RRnez+ADh # vKwCgl/bwBWzvRvUVUvnOaEP6SNJvBi4RHxF5MHDcnrgcuck379GmcXvwhxX24ON # 7E1JMKerjt/sW5+v/N2wZuLBl4F77dbtS+dJKacTKKanfWeA5opieF+yL4TXV5xc # v3coKPHtbcMojyyPQDdPweGFRInECUzF1KVDL3SV9274eCBYLBNdYJWaPk8zhNqw # iBfenk70lrC8RqBsmNLg1oiMCwIDAQABo4IB7TCCAekwEAYJKwYBBAGCNxUBBAMC # AQAwHQYDVR0OBBYEFEhuZOVQBdOCqhc3NyK1bajKdQKVMBkGCSsGAQQBgjcUAgQM # HgoAUwB1AGIAQwBBMAsGA1UdDwQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB8GA1Ud # IwQYMBaAFHItOgIxkEO5FAVO4eqnxzHRI4k0MFoGA1UdHwRTMFEwT6BNoEuGSWh0 # dHA6Ly9jcmwubWljcm9zb2Z0LmNvbS9wa2kvY3JsL3Byb2R1Y3RzL01pY1Jvb0Nl # ckF1dDIwMTFfMjAxMV8wM18yMi5jcmwwXgYIKwYBBQUHAQEEUjBQME4GCCsGAQUF # BzAChkJodHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpL2NlcnRzL01pY1Jvb0Nl # ckF1dDIwMTFfMjAxMV8wM18yMi5jcnQwgZ8GA1UdIASBlzCBlDCBkQYJKwYBBAGC # Ny4DMIGDMD8GCCsGAQUFBwIBFjNodHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtp # b3BzL2RvY3MvcHJpbWFyeWNwcy5odG0wQAYIKwYBBQUHAgIwNB4yIB0ATABlAGcA # YQBsAF8AcABvAGwAaQBjAHkAXwBzAHQAYQB0AGUAbQBlAG4AdAAuIB0wDQYJKoZI # hvcNAQELBQADggIBAGfyhqWY4FR5Gi7T2HRnIpsLlhHhY5KZQpZ90nkMkMFlXy4s # PvjDctFtg/6+P+gKyju/R6mj82nbY78iNaWXXWWEkH2LRlBV2AySfNIaSxzzPEKL # UtCw/WvjPgcuKZvmPRul1LUdd5Q54ulkyUQ9eHoj8xN9ppB0g430yyYCRirCihC7 # pKkFDJvtaPpoLpWgKj8qa1hJYx8JaW5amJbkg/TAj/NGK978O9C9Ne9uJa7lryft # 0N3zDq+ZKJeYTQ49C/IIidYfwzIY4vDFLc5bnrRJOQrGCsLGra7lstnbFYhRRVg4 # MnEnGn+x9Cf43iw6IGmYslmJaG5vp7d0w0AFBqYBKig+gj8TTWYLwLNN9eGPfxxv # FX1Fp3blQCplo8NdUmKGwx1jNpeG39rz+PIWoZon4c2ll9DuXWNB41sHnIc+BncG # 0QaxdR8UvmFhtfDcxhsEvt9Bxw4o7t5lL+yX9qFcltgA1qFGvVnzl6UJS0gQmYAf # 0AApxbGbpT9Fdx41xtKiop96eiL6SJUfq/tHI4D1nvi/a7dLl+LrdXga7Oo3mXkY # S//WsyNodeav+vyL6wuA6mk7r/ww7QRMjt/fdW1jkT3RnVZOT7+AVyKheBEyIXrv # QQqxP/uozKRdwaGIm1dxVk5IRcBCyZt2WwqASGv9eZ/BvW1taslScxMNelDNMYIV # xTCCFcECAQEwgZUwfjELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24x # EDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlv # bjEoMCYGA1UEAxMfTWljcm9zb2Z0IENvZGUgU2lnbmluZyBQQ0EgMjAxMQITMwAA # AI6HkaRXGl/KPgAAAAAAjjANBglghkgBZQMEAgEFAKCBsDAZBgkqhkiG9w0BCQMx # DAYKKwYBBAGCNwIBBDAcBgorBgEEAYI3AgELMQ4wDAYKKwYBBAGCNwIBFTAvBgkq # hkiG9w0BCQQxIgQgjTufBfFg+yFNN/HjjOyZT3voO4VUJsCGJS5cy+YrvhEwRAYK # KwYBBAGCNwIBDDE2MDSgEoAQAEEAegBTAEQASwAyADUAMqEegBxodHRwczovL2Fr # YS5tcy9henNka29zc2RvY3MgMA0GCSqGSIb3DQEBAQUABIIBAMZMeDRC7PoOisYu # RUoqUcOhMrJKAMbVLr+PG3GZSkVhY2+ji0cQdH210YAhpGx7cn4mwdrFsAcTMnJY # HDHB/CqeuhgpfA8yR2h0+njHIbc2HbQvJY4kxeDIw7BfGCaJ6fyuGYrSgKYbzPd/ # Tk/219/68xlxPRRCQf1bpnRH3Oc/AopP4R3DPzi96xTdce1YjZ2rzGEAx/yAwJnO # oGhfDQ62VK9mLBwP/m/CsasY8E/haR+rTqKeDZptWq/OZoxNZlcMdgnECV/Pc3xJ # hK5Q4RJRkt73VLj/w/+JqNgM+9TbjQ9V+zctDMAqXKb0JDp+nlI7X0DERMm2GTXR # TxbjFxehghNNMIITSQYKKwYBBAGCNwMDATGCEzkwghM1BgkqhkiG9w0BBwKgghMm # MIITIgIBAzEPMA0GCWCGSAFlAwQCAQUAMIIBPQYLKoZIhvcNAQkQAQSgggEsBIIB # KDCCASQCAQEGCisGAQQBhFkKAwEwMTANBglghkgBZQMEAgEFAAQgDCuZOqO8zyEU # LZJqbkTJDwb8S7pZmlrtdytp4BJGB+cCBlmSONxQ7RgTMjAxNzA5MDUwOTM3MDku # NDE3WjAHAgEBgAIB9KCBuaSBtjCBszELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldh # c2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBD # b3Jwb3JhdGlvbjENMAsGA1UECxMETU9QUjEnMCUGA1UECxMebkNpcGhlciBEU0Ug # RVNOOjdEMkUtMzc4Mi1CMEY3MSUwIwYDVQQDExxNaWNyb3NvZnQgVGltZS1TdGFt # cCBTZXJ2aWNloIIO0DCCBnEwggRZoAMCAQICCmEJgSoAAAAAAAIwDQYJKoZIhvcN # AQELBQAwgYgxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYD # VQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xMjAw # BgNVBAMTKU1pY3Jvc29mdCBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAyMDEw # MB4XDTEwMDcwMTIxMzY1NVoXDTI1MDcwMTIxNDY1NVowfDELMAkGA1UEBhMCVVMx # EzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoT # FU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEmMCQGA1UEAxMdTWljcm9zb2Z0IFRpbWUt # U3RhbXAgUENBIDIwMTAwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCp # HQ28dxGKOiDs/BOX9fp/aZRrdFQQ1aUKAIKF++18aEssX8XD5WHCdrc+Zitb8BVT # JwQxH0EbGpUdzgkTjnxhMFmxMEQP8WCIhFRDDNdNuDgIs0Ldk6zWczBXJoKjRQ3Q # 6vVHgc2/JGAyWGBG8lhHhjKEHnRhZ5FfgVSxz5NMksHEpl3RYRNuKMYa+YaAu99h # /EbBJx0kZxJyGiGKr0tkiVBisV39dx898Fd1rL2KQk1AUdEPnAY+Z3/1ZsADlkR+ # 79BL/W7lmsqxqPJ6Kgox8NpOBpG2iAg16HgcsOmZzTznL0S6p/TcZL2kAcEgCZN4 # zfy8wMlEXV4WnAEFTyJNAgMBAAGjggHmMIIB4jAQBgkrBgEEAYI3FQEEAwIBADAd # BgNVHQ4EFgQU1WM6XIoxkPNDe3xGG8UzaFqFbVUwGQYJKwYBBAGCNxQCBAweCgBT # AHUAYgBDAEEwCwYDVR0PBAQDAgGGMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgw # FoAU1fZWy4/oolxiaNE9lJBb186aGMQwVgYDVR0fBE8wTTBLoEmgR4ZFaHR0cDov # L2NybC5taWNyb3NvZnQuY29tL3BraS9jcmwvcHJvZHVjdHMvTWljUm9vQ2VyQXV0 # XzIwMTAtMDYtMjMuY3JsMFoGCCsGAQUFBwEBBE4wTDBKBggrBgEFBQcwAoY+aHR0 # cDovL3d3dy5taWNyb3NvZnQuY29tL3BraS9jZXJ0cy9NaWNSb29DZXJBdXRfMjAx # MC0wNi0yMy5jcnQwgaAGA1UdIAEB/wSBlTCBkjCBjwYJKwYBBAGCNy4DMIGBMD0G # CCsGAQUFBwIBFjFodHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vUEtJL2RvY3MvQ1BT # L2RlZmF1bHQuaHRtMEAGCCsGAQUFBwICMDQeMiAdAEwAZQBnAGEAbABfAFAAbwBs # AGkAYwB5AF8AUwB0AGEAdABlAG0AZQBuAHQALiAdMA0GCSqGSIb3DQEBCwUAA4IC # AQAH5ohRDeLG4Jg/gXEDPZ2joSFvs+umzPUxvs8F4qn++ldtGTCzwsVmyWrf9efw # eL3HqJ4l4/m87WtUVwgrUYJEEvu5U4zM9GASinbMQEBBm9xcF/9c+V4XNZgkVkt0 # 70IQyK+/f8Z/8jd9Wj8c8pl5SpFSAK84Dxf1L3mBZdmptWvkx872ynoAb0swRCQi # PM/tA6WWj1kpvLb9BOFwnzJKJ/1Vry/+tuWOM7tiX5rbV0Dp8c6ZZpCM/2pif93F # SguRJuI57BlKcWOdeyFtw5yjojz6f32WapB4pm3S4Zz5Hfw42JT0xqUKloakvZ4a # rgRCg7i1gJsiOCC1JeVk7Pf0v35jWSUPei45V3aicaoGig+JFrphpxHLmtgOR5qA # xdDNp9DvfYPw4TtxCd9ddJgiCGHasFAeb73x4QDf5zEHpJM692VHeOj4qEir995y # fmFrb3epgcunCaw5u+zGy9iCtHLNHfS4hQEegPsbiSpUObJb2sgNVZl6h3M7COaY # LeqN4DMuEin1wC9UJyH3yKxO2ii4sanblrKnQqLJzxlBTeCG+SqaoxFmMNO7dDJL # 32N79ZmKLxvHIa9Zta7cRDyXUHHXodLFVeNp3lfB0d4wwP3M5k37Db9dT+mdHhk4 # L7zPWAUu7w2gUDXa7wknHNWzfjUeCLraNtvTX4/edIhJEjCCBNowggPCoAMCAQIC # EzMAAACiTI4d2qkhfIQAAAAAAKIwDQYJKoZIhvcNAQELBQAwfDELMAkGA1UEBhMC # VVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNV # BAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEmMCQGA1UEAxMdTWljcm9zb2Z0IFRp # bWUtU3RhbXAgUENBIDIwMTAwHhcNMTYwOTA3MTc1NjQ5WhcNMTgwOTA3MTc1NjQ5 # WjCBszELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcT # B1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjENMAsGA1UE # CxMETU9QUjEnMCUGA1UECxMebkNpcGhlciBEU0UgRVNOOjdEMkUtMzc4Mi1CMEY3 # MSUwIwYDVQQDExxNaWNyb3NvZnQgVGltZS1TdGFtcCBTZXJ2aWNlMIIBIjANBgkq # hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApgF3BXvDfQ52aL3GqIPGgnsBcKiwaoRy # T1SObb5nIGq+7C3dL0dx4ZL9dGJrvnTbhTbbNMjHaQrmNhJJQEe4QTRZYj3xE6eu # CQEo0RRYYx85sGg2BNhZ2k1b4JFxEvxBsw3OwXKhFSb285lb6OCKrhB1qjnX8Q7y # CcExdQwpKind7I43Kt9rquMyuNhNe8hxEJDBvjqGGQvo6a0fuDQjrWGMli77Pkwv # QmXGCx6xsFjCa5vnz4sEx5NBneZ5uOX3llfcgMUFBQCmQSI3Fvm060esLzmt0MXT # DETXCVtp0QnzAytjJ1oHkPTvjKMzJY03LD8lmbPzFT6mkur5URjl1QIDAQABo4IB # GzCCARcwHQYDVR0OBBYEFG672cHC2hawfK3CU3/n0BcTPbxXMB8GA1UdIwQYMBaA # FNVjOlyKMZDzQ3t8RhvFM2hahW1VMFYGA1UdHwRPME0wS6BJoEeGRWh0dHA6Ly9j # cmwubWljcm9zb2Z0LmNvbS9wa2kvY3JsL3Byb2R1Y3RzL01pY1RpbVN0YVBDQV8y # MDEwLTA3LTAxLmNybDBaBggrBgEFBQcBAQROMEwwSgYIKwYBBQUHMAKGPmh0dHA6 # Ly93d3cubWljcm9zb2Z0LmNvbS9wa2kvY2VydHMvTWljVGltU3RhUENBXzIwMTAt # MDctMDEuY3J0MAwGA1UdEwEB/wQCMAAwEwYDVR0lBAwwCgYIKwYBBQUHAwgwDQYJ # KoZIhvcNAQELBQADggEBADWZV20z9kidnkHczKlg7lxHSFQRCoa5Vz+nbZiOynxp # pmqWg845sr1kDpkwu77c4HWCa0Ip4YVEjjF7c2hZeZidV7QWB/yiKbyjcIIhJh1l # SxnmiSpVza+6kmreyJoJAlslFpfHq7la2vTzoBuCcKpKxka1eoDEYkKD93FaZCsm # /fOOIwtOFvIb8tA1CkPaPPOpGpGKxDV42RCoYwajZH+svyjuqBwVeI+g98Jxxdi4 # ks6ql3I5TA9oZEROyoblLcuyArEoPf0ZvwDWSNPfDbTtDCSQRRS8lXk6A+xjhjw0 # 7nGyPS5qeZCCtusbGlm7r4uLefGp/Uox8jxqGxVdOsahggN5MIICYQIBATCB46GB # uaSBtjCBszELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNV # BAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjENMAsG # A1UECxMETU9QUjEnMCUGA1UECxMebkNpcGhlciBEU0UgRVNOOjdEMkUtMzc4Mi1C # MEY3MSUwIwYDVQQDExxNaWNyb3NvZnQgVGltZS1TdGFtcCBTZXJ2aWNloiUKAQEw # CQYFKw4DAhoFAAMVAF4vF+lxhNIyy+zXXko7+E63h+n1oIHCMIG/pIG8MIG5MQsw # CQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9u # ZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMQ0wCwYDVQQLEwRNT1BS # MScwJQYDVQQLEx5uQ2lwaGVyIE5UUyBFU046NTdGNi1DMUUwLTU1NEMxKzApBgNV # BAMTIk1pY3Jvc29mdCBUaW1lIFNvdXJjZSBNYXN0ZXIgQ2xvY2swDQYJKoZIhvcN # AQEFBQACBQDdWK1sMCIYDzIwMTcwOTA1MDQ1ODIwWhgPMjAxNzA5MDYwNDU4MjBa # MHcwPQYKKwYBBAGEWQoEATEvMC0wCgIFAN1YrWwCAQAwCgIBAAICDnkCAf8wBwIB # AAICGLQwCgIFAN1Z/uwCAQAwNgYKKwYBBAGEWQoEAjEoMCYwDAYKKwYBBAGEWQoD # AaAKMAgCAQACAxbjYKEKMAgCAQACAwehIDANBgkqhkiG9w0BAQUFAAOCAQEAcmGj # BBTr+m5dd4eEDdc2UUFm4Al/CGHzZYgdOFKvfZ1/YnsnH6MMuoUgAwG6+EhEWyMD # oFUbsyNGdUyXXN9eQPDmjT4Gk1Tl7cQHgHEKVmqElgVAyDISE3V3CvqYlypCasYl # iuOt/aE+EiBterVmkPPEB+XFz1M+WMFEjjA/l/9zTQj9XYjey4415ox5/k4TT02B # GUr+0OcU1/7BzL3CqEHRpal9ES6i7+8jFsm8xgi7ifMZSTVeFlcw0AzO38+YUc7T # +othjWn50Ll0INYWIE1uHMP6M+hGN9fD8TK0WdhaKP59pbcMpd9d3kjG+sNeggSh # bwcVPJiNzcVIaGbjxDGCAvUwggLxAgEBMIGTMHwxCzAJBgNVBAYTAlVTMRMwEQYD # VQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNy # b3NvZnQgQ29ycG9yYXRpb24xJjAkBgNVBAMTHU1pY3Jvc29mdCBUaW1lLVN0YW1w # IFBDQSAyMDEwAhMzAAAAokyOHdqpIXyEAAAAAACiMA0GCWCGSAFlAwQCAQUAoIIB # MjAaBgkqhkiG9w0BCQMxDQYLKoZIhvcNAQkQAQQwLwYJKoZIhvcNAQkEMSIEINnT # isx0ykE9b3gTYFFesVLAmIfNIcIkF816eQ2/IVbgMIHiBgsqhkiG9w0BCRACDDGB # 0jCBzzCBzDCBsQQUXi8X6XGE0jLL7NdeSjv4TreH6fUwgZgwgYCkfjB8MQswCQYD # VQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEe # MBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSYwJAYDVQQDEx1NaWNyb3Nv # ZnQgVGltZS1TdGFtcCBQQ0EgMjAxMAITMwAAAKJMjh3aqSF8hAAAAAAAojAWBBTM # BEq1o6Nbw5EBNOEoqaWczrIaQDANBgkqhkiG9w0BAQsFAASCAQB/Tla6mpPganeI # IBvOA5EgjCOKEE80Yaa2W63x4qVLMy7O19mbabyFCwAMGaL0r+Wkr5VDh0Ql7QtW # P5AJtH3gVScUvoMCCF3ST5ZABCkOhTwq6dD/uaLJhsypmmJSZ2wxMrFoxb1mAY4V # mN35QiX1dS51k4uEQsCIOzEpu1zpzCpHhO77d7Wh7PC3UNFZ10GUpwcPchD0v3aV # BQLRypEKDj7BObIT8MJZWr1cOFe/HAmaU0Ly/ROUvs0i9DqfBx0Gq9td9mnNzYN5 # AEI859CBELSjUFTHvbCx2KyiDNBQWSY+O3MxdHFJ914DBTSRwWlcFRcnlhiJqTNV # ovNvnFsW # SIG # End signature block |