Private/Get-AzureDependencies.ps1

function Get-AzureScopeParts {
  param([string]$Scope)

  $parts = [ordered]@{
    scopeType = "Unknown"
    subscriptionId = $null
    resourceGroup = $null
    resourceId = $null
  }

  if ([string]::IsNullOrWhiteSpace($Scope)) {
    return [pscustomobject]$parts
  }

  if ($Scope -match "^/subscriptions/([^/]+)$") {
    $parts.scopeType = "Subscription"
    $parts.subscriptionId = $Matches[1]
    return [pscustomobject]$parts
  }

  if ($Scope -match "^/subscriptions/([^/]+)/resourceGroups/([^/]+)$") {
    $parts.scopeType = "ResourceGroup"
    $parts.subscriptionId = $Matches[1]
    $parts.resourceGroup = $Matches[2]
    return [pscustomobject]$parts
  }

  if ($Scope -match "^/subscriptions/([^/]+)/resourceGroups/([^/]+)/providers/.+$") {
    $parts.scopeType = "Resource"
    $parts.subscriptionId = $Matches[1]
    $parts.resourceGroup = $Matches[2]
    $parts.resourceId = $Scope
    return [pscustomobject]$parts
  }

  if ($Scope -match "^/providers/Microsoft\.Management/managementGroups/([^/]+)$") {
    $parts.scopeType = "ManagementGroup"
  }

  return [pscustomobject]$parts
}

function Get-AzureSubscriptionFilters {
  param([string]$SubscriptionIds)

  if ([string]::IsNullOrWhiteSpace($SubscriptionIds)) {
    $context = Get-AzContext
    if (-not $context -or -not $context.Subscription -or [string]::IsNullOrWhiteSpace([string]$context.Subscription.Id)) {
      throw "Azure context does not have a current subscription. Provide -SubscriptionIds or run Set-AzContext."
    }

    return @([string]$context.Subscription.Id)
  }

  return @($SubscriptionIds.Split(",") | ForEach-Object { $_.Trim() } | Where-Object { $_ })
}

function Find-AzureResourceForScope {
  param(
    [string]$Scope,
    [hashtable]$ResourceById,
    [hashtable]$ResourceGroupByName,
    [object]$Subscription
  )

  $scopeParts = Get-AzureScopeParts -Scope $Scope

  if ($scopeParts.scopeType -eq "Subscription") {
    return [pscustomobject]@{
      dependencyType = "Subscription"
      resourceId = "/subscriptions/$($Subscription.Id)"
      resourceName = [string]$Subscription.Name
      resourceGroup = $null
      resourceType = "Microsoft.Resources/subscriptions"
      location = $null
      tags = $null
    }
  }

  if ($scopeParts.scopeType -eq "ResourceGroup") {
    $resourceGroupKey = [string]$scopeParts.resourceGroup
    $resourceGroup = $ResourceGroupByName[$resourceGroupKey]
    return [pscustomobject]@{
      dependencyType = "ResourceGroup"
      resourceId = "/subscriptions/$($Subscription.Id)/resourceGroups/$resourceGroupKey"
      resourceName = $resourceGroupKey
      resourceGroup = $resourceGroupKey
      resourceType = "Microsoft.Resources/resourceGroups"
      location = if ($resourceGroup) { [string]$resourceGroup.Location } else { $null }
      tags = if ($resourceGroup) { $resourceGroup.Tags } else { $null }
    }
  }

  if ($scopeParts.scopeType -eq "Resource" -and $ResourceById.ContainsKey([string]$Scope)) {
    $resource = $ResourceById[[string]$Scope]
    return [pscustomobject]@{
      dependencyType = "Resource"
      resourceId = [string]$resource.ResourceId
      resourceName = [string]$resource.Name
      resourceGroup = [string]$resource.ResourceGroupName
      resourceType = [string]$resource.ResourceType
      location = [string]$resource.Location
      tags = $resource.Tags
    }
  }

  return [pscustomobject]@{
    dependencyType = $scopeParts.scopeType
    resourceId = [string]$Scope
    resourceName = $null
    resourceGroup = $scopeParts.resourceGroup
    resourceType = $null
    location = $null
    tags = $null
  }
}

function Test-ActivityLogMatchesServicePrincipal {
  param(
    [object]$Log,
    [object]$ServicePrincipal
  )

  $objectId = [string]$ServicePrincipal.objectId
  $appId = [string]$ServicePrincipal.appId
  $displayName = [string]$ServicePrincipal.displayName

  $callerObjectId = [string]$Log.callerObjectId
  $callerAppId = [string]$Log.callerAppId
  $caller = [string]$Log.caller
  $callerName = [string]$Log.callerName

  if ($objectId -and $callerObjectId -and $callerObjectId.Equals($objectId, [System.StringComparison]::OrdinalIgnoreCase)) {
    return $true
  }

  if ($appId -and $callerAppId -and $callerAppId.Equals($appId, [System.StringComparison]::OrdinalIgnoreCase)) {
    return $true
  }

  if ($appId -and $caller -and $caller.Equals($appId, [System.StringComparison]::OrdinalIgnoreCase)) {
    return $true
  }

  if ($displayName -and $callerName -and $callerName.Equals($displayName, [System.StringComparison]::OrdinalIgnoreCase)) {
    return $true
  }

  return $false
}

function Test-AzureActivityLogMatchesScope {
  param(
    [object]$Log,
    [string]$Scope
  )

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

  $normalizedScope = ([string]$Scope).TrimEnd("/")
  $candidateScopes = @(
    [string]$Log.authorizationScope,
    [string]$Log.resourceId
  ) | Where-Object { -not [string]::IsNullOrWhiteSpace($_) }

  foreach ($candidateScope in $candidateScopes) {
    $normalizedCandidateScope = ([string]$candidateScope).TrimEnd("/")
    if ($normalizedCandidateScope.Equals($normalizedScope, [System.StringComparison]::OrdinalIgnoreCase)) {
      return $true
    }

    if ($normalizedCandidateScope.StartsWith("$normalizedScope/", [System.StringComparison]::OrdinalIgnoreCase)) {
      return $true
    }
  }

  return $false
}

