Private/Get-StorageBlobReadLogs.ps1

function Convert-LogAnalyticsRows {
  param(
    [object]$Table
  )

  $columns = @($Table.columns | ForEach-Object { [string]$_.name })
  foreach ($row in @($Table.rows)) {
    $record = [ordered]@{}
    for ($index = 0; $index -lt $columns.Count; $index++) {
      $record[$columns[$index]] = $row[$index]
    }

    [pscustomobject]$record
  }
}

function Get-LogAnalyticsAccessToken {
  $token = Get-AzAccessToken -ResourceUrl "https://api.loganalytics.azure.com" -ErrorAction Stop
  if ($token.Token -is [securestring]) {
    return ([pscredential]::new("token", $token.Token)).GetNetworkCredential().Password
  }

  return [string]$token.Token
}

function Invoke-LogAnalyticsQuery {
  [CmdletBinding()]
  param(
    [Parameter(Mandatory = $true)]
    [string]$WorkspaceId,

    [Parameter(Mandatory = $true)]
    [string]$Query,

    [Parameter(Mandatory = $true)]
    [datetime]$StartTime,

    [Parameter(Mandatory = $true)]
    [datetime]$EndTime
  )

  $accessToken = Get-LogAnalyticsAccessToken
  $headers = @{
    Authorization = "Bearer $accessToken"
    "Content-Type" = "application/json"
  }
  $body = @{
    query = $Query
    timespan = "$($StartTime.ToUniversalTime().ToString("o"))/$($EndTime.ToUniversalTime().ToString("o"))"
  } | ConvertTo-Json -Depth 10

  $response = Invoke-RestRequestWithRetry `
    -OperationName "Log Analytics query" `
    -Request {
      Invoke-RestMethod `
        -Method POST `
        -Uri "https://api.loganalytics.azure.com/v1/workspaces/$WorkspaceId/query" `
        -Headers $headers `
        -Body $body `
        -ErrorAction Stop
    }

  $primaryResult = @($response.tables | Where-Object name -eq "PrimaryResult" | Select-Object -First 1)
  if (-not $primaryResult) {
    return @()
  }

  return @(Convert-LogAnalyticsRows -Table $primaryResult)
}

function Get-AzureStorageAccountsForScope {
  param(
    [string]$Scope,
    [object[]]$Resources
  )

  $scopeParts = Get-AzureScopeParts -Scope $Scope
  foreach ($resource in @($Resources)) {
    $resourceType = [string]$resource.ResourceType
    if (-not $resourceType.Equals("Microsoft.Storage/storageAccounts", [System.StringComparison]::OrdinalIgnoreCase)) {
      continue
    }

    $resourceId = [string]$resource.ResourceId
    if ([string]::IsNullOrWhiteSpace($resourceId)) {
      continue
    }

    if ($scopeParts.scopeType -eq "Subscription") {
      $resource
      continue
    }

    if ($scopeParts.scopeType -eq "ResourceGroup") {
      if ([string]$resource.ResourceGroupName -eq [string]$scopeParts.resourceGroup) {
        $resource
      }
      continue
    }

    if ($scopeParts.scopeType -eq "Resource" -and (
        $resourceId.Equals([string]$Scope, [System.StringComparison]::OrdinalIgnoreCase) -or
        ([string]$Scope).StartsWith("$resourceId/", [System.StringComparison]::OrdinalIgnoreCase))) {
      $resource
    }
  }
}

function New-KqlStringLiteral {
  param([string]$Value)

  return "'$(([string]$Value).Replace("'", "''"))'"
}

function New-KqlDynamicStringArray {
  param([string[]]$Values)

  $items = @($Values | Where-Object { -not [string]::IsNullOrWhiteSpace($_) } | Sort-Object -Unique | ForEach-Object {
      New-KqlStringLiteral -Value $_
    })

  return "dynamic([$($items -join ",")])"
}

function Get-StorageBlobAccessDirection {
  param([string]$OperationName)

  switch -Regex ([string]$OperationName) {
    "^(GetBlob|GetBlobProperties|GetBlobMetadata)$" { return "Read" }
    "^(PutBlob|PutBlock|PutBlockList|AppendBlock|CopyBlob|SetBlobMetadata|SetBlobProperties)$" { return "Publish" }
    default { return "Other" }
  }
}

function Get-StorageBlobParticipantType {
  param(
    [string]$RequesterAppId,
    [string]$RequesterUpn
  )

  $hasApp = -not [string]::IsNullOrWhiteSpace($RequesterAppId)
  $hasUser = -not [string]::IsNullOrWhiteSpace($RequesterUpn)

  if ($hasApp -and $hasUser) {
    return "UserAndServicePrincipal"
  }

  if ($hasApp) {
    return "ServicePrincipal"
  }

  if ($hasUser) {
    return "User"
  }

  return "Unknown"
}

function ConvertTo-SafeStorageBlobUri {
  param([string]$Uri)

  if ([string]::IsNullOrWhiteSpace($Uri)) {
    return ""
  }

  try {
    $parsedUri = [System.Uri]::new($Uri)
    if ($parsedUri.IsAbsoluteUri) {
      return $parsedUri.GetLeftPart([System.UriPartial]::Path)
    }
  } catch {
    $queryStart = $Uri.IndexOf("?")
    if ($queryStart -ge 0) {
      return $Uri.Substring(0, $queryStart)
    }

    return $Uri
  }

  $relativeQueryStart = $Uri.IndexOf("?")
  if ($relativeQueryStart -ge 0) {
    return $Uri.Substring(0, $relativeQueryStart)
  }

  return $Uri
}

function Test-StorageBlobRequesterMatchesServicePrincipal {
  param(
    [object]$BlobAccess,
    [object]$ServicePrincipal
  )

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

  $requesterObjectId = [string]$BlobAccess.requesterObjectId
  $requesterAppId = [string]$BlobAccess.requesterAppId

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

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

  return $false
}

function Get-StorageBlobReadLogs {
  [CmdletBinding()]
  param(
    [Parameter(Mandatory = $true)]
    [string]$WorkspaceId,

    [Parameter(Mandatory = $true)]
    [object[]]$StorageAccounts,

    [object]$ServicePrincipal = $null,

    [Parameter(Mandatory = $true)]
    [datetime]$StartTime,

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

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

  $accounts = @($StorageAccounts | Where-Object {
      -not [string]::IsNullOrWhiteSpace([string]$_.Name)
    } | Sort-Object Name -Unique)

  if ($accounts.Count -eq 0) {
    return @()
  }

  $accountNames = @($accounts | ForEach-Object { [string]$_.Name })
  $accountResourceIds = @($accounts | ForEach-Object { [string]$_.ResourceId })
  $query = @"
let targetAccounts = $(New-KqlDynamicStringArray -Values $accountNames);
let targetResourceIds = $(New-KqlDynamicStringArray -Values $accountResourceIds);
let readOperations = $(New-KqlDynamicStringArray -Values $BlobReadOperationNames);
let blobAccessEvents = StorageBlobLogs
| where AccountName in~ (targetAccounts) or _ResourceId in~ (targetResourceIds)
| where OperationName in~ (readOperations)
| extend RequesterObjectId = tostring(column_ifexists("RequesterObjectId", "")),
         RequesterAppId = tostring(column_ifexists("RequesterAppId", "")),
         RequesterTenantId = tostring(column_ifexists("RequesterTenantId", "")),
         RequesterUpn = tostring(column_ifexists("RequesterUpn", "")),
         UserAgentHeader = tostring(column_ifexists("UserAgentHeader", "")),
         AuthenticationHash = tostring(column_ifexists("AuthenticationHash", "")),
         SasExpiryStatus = tostring(column_ifexists("SasExpiryStatus", "")),
         SasGeneratorObjectId = tostring(extract(@"(?i)(?:[?&]skoid=)([^&]+)", 1, Uri)),
         SasGeneratorTenantId = tostring(extract(@"(?i)(?:[?&]sktid=)([^&]+)", 1, Uri)),
         SasExpiresOn = tostring(extract(@"(?i)(?:[?&](?:ske|se)=)([^&]+)", 1, Uri)),
         SasSignedIdentifier = tostring(extract(@"(?i)(?:[?&]si=)([^&]+)", 1, Uri)),
         SasSignedPermissions = tostring(extract(@"(?i)(?:[?&]sp=)([^&]+)", 1, Uri)),
         SafeUri = tostring(split(Uri, "?")[0]);
let sasGeneratorEvents = StorageBlobLogs
| where AccountName in~ (targetAccounts) or _ResourceId in~ (targetResourceIds)
| where OperationName =~ "GetUserDelegationKey"
| extend SasGeneratorEventTimestamp = TimeGenerated,
         DelegationGeneratorObjectId = tostring(column_ifexists("RequesterObjectId", "")),
         DelegationGeneratorAppId = tostring(column_ifexists("RequesterAppId", "")),
         DelegationGeneratorTenantId = tostring(column_ifexists("RequesterTenantId", "")),
         DelegationGeneratorUpn = tostring(column_ifexists("RequesterUpn", ""))
| where isnotempty(DelegationGeneratorObjectId)
| summarize arg_max(SasGeneratorEventTimestamp, DelegationGeneratorAppId, DelegationGeneratorTenantId, DelegationGeneratorUpn) by AccountName, DelegationGeneratorObjectId;
blobAccessEvents
| join kind=leftouter sasGeneratorEvents on $left.AccountName == $right.AccountName and $left.SasGeneratorObjectId == $right.DelegationGeneratorObjectId
| extend SasGeneratorAppId = DelegationGeneratorAppId,
         SasGeneratorTenantId = iff(isempty(SasGeneratorTenantId), DelegationGeneratorTenantId, SasGeneratorTenantId),
         SasGeneratorUpn = DelegationGeneratorUpn
| project TimeGenerated, AccountName, OperationName, StatusCode, StatusText, AuthenticationType, AuthenticationHash, SasExpiryStatus, SasGeneratorObjectId, SasGeneratorTenantId, SasGeneratorUpn, SasGeneratorAppId, SasGeneratorEventTimestamp, SasExpiresOn, SasSignedIdentifier, SasSignedPermissions, RequesterObjectId, RequesterAppId, RequesterTenantId, RequesterUpn, CallerIpAddress, UserAgentHeader, SafeUri, ObjectKey, _ResourceId
| order by TimeGenerated desc
| take $MaxRecord
"@


  $rows = @(Invoke-LogAnalyticsQuery `
      -WorkspaceId $WorkspaceId `
      -Query $query `
      -StartTime $StartTime `
      -EndTime (Get-Date))

  foreach ($row in $rows) {
    $safeUri = if (-not [string]::IsNullOrWhiteSpace([string]$row.SafeUri)) {
      [string]$row.SafeUri
    } else {
      ConvertTo-SafeStorageBlobUri -Uri ([string]$row.Uri)
    }

    [pscustomobject]@{
      eventTimestamp = [string]$row.TimeGenerated
      storageAccountName = [string]$row.AccountName
      storageAccountResourceId = [string]$row._ResourceId
      operationName = [string]$row.OperationName
      statusCode = [string]$row.StatusCode
      statusText = [string]$row.StatusText
      accessDirection = Get-StorageBlobAccessDirection -OperationName ([string]$row.OperationName)
      authenticationType = [string]$row.AuthenticationType
      authenticationHash = [string]$row.AuthenticationHash
      sasExpiryStatus = [string]$row.SasExpiryStatus
      sasGeneratorObjectId = [string]$row.SasGeneratorObjectId
      sasGeneratorAppId = [string]$row.SasGeneratorAppId
      sasGeneratorTenantId = [string]$row.SasGeneratorTenantId
      sasGeneratorUpn = [string]$row.SasGeneratorUpn
      sasGeneratorEventTimestamp = [string]$row.SasGeneratorEventTimestamp
      sasExpiresOn = [string]$row.SasExpiresOn
      sasSignedIdentifier = [string]$row.SasSignedIdentifier
      sasSignedPermissions = [string]$row.SasSignedPermissions
      requesterObjectId = [string]$row.RequesterObjectId
      requesterAppId = [string]$row.RequesterAppId
      requesterTenantId = [string]$row.RequesterTenantId
      requesterUpn = [string]$row.RequesterUpn
      requesterType = Get-StorageBlobParticipantType -RequesterAppId ([string]$row.RequesterAppId) -RequesterUpn ([string]$row.RequesterUpn)
      callerIpAddress = [string]$row.CallerIpAddress
      userAgentHeader = [string]$row.UserAgentHeader
      uri = ConvertTo-SafeStorageBlobUri -Uri $safeUri
      objectKey = [string]$row.ObjectKey
      matchesInspectedServicePrincipal = if ($ServicePrincipal) {
        [bool](Test-StorageBlobRequesterMatchesServicePrincipal -BlobAccess ([pscustomobject]@{
              requesterObjectId = [string]$row.RequesterObjectId
              requesterAppId = [string]$row.RequesterAppId
            }) -ServicePrincipal $ServicePrincipal)
      } else {
        $false
      }
      evidenceConfidence = "medium"
      evidenceReason = "StorageBlobLogs show a blob data-plane operation recorded by Azure Storage diagnostic logs. Publish operations can represent data sent to an agent; read operations can represent data consumed from it."
    }
  }
}

function Get-StorageBlobReadCallers {
  param(
    [object[]]$BlobReadEvidence
  )

  $groups = @($BlobReadEvidence) | Group-Object -Property {
    Get-OwnerLensPrincipalKey `
      -ObjectId ([string]$_.requesterObjectId) `
      -AppId ([string]$_.requesterAppId) `
      -Upn ([string]$_.requesterUpn)
  }

  foreach ($group in $groups) {
    $items = @($group.Group | Sort-Object eventTimestamp)
    $first = $items | Select-Object -First 1
    $last = $items | Select-Object -Last 1
    $publishCount = @($items | Where-Object accessDirection -eq "Publish").Count
    $readCount = @($items | Where-Object accessDirection -eq "Read").Count

    [pscustomobject]@{
      requesterKey = [string]$group.Name
      requesterObjectId = [string]$last.requesterObjectId
      requesterAppId = [string]$last.requesterAppId
      requesterTenantId = [string]$last.requesterTenantId
      requesterUpn = [string]$last.requesterUpn
      requesterType = [string]$last.requesterType
      authenticationType = [string]$last.authenticationType
      readCount = [int]$items.Count
      blobAccessCount = [int]$items.Count
      blobReadCount = [int]$readCount
      blobPublishCount = [int]$publishCount
      firstSeen = [string]$first.eventTimestamp
      lastSeen = [string]$last.eventTimestamp
      storageAccounts = @($items | Select-Object -ExpandProperty storageAccountName -Unique | Where-Object { -not [string]::IsNullOrWhiteSpace($_) })
      accessDirections = @($items | Select-Object -ExpandProperty accessDirection -Unique | Where-Object { -not [string]::IsNullOrWhiteSpace($_) })
      operationNames = @($items | Select-Object -ExpandProperty operationName -Unique | Where-Object { -not [string]::IsNullOrWhiteSpace($_) })
      callerIpAddresses = @($items | Select-Object -ExpandProperty callerIpAddress -Unique | Where-Object { -not [string]::IsNullOrWhiteSpace($_) })
      userAgentHeaders = @($items | Select-Object -ExpandProperty userAgentHeader -Unique | Where-Object { -not [string]::IsNullOrWhiteSpace($_) } | Select-Object -First 10)
      sasAuthenticationCount = [int](@($items | Where-Object {
          ([string]$_.authenticationType).Equals("SAS", [System.StringComparison]::OrdinalIgnoreCase)
        }).Count)
      sasGeneratorObjectIds = @($items | ForEach-Object { [string]$_.sasGeneratorObjectId } | Where-Object { -not [string]::IsNullOrWhiteSpace($_) } | Sort-Object -Unique)
      sasGeneratorAppIds = @($items | ForEach-Object { [string]$_.sasGeneratorAppId } | Where-Object { -not [string]::IsNullOrWhiteSpace($_) } | Sort-Object -Unique)
      sasGeneratorUpns = @($items | ForEach-Object { [string]$_.sasGeneratorUpn } | Where-Object { -not [string]::IsNullOrWhiteSpace($_) } | Sort-Object -Unique)
      sasSignedIdentifiers = @($items | ForEach-Object { [string]$_.sasSignedIdentifier } | Where-Object { -not [string]::IsNullOrWhiteSpace($_) } | Sort-Object -Unique)
      sampleUris = @($items | Select-Object -ExpandProperty uri -Unique | Where-Object { -not [string]::IsNullOrWhiteSpace($_) } | Select-Object -First 10)
      matchesInspectedServicePrincipal = [bool](@($items | Where-Object matchesInspectedServicePrincipal).Count -gt 0)
      evidenceConfidence = "medium"
      evidenceReason = "Requester has one or more StorageBlobLogs data-plane records in the selected time window, grouped with both user and service principal identifiers when Azure logged both."
    }
  }
}

