Framework/Core/SVT/Services/ServiceFabric.ps1

Set-StrictMode -Version Latest 
class ServiceFabric : SVTBase
{       
    hidden [PSObject] $ResourceObject;
    hidden [string] $ClusterTagValue;
    hidden [PSObject] $ApplicationList;
    hidden [string] $DefaultTagName = "clusterName"
    hidden [string] $CertStoreLocation = "CurrentUser"
    hidden [string] $CertStoreName = "My"
    ServiceFabric([string] $subscriptionId, [SVTResource] $svtResource): 
        Base($subscriptionId, $svtResource) 
    { 
        $this.GetResourceObject();
        
    }

    hidden [PSObject] GetResourceObject()
    {
        if (-not $this.ResourceObject) 
        {
            $this.ResourceObject =  Get-AzureRmResource -ResourceGroupName $this.ResourceContext.ResourceGroupName -ResourceType $this.ResourceContext.ResourceType -ResourceName $this.ResourceContext.ResourceName -ApiVersion 2016-03-01        

            $this.ResourceObject.Tags.GetEnumerator() | Where-Object { $_.Name -eq $this.DefaultTagName } | ForEach-Object {$this.ClusterTagValue = $_.Value }
            
            ## Commented below two lines of code. This will be covered once we Service Fabric module gets available as part of AzureRM modules set.
            #$this.CheckClusterAccess();
            #$this.ApplicationList = Get-ServiceFabricApplication
            
            if(-not $this.ResourceObject)
            {
                throw ("Resource '{0}' not found under Resource Group '{1}'" -f ($this.ResourceContext.ResourceName), ($this.ResourceContext.ResourceGroupName))
            }
        }
        return $this.ResourceObject;
    }

    hidden [ControlResult] CheckSecurityMode([ControlResult] $controlResult)
    {
        $isCertificateEnabled = [Helpers]::CheckMember($this.ResourceObject.Properties,"certificate" ) 
        
        #Validate if primary certificate is enabled on cluster. Presence of certificate property value indicates, security mode is turned on.
        if($isCertificateEnabled)
        {            
            $controlResult.AddMessage([VerificationResult]::Passed,"Service Fabric cluster is secured with certificate", $this.ResourceObject.Properties.certificate);
        }
        else
        {            
            $controlResult.AddMessage([VerificationResult]::Failed,"Service Fabric cluster is not secured with certificate");
        }
        return $controlResult;    
    }

    hidden [ControlResult] CheckClusterCertificateSSL([ControlResult] $controlResult)
    {
        $managementEndpointUri = $this.ResourceObject.Properties.managementEndpoint
        $managementEndpointUriScheme = ([System.Uri]$managementEndpointUri).Scheme               

        #Validate if cluster management endpoint url is SSL enabled
        if($managementEndpointUriScheme -eq "https")
        {   
            #Hit web request to management endpoint uri and validate certificate trust level
            $request = [System.Net.HttpWebRequest]::Create($managementEndpointUri) 
            try
            {
                $request.GetResponse().Dispose()
                $controlResult.AddMessage([VerificationResult]::Passed,"Service Fabric cluster is protected with CA signed certificate");                    
            }
            catch [System.Net.WebException]
            {
                #Trust failure indicates self signed certificate or domain mismatch certificate present on endpoint
                if ($_.Exception.Status -eq [System.Net.WebExceptionStatus]::TrustFailure)
                {                        
                    $controlResult.AddMessage([VerificationResult]::Verify,"Validate if self signed certificate is not used for cluster management endpoint protection",$this.ResourceObject.Properties.managementEndpoint);
                    $controlResult.SetStateData("Management endpoint", $this.ResourceObject.Properties.managementEndpoint);
                }
                else
                {
                    throw
                }
            }
        }
        else
        {
            $controlResult.AddMessage([VerificationResult]::Failed,"Service Fabric cluster is not protected by SSL")
        }
        return $controlResult;    
    }

