Private/Trees/New-OwnerLensAzureRbacTree.ps1

function Test-OwnerLensResourceUnderScope {
  param(
    [string]$ResourceId,
    [string]$Scope
  )

  if ([string]::IsNullOrWhiteSpace($ResourceId) -or [string]::IsNullOrWhiteSpace($Scope)) {
    return $false
  }

  $normalizedResourceId = $ResourceId.TrimEnd("/")
  $normalizedScope = $Scope.TrimEnd("/")

  return (
    $normalizedResourceId.Equals($normalizedScope, [System.StringComparison]::OrdinalIgnoreCase) -or
    $normalizedResourceId.StartsWith("$normalizedScope/", [System.StringComparison]::OrdinalIgnoreCase)
  )
}

function Get-OwnerLensResourceLabel {
  param(
    [object]$Dependency,
    [object]$Assignment
  )

  if ($Dependency) {
    $resourceName = Get-OwnerLensDisplayValue -Value $Dependency.resourceName -Fallback ([string]$Dependency.resourceId)
    $dependencyType = Get-OwnerLensDisplayValue -Value $Dependency.dependencyType -Fallback "Scope"
    $resourceType = Get-OwnerLensDisplayValue -Value $Dependency.resourceType
    $resourceGroup = Get-OwnerLensDisplayValue -Value $Dependency.resourceGroup
    $resourceId = [string]$Dependency.resourceId
    $resourceLabel = Format-OwnerLensRichLink `
      -Text $resourceName `
      -Uri (ConvertTo-OwnerLensAzurePortalResourceUri -ResourceId $resourceId)
    $scopeDetails = @()

    if (-not [string]::IsNullOrWhiteSpace($resourceType)) {
      $scopeDetails += $resourceType
    }

    if (-not [string]::IsNullOrWhiteSpace($resourceGroup)) {
      $scopeDetails += "rg=$resourceGroup"
    }

    if ($scopeDetails.Count -gt 0) {
      return "[blue]$dependencyType`: $resourceLabel ($($scopeDetails -join ", "))[/]"
    }

    return "[blue]$dependencyType`: $resourceLabel[/]"
  }

  $scope = Get-OwnerLensDisplayValue -Value $Assignment.scope -Fallback "unknown scope"
  return "[blue]Scope: $(Format-OwnerLensAzureResourceId -ResourceId $scope)[/]"
}

function Get-OwnerLensDefaultAzureOwnerTagNames {
  @("userOwner", "technicalOwner", "businessOwner", "groupOwner", "ownerGroup", "teamOwner", "team", "owner", "serviceOwner", "appOwner", "applicationOwner", "productOwner", "managedBy", "ownedBy", "costCenter", "costCentre", "cost-center", "cost_center")
}

function Add-OwnerLensTagNodes {
  param(
    [object]$Tree,
    [object]$Tags,
    [string[]]$OwnerTagNames = @()
  )

  if (-not $Tags) {
    return
  }

  $tagRows = @()
  if ($Tags -is [hashtable] -or $Tags -is [System.Collections.IDictionary]) {
    foreach ($key in $Tags.Keys) {
      $tagRows += [pscustomobject]@{ key = [string]$key; value = [string]$Tags[$key] }
    }
  }
  else {
    foreach ($property in $Tags.PSObject.Properties) {
      $tagRows += [pscustomobject]@{ key = [string]$property.Name; value = [string]$property.Value }
    }
  }

  $tagRows = @($tagRows | Where-Object { -not [string]::IsNullOrWhiteSpace($_.key) } | Sort-Object key)
  if ($tagRows.Count -eq 0) {
    return
  }

  $ownerTagNameSet = [System.Collections.Generic.HashSet[string]]::new([System.StringComparer]::OrdinalIgnoreCase)
  foreach ($ownerTagName in @($OwnerTagNames)) {
    if (-not [string]::IsNullOrWhiteSpace($ownerTagName)) {
      $ownerTagNameSet.Add([string]$ownerTagName) | Out-Null
    }
  }

  $tagsNode = Add-RichTreeNode $Tree "tags ($($tagRows.Count))" -PassThru
  foreach ($tag in $tagRows) {
    $tagText = "$($tag.key)=$($tag.value)"
    if ($ownerTagNameSet.Contains([string]$tag.key)) {
      $tagText = "[green]$tagText[/]"
    }

    Add-RichTreeNode $tagsNode $tagText
  }
}

function Format-OwnerLensStorageDiagnosticStatus {
  param([object]$StorageAccount)

  $diagnosticServices = @($StorageAccount.diagnosticSettings | Sort-Object service)
  $configuredServices = @($diagnosticServices | Where-Object dataAccessLogEnabled)
  if ($configuredServices.Count -eq 0) {
    return "[yellow]No diagnostic settings detected; not possible to detect data access based on logs to increase accuracy.[/]"
  }

  $serviceSummaries = @($configuredServices | ForEach-Object {
      $settingNames = @($_.diagnosticSettingNames | Where-Object { -not [string]::IsNullOrWhiteSpace([string]$_) }) -join ","
      $workspaceIds = @($_.workspaceIds | Where-Object { -not [string]::IsNullOrWhiteSpace([string]$_) } | ForEach-Object {
          Format-OwnerLensShortAzureResourceLink -ResourceId ([string]$_)
        }) -join ","
      $details = @("status=$($_.status)")

      if (-not [string]::IsNullOrWhiteSpace($settingNames)) {
        $details += "settings=$settingNames"
      }

      if (-not [string]::IsNullOrWhiteSpace($workspaceIds)) {
        $details += "workspaces=$workspaceIds"
      }

      "$($_.service) ($($details -join ", "))"
    })

  return "[dim]Configured: $($serviceSummaries -join "; ")[/]"
}

function Get-OwnerLensPrincipalDisplayText {
  param(
    [string]$Label,
    [string]$PrincipalType,
    [string]$PrincipalId,
    [string]$PrincipalUpn
  )

  $displayLabel = Get-OwnerLensDisplayValue -Value $Label -Fallback "unknown principal"
  $displayType = Get-OwnerLensDisplayValue -Value $PrincipalType -Fallback "Principal"
  $displayId = Get-OwnerLensDisplayValue -Value $PrincipalId -Fallback "unknown id"
  $displayUpn = Get-OwnerLensDisplayValue -Value $PrincipalUpn -Fallback "unknown upn"

  return "$displayLabel ($displayType, id=$displayId, upn=$displayUpn)"
}

function Get-OwnerLensActivityCallerPrincipalType {
  param([object]$Caller)

  return Get-OwnerLensPrincipalType `
    -Caller ([string]$Caller.caller) `
    -AppId ([string]$Caller.callerAppId)
}

