helpers/test/Setup-AWSTestResources.ps1

<#
.SYNOPSIS
    Creates minimal AWS test resources for WUG AWS discovery E2E testing.
 
.DESCRIPTION
    Creates one EC2 instance (t3.micro), one RDS instance (db.t3.micro MySQL),
    and one Application Load Balancer in the specified region.
 
    Uses the project's Invoke-AWSREST function (no AWS CLI required).
    Requires AWS credentials with EC2, RDS, ELBv2 write permissions.
    The default vault user (whatsupgold-test) is read-only; provide
    -Credential for a user with write access.
 
    Safe to re-run: handles duplicate resource errors gracefully.
 
.PARAMETER Region
    AWS region. Default: us-east-1
 
.PARAMETER Credential
    PSCredential where UserName = Access Key ID, Password = Secret Access Key.
    If omitted, uses the DPAPI-encrypted vault credential (AWS.Credential).
 
.EXAMPLE
    $cred = Get-Credential -Message 'AWS Access Key (user) + Secret Key (password)'
    .\Setup-AWSTestResources.ps1 -Credential $cred
 
.EXAMPLE
    .\Setup-AWSTestResources.ps1 -Region us-west-2
 
.NOTES
    Resources created (all tagged wug-test=true):
      EC2: wug-test-ec2 (t3.micro, Amazon Linux 2023)
      RDS: wug-test-rds (db.t3.micro, MySQL 8)
      ALB: wug-test-alb (Application LB, HTTP:80)
      SG: wug-test-sg (ICMP + TCP 80 + TCP 3306)
      TG: wug-test-tg (HTTP target group -> EC2)
 
    Estimated cost: ~$0.05/hr total. Tear down after testing.
#>

[CmdletBinding()]
param(
    [string]$Region = 'us-east-1',
    [PSCredential]$Credential
)

$ErrorActionPreference = 'Stop'
$scriptDir = Split-Path $MyInvocation.MyCommand.Path -Parent

# Dot-source dependencies
$awsHelpersPath = Join-Path (Split-Path $scriptDir -Parent) 'aws\AWSHelpers.ps1'
. $awsHelpersPath
$discoveryHelpersPath = Join-Path (Split-Path $scriptDir -Parent) 'discovery\DiscoveryHelpers.ps1'
. $discoveryHelpersPath

# Resolve credentials from PSCredential or vault
if (-not $Credential) {
    try {
        $raw = Get-DiscoveryCredential -Name 'AWS.Credential'
        $parts = $raw -split '\|', 2
        $secSK = ConvertTo-SecureString $parts[1] -AsPlainText -Force
        $Credential = New-Object PSCredential($parts[0], $secSK)
        Write-Host "Using vault credential (AccessKey: $($Credential.UserName))" -ForegroundColor Cyan
    }
    catch {
        throw "No -Credential provided and vault credential not found: $_"
    }
}

$bstrSK = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($Credential.Password)
try { $plainSK = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($bstrSK) }
finally { [System.Runtime.InteropServices.Marshal]::ZeroFreeBSTR($bstrSK) }

Connect-AWSProfileREST -AccessKey $Credential.UserName -SecretKey $plainSK -Region $Region
$plainSK = $null

$ec2Ver = '2016-11-15'
$rdsVer = '2014-10-31'
$elbVer = '2015-12-01'

Write-Host ""
Write-Host "=== WUG AWS Test Resource Setup ===" -ForegroundColor Cyan
Write-Host "Region: $Region" -ForegroundColor White
Write-Host ""

# ---------------------------------------------------------------
# 1. Find default VPC
# ---------------------------------------------------------------
Write-Host "Finding default VPC..." -ForegroundColor Yellow
$vpcResp = Invoke-AWSREST -Service ec2 -Action DescribeVpcs -Version $ec2Ver -Region $Region -Parameters @{
    'Filter.1.Name' = 'is-default'; 'Filter.1.Value.1' = 'true'
}
$vpcs = @($vpcResp.DescribeVpcsResponse.vpcSet.item)
if ($vpcs.Count -eq 0) { throw "No default VPC in $Region. Create one first." }
$vpcId = $vpcs[0].vpcId
$vpcCidr = $vpcs[0].cidrBlock
Write-Host " VPC: $vpcId ($vpcCidr)" -ForegroundColor Green

# ---------------------------------------------------------------
# 2. Get subnets (need 2 AZs for ALB)
# ---------------------------------------------------------------
Write-Host "Finding subnets..." -ForegroundColor Yellow
$subResp = Invoke-AWSREST -Service ec2 -Action DescribeSubnets -Version $ec2Ver -Region $Region -Parameters @{
    'Filter.1.Name' = 'vpc-id'; 'Filter.1.Value.1' = $vpcId
}
$allSubnets = @($subResp.DescribeSubnetsResponse.subnetSet.item)
$azGroups = $allSubnets | Group-Object availabilityZone | Select-Object -First 2
if ($azGroups.Count -lt 2) { throw "Need 2+ AZs for ALB, found $($azGroups.Count)." }
$subnet1 = $azGroups[0].Group[0].subnetId
$subnet2 = $azGroups[1].Group[0].subnetId
Write-Host " Subnet 1: $subnet1 ($($azGroups[0].Name))" -ForegroundColor Green
Write-Host " Subnet 2: $subnet2 ($($azGroups[1].Name))" -ForegroundColor Green

# ---------------------------------------------------------------
# 3. Create security group
# ---------------------------------------------------------------
Write-Host "Creating security group 'wug-test-sg'..." -ForegroundColor Yellow
$sgId = $null
try {
    $sgResp = Invoke-AWSREST -Service ec2 -Action CreateSecurityGroup -Version $ec2Ver -Region $Region -Method POST -Parameters @{
        GroupName        = 'wug-test-sg'
        GroupDescription = 'WUG discovery test resources'
        VpcId            = $vpcId
    }
    $sgId = $sgResp.CreateSecurityGroupResponse.groupId
    Write-Host " Created SG: $sgId" -ForegroundColor Green
}
catch {
    if ("$_" -match 'InvalidGroup\.Duplicate') {
        $existSg = Invoke-AWSREST -Service ec2 -Action DescribeSecurityGroups -Version $ec2Ver -Region $Region -Parameters @{
            'Filter.1.Name' = 'group-name'; 'Filter.1.Value.1' = 'wug-test-sg'
            'Filter.2.Name' = 'vpc-id'; 'Filter.2.Value.1' = $vpcId
        }
        $sgId = $existSg.DescribeSecurityGroupsResponse.securityGroupInfo.item.groupId
        Write-Host " SG already exists: $sgId" -ForegroundColor Yellow
    }
    else { throw }
}