    hidden [ControlResult] CheckAADClientAuthentication([ControlResult] $controlResult)
    {
        $isAADEnabled = [Helpers]::CheckMember($this.ResourceObject.Properties,"azureActiveDirectory")
        
        #Presence of 'AzureActiveDirectory' indicates, AAD authentication is enabled for client authentication
        if($isAADEnabled)
        {            
            $controlResult.AddMessage([VerificationResult]::Passed,"AAD is enabled for client authentication",$this.ResourceObject.Properties.azureActiveDirectory )
        }
        else
        {            
            $controlResult.AddMessage([VerificationResult]::Failed,"AAD is not enabled for client authentication")
        }

        return $controlResult
    }

    hidden [ControlResult] CheckClusterProtectionLevel([ControlResult] $controlResult)
    {
        $fabricSecuritySettings = $this.ResourceObject.Properties.fabricSettings | where {$_.Name -eq "Security"}

        #Absence of security settings indicates, secure mode is not enabled on cluster.
        if($null -ne $fabricSecuritySettings)
        {
            $clusterProtectionLevel = $fabricSecuritySettings.parameters | Where-Object { $_.name -eq "ClusterProtectionLevel"}
            if($clusterProtectionLevel.value -eq "EncryptAndSign")
            {
              $controlResult.AddMessage([VerificationResult]::Passed,"Cluster security is ON with 'EncryptAndSign' protection level",$clusterProtectionLevel);
            }
            else 
            {
              $controlResult.AddMessage([VerificationResult]::Failed,"Cluster security is not set with 'EncryptAndSign' protection level. Current protection level is :", $clusterProtectionLevel);
                $controlResult.SetStateData("Cluster protection level", $clusterProtectionLevel);
            }
        }
        else
        {
          $controlResult.AddMessage([VerificationResult]::Failed,"Cluster security is OFF");
        }

        return $controlResult
    }

    hidden [ControlResult[]] CheckNSGConfigurations([ControlResult] $controlResult)
    {
        [ControlResult[]] $controlResultList = @()        

        $virtualNetworkResources = $this.GetLinkedResources("Microsoft.Network/virtualNetworks") 
        #Iterate through all cluster linked VNet resources
        $virtualNetworkResources |ForEach-Object{            
            $virtualNetwork=Get-AzureRmVirtualNetwork -ResourceGroupName $_.ResourceGroupName -Name $_.Name 
            $subnetConfig = Get-AzureRmVirtualNetworkSubnetConfig -VirtualNetwork $virtualNetwork
            #Iterate through Subnet and validate if NSG is configured or not
            $subnetConfig | ForEach-Object{
                $subnetName =$_.Name
                [ControlResult] $childControlResult = $this.CreateControlResult($subnetName);                    
                $isCompliant =  ($_.NetworkSecurityGroup -ne $null)        
                #If NSG is enabled on Subnet display all security rules applied
                if($isCompliant)
                {
                    $nsgResource = Get-AzureRmResource -ResourceId $_.NetworkSecurityGroup.Id
                    $nsgResourceDetails = Get-AzureRmNetworkSecurityGroup -ResourceGroupName $nsgResource.ResourceGroupName -Name $nsgResource.Name                
                    
                    $childControlResult.AddMessage([VerificationResult]::Verify, "Validate NSG security rules applied on subnet '$subnetName' ", $nsgResourceDetails)                    
                    $childControlResult.SetStateData("NSG security rules applied on subnet", $nsgResourceDetails);
                }
                #If NSG is not enabled on Subnet fail the TCP with Subnet details
                else
                {
                    $childControlResult.AddMessage([VerificationResult]::Failed, "NSG is not configured on subnet '$subnetName'",$_)        
                } 
                $controlResultList += $childControlResult 
            }                
        }

        return $controlResultList
    }