function New-AzureRbacScopeActivityEvidence {
  param(
    [object]$Subscription,
    [object]$Log,
    [object]$RoleAssignment,
    [object]$ServicePrincipal
  )

  [pscustomobject]@{
    subscriptionId = [string]$Subscription.Id
    subscriptionName = [string]$Subscription.Name
    rbacScope = [string]$RoleAssignment.Scope
    rbacRoleDefinitionName = [string]$RoleAssignment.RoleDefinitionName
    eventTimestamp = [string]$Log.eventTimestamp
    caller = [string]$Log.caller
    callerObjectId = [string]$Log.callerObjectId
    callerAppId = [string]$Log.callerAppId
    callerName = [string]$Log.callerName
    callerTenantId = [string]$Log.callerTenantId
    operationName = [string]$Log.operationName
    operationNameValue = [string]$Log.operationNameValue
    status = [string]$Log.status
    resourceGroupName = [string]$Log.resourceGroupName
    resourceId = [string]$Log.resourceId
    resourceType = [string]$Log.resourceType
    authorizationAction = [string]$Log.authorizationAction
    authorizationScope = [string]$Log.authorizationScope
    matchesInspectedServicePrincipal = [bool](Test-ActivityLogMatchesServicePrincipal -Log $Log -ServicePrincipal $ServicePrincipal)
    evidenceConfidence = "low"
    evidenceReason = "Activity logs show recent management-plane operations under an RBAC scope assigned to the inspected service principal; this is access context, not ownership proof."
  }
}

function Get-AzureRbacScopeActivityCallers {
  param(
    [object[]]$ActivityEvidence
  )

  $groups = @($ActivityEvidence) | Group-Object -Property {
    $callerObjectId = [string]$_.callerObjectId
    $callerAppId = [string]$_.callerAppId
    $caller = [string]$_.caller
    $callerName = [string]$_.callerName

    if (-not [string]::IsNullOrWhiteSpace($callerObjectId)) {
      return "object:$callerObjectId"
    }

    if (-not [string]::IsNullOrWhiteSpace($callerAppId)) {
      return "app:$callerAppId"
    }

    if (-not [string]::IsNullOrWhiteSpace($caller)) {
      return "caller:$caller"
    }

    if (-not [string]::IsNullOrWhiteSpace($callerName)) {
      return "name:$callerName"
    }

    return "unknown"
  }

  foreach ($group in $groups) {
    $items = @($group.Group | Sort-Object eventTimestamp)
    $first = $items | Select-Object -First 1
    $last = $items | Select-Object -Last 1

    [pscustomobject]@{
      callerKey = [string]$group.Name
      caller = [string]$last.caller
      callerObjectId = [string]$last.callerObjectId
      callerAppId = [string]$last.callerAppId
      callerName = [string]$last.callerName
      callerTenantId = [string]$last.callerTenantId
      eventCount = [int]$items.Count
      firstSeen = [string]$first.eventTimestamp
      lastSeen = [string]$last.eventTimestamp
      subscriptions = @($items | Select-Object -ExpandProperty subscriptionName -Unique)
      rbacScopes = @($items | Select-Object -ExpandProperty rbacScope -Unique)
      resourceIds = @($items | Select-Object -ExpandProperty resourceId -Unique | Where-Object { -not [string]::IsNullOrWhiteSpace($_) })
      operationNames = @($items | Select-Object -ExpandProperty operationNameValue -Unique | Where-Object { -not [string]::IsNullOrWhiteSpace($_) })
      matchesInspectedServicePrincipal = [bool](@($items | Where-Object matchesInspectedServicePrincipal).Count -gt 0)
      evidenceConfidence = "low"
      evidenceReason = "Caller performed recent management-plane operations under one or more RBAC scopes assigned to the inspected service principal."
    }
  }
}