function Get-StorageBlobReadObjects {
  param(
    [object[]]$BlobReadEvidence
  )

  $readEvidence = @($BlobReadEvidence | Where-Object {
      ([string]$_.accessDirection).Equals("Read", [System.StringComparison]::OrdinalIgnoreCase)
    })

  $groups = @($readEvidence) | Group-Object -Property {
    $uri = [string]$_.uri
    $objectKey = [string]$_.objectKey

    $requesterKey = Get-OwnerLensPrincipalKey `
      -ObjectId ([string]$_.requesterObjectId) `
      -AppId ([string]$_.requesterAppId) `
      -Upn ([string]$_.requesterUpn)

    $blobKey = if (-not [string]::IsNullOrWhiteSpace($uri)) {
      "uri:$uri"
    } elseif (-not [string]::IsNullOrWhiteSpace($objectKey)) {
      "objectKey:$objectKey"
    } else {
      "unknownBlob"
    }

    return "$requesterKey|$blobKey"
  }

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

    [pscustomobject]@{
      requesterBlobKey = [string]$group.Name
      requesterObjectId = [string]$last.requesterObjectId
      requesterAppId = [string]$last.requesterAppId
      requesterTenantId = [string]$last.requesterTenantId
      requesterUpn = [string]$last.requesterUpn
      requesterType = [string]$last.requesterType
      authenticationType = [string]$last.authenticationType
      storageAccountName = [string]$last.storageAccountName
      storageAccountResourceId = [string]$last.storageAccountResourceId
      uri = [string]$last.uri
      objectKey = [string]$last.objectKey
      sasAuthenticationCount = [int](@($items | Where-Object {
          ([string]$_.authenticationType).Equals("SAS", [System.StringComparison]::OrdinalIgnoreCase)
        }).Count)
      sasGeneratorObjectIds = @($items | ForEach-Object { [string]$_.sasGeneratorObjectId } | Where-Object { -not [string]::IsNullOrWhiteSpace($_) } | Sort-Object -Unique)
      sasGeneratorAppIds = @($items | ForEach-Object { [string]$_.sasGeneratorAppId } | Where-Object { -not [string]::IsNullOrWhiteSpace($_) } | Sort-Object -Unique)
      sasGeneratorUpns = @($items | ForEach-Object { [string]$_.sasGeneratorUpn } | Where-Object { -not [string]::IsNullOrWhiteSpace($_) } | Sort-Object -Unique)
      sasSignedIdentifiers = @($items | ForEach-Object { [string]$_.sasSignedIdentifier } | Where-Object { -not [string]::IsNullOrWhiteSpace($_) } | Sort-Object -Unique)
      blobReadCount = [int]$items.Count
      firstReadAt = [string]$first.eventTimestamp
      lastReadAt = [string]$last.eventTimestamp
      operationNames = @($items | Select-Object -ExpandProperty operationName -Unique | Where-Object { -not [string]::IsNullOrWhiteSpace($_) })
      callerIpAddresses = @($items | Select-Object -ExpandProperty callerIpAddress -Unique | Where-Object { -not [string]::IsNullOrWhiteSpace($_) })
      userAgentHeaders = @($items | Select-Object -ExpandProperty userAgentHeader -Unique | Where-Object { -not [string]::IsNullOrWhiteSpace($_) } | Select-Object -First 10)
      matchesInspectedServicePrincipal = [bool](@($items | Where-Object matchesInspectedServicePrincipal).Count -gt 0)
      evidenceConfidence = "medium"
      evidenceReason = "Requester read a specific blob one or more times according to StorageBlobLogs in the selected time window."
    }
  }
}

# SIG # Begin signature block
# MII9MQYJKoZIhvcNAQcCoII9IjCCPR4CAQExDzANBglghkgBZQMEAgEFADB5Bgor
# BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG
# KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCCT8GPolyGJzcp+
# boWqMYoDgzCZyIaIns90tYwg7w4ll6CCIfYwggXMMIIDtKADAgECAhBUmNLR1FsZ
# 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+tHD6n58vhavFIrmcxghqRMIIajQIBATBxMFox
# CzAJBgNVBAYTAlVTMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xKzAp
# BgNVBAMTIk1pY3Jvc29mdCBJRCBWZXJpZmllZCBDUyBBT0MgQ0EgMDQCEzMABU99
# NQlABlAeikYAAAAFT30wDQYJYIZIAWUDBAIBBQCgXjAQBgorBgEEAYI3AgEMMQIw
# ADAZBgkqhkiG9w0BCQMxDAYKKwYBBAGCNwIBBDAvBgkqhkiG9w0BCQQxIgQgZ18N
# ZunZgmXIl+u0jKXG4CrLD+tWd2hWRBi65iqPdoIwDQYJKoZIhvcNAQEBBQAEggGA
# bVLn4SJm5HqNbGack3EYs03SodV3DPuaR8LFo2vyvoIA+DlboxpiU88kmgTv2N6n
# 64pzs3yHETjU3hOy56klmLlfsbKO9eLO/qCyydx5/ORwCvDoiLw7pMbBw8vzXkdQ
# 5W9ZUsu3wCo2F/QSqd2F1t8P84OWeZpZkKGRrS63BY3tqLzNc1yQUX6NuuJAGNZK
# /pBmRtj4WgT/5lM4tuJbYRsrUChiGWEhNx1vJo9T64BOmMW0ykIvlgM8jOlXh9Tw
# bWG/rT82sQvWALe8mBYLqAJkvFX9UW8wauDw6R1QnVf4O25sKfMuDHluAYUyE6ri
# 2lFzQt7ghGJjov/V+55fUPgex8KfJ2PYtvbCZklQPbdcLRTQqBRftR/207nBJSA1
# addRaarEcC9+RFSwxnuCTDDaiIYyty/uajzXzQd7w3cgBKV5fAQcvLp8t1jHhaug
# k/C2OxYm+qUI70uby+PRJRN16K0KXJmeReiY1tJ500CvAPaJJMk0Ds84FygASaYN
# oYIYETCCGA0GCisGAQQBgjcDAwExghf9MIIX+QYJKoZIhvcNAQcCoIIX6jCCF+YC
# AQMxDzANBglghkgBZQMEAgEFADCCAWIGCyqGSIb3DQEJEAEEoIIBUQSCAU0wggFJ
# AgEBBgorBgEEAYRZCgMBMDEwDQYJYIZIAWUDBAIBBQAEIECi1XOTxxR/Osg1vm1w
# 3YRM4DBjwmzyQfnXGV3nenwYAgZqhGwUNIAYEzIwMjYwODI2MTIxMDMyLjkxOVow
# BIACAfSggeGkgd4wgdsxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9u
# MRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRp
# b24xJTAjBgNVBAsTHE1pY3Jvc29mdCBBbWVyaWNhIE9wZXJhdGlvbnMxJzAlBgNV
# BAsTHm5TaGllbGQgVFNTIEVTTjo3QTAwLTA1RTAtRDk0NzE1MDMGA1UEAxMsTWlj
# 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+gAwIBAgITMwAAAFhlzes/odf80gAAAAAAWDANBgkqhkiG9w0B
# AQwFADBhMQswCQYDVQQGEwJVUzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0
# aW9uMTIwMAYDVQQDEylNaWNyb3NvZnQgUHVibGljIFJTQSBUaW1lc3RhbXBpbmcg
# Q0EgMjAyMDAeFw0yNTEwMjMyMDQ2NTVaFw0yNjEwMjIyMDQ2NTVaMIHbMQswCQYD
# VQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEe
# MBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSUwIwYDVQQLExxNaWNyb3Nv
# ZnQgQW1lcmljYSBPcGVyYXRpb25zMScwJQYDVQQLEx5uU2hpZWxkIFRTUyBFU046
# N0EwMC0wNUUwLUQ5NDcxNTAzBgNVBAMTLE1pY3Jvc29mdCBQdWJsaWMgUlNBIFRp
# bWUgU3RhbXBpbmcgQXV0aG9yaXR5MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC
# CgKCAgEAnXg0pHaQ7PVAlln+HZZrJFcLoKbekhW1yL+QNBUgFFUsjZIKaqqN4oIJ
# sJM3ps0rJNSO7ndCNRuZDX2Wgur3Ak77eXrloBXqZmO6ZVXeDNRCLldW4A0/Nfjz
# J7XXkdEhjr81ghXEpR7zC+wbaNN+sPSxzLAZBeibDFP7Xws5wX0ZtIsN1a2+Xq5b
# vWp3kRMytwskTjunRgeLZL/tBp237JVdRPFAQ9jYRKpCqUBo/v1xjBLRCV3PalKj
# nGfb3MN4U7jVyqifFHShcnW5CERRoBmUa6sygDzFSr8e3g93TPNLFUivUE0GmLfb
# X5ceD1Gt1FcZ6x/JLVATzk5+BWHbMxwJIVkVPTqSSMjQ6KTKdcnq3pH0c4AFJp/g
# lvcpq0U9fzZIjJGGvdpishlRl77RQtUhSjxHvCn3LC/xqQQwOHSQDsGh6NX2D0Rf
# sSyEtTAByAae+2w1HByTDTcmlTNLEuQLeCj1gNBdIWj0WOYyDtjjQ/8iTWY6ey1v
# b9qHljIj5HgIndT5P9MYk2Vg2e7hKUZNBNbA/hsgBsuoZ+IX89WvjEN9abF91S4O
# JVuinmKsLO/MLbnl7ikuD0dN6oA0YewyDQncs12sM9HOtu72QA/TZlefvW8r9xtM
# XAYoQlcGjsk8W4Uc7cfqVqbIPjdoc8ZxBzLcXcVyP4p5cyLwvkMCAwEAAaOCAcsw
# ggHHMB0GA1UdDgQWBBRyjU3Fer4VxXJ+hjPcRJnxnRIJsDAfBgNVHSMEGDAWgBRr
# aSg6NS9IY0DPe9ivSek+2T3bITBsBgNVHR8EZTBjMGGgX6BdhltodHRwOi8vd3d3
# Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2NybC9NaWNyb3NvZnQlMjBQdWJsaWMlMjBS
# U0ElMjBUaW1lc3RhbXBpbmclMjBDQSUyMDIwMjAuY3JsMHkGCCsGAQUFBwEBBG0w
# azBpBggrBgEFBQcwAoZdaHR0cDovL3d3dy5taWNyb3NvZnQuY29tL3BraW9wcy9j
# ZXJ0cy9NaWNyb3NvZnQlMjBQdWJsaWMlMjBSU0ElMjBUaW1lc3RhbXBpbmclMjBD
# QSUyMDIwMjAuY3J0MAwGA1UdEwEB/wQCMAAwFgYDVR0lAQH/BAwwCgYIKwYBBQUH
# AwgwDgYDVR0PAQH/BAQDAgeAMGYGA1UdIARfMF0wUQYMKwYBBAGCN0yDfQEBMEEw
# PwYIKwYBBQUHAgEWM2h0dHA6Ly93d3cubWljcm9zb2Z0LmNvbS9wa2lvcHMvRG9j
# cy9SZXBvc2l0b3J5Lmh0bTAIBgZngQwBBAIwDQYJKoZIhvcNAQEMBQADggIBAHvr
# xIiVF1iHcXvxrJTCD8eOtbPUbK9x+Lz70iYehh+G0UoOMcMf04QD6tQPTeZ5HhGE
# Tkcn0raDJ5NpfbRBuKEH31rxbZK97o12KRDNJ3Nu4ePaUIpH/TcWz8PLVOCECywS
# xbEgEG20kyydGc46c591tXzpfkJDckjoYrypaerdeQLRQH9LaoTYZfdAzMo+Dy0O
# 1DzFJkF5YnsmAM8lt9r1NtXdFjdbFMCbV5dau64mV22s186A8Umi+l239+Ue0cbJ
# QIykWhIlhhWhxQgoksqHz7kp2GFZAAeySTmIOQOWyXOA8JA8TISJyn3JDOgStv58
# 3P3V0QSALT6JXDCW26FV208VGJMzkv0S22iOTZJ/oamTpk8RzD8oWT8pfbe1q/k/
# bxPiXYRbzps96a5YOko7n0Vdo61DOJhL/mhk01Y348gq6vhG/VTcdGHh1rCkwOM0
# 5B35AZZq9AtPpfRzJinrHzzGRx+r6fD3ccYMPMMX/Nwd2irzrph172fQcSf1fMwv
# wIhmfH4GWJJ+mf1HA6uXoAOVByckguXvlj8gPi7T2ES6RU8+QssfqTNTJKjsBheW
# KWv2W4ESVen2L7lCz7i79FhA+0kp0yXJnYwdzWS0ovTINULINmzVyMcSUm5WuVf8
# YZ33cAud2Opr6N1+RuLZDavDvjiehlI5dH+GEy56MYIHQzCCBz8CAQEweDBhMQsw
# CQYDVQQGEwJVUzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTIwMAYD
# VQQDEylNaWNyb3NvZnQgUHVibGljIFJTQSBUaW1lc3RhbXBpbmcgQ0EgMjAyMAIT
# MwAAAFhlzes/odf80gAAAAAAWDANBglghkgBZQMEAgEFAKCCBJwwEQYLKoZIhvcN
# AQkQAg8xAgUAMBoGCSqGSIb3DQEJAzENBgsqhkiG9w0BCRABBDAcBgkqhkiG9w0B
# CQUxDxcNMjYwODI2MTIxMDMyWjAvBgkqhkiG9w0BCQQxIgQgIMSwwjQvK6Sg0udF
# 8gPwDEsXoA3EVk/bcSE3SgVgh9swgbkGCyqGSIb3DQEJEAIvMYGpMIGmMIGjMIGg
# BCDFIlS7sgfQ+wAo1cWbWz+WN69VBds58hbran919aLocTB8MGWkYzBhMQswCQYD
# VQQGEwJVUzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTIwMAYDVQQD
# EylNaWNyb3NvZnQgUHVibGljIFJTQSBUaW1lc3RhbXBpbmcgQ0EgMjAyMAITMwAA
# AFhlzes/odf80gAAAAAAWDCCA14GCyqGSIb3DQEJEAISMYIDTTCCA0mhggNFMIID
# QTCCAikCAQEwggEJoYHhpIHeMIHbMQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2Fz
# aGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENv
# cnBvcmF0aW9uMSUwIwYDVQQLExxNaWNyb3NvZnQgQW1lcmljYSBPcGVyYXRpb25z
# MScwJQYDVQQLEx5uU2hpZWxkIFRTUyBFU046N0EwMC0wNUUwLUQ5NDcxNTAzBgNV
# BAMTLE1pY3Jvc29mdCBQdWJsaWMgUlNBIFRpbWUgU3RhbXBpbmcgQXV0aG9yaXR5
# oiMKAQEwBwYFKw4DAhoDFQCdZHkb26ercF2O62vCdZUfUSvEXKBnMGWkYzBhMQsw
# CQYDVQQGEwJVUzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTIwMAYD
# VQQDEylNaWNyb3NvZnQgUHVibGljIFJTQSBUaW1lc3RhbXBpbmcgQ0EgMjAyMDAN
# BgkqhkiG9w0BAQsFAAIFAO44zckwIhgPMjAyNjA4MjYwMjI4MjVaGA8yMDI2MDgy
# NzAyMjgyNVowdDA6BgorBgEEAYRZCgQBMSwwKjAKAgUA7jjNyQIBADAHAgEAAgIH
# BjAHAgEAAgISDzAKAgUA7jofSQIBADA2BgorBgEEAYRZCgQCMSgwJjAMBgorBgEE
# AYRZCgMCoAowCAIBAAIDB6EgoQowCAIBAAIDAYagMA0GCSqGSIb3DQEBCwUAA4IB
# AQAjvkLNQq9F2agxD8+0MlhiR0IDOGLZ/UNvnZC1O9Zn0DwP1tIKPvvf9VH5tNAj
# Tle8q9errQv3bTdSV+quDE/2rv6wfeHxucnfECPI9sATHukaiLzdlZZyRtLel6vf
# 7QcJOWXfTxcOy1SXNt/xBWfvNr6mlMO+ljsS/ryJ8XKeP9rCp+tYvnZrroav+XIi
# 1KXWTuTLZr0kRrt+wCnV/ObilHxDHB5oO2U1/ppXxfkh8OucV2C9EuiUGhmRQuJy
# l5bD5rvG6yQOYMOUGNIeGN3gvOORPGxRpzhdmYIVyYFvpifhwgThjqY6IudsSFXs
# +njj3vc9SBq+jsF9qgiu5nltMA0GCSqGSIb3DQEBAQUABIICAJkwwyW17NJhN9L/
# Uaq+9nbuzdDBqZ4Mho6fK5RJAF1bfphxdmkDPtd1N/sHXIXBZgmeFo5JSQf2px0U
# SZ5PxY9QSHuWMaHAJVkUW5/xaPX1DuppvL/MNTMYeq1NIvuJPwAVDtV6wbrMEIMs
# 43nW+bXxxJdFkjzzrk+HKmbt8fgsT24Z5r+EeZdZ+Iq7pl6ZVbXAGw5RW0HKlZs3
# 04NsMS8YcSUIj76YBMgS/4cugtgT6RosttjqGWMqKLEiuwHo74+OPokID6wB78WF
# cCC/EbIL0EA2f08jwdF8vSvSE3J1+xdfQK/b+1BD/sWbp26UcDOeSvGatKkgr1xW
# vVA2GM5V1nd5jLiUF5TkWQeBjm1v0q/zrKbmst5wa5hXswekaO8aLqTJaggsjJca
# TLQy0j1zWx/OOEPaHvpeDvtdfQVy5/8M0g3YWCWrtBJl0NK+b1ryaOEMYkkKtcy8
# ZgsoD0TLDaLwJLbRlTW6HvhuxMrM2S0jaZEuqzHdsiTVcYq7RfLtRRiIvXdM10pU
# 9a0xLhCAIM5yH4mZWtNjsB1NNnUrbPkEFqXbJ/N2sqm6nXcDn9dsdW+HpXlHdTwD
# a9Rsm7xlSrkQhPg9U8Ct25flPScJBO4cPD1aX/4np4sX4pEb4N9QHdUfzB+rlC/7
# BEG5Af0Y/yL/AgRzbTEzf756Zy74
# SIG # End signature block