    hidden [ControlResult[]] CheckStorageEncryption([ControlResult] $controlResult)
    {
        [ControlResult[]] $controlResultList = @()
        $vmssResources = $this.GetLinkedResources("Microsoft.Compute/virtualMachineScaleSets")
        #Iterate through cluster linked vmss resources
        $vmssResources | ForEach-Object{
            $vmssResourceId = Get-AzureRmResource -ResourceId $_.ResourceId 
            #Get all storage account details where vmss disk is stored
            $vmssResourceId.Properties.virtualMachineProfile.storageProfile.osDisk.vhdContainers | ForEach-Object{
                $storageName = Convert-String -InputObject $_ -Example "https://accountname.blob.core.windows.net/vhds=accountname"
                $storageAccount = Get-AzureRmStorageAccount -Name $storageName -ResourceGroupName $this.ResourceContext.ResourceGroupName              
                [ControlResult] $childControlResult = $this.CreateControlResult($storageName);
                #Validate if storage account storing vmss os disk/Cluster data is encrypted or not
                if($null -ne $storageAccount.Encryption)
                {                     
                    $childControlResult.AddMessage([VerificationResult]::Passed, "Storage encryption is enabled for '$storageName'");
                }
                else
                {                        
                    $childControlResult.AddMessage([VerificationResult]::Failed, "Storage encryption is not enabled for '$storageName'");
                }                
               $controlResultList += $childControlResult
            }
        }
        return $controlResultList; 
    }

    hidden [ControlResult[]] CheckVmssDiagnostics([ControlResult] $controlResult)
    {
        [ControlResult[]] $controlResultList = @()
        $vmssResources = $this.GetLinkedResources("Microsoft.Compute/virtualMachineScaleSets")
        #Iterate through cluster linked vmss resources
        $vmssResources | ForEach-Object{
            $VMScaleSetName = $_.Name    
            [ControlResult] $childControlResult = $this.CreateControlResult($VMScaleSetName);          
            $nodeTypeResource = Get-AzureRmVmss -ResourceGroupName  $_.ResourceGroupName -VMScaleSetName  $VMScaleSetName
            $diagnosticsSettings = $nodeTypeResource.VirtualMachineProfile.ExtensionProfile.Extensions  | ? { $_.Type -eq "IaaSDiagnostics" -and $_.Publisher -eq "Microsoft.Azure.Diagnostics" }
            #Validate if diagnostics is enabled on vmss
            if($null -ne $diagnosticsSettings )
            {                
                $childControlResult.AddMessage([VerificationResult]::Passed, "Diagnostics is enabled on Vmss '$VMScaleSetName'",$diagnosticsSettings);
            }
            else
            {
                $childControlResult.AddMessage([VerificationResult]::Failed, "Diagnostics is disabled on Vmss '$VMScaleSetName'");
            } 
        
            $controlResultList += $childControlResult 
        }
        return $controlResultList        
    }

    hidden [ControlResult[]] CheckStatefulServiceReplicaSetSize([ControlResult] $controlResult)
    {
        [ControlResult[]] $controlResultList = @() 
        #Iterate through the applications present in cluster
        if($this.ApplicationList)
        {
            $this.ApplicationList | ForEach-Object{
                $serviceFabricApplication = $_

                Get-ServiceFabricService -ApplicationName $serviceFabricApplication.ApplicationName  | ForEach-Object{                
                    $serviceName = $_.ServiceName 
                    [ControlResult] $childControlResult = $this.CreateControlResult($serviceName);      
                    $serviceDescription = Get-ServiceFabricServiceDescription -ServiceName $_.ServiceName 
                    #Filter application with Stateful service type
                    if($serviceDescription.ServiceKind -eq "Stateful")
                    {
                        [ControlResult] $childControlResult = $this.CreateControlResult($serviceName)     
                        #Validate minimum replica and target replica size for each service
                        $isCompliant = !($serviceDescription.MinReplicaSetSize -lt 3 -or $serviceDescription.TargetReplicaSetSize -lt 3)

                        if($isCompliant){ $controlStatus = [VerificationResult]::Passed } else{ $controlStatus = [VerificationResult]::Failed }
                        $childControlResult.AddMessage([VerificationResult]::Failed, "Replica set size details for service '$serviceName'",$serviceDescription)
                        $controlResultList += $childControlResult 
                    }                
                }
            }
        }
        else
        {
            $controlResult.AddMessage([VerificationResult]::Passed,"No stateful service found.")
            $controlResultList += $controlResult
        }
        return $controlResultList
    }

