helpers/gcp/discover-gcp-immediate-add-with-attributes.ps1

# Configuration
$GCPKeyFilePath = "C:\path\to\service-account-key.json"  # Path to GCP service account JSON key
$GCPProjects    = @("your-project-id")                   # GCP project IDs to scan
$WUGServer      = "192.168.1.250"

# Credentials
if (!$WUGCred) { $WUGCred = Get-Credential -Message "Enter credentials for WUG server" }

# Check if required modules are installed and loaded
if (-not (Get-Module -Name WhatsUpGoldPS)) { Import-Module WhatsUpGoldPS }

if (-not (Get-Module -Name GoogleCloud -ListAvailable)) {
    throw "Required module 'GoogleCloud' is not installed. Run: Install-Module -Name GoogleCloud -Scope CurrentUser -Force"
}
if (-not (Get-Module -Name GoogleCloud)) { Import-Module GoogleCloud }

# Load helper functions
. "$PSScriptRoot\GCPHelpers.ps1"

# ========================
# Connect to GCP
# ========================
Write-Host "`n=== Connecting to GCP ===" -ForegroundColor Cyan
Connect-GCPAccount -KeyFilePath $GCPKeyFilePath -Project $GCPProjects[0]

# ========================
# Discover Resources Across Projects
# ========================
$allVMs  = @()
$allSQL  = @()
$allLBs  = @()

foreach ($project in $GCPProjects) {
    Write-Host "`n=== Project: $project ===" -ForegroundColor Cyan

    # --- Compute Engine Instances ---
    Write-Host " Gathering Compute Engine instances..." -ForegroundColor Gray
    try {
        $vms = @(Get-GCPComputeInstances -Project $project)
        Write-Host " Found $($vms.Count) VM instances" -ForegroundColor Gray
        $allVMs += $vms
    }
    catch {
        Write-Warning " Could not enumerate Compute Engine in $project : $($_.Exception.Message)"
    }

    # --- Cloud SQL Instances ---
    Write-Host " Gathering Cloud SQL instances..." -ForegroundColor Gray
    try {
        $sqlInstances = @(Get-GCPCloudSQLInstances -Project $project)
        Write-Host " Found $($sqlInstances.Count) Cloud SQL instances" -ForegroundColor Gray
        $allSQL += $sqlInstances
    }
    catch {
        Write-Warning " Could not enumerate Cloud SQL in $project : $($_.Exception.Message)"
    }

    # --- Forwarding Rules (Load Balancers) ---
    Write-Host " Gathering Forwarding Rules (Load Balancers)..." -ForegroundColor Gray
    try {
        $lbs = @(Get-GCPForwardingRules -Project $project)
        Write-Host " Found $($lbs.Count) forwarding rules" -ForegroundColor Gray
        $allLBs += $lbs
    }
    catch {
        Write-Warning " Could not enumerate forwarding rules in $project : $($_.Exception.Message)"
    }
}

# ========================
# Display Summary
# ========================
Write-Host "`n=== Discovery Summary ===" -ForegroundColor Cyan
Write-Host " Compute Engine VMs: $($allVMs.Count)"
Write-Host " Cloud SQL: $($allSQL.Count)"
Write-Host " Forwarding Rules: $($allLBs.Count)"

if ($allVMs.Count -gt 0) {
    Write-Host "`n=== Compute Engine Instances ===" -ForegroundColor Cyan
    $allVMs | Format-Table Name, MachineType, Status, Zone, ExternalIP, InternalIP -AutoSize
}

if ($allSQL.Count -gt 0) {
    Write-Host "`n=== Cloud SQL Instances ===" -ForegroundColor Cyan
    $allSQL | Format-Table InstanceName, DatabaseVersion, Tier, State, Region, PublicIP, PrivateIP -AutoSize
}

if ($allLBs.Count -gt 0) {
    Write-Host "`n=== Forwarding Rules ===" -ForegroundColor Cyan
    $allLBs | Format-Table Name, IPAddress, IPProtocol, PortRange, Region, Scheme -AutoSize
}