# Add ingress rules (ICMP for ping, HTTP for ALB, MySQL for RDS - VPC only)
foreach ($rule in @(
    @{ Protocol = 'icmp'; From = '-1'; To = '-1'; Cidr = '0.0.0.0/0' },
    @{ Protocol = 'tcp';  From = '80'; To = '80'; Cidr = '0.0.0.0/0' },
    @{ Protocol = 'tcp';  From = '3306'; To = '3306'; Cidr = $vpcCidr }
)) {
    try {
        Invoke-AWSREST -Service ec2 -Action AuthorizeSecurityGroupIngress -Version $ec2Ver -Region $Region -Method POST -Parameters @{
            GroupId                            = $sgId
            'IpPermissions.1.IpProtocol'       = $rule.Protocol
            'IpPermissions.1.FromPort'         = $rule.From
            'IpPermissions.1.ToPort'           = $rule.To
            'IpPermissions.1.IpRanges.1.CidrIp' = $rule.Cidr
        } | Out-Null
    }
    catch {
        if ("$_" -match 'InvalidPermission\.Duplicate') { continue }
        Write-Warning "Ingress rule ($($rule.Protocol):$($rule.From)): $_"
    }
}

# ---------------------------------------------------------------
# 4. Find latest Amazon Linux 2023 AMI
# ---------------------------------------------------------------
Write-Host "Looking up latest Amazon Linux 2023 AMI..." -ForegroundColor Yellow
$amiResp = Invoke-AWSREST -Service ec2 -Action DescribeImages -Version $ec2Ver -Region $Region -Parameters @{
    'Owner.1'          = 'amazon'
    'Filter.1.Name'    = 'name';         'Filter.1.Value.1' = 'al2023-ami-2023*-kernel-6.1-x86_64'
    'Filter.2.Name'    = 'state';        'Filter.2.Value.1' = 'available'
    'Filter.3.Name'    = 'architecture'; 'Filter.3.Value.1' = 'x86_64'
}
$images = @($amiResp.DescribeImagesResponse.imagesSet.item)
if ($images.Count -eq 0) { throw "No Amazon Linux 2023 AMI found in $Region." }
$latest = $images | Sort-Object -Property creationDate -Descending | Select-Object -First 1
$amiId = $latest.imageId
Write-Host " AMI: $amiId ($($latest.name))" -ForegroundColor Green

# ---------------------------------------------------------------
# 5. Launch EC2 instance
# ---------------------------------------------------------------
Write-Host "Launching EC2 instance (t3.micro)..." -ForegroundColor Yellow
$ec2Id = $null
try {
    $ec2Resp = Invoke-AWSREST -Service ec2 -Action RunInstances -Version $ec2Ver -Region $Region -Method POST -Parameters @{
        ImageId                              = $amiId
        InstanceType                         = 't3.micro'
        MinCount                             = '1'
        MaxCount                             = '1'
        'SecurityGroupId.1'                  = $sgId
        SubnetId                             = $subnet1
        'TagSpecification.1.ResourceType'    = 'instance'
        'TagSpecification.1.Tag.1.Key'       = 'Name'
        'TagSpecification.1.Tag.1.Value'     = 'wug-test-ec2'
        'TagSpecification.1.Tag.2.Key'       = 'wug-test'
        'TagSpecification.1.Tag.2.Value'     = 'true'
    }
    $ec2Id = $ec2Resp.RunInstancesResponse.instancesSet.item.instanceId
    Write-Host " EC2: $ec2Id" -ForegroundColor Green
}
catch {
    Write-Warning "EC2 launch failed: $_"
    # Check if one already exists
    $existEc2 = Invoke-AWSREST -Service ec2 -Action DescribeInstances -Version $ec2Ver -Region $Region -Parameters @{
        'Filter.1.Name' = 'tag:Name'; 'Filter.1.Value.1' = 'wug-test-ec2'
        'Filter.2.Name' = 'instance-state-name'; 'Filter.2.Value.1' = 'running'
    }
    $existInst = $existEc2.DescribeInstancesResponse.reservationSet.item.instancesSet.item
    if ($existInst) {
        $ec2Id = $existInst.instanceId
        Write-Host " EC2 already exists: $ec2Id" -ForegroundColor Yellow
    }
}

# ---------------------------------------------------------------
# 6. Create RDS instance
# ---------------------------------------------------------------
Write-Host "Creating RDS instance (db.t3.micro, MySQL)..." -ForegroundColor Yellow
Write-Host " This takes 5-10 minutes to become available." -ForegroundColor DarkGray
try {
    Invoke-AWSREST -Service rds -Action CreateDBInstance -Version $rdsVer -Region $Region -Method POST -Parameters @{
        DBInstanceIdentifier          = 'wug-test-rds'
        DBInstanceClass               = 'db.t3.micro'
        Engine                        = 'mysql'
        MasterUsername                 = 'admin'
        MasterUserPassword            = ('wugT' + [guid]::NewGuid().ToString('N').Substring(0,16))
        AllocatedStorage              = '20'
        'VpcSecurityGroupIds.member.1' = $sgId
        MultiAZ                       = 'false'
        'Tags.member.1.Key'           = 'wug-test'
        'Tags.member.1.Value'         = 'true'
    } | Out-Null
    Write-Host " RDS: wug-test-rds (creating...)" -ForegroundColor Green
}
catch {
    if ("$_" -match 'DBInstanceAlreadyExists') {
        Write-Host " RDS: wug-test-rds (already exists)" -ForegroundColor Yellow
    }
    else { throw }
}

# ---------------------------------------------------------------
# 7. Create Application Load Balancer
# ---------------------------------------------------------------
Write-Host "Creating ALB..." -ForegroundColor Yellow
$albArn = $null
$albDns = $null
try {
    $albResp = Invoke-AWSREST -Service elasticloadbalancing -Action CreateLoadBalancer -Version $elbVer -Region $Region -Method POST -Parameters @{
        Name                       = 'wug-test-alb'
        'Subnets.member.1'         = $subnet1
        'Subnets.member.2'         = $subnet2
        'SecurityGroups.member.1'  = $sgId
        Type                       = 'application'
        'Tags.member.1.Key'        = 'wug-test'
        'Tags.member.1.Value'      = 'true'
    }
    $albArn = $albResp.CreateLoadBalancerResponse.CreateLoadBalancerResult.LoadBalancers.member.LoadBalancerArn
    $albDns = $albResp.CreateLoadBalancerResponse.CreateLoadBalancerResult.LoadBalancers.member.DNSName
    Write-Host " ALB: $albDns" -ForegroundColor Green
}
catch {
    if ("$_" -match 'DuplicateLoadBalancerName') {
        $existAlb = Invoke-AWSREST -Service elasticloadbalancing -Action DescribeLoadBalancers -Version $elbVer -Region $Region -Parameters @{
            'Names.member.1' = 'wug-test-alb'
        }
        $albArn = $existAlb.DescribeLoadBalancersResponse.DescribeLoadBalancersResult.LoadBalancers.member.LoadBalancerArn
        $albDns = $existAlb.DescribeLoadBalancersResponse.DescribeLoadBalancersResult.LoadBalancers.member.DNSName
        Write-Host " ALB already exists: $albDns" -ForegroundColor Yellow
    }
    else { throw }
}