    hidden [ControlResult[]] CheckStatelessServiceInstanceCount([ControlResult] $controlResult)
    {
        [ControlResult[]] $controlResultList = @()  
        #Iterate through the applications present in cluster
        if($this.ApplicationList)
        {
            $this.ApplicationList | ForEach-Object{
                $serviceFabricApplication = $_
                Get-ServiceFabricService -ApplicationName $serviceFabricApplication.ApplicationName | 
                ForEach-Object{
                    $serviceName = $_.ServiceName         
                    [ControlResult] $childControlResult = $this.CreateControlResult($serviceName);         
                    $serviceDescription = Get-ServiceFabricServiceDescription -ServiceName $serviceName 
                    #Filter application with Stateless service type
                    if($serviceDescription.ServiceKind -eq "Stateless")
                    {                    
                        $instantCount = $serviceDescription.InstanceCount
                        Add-OutputLogEvent -OutputLogFilePath $outputLogFilePath -EventData "Service Fabric service [$serviceName] has instance count : [$instantCount]"  
                        #Validate instancecount it -1 (auto) or greater than equal to 3
                        if($serviceDescription.InstanceCount -eq -1 -and $serviceDescription.InstanceCount -ge 3){$controlStatus = [VerificationResult]::Passed } else{ $controlStatus = [VerificationResult]::Failed }
                        $childControlResult.AddMessage([VerificationResult]::Failed, "Instance count for service '$serviceName'",$serviceDescription)
                        $controlResultList += $childControlResult 
                    } 
                } 
            }
        }
        else
        {
            $controlResult.AddMessage([VerificationResult]::Passed,"No stateless service found.")
            $controlResultList += $controlResult
        } 
        return $controlResultList        
    }

    hidden [ControlResult[]] CheckPublicEndpointSSL([ControlResult] $controlResult)
    {
        [ControlResult[]] $controlResultList = @() 
        $loadBalancerBackendPorts = @()
        $loadBalancerResources = $this.GetLinkedResources("Microsoft.Network/loadBalancers")
        #Collect all open ports on load balancer
        $loadBalancerResources | ForEach-Object{
            $loadBalancerResource = Get-AzureRmLoadBalancer -Name $_.ResourceName -ResourceGroupName $_.ResourceGroupName
            $loadBalancingRules = @($loadBalancerResource.FrontendIpConfigurations | ? { $_.PublicIpAddress -ne $null } | % { $_.LoadBalancingRules })
        
            $loadBalancingRules | % {
                $loadBalancingRuleId = $_.Id;
                $loadBalancingRule = $loadBalancerResource.LoadBalancingRules | ? { $_.Id -eq  $loadBalancingRuleId } | select -First 1
                $loadBalancerBackendPorts += $loadBalancingRule.BackendPort;
            };   
        }
        
        #If no ports open, Pass the TCP
        if($loadBalancerBackendPorts.Count -eq 0)
        {
            $controlResult.AddMessage([VerificationResult]::Passed,"No ports enabled.")  
            $controlResultList += $controlResult      
        }
        #If Ports are open for public in load balancer, map load balancer ports with application endpoint ports and validate if SSL is enabled.
        else
        {
            $controlResult.AddMessage("List of publicly exposed port",$loadBalancerBackendPorts)        
         
            if($this.ApplicationList)
            {
                $this.ApplicationList | 
                ForEach-Object{
                    $serviceFabricApplication = $_
                    Get-ServiceFabricServiceType -ApplicationTypeName $serviceFabricApplication.ApplicationTypeName -ApplicationTypeVersion $serviceFabricApplication.ApplicationTypeVersion | 
                    ForEach-Object{
                        $currentService = $_
                        $serviceManifest = [xml](Get-ServiceFabricServiceManifest -ApplicationTypeName $serviceFabricApplication.ApplicationTypeName -ApplicationTypeVersion $serviceFabricApplication.ApplicationTypeVersion -ServiceManifestName $_.ServiceManifestName)

                        $serviceManifest.ServiceManifest.Resources.Endpoints.ChildNodes | 
                        ForEach-Object{
                            $endpoint = $_
                            $serviceTypeName = $currentService.ServiceTypeName
                            [ControlResult] $childControlResult = $this.CreateControlResult($serviceTypeName +"_" + $endpoint.Name);  
                    
                            if($endpoint.Port -eq $null)
                            {
                                #Add message
                                $childControlResult.AddMessage([VerificationResult]::Passed) 
                            }
                            else
                            {
                                if($loadBalancerBackendPorts.Contains($endpoint.Port) )
                                {                      
                                    if($endpoint.Protocol -eq "https"){  $controlResult.AddMessage([VerificationResult]::Passed,"Endpoint is protected with SSL") }
                                    elseif($endpoint.Protocol -eq "http"){  $controlResult.AddMessage([VerificationResult]::Failed,"Endpoint is not protected with SSL") }
                                    else {  $controlResult.AddMessage([VerificationResult]::Verify,"Verify if endpoint is protected with SSL",$endpoint) }                            
                                }
                                else
                                {                        
                                    $controlResult.AddMessage([VerificationResult]::Passed,"Endpoint is not publicly opened")
                                }
                            }  
                            $controlResultList += $childControlResult 
                        }                   
                    }
                }             
            }
            else
            {
                $controlResult.AddMessage([VerificationResult]::Passed,"No service found.")
                $controlResultList += $controlResult
            }    
        } 
        return $controlResultList        
    }