function New-OwnerLensAzureRbacTree {
  [CmdletBinding()]
  param(
    [Parameter(Mandatory = $true)]
    [object]$Report
  )

  $sp = Get-OwnerLensReportValue -Report $Report -Path "enterpriseApplication"
  $displayName = Get-OwnerLensDisplayValue -Value $sp.displayName -Fallback "service principal"
  $root = New-RichTree "[magenta]Service Principal: $displayName (objectId=$($sp.objectId), appId=$($sp.appId))[/]"
  $roleAssignments = Get-OwnerLensReportArray -Report $Report -Path "azure.roleAssignments"
  $resourceDependencies = Get-OwnerLensReportArray -Report $Report -Path "azure.resourceDependencies"
  $coAssignedRoleCandidates = Get-OwnerLensReportArray -Report $Report -Path "azure.coAssignedRoleCandidates"
  $rbacScopeActivityCallers = Get-OwnerLensReportArray -Report $Report -Path "azure.rbacScopeActivityCallers"
  $storageAccountsWithRbac = Get-OwnerLensReportArray -Report $Report -Path "azure.storageAccountsWithRbac"
  $blobReadCallers = Get-OwnerLensReportArray -Report $Report -Path "azure.blobReadCallers"
  $ownerTagConfiguration = Get-OwnerLensReportValue -Report $Report -Path "meta.ownerTagConfiguration"
  $ownerTagNames = @($ownerTagConfiguration.userOwnerTagNames) +
    @($ownerTagConfiguration.groupOwnerTagNames) +
    @($ownerTagConfiguration.tagOwnerTagNames)
  if ($ownerTagNames.Count -eq 0) {
    $ownerTagNames = @(Get-OwnerLensDefaultAzureOwnerTagNames)
  }

  if ($roleAssignments.Count -eq 0) {
    Add-RichTreeNode $root "no Azure RBAC role assignments found for this service principal"
    return $root
  }

  foreach ($scopeGroup in @($roleAssignments | Group-Object scope | Sort-Object Name)) {
    $scope = [string]$scopeGroup.Name
    $assignments = @($scopeGroup.Group | Sort-Object subscriptionName, roleDefinitionName)
    $firstAssignment = $assignments | Select-Object -First 1
    $dependency = @($resourceDependencies | Where-Object {
        ([string]$_.resourceId).Equals($scope, [System.StringComparison]::OrdinalIgnoreCase)
      } | Select-Object -First 1)

    $resourceNode = Add-RichTreeNode $root (Get-OwnerLensResourceLabel -Dependency $dependency -Assignment $firstAssignment) -PassThru
    Add-RichTreeNode $resourceNode "scope: $(Format-OwnerLensAzureResourceId -ResourceId $scope)"

    $rolesNode = Add-RichTreeNode $resourceNode "roles for inspected SP ($($assignments.Count))" -PassThru
    foreach ($assignment in $assignments) {
      $roleLabel = Get-OwnerLensDisplayValue -Value $assignment.roleDefinitionName -Fallback "unknown role"
      $subscriptionName = Get-OwnerLensDisplayValue -Value $assignment.subscriptionName
      if (-not [string]::IsNullOrWhiteSpace($subscriptionName)) {
        $roleLabel = "$roleLabel (subscription=$subscriptionName)"
      }

      Add-RichTreeNode $rolesNode $roleLabel
    }

    Add-OwnerLensTagNodes -Tree $resourceNode -Tags $dependency.tags -OwnerTagNames $ownerTagNames

    $coAssignedPrincipals = @($coAssignedRoleCandidates | Where-Object {
        ([string]$_.scope).Equals($scope, [System.StringComparison]::OrdinalIgnoreCase)
      } | Sort-Object principalDisplayName, principalName, roleDefinitionName)
    if ($coAssignedPrincipals.Count -gt 0) {
      $principalGroups = @($coAssignedPrincipals | Group-Object {
          $principalId = Get-OwnerLensDisplayValue -Value $_.principalId
          if (-not [string]::IsNullOrWhiteSpace($principalId)) {
            return "id:$principalId"
          }

          $principalName = Get-OwnerLensDisplayValue -Value $_.principalName
          if (-not [string]::IsNullOrWhiteSpace($principalName)) {
            return "upn:$principalName"
          }

          return "display:$($_.principalDisplayName)"
        } | Sort-Object {
          $firstPrincipal = $_.Group | Select-Object -First 1
          Get-OwnerLensDisplayValue -Value $firstPrincipal.principalDisplayName -Fallback (Get-OwnerLensDisplayValue -Value $firstPrincipal.principalName -Fallback $firstPrincipal.principalId)
        })
      $coAssignedCount = Format-OwnerLensRichLink `
        -Text ([string]$principalGroups.Count) `
        -Uri (ConvertTo-OwnerLensAzurePortalIamUri -Scope $scope)
      $coAssignedNode = Add-RichTreeNode $resourceNode "other principals on same scope ($coAssignedCount)" -PassThru
      foreach ($principalGroup in $principalGroups) {
        $principal = $principalGroup.Group | Select-Object -First 1
        $principalLabel = Get-OwnerLensDisplayValue -Value $principal.principalDisplayName -Fallback (Get-OwnerLensDisplayValue -Value $principal.principalName -Fallback $principal.principalId)
        $principalType = Get-OwnerLensDisplayValue -Value $principal.principalType -Fallback "Principal"
        $principalId = Get-OwnerLensDisplayValue -Value $principal.principalId -Fallback "unknown id"
        $principalUpn = Get-OwnerLensDisplayValue -Value $principal.principalName -Fallback "unknown upn"
        $hasDataAccess = [bool](@($principalGroup.Group | Where-Object {
              [bool]$_.isStorageDataReadRole
            }).Count -gt 0)
        $principalText = Format-OwnerLensPrincipalLabel `
          -Text (Get-OwnerLensPrincipalDisplayText -Label $principalLabel -PrincipalType $principalType -PrincipalId $principalId -PrincipalUpn $principalUpn) `
          -PrincipalType $principalType `
          -HasDataAccess $hasDataAccess
        $principalNode = Add-RichTreeNode $coAssignedNode $principalText -PassThru
        $principalRoles = @($principalGroup.Group | Sort-Object roleDefinitionName, subscriptionName | ForEach-Object {
            Get-OwnerLensDisplayValue -Value $_.roleDefinitionName -Fallback "unknown role"
          } | Sort-Object -Unique)
        foreach ($roleName in $principalRoles) {
          Add-RichTreeNode $principalNode $roleName
        }
      }
    }

    $activityCallers = @($rbacScopeActivityCallers | Where-Object {
        @($_.rbacScopes) -contains $scope
      } | Sort-Object @{ Expression = "eventCount"; Descending = $true }, callerName, caller)
    if ($activityCallers.Count -gt 0) {
      $activityNode = Add-RichTreeNode $resourceNode "recent activity callers ($($activityCallers.Count))" -PassThru
      foreach ($caller in $activityCallers) {
        $callerLabel = Get-OwnerLensDisplayValue -Value $caller.callerName -Fallback (Get-OwnerLensDisplayValue -Value $caller.caller -Fallback $caller.callerKey)
        $callerType = Get-OwnerLensActivityCallerPrincipalType -Caller $caller
        $callerId = Get-OwnerLensDisplayValue -Value $caller.callerObjectId -Fallback $caller.callerAppId
        $highlightCaller = [bool]$caller.matchesInspectedServicePrincipal -or
          ([string]$callerType).Equals("User", [System.StringComparison]::OrdinalIgnoreCase)
        $callerText = Format-OwnerLensPrincipalLabel `
          -Text (Get-OwnerLensPrincipalDisplayText -Label $callerLabel -PrincipalType $callerType -PrincipalId $callerId -PrincipalUpn ([string]$caller.caller)) `
          -PrincipalType $callerType `
          -HasDataAccess $highlightCaller
        Add-RichTreeNode $activityNode "$callerText (events=$($caller.eventCount), lastSeen=$($caller.lastSeen), inspectedSP=$($caller.matchesInspectedServicePrincipal))"
      }
    }

    $storageAccounts = @($storageAccountsWithRbac | Where-Object {
        Test-OwnerLensResourceUnderScope -ResourceId ([string]$_.resourceId) -Scope $scope
      } | Sort-Object name)
    if ($storageAccounts.Count -gt 0) {
      $storageNode = Add-RichTreeNode $resourceNode "storage accounts with data-plane read ($($storageAccounts.Count))" -PassThru
      foreach ($storageAccount in $storageAccounts) {
        $readServices = @($storageAccount.dataPlaneReadServices) -join ","
        $verificationStatus = Get-OwnerLensDisplayValue -Value $storageAccount.dataAccessVerificationStatus -Fallback "Unknown"
        $storageAccountNode = Add-RichTreeNode $storageNode "$(Format-OwnerLensRichLink -Text ([string]$storageAccount.name) -Uri (ConvertTo-OwnerLensAzurePortalResourceUri -ResourceId ([string]$storageAccount.resourceId))) (rg=$($storageAccount.resourceGroup), location=$($storageAccount.location), read=$readServices, diagnostics=$verificationStatus)" -PassThru
        Add-RichTreeNode $storageAccountNode (Format-OwnerLensStorageDiagnosticStatus -StorageAccount $storageAccount)

        $blobParticipants = @($blobReadCallers | Where-Object {
            @($_.storageAccounts) -contains [string]$storageAccount.name
          } | Sort-Object @{ Expression = "blobAccessCount"; Descending = $true }, requesterUpn, requesterAppId)
        if ($blobParticipants.Count -gt 0) {
          $participantsNode = Add-RichTreeNode $storageAccountNode "blob data-plane participants ($($blobParticipants.Count))" -PassThru
          foreach ($participant in $blobParticipants) {
            $participantLabel = Get-OwnerLensDisplayValue -Value $participant.requesterUpn -Fallback (Get-OwnerLensDisplayValue -Value $participant.requesterAppId -Fallback $participant.requesterKey)
            Add-RichTreeNode $participantsNode "$participantLabel ($($participant.requesterType), reads=$($participant.blobReadCount), publishes=$($participant.blobPublishCount), inspectedSP=$($participant.matchesInspectedServicePrincipal))"
          }
        }
      }
    }
  }

  return $root
}