# ---------------------------------------------------------------
# 8. Create target group + listener
# ---------------------------------------------------------------
Write-Host "Creating target group + listener..." -ForegroundColor Yellow
$tgArn = $null
try {
    $tgResp = Invoke-AWSREST -Service elasticloadbalancing -Action CreateTargetGroup -Version $elbVer -Region $Region -Method POST -Parameters @{
        Name                    = 'wug-test-tg'
        Protocol                = 'HTTP'
        Port                    = '80'
        VpcId                   = $vpcId
        TargetType              = 'instance'
        'Tags.member.1.Key'     = 'wug-test'
        'Tags.member.1.Value'   = 'true'
    }
    $tgArn = $tgResp.CreateTargetGroupResponse.CreateTargetGroupResult.TargetGroups.member.TargetGroupArn
}
catch {
    if ("$_" -match 'DuplicateTargetGroupName') {
        $existTg = Invoke-AWSREST -Service elasticloadbalancing -Action DescribeTargetGroups -Version $elbVer -Region $Region -Parameters @{
            'Names.member.1' = 'wug-test-tg'
        }
        $tgArn = $existTg.DescribeTargetGroupsResponse.DescribeTargetGroupsResult.TargetGroups.member.TargetGroupArn
        Write-Host " Target group already exists" -ForegroundColor Yellow
    }
    else { throw }
}

# Register EC2 in target group
if ($ec2Id -and $tgArn) {
    try {
        Invoke-AWSREST -Service elasticloadbalancing -Action RegisterTargets -Version $elbVer -Region $Region -Method POST -Parameters @{
            TargetGroupArn      = $tgArn
            'Targets.member.1.Id' = $ec2Id
        } | Out-Null
    }
    catch { Write-Verbose "Register target: $_" }
}

# Create listener
if ($albArn -and $tgArn) {
    try {
        Invoke-AWSREST -Service elasticloadbalancing -Action CreateListener -Version $elbVer -Region $Region -Method POST -Parameters @{
            LoadBalancerArn                          = $albArn
            Protocol                                 = 'HTTP'
            Port                                     = '80'
            'DefaultActions.member.1.Type'            = 'forward'
            'DefaultActions.member.1.TargetGroupArn'  = $tgArn
        } | Out-Null
        Write-Host " Target group + listener created" -ForegroundColor Green
    }
    catch {
        if ("$_" -match 'DuplicateListener') {
            Write-Host " Listener already exists" -ForegroundColor Yellow
        }
        else { Write-Warning "Listener: $_" }
    }
}

# ---------------------------------------------------------------
# Summary
# ---------------------------------------------------------------
Write-Host ""
Write-Host "=== Test Resources Created ===" -ForegroundColor Cyan
Write-Host " EC2 Instance: $ec2Id" -ForegroundColor White
Write-Host " RDS Instance: wug-test-rds (allow 5-10 min)" -ForegroundColor White
Write-Host " ALB: wug-test-alb ($albDns)" -ForegroundColor White
Write-Host " Security Group: $sgId" -ForegroundColor White
Write-Host " Region: $Region" -ForegroundColor White
Write-Host ""
Write-Host " After RDS is available, run the discovery:" -ForegroundColor Yellow
Write-Host " .\helpers\discovery\Setup-AWS-Discovery.ps1 -Region $Region" -ForegroundColor White
Write-Host ""
Write-Host " To tear down when done:" -ForegroundColor Yellow
Write-Host " .\helpers\test\Teardown-AWSTestResources.ps1 -Region $Region" -ForegroundColor White
Write-Host " (RDS password was randomly generated - not needed for teardown)" -ForegroundColor DarkGray