    [void] CheckClusterAccess()
    {    
        #Function to validate authentication and connect with Service Fabric cluster
        $sfCluster = $null       
        $uri = ([System.Uri]$this.ResourceObject.Properties.managementEndpoint).Host                
        $primaryNodeType = $this.ResourceObject.Properties.nodeTypes | where { $_.isPrimary -eq $true }
                
        $ClusterConnectionUri = $uri +":"+ $primaryNodeType.clientConnectionEndpointPort
        $this.PublishCustomMessage("Connecting with Service Fabric cluster...")
        $this.PublishCustomMessage("Validating if Service Fabric is secure...")
        
        $isClusterSecure =  [Helpers]::CheckMember($this.ResourceObject.Properties,"certificate" )               
                
        if($isClusterSecure)
        {
            $serviceFabricCertificate = $this.ResourceObject.Properties.certificate              
            $this.PublishCustomMessage("Service Fabric is secure")
            $CertThumbprint= $this.ResourceObject.Properties.certificate.thumbprint
            $serviceFabricAAD =$this.ResourceObject.Properties.azureActiveDirectory
            if($serviceFabricAAD -ne $null)
            {
                try
                {
                    $this.PublishCustomMessage("Connecting Service Fabric using AAD...")
                    $sfCluster = Connect-ServiceFabricCluster -ConnectionEndpoint $ClusterConnectionUri -AzureActiveDirectory -ServerCertThumbprint $CertThumbprint #-SecurityToken "
                     $this.PublishCustomMessage("Connection using AAD is successful.")
                }
                catch
                {
                    throw "You may not have permission to connect with cluster"
                }
            }              
            else
            {
                $this.PublishCustomMessage("Validating if cluster certificate present on machine...")
                $IsCertPresent = (Get-ChildItem -Path Cert:\$this.CertStoreLocation\$this.CertStoreName | Where-Object {$_.Thumbprint -eq $CertThumbprint }).Count                    
                if($IsCertPresent)
                {
                    $this.PublishCustomMessage("Connecting Service Fabric using certificate")
                    $sfCluster = Connect-serviceFabricCluster -ConnectionEndpoint $ClusterConnectionUri -KeepAliveIntervalInSec 10 -X509Credential -ServerCertThumbprint $CertThumbprint -FindType FindByThumbprint -FindValue $CertThumbprint -StoreLocation $this.CertStoreLocation -StoreName $this.CertStoreName 
                }
                else
                {
                    throw "Can not connect with Service Fabric due to unavailability of cluster certificate in local machine. Validate cluster certificate is present in 'CurrentUser' location."
                }
            }                    
        }
        else
        {
            "Service Fabric is unsecure"
            $sfCluster = Connect-serviceFabricCluster -ConnectionEndpoint $ClusterConnectionUri
            "Service Fabric connection is successful"
        }
    }