function Get-AzureDependencies {
  [CmdletBinding()]
  param(
    [Parameter(Mandatory = $true)]
    [object]$ServicePrincipal,

    [string]$SubscriptionIds = "",

    [ValidateRange(1, 3650)]
    [int]$ActivityDays = 30,

    [ValidateRange(1, 1000000)]
    [int]$MaxActivityRecords = 5000,

    [string]$LogAnalyticsWorkspaceId = "",

    [ValidateRange(1, 1000000)]
    [int]$MaxBlobReadRecords = 5000,

    [string[]]$BlobReadOperationNames = @("GetBlob", "PutBlob", "PutBlock", "PutBlockList", "AppendBlock", "CopyBlob"),

    [switch]$SkipActivityLogs
  )

  $subscriptionFilters = Get-AzureSubscriptionFilters -SubscriptionIds $SubscriptionIds
  $enabledSubscriptions = Get-AzSubscription | Where-Object State -eq "Enabled"
  $selectedSubscriptions = @()

  foreach ($filter in $subscriptionFilters) {
    $subscription = $enabledSubscriptions | Where-Object { $_.Id -eq $filter -or $_.Name -eq $filter } | Select-Object -First 1
    if (-not $subscription) {
      throw "Subscription not found or not enabled: $filter"
    }

    if (-not ($selectedSubscriptions | Where-Object Id -eq $subscription.Id)) {
      $selectedSubscriptions += $subscription
    }
  }

  $roleAssignments = @()
  $coAssignedRoleCandidates = @()
  $resourceDependencies = @()
  $activityEvidence = @()
  $rbacScopeActivityEvidence = @()
  $blobReadEvidence = @()
  $storageAccountsWithRbac = @{}
  $activityStartTime = (Get-Date).AddDays(-$ActivityDays)
  $servicePrincipalObjectId = [string]$ServicePrincipal.objectId
  $candidateRoleAssignmentIds = [System.Collections.Generic.HashSet[string]]::new([System.StringComparer]::OrdinalIgnoreCase)
  $queriedCoAssignedScopes = [System.Collections.Generic.HashSet[string]]::new([System.StringComparer]::OrdinalIgnoreCase)

  foreach ($subscription in $selectedSubscriptions) {
    Set-AzContext -SubscriptionId $subscription.Id | Out-Null

    $resources = @(Get-AzResource)
    $resourceGroups = @(Get-AzResourceGroup)
    $resourceById = @{}
    foreach ($resource in $resources) {
      if (-not [string]::IsNullOrWhiteSpace([string]$resource.ResourceId)) {
        $resourceById[[string]$resource.ResourceId] = $resource
      }
    }

    $resourceGroupByName = @{}
    foreach ($resourceGroup in $resourceGroups) {
      if (-not [string]::IsNullOrWhiteSpace([string]$resourceGroup.ResourceGroupName)) {
        $resourceGroupByName[[string]$resourceGroup.ResourceGroupName] = $resourceGroup
      }
    }

    $assignments = @(Get-AzRoleAssignment -ObjectId $servicePrincipalObjectId -ErrorAction SilentlyContinue)
    foreach ($assignment in $assignments) {
      $roleAssignments += [pscustomobject]@{
        subscriptionId = [string]$subscription.Id
        subscriptionName = [string]$subscription.Name
        roleAssignmentId = [string]$assignment.RoleAssignmentId
        scope = [string]$assignment.Scope
        principalId = [string]$assignment.ObjectId
        principalType = [string]$assignment.ObjectType
        principalDisplayName = [string]$assignment.DisplayName
        roleDefinitionId = [string]$assignment.RoleDefinitionId
        roleDefinitionName = [string]$assignment.RoleDefinitionName
        condition = [string]$assignment.Condition
        conditionVersion = [string]$assignment.ConditionVersion
      }

      $resourceDependencies += Find-AzureResourceForScope `
        -Scope ([string]$assignment.Scope) `
        -ResourceById $resourceById `
        -ResourceGroupByName $resourceGroupByName `
        -Subscription $subscription

      foreach ($storageAccount in @(Get-AzureStorageAccountsForScope -Scope ([string]$assignment.Scope) -Resources $resources)) {
        $storageAccountResourceId = [string]$storageAccount.ResourceId
        if (-not [string]::IsNullOrWhiteSpace($storageAccountResourceId)) {
          $storageAccountsWithRbac[$storageAccountResourceId] = $storageAccount
        }
      }

      $assignmentScope = [string]$assignment.Scope
      if (-not $queriedCoAssignedScopes.Add($assignmentScope)) {
        continue
      }

      $sameScopeAssignments = @(Get-AzRoleAssignment -Scope $assignmentScope -ErrorAction SilentlyContinue)
      foreach ($sameScopeAssignment in $sameScopeAssignments) {
        if (-not ([string]$sameScopeAssignment.Scope).Equals([string]$assignment.Scope, [System.StringComparison]::OrdinalIgnoreCase)) {
          continue
        }

        $candidatePrincipalId = [string]$sameScopeAssignment.ObjectId
        if ([string]::IsNullOrWhiteSpace($candidatePrincipalId)) {
          continue
        }

        if ($candidatePrincipalId.Equals($servicePrincipalObjectId, [System.StringComparison]::OrdinalIgnoreCase)) {
          continue
        }

        $candidateRoleAssignmentId = [string]$sameScopeAssignment.RoleAssignmentId
        if (-not [string]::IsNullOrWhiteSpace($candidateRoleAssignmentId)) {
          if (-not $candidateRoleAssignmentIds.Add($candidateRoleAssignmentId)) {
            continue
          }
        }

        $coAssignedRoleCandidates += [pscustomobject]@{
          subscriptionId = [string]$subscription.Id
          subscriptionName = [string]$subscription.Name
          roleAssignmentId = $candidateRoleAssignmentId
          scope = [string]$sameScopeAssignment.Scope
          principalId = $candidatePrincipalId
          principalType = [string]$sameScopeAssignment.ObjectType
          principalName = [string]$sameScopeAssignment.SignInName
          principalDisplayName = [string]$sameScopeAssignment.DisplayName
          roleDefinitionId = [string]$sameScopeAssignment.RoleDefinitionId
          roleDefinitionName = [string]$sameScopeAssignment.RoleDefinitionName
        }
      }
    }

    if (-not $SkipActivityLogs) {
      $logs = Get-AzureActivityLogs `
        -SubscriptionId ([string]$subscription.Id) `
        -StartTime $activityStartTime `
        -MaxRecord $MaxActivityRecords

      foreach ($log in @($logs)) {
        foreach ($assignment in $assignments) {
          if (Test-AzureActivityLogMatchesScope -Log $log -Scope ([string]$assignment.Scope)) {
            $rbacScopeActivityEvidence += New-AzureRbacScopeActivityEvidence `
              -Subscription $subscription `
              -Log $log `
              -RoleAssignment $assignment `
              -ServicePrincipal $ServicePrincipal
          }
        }

        if (Test-ActivityLogMatchesServicePrincipal -Log $log -ServicePrincipal $ServicePrincipal) {
          $activityEvidence += [pscustomobject]@{
            subscriptionId = [string]$subscription.Id
            subscriptionName = [string]$subscription.Name
            eventTimestamp = [string]$log.eventTimestamp
            caller = [string]$log.caller
            callerObjectId = [string]$log.callerObjectId
            callerAppId = [string]$log.callerAppId
            callerName = [string]$log.callerName
            operationName = [string]$log.operationName
            operationNameValue = [string]$log.operationNameValue
            status = [string]$log.status
            resourceGroupName = [string]$log.resourceGroupName
            resourceId = [string]$log.resourceId
            resourceType = [string]$log.resourceType
            authorizationAction = [string]$log.authorizationAction
            authorizationScope = [string]$log.authorizationScope
            evidenceConfidence = "low"
            evidenceReason = "Activity logs show recent use by this service principal identifier; this is access evidence, not ownership proof."
          }
        }
      }
    }
  }

  if (-not [string]::IsNullOrWhiteSpace($LogAnalyticsWorkspaceId)) {
    $blobReadEvidence = @(Get-StorageBlobReadLogs `
        -WorkspaceId $LogAnalyticsWorkspaceId `
        -StorageAccounts @($storageAccountsWithRbac.Values) `
        -ServicePrincipal $ServicePrincipal `
        -StartTime $activityStartTime `
        -MaxRecord $MaxBlobReadRecords `
        -BlobReadOperationNames $BlobReadOperationNames)
  }

  return [pscustomobject]@{
    requestedSubscriptions = @($subscriptionFilters)
    subscriptions = @($selectedSubscriptions | ForEach-Object {
      [pscustomobject]@{
        subscriptionId = [string]$_.Id
        subscriptionName = [string]$_.Name
        tenantId = [string]$_.TenantId
      }
    })
    roleAssignments = @($roleAssignments | Sort-Object subscriptionName, scope, roleDefinitionName)
    coAssignedRoleCandidates = @($coAssignedRoleCandidates | Sort-Object subscriptionName, scope, principalDisplayName, roleDefinitionName)
    resourceDependencies = @($resourceDependencies |
      Sort-Object resourceId -Unique |
      Sort-Object dependencyType, resourceGroup, resourceName)
    activityEvidence = @($activityEvidence | Sort-Object eventTimestamp, resourceId)
    rbacScopeActivityEvidence = @($rbacScopeActivityEvidence | Sort-Object eventTimestamp, rbacScope, resourceId)
    rbacScopeActivityCallers = @(Get-AzureRbacScopeActivityCallers -ActivityEvidence @($rbacScopeActivityEvidence) |
      Sort-Object @{ Expression = "eventCount"; Descending = $true }, lastSeen)
    blobReadEvidence = @($blobReadEvidence | Sort-Object eventTimestamp, storageAccountName, uri)
    blobReadCallers = @(Get-StorageBlobReadCallers -BlobReadEvidence @($blobReadEvidence) |
      Sort-Object @{ Expression = "blobAccessCount"; Descending = $true }, lastSeen)
    storageAccountsWithRbac = @($storageAccountsWithRbac.Values | ForEach-Object {
      [pscustomobject]@{
        resourceId = [string]$_.ResourceId
        name = [string]$_.Name
        resourceGroup = [string]$_.ResourceGroupName
        location = [string]$_.Location
      }
    } | Sort-Object name)
    logAnalyticsWorkspaceId = [string]$LogAnalyticsWorkspaceId
    maxBlobReadRecords = $MaxBlobReadRecords
    activityStartTime = $activityStartTime.ToUniversalTime().ToString("o")
    maxActivityRecords = $MaxActivityRecords
    activitySkipped = [bool]$SkipActivityLogs
  }
}

# SIG # Begin signature block
# MII9MQYJKoZIhvcNAQcCoII9IjCCPR4CAQExDzANBglghkgBZQMEAgEFADB5Bgor
# BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG
# KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCBFqLbhfwOMpQgN
# hXhUA9e/sYQcp4LXlBNeOTvH8N8plaCCIfYwggXMMIIDtKADAgECAhBUmNLR1FsZ
# 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
# 03u4aUoqlmZpxJTG9F9urJh4iIAGXKKy7aIwggaoMIIEkKADAgECAhMzAASy5NjH
# +PRKezsKAAAABLLkMA0GCSqGSIb3DQEBDAUAMFoxCzAJBgNVBAYTAlVTMR4wHAYD
# VQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xKzApBgNVBAMTIk1pY3Jvc29mdCBJ
# RCBWZXJpZmllZCBDUyBBT0MgQ0EgMDQwHhcNMjYwODEyMDg1ODE4WhcNMjYwODE1
# MDg1ODE4WjBpMQswCQYDVQQGEwJQTDEXMBUGA1UECB4OAUEA8wBkAHoAawBpAGUx
# DzANBgNVBAcTBldpZWx1bjEXMBUGA1UEChMOc29mdDRwbSBzcCB6b28xFzAVBgNV
# BAMTDnNvZnQ0cG0gc3Agem9vMIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIBigKC
# AYEAiXC7gBUSO8amBSo2+j0tuOkycf07cqnmxd4FeidgU+njUj4DwajTsLkUiq7g
# F2O8XMLDRxHCxW1jtCYH+RQgQU9QS1l0vTC7l/BlU+2FslURQDrnm1qBIx2vRW3S
# sH0JWH6ZnmP1PeuRaemM4OCHSXZKL04KXuM7dEo7zEGwcpXEbIy0Ehn6rSQHLLYR
# oFNK2ND155poVmNnho0AikOfFNQ5Zmt4002eBI1jBbcWaN1vR4N5XQfYUKd2NnWC
# e2q3kUmqax6lCNDdg2hREsUe+uf6qCRLd3BbQpzr5GWxvaJAHeKoXGCf3oFbpjeT
# /JzhxcK9hCmHJxTjMccJrwW9VZ7jeVlMCVXJVRPXURLur/HMU0/EF3c8xPVwtIvX
# rDumUf861dT9gt1jGv9AoJElN/XOK9FLwo12rU8qyki+NV1tOHAiCfhBU5Dny3Gz
# vEuzrgKE/R8/7J2JWL9Pgb28d8mlfPZezueETJHxd3Y6sDT5+PP7oOA3G/+1Q19/
# Tz7JAgMBAAGjggHWMIIB0jAMBgNVHRMBAf8EAjAAMA4GA1UdDwEB/wQEAwIHgDA9
# BgNVHSUENjA0BgorBgEEAYI3YQEABggrBgEFBQcDAwYcKwYBBAGCN2GCycz3dYGA
# 0Y0Tg469piSB0sq0aDAdBgNVHQ4EFgQUu/Bn01b97e842Q54MLTP04OW0tQwHwYD
# VR0jBBgwFoAUayVB3vtrfP0YgAotf492XapzPbgwZwYDVR0fBGAwXjBcoFqgWIZW
# aHR0cDovL3d3dy5taWNyb3NvZnQuY29tL3BraW9wcy9jcmwvTWljcm9zb2Z0JTIw
# SUQlMjBWZXJpZmllZCUyMENTJTIwQU9DJTIwQ0ElMjAwNC5jcmwwdAYIKwYBBQUH
# AQEEaDBmMGQGCCsGAQUFBzAChlhodHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtp
# b3BzL2NlcnRzL01pY3Jvc29mdCUyMElEJTIwVmVyaWZpZWQlMjBDUyUyMEFPQyUy
# MENBJTIwMDQuY3J0MFQGA1UdIARNMEswSQYEVR0gADBBMD8GCCsGAQUFBwIBFjNo
# dHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpb3BzL0RvY3MvUmVwb3NpdG9yeS5o
# dG0wDQYJKoZIhvcNAQEMBQADggIBAIKCdHRzqgKHB6u7eb4VQqKJR1gf0grlY3QR
# kqZC9yNemKXqlg0iL5NYDRsysjzSZyX4rKU/ZTe8qTuruyBprgW3vF80Dmm8S0+t
# m/xbJeet2RRXJHj2NaEoavxrDZ1YWb7Dn+cgrPuQACE5Arhg2lYnwO19R+YOa/R+
# z/cwP4vkeQ0w9zVpl2xdFxmM/MiJWm8DEuNTtlNOE/NstBxMX8VW7nGL8qFreOZP
# 8f78acfGhX76pcHHraQxeihVBT6NHlyyEcUi95TkjUP4jAYaYJ2WzBt5ISZX9yoS
# 0khleUTBwMg0gFbDQz4JoT5tPQwky9C+LLhcIs+om/fCBEW1eyoZAUuW1lQI+bZ6
# EBALlBk5x3uGjyajZTCzVYxWJ6KARyEq1HdYi0se6Nm/FZGxb94yRXwGj7etZrk6
# TvjX4sLsDT1HeAPJ+eT4Ohgdmhzq98bdFqNKXx5NFrafdV+RZ1RiCOc1JBKdDc4g
# os3dzZJ0mctzN9zZpbOIev2keYRf2Q3QA+wJ6B7WMOw0LltK4pBw8UEoFnlr69wN
# Fe8rK/PmxfolP9BKB7n8jWsOlI/B7aP1oodsCH3N3lfuE07wp9YfUQ7squoZ2e4N
# HsHWYVL88f2qfQlrCRMOmhlE1tFqY0gm/sQV2RvJlkUk1m5lgfPT8Z5p3UGEyhWM
# 3bTmqS46MIIGqDCCBJCgAwIBAgITMwAEsuTYx/j0Sns7CgAAAASy5DANBgkqhkiG
# 9w0BAQwFADBaMQswCQYDVQQGEwJVUzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBv
# cmF0aW9uMSswKQYDVQQDEyJNaWNyb3NvZnQgSUQgVmVyaWZpZWQgQ1MgQU9DIENB
# IDA0MB4XDTI2MDgxMjA4NTgxOFoXDTI2MDgxNTA4NTgxOFowaTELMAkGA1UEBhMC
# UEwxFzAVBgNVBAgeDgFBAPMAZAB6AGsAaQBlMQ8wDQYDVQQHEwZXaWVsdW4xFzAV
# BgNVBAoTDnNvZnQ0cG0gc3Agem9vMRcwFQYDVQQDEw5zb2Z0NHBtIHNwIHpvbzCC
# AaIwDQYJKoZIhvcNAQEBBQADggGPADCCAYoCggGBAIlwu4AVEjvGpgUqNvo9Lbjp
# MnH9O3Kp5sXeBXonYFPp41I+A8Go07C5FIqu4BdjvFzCw0cRwsVtY7QmB/kUIEFP
# UEtZdL0wu5fwZVPthbJVEUA655tagSMdr0Vt0rB9CVh+mZ5j9T3rkWnpjODgh0l2
# Si9OCl7jO3RKO8xBsHKVxGyMtBIZ+q0kByy2EaBTStjQ9eeaaFZjZ4aNAIpDnxTU
# OWZreNNNngSNYwW3Fmjdb0eDeV0H2FCndjZ1gntqt5FJqmsepQjQ3YNoURLFHvrn
# +qgkS3dwW0Kc6+Rlsb2iQB3iqFxgn96BW6Y3k/yc4cXCvYQphycU4zHHCa8FvVWe
# 43lZTAlVyVUT11ES7q/xzFNPxBd3PMT1cLSL16w7plH/OtXU/YLdYxr/QKCRJTf1
# zivRS8KNdq1PKspIvjVdbThwIgn4QVOQ58txs7xLs64ChP0fP+ydiVi/T4G9vHfJ
# pXz2Xs7nhEyR8Xd2OrA0+fjz+6DgNxv/tUNff08+yQIDAQABo4IB1jCCAdIwDAYD
# VR0TAQH/BAIwADAOBgNVHQ8BAf8EBAMCB4AwPQYDVR0lBDYwNAYKKwYBBAGCN2EB
# AAYIKwYBBQUHAwMGHCsGAQQBgjdhgsnM93WBgNGNE4OOvaYkgdLKtGgwHQYDVR0O
# BBYEFLvwZ9NW/e3vONkOeDC0z9ODltLUMB8GA1UdIwQYMBaAFGslQd77a3z9GIAK
# LX+Pdl2qcz24MGcGA1UdHwRgMF4wXKBaoFiGVmh0dHA6Ly93d3cubWljcm9zb2Z0
# LmNvbS9wa2lvcHMvY3JsL01pY3Jvc29mdCUyMElEJTIwVmVyaWZpZWQlMjBDUyUy
# MEFPQyUyMENBJTIwMDQuY3JsMHQGCCsGAQUFBwEBBGgwZjBkBggrBgEFBQcwAoZY
# aHR0cDovL3d3dy5taWNyb3NvZnQuY29tL3BraW9wcy9jZXJ0cy9NaWNyb3NvZnQl
# MjBJRCUyMFZlcmlmaWVkJTIwQ1MlMjBBT0MlMjBDQSUyMDA0LmNydDBUBgNVHSAE
# TTBLMEkGBFUdIAAwQTA/BggrBgEFBQcCARYzaHR0cDovL3d3dy5taWNyb3NvZnQu
# Y29tL3BraW9wcy9Eb2NzL1JlcG9zaXRvcnkuaHRtMA0GCSqGSIb3DQEBDAUAA4IC
# AQCCgnR0c6oChweru3m+FUKiiUdYH9IK5WN0EZKmQvcjXpil6pYNIi+TWA0bMrI8
# 0mcl+KylP2U3vKk7q7sgaa4Ft7xfNA5pvEtPrZv8WyXnrdkUVyR49jWhKGr8aw2d
# WFm+w5/nIKz7kAAhOQK4YNpWJ8DtfUfmDmv0fs/3MD+L5HkNMPc1aZdsXRcZjPzI
# iVpvAxLjU7ZTThPzbLQcTF/FVu5xi/Kha3jmT/H+/GnHxoV++qXBx62kMXooVQU+
# jR5cshHFIveU5I1D+IwGGmCdlswbeSEmV/cqEtJIZXlEwcDINIBWw0M+CaE+bT0M
# JMvQviy4XCLPqJv3wgRFtXsqGQFLltZUCPm2ehAQC5QZOcd7ho8mo2Uws1WMViei
# gEchKtR3WItLHujZvxWRsW/eMkV8Bo+3rWa5Ok741+LC7A09R3gDyfnk+DoYHZoc
# 6vfG3RajSl8eTRa2n3VfkWdUYgjnNSQSnQ3OIKLN3c2SdJnLczfc2aWziHr9pHmE
# X9kN0APsCege1jDsNC5bSuKQcPFBKBZ5a+vcDRXvKyvz5sX6JT/QSge5/I1rDpSP
# we2j9aKHbAh9zd5X7hNO8KfWH1EO7KrqGdnuDR7B1mFS/PH9qn0JawkTDpoZRNbR
# amNIJv7EFdkbyZZFJNZuZYHz0/Gead1BhMoVjN205qkuOjCCBygwggUQoAMCAQIC
# 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+tHD6n58vhavFIrmcxghqRMIIajQIBATBxMFox
# CzAJBgNVBAYTAlVTMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xKzAp
# BgNVBAMTIk1pY3Jvc29mdCBJRCBWZXJpZmllZCBDUyBBT0MgQ0EgMDQCEzMABLLk
# 2Mf49Ep7OwoAAAAEsuQwDQYJYIZIAWUDBAIBBQCgXjAQBgorBgEEAYI3AgEMMQIw
# ADAZBgkqhkiG9w0BCQMxDAYKKwYBBAGCNwIBBDAvBgkqhkiG9w0BCQQxIgQgTPaO
# 87s5GAl3Yt59KpUE/h11llbSbaiqHuFVGY1ka/YwDQYJKoZIhvcNAQEBBQAEggGA
# PSIAuIDg4juQCSN+VtCAdOMWgAjplz1jrmx7dWmamrnjWna5zqpCbCla3CbBn3Ju
# lMEN4fJ4X79WVogR+3YLaXroxzgjA78lW4EEraeSNsXe+Fskg9aGlsjyIqcOXCP0
# gLTUEZE0GnsH9OpaL5pd2+NqA3PHeNwr0jpfonIq2o14jdagi/Nj00c8rl5sgUBW
# 1wmBpuXdHg68CDgDaoPBJzDQaA0OT+nNcHT/i9OgLHG/tb/YfBriLJmHPr1OCKZQ
# +j5iztZRjAHN1J263HRBfDKZoTYrOf4Rl24nvF3/gI/SIp2+TA3tA/D8pcSXGVi6
# eQ5BfN00vdeGsef3W4n7/yHR7KqxunufX00ahCs/tlBrjSOy6/98CmihnmLW63CZ
# /0lXYs0XW5qFw4S7Hf2aUJgphaIWYM8rc3pnMVUx/bBw1kcJMAQ09GHw/rriv9m4
# kTGzenIQAcCCr2oYKr0RH4flZxoL9IBJMtuS1ow9uwZnrTmM2DmXVqc6TrQ7YZUm
# oYIYETCCGA0GCisGAQQBgjcDAwExghf9MIIX+QYJKoZIhvcNAQcCoIIX6jCCF+YC
# AQMxDzANBglghkgBZQMEAgEFADCCAWIGCyqGSIb3DQEJEAEEoIIBUQSCAU0wggFJ
# AgEBBgorBgEEAYRZCgMBMDEwDQYJYIZIAWUDBAIBBQAEIJoe/lvqU1SgdiLHnqqY
# EBChW5BOZvS7WA691JggWy77AgZqX4ZNNMgYEzIwMjYwODEzMjA1NjE4Ljc3NVow
# BIACAfSggeGkgd4wgdsxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9u
# MRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRp
# b24xJTAjBgNVBAsTHE1pY3Jvc29mdCBBbWVyaWNhIE9wZXJhdGlvbnMxJzAlBgNV
# BAsTHm5TaGllbGQgVFNTIEVTTjo3ODAwLTA1RTAtRDk0NzE1MDMGA1UEAxMsTWlj
# cm9zb2Z0IFB1YmxpYyBSU0EgVGltZSBTdGFtcGluZyBBdXRob3JpdHmggg8hMIIH
# gjCCBWqgAwIBAgITMwAAAAXlzw//Zi7JhwAAAAAABTANBgkqhkiG9w0BAQwFADB3
# MQswCQYDVQQGEwJVUzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMUgw
# RgYDVQQDEz9NaWNyb3NvZnQgSWRlbnRpdHkgVmVyaWZpY2F0aW9uIFJvb3QgQ2Vy
# dGlmaWNhdGUgQXV0aG9yaXR5IDIwMjAwHhcNMjAxMTE5MjAzMjMxWhcNMzUxMTE5
# MjA0MjMxWjBhMQswCQYDVQQGEwJVUzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBv
# cmF0aW9uMTIwMAYDVQQDEylNaWNyb3NvZnQgUHVibGljIFJTQSBUaW1lc3RhbXBp
# bmcgQ0EgMjAyMDCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAJ5851Jj
# /eDFnwV9Y7UGIqMcHtfnlzPREwW9ZUZHd5HBXXBvf7KrQ5cMSqFSHGqg2/qJhYqO
# QxwuEQXG8kB41wsDJP5d0zmLYKAY8Zxv3lYkuLDsfMuIEqvGYOPURAH+Ybl4SJEE
# Snt0MbPEoKdNihwM5xGv0rGofJ1qOYSTNcc55EbBT7uq3wx3mXhtVmtcCEr5ZKTk
# KKE1CxZvNPWdGWJUPC6e4uRfWHIhZcgCsJ+sozf5EeH5KrlFnxpjKKTavwfFP6Xa
# GZGWUG8TZaiTogRoAlqcevbiqioUz1Yt4FRK53P6ovnUfANjIgM9JDdJ4e0qiDRm
# 5sOTiEQtBLGd9Vhd1MadxoGcHrRCsS5rO9yhv2fjJHrmlQ0EIXmp4DhDBieKUGR+
# eZ4CNE3ctW4uvSDQVeSp9h1SaPV8UWEfyTxgGjOsRpeexIveR1MPTVf7gt8hY64X
# NPO6iyUGsEgt8c2PxF87E+CO7A28TpjNq5eLiiunhKbq0XbjkNoU5JhtYUrlmAbp
# xRjb9tSreDdtACpm3rkpxp7AQndnI0Shu/fk1/rE3oWsDqMX3jjv40e8KN5YsJBn
# czyWB4JyeeFMW3JBfdeAKhzohFe8U5w9WuvcP1E8cIxLoKSDzCCBOu0hWdjzKNu8
# Y5SwB1lt5dQhABYyzR3dxEO/T1K/BVF3rV69AgMBAAGjggIbMIICFzAOBgNVHQ8B
# Af8EBAMCAYYwEAYJKwYBBAGCNxUBBAMCAQAwHQYDVR0OBBYEFGtpKDo1L0hjQM97
# 2K9J6T7ZPdshMFQGA1UdIARNMEswSQYEVR0gADBBMD8GCCsGAQUFBwIBFjNodHRw
# Oi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpb3BzL0RvY3MvUmVwb3NpdG9yeS5odG0w
# EwYDVR0lBAwwCgYIKwYBBQUHAwgwGQYJKwYBBAGCNxQCBAweCgBTAHUAYgBDAEEw
# DwYDVR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAWgBTIftJqhSobyhmYBAcnz1AQT2io
# ojCBhAYDVR0fBH0wezB5oHegdYZzaHR0cDovL3d3dy5taWNyb3NvZnQuY29tL3Br
# aW9wcy9jcmwvTWljcm9zb2Z0JTIwSWRlbnRpdHklMjBWZXJpZmljYXRpb24lMjBS
# b290JTIwQ2VydGlmaWNhdGUlMjBBdXRob3JpdHklMjAyMDIwLmNybDCBlAYIKwYB
# BQUHAQEEgYcwgYQwgYEGCCsGAQUFBzAChnVodHRwOi8vd3d3Lm1pY3Jvc29mdC5j
# b20vcGtpb3BzL2NlcnRzL01pY3Jvc29mdCUyMElkZW50aXR5JTIwVmVyaWZpY2F0
# aW9uJTIwUm9vdCUyMENlcnRpZmljYXRlJTIwQXV0aG9yaXR5JTIwMjAyMC5jcnQw
# DQYJKoZIhvcNAQEMBQADggIBAF+Idsd+bbVaFXXnTHho+k7h2ESZJRWluLE0Oa/p
# O+4ge/XEizXvhs0Y7+KVYyb4nHlugBesnFqBGEdC2IWmtKMyS1OWIviwpnK3aL5J
# edwzbeBF7POyg6IGG/XhhJ3UqWeWTO+Czb1c2NP5zyEh89F72u9UIw+IfvM9lzDm
# c2O2END7MPnrcjWdQnrLn1Ntday7JSyrDvBdmgbNnCKNZPmhzoa8PccOiQljjTW6
# GePe5sGFuRHzdFt8y+bN2neF7Zu8hTO1I64XNGqst8S+w+RUdie8fXC1jKu3m9KG
# IqF4aldrYBamyh3g4nJPj/LR2CBaLyD+2BuGZCVmoNR/dSpRCxlot0i79dKOChmo
# ONqbMI8m04uLaEHAv4qwKHQ1vBzbV/nG89LDKbRSSvijmwJwxRxLLpMQ/u4xXxFf
# R4f/gksSkbJp7oqLwliDm/h+w0aJ/U5ccnYhYb7vPKNMN+SZDWycU5ODIRfyoGl5
# 9BsXR/HpRGtiJquOYGmvA/pk5vC1lcnbeMrcWD/26ozePQ/TWfNXKBOmkFpvPE8C
# H+EeGGWzqTCjdAsno2jzTeNSxlx3glDGJgcdz5D/AAxw9Sdgq/+rY7jjgs7X6fqP
# TXPmaCAJKVHAP19oEjJIBwD1LyHbaEgBxFCogYSOiUIr0Xqcr1nJfiWG2GwYe6Zo
# AF1bMIIHlzCCBX+gAwIBAgITMwAAAFck05XgounJMQAAAAAAVzANBgkqhkiG9w0B
# AQwFADBhMQswCQYDVQQGEwJVUzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0
# aW9uMTIwMAYDVQQDEylNaWNyb3NvZnQgUHVibGljIFJTQSBUaW1lc3RhbXBpbmcg
# Q0EgMjAyMDAeFw0yNTEwMjMyMDQ2NTNaFw0yNjEwMjIyMDQ2NTNaMIHbMQswCQYD
# VQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEe
# MBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSUwIwYDVQQLExxNaWNyb3Nv
# ZnQgQW1lcmljYSBPcGVyYXRpb25zMScwJQYDVQQLEx5uU2hpZWxkIFRTUyBFU046
# NzgwMC0wNUUwLUQ5NDcxNTAzBgNVBAMTLE1pY3Jvc29mdCBQdWJsaWMgUlNBIFRp
# bWUgU3RhbXBpbmcgQXV0aG9yaXR5MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC
# CgKCAgEAsWylCpMIfbizJLY1kPXO2cmX2HRWvRbAmeKSZ5ex7/jCymdV7Eap+Ic2
# iqRtWDkKKe5gL6JV80wtn5C2qHJLPxUYFKNG3UkHkAI21MoCN+YWnhT8K/YuPib6
# +6970jdbeFKIiZMWwd5hnpX9J3jeteuEdXbp/DfFBK15JuD3JOzWuF2suQCPgqYj
# QPk/gpq+3KCKtXJRbXSCSJ9YtITU2IHwmfdE7l2PfZ154w041po+fDeTj0gJOzcV
# /Jv56Q0M+w19jAKo/I5PEzrLV1IPQnmP4or1X4RbJXk8ONXyOOfXOxK2VLpNxgkl
# K1yAezbFP2uzqihaXkW1h9GQLGENKESnezwgdRaLNNaYtm8AT/pZHYJ35mZVqkZd
# MIckpQHJk/F1fSLyDKeKtH4TC4cc3ESKUMgItq07ZZm74JCsfhmrQ1ijVNDi1Sln
# +QBamgC7WviZbkQnceQRq9DY+6hANwOrasAZUiVr2kPuj1jHDOXzUG4O9QTK70P/
# oXSqZAN1oTv3UfF8JTGmAxg+l1ZPOz50MY96HBDw/3bI/wBGNvLk6fLVnrxGN5B5
# unF/lYvjjWbIUdyBPVQnPOKXu08SRHbY19M1HoWX6PNZv+vzSeqVeWWHKdKjC3Gj
# VjbbGpi+JLbiyaKRSwEqo49tJLvu69cQ7dWsbksai4TURnVj2mMCAwEAAaOCAcsw
# ggHHMB0GA1UdDgQWBBSOg8leLTUOAglIZ+bjXpiD7RKSpzAfBgNVHSMEGDAWgBRr
# aSg6NS9IY0DPe9ivSek+2T3bITBsBgNVHR8EZTBjMGGgX6BdhltodHRwOi8vd3d3
# Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2NybC9NaWNyb3NvZnQlMjBQdWJsaWMlMjBS
# U0ElMjBUaW1lc3RhbXBpbmclMjBDQSUyMDIwMjAuY3JsMHkGCCsGAQUFBwEBBG0w
# azBpBggrBgEFBQcwAoZdaHR0cDovL3d3dy5taWNyb3NvZnQuY29tL3BraW9wcy9j
# ZXJ0cy9NaWNyb3NvZnQlMjBQdWJsaWMlMjBSU0ElMjBUaW1lc3RhbXBpbmclMjBD
# QSUyMDIwMjAuY3J0MAwGA1UdEwEB/wQCMAAwFgYDVR0lAQH/BAwwCgYIKwYBBQUH
# AwgwDgYDVR0PAQH/BAQDAgeAMGYGA1UdIARfMF0wUQYMKwYBBAGCN0yDfQEBMEEw
# PwYIKwYBBQUHAgEWM2h0dHA6Ly93d3cubWljcm9zb2Z0LmNvbS9wa2lvcHMvRG9j
# cy9SZXBvc2l0b3J5Lmh0bTAIBgZngQwBBAIwDQYJKoZIhvcNAQEMBQADggIBAHJ1
# wHY86Zk5SUBDPY25d/u9YJVaaNa71uxjX4cyO/XJ4uPENCSOwkRTnNogPLxTD0Fg
# 3z4TFf/2T/0IFSxdtWVtTjhzrn+WLInzeRawUhTCFVrPBJKEWVshm+Ig7/nB7JbJ
# N88+ltImBbL5kT1StBLfG6UksAcDbNSQww90CUXhGueBxlnSvjkAX1ohiN16y1bB
# 2s0rvQx8Csepl2CuBefTfDrMGzW/tzNx5YaK2D8OWweqTWZcGlJO4YjZNI83cTrQ
# ghfHl/8AXOHj8cWL3wEFltQQs2xeRYAb3Kdnl7oIWKKXWaBYJY5P3QPsiC+DTMp7
# ejdYKTrb396f3gr+wL/Ms5/Z3vIWZPJJv18qNw40fUNveRnwzMQnx8dM2bGuXXQZ
# 5y7P8aXT4HJMo349qZtn4XQwiUE/DDp++MUL0kgjvd/Deo7Xr371PFPPYb4TboZh
# jV1x9+wCHDoOpNCBt+VuXU78ytJdKzQ1Jv2cEP1F9H9/wSLsMDUvWME7u9mGElOP
# DZPMVr8AuBEuLdbTSEdaLwsZBplzxLBcgxhZ/Cs30yBhuE3QhqT1YDZ2pa56RexP
# A2SasPcToT6gJgJ6E06BmZ2zQTNvWOjs5XQqHbYuXcoeDcwe2UaC7EDOGD8GmLE9
# LiqtQsuQCM7v7I2xR+sPZT2Ax/85HjIkM+3MzTK1MYIHQzCCBz8CAQEweDBhMQsw
# CQYDVQQGEwJVUzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTIwMAYD
# VQQDEylNaWNyb3NvZnQgUHVibGljIFJTQSBUaW1lc3RhbXBpbmcgQ0EgMjAyMAIT
# MwAAAFck05XgounJMQAAAAAAVzANBglghkgBZQMEAgEFAKCCBJwwEQYLKoZIhvcN
# AQkQAg8xAgUAMBoGCSqGSIb3DQEJAzENBgsqhkiG9w0BCRABBDAcBgkqhkiG9w0B
# CQUxDxcNMjYwODEzMjA1NjE4WjAvBgkqhkiG9w0BCQQxIgQgeYXUzyToCBAQn7S+
# Xz/P+Upz+6IY2A3gFOPOxre+r0gwgbkGCyqGSIb3DQEJEAIvMYGpMIGmMIGjMIGg
# BCD1PJ9ktQVuTGWIbKLO4f1VUOlUU29ARCEpDZmFTHjbUjB8MGWkYzBhMQswCQYD
# VQQGEwJVUzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTIwMAYDVQQD
# EylNaWNyb3NvZnQgUHVibGljIFJTQSBUaW1lc3RhbXBpbmcgQ0EgMjAyMAITMwAA
# AFck05XgounJMQAAAAAAVzCCA14GCyqGSIb3DQEJEAISMYIDTTCCA0mhggNFMIID
# QTCCAikCAQEwggEJoYHhpIHeMIHbMQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2Fz
# aGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENv
# cnBvcmF0aW9uMSUwIwYDVQQLExxNaWNyb3NvZnQgQW1lcmljYSBPcGVyYXRpb25z
# MScwJQYDVQQLEx5uU2hpZWxkIFRTUyBFU046NzgwMC0wNUUwLUQ5NDcxNTAzBgNV
# BAMTLE1pY3Jvc29mdCBQdWJsaWMgUlNBIFRpbWUgU3RhbXBpbmcgQXV0aG9yaXR5
# oiMKAQEwBwYFKw4DAhoDFQD9LzE5nEJRAUE2Ss3xaKKPXHnLw6BnMGWkYzBhMQsw
# CQYDVQQGEwJVUzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTIwMAYD
# VQQDEylNaWNyb3NvZnQgUHVibGljIFJTQSBUaW1lc3RhbXBpbmcgQ0EgMjAyMDAN
# BgkqhkiG9w0BAQsFAAIFAO4oVyEwIhgPMjAyNjA4MTMxNDQ1NTNaGA8yMDI2MDgx
# NDE0NDU1M1owdDA6BgorBgEEAYRZCgQBMSwwKjAKAgUA7ihXIQIBADAHAgEAAgIV
# GTAHAgEAAgISTTAKAgUA7imooQIBADA2BgorBgEEAYRZCgQCMSgwJjAMBgorBgEE
# AYRZCgMCoAowCAIBAAIDB6EgoQowCAIBAAIDAYagMA0GCSqGSIb3DQEBCwUAA4IB
# AQAJmsYW5LPMoDq+dJfx2Ie+BsbqXER1AKOFq+hQohbU8nMp4aWRnWGRdABPkjmH
# r6t+Lc1xG+IDZQ7N9aeetqHgzXrVDH8cW4C1R1UmmEomB3TDzTwDrNQjOHkec8Sg
# mtQxomGwiUac09zFndAQL17u3zbPUuRW8p4dZmLi3CJoBuiya6iPSDjBhmbMAVEN
# Mr6yUTxBLAqflc4PxyZ6TT5phc467f8hk+1vHqQc2PY+ENhXIYNlMsYUG5rqX2Xp
# qO2ZoWjG/jCgU49xgX4badcdQ+1vOess0aSFnAHvvBvnPE6JFy/5oDY/aYxbq1cs
# 0ArDJprNfVHItgDv6hAMOr0TMA0GCSqGSIb3DQEBAQUABIICADKAEUOYP6gUwexq
# mn55oDJZHu5R1pRYPj0937ejBHJLFMwtVxaI3MDet1d9irWMk+6II5gaiMsrXSdk
# cjTMRhr8eQy+8wgBkUYERPK4iD2mifpWb3d7IxnVKTwH9bJ7e6XyludOG+IEq1NX
# oglq06jqkCETQsKzF0HXX+GPCyVY9inAEIiAdBaxrdG65iHyCXHJdEC1rhP16OLu
# p9VWN19RrWHhsxdm2j8BtZqVufprht8jrU4HwXZ10LqmOW/t+7fv7V+mbx4kqdee
# fx3pIoIyrBSOquhLW7q9uOaVwL+xMLEELNvbqHJsVkDjOGepq4onpG0znIxklMEX
# Z7vB4LrNOw8rHGEM9nhHTBBdQAIJCPMvFaziAWBF8snUPgWNIFdt7gGkvea/297y
# mpMrdxcKir5yAZX9CfZNH0BZdkAdSmZP/zUmBUTlwP9Mgz89OX4qA2MWZpgozOuf
# gAYf8sPnkkpOc5EPLg5DtK0ubyCtP4cbhy6aH65ZijIMY1WTzIIAl5qth48QlsRC
# zzlR1RX+A16ppno6lmA9VtrgRRirICvED+MoDl7UI5qSKoQ9BDC0Tb5jsPX7OpPq
# JK+SkYKmBV3rSL5LGT19KdA0OJWcztRn8LOh6WYU0LAMmyKLzoCqM22LAE6dYacQ
# sCHDWxaIFyEbWKRtQ3d7/qfSHhHe
# SIG # End signature block