# SIG # Begin signature block
# MIIr+wYJKoZIhvcNAQcCoIIr7DCCK+gCAQExDzANBglghkgBZQMEAgEFADB5Bgor
# BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG
# KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCDUPxDGA31qUqV7
# YvUArOMF1DVMZtz+DkWAIjIvLRvB2KCCJQ0wggVvMIIEV6ADAgECAhBI/JO0YFWU
# jTanyYqJ1pQWMA0GCSqGSIb3DQEBDAUAMHsxCzAJBgNVBAYTAkdCMRswGQYDVQQI
# DBJHcmVhdGVyIE1hbmNoZXN0ZXIxEDAOBgNVBAcMB1NhbGZvcmQxGjAYBgNVBAoM
# EUNvbW9kbyBDQSBMaW1pdGVkMSEwHwYDVQQDDBhBQUEgQ2VydGlmaWNhdGUgU2Vy
# dmljZXMwHhcNMjEwNTI1MDAwMDAwWhcNMjgxMjMxMjM1OTU5WjBWMQswCQYDVQQG
# EwJHQjEYMBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMS0wKwYDVQQDEyRTZWN0aWdv
# IFB1YmxpYyBDb2RlIFNpZ25pbmcgUm9vdCBSNDYwggIiMA0GCSqGSIb3DQEBAQUA
# A4ICDwAwggIKAoICAQCN55QSIgQkdC7/FiMCkoq2rjaFrEfUI5ErPtx94jGgUW+s
# hJHjUoq14pbe0IdjJImK/+8Skzt9u7aKvb0Ffyeba2XTpQxpsbxJOZrxbW6q5KCD
# J9qaDStQ6Utbs7hkNqR+Sj2pcaths3OzPAsM79szV+W+NDfjlxtd/R8SPYIDdub7
# P2bSlDFp+m2zNKzBenjcklDyZMeqLQSrw2rq4C+np9xu1+j/2iGrQL+57g2extme
# me/G3h+pDHazJyCh1rr9gOcB0u/rgimVcI3/uxXP/tEPNqIuTzKQdEZrRzUTdwUz
# T2MuuC3hv2WnBGsY2HH6zAjybYmZELGt2z4s5KoYsMYHAXVn3m3pY2MeNn9pib6q
# RT5uWl+PoVvLnTCGMOgDs0DGDQ84zWeoU4j6uDBl+m/H5x2xg3RpPqzEaDux5mcz
# mrYI4IAFSEDu9oJkRqj1c7AGlfJsZZ+/VVscnFcax3hGfHCqlBuCF6yH6bbJDoEc
# QNYWFyn8XJwYK+pF9e+91WdPKF4F7pBMeufG9ND8+s0+MkYTIDaKBOq3qgdGnA2T
# OglmmVhcKaO5DKYwODzQRjY1fJy67sPV+Qp2+n4FG0DKkjXp1XrRtX8ArqmQqsV/
# AZwQsRb8zG4Y3G9i/qZQp7h7uJ0VP/4gDHXIIloTlRmQAOka1cKG8eOO7F/05QID
# AQABo4IBEjCCAQ4wHwYDVR0jBBgwFoAUoBEKIz6W8Qfs4q8p74Klf9AwpLQwHQYD
# VR0OBBYEFDLrkpr/NZZILyhAQnAgNpFcF4XmMA4GA1UdDwEB/wQEAwIBhjAPBgNV
# HRMBAf8EBTADAQH/MBMGA1UdJQQMMAoGCCsGAQUFBwMDMBsGA1UdIAQUMBIwBgYE
# VR0gADAIBgZngQwBBAEwQwYDVR0fBDwwOjA4oDagNIYyaHR0cDovL2NybC5jb21v
# ZG9jYS5jb20vQUFBQ2VydGlmaWNhdGVTZXJ2aWNlcy5jcmwwNAYIKwYBBQUHAQEE
# KDAmMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5jb21vZG9jYS5jb20wDQYJKoZI
# hvcNAQEMBQADggEBABK/oe+LdJqYRLhpRrWrJAoMpIpnuDqBv0WKfVIHqI0fTiGF
# OaNrXi0ghr8QuK55O1PNtPvYRL4G2VxjZ9RAFodEhnIq1jIV9RKDwvnhXRFAZ/ZC
# J3LFI+ICOBpMIOLbAffNRk8monxmwFE2tokCVMf8WPtsAO7+mKYulaEMUykfb9gZ
# pk+e96wJ6l2CxouvgKe9gUhShDHaMuwV5KZMPWw5c9QLhTkg4IUaaOGnSDip0TYl
# d8GNGRbFiExmfS9jzpjoad+sPKhdnckcW67Y8y90z7h+9teDnRGWYpquRRPaf9xH
# +9/DUp/mBlXpnYzyOmJRvOwkDynUWICE5EV7WtgwggWNMIIEdaADAgECAhAOmxiO
# +dAt5+/bUOIIQBhaMA0GCSqGSIb3DQEBDAUAMGUxCzAJBgNVBAYTAlVTMRUwEwYD
# VQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xJDAi
# BgNVBAMTG0RpZ2lDZXJ0IEFzc3VyZWQgSUQgUm9vdCBDQTAeFw0yMjA4MDEwMDAw
# MDBaFw0zMTExMDkyMzU5NTlaMGIxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdp
# Q2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xITAfBgNVBAMTGERp
# Z2lDZXJ0IFRydXN0ZWQgUm9vdCBHNDCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCC
# AgoCggIBAL/mkHNo3rvkXUo8MCIwaTPswqclLskhPfKK2FnC4SmnPVirdprNrnsb
# hA3EMB/zG6Q4FutWxpdtHauyefLKEdLkX9YFPFIPUh/GnhWlfr6fqVcWWVVyr2iT
# cMKyunWZanMylNEQRBAu34LzB4TmdDttceItDBvuINXJIB1jKS3O7F5OyJP4IWGb
# NOsFxl7sWxq868nPzaw0QF+xembud8hIqGZXV59UWI4MK7dPpzDZVu7Ke13jrclP
# XuU15zHL2pNe3I6PgNq2kZhAkHnDeMe2scS1ahg4AxCN2NQ3pC4FfYj1gj4QkXCr
# VYJBMtfbBHMqbpEBfCFM1LyuGwN1XXhm2ToxRJozQL8I11pJpMLmqaBn3aQnvKFP
# ObURWBf3JFxGj2T3wWmIdph2PVldQnaHiZdpekjw4KISG2aadMreSx7nDmOu5tTv
# kpI6nj3cAORFJYm2mkQZK37AlLTSYW3rM9nF30sEAMx9HJXDj/chsrIRt7t/8tWM
# cCxBYKqxYxhElRp2Yn72gLD76GSmM9GJB+G9t+ZDpBi4pncB4Q+UDCEdslQpJYls
# 5Q5SUUd0viastkF13nqsX40/ybzTQRESW+UQUOsxxcpyFiIJ33xMdT9j7CFfxCBR
# a2+xq4aLT8LWRV+dIPyhHsXAj6KxfgommfXkaS+YHS312amyHeUbAgMBAAGjggE6
# MIIBNjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTs1+OC0nFdZEzfLmc/57qY
# rhwPTzAfBgNVHSMEGDAWgBRF66Kv9JLLgjEtUYunpyGd823IDzAOBgNVHQ8BAf8E
# BAMCAYYweQYIKwYBBQUHAQEEbTBrMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5k
# aWdpY2VydC5jb20wQwYIKwYBBQUHMAKGN2h0dHA6Ly9jYWNlcnRzLmRpZ2ljZXJ0
# LmNvbS9EaWdpQ2VydEFzc3VyZWRJRFJvb3RDQS5jcnQwRQYDVR0fBD4wPDA6oDig
# NoY0aHR0cDovL2NybDMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEUm9v
# dENBLmNybDARBgNVHSAECjAIMAYGBFUdIAAwDQYJKoZIhvcNAQEMBQADggEBAHCg
# v0NcVec4X6CjdBs9thbX979XB72arKGHLOyFXqkauyL4hxppVCLtpIh3bb0aFPQT
# SnovLbc47/T/gLn4offyct4kvFIDyE7QKt76LVbP+fT3rDB6mouyXtTP0UNEm0Mh
# 65ZyoUi0mcudT6cGAxN3J0TU53/oWajwvy8LpunyNDzs9wPHh6jSTEAZNUZqaVSw
# uKFWjuyk1T3osdz9HNj0d1pcVIxv76FQPfx2CWiEn2/K2yCNNWAcAgPLILCsWKAO
# QGPFmCLBsln1VWvPJ6tsds5vIy30fnFqI2si/xK4VC0nftg62fC2h5b9W9FcrBjD
# TZ9ztwGpn1eqXijiuZQwggYaMIIEAqADAgECAhBiHW0MUgGeO5B5FSCJIRwKMA0G
# CSqGSIb3DQEBDAUAMFYxCzAJBgNVBAYTAkdCMRgwFgYDVQQKEw9TZWN0aWdvIExp
# bWl0ZWQxLTArBgNVBAMTJFNlY3RpZ28gUHVibGljIENvZGUgU2lnbmluZyBSb290
# IFI0NjAeFw0yMTAzMjIwMDAwMDBaFw0zNjAzMjEyMzU5NTlaMFQxCzAJBgNVBAYT
# AkdCMRgwFgYDVQQKEw9TZWN0aWdvIExpbWl0ZWQxKzApBgNVBAMTIlNlY3RpZ28g
# UHVibGljIENvZGUgU2lnbmluZyBDQSBSMzYwggGiMA0GCSqGSIb3DQEBAQUAA4IB
# jwAwggGKAoIBgQCbK51T+jU/jmAGQ2rAz/V/9shTUxjIztNsfvxYB5UXeWUzCxEe
# AEZGbEN4QMgCsJLZUKhWThj/yPqy0iSZhXkZ6Pg2A2NVDgFigOMYzB2OKhdqfWGV
# oYW3haT29PSTahYkwmMv0b/83nbeECbiMXhSOtbam+/36F09fy1tsB8je/RV0mIk
# 8XL/tfCK6cPuYHE215wzrK0h1SWHTxPbPuYkRdkP05ZwmRmTnAO5/arnY83jeNzh
# P06ShdnRqtZlV59+8yv+KIhE5ILMqgOZYAENHNX9SJDm+qxp4VqpB3MV/h53yl41
# aHU5pledi9lCBbH9JeIkNFICiVHNkRmq4TpxtwfvjsUedyz8rNyfQJy/aOs5b4s+
# ac7IH60B+Ja7TVM+EKv1WuTGwcLmoU3FpOFMbmPj8pz44MPZ1f9+YEQIQty/NQd/
# 2yGgW+ufflcZ/ZE9o1M7a5Jnqf2i2/uMSWymR8r2oQBMdlyh2n5HirY4jKnFH/9g
# Rvd+QOfdRrJZb1sCAwEAAaOCAWQwggFgMB8GA1UdIwQYMBaAFDLrkpr/NZZILyhA
# QnAgNpFcF4XmMB0GA1UdDgQWBBQPKssghyi47G9IritUpimqF6TNDDAOBgNVHQ8B
# Af8EBAMCAYYwEgYDVR0TAQH/BAgwBgEB/wIBADATBgNVHSUEDDAKBggrBgEFBQcD
# AzAbBgNVHSAEFDASMAYGBFUdIAAwCAYGZ4EMAQQBMEsGA1UdHwREMEIwQKA+oDyG
# Omh0dHA6Ly9jcmwuc2VjdGlnby5jb20vU2VjdGlnb1B1YmxpY0NvZGVTaWduaW5n
# Um9vdFI0Ni5jcmwwewYIKwYBBQUHAQEEbzBtMEYGCCsGAQUFBzAChjpodHRwOi8v
# Y3J0LnNlY3RpZ28uY29tL1NlY3RpZ29QdWJsaWNDb2RlU2lnbmluZ1Jvb3RSNDYu
# cDdjMCMGCCsGAQUFBzABhhdodHRwOi8vb2NzcC5zZWN0aWdvLmNvbTANBgkqhkiG
# 9w0BAQwFAAOCAgEABv+C4XdjNm57oRUgmxP/BP6YdURhw1aVcdGRP4Wh60BAscjW
# 4HL9hcpkOTz5jUug2oeunbYAowbFC2AKK+cMcXIBD0ZdOaWTsyNyBBsMLHqafvIh
# rCymlaS98+QpoBCyKppP0OcxYEdU0hpsaqBBIZOtBajjcw5+w/KeFvPYfLF/ldYp
# mlG+vd0xqlqd099iChnyIMvY5HexjO2AmtsbpVn0OhNcWbWDRF/3sBp6fWXhz7Dc
# ML4iTAWS+MVXeNLj1lJziVKEoroGs9Mlizg0bUMbOalOhOfCipnx8CaLZeVme5yE
# Lg09Jlo8BMe80jO37PU8ejfkP9/uPak7VLwELKxAMcJszkyeiaerlphwoKx1uHRz
# NyE6bxuSKcutisqmKL5OTunAvtONEoteSiabkPVSZ2z76mKnzAfZxCl/3dq3dUNw
# 4rg3sTCggkHSRqTqlLMS7gjrhTqBmzu1L90Y1KWN/Y5JKdGvspbOrTfOXyXvmPL6
# E52z1NZJ6ctuMFBQZH3pwWvqURR8AgQdULUvrxjUYbHHj95Ejza63zdrEcxWLDX6
# xWls/GDnVNueKjWUH3fTv1Y8Wdho698YADR7TNx8X8z2Bev6SivBBOHY+uqiirZt
# g0y9ShQoPzmCcn63Syatatvx157YK9hlcPmVoa1oDE5/L9Uo2bC5a4CH2RwwggY+
# MIIEpqADAgECAhAHnODk0RR/hc05c892LTfrMA0GCSqGSIb3DQEBDAUAMFQxCzAJ
# BgNVBAYTAkdCMRgwFgYDVQQKEw9TZWN0aWdvIExpbWl0ZWQxKzApBgNVBAMTIlNl
# Y3RpZ28gUHVibGljIENvZGUgU2lnbmluZyBDQSBSMzYwHhcNMjYwMjA5MDAwMDAw
# WhcNMjkwNDIxMjM1OTU5WjBVMQswCQYDVQQGEwJVUzEUMBIGA1UECAwLQ29ubmVj
# dGljdXQxFzAVBgNVBAoMDkphc29uIEFsYmVyaW5vMRcwFQYDVQQDDA5KYXNvbiBB
# bGJlcmlubzCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAPN6aN4B1yYW
# kI5b5TBj3I0VV/peETrHb6EY4BHGxt8Ap+eT+WpEpJyEtRYPxEmNJL3A38Bkg7mw
# zPE3/1NK570ZBCuBjSAn4mSDIgIuXZnvyBO9W1OQs5d67MlJLUAEufl18tOr3ST1
# DeO9gSjQSAE5Nql0QDxPnm93OZBon+Fz3CmE+z3MwAe2h4KdtRAnCqwM+/V7iBdb
# w+JOxolpx+7RVjGyProTENIG3pe/hKvPb501lf8uBAADLdjZr5ip8vIWbf857Yw1
# Bu10nVI7HW3eE8Cl5//d1ribHlzTzQLfttW+k+DaFsKZBBL56l4YAlIVRsrOiE1k
# dHYYx6IGrEA809R7+TZA9DzGqyFiv9qmJAbL4fDwetDeyIq+Oztz1LvEdy8Rcd0J
# BY+J4S0eDEFIA3X0N8VcLeAwabKb9AjulKXwUeqCJLvN79CJ90UTZb2+I+tamj0d
# n+IKMEsJ4v4Ggx72sxFr9+6XziodtTg5Luf2xd6+PhhamOxF2px9LObhBLLEMyRs
# CHZIzVZOFKu9BpHQH7ufGB+Sa80Tli0/6LEyn9+bMYWi2ttn6lLOPThXMiQaooRU
# q6q2u3+F4SaPlxVFLI7OJVMhar6nW6joBvELTJPmANSMjDSRFDfHRCdGbZsL/keE
# LJNy+jZctF6VvxQEjFM8/bazu6qYhrA7AgMBAAGjggGJMIIBhTAfBgNVHSMEGDAW
# gBQPKssghyi47G9IritUpimqF6TNDDAdBgNVHQ4EFgQU6YF0o0D5AVhKHbVocr8G
# aSIBibAwDgYDVR0PAQH/BAQDAgeAMAwGA1UdEwEB/wQCMAAwEwYDVR0lBAwwCgYI
# KwYBBQUHAwMwSgYDVR0gBEMwQTA1BgwrBgEEAbIxAQIBAwIwJTAjBggrBgEFBQcC
# ARYXaHR0cHM6Ly9zZWN0aWdvLmNvbS9DUFMwCAYGZ4EMAQQBMEkGA1UdHwRCMEAw
# PqA8oDqGOGh0dHA6Ly9jcmwuc2VjdGlnby5jb20vU2VjdGlnb1B1YmxpY0NvZGVT
# aWduaW5nQ0FSMzYuY3JsMHkGCCsGAQUFBwEBBG0wazBEBggrBgEFBQcwAoY4aHR0
# cDovL2NydC5zZWN0aWdvLmNvbS9TZWN0aWdvUHVibGljQ29kZVNpZ25pbmdDQVIz
# Ni5jcnQwIwYIKwYBBQUHMAGGF2h0dHA6Ly9vY3NwLnNlY3RpZ28uY29tMA0GCSqG
# SIb3DQEBDAUAA4IBgQAEIsm4xnOd/tZMVrKwi3doAXvCwOA/RYQnFJD7R/bSQRu3
# wXEK4o9SIefye18B/q4fhBkhNAJuEvTQAGfqbbpxow03J5PrDTp1WPCWbXKX8Oz9
# vGWJFyJxRGftkdzZ57JE00synEMS8XCwLO9P32MyR9Z9URrpiLPJ9rQjfHMb1BUd
# vaNayomm7aWLAnD+X7jm6o8sNT5An1cwEAob7obWDM6sX93wphwJNBJAstH9Ozs6
# LwISOX6sKS7CKm9N3Kp8hOUue0ZHAtZdFl6o5u12wy+zzieGEI50fKnN77FfNKFO
# WKlS6OJwlArcbFegB5K89LcE5iNSmaM3VMB2ADV1FEcjGSHw4lTg1Wx+WMAMdl/7
# nbvfFxJ9uu5tNiT54B0s+lZO/HztwXYQUczdsFon3pjsNrsk9ZlalBi5SHkIu+F6
# g7tWiEv3rtVApmJRnLkUr2Xq2a4nbslUCt4jKs5UX4V1nSX8OM++AXoyVGO+iTj7
# z+pl6XE9Gw/Td6WKKKswgga0MIIEnKADAgECAhANx6xXBf8hmS5AQyIMOkmGMA0G
# CSqGSIb3DQEBCwUAMGIxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJ
# bmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xITAfBgNVBAMTGERpZ2lDZXJ0
# IFRydXN0ZWQgUm9vdCBHNDAeFw0yNTA1MDcwMDAwMDBaFw0zODAxMTQyMzU5NTla
# MGkxCzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5EaWdpQ2VydCwgSW5jLjFBMD8GA1UE
# AxM4RGlnaUNlcnQgVHJ1c3RlZCBHNCBUaW1lU3RhbXBpbmcgUlNBNDA5NiBTSEEy
# NTYgMjAyNSBDQTEwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC0eDHT
# CphBcr48RsAcrHXbo0ZodLRRF51NrY0NlLWZloMsVO1DahGPNRcybEKq+RuwOnPh
# of6pvF4uGjwjqNjfEvUi6wuim5bap+0lgloM2zX4kftn5B1IpYzTqpyFQ/4Bt0mA
# xAHeHYNnQxqXmRinvuNgxVBdJkf77S2uPoCj7GH8BLuxBG5AvftBdsOECS1UkxBv
# MgEdgkFiDNYiOTx4OtiFcMSkqTtF2hfQz3zQSku2Ws3IfDReb6e3mmdglTcaarps
# 0wjUjsZvkgFkriK9tUKJm/s80FiocSk1VYLZlDwFt+cVFBURJg6zMUjZa/zbCclF
# 83bRVFLeGkuAhHiGPMvSGmhgaTzVyhYn4p0+8y9oHRaQT/aofEnS5xLrfxnGpTXi
# UOeSLsJygoLPp66bkDX1ZlAeSpQl92QOMeRxykvq6gbylsXQskBBBnGy3tW/AMOM
# CZIVNSaz7BX8VtYGqLt9MmeOreGPRdtBx3yGOP+rx3rKWDEJlIqLXvJWnY0v5ydP
# pOjL6s36czwzsucuoKs7Yk/ehb//Wx+5kMqIMRvUBDx6z1ev+7psNOdgJMoiwOrU
# G2ZdSoQbU2rMkpLiQ6bGRinZbI4OLu9BMIFm1UUl9VnePs6BaaeEWvjJSjNm2qA+
# sdFUeEY0qVjPKOWug/G6X5uAiynM7Bu2ayBjUwIDAQABo4IBXTCCAVkwEgYDVR0T
# AQH/BAgwBgEB/wIBADAdBgNVHQ4EFgQU729TSunkBnx6yuKQVvYv1Ensy04wHwYD
# VR0jBBgwFoAU7NfjgtJxXWRM3y5nP+e6mK4cD08wDgYDVR0PAQH/BAQDAgGGMBMG
# A1UdJQQMMAoGCCsGAQUFBwMIMHcGCCsGAQUFBwEBBGswaTAkBggrBgEFBQcwAYYY
# aHR0cDovL29jc3AuZGlnaWNlcnQuY29tMEEGCCsGAQUFBzAChjVodHRwOi8vY2Fj
# ZXJ0cy5kaWdpY2VydC5jb20vRGlnaUNlcnRUcnVzdGVkUm9vdEc0LmNydDBDBgNV
# HR8EPDA6MDigNqA0hjJodHRwOi8vY3JsMy5kaWdpY2VydC5jb20vRGlnaUNlcnRU
# cnVzdGVkUm9vdEc0LmNybDAgBgNVHSAEGTAXMAgGBmeBDAEEAjALBglghkgBhv1s
# BwEwDQYJKoZIhvcNAQELBQADggIBABfO+xaAHP4HPRF2cTC9vgvItTSmf83Qh8WI
# GjB/T8ObXAZz8OjuhUxjaaFdleMM0lBryPTQM2qEJPe36zwbSI/mS83afsl3YTj+
# IQhQE7jU/kXjjytJgnn0hvrV6hqWGd3rLAUt6vJy9lMDPjTLxLgXf9r5nWMQwr8M
# yb9rEVKChHyfpzee5kH0F8HABBgr0UdqirZ7bowe9Vj2AIMD8liyrukZ2iA/wdG2
# th9y1IsA0QF8dTXqvcnTmpfeQh35k5zOCPmSNq1UH410ANVko43+Cdmu4y81hjaj
# V/gxdEkMx1NKU4uHQcKfZxAvBAKqMVuqte69M9J6A47OvgRaPs+2ykgcGV00TYr2
# Lr3ty9qIijanrUR3anzEwlvzZiiyfTPjLbnFRsjsYg39OlV8cipDoq7+qNNjqFze
# GxcytL5TTLL4ZaoBdqbhOhZ3ZRDUphPvSRmMThi0vw9vODRzW6AxnJll38F0cuJG
# 7uEBYTptMSbhdhGQDpOXgpIUsWTjd6xpR6oaQf/DJbg3s6KCLPAlZ66RzIg9sC+N
# Jpud/v4+7RWsWCiKi9EOLLHfMR2ZyJ/+xhCx9yHbxtl5TPau1j/1MIDpMPx0LckT
# etiSuEtQvLsNz3Qbp7wGWqbIiOWCnb5WqxL3/BAPvIXKUjPSxyZsq8WhbaM2tszW
# kPZPubdcMIIG7TCCBNWgAwIBAgIQCoDvGEuN8QWC0cR2p5V0aDANBgkqhkiG9w0B
# AQsFADBpMQswCQYDVQQGEwJVUzEXMBUGA1UEChMORGlnaUNlcnQsIEluYy4xQTA/
# BgNVBAMTOERpZ2lDZXJ0IFRydXN0ZWQgRzQgVGltZVN0YW1waW5nIFJTQTQwOTYg
# U0hBMjU2IDIwMjUgQ0ExMB4XDTI1MDYwNDAwMDAwMFoXDTM2MDkwMzIzNTk1OVow
# YzELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDkRpZ2lDZXJ0LCBJbmMuMTswOQYDVQQD
# EzJEaWdpQ2VydCBTSEEyNTYgUlNBNDA5NiBUaW1lc3RhbXAgUmVzcG9uZGVyIDIw
# MjUgMTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANBGrC0Sxp7Q6q5g
# VrMrV7pvUf+GcAoB38o3zBlCMGMyqJnfFNZx+wvA69HFTBdwbHwBSOeLpvPnZ8ZN
# +vo8dE2/pPvOx/Vj8TchTySA2R4QKpVD7dvNZh6wW2R6kSu9RJt/4QhguSssp3qo
# me7MrxVyfQO9sMx6ZAWjFDYOzDi8SOhPUWlLnh00Cll8pjrUcCV3K3E0zz09ldQ/
# /nBZZREr4h/GI6Dxb2UoyrN0ijtUDVHRXdmncOOMA3CoB/iUSROUINDT98oksouT
# MYFOnHoRh6+86Ltc5zjPKHW5KqCvpSduSwhwUmotuQhcg9tw2YD3w6ySSSu+3qU8
# DD+nigNJFmt6LAHvH3KSuNLoZLc1Hf2JNMVL4Q1OpbybpMe46YceNA0LfNsnqcnp
# JeItK/DhKbPxTTuGoX7wJNdoRORVbPR1VVnDuSeHVZlc4seAO+6d2sC26/PQPdP5
# 1ho1zBp+xUIZkpSFA8vWdoUoHLWnqWU3dCCyFG1roSrgHjSHlq8xymLnjCbSLZ49
# kPmk8iyyizNDIXj//cOgrY7rlRyTlaCCfw7aSUROwnu7zER6EaJ+AliL7ojTdS5P
# WPsWeupWs7NpChUk555K096V1hE0yZIXe+giAwW00aHzrDchIc2bQhpp0IoKRR7Y
# ufAkprxMiXAJQ1XCmnCfgPf8+3mnAgMBAAGjggGVMIIBkTAMBgNVHRMBAf8EAjAA
# MB0GA1UdDgQWBBTkO/zyMe39/dfzkXFjGVBDz2GM6DAfBgNVHSMEGDAWgBTvb1NK
# 6eQGfHrK4pBW9i/USezLTjAOBgNVHQ8BAf8EBAMCB4AwFgYDVR0lAQH/BAwwCgYI
# KwYBBQUHAwgwgZUGCCsGAQUFBwEBBIGIMIGFMCQGCCsGAQUFBzABhhhodHRwOi8v
# b2NzcC5kaWdpY2VydC5jb20wXQYIKwYBBQUHMAKGUWh0dHA6Ly9jYWNlcnRzLmRp
# Z2ljZXJ0LmNvbS9EaWdpQ2VydFRydXN0ZWRHNFRpbWVTdGFtcGluZ1JTQTQwOTZT
# SEEyNTYyMDI1Q0ExLmNydDBfBgNVHR8EWDBWMFSgUqBQhk5odHRwOi8vY3JsMy5k
# aWdpY2VydC5jb20vRGlnaUNlcnRUcnVzdGVkRzRUaW1lU3RhbXBpbmdSU0E0MDk2
# U0hBMjU2MjAyNUNBMS5jcmwwIAYDVR0gBBkwFzAIBgZngQwBBAIwCwYJYIZIAYb9
# bAcBMA0GCSqGSIb3DQEBCwUAA4ICAQBlKq3xHCcEua5gQezRCESeY0ByIfjk9iJP
# 2zWLpQq1b4URGnwWBdEZD9gBq9fNaNmFj6Eh8/YmRDfxT7C0k8FUFqNh+tshgb4O
# 6Lgjg8K8elC4+oWCqnU/ML9lFfim8/9yJmZSe2F8AQ/UdKFOtj7YMTmqPO9mzskg
# iC3QYIUP2S3HQvHG1FDu+WUqW4daIqToXFE/JQ/EABgfZXLWU0ziTN6R3ygQBHMU
# BaB5bdrPbF6MRYs03h4obEMnxYOX8VBRKe1uNnzQVTeLni2nHkX/QqvXnNb+YkDF
# kxUGtMTaiLR9wjxUxu2hECZpqyU1d0IbX6Wq8/gVutDojBIFeRlqAcuEVT0cKsb+
# zJNEsuEB7O7/cuvTQasnM9AWcIQfVjnzrvwiCZ85EE8LUkqRhoS3Y50OHgaY7T/l
# wd6UArb+BOVAkg2oOvol/DJgddJ35XTxfUlQ+8Hggt8l2Yv7roancJIFcbojBcxl
# RcGG0LIhp6GvReQGgMgYxQbV1S3CrWqZzBt1R9xJgKf47CdxVRd/ndUlQ05oxYy2
# zRWVFjF7mcr4C34Mj3ocCVccAvlKV9jEnstrniLvUxxVZE/rptb7IRE2lskKPIJg
# baP5t2nGj/ULLi49xTcBZU8atufk+EMF/cWuiC7POGT75qaL6vdCvHlshtjdNXOC
# IUjsarfNZzGCBkQwggZAAgEBMGgwVDELMAkGA1UEBhMCR0IxGDAWBgNVBAoTD1Nl
# Y3RpZ28gTGltaXRlZDErMCkGA1UEAxMiU2VjdGlnbyBQdWJsaWMgQ29kZSBTaWdu
# aW5nIENBIFIzNgIQB5zg5NEUf4XNOXPPdi036zANBglghkgBZQMEAgEFAKCBhDAY
# BgorBgEEAYI3AgEMMQowCKACgAChAoAAMBkGCSqGSIb3DQEJAzEMBgorBgEEAYI3
# AgEEMBwGCisGAQQBgjcCAQsxDjAMBgorBgEEAYI3AgEVMC8GCSqGSIb3DQEJBDEi
# BCAr7Udol6jHQs3I3It7r51u1ABK/vUs2ZdyarysBcUUCTANBgkqhkiG9w0BAQEF
# AASCAgDd4uRWrhGY0PU349o+J0DVRE5MWV/WxSPPNYxb388OC8E427RzNljN5fgG
# qGZSZtl417aFvaamW9PeOP36u8IxF6EAkCBVlnfBMom6xJoolavAyV/rvbM1o0lU
# XtSGficouDDp+XiIAMkJu7i/jZMl0dgR87ZseHzx3J4V84o7bq7FzZmHro/Huw+n
# WvSU7vNqcm04xS00UWFa+9yc92h+Yop+pPuKgd+/UhkqnX+ZLzbuRR89fwOFizrB
# xHGhGYS6kNtZQifFXkiCdwooZZE/ukr1LlSFrncz9lX/jsunguvdYFc1fqVSWG9r
# WtUvImCaEmmpfFyns+vrabCzfKNvR5yyQi0RwuVqV2eqcq5wOlhPQO2PG8xc1zoj
# icC5GO1CVCAbP4EiaDxzfwxIwG6/ZFz1Nx00tivGmpt6rYFnb0Mjjg4hNETBZlJ+
# F9Qrf8v6xcPqi06QRyO9W1lsw6SrzsWQWRG7Fob07Twc9bLEVHqe1nz9kKFefAO5
# Skb4j7hBSFqKI8Y6UumpCr05P7/sd/X5aurvqBd3m5+bbXhSX8woOCNTQCPn3fMF
# +rY27aSiEuxxx1ZOU8WDDCgYO2L98knUQxd5s9VoSf4nNqLPpQwjnLk2P8tmMaZg
# /LJtZ/moHVTmFhqgrtdpOxK7RGdOqKyb/Z/hEms3C3PU7AJNhKGCAyYwggMiBgkq
# hkiG9w0BCQYxggMTMIIDDwIBATB9MGkxCzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5E
# aWdpQ2VydCwgSW5jLjFBMD8GA1UEAxM4RGlnaUNlcnQgVHJ1c3RlZCBHNCBUaW1l
# U3RhbXBpbmcgUlNBNDA5NiBTSEEyNTYgMjAyNSBDQTECEAqA7xhLjfEFgtHEdqeV
# dGgwDQYJYIZIAWUDBAIBBQCgaTAYBgkqhkiG9w0BCQMxCwYJKoZIhvcNAQcBMBwG
# CSqGSIb3DQEJBTEPFw0yNjA1MjQxNzQxMjZaMC8GCSqGSIb3DQEJBDEiBCACCdnc
# IlRK5Sb9LukLSN3HDWpD04tmrPAK4Hb83s25WzANBgkqhkiG9w0BAQEFAASCAgBd
# zJrFJR1F2THmzJE8Ttu+K9oajFMqf/rgWvguvLKmHpfuXnw5dmU/q1QILcrpmbJe
# ikwV4UpNgGjhGNNkuvMiHegDB6tQZKcSzBBQHEWRa/yrBJfpYgW0bHY78/XPxUmU
# 83r4cYnRAi9O9Tbqy31WPY/PY5cvxLsDYybuzUp7c7gHF+h5vYHWFD675Z7/a2ER
# 2dHZXhCBem1GuJqmOC1sKZJ5h/D7/Ae0USl2hJ/r8xS38EX9jwb8cE57IiWK1L7F
# AjUV+2sTr+d0S+NoOTqDSeNfLFTNN1w2npOn3hmdfe5VvM7EWF/2SGWVgEQa/dZ2
# ikFY59H9cSBTRAKHqdZtqgeDnzcBsba0hUlIiH16SgvctV6/SKETQ/PYPlGNKDEr
# ODn4YoCM3Xl3fmaZaBxg5BQCUtzT5TWOWHtccopt5yZsdqp5UEHs4POTS/KbBhEN
# YTlAImWOOjl1fmaoplV4wk2ZScU0X1CijEj6n/GdWyiJ8tdQ+UIuwBpoulQQ+bPA
# gC/IdCNEiDDaDkda6iRZCGfhPFoYTWeCp+kpPUo7yQKNp2uJbftvVA23o+M32JCV
# Y21GRjEOcXif6UWZCvK1s5D/rKG9KikRtTifL9P4XwNPliOVBK19N6OMSejc+J//
# LNZ0RK5StUEUvZgPMvyv363x3pubRzMTMUlXGIXYtw==
# SIG # End signature block