# SIG # Begin signature block
# MII9MAYJKoZIhvcNAQcCoII9ITCCPR0CAQExDzANBglghkgBZQMEAgEFADB5Bgor
# BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG
# KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCClnOwHvslizpQU
# sCXsSNydQR5G+Ao7ZEVpYEg3tyawt6CCIfYwggXMMIIDtKADAgECAhBUmNLR1FsZ
# lUgTecgRwIeZMA0GCSqGSIb3DQEBDAUAMHcxCzAJBgNVBAYTAlVTMR4wHAYDVQQK
# ExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xSDBGBgNVBAMTP01pY3Jvc29mdCBJZGVu
# dGl0eSBWZXJpZmljYXRpb24gUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgMjAy
# MDAeFw0yMDA0MTYxODM2MTZaFw00NTA0MTYxODQ0NDBaMHcxCzAJBgNVBAYTAlVT
# MR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xSDBGBgNVBAMTP01pY3Jv
# c29mdCBJZGVudGl0eSBWZXJpZmljYXRpb24gUm9vdCBDZXJ0aWZpY2F0ZSBBdXRo
# b3JpdHkgMjAyMDCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBALORKgeD
# Bmf9np3gx8C3pOZCBH8Ppttf+9Va10Wg+3cL8IDzpm1aTXlT2KCGhFdFIMeiVPvH
# or+Kx24186IVxC9O40qFlkkN/76Z2BT2vCcH7kKbK/ULkgbk/WkTZaiRcvKYhOuD
# PQ7k13ESSCHLDe32R0m3m/nJxxe2hE//uKya13NnSYXjhr03QNAlhtTetcJtYmrV
# qXi8LW9J+eVsFBT9FMfTZRY33stuvF4pjf1imxUs1gXmuYkyM6Nix9fWUmcIxC70
# ViueC4fM7Ke0pqrrBc0ZV6U6CwQnHJFnni1iLS8evtrAIMsEGcoz+4m+mOJyoHI1
# vnnhnINv5G0Xb5DzPQCGdTiO0OBJmrvb0/gwytVXiGhNctO/bX9x2P29Da6SZEi3
# W295JrXNm5UhhNHvDzI9e1eM80UHTHzgXhgONXaLbZ7LNnSrBfjgc10yVpRnlyUK
# xjU9lJfnwUSLgP3B+PR0GeUw9gb7IVc+BhyLaxWGJ0l7gpPKWeh1R+g/OPTHU3mg
# trTiXFHvvV84wRPmeAyVWi7FQFkozA8kwOy6CXcjmTimthzax7ogttc32H83rwjj
# O3HbbnMbfZlysOSGM1l0tRYAe1BtxoYT2v3EOYI9JACaYNq6lMAFUSw0rFCZE4e7
# swWAsk0wAly4JoNdtGNz764jlU9gKL431VulAgMBAAGjVDBSMA4GA1UdDwEB/wQE
# AwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTIftJqhSobyhmYBAcnz1AQ
# T2ioojAQBgkrBgEEAYI3FQEEAwIBADANBgkqhkiG9w0BAQwFAAOCAgEAr2rd5hnn
# LZRDGU7L6VCVZKUDkQKL4jaAOxWiUsIWGbZqWl10QzD0m/9gdAmxIR6QFm3FJI9c
# Zohj9E/MffISTEAQiwGf2qnIrvKVG8+dBetJPnSgaFvlVixlHIJ+U9pW2UYXeZJF
# xBA2CFIpF8svpvJ+1Gkkih6PsHMNzBxKq7Kq7aeRYwFkIqgyuH4yKLNncy2RtNwx
# AQv3Rwqm8ddK7VZgxCwIo3tAsLx0J1KH1r6I3TeKiW5niB31yV2g/rarOoDXGpc8
# FzYiQR6sTdWD5jw4vU8w6VSp07YEwzJ2YbuwGMUrGLPAgNW3lbBeUU0i/OxYqujY
# lLSlLu2S3ucYfCFX3VVj979tzR/SpncocMfiWzpbCNJbTsgAlrPhgzavhgplXHT2
# 6ux6anSg8Evu75SjrFDyh+3XOjCDyft9V77l4/hByuVkrrOj7FjshZrM77nq81YY
# uVxzmq/FdxeDWds3GhhyVKVB0rYjdaNDmuV3fJZ5t0GNv+zcgKCf0Xd1WF81E+Al
# GmcLfc4l+gcK5GEh2NQc5QfGNpn0ltDGFf5Ozdeui53bFv0ExpK91IjmqaOqu/dk
# ODtfzAzQNb50GQOmxapMomE2gj4d8yu8l13bS3g7LfU772Aj6PXsCyM2la+YZr9T
# 03u4aUoqlmZpxJTG9F9urJh4iIAGXKKy7aIwggaoMIIEkKADAgECAhMzAAVPfTUJ
# QAZQHopGAAAABU99MA0GCSqGSIb3DQEBDAUAMFoxCzAJBgNVBAYTAlVTMR4wHAYD
# VQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xKzApBgNVBAMTIk1pY3Jvc29mdCBJ
# RCBWZXJpZmllZCBDUyBBT0MgQ0EgMDQwHhcNMjYwODI1MDgwNDExWhcNMjYwODI4
# MDgwNDExWjBpMQswCQYDVQQGEwJQTDEXMBUGA1UECB4OAUEA8wBkAHoAawBpAGUx
# DzANBgNVBAcTBldpZWx1bjEXMBUGA1UEChMOc29mdDRwbSBzcCB6b28xFzAVBgNV
# BAMTDnNvZnQ0cG0gc3Agem9vMIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIBigKC
# AYEAocE6bh7BfN0QU54JIUvRPWmy+ysJUci/b3hULZiKuxSXgSEDL84ShpNAGwrh
# lV6tPR5vcscj86/4XIFBEska7rrQn8vTXT1jHQs5osShbzpPVYGQ7XZoxZ3UKtjg
# t8Qlk9SdprbULZjoAOtC3PJd4nAC8coEpIOcMlorOuqBGvpfoojTOlN6Zg/Jib4x
# tbUMvRloe2so7oo27Vy/sXxGiyp1/uOPa+4r3IxB5/WUJ1MQBiql7DDwpUJNd1wV
# EftVYiuKDM2NE5l/eGKMIwRwhReCAloZOh6OFkOXSJ6g4hCqWeecT2D6fQvyn8ZZ
# pawAgbtLA5urPZejm/mqoTEqTx1KWQW+k8yqiFqLrxVlGtb0SHZxLVvjTd9gSwy4
# oANA6jfb/JJg5g1M3EeKIQPV5jvGIl6yfbOhyTggX1etcvPI4eXEw+f1kmh8TdTU
# yHLBbuZ9kMWG2qtVmpqwtHrL2UwBAKo5MhXa3e6ERoVnEcROadONbo27S8WHqo3T
# uRFxAgMBAAGjggHWMIIB0jAMBgNVHRMBAf8EAjAAMA4GA1UdDwEB/wQEAwIHgDA9
# BgNVHSUENjA0BgorBgEEAYI3YQEABggrBgEFBQcDAwYcKwYBBAGCN2GCycz3dYGA
# 0Y0Tg469piSB0sq0aDAdBgNVHQ4EFgQURabqFJmKZYz1eHc7Xhaz0j6pNQ4wHwYD
# VR0jBBgwFoAUayVB3vtrfP0YgAotf492XapzPbgwZwYDVR0fBGAwXjBcoFqgWIZW
# aHR0cDovL3d3dy5taWNyb3NvZnQuY29tL3BraW9wcy9jcmwvTWljcm9zb2Z0JTIw
# SUQlMjBWZXJpZmllZCUyMENTJTIwQU9DJTIwQ0ElMjAwNC5jcmwwdAYIKwYBBQUH
# AQEEaDBmMGQGCCsGAQUFBzAChlhodHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtp
# b3BzL2NlcnRzL01pY3Jvc29mdCUyMElEJTIwVmVyaWZpZWQlMjBDUyUyMEFPQyUy
# MENBJTIwMDQuY3J0MFQGA1UdIARNMEswSQYEVR0gADBBMD8GCCsGAQUFBwIBFjNo
# dHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpb3BzL0RvY3MvUmVwb3NpdG9yeS5o
# dG0wDQYJKoZIhvcNAQEMBQADggIBAA7WN0dZBECI5337xXm8N31AzYt/jteKg705
# rwgWajF4r9oGfz7dvPc6zUYpu6D9ZzkSL4nlGAWXb/vlBn8uh48UltXdZWdwIS34
# mLMUdGr4OMKrpCakWAmvip4pS+KP/DMoFX7L5Fs53gghdFU6Z54OnUDHODPPF44H
# Zjq4Z/E0Xu2gVTfvQGBwzq6lNjxCXRR1v+XG1v0s+s9f/qPKAh9VDfPLRnb1w1PF
# JuhC9GOpwU0b+8P8F6HdzRLoyiVkPIHEoWVxhQNnqk860hJXMCZ+MneMJCOWpRQO
# eTzPVvpyMzXny21kKvNlMg1M/hdlTXoauvBbH0ttDopbSJNKTpqwNDRiLXlLubbv
# pKIBSvUJGkjJjGvoK+rEG1C2YUJdNePG01Lm6HffemlVxk41akC6QlzUKZIsIm9F
# PcyHWVsmH7yQ2aH5gqKQfhC9Y5w6c5WSQ6bqJAixCMTeNtV0NHleXxRZ5qLI+cfC
# fX0zzzXaAkYDmwkmiHuu9CTMsCeTP6Oxi8QPoZinWPgktOnFaMknT5gDLWWzpTuc
# b3S1Wt41UhuPLP2Jgi+rID9F4laca10Ir2VOMgS5oz0roDTW5wOWUWQl/+2ISqoE
# shl+RwZcyi4L571Akr6hjt4uo7rESFzentjz57qj/5r0asX9mQkcZL7WvmqpePrI
# RxtltUE3MIIGqDCCBJCgAwIBAgITMwAFT301CUAGUB6KRgAAAAVPfTANBgkqhkiG
# 9w0BAQwFADBaMQswCQYDVQQGEwJVUzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBv
# cmF0aW9uMSswKQYDVQQDEyJNaWNyb3NvZnQgSUQgVmVyaWZpZWQgQ1MgQU9DIENB
# IDA0MB4XDTI2MDgyNTA4MDQxMVoXDTI2MDgyODA4MDQxMVowaTELMAkGA1UEBhMC
# UEwxFzAVBgNVBAgeDgFBAPMAZAB6AGsAaQBlMQ8wDQYDVQQHEwZXaWVsdW4xFzAV
# BgNVBAoTDnNvZnQ0cG0gc3Agem9vMRcwFQYDVQQDEw5zb2Z0NHBtIHNwIHpvbzCC
# AaIwDQYJKoZIhvcNAQEBBQADggGPADCCAYoCggGBAKHBOm4ewXzdEFOeCSFL0T1p
# svsrCVHIv294VC2YirsUl4EhAy/OEoaTQBsK4ZVerT0eb3LHI/Ov+FyBQRLJGu66
# 0J/L0109Yx0LOaLEoW86T1WBkO12aMWd1CrY4LfEJZPUnaa21C2Y6ADrQtzyXeJw
# AvHKBKSDnDJaKzrqgRr6X6KI0zpTemYPyYm+MbW1DL0ZaHtrKO6KNu1cv7F8Rosq
# df7jj2vuK9yMQef1lCdTEAYqpeww8KVCTXdcFRH7VWIrigzNjROZf3hijCMEcIUX
# ggJaGToejhZDl0ieoOIQqlnnnE9g+n0L8p/GWaWsAIG7SwObqz2Xo5v5qqExKk8d
# SlkFvpPMqohai68VZRrW9Eh2cS1b403fYEsMuKADQOo32/ySYOYNTNxHiiED1eY7
# xiJesn2zock4IF9XrXLzyOHlxMPn9ZJofE3U1MhywW7mfZDFhtqrVZqasLR6y9lM
# AQCqOTIV2t3uhEaFZxHETmnTjW6Nu0vFh6qN07kRcQIDAQABo4IB1jCCAdIwDAYD
# VR0TAQH/BAIwADAOBgNVHQ8BAf8EBAMCB4AwPQYDVR0lBDYwNAYKKwYBBAGCN2EB
# AAYIKwYBBQUHAwMGHCsGAQQBgjdhgsnM93WBgNGNE4OOvaYkgdLKtGgwHQYDVR0O
# BBYEFEWm6hSZimWM9Xh3O14Ws9I+qTUOMB8GA1UdIwQYMBaAFGslQd77a3z9GIAK
# LX+Pdl2qcz24MGcGA1UdHwRgMF4wXKBaoFiGVmh0dHA6Ly93d3cubWljcm9zb2Z0
# LmNvbS9wa2lvcHMvY3JsL01pY3Jvc29mdCUyMElEJTIwVmVyaWZpZWQlMjBDUyUy
# MEFPQyUyMENBJTIwMDQuY3JsMHQGCCsGAQUFBwEBBGgwZjBkBggrBgEFBQcwAoZY
# aHR0cDovL3d3dy5taWNyb3NvZnQuY29tL3BraW9wcy9jZXJ0cy9NaWNyb3NvZnQl
# MjBJRCUyMFZlcmlmaWVkJTIwQ1MlMjBBT0MlMjBDQSUyMDA0LmNydDBUBgNVHSAE
# TTBLMEkGBFUdIAAwQTA/BggrBgEFBQcCARYzaHR0cDovL3d3dy5taWNyb3NvZnQu
# Y29tL3BraW9wcy9Eb2NzL1JlcG9zaXRvcnkuaHRtMA0GCSqGSIb3DQEBDAUAA4IC
# AQAO1jdHWQRAiOd9+8V5vDd9QM2Lf47XioO9Oa8IFmoxeK/aBn8+3bz3Os1GKbug
# /Wc5Ei+J5RgFl2/75QZ/LoePFJbV3WVncCEt+JizFHRq+DjCq6QmpFgJr4qeKUvi
# j/wzKBV+y+RbOd4IIXRVOmeeDp1AxzgzzxeOB2Y6uGfxNF7toFU370BgcM6upTY8
# Ql0Udb/lxtb9LPrPX/6jygIfVQ3zy0Z29cNTxSboQvRjqcFNG/vD/Beh3c0S6Mol
# ZDyBxKFlcYUDZ6pPOtISVzAmfjJ3jCQjlqUUDnk8z1b6cjM158ttZCrzZTINTP4X
# ZU16GrrwWx9LbQ6KW0iTSk6asDQ0Yi15S7m276SiAUr1CRpIyYxr6CvqxBtQtmFC
# XTXjxtNS5uh333ppVcZONWpAukJc1CmSLCJvRT3Mh1lbJh+8kNmh+YKikH4QvWOc
# OnOVkkOm6iQIsQjE3jbVdDR5Xl8UWeaiyPnHwn19M8812gJGA5sJJoh7rvQkzLAn
# kz+jsYvED6GYp1j4JLTpxWjJJ0+YAy1ls6U7nG90tVreNVIbjyz9iYIvqyA/ReJW
# nGtdCK9lTjIEuaM9K6A01ucDllFkJf/tiEqqBLIZfkcGXMouC+e9QJK+oY7eLqO6
# xEhc3p7Y8+e6o/+a9GrF/ZkJHGS+1r5qqXj6yEcbZbVBNzCCBygwggUQoAMCAQIC
# EzMAAAAWMZKNkgJle5oAAAAAABYwDQYJKoZIhvcNAQEMBQAwYzELMAkGA1UEBhMC
# VVMxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjE0MDIGA1UEAxMrTWlj
# cm9zb2Z0IElEIFZlcmlmaWVkIENvZGUgU2lnbmluZyBQQ0EgMjAyMTAeFw0yNjAz
# MjYxODExMjlaFw0zMTAzMjYxODExMjlaMFoxCzAJBgNVBAYTAlVTMR4wHAYDVQQK
# ExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xKzApBgNVBAMTIk1pY3Jvc29mdCBJRCBW
# ZXJpZmllZCBDUyBBT0MgQ0EgMDQwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIK
# AoICAQDKVfrI2+gJMM/0bQ5OVKNdvOASzLbUUMvXuf+Vl7YGuofPaZHVo3gMHF5i
# nT+GMSpIcfIZ9qtXU1UG68ry8vNbQtOL4Nm30ifXpqI1+ByiAWLO1YT0WnzG7XPO
# uoTeeWsNZv5FmjxCsReBZvyzyzCyXZbu1EQfJxWTH4ebUwtAiW9rqMf9eDj/wYhi
# EfNteJV3ZFeibD2ztCHr9JhFdd97XbnCHgQoTIqc02X5xlRKtUGBa++OtHBBjiJ/
# uwBnzTkqu4FjpZjQeJtrmda+ur1CT2jflWIB/ypn7u7V9tvW9wJbJYt/H2EtJ0GO
# NWxJZ7TEu8jWPindOO3lzPP7UtzS/mVDV94HucWaltmsra6zSG8BoEJ87IM8QSb7
# vfm/O41FhYkUv89WIj5ES2O4kxyiMSfe95CMivCuYrRP2hKvx7egPMrWgDDBkxML
# grKZO9hRNUMm8vk3w5b9SogHOyJVhxyFm8aFXfIxgqDF4S0g4bhbhnzljmSlCLlu
# mMZcXFGDjpF2tNoAu3VGFGYtHtTSNVKvZpgB3b4ynaoDkbPf+Wg4523jt4VneasB
# gZhC1srZI2NCnCBBfgjLq04pqEKAWEohyW2K29KSkkHvt5VaE1ac3Yt+oyiOzMS5
# 7tXwQDJLGvLg/OXFO0VNvczDndfIfXYExB/ab2PuMSwd5VIBOwIDAQABo4IB3DCC
# AdgwDgYDVR0PAQH/BAQDAgGGMBAGCSsGAQQBgjcVAQQDAgEAMB0GA1UdDgQWBBRr
# JUHe+2t8/RiACi1/j3ZdqnM9uDBUBgNVHSAETTBLMEkGBFUdIAAwQTA/BggrBgEF
# BQcCARYzaHR0cDovL3d3dy5taWNyb3NvZnQuY29tL3BraW9wcy9Eb2NzL1JlcG9z
# aXRvcnkuaHRtMBkGCSsGAQQBgjcUAgQMHgoAUwB1AGIAQwBBMBIGA1UdEwEB/wQI
# MAYBAf8CAQAwHwYDVR0jBBgwFoAU2UEpsA8PY2zvadf1zSmepEhqMOYwcAYDVR0f
# BGkwZzBloGOgYYZfaHR0cDovL3d3dy5taWNyb3NvZnQuY29tL3BraW9wcy9jcmwv
# TWljcm9zb2Z0JTIwSUQlMjBWZXJpZmllZCUyMENvZGUlMjBTaWduaW5nJTIwUENB
# JTIwMjAyMS5jcmwwfQYIKwYBBQUHAQEEcTBvMG0GCCsGAQUFBzAChmFodHRwOi8v
# d3d3Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2NlcnRzL01pY3Jvc29mdCUyMElEJTIw
# VmVyaWZpZWQlMjBDb2RlJTIwU2lnbmluZyUyMFBDQSUyMDIwMjEuY3J0MA0GCSqG
# SIb3DQEBDAUAA4ICAQAG1VBeVHTVRBljlcZD3IiMxwPyMjQyLNaEnVu5mODm2hRB
# JfH8GsBLATmrHAc8F47jmk5CnpUPiIguCbw6Z/KVj4Dsoiq228NSLMLewFfGMri7
# uwNGLISC5ccp8vUdADDEIsS2dE+QI9OwkDpv3XuUD7d+hAgcLVcMOl1AsfEZtsZe
# nhGvSYUrm/FuLq0BqEGL9GXM5c+Ho9q8o+Vn/S+GWQN2y+gkRO15s0kI05nUpq/d
# OD4ri9rgVs6tipEd0YZqGgD+CZNiaZWrDTOQbNPncd2F9qOsUa20miYruoT5PwJA
# aI+QQiTE2ZJeMJOkOpzhTUgqVMZwZidEUZKCqudaeQA08WwnkQMfKyHzaU8j48UL
# cU4hUwvMsv7fSurOe9GAdRQCPvF8WcSK5oDHe8VVJM4tv6KKCm91HqLx9JamBgRI
# 6R2SfY3nu26EGznu0rCg/769z8xWm4PVcC2ZaL6VlKVqFp1NsN8YqMyf5t+bbGVb
# 09noFKcJG/UwyGlxRmQBlfeBUQx5/ytlzZzsEnhrJF9fTAfje8j3OdX5lEnePTFQ
# LRlvzZFBqUXnIeQKv3fHQjC9m2fo/Z01DII/qp3d8LhGVUW0BCG04fRwHJNH8iqq
# CG/qofMv+kym2AxBDnHzNgRjL60JOFiBgiurvLhYQNhB95KWojFA6shQnggkMTCC
# B54wggWGoAMCAQICEzMAAAAHh6M0o3uljhwAAAAAAAcwDQYJKoZIhvcNAQEMBQAw
# dzELMAkGA1UEBhMCVVMxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjFI
# MEYGA1UEAxM/TWljcm9zb2Z0IElkZW50aXR5IFZlcmlmaWNhdGlvbiBSb290IENl
# cnRpZmljYXRlIEF1dGhvcml0eSAyMDIwMB4XDTIxMDQwMTIwMDUyMFoXDTM2MDQw
# MTIwMTUyMFowYzELMAkGA1UEBhMCVVMxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jw
# b3JhdGlvbjE0MDIGA1UEAxMrTWljcm9zb2Z0IElEIFZlcmlmaWVkIENvZGUgU2ln
# bmluZyBQQ0EgMjAyMTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBALLw
# wK8ZiCji3VR6TElsaQhVCbRS/3pK+MHrJSj3Zxd3KU3rlfL3qrZilYKJNqztA9OQ
# acr1AwoNcHbKBLbsQAhBnIB34zxf52bDpIO3NJlfIaTE/xrweLoQ71lzCHkD7A4A
# s1Bs076Iu+mA6cQzsYYH/Cbl1icwQ6C65rU4V9NQhNUwgrx9rGQ//h890Q8JdjLL
# w0nV+ayQ2Fbkd242o9kH82RZsH3HEyqjAB5a8+Ae2nPIPc8sZU6ZE7iRrRZywRmr
# KDp5+TcmJX9MRff241UaOBs4NmHOyke8oU1TYrkxh+YeHgfWo5tTgkoSMoayqoDp
# HOLJs+qG8Tvh8SnifW2Jj3+ii11TS8/FGngEaNAWrbyfNrC69oKpRQXY9bGH6jn9
# NEJv9weFxhTwyvx9OJLXmRGbAUXN1U9nf4lXezky6Uh/cgjkVd6CGUAf0K+Jw+GE
# /5VpIVbcNr9rNE50Sbmy/4RTCEGvOq3GhjITbCa4crCzTTHgYYjHs1NbOc6brH+e
# KpWLtr+bGecy9CrwQyx7S/BfYJ+ozst7+yZtG2wR461uckFu0t+gCwLdN0A6cFtS
# RtR8bvxVFyWwTtgMMFRuBa3vmUOTnfKLsLefRaQcVTgRnzeLzdpt32cdYKp+dhr2
# ogc+qM6K4CBI5/j4VFyC4QFeUP2YAidLtvpXRRo3AgMBAAGjggI1MIICMTAOBgNV
# HQ8BAf8EBAMCAYYwEAYJKwYBBAGCNxUBBAMCAQAwHQYDVR0OBBYEFNlBKbAPD2Ns
# 72nX9c0pnqRIajDmMFQGA1UdIARNMEswSQYEVR0gADBBMD8GCCsGAQUFBwIBFjNo
# dHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpb3BzL0RvY3MvUmVwb3NpdG9yeS5o
# dG0wGQYJKwYBBAGCNxQCBAweCgBTAHUAYgBDAEEwDwYDVR0TAQH/BAUwAwEB/zAf
# BgNVHSMEGDAWgBTIftJqhSobyhmYBAcnz1AQT2ioojCBhAYDVR0fBH0wezB5oHeg
# dYZzaHR0cDovL3d3dy5taWNyb3NvZnQuY29tL3BraW9wcy9jcmwvTWljcm9zb2Z0
# JTIwSWRlbnRpdHklMjBWZXJpZmljYXRpb24lMjBSb290JTIwQ2VydGlmaWNhdGUl
# MjBBdXRob3JpdHklMjAyMDIwLmNybDCBwwYIKwYBBQUHAQEEgbYwgbMwgYEGCCsG
# AQUFBzAChnVodHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2NlcnRzL01p
# Y3Jvc29mdCUyMElkZW50aXR5JTIwVmVyaWZpY2F0aW9uJTIwUm9vdCUyMENlcnRp
# ZmljYXRlJTIwQXV0aG9yaXR5JTIwMjAyMC5jcnQwLQYIKwYBBQUHMAGGIWh0dHA6
# Ly9vbmVvY3NwLm1pY3Jvc29mdC5jb20vb2NzcDANBgkqhkiG9w0BAQwFAAOCAgEA
# fyUqnv7Uq+rdZgrbVyNMul5skONbhls5fccPlmIbzi+OwVdPQ4H55v7VOInnmezQ
# EeW4LqK0wja+fBznANbXLB0KrdMCbHQpbLvG6UA/Xv2pfpVIE1CRFfNF4XKO8XYE
# a3oW8oVH+KZHgIQRIwAbyFKQ9iyj4aOWeAzwk+f9E5StNp5T8FG7/VEURIVWArbA
# zPt9ThVN3w1fAZkF7+YU9kbq1bCR2YD+MtunSQ1Rft6XG7b4e0ejRA7mB2IoX5hN
# h3UEauY0byxNRG+fT2MCEhQl9g2i2fs6VOG19CNep7SquKaBjhWmirYyANb0RJSL
# WjinMLXNOAga10n8i9jqeprzSMU5ODmrMCJE12xS/NWShg/tuLjAsKP6SzYZ+1Ry
# 358ZTFcx0FS/mx2vSoU8s8HRvy+rnXqyUJ9HBqS0DErVLjQwK8VtsBdekBmdTbQV
# oCgPCqr+PDPB3xajYnzevs7eidBsM71PINK2BoE2UfMwxCCX3mccFgx6UsQeRSdV
# VVNSyALQe6PT12418xon2iDGE81OGCreLzDcMAZnrUAx4XQLUz6ZTl65yPUiOh3k
# 7Yww94lDf+8oG2oZmDh5O1Qe38E+M3vhKwmzIeoB1dVLlz4i3IpaDcR+iuGjH2Td
# aC1ZOmBXiCRKJLj4DT2uhJ04ji+tHD6n58vhavFIrmcxghqQMIIajAIBATBxMFox
# CzAJBgNVBAYTAlVTMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xKzAp
# BgNVBAMTIk1pY3Jvc29mdCBJRCBWZXJpZmllZCBDUyBBT0MgQ0EgMDQCEzMABU99
# NQlABlAeikYAAAAFT30wDQYJYIZIAWUDBAIBBQCgXjAQBgorBgEEAYI3AgEMMQIw
# ADAZBgkqhkiG9w0BCQMxDAYKKwYBBAGCNwIBBDAvBgkqhkiG9w0BCQQxIgQgWZsv
# 0/khzygtYNL/De+pvnAaEuee2OqFJPZPeCmnFukwDQYJKoZIhvcNAQEBBQAEggGA
# muq/z94+xqH+SIZSe+hl04u/5tNbDw1f/RTiIRiBWea97TliFXoeEU5727meev3k
# KJbAmEbfDybcKlyAidCKiezusxlvTBEJLmqw1sg+r0nzQOV1ShV/ziBwTzAbsuet
# iyaEOIUO0WINxCpSqqsQwwYH6K5IAnd64jcGyfx522f54lASFzTk6F98mhmW2Xo9
# AeU59L7CKEPsIGTPlPW6HTHMD5lVrsPLnauRNX7w6AVIdLNqWoBeLt42VkdvBlQj
# NkqlFBzfGjvtr4edDeDmk2Q6XY6GcUvAmM5y49zLV9PJcnWBqSQmQJGL13uLXH6Z
# EZPtRt24WDeqrMhHDZ4ddK8rD+OOWTe46KrvC64ZfWL9hnVkA91jlYtCX1glxvi7
# T5nkuL0PF2GV2FPpgEWGfNvRXFop8Vdr6kbVuRV+oKM1/6rO5mseAe7ijJ0/UM8+
# 2bTjia4zm8jEra+Eh819T6Aji1QgcdT/domwEks9Qm8ZMsLjuP3m+IiDxfysfi7c
# oYIYEDCCGAwGCisGAQQBgjcDAwExghf8MIIX+AYJKoZIhvcNAQcCoIIX6TCCF+UC
# AQMxDzANBglghkgBZQMEAgEFADCCAWEGCyqGSIb3DQEJEAEEoIIBUASCAUwwggFI
# AgEBBgorBgEEAYRZCgMBMDEwDQYJYIZIAWUDBAIBBQAEIDrFvlUcBf69al9hlWQA
# Q5b8fFTd7RbUn3R6lFUwUtc5AgZqhGwUNJcYEjIwMjYwODI2MTIxMTE3LjQ2WjAE
# gAIB9KCB4aSB3jCB2zELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24x
# EDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlv
# bjElMCMGA1UECxMcTWljcm9zb2Z0IEFtZXJpY2EgT3BlcmF0aW9uczEnMCUGA1UE
# CxMeblNoaWVsZCBUU1MgRVNOOjdBMDAtMDVFMC1EOTQ3MTUwMwYDVQQDEyxNaWNy
# b3NvZnQgUHVibGljIFJTQSBUaW1lIFN0YW1waW5nIEF1dGhvcml0eaCCDyEwggeC
# MIIFaqADAgECAhMzAAAABeXPD/9mLsmHAAAAAAAFMA0GCSqGSIb3DQEBDAUAMHcx
# CzAJBgNVBAYTAlVTMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xSDBG
# BgNVBAMTP01pY3Jvc29mdCBJZGVudGl0eSBWZXJpZmljYXRpb24gUm9vdCBDZXJ0
# aWZpY2F0ZSBBdXRob3JpdHkgMjAyMDAeFw0yMDExMTkyMDMyMzFaFw0zNTExMTky
# MDQyMzFaMGExCzAJBgNVBAYTAlVTMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9y
# YXRpb24xMjAwBgNVBAMTKU1pY3Jvc29mdCBQdWJsaWMgUlNBIFRpbWVzdGFtcGlu
# ZyBDQSAyMDIwMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAnnznUmP9
# 4MWfBX1jtQYioxwe1+eXM9ETBb1lRkd3kcFdcG9/sqtDlwxKoVIcaqDb+omFio5D
# HC4RBcbyQHjXCwMk/l3TOYtgoBjxnG/eViS4sOx8y4gSq8Zg49REAf5huXhIkQRK
# e3Qxs8Sgp02KHAznEa/Ssah8nWo5hJM1xznkRsFPu6rfDHeZeG1Wa1wISvlkpOQo
# oTULFm809Z0ZYlQ8Lp7i5F9YciFlyAKwn6yjN/kR4fkquUWfGmMopNq/B8U/pdoZ
# kZZQbxNlqJOiBGgCWpx69uKqKhTPVi3gVErnc/qi+dR8A2MiAz0kN0nh7SqINGbm
# w5OIRC0EsZ31WF3Uxp3GgZwetEKxLms73KG/Z+MkeuaVDQQheangOEMGJ4pQZH55
# ngI0Tdy1bi69INBV5Kn2HVJo9XxRYR/JPGAaM6xGl57Ei95HUw9NV/uC3yFjrhc0
# 87qLJQawSC3xzY/EXzsT4I7sDbxOmM2rl4uKK6eEpurRduOQ2hTkmG1hSuWYBunF
# GNv21Kt4N20AKmbeuSnGnsBCd2cjRKG79+TX+sTehawOoxfeOO/jR7wo3liwkGdz
# PJYHgnJ54UxbckF914AqHOiEV7xTnD1a69w/UTxwjEugpIPMIIE67SFZ2PMo27xj
# lLAHWW3l1CEAFjLNHd3EQ79PUr8FUXetXr0CAwEAAaOCAhswggIXMA4GA1UdDwEB
# /wQEAwIBhjAQBgkrBgEEAYI3FQEEAwIBADAdBgNVHQ4EFgQUa2koOjUvSGNAz3vY
# r0npPtk92yEwVAYDVR0gBE0wSzBJBgRVHSAAMEEwPwYIKwYBBQUHAgEWM2h0dHA6
# Ly93d3cubWljcm9zb2Z0LmNvbS9wa2lvcHMvRG9jcy9SZXBvc2l0b3J5Lmh0bTAT
# BgNVHSUEDDAKBggrBgEFBQcDCDAZBgkrBgEEAYI3FAIEDB4KAFMAdQBiAEMAQTAP
# BgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFMh+0mqFKhvKGZgEByfPUBBPaKii
# MIGEBgNVHR8EfTB7MHmgd6B1hnNodHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtp
# b3BzL2NybC9NaWNyb3NvZnQlMjBJZGVudGl0eSUyMFZlcmlmaWNhdGlvbiUyMFJv
# b3QlMjBDZXJ0aWZpY2F0ZSUyMEF1dGhvcml0eSUyMDIwMjAuY3JsMIGUBggrBgEF
# BQcBAQSBhzCBhDCBgQYIKwYBBQUHMAKGdWh0dHA6Ly93d3cubWljcm9zb2Z0LmNv
# bS9wa2lvcHMvY2VydHMvTWljcm9zb2Z0JTIwSWRlbnRpdHklMjBWZXJpZmljYXRp
# b24lMjBSb290JTIwQ2VydGlmaWNhdGUlMjBBdXRob3JpdHklMjAyMDIwLmNydDAN
# BgkqhkiG9w0BAQwFAAOCAgEAX4h2x35ttVoVdedMeGj6TuHYRJklFaW4sTQ5r+k7
# 7iB79cSLNe+GzRjv4pVjJviceW6AF6ycWoEYR0LYhaa0ozJLU5Yi+LCmcrdovkl5
# 3DNt4EXs87KDogYb9eGEndSpZ5ZM74LNvVzY0/nPISHz0Xva71QjD4h+8z2XMOZz
# Y7YQ0Psw+etyNZ1CesufU211rLslLKsO8F2aBs2cIo1k+aHOhrw9xw6JCWONNboZ
# 497mwYW5EfN0W3zL5s3ad4Xtm7yFM7Ujrhc0aqy3xL7D5FR2J7x9cLWMq7eb0oYi
# oXhqV2tgFqbKHeDick+P8tHYIFovIP7YG4ZkJWag1H91KlELGWi3SLv10o4KGag4
# 2pswjybTi4toQcC/irAodDW8HNtX+cbz0sMptFJK+KObAnDFHEsukxD+7jFfEV9H
# h/+CSxKRsmnuiovCWIOb+H7DRon9TlxydiFhvu88o0w35JkNbJxTk4MhF/KgaXn0
# GxdH8elEa2Imq45gaa8D+mTm8LWVydt4ytxYP/bqjN49D9NZ81coE6aQWm88TwIf
# 4R4YZbOpMKN0CyejaPNN41LGXHeCUMYmBx3PkP8ADHD1J2Cr/6tjuOOCztfp+o9N
# c+ZoIAkpUcA/X2gSMkgHAPUvIdtoSAHEUKiBhI6JQivRepyvWcl+JYbYbBh7pmgA
# XVswggeXMIIFf6ADAgECAhMzAAAAWGXN6z+h1/zSAAAAAABYMA0GCSqGSIb3DQEB
# DAUAMGExCzAJBgNVBAYTAlVTMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRp
# b24xMjAwBgNVBAMTKU1pY3Jvc29mdCBQdWJsaWMgUlNBIFRpbWVzdGFtcGluZyBD
# QSAyMDIwMB4XDTI1MTAyMzIwNDY1NVoXDTI2MTAyMjIwNDY1NVowgdsxCzAJBgNV
# BAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4w
# HAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xJTAjBgNVBAsTHE1pY3Jvc29m
# dCBBbWVyaWNhIE9wZXJhdGlvbnMxJzAlBgNVBAsTHm5TaGllbGQgVFNTIEVTTjo3
# QTAwLTA1RTAtRDk0NzE1MDMGA1UEAxMsTWljcm9zb2Z0IFB1YmxpYyBSU0EgVGlt
# ZSBTdGFtcGluZyBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIK
# AoICAQCdeDSkdpDs9UCWWf4dlmskVwugpt6SFbXIv5A0FSAUVSyNkgpqqo3iggmw
# kzemzSsk1I7ud0I1G5kNfZaC6vcCTvt5euWgFepmY7plVd4M1EIuV1bgDT81+PMn
# tdeR0SGOvzWCFcSlHvML7Bto036w9LHMsBkF6JsMU/tfCznBfRm0iw3Vrb5erlu9
# aneREzK3CyROO6dGB4tkv+0GnbfslV1E8UBD2NhEqkKpQGj+/XGMEtEJXc9qUqOc
# Z9vcw3hTuNXKqJ8UdKFydbkIRFGgGZRrqzKAPMVKvx7eD3dM80sVSK9QTQaYt9tf
# lx4PUa3UVxnrH8ktUBPOTn4FYdszHAkhWRU9OpJIyNDopMp1yerekfRzgAUmn+CW
# 9ymrRT1/NkiMkYa92mKyGVGXvtFC1SFKPEe8KfcsL/GpBDA4dJAOwaHo1fYPRF+x
# LIS1MAHIBp77bDUcHJMNNyaVM0sS5At4KPWA0F0haPRY5jIO2OND/yJNZjp7LW9v
# 2oeWMiPkeAid1Pk/0xiTZWDZ7uEpRk0E1sD+GyAGy6hn4hfz1a+MQ31psX3VLg4l
# W6KeYqws78wtueXuKS4PR03qgDRh7DINCdyzXawz0c627vZAD9NmV5+9byv3G0xc
# BihCVwaOyTxbhRztx+pWpsg+N2hzxnEHMtxdxXI/inlzIvC+QwIDAQABo4IByzCC
# AccwHQYDVR0OBBYEFHKNTcV6vhXFcn6GM9xEmfGdEgmwMB8GA1UdIwQYMBaAFGtp
# KDo1L0hjQM972K9J6T7ZPdshMGwGA1UdHwRlMGMwYaBfoF2GW2h0dHA6Ly93d3cu
# bWljcm9zb2Z0LmNvbS9wa2lvcHMvY3JsL01pY3Jvc29mdCUyMFB1YmxpYyUyMFJT
# QSUyMFRpbWVzdGFtcGluZyUyMENBJTIwMjAyMC5jcmwweQYIKwYBBQUHAQEEbTBr
# MGkGCCsGAQUFBzAChl1odHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2Nl
# cnRzL01pY3Jvc29mdCUyMFB1YmxpYyUyMFJTQSUyMFRpbWVzdGFtcGluZyUyMENB
# JTIwMjAyMC5jcnQwDAYDVR0TAQH/BAIwADAWBgNVHSUBAf8EDDAKBggrBgEFBQcD
# CDAOBgNVHQ8BAf8EBAMCB4AwZgYDVR0gBF8wXTBRBgwrBgEEAYI3TIN9AQEwQTA/
# BggrBgEFBQcCARYzaHR0cDovL3d3dy5taWNyb3NvZnQuY29tL3BraW9wcy9Eb2Nz
# L1JlcG9zaXRvcnkuaHRtMAgGBmeBDAEEAjANBgkqhkiG9w0BAQwFAAOCAgEAe+vE
# iJUXWIdxe/GslMIPx461s9Rsr3H4vPvSJh6GH4bRSg4xwx/ThAPq1A9N5nkeEYRO
# RyfStoMnk2l9tEG4oQffWvFtkr3ujXYpEM0nc27h49pQikf9NxbPw8tU4IQLLBLF
# sSAQbbSTLJ0Zzjpzn3W1fOl+QkNySOhivKlp6t15AtFAf0tqhNhl90DMyj4PLQ7U
# PMUmQXlieyYAzyW32vU21d0WN1sUwJtXl1q7riZXbazXzoDxSaL6Xbf35R7RxslA
# jKRaEiWGFaHFCCiSyofPuSnYYVkAB7JJOYg5A5bJc4DwkDxMhInKfckM6BK2/nzc
# /dXRBIAtPolcMJbboVXbTxUYkzOS/RLbaI5Nkn+hqZOmTxHMPyhZPyl9t7Wr+T9v
# E+JdhFvOmz3prlg6SjufRV2jrUM4mEv+aGTTVjfjyCrq+Eb9VNx0YeHWsKTA4zTk
# HfkBlmr0C0+l9HMmKesfPMZHH6vp8Pdxxgw8wxf83B3aKvOumHXvZ9BxJ/V8zC/A
# iGZ8fgZYkn6Z/UcDq5egA5UHJySC5e+WPyA+LtPYRLpFTz5Cyx+pM1MkqOwGF5Yp
# a/ZbgRJV6fYvuULPuLv0WED7SSnTJcmdjB3NZLSi9Mg1Qsg2bNXIxxJSbla5V/xh
# nfdwC53Y6mvo3X5G4tkNq8O+OJ6GUjl0f4YTLnoxggdDMIIHPwIBATB4MGExCzAJ
# BgNVBAYTAlVTMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xMjAwBgNV
# BAMTKU1pY3Jvc29mdCBQdWJsaWMgUlNBIFRpbWVzdGFtcGluZyBDQSAyMDIwAhMz
# AAAAWGXN6z+h1/zSAAAAAABYMA0GCWCGSAFlAwQCAQUAoIIEnDARBgsqhkiG9w0B
# CRACDzECBQAwGgYJKoZIhvcNAQkDMQ0GCyqGSIb3DQEJEAEEMBwGCSqGSIb3DQEJ
# BTEPFw0yNjA4MjYxMjExMTdaMC8GCSqGSIb3DQEJBDEiBCArLR9sJHpj51HgtNWG
# hSe4FmEAccfN9Oti0aOQxmJ29DCBuQYLKoZIhvcNAQkQAi8xgakwgaYwgaMwgaAE
# IMUiVLuyB9D7ACjVxZtbP5Y3r1UF2znyFutqf3X1ouhxMHwwZaRjMGExCzAJBgNV
# BAYTAlVTMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xMjAwBgNVBAMT
# KU1pY3Jvc29mdCBQdWJsaWMgUlNBIFRpbWVzdGFtcGluZyBDQSAyMDIwAhMzAAAA
# WGXN6z+h1/zSAAAAAABYMIIDXgYLKoZIhvcNAQkQAhIxggNNMIIDSaGCA0UwggNB
# MIICKQIBATCCAQmhgeGkgd4wgdsxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNo
# aW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29y
# cG9yYXRpb24xJTAjBgNVBAsTHE1pY3Jvc29mdCBBbWVyaWNhIE9wZXJhdGlvbnMx
# JzAlBgNVBAsTHm5TaGllbGQgVFNTIEVTTjo3QTAwLTA1RTAtRDk0NzE1MDMGA1UE
# AxMsTWljcm9zb2Z0IFB1YmxpYyBSU0EgVGltZSBTdGFtcGluZyBBdXRob3JpdHmi
# IwoBATAHBgUrDgMCGgMVAJ1keRvbp6twXY7ra8J1lR9RK8RcoGcwZaRjMGExCzAJ
# BgNVBAYTAlVTMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xMjAwBgNV
# BAMTKU1pY3Jvc29mdCBQdWJsaWMgUlNBIFRpbWVzdGFtcGluZyBDQSAyMDIwMA0G
# CSqGSIb3DQEBCwUAAgUA7jjNyTAiGA8yMDI2MDgyNjAyMjgyNVoYDzIwMjYwODI3
# MDIyODI1WjB0MDoGCisGAQQBhFkKBAExLDAqMAoCBQDuOM3JAgEAMAcCAQACAgcG
# MAcCAQACAhIPMAoCBQDuOh9JAgEAMDYGCisGAQQBhFkKBAIxKDAmMAwGCisGAQQB
# hFkKAwKgCjAIAgEAAgMHoSChCjAIAgEAAgMBhqAwDQYJKoZIhvcNAQELBQADggEB
# ACO+Qs1Cr0XZqDEPz7QyWGJHQgM4Ytn9Q2+dkLU71mfQPA/W0go++9/1Ufm00CNO
# V7yr16utC/dtN1JX6q4MT/au/rB94fG5yd8QI8j2wBMe6RqIvN2VlnJG0t6Xq9/t
# Bwk5Zd9PFw7LVJc23/EFZ+82vqaUw76WOxL+vInxcp4/2sKn61i+dmuuhq/5ciLU
# pdZO5MtmvSRGu37AKdX85uKUfEMcHmg7ZTX+mlfF+SHw65xXYL0S6JQaGZFC4nKX
# lsPmu8brJA5gw5QY0h4Y3eC845E8bFGnOF2ZghXJgW+mJ+HCBOGOpjoi52xIVez6
# eOPe9z1IGr6OwX2qCK7meW0wDQYJKoZIhvcNAQEBBQAEggIAffokd1xoI0Tsp10z
# hhbtx8sKlS2f8sZt2rpZvurtGYLvt6N+5RCJrGx4Dg9u6GsWGmHa4kTYov9i6T5S
# I6pA5tKrnJth7uDK9AkbuO6PZ26Hpwo8u/RNxCQNQyO+1MsSHNeSPJjWWtmIY5B8
# CtLg6yIgnBC97w8SDBcaDGCapimS2p0QXpnOkmXnANwJs9GSsByJE5b0OCEeQr73
# 2bvdc86D9BGRLbPMHC3d4LIKfRS0+J1wAhNE7TxTFudMUbnVIFNgTO2czusf2jAX
# ahu6HSOTkcm7e9UXAVOrMoQuGOy3zLissYwObuaoSf9tksKQt+HX9w4axY++MgXd
# uqF9JBjexv2DrGMYV7I5vLlbZIcT2s6Oxh5O6W5Vw7V1OlOSCoeNTZ2MNwOja6CU
# ny1eB7dtCS07Ode26W6K4XROSPDBUkUArjPZIpch65ckhLFfzAjMxJMYk388M4Rt
# kQXj3GK0TE5X5+5BTSsqsitiMgj6H4wAvM0bmfP6VUMmDS6xuPmKWs/JhafA4h9q
# SQ1dewJvk53fvKQR3RMC5VP8EXjEjXpEua59D3+eU7oVeSY+f+poRothwTa0y7gO
# dHquKyCsxtBdrK824ZSdmLpwkzp8k8RzoJuOrbFQRskY3+dCCsP+0v5DwYXGujZe
# kH4ncYKtB5jT9LXbLlH3GERl6Rc=
# SIG # End signature block