    [PSObject] GetLinkedResources([string] $resourceType)
    {
        return  Find-AzureRmResource -TagName $this.DefaultTagName -TagValue $this.ClusterTagValue | Where-Object { ($_.ResourceType -EQ $resourceType) -and ($_.ResourceGroupName -eq $this.ResourceContext.ResourceGroupName) }
    }    
}
# SIG # Begin signature block
# MIIkAQYJKoZIhvcNAQcCoIIj8jCCI+4CAQExDzANBglghkgBZQMEAgEFADB5Bgor
# BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG
# KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCAO3RiBy6W1b3oC
# +FRFjDLDd+Z5wAf7Oqg3GOnV8yY8WKCCDZMwggYRMIID+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
# xDCCFcACAQEwgZUwfjELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24x
# EDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlv
# bjEoMCYGA1UEAxMfTWljcm9zb2Z0IENvZGUgU2lnbmluZyBQQ0EgMjAxMQITMwAA
# AI6HkaRXGl/KPgAAAAAAjjANBglghkgBZQMEAgEFAKCBsDAZBgkqhkiG9w0BCQMx
# DAYKKwYBBAGCNwIBBDAcBgorBgEEAYI3AgELMQ4wDAYKKwYBBAGCNwIBFTAvBgkq
# hkiG9w0BCQQxIgQg/VMUM7HH7M3/XUxGeBGj45Dhcdp3I1aK/xzb1ImH9XcwRAYK
# KwYBBAGCNwIBDDE2MDSgEoAQAEEAegBTAEQASwAyADUAMqEegBxodHRwczovL2Fr
# YS5tcy9henNka29zc2RvY3MgMA0GCSqGSIb3DQEBAQUABIIBAHqVmrCPCGDi8FPU
# 2HHarbYTeoW7RNAmIz1g7mH4Om1vgZkD+wKz1Lxqj4mfwt+VuX92VYh3+Zgnd0/1
# EHvjyh2shQ6bua1MtA6cW3TPt+nSjyVuRmeZNkSg95kT9KKd2i6KD/e7MMSvIHZW
# qAKD0UiFbGHtcD0CDCRYmoy3X6PGY8+haCRnh6RQnrxj700gvHxPyH//h/DgUubG
# /LW6iPG00ihXzyZoMbHDNnBFBMqPlfMpBlUMw3yJ1oGss3GPw/gKB1Z8L4miHcVQ
# midKLpRPnM4Z4l//8ZNPtSJcJBkC8hcaZ/4z+sA9nTUw03tGf7+vn3gK+Mtu+jaS
# NCapTtuhghNMMIITSAYKKwYBBAGCNwMDATGCEzgwghM0BgkqhkiG9w0BBwKgghMl
# MIITIQIBAzEPMA0GCWCGSAFlAwQCAQUAMIIBPQYLKoZIhvcNAQkQAQSgggEsBIIB
# KDCCASQCAQEGCisGAQQBhFkKAwEwMTANBglghkgBZQMEAgEFAAQgxDoY7BkZ/g53
# CGnUZz+pJfWA+Efui7bHVve9KAEQLC4CBlmSFyJyhxgTMjAxNzA5MDUwOTM3MTUu
# NzIzWjAHAgEBgAIB9KCBuaSBtjCBszELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldh
# c2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBD
# b3Jwb3JhdGlvbjENMAsGA1UECxMETU9QUjEnMCUGA1UECxMebkNpcGhlciBEU0Ug
# RVNOOkIxQjctRjY3Ri1GRUMyMSUwIwYDVQQDExxNaWNyb3NvZnQgVGltZS1TdGFt
# cCBTZXJ2aWNloIIOzzCCBnEwggRZoAMCAQICCmEJgSoAAAAAAAIwDQYJKoZIhvcN
# 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
# EzMAAACxcRN533X2NcgAAAAAALEwDQYJKoZIhvcNAQELBQAwfDELMAkGA1UEBhMC
# VVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNV
# BAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEmMCQGA1UEAxMdTWljcm9zb2Z0IFRp
# bWUtU3RhbXAgUENBIDIwMTAwHhcNMTYwOTA3MTc1NjU3WhcNMTgwOTA3MTc1NjU3
# WjCBszELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcT
# B1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjENMAsGA1UE
# CxMETU9QUjEnMCUGA1UECxMebkNpcGhlciBEU0UgRVNOOkIxQjctRjY3Ri1GRUMy
# MSUwIwYDVQQDExxNaWNyb3NvZnQgVGltZS1TdGFtcCBTZXJ2aWNlMIIBIjANBgkq
# hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqqQklG1Y1lu8ob0P7deumuRn4JvRi2GE
# rmK94vgbnWPmd0j/9arA7539HD1dpG1uhYbmnAxc+qsuvMM0fpEvttTK4lZSU7ss
# 5rJfWmbFn/J8kSGI8K9iBaB6hQkJuIX4si9ppNr9R3oZI3HbJ/yRkKUPk4hozpY6
# CkehRc0/Zfu6tQiyqI7mClXYZTXjw+rLsh3/gdBvYDd38zFBllaf+3uimKQgUTXG
# jbKfqZZk3tEU3ibWVPUxAmmxlG3sWTlXmU31fCw/6TVzGg251lq+Q46OjbeH9vB2
# TOcqEso4Nai3J1CdMAYUdlelVVtgQdIx/c+5Hvrw0Y6W7uGBAWnW5wIDAQABo4IB
# GzCCARcwHQYDVR0OBBYEFE5XPfeLLhRLV7L8Il7Tz7cnRBA7MB8GA1UdIwQYMBaA
# FNVjOlyKMZDzQ3t8RhvFM2hahW1VMFYGA1UdHwRPME0wS6BJoEeGRWh0dHA6Ly9j
# cmwubWljcm9zb2Z0LmNvbS9wa2kvY3JsL3Byb2R1Y3RzL01pY1RpbVN0YVBDQV8y
# MDEwLTA3LTAxLmNybDBaBggrBgEFBQcBAQROMEwwSgYIKwYBBQUHMAKGPmh0dHA6
# Ly93d3cubWljcm9zb2Z0LmNvbS9wa2kvY2VydHMvTWljVGltU3RhUENBXzIwMTAt
# MDctMDEuY3J0MAwGA1UdEwEB/wQCMAAwEwYDVR0lBAwwCgYIKwYBBQUHAwgwDQYJ
# KoZIhvcNAQELBQADggEBAHPujfu0W8PBTpjfYaPrAKIBLKcljT4+YnWbbgGvmXU8
# OvIUDBkkv8gNGGHRO5DSySaCARIzgn2yIheAqh6GwM2yKrfb4eVCYPe1CTlCseS5
# TOv+Tn/95mXj+NxTqvuNmrhgCVr0CQ7b3xoKcwDcQbg7TmerDgbIv2k7cEqbYbU/
# B3MtSX8Zjjf0ZngdKoX0JYkAEDbZchOrRiUtDJItegPKZPf6CjeHYjrmKwvTOVCz
# v3lW0uyh1yb/ODeRH+VqENSHCboFiEiq9KpKMOpek1VvQhmI2KbTlRvK869gj1Nw
# uUHH8c3WXu4A0X1+CBmU8t0gvd/fFlQvw04veKWh986hggN4MIICYAIBATCB46GB
# uaSBtjCBszELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNV
# BAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjENMAsG
# A1UECxMETU9QUjEnMCUGA1UECxMebkNpcGhlciBEU0UgRVNOOkIxQjctRjY3Ri1G
# RUMyMSUwIwYDVQQDExxNaWNyb3NvZnQgVGltZS1TdGFtcCBTZXJ2aWNloiUKAQEw
# CQYFKw4DAhoFAAMVADq635MoZeR60+ej9uKnRG5YqlPSoIHCMIG/pIG8MIG5MQsw
# CQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9u
# ZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMQ0wCwYDVQQLEwRNT1BS
# MScwJQYDVQQLEx5uQ2lwaGVyIE5UUyBFU046NERFOS0wQzVFLTNFMDkxKzApBgNV
# BAMTIk1pY3Jvc29mdCBUaW1lIFNvdXJjZSBNYXN0ZXIgQ2xvY2swDQYJKoZIhvcN
# AQEFBQACBQDdWK0XMCIYDzIwMTcwOTA1MDQ1NjU1WhgPMjAxNzA5MDYwNDU2NTVa
# MHYwPAYKKwYBBAGEWQoEATEuMCwwCgIFAN1YrRcCAQAwCQIBAAIBIAIB/zAHAgEA
# AgIY4zAKAgUA3Vn+lwIBADA2BgorBgEEAYRZCgQCMSgwJjAMBgorBgEEAYRZCgMB
# oAowCAIBAAIDFuNgoQowCAIBAAIDB6EgMA0GCSqGSIb3DQEBBQUAA4IBAQA+ZEd4
# ooPHiKXaGoIJl7xct64OrgoneiQ1Q/WdfJxEl3cjN5B2vRUuQX+6hq5knZBRNSvQ
# hFHIumBL52FqmEl0yu4JrEcavJhNtK+rZYIdiYW/IJN+eYjR7Ca7UiPnqC0AovLC
# q7CH9Pa2LZrFMTw3OEfjCa5O4ZZ2eVaBP0Ts30GgU+BVK7RQ1OnnV3rRL3vwFs9m
# 4RHh92aifGO3xwvmONclucmsupzvizd0YzkG5kFkIj38HaPpRKiR+/z1e1s/qQ5W
# 90R5AVKCgBS/r47n+pjTrHtHKX65tYUnd1FCED51VBM/yI372NQ/ts1ncTv5dpIN
# p/KxiiIUcI+/YNj1MYIC9TCCAvECAQEwgZMwfDELMAkGA1UEBhMCVVMxEzARBgNV
# BAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jv
# c29mdCBDb3Jwb3JhdGlvbjEmMCQGA1UEAxMdTWljcm9zb2Z0IFRpbWUtU3RhbXAg
# UENBIDIwMTACEzMAAACxcRN533X2NcgAAAAAALEwDQYJYIZIAWUDBAIBBQCgggEy
# MBoGCSqGSIb3DQEJAzENBgsqhkiG9w0BCRABBDAvBgkqhkiG9w0BCQQxIgQgb1zh
# cn3HS9yduKkOxtXg+sIcm8oEJTh74vmCkFZNuIowgeIGCyqGSIb3DQEJEAIMMYHS
# MIHPMIHMMIGxBBQ6ut+TKGXketPno/bip0RuWKpT0jCBmDCBgKR+MHwxCzAJBgNV
# BAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4w
# HAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xJjAkBgNVBAMTHU1pY3Jvc29m
# dCBUaW1lLVN0YW1wIFBDQSAyMDEwAhMzAAAAsXETed919jXIAAAAAACxMBYEFF50
# WhcZSLtM19KqNcuqdWzh7UwDMA0GCSqGSIb3DQEBCwUABIIBAAbnInFeVXEH50YW
# AfbshM7CjeurDtuUZe6hGS5lPYrpafHCbtByB4gWfeUGdL/6XThOEeeZgqi4jU9H
# NLv8cRoSDt/xkyM0zgBnRrVPh+s06uUw4yY0kp47NbC+HX1dCcEdDV7ysCVyzIq/
# QkEEO1/PeSejL4aetHmcvxBhlS2125M3BHw6g2RisrTqXdIafNjjrRexBDfgz6g5
# KnTtJoa1NcSdKhvmm+OT50BaixVp8X3Fk1uzEsAGnM2d+oztLBos0Jm1Bte+ouSx
# SZUeTeiGKIPn+SLJ6jXZ5mXAYDV4ezqjPbffOIMablmhjUde7FHKtTkM5MfJDGWa
# 4htHgYw=
# SIG # End signature block