modules/AzStack.Insights/rules/MocArb.ArbApplianceStatus.ps1
|
<#
.SYNOPSIS Validate that the Arc Resource Bridge appliance is online in Azure. .DESCRIPTION This script uses az CLI with managed identity to query Azure Resource Manager and verify the Arc Resource Bridge appliance reports a healthy/running status. #> [CmdletBinding()] param() # Import localization strings from the locale directory # this will natively import the psd1 file that has the same name as the script # and the locale folder that matches the current culture of the user running the script Import-LocalizedData -BindingVariable 'localizedData' -BaseDirectory "$PSScriptRoot\locale" -UICulture $PSUICulture $insightRule = Initialize-InsightRule -Id $localizedData.Id -Properties $localizedData.Insight <# START INSIGHT RULE LOGIC #> try { # This rule requires Azure connectivity to query ARB appliance status via az CLI. # Disconnected clusters cannot reach Azure endpoints, so skip gracefully. if ($Global:CSSTools_AzsSupport.EnvironmentInfo.DisconnectedOps) { Write-InsightLog -Level Informational -Message "This insight is not applicable to disconnected clusters" $insightRule.Status = [InsightStatus]::INFO $insightRule.Duration = New-TimeSpan -Start $insightRule.OccurrenceTimeUTC -End $([System.DateTime]::UtcNow) Write-InsightEvent -Insight $insightRule return $insightRule } # Verify az CLI is available $azPath = Get-Command -Name 'az' -ErrorAction Ignore if (-not $azPath) { Write-InsightLog -Level:Warning -Message "az CLI not found on $env:COMPUTERNAME" $insightRule.Status = [InsightStatus]::WARNING $insightRule.ErrorMessage = $localizedData.Insight.ErrorMessage.NoAzCli } else { # Login using managed identity (2>$null suppresses stderr warnings from az CLI) az login --identity --only-show-errors 2>$null | Out-Null if ($LASTEXITCODE -ne 0) { throw "az login --identity failed (exit code $LASTEXITCODE)." } # Capture the active subscription BEFORE we do any `az account set` # so the outer finally can restore it. Without this, subsequent # validators in the same runspace inherit whichever sub we last # switched into (the bridge sub on the success path, the last enum # sub on the fallback path). Reviewer-flagged: PR #15849843. $originalSub = (az account show --query id -o tsv 2>$null) if ([string]::IsNullOrWhiteSpace($originalSub)) { $originalSub = $null } # Discover the ARB appliance across every subscription the managed # identity has read access to. # # Why Resource Graph is the primary path: # `az login --identity` in a fresh PowerShell session only # authenticates the MI against the VM's home subscription, so # `az account list` returns just that one sub even when the MI has # role assignments in many others. Iterating with `az account set` # over that incomplete list silently misses the sub that owns the # appliance. This was the observed failure on LH-21 node U05 where # the appliance lives in sub 7f2083a5... but `az account list` # returned only the home sub fc0d71a1... . # # `az graph query` hits ARM Resource Graph directly with the MI # token, which evaluates RBAC across ALL subscriptions the # principal can read. One call, no `az account` profile state, no # alphabetical ordering hazards. # # Why we keep the per-sub loop as a fallback: # `resource-graph` is an az CLI extension. It is installed in the # CSSTools-bundled az on production nodes today, but we cannot # assume it is present on every node forever, and Resource Graph # has occasional transient 5xx failures. If the primary path # produces no result for any reason, we fall back to enumerating # `az account list` subs. That path is degraded (it misses subs # the MI hasn't been logged into) but it is strictly better than # nothing. $allAppliances = @() $discoveryPath = $null # Primary path: Resource Graph # # Retry-on-zero rationale (added 2026-05-23, LH28 incident): # az graph query occasionally returns exit 0 with an empty data # array even when the appliance exists. Manual re-runs seconds # later succeed. Without retry this surfaces as a NoAppliance # FAILURE on a perfectly healthy cluster. We retry up to 3 times # with exponential backoff (3s / 6s / 12s = 21s worst case) before # treating zero as authoritative. Each retry writes to host so the # operator sees the transient in real time, above the final # summary table. $graphQuery = "resources | where type =~ 'microsoft.resourceconnector/appliances' | project id, name, resourceGroup, subscriptionId" $graphJson = az graph query -q $graphQuery --first 1000 -o json 2>$null $graphExitCode = $LASTEXITCODE if ($graphExitCode -eq 0 -and -not [string]::IsNullOrWhiteSpace($graphJson)) { try { $graphResult = $graphJson | ConvertFrom-Json $resultCount = if ($graphResult.data) { @($graphResult.data).Count } else { 0 } if ($resultCount -eq 0) { # Zero-response diagnostic data capture (emission deferred # to AFTER the retry loop so a successful retry doesn't # leave a misleading WARNING trace alongside the recovery # message). Reviewer-flagged: PR #15849843. # total_records / skip_token reveal paging anomalies # (Graph occasionally reports data=[] with # total_records>0 — that's a partial-response bug, # not a real absence). # ARM list on the current sub is the ground-truth # cross-check: if ARM sees the appliance but Graph # doesn't, it's Graph indexing lag, not state. # Current sub captured in case context drifted # mid-run. $totalRecords = if ($null -ne $graphResult.total_records) { $graphResult.total_records } else { '<unset>' } $skipToken = if ($graphResult.skip_token) { 'present' } else { 'null' } $currentSub = (az account show --query id -o tsv 2>$null) if ([string]::IsNullOrWhiteSpace($currentSub)) { $currentSub = '<unknown>' } $armCount = -1 $armCheckJson = az resource list --resource-type 'Microsoft.ResourceConnector/appliances' -o json 2>$null if ($LASTEXITCODE -eq 0 -and -not [string]::IsNullOrWhiteSpace($armCheckJson)) { try { $armCount = @($armCheckJson | ConvertFrom-Json).Count } catch { $armCount = -1 } } $initialGraphJson = $graphJson $retryDelays = @(3, 6, 12) for ($attempt = 1; $attempt -le $retryDelays.Count; $attempt++) { $delay = $retryDelays[$attempt - 1] Write-Host "[$env:COMPUTERNAME] ARB discovery: Resource Graph returned zero results, retrying in ${delay}s (attempt $attempt of $($retryDelays.Count))..." -ForegroundColor Yellow Write-InsightLog -Level:Warning -Message "ARB discovery on $env:COMPUTERNAME: Resource Graph returned zero results. Retry $attempt of $($retryDelays.Count) after ${delay}s." Start-Sleep -Seconds $delay $graphJson = az graph query -q $graphQuery --first 1000 -o json 2>$null if ($LASTEXITCODE -ne 0 -or [string]::IsNullOrWhiteSpace($graphJson)) { continue } $graphResult = $graphJson | ConvertFrom-Json $resultCount = if ($graphResult.data) { @($graphResult.data).Count } else { 0 } if ($resultCount -gt 0) { Write-Host "[$env:COMPUTERNAME] ARB discovery: Resource Graph returned $resultCount appliance(s) on retry $attempt." -ForegroundColor Green Write-InsightLog -Level:Informational -Message "ARB discovery on $env:COMPUTERNAME: Resource Graph recovered on retry $attempt with $resultCount appliance(s)." break } } if ($resultCount -eq 0) { # Retries exhausted — NOW emit the zero-response # diagnostic captured from the first attempt. Raw # JSON payloads ($initialGraphJson, $armCheckJson) # are intentionally omitted from the persisted log # message to keep ingestion-friendly: the structured # counts (total_records, skip_token, currentSub, # armCount) carry the actionable signal. Raw # responses remain in-memory ($initialGraphJson, # $armCheckJson) for a debugger-attached engineer to # inspect. PR-Assistant-flagged: PR #15849843. Write-Host "[$env:COMPUTERNAME] ARB discovery: Graph returned zero (total_records=$totalRecords, skip_token=$skipToken); current sub $currentSub reports $armCount appliance(s) via ARM list." -ForegroundColor Yellow Write-InsightLog -Level:Warning -Message "ARB discovery zero-response diagnostic on $env:COMPUTERNAME : total_records=$totalRecords skip_token=$skipToken currentSub=$currentSub armListCountInCurrentSub=$armCount" } } if ($resultCount -gt 0) { $allAppliances = @($graphResult.data) $discoveryPath = "Resource Graph ($($allAppliances.Count) appliance(s) across $((@($allAppliances | Select-Object -ExpandProperty subscriptionId -Unique)).Count) subscription(s))" } else { $discoveryPath = "Resource Graph (zero results after 3 retries)" } } catch { Write-InsightLog -Level:Warning -Message "Failed to parse Resource Graph response on $env:COMPUTERNAME : $_" } } else { Write-InsightLog -Level:Informational -Message "az graph query failed (exit code $graphExitCode) on $env:COMPUTERNAME. Falling back to per-subscription enumeration." } # Fallback path: per-subscription enumeration (degraded — only sees # subs the MI is currently logged into, but better than no fallback) if ($allAppliances.Count -eq 0) { $subListJson = az account list --query "[?state=='Enabled'].id" -o json 2>$null $enabledSubs = @() if ($LASTEXITCODE -eq 0 -and -not [string]::IsNullOrWhiteSpace($subListJson)) { $enabledSubs = @($subListJson | ConvertFrom-Json) } if ($enabledSubs.Count -eq 0) { Write-InsightLog -Level:Warning -Message "az account list returned no Enabled subscriptions on $env:COMPUTERNAME. The appliance lookup will proceed using the default subscription." $enabledSubs = @($null) } foreach ($candidateSub in $enabledSubs) { if ($candidateSub) { az account set -s $candidateSub 2>$null | Out-Null if ($LASTEXITCODE -ne 0) { Write-InsightLog -Level:Warning -Message "az account set -s '$candidateSub' failed (exit code $LASTEXITCODE) on $env:COMPUTERNAME. Skipping this subscription." continue } } $allJson = az resource list --resource-type 'Microsoft.ResourceConnector/appliances' --query "[].{id:id,name:name,resourceGroup:resourceGroup,subscriptionId:'$candidateSub'}" -o json 2>$null if ($LASTEXITCODE -eq 0 -and -not [string]::IsNullOrWhiteSpace($allJson)) { $subAppliances = @($allJson | ConvertFrom-Json) if ($subAppliances.Count -gt 0) { $allAppliances += $subAppliances } } } if ($allAppliances.Count -gt 0) { $discoveryPath = "per-subscription fallback ($($allAppliances.Count) appliance(s) across $($enabledSubs.Count) sub(s))" } } if ($discoveryPath) { Write-InsightLog -Level:Informational -Message "ARB discovery on $env:COMPUTERNAME used $discoveryPath" } # Primary key: local cluster name from Failover Cluster (authoritative on-box identity) $localClusterName = $null try { $localClusterName = (Get-Cluster -ErrorAction Stop).Name } catch { Write-InsightLog -Level:Warning -Message "Could not resolve local cluster name via Get-Cluster on $env:COMPUTERNAME : $_" } # Secondary key: ECE management cluster name (may be wrong/stale on some clusters; treated as advisory) $eceClusterName = $null try { $eceClusterName = Get-AzsSupportEceManagementClusterName -ErrorAction Stop } catch { Write-InsightLog -Level:Informational -Message "Get-AzsSupportEceManagementClusterName failed on $env:COMPUTERNAME, continuing with local cluster name only: $_" } $resources = @() $matchKey = $null $ambiguousWarningSet = $false if ($allAppliances.Count -gt 0) { if ($localClusterName) { # Strict suffix match only. The earlier `-like "$X-*"` fallback # was loose enough to cross-match siblings (e.g. `contoso-prod` # would match `contoso-prod-east-arcbridge`). The Graph query # already filters by resource type, so we don't need a tolerant # name net; the single-appliance subscription fallback below # handles the unambiguous case where naming differs from the # `<cluster>-arcbridge` convention. Reviewer-flagged: PR #15849843. $resources = @($allAppliances | Where-Object { $_.name -eq "$localClusterName-arcbridge" }) if ($resources.Count -gt 0) { $matchKey = "local cluster suffix '$localClusterName-arcbridge'" } } if ($resources.Count -eq 0 -and $eceClusterName -and $eceClusterName -ne $localClusterName) { $resources = @($allAppliances | Where-Object { $_.name -eq "$eceClusterName-arcbridge" }) if ($resources.Count -gt 0) { $matchKey = "ECE management cluster suffix '$eceClusterName-arcbridge'" } } # Exact-name match returned multiple appliances → ambiguous. ARM # enforces uniqueness within (subscription, resource group, type, # name), so the same `<cluster>-arcbridge` name CAN exist in # different resource groups across the tenant when ARG fans out # across subs accessible to the MI. Rare in practice but treated # as ambiguous instead of silently selecting the first. # PR-Assistant-flagged: PR #15849843. if ($resources.Count -gt 1) { $applianceNames = ($resources | ForEach-Object { "$($_.name) (rg=$($_.resourceGroup), sub=$($_.subscriptionId))" }) -join ', ' $expected = if ($matchKey -like '*local cluster*') { $localClusterName } else { $eceClusterName } Write-InsightLog -Level:Warning -Message "Found $($resources.Count) appliance(s) ($applianceNames) matching cluster name '$expected-arcbridge' on $env:COMPUTERNAME. Not selecting an arbitrary appliance." $ambiguousWarningSet = $true $insightRule.Status = [InsightStatus]::WARNING $insightRule.ErrorMessage = ($localizedData.Insight.ErrorMessage.AmbiguousApplianceMultiMatch -f $resources.Count, $applianceNames, $expected) $insightRule.Properties = @([PSCustomObject]@{ Node = $env:COMPUTERNAME LocalClusterName = $localClusterName EceClusterName = $eceClusterName ExpectedName = "$expected-arcbridge" AppliancesFound = $applianceNames MatchKey = $matchKey }) # Clear resources to prevent the elseif below from selecting $resources[0] $resources = @() $matchKey = $null } # Single-appliance fallback: unambiguous case, dominant in the fleet if ($resources.Count -eq 0 -and -not $ambiguousWarningSet -and $allAppliances.Count -eq 1) { $resources = @($allAppliances) $matchKey = "single-appliance subscription fallback" Write-InsightLog -Level:Informational -Message "No prefix match for local='$localClusterName' / ece='$eceClusterName'; subscription contains exactly one appliance ($($allAppliances[0].name)). Using it." } # Multiple appliances, no prefix match → ambiguous, warn explicitly if ($resources.Count -eq 0 -and -not $ambiguousWarningSet -and $allAppliances.Count -gt 1) { $applianceNames = ($allAppliances | ForEach-Object { $_.name }) -join ', ' $expected = if ($localClusterName) { $localClusterName } else { $eceClusterName } Write-InsightLog -Level:Warning -Message "Found $($allAppliances.Count) appliance(s) ($applianceNames) but none match cluster prefix '$expected' on $env:COMPUTERNAME" $ambiguousWarningSet = $true $insightRule.Status = [InsightStatus]::WARNING $insightRule.ErrorMessage = ($localizedData.Insight.ErrorMessage.AmbiguousAppliance -f $allAppliances.Count, $applianceNames, $expected) $insightRule.Properties = @([PSCustomObject]@{ Node = $env:COMPUTERNAME LocalClusterName = $localClusterName EceClusterName = $eceClusterName ExpectedPrefix = "$expected*" AppliancesFound = $applianceNames }) } } if ($resources.Count -eq 0 -and -not $ambiguousWarningSet) { Write-InsightLog -Level:Error -Message "No Arc resource bridge appliance found in subscription on $env:COMPUTERNAME (local='$localClusterName', ece='$eceClusterName')" $insightRule.Status = [InsightStatus]::FAILURE $insightRule.ErrorMessage = $localizedData.Insight.ErrorMessage.NoAppliance } elseif ($resources.Count -gt 0) { $bridgeName = $resources[0].name $rg = $resources[0].resourceGroup $bridgeId = $resources[0].id $bridgeSubId = $resources[0].subscriptionId Write-InsightLog -Level:Informational -Message "Selected ARB appliance '$bridgeName' in '$rg' via $matchKey" # Defense in depth: set the active subscription to the appliance's # owning sub before the status call. `az resource show --ids` # parses the sub from the ARM ID, but some az CLI versions still # consult the active profile for token acquisition. Setting # explicitly avoids that ambiguity. The MI may not have ever # logged into this sub if discovery used Resource Graph, so # tolerate failure here — `--ids` will still try. if ($bridgeSubId) { az account set -s $bridgeSubId 2>$null | Out-Null } # Query the appliance status. Use `az resource show --ids` for the # canonical view: it consistently returns full top-level properties, # whereas `az arcappliance show` has been observed to error on some # nodes when the extension version is behind. This call is the # authoritative status check. $showOutput = az resource show --ids $bridgeId -o json 2>$null if ($LASTEXITCODE -ne 0 -or [string]::IsNullOrWhiteSpace($showOutput)) { throw "az resource show --ids '$bridgeId' failed (exit code $LASTEXITCODE)." } $appliance = "$showOutput" | ConvertFrom-Json $status = $appliance.properties.status $provisioningState = $appliance.properties.provisioningState $result = [PSCustomObject]@{ Node = $env:COMPUTERNAME ApplianceName = $bridgeName ResourceGroup = $rg Status = $status ProvisioningState = $provisioningState } $insightRule.Properties = @($result) # SUCCESS requires status=Running AND provisioningState=Succeeded if ($status -eq 'Running' -and $provisioningState -eq 'Succeeded') { $insightRule.Status = [InsightStatus]::SUCCESS } else { $reasons = @() if ($status -ne 'Running') { $reasons += "status is '$status' (expected 'Running')" } if ($provisioningState -ne 'Succeeded') { $reasons += "provisioningState is '$provisioningState' (expected 'Succeeded')" } $detail = $reasons -join '; ' Write-InsightLog -Level:Error -Message "ARB appliance '$bridgeName': $detail" $insightRule.Status = [InsightStatus]::FAILURE $insightRule.ErrorMessage = ($localizedData.Insight.ErrorMessage.Unhealthy -f $bridgeName, $detail) } } } } catch { $_ | Write-InsightLog -Level 'Exception' $insightRule.ScriptStackTrace = Get-FormattedException -Exception $_.Exception $insightRule.Status = [InsightStatus]::UNKNOWN } finally { # Restore the active subscription so we don't leak the bridge sub (or # whichever sub the fallback loop last set) into the next validator in # this runspace. if ($originalSub) { az account set -s $originalSub 2>$null | Out-Null } } <# END INSIGHT RULE LOGIC #> # if the status is FAILURE or WARNING, set the failure code and remediation message if ($insightRule.Status -eq [InsightStatus]::FAILURE -or $insightRule.Status -eq [InsightStatus]::WARNING) { $insightRule.ErrorCode = $localizedData.Insight.ErrorCode $remediation = $localizedData.Insight.Remediation if ($bridgeName) { $remediation = $remediation.Replace('<ApplianceName>', $bridgeName) } if ($rg) { $remediation = $remediation.Replace('<ResourceGroup>', $rg) } $insightRule.Remediation = $remediation } $insightRule.Duration = New-TimeSpan -Start $insightRule.OccurrenceTimeUTC -End $([System.DateTime]::UtcNow) Write-InsightEvent -Insight $insightRule return $insightRule # SIG # Begin signature block # MIInbgYJKoZIhvcNAQcCoIInXzCCJ1sCAQExDzANBglghkgBZQMEAgEFADB5Bgor # BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG # KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCDZg1Au/CvAiTlc # WIhgGF2JoBxFBsL/aU9GMHZt3KBOf6CCDMkwggYEMIID7KADAgECAhMzAAACHPrN # xZvoL37EAAAAAAIcMA0GCSqGSIb3DQEBCwUAMFcxCzAJBgNVBAYTAlVTMR4wHAYD # VQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMTH01pY3Jvc29mdCBD # b2RlIFNpZ25pbmcgUENBIDIwMjQwHhcNMjYwNDE2MTg1OTQxWhcNMjcwNDE1MTg1 # OTQxWjB0MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UE # BxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMR4wHAYD # VQQDExVNaWNyb3NvZnQgQ29ycG9yYXRpb24wggEiMA0GCSqGSIb3DQEBAQUAA4IB # DwAwggEKAoIBAQDVsZfgOKmM31HPfoWOoNEiw0SlCiIxUMC0I9NMWbucKOw/e9lP # oAoehQVu6SG65V4EPzrYsnBnFPNoi4/HoOdjhz1qkrEt4I6tEcxXU6oOeY9zGveC # /3iBeuhLYxM3M/PkcUoebF+Nednm8OkdSPoDu8imViHPQq/8CQUu0WRR4rE+dMRf # rpVqfmNi2qWCX94T4MsepijGVkwE//tJg0ryAiYdHT34LSnlG/RSBZmQRGWZ5g8j # qnKjRParSqMft1gvjuUTVgtWNZfgcLFSK5Wa0myrq8OPcgTGGsRgun+tnSS+IxDT # xVsAPH1OzvPjwomguByhUe/OcvUN0D5Wmp7xAgMBAAGjggGqMIIBpjAOBgNVHQ8B # Af8EBAMCB4AwHwYDVR0lBBgwFgYKKwYBBAGCN0wIAQYIKwYBBQUHAwMwHQYDVR0O # BBYEFNoH7a2YDjOSwpkp6DHcmUS7J+0yMFQGA1UdEQRNMEukSTBHMS0wKwYDVQQL # EyRNaWNyb3NvZnQgSXJlbGFuZCBPcGVyYXRpb25zIExpbWl0ZWQxFjAUBgNVBAUT # DTIzMDAxMis1MDc1NjkwHwYDVR0jBBgwFoAUf1k/VCHarU/vBeXmo9ctBpQSCDEw # YAYDVR0fBFkwVzBVoFOgUYZPaHR0cDovL3d3dy5taWNyb3NvZnQuY29tL3BraW9w # cy9jcmwvTWljcm9zb2Z0JTIwQ29kZSUyMFNpZ25pbmclMjBQQ0ElMjAyMDI0LmNy # bDBtBggrBgEFBQcBAQRhMF8wXQYIKwYBBQUHMAKGUWh0dHA6Ly93d3cubWljcm9z # b2Z0LmNvbS9wa2lvcHMvY2VydHMvTWljcm9zb2Z0JTIwQ29kZSUyMFNpZ25pbmcl # MjBQQ0ElMjAyMDI0LmNydDAMBgNVHRMBAf8EAjAAMA0GCSqGSIb3DQEBCwUAA4IC # AQAUnEqhaRXe0T3hIJjvdQErEkrA/7bByjn6t5IArODkkRjzkYwtKMc2yYj2quaN # rLutWw2YZcngKPy1b71YyDJQTy4NDRwaSh9Tw5thrk3NmcPrAHia5vtcBJ1CgtKK # 7mQbIcQ22d/N3813ayCDDFewu1+jsZmX+r/aTEqaOM4TVxVtRSkuCy8nAXKuChOK # Li/zA4XuH8iEYqIsj2YoNaeSxVmeGiERXpKdo3dDmYi0kO5w2D8VS4c3+9h6gElY # BaAAg/dYErBg27qT3vv0zRDJhJufvCNylA8S7/+8H5E/PV5cng6na9VV/w9OV3qu # uND6zdGa2EX38Glp50F9AIQk3p2xXmcvorDeM4XJ7UlWYBi6g80J1SSOQnInCYFE # msfUNn3+1AaTJKSJL83quKArTac2pKhu0Yzzzrzo6HrsRiQKzpnRBb1/dMa6P3hz # 75XbMRBctNsFhZC07WCmjExdLg2eHW5uV0TY8D5+6wozJf7vF3+WHkYPO85Z+BC6 # U4FkNbYNycZ9cE4j1tXRdyDCfml6c0HWPHjNVDObrv9lKt3qUqFpX38VCqVCyNOO # 1UcXfQiVjJw32U2WUKZjt/neJKHEBsm9kFsLuWzkQ53+qcaSaytmsCnk2gOglrlD # 5d3kKyvvAw+rzm0lT8K38P6PLxfZQHhu4W8dV7Av8N2ZmDCCBr0wggSloAMCAQIC # EzMAAAA5O7Y3Gb8GHWcAAAAAADkwDQYJKoZIhvcNAQEMBQAwgYgxCzAJBgNVBAYT # AlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYD # VQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xMjAwBgNVBAMTKU1pY3Jvc29mdCBS # b290IENlcnRpZmljYXRlIEF1dGhvcml0eSAyMDExMB4XDTI0MDgwODIwNTQxOFoX # DTM2MDMyMjIyMTMwNFowVzELMAkGA1UEBhMCVVMxHjAcBgNVBAoTFU1pY3Jvc29m # dCBDb3Jwb3JhdGlvbjEoMCYGA1UEAxMfTWljcm9zb2Z0IENvZGUgU2lnbmluZyBQ # Q0EgMjAyNDCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANgBnB7jOMeq # lRYHNa265v4IY9fH8TKhemHfPINe1gpLaV3dhg324WwH06LcHbpnsBukCDNitryo # 0dtS/EW6I/yEL/bLSY8hKpbfQuWusBPr9qazYcDxCW/qnjb5JsI1s8bNOg3bVATv # QVL4tcf03aTycsz8QeCdM0l/yHRObJ9QqazM1r6VPEOJ7LL+uEEb73w6QCuhs89a # 1uv1zerOYMnsneRRwCbpyW11IcggU0cRKDDq1pjVJzIbIF6+oiXXbReOsgeI8zu1 # FyQfK0fVkaya8SmVHQ/tOf23mZ4W9k0Ri22QW9p3UgSC5OUDktKxxcCmGL6tXLfO # GSWHIIV4YrTJTT6PNty5REojHJuZHArkF9VnHTERWoTjAzfI3kP+5b4alUdhgAZ7 # ttOu1bVnXfHaqPYl2rPs20ji03LOVWsh/radgE17es5hL+t6lV0eVHrVhsssROWJ # uz2MXMCt7iw7lFPG9LXKGjsmonn2gotGdHIuEg5JnJMJVmixd5LRlkmgYRZKzhxS # CwyoGIq0PhaA7Y+VPct5pCHkijcIIDm0nlkK+0KyepolcqGm0T/GYQRMhHJlGOOm # VQop36wUVUYklUy++vDWeEgEo4s7hxN6mIbf2MSIQ/iIfMZgJxC69oukMUXCrOC3 # SkE/xIkgpfl22MM1itkZ35nNXkMolU1lAgMBAAGjggFOMIIBSjAOBgNVHQ8BAf8E # BAMCAYYwEAYJKwYBBAGCNxUBBAMCAQAwHQYDVR0OBBYEFH9ZP1Qh2q1P7wXl5qPX # LQaUEggxMBkGCSsGAQQBgjcUAgQMHgoAUwB1AGIAQwBBMA8GA1UdEwEB/wQFMAMB # Af8wHwYDVR0jBBgwFoAUci06AjGQQ7kUBU7h6qfHMdEjiTQwWgYDVR0fBFMwUTBP # oE2gS4ZJaHR0cDovL2NybC5taWNyb3NvZnQuY29tL3BraS9jcmwvcHJvZHVjdHMv # TWljUm9vQ2VyQXV0MjAxMV8yMDExXzAzXzIyLmNybDBeBggrBgEFBQcBAQRSMFAw # TgYIKwYBBQUHMAKGQmh0dHA6Ly93d3cubWljcm9zb2Z0LmNvbS9wa2kvY2VydHMv # TWljUm9vQ2VyQXV0MjAxMV8yMDExXzAzXzIyLmNydDANBgkqhkiG9w0BAQwFAAOC # AgEAFJQfOChP7onn6fLIMKrSlN1WYKwDFgAddymOUO3FrM8d7B/W/iQ6DxXsDn7D # 5W4wMwYeLystcEqfkjz4NURRgazyMu5yRzQh4LqjA4tStTcJh1opExo7nn5PuPBY # nbu0+THSuVHTe0VTTPVhily/piFrDo3axQ9P4C+Ol5yet+2gTfekICS5xS+cYfSI # vgn0JksVBVMYVI5QFu/qhnLhsEFEUzG8fvv0hjgkO+lkpV9ty6GkN4vdnd7ya6Q6 # aR9y34aiM1qmxaxBi6OUnyNl6fkuun/diTFnYDLTppOkr/mg5WSfCiDVMNCxtj4w # PKC5OmHm1DQIt/MNokbbH3UGsFP1QbzsLocuSqLCvH09Io3fDPTmscR9Y75G4qX7 # RTX8AdBPo0I6OEojf39zuFZt0qOHm65YWQE69cZM2ueE1MB05dNNgHK9gTE7zKvK # /fg8B2qjW88MT/WF5V5uvZGtqa9FSL2RazArA+rDPuf6JGYz4HpgMZHB4S6szWSK # YBv0VisCzfxgeU+dquXW9bd0auYlOB58DPcOYKdc3Se94g+xL4pcEhbB54JOgAkw # YTu/9dLeH2pDqeJZAABVDWRQCaXfO5LgyKwKCLYXpigrZYCjUSBcr+Ve8PFWMhVT # Ql0v4q8J/AUmQN5W4n101cY2L4A7GTQG1h32HHAvfQESWP0xghn7MIIZ9wIBATBu # MFcxCzAJBgNVBAYTAlVTMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24x # KDAmBgNVBAMTH01pY3Jvc29mdCBDb2RlIFNpZ25pbmcgUENBIDIwMjQCEzMAAAIc # +s3Fm+gvfsQAAAAAAhwwDQYJYIZIAWUDBAIBBQCgga4wGQYJKoZIhvcNAQkDMQwG # CisGAQQBgjcCAQQwHAYKKwYBBAGCNwIBCzEOMAwGCisGAQQBgjcCARUwLwYJKoZI # hvcNAQkEMSIEIFuSGoMk5qL30tZy38gBHueVRNSbpz787n2MqIVPCMRhMEIGCisG # AQQBgjcCAQwxNDAyoBSAEgBNAGkAYwByAG8AcwBvAGYAdKEagBhodHRwOi8vd3d3 # Lm1pY3Jvc29mdC5jb20wDQYJKoZIhvcNAQEBBQAEggEAUDlDw0R4EtFrh52lPHbm # mjC8xoNpLbmPhm6xTfNlQhoyx3Xn82y5xArMhaIukIdTtC7E6OaL6V8EB8VgLNRD # bQIOyXGsey6m6XmWwwFuUprTMa2UWG4pQokQDvRHyBVYrF5xBdcef0wDlPn7NTnm # Hh6WMeWZK6r3ozdlSJLq3poTBDFE9KqyqoZjO3E13vaim2vQwspbtbWYRGT+Hr1S # JDSlhGHZ1mGN++rb9DGcQc+Ia/q6bCF0GOjKqZfI6SGv6UL+Bnyuu2g/pKRUOIvJ # Xaeq0qSbntZ3qDzZt+ryxTYyNozuboyIvcSdMmwoGuSuZYsFvvfxpPMgZWQE/gA5 # V6GCF60wghepBgorBgEEAYI3AwMBMYIXmTCCF5UGCSqGSIb3DQEHAqCCF4YwgheC # AgEDMQ8wDQYJYIZIAWUDBAIBBQAwggFaBgsqhkiG9w0BCRABBKCCAUkEggFFMIIB # QQIBAQYKKwYBBAGEWQoDATAxMA0GCWCGSAFlAwQCAQUABCBYDp5AiJZDCiVLFZqa # iIkkvzLxzyB6Hq6IGjOQfAwNAAIGahF0uM6rGBMyMDI2MDUyNzE0MDc0NC4zMjFa # MASAAgH0oIHZpIHWMIHTMQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3Rv # bjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0 # aW9uMS0wKwYDVQQLEyRNaWNyb3NvZnQgSXJlbGFuZCBPcGVyYXRpb25zIExpbWl0 # ZWQxJzAlBgNVBAsTHm5TaGllbGQgVFNTIEVTTjo1NTFBLTA1RTAtRDk0NzElMCMG # A1UEAxMcTWljcm9zb2Z0IFRpbWUtU3RhbXAgU2VydmljZaCCEfswggcoMIIFEKAD # AgECAhMzAAACG9CyuAJn93LPAAEAAAIbMA0GCSqGSIb3DQEBCwUAMHwxCzAJBgNV # BAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4w # HAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xJjAkBgNVBAMTHU1pY3Jvc29m # dCBUaW1lLVN0YW1wIFBDQSAyMDEwMB4XDTI1MDgxNDE4NDgzMFoXDTI2MTExMzE4 # NDgzMFowgdMxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYD # VQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xLTAr # BgNVBAsTJE1pY3Jvc29mdCBJcmVsYW5kIE9wZXJhdGlvbnMgTGltaXRlZDEnMCUG # A1UECxMeblNoaWVsZCBUU1MgRVNOOjU1MUEtMDVFMC1EOTQ3MSUwIwYDVQQDExxN # aWNyb3NvZnQgVGltZS1TdGFtcCBTZXJ2aWNlMIICIjANBgkqhkiG9w0BAQEFAAOC # Ag8AMIICCgKCAgEAjsWd52ZZkzB5Xe5g/l2GsOjAz30sg6jVxfFJV+w4xIDVyaI3 # LO8bIpmzYul3AZHg50UIQ8PrSRZGpQqFkRNu+o3YKJ4g2uGYBRksHnHYR0uVSCQg # 58ThkYyeplGX3oAvGRVuPIpQtAiTsR76A/gdoU7HDwEbb73bJwTyrbKHhR+WaMy9 # DQHI4k5Qo4+bZDs0kj76bvhJvdGU+S8zxQBp7UAhjJnFqKxIusSITE7zCCR422EL # hkhVVOFqK2w6h1MAvILe76hxRIcPj0SBL2r8O9tx5njU4+tg2rAdU153pmyhqazd # pUccYBE9wDRFUd/e9CoWx7TdnUicB+Mai7RT6qse7e5aGqX1B7bnj/ZHvrrfF+BJ # EIlS9iDXAUgekvXZ+FZmjvLwP+dN+0/crh++r4e8FknF7EX6IJfnmNeDN/68Z59k # baJ1f+P5mnKYfydCeZmxrGpS0taWkDk36D3jPVZflvxrc+1rhCIlM5v9agLEFI12 # QiBTfpOBOBr3AGCPk+eH0+latjQajug+2/BD12qb82500LQytUWT2ota/HYnRgSv # 1jvZ0/dml1FsxWYzOnCrjfdB/7N6pNySt4vn+PGN6dFLim7kxos+B9WfQPezJi3f # uKyyDAB9zSHPj1Zu8nZfecZJ9um4zj7DFgvJXTDTnG5qlG4ZdbFRa/rrfzkCAwEA # AaOCAUkwggFFMB0GA1UdDgQWBBS2vp93/lxLppNK8OkauJ2AvNmIUDAfBgNVHSME # GDAWgBSfpxVdAF5iXYP05dJlpxtTNRnpcjBfBgNVHR8EWDBWMFSgUqBQhk5odHRw # Oi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2NybC9NaWNyb3NvZnQlMjBUaW1l # LVN0YW1wJTIwUENBJTIwMjAxMCgxKS5jcmwwbAYIKwYBBQUHAQEEYDBeMFwGCCsG # AQUFBzAChlBodHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2NlcnRzL01p # Y3Jvc29mdCUyMFRpbWUtU3RhbXAlMjBQQ0ElMjAyMDEwKDEpLmNydDAMBgNVHRMB # Af8EAjAAMBYGA1UdJQEB/wQMMAoGCCsGAQUFBwMIMA4GA1UdDwEB/wQEAwIHgDAN # BgkqhkiG9w0BAQsFAAOCAgEAZkU1XxQD4OTM3GTht32TXShIfPBoMfSsFsBQqFOZ # qLJOxyJOllIBFpmpvOtGNPkC5Z8ldG8aCpvgFNo/jDWeT5FiW53dAj9KnZxpsQ3P # f5fRzSGHRcxEMOdXIVzDJwcZUX0cjfxna7ydNv8eXB/Xk6G6SyrR2OH6S1LHMW11 # m3UvKF+eLjIPl45rximuDCoEd+ad0lOAXA5/vZOKN5n/ePYeP0LRchZX0Q6H8n/Z # mSPMlbli3MO851Q09RmT/ZGHa+/Fdy+WLDrwcYykV9mUy/4TbwKw6FtdR6ZPHxMd # Ii1pk8Y2mC/GzCq0LCsH0uTFeQ6Q7Nc3MRmER/3mLWUhbaWHgX1FbYchvR22b+Bu # p+YPR5Q/0BhaaAN6AIBfcGs+u/nJoIByyZKA8cTyCmnUI/4vW6D4vywg3XBFf4f2 # DwFHy/evsC+58KMl+k2wa05X2kK0T/bCPLhaov9ZXyobawfNOLYGiauKT2FWvbwZ # zHIFCTxjBww6Pt5uRvCE/jnUcf/xhlOGMn6iKO9Xt49vZTE2SfIBk/34iLTRBJ6H # 7aGPTTQnza3OfWu1/dRycC6Wl5ons3PjnGXTSKSxXllJPmg6R/ulGonP/UCYoJ6m # N+EXjfyDLPXLqsr91+VTG1rYzRCjPwBFAHv4EIwaE0ajCrf75eUGI3+oXU0UP6rl # oZ8wggdxMIIFWaADAgECAhMzAAAAFcXna54Cm0mZAAAAAAAVMA0GCSqGSIb3DQEB # CwUAMIGIMQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UE # BxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTIwMAYD # VQQDEylNaWNyb3NvZnQgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgMjAxMDAe # Fw0yMTA5MzAxODIyMjVaFw0zMDA5MzAxODMyMjVaMHwxCzAJBgNVBAYTAlVTMRMw # EQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVN # aWNyb3NvZnQgQ29ycG9yYXRpb24xJjAkBgNVBAMTHU1pY3Jvc29mdCBUaW1lLVN0 # YW1wIFBDQSAyMDEwMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA5OGm # TOe0ciELeaLL1yR5vQ7VgtP97pwHB9KpbE51yMo1V/YBf2xK4OK9uT4XYDP/XE/H # ZveVU3Fa4n5KWv64NmeFRiMMtY0Tz3cywBAY6GB9alKDRLemjkZrBxTzxXb1hlDc # wUTIcVxRMTegCjhuje3XD9gmU3w5YQJ6xKr9cmmvHaus9ja+NSZk2pg7uhp7M62A # W36MEBydUv626GIl3GoPz130/o5Tz9bshVZN7928jaTjkY+yOSxRnOlwaQ3KNi1w # jjHINSi947SHJMPgyY9+tVSP3PoFVZhtaDuaRr3tpK56KTesy+uDRedGbsoy1cCG # MFxPLOJiss254o2I5JasAUq7vnGpF1tnYN74kpEeHT39IM9zfUGaRnXNxF803RKJ # 1v2lIH1+/NmeRd+2ci/bfV+AutuqfjbsNkz2K26oElHovwUDo9Fzpk03dJQcNIIP # 8BDyt0cY7afomXw/TNuvXsLz1dhzPUNOwTM5TI4CvEJoLhDqhFFG4tG9ahhaYQFz # ymeiXtcodgLiMxhy16cg8ML6EgrXY28MyTZki1ugpoMhXV8wdJGUlNi5UPkLiWHz # NgY1GIRH29wb0f2y1BzFa/ZcUlFdEtsluq9QBXpsxREdcu+N+VLEhReTwDwV2xo3 # xwgVGD94q0W29R6HXtqPnhZyacaue7e3PmriLq0CAwEAAaOCAd0wggHZMBIGCSsG # AQQBgjcVAQQFAgMBAAEwIwYJKwYBBAGCNxUCBBYEFCqnUv5kxJq+gpE8RjUpzxD/ # LwTuMB0GA1UdDgQWBBSfpxVdAF5iXYP05dJlpxtTNRnpcjBcBgNVHSAEVTBTMFEG # DCsGAQQBgjdMg30BATBBMD8GCCsGAQUFBwIBFjNodHRwOi8vd3d3Lm1pY3Jvc29m # dC5jb20vcGtpb3BzL0RvY3MvUmVwb3NpdG9yeS5odG0wEwYDVR0lBAwwCgYIKwYB # BQUHAwgwGQYJKwYBBAGCNxQCBAweCgBTAHUAYgBDAEEwCwYDVR0PBAQDAgGGMA8G # A1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAU1fZWy4/oolxiaNE9lJBb186aGMQw # VgYDVR0fBE8wTTBLoEmgR4ZFaHR0cDovL2NybC5taWNyb3NvZnQuY29tL3BraS9j # cmwvcHJvZHVjdHMvTWljUm9vQ2VyQXV0XzIwMTAtMDYtMjMuY3JsMFoGCCsGAQUF # BwEBBE4wTDBKBggrBgEFBQcwAoY+aHR0cDovL3d3dy5taWNyb3NvZnQuY29tL3Br # aS9jZXJ0cy9NaWNSb29DZXJBdXRfMjAxMC0wNi0yMy5jcnQwDQYJKoZIhvcNAQEL # BQADggIBAJ1VffwqreEsH2cBMSRb4Z5yS/ypb+pcFLY+TkdkeLEGk5c9MTO1OdfC # cTY/2mRsfNB1OW27DzHkwo/7bNGhlBgi7ulmZzpTTd2YurYeeNg2LpypglYAA7AF # vonoaeC6Ce5732pvvinLbtg/SHUB2RjebYIM9W0jVOR4U3UkV7ndn/OOPcbzaN9l # 9qRWqveVtihVJ9AkvUCgvxm2EhIRXT0n4ECWOKz3+SmJw7wXsFSFQrP8DJ6LGYnn # 8AtqgcKBGUIZUnWKNsIdw2FzLixre24/LAl4FOmRsqlb30mjdAy87JGA0j3mSj5m # O0+7hvoyGtmW9I/2kQH2zsZ0/fZMcm8Qq3UwxTSwethQ/gpY3UA8x1RtnWN0SCyx # TkctwRQEcb9k+SS+c23Kjgm9swFXSVRk2XPXfx5bRAGOWhmRaw2fpCjcZxkoJLo4 # S5pu+yFUa2pFEUep8beuyOiJXk+d0tBMdrVXVAmxaQFEfnyhYWxz/gq77EFmPWn9 # y8FBSX5+k77L+DvktxW/tM4+pTFRhLy/AsGConsXHRWJjXD+57XQKBqJC4822rpM # +Zv/Cuk0+CQ1ZyvgDbjmjJnW4SLq8CdCPSWU5nR0W2rRnj7tfqAxM328y+l7vzhw # RNGQ8cirOoo6CGJ/2XBjU02N7oJtpQUQwXEGahC0HVUzWLOhcGbyoYIDVjCCAj4C # AQEwggEBoYHZpIHWMIHTMQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3Rv # bjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0 # aW9uMS0wKwYDVQQLEyRNaWNyb3NvZnQgSXJlbGFuZCBPcGVyYXRpb25zIExpbWl0 # ZWQxJzAlBgNVBAsTHm5TaGllbGQgVFNTIEVTTjo1NTFBLTA1RTAtRDk0NzElMCMG # A1UEAxMcTWljcm9zb2Z0IFRpbWUtU3RhbXAgU2VydmljZaIjCgEBMAcGBSsOAwIa # AxUAhoV6r49M4GBd41K1RYB1Z0f4zuCggYMwgYCkfjB8MQswCQYDVQQGEwJVUzET # MBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMV # TWljcm9zb2Z0IENvcnBvcmF0aW9uMSYwJAYDVQQDEx1NaWNyb3NvZnQgVGltZS1T # dGFtcCBQQ0EgMjAxMDANBgkqhkiG9w0BAQsFAAIFAO3BONswIhgPMjAyNjA1Mjcw # OTMzMTVaGA8yMDI2MDUyODA5MzMxNVowdDA6BgorBgEEAYRZCgQBMSwwKjAKAgUA # 7cE42wIBADAHAgEAAgILKzAHAgEAAgIR4TAKAgUA7cKKWwIBADA2BgorBgEEAYRZ # CgQCMSgwJjAMBgorBgEEAYRZCgMCoAowCAIBAAIDB6EgoQowCAIBAAIDAYagMA0G # CSqGSIb3DQEBCwUAA4IBAQBoRkFgXg00dNmCiA6PPsobZ2ZrKz1FSd5ywpZmBH2+ # DlLqtIFYUyNLF9eeD76dTUrjNV7mmC4cAyu3C7gxLdx5E0ZuHgIqhMvScgtvA7hp # 6KNZC69V2bn42QN43vHg7vGA0urGvRAE4iDYdV+jCWYRd8BACMYsJkWENtoKumpd # Lrk/eN0xYJYnH8hg30rtnLunDRJeSJ4ODvOdcOZfS4rElriv8a+FUFvt95+hKO1N # 4EQ+iRT6T6nw8FSlvcKgrFjabkzZLfqDGfwz+IQh7MOfloMRa7FJ/eezzJJlWxE1 # eOD4mLqcmsME8ioM0CnW6UYTvGdh7C0Y0g/z0Pt2vf5kMYIEDTCCBAkCAQEwgZMw # fDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1Jl # ZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEmMCQGA1UEAxMd # TWljcm9zb2Z0IFRpbWUtU3RhbXAgUENBIDIwMTACEzMAAAIb0LK4Amf3cs8AAQAA # AhswDQYJYIZIAWUDBAIBBQCgggFKMBoGCSqGSIb3DQEJAzENBgsqhkiG9w0BCRAB # BDAvBgkqhkiG9w0BCQQxIgQgFrLPgxnkwdSZcimz9w8P7RsgGISlHdCf0eyBlePY # cfswgfoGCyqGSIb3DQEJEAIvMYHqMIHnMIHkMIG9BCAwJRSVuD2jmMcQCFXdLuJA # wDpUVNZ6bc6dfJU83Q2LgDCBmDCBgKR+MHwxCzAJBgNVBAYTAlVTMRMwEQYDVQQI # EwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3Nv # ZnQgQ29ycG9yYXRpb24xJjAkBgNVBAMTHU1pY3Jvc29mdCBUaW1lLVN0YW1wIFBD # QSAyMDEwAhMzAAACG9CyuAJn93LPAAEAAAIbMCIEIDPplANOBr3l3lMhaw0h4UYJ # +ZlcRc7kw79bdMAP6S++MA0GCSqGSIb3DQEBCwUABIICAFZJbPAqsvHIVg0W6+PV # ybE7uUmFCD49TCJaCHzfu8FRaxgcKOzc0bvggZnzXnrw/2CLEbXLpxavbbvKzE1+ # xBt5QluGv+SaB9JCzld29iGN7/zu9LY/oPLeMC4RKFCLrTCtm/FBlnF+LEBZVRXl # 3V3Z/UrRuBxS59/xdF+/WiW3nFaZLshtG6rWUm22KjgYyK5uWlxhq8dkOrRMQdjZ # vTfSnEP3zFXkNMlGwCu9Df6/3IFAGdg4EciKQQEqNRztnMar8pq/pH3pXwd6xsyp # deSDE7OmhGUHKUw4a5qISpDpbXd47ABbZQLbcbZ9OszG5Qs/jzMhp+gnTOu4kKY5 # +paECqVL/L0vEuS6UtcmGIXnw7+fdOPR9e1zuvf5P/48wy1tREl4DaArUhQyyoy8 # RZevyiOvX9Ztgm7724x9DENsB9qNPOEQkPQtQQZ+9/S+9+3KlW+40buuLYHbVMjI # 6zS5s+XHTIvDNKl3/iJ3jdD+/BpCB6z4WbXXJ2x4Al37hlahRsTy51zCaXTB8zVR # U34YjNlpfcyFk1QXNJbu3ZaqMJ1nPrLW7VvEuTiQJC1kjytC39XXGZHV2MJ1vxOa # fUhNpUU0biPSnW54ptndcMsb7KqrJ0YD3SCZs1HMJzkzCLyzOUS+GfzldDrvvS9A # uEOUQ1dPcUqKKyCpF9YLE6x8 # SIG # End signature block |