helpers/bigleaf/BigleafHelpers.ps1
|
# ============================================================================= # Bigleaf Cloud Connect API Helpers for WhatsUpGoldPS # Provides functions to interact with the Bigleaf API (https://api.bigleaf.net/v2) # and produce dashboard-ready data for site, circuit, and device status. # # Authentication: HTTP Basic (username + password or API token as password). # Rate limit: 10 calls per minute per account. # # Typical workflow: # 1. Connect-BigleafAPI (authenticate and store session headers) # 2. Get-BigleafSites (retrieve site and circuit configuration) # 3. Get-BigleafSiteStatus (retrieve real-time status and risks) # 4. Get-BigleafDashboard (combine sites + status into dashboard data) # 5. Export-BigleafDashboardHtml (render an interactive HTML report) # ============================================================================= # --------------------------------------------------------------------------- # Connect-BigleafAPI # --------------------------------------------------------------------------- function Connect-BigleafAPI { <# .SYNOPSIS Authenticates to the Bigleaf Cloud Connect API and stores session headers. .DESCRIPTION Uses HTTP Basic authentication to validate credentials against the Bigleaf API. On success, stores the Base64-encoded authorization header in $global:BigleafHeaders for use by subsequent helper functions. .PARAMETER Credential PSCredential object containing the Bigleaf username and password/token. .PARAMETER BaseUri Base URI of the Bigleaf API. Defaults to https://api.bigleaf.net/v2. .EXAMPLE Connect-BigleafAPI -Credential (Get-Credential) .EXAMPLE $cred = New-Object PSCredential("user@example.com", (ConvertTo-SecureString "token" -AsPlainText -Force)) Connect-BigleafAPI -Credential $cred #> [CmdletBinding()] param( [Parameter(Mandatory)] [pscredential]$Credential, [Parameter()] [string]$BaseUri = "https://api.bigleaf.net/v2" ) $username = $Credential.UserName $password = $Credential.GetNetworkCredential().Password $pair = "${username}:${password}" $bytes = [System.Text.Encoding]::UTF8.GetBytes($pair) $encoded = [Convert]::ToBase64String($bytes) $password = $null; $pair = $null $headers = @{ Authorization = "Basic $encoded" Accept = "application/json" } # Validate credentials by calling the token introspection endpoint try { $uri = "$BaseUri/token" $response = Invoke-RestMethod -Uri $uri -Headers $headers -Method Get -ErrorAction Stop Write-Host "Connected to Bigleaf API as $($response.login) ($($response.full_name))" -ForegroundColor Green } catch { throw "Failed to authenticate to Bigleaf API at $BaseUri - $($_.Exception.Message)" } $global:BigleafHeaders = $headers $global:BigleafBaseUri = $BaseUri.TrimEnd('/') } # --------------------------------------------------------------------------- # Disconnect-BigleafAPI # --------------------------------------------------------------------------- function Disconnect-BigleafAPI { <# .SYNOPSIS Clears stored Bigleaf API session data. .EXAMPLE Disconnect-BigleafAPI #> [CmdletBinding()] param() $global:BigleafHeaders = $null $global:BigleafBaseUri = $null Write-Host "Disconnected from Bigleaf API." -ForegroundColor Yellow } # --------------------------------------------------------------------------- # Invoke-BigleafAPI (internal helper) # --------------------------------------------------------------------------- function Invoke-BigleafAPI { <# .SYNOPSIS Sends a request to the Bigleaf API with automatic pagination. .DESCRIPTION Handles paginated GET requests to the Bigleaf API, automatically fetching subsequent pages until all records are retrieved. Respects the 10 calls/minute rate limit with a configurable delay. .PARAMETER Endpoint API endpoint path (e.g. "/sites", "/status"). .PARAMETER QueryParameters Optional hashtable of additional query parameters. .PARAMETER PageSize Number of records per page. Defaults to 100. .PARAMETER SingleObject If set, returns the first (non-array) response without pagination. .EXAMPLE Invoke-BigleafAPI -Endpoint "/sites" .EXAMPLE Invoke-BigleafAPI -Endpoint "/sites/123/risks" -SingleObject #> [CmdletBinding()] param( [Parameter(Mandatory)] [string]$Endpoint, [Parameter()] [hashtable]$QueryParameters = @{}, [Parameter()] [int]$PageSize = 100, [Parameter()] [switch]$SingleObject ) if (-not $global:BigleafHeaders) { throw "Not connected to Bigleaf API. Run Connect-BigleafAPI first." } $baseUrl = "$($global:BigleafBaseUri)$Endpoint" if ($SingleObject) { $queryParts = @() foreach ($key in $QueryParameters.Keys) { $queryParts += "$key=$([uri]::EscapeDataString($QueryParameters[$key]))" } $url = if ($queryParts.Count -gt 0) { "$baseUrl`?$($queryParts -join '&')" } else { $baseUrl } try { return Invoke-RestMethod -Uri $url -Headers $global:BigleafHeaders -Method Get -ErrorAction Stop } catch { if ($_.Exception.Response.StatusCode -eq 429) { $retryAfter = 60 try { $retryAfter = [int]$_.Exception.Response.Headers['Retry-After'] } catch {} Write-Warning "Rate limited. Waiting ${retryAfter}s before retrying..." Start-Sleep -Seconds $retryAfter return Invoke-RestMethod -Uri $url -Headers $global:BigleafHeaders -Method Get -ErrorAction Stop } throw } } # Paginated retrieval $allResults = @() $page = 1 do { $params = @{ page = $page; count = $PageSize } foreach ($key in $QueryParameters.Keys) { $params[$key] = $QueryParameters[$key] } $queryParts = @() foreach ($key in $params.Keys) { $queryParts += "$key=$([uri]::EscapeDataString($params[$key]))" } $url = "$baseUrl`?$($queryParts -join '&')" try { $response = Invoke-RestMethod -Uri $url -Headers $global:BigleafHeaders -Method Get -ErrorAction Stop } catch { if ($_.Exception.Response.StatusCode -eq 429) { $retryAfter = 60 try { $retryAfter = [int]$_.Exception.Response.Headers['Retry-After'] } catch {} Write-Warning "Rate limited on page $page. Waiting ${retryAfter}s before retrying..." Start-Sleep -Seconds $retryAfter $response = Invoke-RestMethod -Uri $url -Headers $global:BigleafHeaders -Method Get -ErrorAction Stop } else { throw } } if ($response -is [array]) { $allResults += $response if ($response.Count -lt $PageSize) { break } } else { $allResults += $response break } $page++ } while ($true) return $allResults } # --------------------------------------------------------------------------- # Get-BigleafSites # --------------------------------------------------------------------------- function Get-BigleafSites { <# .SYNOPSIS Retrieves all Bigleaf sites with circuit, CPE, and LAN network details. .DESCRIPTION Returns an array of site objects containing site configuration, circuit definitions, LAN networks, and CPE device information. .PARAMETER SiteId Optional site ID to retrieve a specific site. .EXAMPLE Get-BigleafSites .EXAMPLE Get-BigleafSites -SiteId 12345 #> [CmdletBinding()] param( [Parameter()] [int]$SiteId ) if ($SiteId) { return Invoke-BigleafAPI -Endpoint "/sites/$SiteId" -SingleObject } return Invoke-BigleafAPI -Endpoint "/sites" } # --------------------------------------------------------------------------- # Get-BigleafSiteStatus # --------------------------------------------------------------------------- function Get-BigleafSiteStatus { <# .SYNOPSIS Retrieves real-time status for all sites or a specific site. .DESCRIPTION Returns site status including device status, circuit status overview, and risk overview for each site. .PARAMETER SiteId Optional site ID to filter status to a single site. .EXAMPLE Get-BigleafSiteStatus .EXAMPLE Get-BigleafSiteStatus -SiteId 12345 #> [CmdletBinding()] param( [Parameter()] [int]$SiteId ) $params = @{} if ($SiteId) { $params['site_id'] = $SiteId } return Invoke-BigleafAPI -Endpoint "/status" -QueryParameters $params } # --------------------------------------------------------------------------- # Get-BigleafCircuitStatus # --------------------------------------------------------------------------- function Get-BigleafCircuitStatus { <# .SYNOPSIS Retrieves circuit status for a specific site. .DESCRIPTION Returns detailed circuit status (up, normal, degraded, down) for each WAN circuit configured on the specified site. .PARAMETER SiteId The site ID to retrieve circuit status for. .EXAMPLE Get-BigleafCircuitStatus -SiteId 12345 #> [CmdletBinding()] param( [Parameter(Mandatory)] [int]$SiteId ) return Invoke-BigleafAPI -Endpoint "/sites/$SiteId/circuit-status" } # --------------------------------------------------------------------------- # Get-BigleafDeviceStatus # --------------------------------------------------------------------------- function Get-BigleafDeviceStatus { <# .SYNOPSIS Retrieves device status for a specific site. .DESCRIPTION Returns the current status (provision, pending, up, down) of CPE and switch devices at the specified site. .PARAMETER SiteId The site ID to retrieve device status for. .EXAMPLE Get-BigleafDeviceStatus -SiteId 12345 #> [CmdletBinding()] param( [Parameter(Mandatory)] [int]$SiteId ) return Invoke-BigleafAPI -Endpoint "/sites/$SiteId/device-status" } # --------------------------------------------------------------------------- # Get-BigleafSiteRisks # --------------------------------------------------------------------------- function Get-BigleafSiteRisks { <# .SYNOPSIS Retrieves risks for a specific site. .DESCRIPTION Returns a list of all risks for the site, ordered by risk_level and last_at, including circuit-level risk details and recommended actions. .PARAMETER SiteId The site ID to retrieve risks for. .EXAMPLE Get-BigleafSiteRisks -SiteId 12345 #> [CmdletBinding()] param( [Parameter(Mandatory)] [int]$SiteId ) return Invoke-BigleafAPI -Endpoint "/sites/$SiteId/risks" } # --------------------------------------------------------------------------- # Get-BigleafAccounts # --------------------------------------------------------------------------- function Get-BigleafAccounts { <# .SYNOPSIS Retrieves all Bigleaf user accounts. .DESCRIPTION Returns account details including login, email, name, timezone, and alert/report configuration settings. .EXAMPLE Get-BigleafAccounts #> [CmdletBinding()] param() return Invoke-BigleafAPI -Endpoint "/accounts" } # --------------------------------------------------------------------------- # Get-BigleafCompanies # --------------------------------------------------------------------------- function Get-BigleafCompanies { <# .SYNOPSIS Retrieves all Bigleaf companies. .DESCRIPTION Returns company details including company name, role, provider relationships, and sensitivity configuration. .EXAMPLE Get-BigleafCompanies #> [CmdletBinding()] param() return Invoke-BigleafAPI -Endpoint "/companies" } # --------------------------------------------------------------------------- # Get-BigleafMetadata # --------------------------------------------------------------------------- function Get-BigleafMetadata { <# .SYNOPSIS Retrieves Bigleaf API metadata for health checks. .DESCRIPTION Returns API service information including version, environment, and commit reference. Useful as a health check endpoint. .EXAMPLE Get-BigleafMetadata #> [CmdletBinding()] param() # Metadata endpoint does not require auth $uri = if ($global:BigleafBaseUri) { "$($global:BigleafBaseUri)/metadata" } else { "https://api.bigleaf.net/v2/metadata" } return Invoke-RestMethod -Uri $uri -Method Get -ErrorAction Stop } # --------------------------------------------------------------------------- # Get-BigleafDashboard # --------------------------------------------------------------------------- function Get-BigleafDashboard { <# .SYNOPSIS Builds enriched dashboard data combining sites, status, and risks. .DESCRIPTION Retrieves all sites and their real-time status, then produces a flat array of dashboard rows. Each row represents a site with its circuits, devices, risk summary, and optional WhatsUp Gold device enrichment. .EXAMPLE Connect-BigleafAPI -Credential (Get-Credential) $dashboard = Get-BigleafDashboard $dashboard | Format-Table SiteName, SiteStatus, CircuitSummary, HighestRisk .EXAMPLE $dashboard = Get-BigleafDashboard $dashboard | Where-Object { $_.SiteStatus -ne 'healthy' } #> [CmdletBinding()] param() Write-Host "Retrieving Bigleaf sites..." -ForegroundColor Cyan $sites = Get-BigleafSites if (-not $sites) { Write-Warning "No sites found." return @() } Write-Host " Found $($sites.Count) site(s)." -ForegroundColor Green Write-Host "Retrieving site status..." -ForegroundColor Cyan $statusList = Get-BigleafSiteStatus $statusIndex = @{} if ($statusList) { foreach ($s in $statusList) { $statusIndex[$s.site_id] = $s } } Write-Host " Retrieved status for $($statusIndex.Count) site(s)." -ForegroundColor Green # Build a WUG device index if connected to WhatsUp Gold $wugDeviceIndex = @{} if ($global:WUGBearerHeaders) { try { $wugDevices = Get-WUGDevice -View overview foreach ($dev in $wugDevices) { if ($dev.networkAddress) { $wugDeviceIndex[$dev.networkAddress] = $dev } if ($dev.hostName) { $wugDeviceIndex[$dev.hostName] = $dev } } Write-Verbose "Indexed $($wugDeviceIndex.Count) WUG devices for enrichment." } catch { Write-Warning "Could not retrieve WUG devices for enrichment: $($_.Exception.Message)" } } $dashboard = @() foreach ($site in $sites) { $siteId = $site.site_id $status = if ($statusIndex.ContainsKey($siteId)) { $statusIndex[$siteId] } else { $null } # Circuit summary from site config $circuitNames = @() $circuitTypes = @() $totalDownBw = 0 $totalUpBw = 0 if ($site.circuits) { foreach ($c in $site.circuits) { $circuitNames += $c.circuit_name $circuitTypes += $c.circuit_type $totalDownBw += $c.download_bandwidth $totalUpBw += $c.upload_bandwidth } } $circuitCount = if ($site.circuits) { $site.circuits.Count } else { 0 } # Circuit status summary from status endpoint $circuitStatuses = @() if ($status -and $status.circuits) { foreach ($cs in $status.circuits) { $circuitStatuses += "$($cs.wan_index):$($cs.status)" } } # Device status summary $deviceStatuses = @() if ($status -and $status.devices) { foreach ($ds in $status.devices) { $role = if ($ds.cpe_role) { $ds.cpe_role } else { $ds.target_type } $deviceStatuses += "$role=$($ds.status)" } } # Risk summary from status endpoint $risks = if ($status -and $status.risks) { $status.risks } else { @() } $highestRisk = "healthy" $riskLevels = @("site-outage", "high", "medium", "low", "healthy") foreach ($r in $risks) { $rLevel = if ($r.risk_level) { $r.risk_level } else { "healthy" } if ($riskLevels.IndexOf($rLevel) -lt $riskLevels.IndexOf($highestRisk)) { $highestRisk = $rLevel } } $riskCount = $risks.Count # LAN network summary $lanNetworks = @() if ($site.lan_networks) { foreach ($ln in $site.lan_networks) { $lanNetworks += $ln.network } } # CPE info $cpeSerials = @() $cpeIPs = @() if ($site.cpe) { foreach ($cpe in $site.cpe) { $cpeSerials += $cpe.cpe_serial if ($cpe.config_ip) { $cpeIPs += $cpe.config_ip } } } # Site status $siteStatus = if ($status) { $status.site_status } else { "unknown" } $row = [ordered]@{ SiteId = $siteId SiteName = $site.site_name CompanyId = $site.company_id CompanyName = $site.company_name SiteStatus = $siteStatus HighestRisk = $highestRisk RiskCount = $riskCount ServiceName = if ($site.service) { $site.service.service_name } else { "" } ServiceBandwidth = if ($site.service) { $site.service.bandwidth } else { 0 } ServiceBandwidthUp = if ($site.service) { $site.service.bandwidth_up } else { 0 } AvailabilityConfig = $site.availability_config PrimaryPop = $site.primary_pop SecondaryPop = $site.secondary_pop CircuitCount = $circuitCount CircuitNames = ($circuitNames -join ", ") CircuitTypes = ($circuitTypes -join ", ") TotalDownloadBW = $totalDownBw TotalUploadBW = $totalUpBw CircuitStatusSummary = ($circuitStatuses -join ", ") DeviceStatusSummary = ($deviceStatuses -join ", ") LANNetworks = ($lanNetworks -join ", ") CPESerials = ($cpeSerials -join ", ") CPEIPs = ($cpeIPs -join ", ") ProvisionedOn = if ($site.provisioned_on) { $site.provisioned_on } else { "" } ServiceIn = if ($site.service_in) { $site.service_in } else { "" } } # Enrich with WUG device data if available (match on CPE IPs) $wugDev = $null foreach ($ip in $cpeIPs) { if ($wugDeviceIndex.ContainsKey($ip)) { $wugDev = $wugDeviceIndex[$ip] break } } if (-not $wugDev -and $wugDeviceIndex.ContainsKey($site.site_name)) { $wugDev = $wugDeviceIndex[$site.site_name] } if ($wugDev) { $row["WUGDeviceId"] = $wugDev.id $row["WUGDeviceName"] = $wugDev.name $row["WUGHostName"] = $wugDev.hostName $row["WUGBestState"] = $wugDev.bestState $row["WUGWorstState"] = $wugDev.worstState $row["WUGActiveMonitors"] = $wugDev.totalActiveMonitors $row["WUGMonitorsDown"] = $wugDev.totalActiveMonitorsDown } else { $row["WUGDeviceId"] = "" $row["WUGDeviceName"] = "" $row["WUGHostName"] = "" $row["WUGBestState"] = "" $row["WUGWorstState"] = "" $row["WUGActiveMonitors"] = "" $row["WUGMonitorsDown"] = "" } $dashboard += [PSCustomObject]$row } return $dashboard } # --------------------------------------------------------------------------- # Export-BigleafDashboardHtml # --------------------------------------------------------------------------- function Export-BigleafDashboardHtml { <# .SYNOPSIS Renders Bigleaf dashboard data into a self-contained HTML file. .DESCRIPTION Takes the output of Get-BigleafDashboard and generates a Bootstrap-based HTML report with sortable, searchable, and exportable tables. Uses colour-coded status indicators for site and circuit health. .PARAMETER DashboardData Array of objects from Get-BigleafDashboard. .PARAMETER OutputPath File path for the output HTML file. .PARAMETER ReportTitle Title shown in the report header. Defaults to "Bigleaf Dashboard". .PARAMETER TemplatePath Optional path to a custom HTML template. If omitted, uses the built-in template at helpers/bigleaf/Bigleaf-Dashboard-Template.html. .EXAMPLE $dashboard = Get-BigleafDashboard Export-BigleafDashboardHtml -DashboardData $dashboard -OutputPath "$env:TEMP\Bigleaf-Dashboard.html" .EXAMPLE $dashboard = Get-BigleafDashboard Export-BigleafDashboardHtml -DashboardData $dashboard -OutputPath "C:\Reports\bigleaf.html" -ReportTitle "Bigleaf WAN Status" #> [CmdletBinding()] param( [Parameter(Mandatory)]$DashboardData, [Parameter(Mandatory)][string]$OutputPath, [string]$ReportTitle = "Bigleaf Dashboard", [string]$TemplatePath ) if (-not $TemplatePath) { $TemplatePath = Join-Path $PSScriptRoot "Bigleaf-Dashboard-Template.html" } if (-not (Test-Path $TemplatePath)) { throw "HTML template not found at $TemplatePath" } # Build column definitions for bootstrap-table $firstObj = $DashboardData | Select-Object -First 1 $columns = @() foreach ($prop in $firstObj.PSObject.Properties) { $col = @{ field = $prop.Name title = ($prop.Name -creplace '([A-Z])', ' $1').Trim() sortable = $true searchable = $true } if ($prop.Name -eq 'SiteStatus') { $col.formatter = 'formatSiteStatus' } if ($prop.Name -eq 'HighestRisk') { $col.formatter = 'formatRiskLevel' } if ($prop.Name -match 'WUGBestState|WUGWorstState') { $col.formatter = 'formatWugState' } $columns += $col } $columnsJson = $columns | ConvertTo-Json -Depth 5 -Compress $dataJson = $DashboardData | ConvertTo-Json -Depth 5 -Compress $tableConfig = @" columns: $columnsJson, data: $dataJson "@ $html = Get-Content -Path $TemplatePath -Raw $html = $html -replace 'replaceThisHere', $tableConfig $html = $html -replace 'ReplaceYourReportNameHere', $ReportTitle $html = $html -replace 'ReplaceUpdateTimeHere', (Get-Date).ToString("yyyy-MM-dd HH:mm:ss") Set-Content -Path $OutputPath -Value $html -Encoding UTF8 Write-Verbose "Bigleaf Dashboard HTML written to $OutputPath" } # SIG # Begin signature block # MIIr+wYJKoZIhvcNAQcCoIIr7DCCK+gCAQExDzANBglghkgBZQMEAgEFADB5Bgor # BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG # KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCBGpNJOvKYhNYZP # LK5BmLq/Pz1NA+ECB6gHUAkQdf0iK6CCJQ0wggVvMIIEV6ADAgECAhBI/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 # BCDEVMS0ltDsdZ1dY+/Fy/Kn970ZEGHyO8V8qJTgOdj2+DANBgkqhkiG9w0BAQEF # AASCAgCw8jfC3rQF27GOS2ob+zMxE15uaW5nSFW0a6hdfEFUWNPvTbfUvXFrMO5O # mOMq6ZIl+35fU9Z0TWHLyax+IpExhvPiuuqrFW/uDnKBNIDcCjwMbUzpNUpEFU43 # 9sbGiWLOe7lXVuk+EGKQZK7X916BA4/zGXnf3NfaqLBURuI6ETNz493xnPtU/LwW # wB/20IOn5Qph9/jnisOtj07FtSdy2iwYdGBwoRxLhDuAR+4B1vo4DingGBFrYMGL # T/VkQqfUjwUImVK8eaV49q73XfR471NvACSROil2RiVkIePHZfqUCD1nbu7LbAWm # a9wyifjFDY71oVJo0y1l2s7k3moCngygKM72vz0Ore5xgSeKgRpdHeUIBLKSQjKJ # emO9Is2Bpae18ZWtSvE4IhMQH4467X0O6WCbCkU2YDlgE/OlrOh+GCC9o3H9ofsh # aG5tPzMzBhcj6tdRXmB9VPhVyNELpPsTynb0btvsWRutPaaLux3gqDK3Gmqo49mF # WcBvkDVEbG+9I03o3khx4vxp0jpse760R5+HAmgRJBruOSfMFCBqKNAQnOWgYOfa # Lon9tWseyt0gubIU7vYaG+UI2EqsP4+FNviSrDFP1MtrNBAt6fAcBtqhf459SBfk # 0C6FsgGv8Lls72PD6/PHkQWL4fUHCU3uM7kXbvn7gLLhRqke3aGCAyYwggMiBgkq # hkiG9w0BCQYxggMTMIIDDwIBATB9MGkxCzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5E # aWdpQ2VydCwgSW5jLjFBMD8GA1UEAxM4RGlnaUNlcnQgVHJ1c3RlZCBHNCBUaW1l # U3RhbXBpbmcgUlNBNDA5NiBTSEEyNTYgMjAyNSBDQTECEAqA7xhLjfEFgtHEdqeV # dGgwDQYJYIZIAWUDBAIBBQCgaTAYBgkqhkiG9w0BCQMxCwYJKoZIhvcNAQcBMBwG # CSqGSIb3DQEJBTEPFw0yNjA0MjAwMDE2MzRaMC8GCSqGSIb3DQEJBDEiBCDnV6LG # GTWIVxWCBvHIebJwN6By1Xtb0fRKPzRpeLlFbjANBgkqhkiG9w0BAQEFAASCAgA9 # tszn6Bi095/O5PZsC91wi5PNrQ5bFRmP3XH0jajeY2+rJR3rA/4RFYpU/mHwFtyc # hBYuPdM5Lr/AZyJq635NYw5tuNldonR01+F+AacS7d0XqfsmO9bKs45xrrF84Pm1 # bipwwf8YHVYTZ7UcoSthIQR2wIWZopFJ4jQsMEeaMr1B6kR138C8cov6yEJev1Ub # R4dHNJUD+JJYJTK3XOianyiZRgbSzXmJgMF1ENWugCi18/IFXBXDIjPTL/nhU1G3 # Sc8Ykj22cyo2HTucpE3mseEXQUzd+F/9CFcDdeQqWYpMFdxrYSFngCw8YlN0S+e0 # /9HyE45xRkljSQ9C3IEEpkao9E2iy8p2yTIj7XxxZehtFLi7A1craX05VxtrTe0z # hnlvjQTzO+Ru9DFcvLyxDT397V/o9s9xeCCXJ06fiNjiARYdB5fikrxtPvqnkFnQ # gqf609uZlEA4WsUI4zDlzn8kO25NtdNEx1zWVJB21U5ZK02E2yVwDSh5IG+s3CpI # pv4zlMp72i5lRuJksOvc0h+2MTwVE5/nqXt558P/EhMmlreGQe2auAwVolnSU1Ub # 8WF6GYEg+5+hGJ424nKPL3nO2qnZ+ZqYFt38ssJEnGKYredsN0Bi7jFAmnCwzsNY # 0pk5mgBg6BuQROq4KlVDB9P/LCNExL7fYodFCuXp+g== # SIG # End signature block |