# ========================
# Add to WhatsUp Gold
# ========================
Connect-WUGServer -serverUri $WUGServer -Credential $WUGCred -Protocol https -IgnoreSSLErrors

$added = 0; $skipped = 0

# --- Compute Engine VMs ---
Write-Host "`n=== Adding Compute Engine VMs to WUG ===" -ForegroundColor Cyan
foreach ($vm in $allVMs) {
    $ip = Resolve-GCPResourceIP -ResourceType ComputeEngine -Resource $vm

    if (-not $ip -or $ip -notmatch '^\d{1,3}(\.\d{1,3}){3}$') {
        Write-Warning "Skipping VM $($vm.Name) - no resolvable IP"
        $skipped++
        continue
    }

    if (Get-WUGDevice -SearchValue $ip -View id) {
        Write-Warning "Skipping already monitored VM $($vm.Name) ($ip)"
        $skipped++
        continue
    }

    # Fetch Cloud Monitoring metrics
    $metrics = Get-GCPCloudMonitoringMetrics -Project $GCPProjects[0] -ResourceType "gce_instance" `
        -ResourceLabels @{ instance_id = $vm.InstanceId; zone = $vm.Zone }

    $attributes = @(
        @{ Name = "GCP_Type";            Value = "Compute Engine VM" }
        @{ Name = "GCP_InstanceId";      Value = "$($vm.InstanceId)" }
        @{ Name = "GCP_Name";            Value = "$($vm.Name)" }
        @{ Name = "GCP_MachineType";     Value = "$($vm.MachineType)" }
        @{ Name = "GCP_Status";          Value = "$($vm.Status)" }
        @{ Name = "GCP_Zone";            Value = "$($vm.Zone)" }
        @{ Name = "GCP_Region";          Value = "$($vm.Region)" }
        @{ Name = "GCP_InternalIP";      Value = "$($vm.InternalIP)" }
        @{ Name = "GCP_ExternalIP";      Value = "$($vm.ExternalIP)" }
        @{ Name = "GCP_Network";         Value = "$($vm.Network)" }
        @{ Name = "GCP_Subnet";          Value = "$($vm.Subnet)" }
        @{ Name = "GCP_DiskCount";       Value = "$($vm.DiskCount)" }
        @{ Name = "GCP_BootDiskType";    Value = "$($vm.BootDiskType)" }
        @{ Name = "GCP_Tags";            Value = "$($vm.Tags)" }
        @{ Name = "GCP_Labels";          Value = "$($vm.Labels)" }
        @{ Name = "GCP_ServiceAccounts"; Value = "$($vm.ServiceAccounts)" }
        @{ Name = "GCP_CreationTime";    Value = "$($vm.CreationTime)" }
        @{ Name = "GCP_LastSync";        Value = "$((Get-Date).ToString('yyyy-MM-dd HH:mm:ss'))" }
    )

    foreach ($m in $metrics) {
        $safeMetricName = $m.MetricName -replace '[^a-zA-Z0-9_]', '_'
        $attributes += @{
            Name  = "GCP_Metric_$safeMetricName"
            Value = "$($m.LastValue) $($m.Unit)"
        }
    }

    $note = "GCE $($vm.MachineType) | $($vm.Zone) | " +
            "Network: $($vm.Network)/$($vm.Subnet) | Disks: $($vm.DiskCount) | " +
            "Created: $($vm.CreationTime) | Added $((Get-Date).ToString('yyyy-MM-dd HH:mm'))"

    $newDeviceId = Add-WUGDeviceTemplate `
        -displayName $vm.Name `
        -DeviceAddress $ip `
        -Brand "GCP Compute Engine" `
        -OS "Google Compute Engine" `
        -ActiveMonitors @("Ping") `
        -PerformanceMonitors @("CPU Utilization", "Memory Utilization", "Disk Utilization",
            "Interface Utilization", "Ping Latency and Availability") `
        -Attributes $attributes `
        -Note $note

    if ($newDeviceId) {
        Write-Host " Added VM $($vm.Name) ($ip)" -ForegroundColor Green
        $added++
    }
}

# --- Cloud SQL Instances ---
Write-Host "`n=== Adding Cloud SQL Instances to WUG ===" -ForegroundColor Cyan
foreach ($db in $allSQL) {
    $ip = Resolve-GCPResourceIP -ResourceType CloudSQL -Resource $db

    if (-not $ip -or $ip -notmatch '^\d{1,3}(\.\d{1,3}){3}$') {
        Write-Warning "Skipping Cloud SQL $($db.InstanceName) - no resolvable IP"
        $skipped++
        continue
    }

    if (Get-WUGDevice -SearchValue $ip -View id) {
        Write-Warning "Skipping already monitored Cloud SQL $($db.InstanceName) ($ip)"
        $skipped++
        continue
    }

    # Fetch Cloud Monitoring metrics
    $metrics = Get-GCPCloudMonitoringMetrics -Project $GCPProjects[0] -ResourceType "cloudsql_database" `
        -ResourceLabels @{ database_id = "$($GCPProjects[0]):$($db.InstanceName)" }

    $attributes = @(
        @{ Name = "GCP_Type";              Value = "Cloud SQL" }
        @{ Name = "GCP_InstanceName";      Value = "$($db.InstanceName)" }
        @{ Name = "GCP_DatabaseVersion";   Value = "$($db.DatabaseVersion)" }
        @{ Name = "GCP_Tier";              Value = "$($db.Tier)" }
        @{ Name = "GCP_State";             Value = "$($db.State)" }
        @{ Name = "GCP_Region";            Value = "$($db.Region)" }
        @{ Name = "GCP_GceZone";           Value = "$($db.GceZone)" }
        @{ Name = "GCP_PublicIP";          Value = "$($db.PublicIP)" }
        @{ Name = "GCP_PrivateIP";         Value = "$($db.PrivateIP)" }
        @{ Name = "GCP_DataDiskSizeGB";    Value = "$($db.DataDiskSizeGB)" }
        @{ Name = "GCP_DataDiskType";      Value = "$($db.DataDiskType)" }
        @{ Name = "GCP_BackupEnabled";     Value = "$($db.BackupEnabled)" }
        @{ Name = "GCP_HA";                Value = "$($db.HA)" }
        @{ Name = "GCP_StorageAutoResize"; Value = "$($db.StorageAutoResize)" }
        @{ Name = "GCP_ConnectionName";    Value = "$($db.ConnectionName)" }
        @{ Name = "GCP_LastSync";          Value = "$((Get-Date).ToString('yyyy-MM-dd HH:mm:ss'))" }
    )

    foreach ($m in $metrics) {
        $safeMetricName = $m.MetricName -replace '[^a-zA-Z0-9_]', '_'
        $attributes += @{
            Name  = "GCP_Metric_$safeMetricName"
            Value = "$($m.LastValue) $($m.Unit)"
        }
    }

    $note = "Cloud SQL $($db.DatabaseVersion) | $($db.Tier) | " +
            "$($db.Region) | Disk: $($db.DataDiskSizeGB) GB $($db.DataDiskType) | " +
            "HA: $($db.HA) | Added $((Get-Date).ToString('yyyy-MM-dd HH:mm'))"

    $newDeviceId = Add-WUGDeviceTemplate `
        -displayName $db.InstanceName `
        -DeviceAddress $ip `
        -Brand "GCP Cloud SQL" `
        -OS "$($db.DatabaseVersion)" `
        -ActiveMonitors @("Ping") `
        -PerformanceMonitors @("Ping Latency and Availability") `
        -Attributes $attributes `
        -Note $note

    if ($newDeviceId) {
        Write-Host " Added Cloud SQL $($db.InstanceName) ($ip)" -ForegroundColor Green
        $added++
    }
}

# --- Forwarding Rules (Load Balancers) ---
Write-Host "`n=== Adding Forwarding Rules to WUG ===" -ForegroundColor Cyan
foreach ($lb in $allLBs) {
    $ip = Resolve-GCPResourceIP -ResourceType ForwardingRule -Resource $lb

    if (-not $ip -or $ip -notmatch '^\d{1,3}(\.\d{1,3}){3}$') {
        Write-Warning "Skipping LB $($lb.Name) - no resolvable IP"
        $skipped++
        continue
    }

    if (Get-WUGDevice -SearchValue $ip -View id) {
        Write-Warning "Skipping already monitored LB $($lb.Name) ($ip)"
        $skipped++
        continue
    }

    $attributes = @(
        @{ Name = "GCP_Type";          Value = "Forwarding Rule" }
        @{ Name = "GCP_Name";          Value = "$($lb.Name)" }
        @{ Name = "GCP_IPAddress";     Value = "$($lb.IPAddress)" }
        @{ Name = "GCP_IPProtocol";    Value = "$($lb.IPProtocol)" }
        @{ Name = "GCP_PortRange";     Value = "$($lb.PortRange)" }
        @{ Name = "GCP_Target";        Value = "$($lb.Target)" }
        @{ Name = "GCP_Region";        Value = "$($lb.Region)" }
        @{ Name = "GCP_Network";       Value = "$($lb.Network)" }
        @{ Name = "GCP_Scheme";        Value = "$($lb.Scheme)" }
        @{ Name = "GCP_LastSync";      Value = "$((Get-Date).ToString('yyyy-MM-dd HH:mm:ss'))" }
    )

    $note = "GCP LB $($lb.Scheme) | $($lb.IPProtocol) $($lb.PortRange) | " +
            "Region: $($lb.Region) | Target: $($lb.Target) | " +
            "Added $((Get-Date).ToString('yyyy-MM-dd HH:mm'))"

    $newDeviceId = Add-WUGDeviceTemplate `
        -displayName $lb.Name `
        -DeviceAddress $ip `
        -Brand "GCP Load Balancer" `
        -OS "Google Cloud Load Balancer" `
        -ActiveMonitors @("Ping") `
        -PerformanceMonitors @("Ping Latency and Availability") `
        -Attributes $attributes `
        -Note $note

    if ($newDeviceId) {
        Write-Host " Added LB $($lb.Name) ($ip)" -ForegroundColor Green
        $added++
    }
}

Write-Host "`n=== Results ===" -ForegroundColor Cyan
Write-Host " Added: $added"
Write-Host " Skipped: $skipped"
Write-Host " Total: $($allVMs.Count + $allSQL.Count + $allLBs.Count)"

# Cleanup
if ($Global:WUGConnection) {
    Disconnect-WUGServer
}

# SIG # Begin signature block
# MIIVlwYJKoZIhvcNAQcCoIIViDCCFYQCAQExDzANBglghkgBZQMEAgEFADB5Bgor
# BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG
# KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCByeCJq2O1iax3w
# AccbrVgZE+itdghiX1WBa7g6aFhN9KCCEdMwggVvMIIEV6ADAgECAhBI/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/mBlXpnYzyOmJRvOwkDynUWICE5EV7WtgwggYaMIIEAqADAgECAhBiHW0M
# UgGeO5B5FSCJIRwKMA0GCSqGSIb3DQEBDAUAMFYxCzAJBgNVBAYTAkdCMRgwFgYD
# VQQKEw9TZWN0aWdvIExpbWl0ZWQxLTArBgNVBAMTJFNlY3RpZ28gUHVibGljIENv
# ZGUgU2lnbmluZyBSb290IFI0NjAeFw0yMTAzMjIwMDAwMDBaFw0zNjAzMjEyMzU5
# NTlaMFQxCzAJBgNVBAYTAkdCMRgwFgYDVQQKEw9TZWN0aWdvIExpbWl0ZWQxKzAp
# BgNVBAMTIlNlY3RpZ28gUHVibGljIENvZGUgU2lnbmluZyBDQSBSMzYwggGiMA0G
# CSqGSIb3DQEBAQUAA4IBjwAwggGKAoIBgQCbK51T+jU/jmAGQ2rAz/V/9shTUxjI
# ztNsfvxYB5UXeWUzCxEeAEZGbEN4QMgCsJLZUKhWThj/yPqy0iSZhXkZ6Pg2A2NV
# DgFigOMYzB2OKhdqfWGVoYW3haT29PSTahYkwmMv0b/83nbeECbiMXhSOtbam+/3
# 6F09fy1tsB8je/RV0mIk8XL/tfCK6cPuYHE215wzrK0h1SWHTxPbPuYkRdkP05Zw
# mRmTnAO5/arnY83jeNzhP06ShdnRqtZlV59+8yv+KIhE5ILMqgOZYAENHNX9SJDm
# +qxp4VqpB3MV/h53yl41aHU5pledi9lCBbH9JeIkNFICiVHNkRmq4TpxtwfvjsUe
# dyz8rNyfQJy/aOs5b4s+ac7IH60B+Ja7TVM+EKv1WuTGwcLmoU3FpOFMbmPj8pz4
# 4MPZ1f9+YEQIQty/NQd/2yGgW+ufflcZ/ZE9o1M7a5Jnqf2i2/uMSWymR8r2oQBM
# dlyh2n5HirY4jKnFH/9gRvd+QOfdRrJZb1sCAwEAAaOCAWQwggFgMB8GA1UdIwQY
# MBaAFDLrkpr/NZZILyhAQnAgNpFcF4XmMB0GA1UdDgQWBBQPKssghyi47G9IritU
# pimqF6TNDDAOBgNVHQ8BAf8EBAMCAYYwEgYDVR0TAQH/BAgwBgEB/wIBADATBgNV
# HSUEDDAKBggrBgEFBQcDAzAbBgNVHSAEFDASMAYGBFUdIAAwCAYGZ4EMAQQBMEsG
# A1UdHwREMEIwQKA+oDyGOmh0dHA6Ly9jcmwuc2VjdGlnby5jb20vU2VjdGlnb1B1
# YmxpY0NvZGVTaWduaW5nUm9vdFI0Ni5jcmwwewYIKwYBBQUHAQEEbzBtMEYGCCsG
# AQUFBzAChjpodHRwOi8vY3J0LnNlY3RpZ28uY29tL1NlY3RpZ29QdWJsaWNDb2Rl
# U2lnbmluZ1Jvb3RSNDYucDdjMCMGCCsGAQUFBzABhhdodHRwOi8vb2NzcC5zZWN0
# aWdvLmNvbTANBgkqhkiG9w0BAQwFAAOCAgEABv+C4XdjNm57oRUgmxP/BP6YdURh
# w1aVcdGRP4Wh60BAscjW4HL9hcpkOTz5jUug2oeunbYAowbFC2AKK+cMcXIBD0Zd
# OaWTsyNyBBsMLHqafvIhrCymlaS98+QpoBCyKppP0OcxYEdU0hpsaqBBIZOtBajj
# cw5+w/KeFvPYfLF/ldYpmlG+vd0xqlqd099iChnyIMvY5HexjO2AmtsbpVn0OhNc
# WbWDRF/3sBp6fWXhz7DcML4iTAWS+MVXeNLj1lJziVKEoroGs9Mlizg0bUMbOalO
# hOfCipnx8CaLZeVme5yELg09Jlo8BMe80jO37PU8ejfkP9/uPak7VLwELKxAMcJs
# zkyeiaerlphwoKx1uHRzNyE6bxuSKcutisqmKL5OTunAvtONEoteSiabkPVSZ2z7
# 6mKnzAfZxCl/3dq3dUNw4rg3sTCggkHSRqTqlLMS7gjrhTqBmzu1L90Y1KWN/Y5J
# KdGvspbOrTfOXyXvmPL6E52z1NZJ6ctuMFBQZH3pwWvqURR8AgQdULUvrxjUYbHH
# j95Ejza63zdrEcxWLDX6xWls/GDnVNueKjWUH3fTv1Y8Wdho698YADR7TNx8X8z2
# Bev6SivBBOHY+uqiirZtg0y9ShQoPzmCcn63Syatatvx157YK9hlcPmVoa1oDE5/
# L9Uo2bC5a4CH2RwwggY+MIIEpqADAgECAhAHnODk0RR/hc05c892LTfrMA0GCSqG
# SIb3DQEBDAUAMFQxCzAJBgNVBAYTAkdCMRgwFgYDVQQKEw9TZWN0aWdvIExpbWl0
# ZWQxKzApBgNVBAMTIlNlY3RpZ28gUHVibGljIENvZGUgU2lnbmluZyBDQSBSMzYw
# HhcNMjYwMjA5MDAwMDAwWhcNMjkwNDIxMjM1OTU5WjBVMQswCQYDVQQGEwJVUzEU
# MBIGA1UECAwLQ29ubmVjdGljdXQxFzAVBgNVBAoMDkphc29uIEFsYmVyaW5vMRcw
# FQYDVQQDDA5KYXNvbiBBbGJlcmlubzCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCC
# AgoCggIBAPN6aN4B1yYWkI5b5TBj3I0VV/peETrHb6EY4BHGxt8Ap+eT+WpEpJyE
# tRYPxEmNJL3A38Bkg7mwzPE3/1NK570ZBCuBjSAn4mSDIgIuXZnvyBO9W1OQs5d6
# 7MlJLUAEufl18tOr3ST1DeO9gSjQSAE5Nql0QDxPnm93OZBon+Fz3CmE+z3MwAe2
# h4KdtRAnCqwM+/V7iBdbw+JOxolpx+7RVjGyProTENIG3pe/hKvPb501lf8uBAAD
# LdjZr5ip8vIWbf857Yw1Bu10nVI7HW3eE8Cl5//d1ribHlzTzQLfttW+k+DaFsKZ
# BBL56l4YAlIVRsrOiE1kdHYYx6IGrEA809R7+TZA9DzGqyFiv9qmJAbL4fDwetDe
# yIq+Oztz1LvEdy8Rcd0JBY+J4S0eDEFIA3X0N8VcLeAwabKb9AjulKXwUeqCJLvN
# 79CJ90UTZb2+I+tamj0dn+IKMEsJ4v4Ggx72sxFr9+6XziodtTg5Luf2xd6+Phha
# mOxF2px9LObhBLLEMyRsCHZIzVZOFKu9BpHQH7ufGB+Sa80Tli0/6LEyn9+bMYWi
# 2ttn6lLOPThXMiQaooRUq6q2u3+F4SaPlxVFLI7OJVMhar6nW6joBvELTJPmANSM
# jDSRFDfHRCdGbZsL/keELJNy+jZctF6VvxQEjFM8/bazu6qYhrA7AgMBAAGjggGJ
# MIIBhTAfBgNVHSMEGDAWgBQPKssghyi47G9IritUpimqF6TNDDAdBgNVHQ4EFgQU
# 6YF0o0D5AVhKHbVocr8GaSIBibAwDgYDVR0PAQH/BAQDAgeAMAwGA1UdEwEB/wQC
# MAAwEwYDVR0lBAwwCgYIKwYBBQUHAwMwSgYDVR0gBEMwQTA1BgwrBgEEAbIxAQIB
# AwIwJTAjBggrBgEFBQcCARYXaHR0cHM6Ly9zZWN0aWdvLmNvbS9DUFMwCAYGZ4EM
# AQQBMEkGA1UdHwRCMEAwPqA8oDqGOGh0dHA6Ly9jcmwuc2VjdGlnby5jb20vU2Vj
# dGlnb1B1YmxpY0NvZGVTaWduaW5nQ0FSMzYuY3JsMHkGCCsGAQUFBwEBBG0wazBE
# BggrBgEFBQcwAoY4aHR0cDovL2NydC5zZWN0aWdvLmNvbS9TZWN0aWdvUHVibGlj
# Q29kZVNpZ25pbmdDQVIzNi5jcnQwIwYIKwYBBQUHMAGGF2h0dHA6Ly9vY3NwLnNl
# Y3RpZ28uY29tMA0GCSqGSIb3DQEBDAUAA4IBgQAEIsm4xnOd/tZMVrKwi3doAXvC
# wOA/RYQnFJD7R/bSQRu3wXEK4o9SIefye18B/q4fhBkhNAJuEvTQAGfqbbpxow03
# J5PrDTp1WPCWbXKX8Oz9vGWJFyJxRGftkdzZ57JE00synEMS8XCwLO9P32MyR9Z9
# URrpiLPJ9rQjfHMb1BUdvaNayomm7aWLAnD+X7jm6o8sNT5An1cwEAob7obWDM6s
# X93wphwJNBJAstH9Ozs6LwISOX6sKS7CKm9N3Kp8hOUue0ZHAtZdFl6o5u12wy+z
# zieGEI50fKnN77FfNKFOWKlS6OJwlArcbFegB5K89LcE5iNSmaM3VMB2ADV1FEcj
# GSHw4lTg1Wx+WMAMdl/7nbvfFxJ9uu5tNiT54B0s+lZO/HztwXYQUczdsFon3pjs
# Nrsk9ZlalBi5SHkIu+F6g7tWiEv3rtVApmJRnLkUr2Xq2a4nbslUCt4jKs5UX4V1
# nSX8OM++AXoyVGO+iTj7z+pl6XE9Gw/Td6WKKKsxggMaMIIDFgIBATBoMFQxCzAJ
# BgNVBAYTAkdCMRgwFgYDVQQKEw9TZWN0aWdvIExpbWl0ZWQxKzApBgNVBAMTIlNl
# Y3RpZ28gUHVibGljIENvZGUgU2lnbmluZyBDQSBSMzYCEAec4OTRFH+FzTlzz3Yt
# N+swDQYJYIZIAWUDBAIBBQCggYQwGAYKKwYBBAGCNwIBDDEKMAigAoAAoQKAADAZ
# BgkqhkiG9w0BCQMxDAYKKwYBBAGCNwIBBDAcBgorBgEEAYI3AgELMQ4wDAYKKwYB
# BAGCNwIBFTAvBgkqhkiG9w0BCQQxIgQgCs7q66RWFhcT6NKH2ZMBQ7bXAa8ERo9q
# VpdbCanwz6wwDQYJKoZIhvcNAQEBBQAEggIAnqkHEzh8LUDivx7CsEAU4jUdq6X6
# zqiS8lv6BpryYeuflOB4WFHu9Te6dwIK+nQlJmwguNyrg1syJidP3q/RmBnobu6u
# PU0Iye38/kkwB2OiYfC/thdL/WvKtpKPzfmVR7XK77pQ50WzEsHbpAwlkqABhTAi
# NdDHkOaLeBrNc1YobSOhLHp8YWkQffvSw2idlrr1VuYDAdix96YkOC9ZuiOvAsAw
# Zd1P+cNORJdGFac7IIABHDhoQonnzWU3JGHPSIw/ARvx0lizt+Go8OU023DBIMof
# DJmJog5klQSoqEeLEwCqzrQPt7m/DouhsK8wmX5WW2g6ZeQYua76SW0dyU+7rLlR
# hziMSQUrNd08fE6XwVsq5aUQVTAmmK+bSX+yLBNRy5dRdeG81FLeWnvoZTpqo4nT
# +pYmxLfF+eI83RRpX9uLO8DV+lDosbdcSZK1GhqiLtTIOFG4WyLsrghMekvMjGVk
# 2dpjs0aG+TdJ97g0Wljin2ypoLsPWKrjJXr+gwXRLXT5jmYIOq+L1m/YZWcg9/tc
# UxHPzqka8zeSLPXT2M0M6ekR82hNoY41qlPFUB2HGlplc4hj0oPoi8YRJeMsxQ/j
# waWYCRQ+CYh0tetyZtP4flw0GsV1J1g+mhPwjQ3MOeyKn/Epoqgu+u0GQPCw9dpf
# V0eYrkkszrNQUYE=
# SIG # End signature block