CyberInt.IoC.psm1

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

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

    [Parameter(Mandatory = $true)]
    [PSCredential]$Credential,

    [Parameter(Mandatory = $false)]
    [hashtable]$QueryParams = @{},

    [Parameter(Mandatory = $true)]
    [string]$BaseUrl
  )

  begin {
    $Me = $MyInvocation.MyCommand.Name
    Write-Verbose ('{0}: called from {1}' -f $Me, $MyInvocation.CommandOrigin.Name)

    $uri = "{0}{1}" -f $BaseUrl, $Endpoint
    Write-Verbose ('{0}: calling URI: {1}' -f $Me, $uri)
    $accessToken = $Credential.GetNetworkCredential().Password
  }

  process {
    if ($QueryParams.Count -gt 0) {
      $queryString = [System.Web.HttpUtility]::ParseQueryString('')
      foreach ($param in $QueryParams.GetEnumerator()) {
        $queryString[$param.Key] = $param.Value
      }
      $uri = "{0}?{1}" -f $uri, $queryString.ToString()
    }

    $headers = @{
      "Cookie" = "access_token={0}" -f $accessToken
    }

    try {
      $response = Invoke-RestMethod -Uri $uri -Method $Method -Headers $headers -ContentType "application/json" -ErrorAction Stop -verbose -debug
      Write-Output -InputObject $response
    }
    catch {
      $statusCode = $_.Exception.Response.StatusCode.value__
      $errorMessage = $_.Exception.Message
      if ($PSBoundParameters.ContainsKey('Debug')) {
        Write-Debug ('{0}: Debug Exception: {1}' -f $Me, ($_.Exception | ConvertTo-Json -Depth 5))
      }

      switch ($statusCode) {
        401 { Write-Error ("{0}: Authentication failed: Invalid credentials" -f $Me) -ErrorAction Stop }
        403 {
          Write-Error ("{0}: Access denied: Insufficient permissions" -f $Me) -ErrorAction Stop
          Write-Debug ('{0}: Debug Exception: {1}' -f $Me, ($_.Exception | ConvertTo-Json -Depth 3))
        }
        422 { Write-Error ("{0}: Invalid input: {1}" -f $Me, $errorMessage) -ErrorAction Stop }
        429 { Write-Warning ("{0}: Rate limit exceeded" -f$Me) }
        404 { Write-Warning ("{0}: Resource not found" -f $Me) }
        default { Write-Error ("{0}: Error {1}: {2}" -f $Me, $statusCode, $errorMessage) -ErrorAction Stop }
      }
    }
  }
}

function Get-CyberintDomain {
  <#
    .SYNOPSIS
    Retrieves IOC information for a domain.
 
    .PARAMETER Value
    The domain name
 
    .PARAMETER Credential
    PSCredential object containing the API access token
 
    .PARAMETER BaseUrl
    The base URL of the customer's API instance
    #>

  [CmdletBinding()]
  param (
    [Parameter(Mandatory = $true)]
    [ValidatePattern("^(?:(?:(?:[[a-z0-9](?:[a-z0-9\-]*[a-z0-9])?)\.))*(?:[a-z0-9][a-z0-9\-]*[a-z0-9])$")]
    [string]$Value,

    [Parameter(Mandatory = $true)]
    [PSCredential]$Credential,

    [Parameter(Mandatory = $true)]
    [string]$BaseUrl
  )

  process {
    $queryParams = @{ value = $Value }
    Invoke-CyberintApiRequest -Endpoint "/api/v1/domain" -Method "GET" -Credential $Credential -QueryParams $queryParams -BaseUrl $BaseUrl
  }
}

function Get-CyberintDailyFeed {
  <#
    .SYNOPSIS
    Downloads daily IOC feed, either for a specific date or by type and activity.
 
    .PARAMETER Date
    The date in YYYY-MM-DD format
 
    .PARAMETER Limit
    Number of items to retrieve (BasicFeed only)
 
    .PARAMETER Offset
    Number of items to skip (BasicFeed only)
 
    .PARAMETER Format
    The desired output format (jsonl, csv, json, txt)
 
    .PARAMETER DetectedActivity
    The detected activity type (TypedFeed only)
 
    .PARAMETER IocType
    The IOC type (file/sha256, ipv4, domain, url) (TypedFeed only)
 
    .PARAMETER Credential
    PSCredential object containing the API access token
 
    .PARAMETER BaseUrl
    The base URL of the customer's API instance
    #>

  [CmdletBinding(DefaultParameterSetName = 'BasicFeed')]
  param (
    [Parameter(Mandatory = $true, ParameterSetName = 'BasicFeed')]
    [Parameter(Mandatory = $true, ParameterSetName = 'TypedFeed')]
    [ValidatePattern("^\d{4}-\d{2}-\d{2}$")]
    [string]$Date,

    [Parameter(Mandatory = $false, ParameterSetName = 'BasicFeed')]
    [int]$Limit,

    [Parameter(Mandatory = $false, ParameterSetName = 'BasicFeed')]
    [int]$Offset,

    [Parameter(Mandatory = $false, ParameterSetName = 'BasicFeed')]
    [Parameter(Mandatory = $false, ParameterSetName = 'TypedFeed')]
    [ValidateSet("jsonl", "csv", "json", "txt")]
    [string]$Format = "jsonl",

    [Parameter(Mandatory = $true, ParameterSetName = 'TypedFeed')]
    [ValidateSet("malware_payload", "cnc_server", "infected_machine", "phishing_website", "payload_delivery", "cc_skimming",
      "botnet", "anonymization", "unclassified", "n/a", "adware", "volatile_website", "benign", "compromised_website",
      "phishing", "infecting_website", "infecting_url", "web_hosting", "file_hosting", "parked", "spam", "cryptominer",
      "riskware", "unknown", "volatile", "compromised_server", "infection_source", "scanner", "anonymiser",
      "compromised_host")]
    [string]$DetectedActivity,

    [Parameter(Mandatory = $true, ParameterSetName = 'TypedFeed')]
    [ValidateSet("file/sha256", "ipv4", "domain", "url")]
    [string]$IocType,

    [Parameter(Mandatory = $true, ParameterSetName = 'BasicFeed')]
    [Parameter(Mandatory = $true, ParameterSetName = 'TypedFeed')]
    [PSCredential]$Credential,

    [Parameter(Mandatory = $true, ParameterSetName = 'BasicFeed')]
    [Parameter(Mandatory = $true, ParameterSetName = 'TypedFeed')]
    [string]$BaseUrl
  )

  process {
    $queryParams = @{}
    $endpoint = "/api/v1/feed/daily"

    if ($PSCmdlet.ParameterSetName -eq 'BasicFeed') {
      $endpoint = "/api/v1/feed/daily/{0}" -f $Date
      if ($PSBoundParameters.ContainsKey('Limit')) { $queryParams["limit"] = $Limit }
      if ($PSBoundParameters.ContainsKey('Offset')) { $queryParams["offset"] = $Offset }
      if ($PSBoundParameters.ContainsKey('Format')) { $queryParams["format"] = $Format }
    }
    else {
      $queryParams = @{
        detected_activity = $DetectedActivity
        ioc_type          = $IocType
        date              = $Date
        format            = $Format
      }
    }

    Invoke-CyberintApiRequest -Endpoint $endpoint -Method "GET" -Credential $Credential -QueryParams $queryParams -BaseUrl $BaseUrl
  }
}

function Get-CyberintFileSha256 {
  <#
    .SYNOPSIS
    Retrieves IOC information for a file SHA256 hash.
 
    .PARAMETER Value
    The SHA256 hash value (64 hexadecimal characters)
 
    .PARAMETER Credential
    PSCredential object containing the API access token
 
    .PARAMETER BaseUrl
    The base URL of the customer's API instance
    #>

  [CmdletBinding()]
  param (
    [Parameter(Mandatory = $true)]
    [ValidatePattern("^[a-f0-9]{64}$")]
    [string]$Value,

    [Parameter(Mandatory = $true)]
    [PSCredential]$Credential,

    [Parameter(Mandatory = $true)]
    [string]$BaseUrl
  )

  process {
    $queryParams = @{ value = $Value }
    Invoke-CyberintApiRequest -Endpoint "/api/v1/file/sha256" -Method "GET" -Credential $Credential -QueryParams $queryParams -BaseUrl $BaseUrl
  }
}

function Get-CyberintIPv4 {
  <#
    .SYNOPSIS
    Retrieves IOC information for an IPv4 address.
 
    .PARAMETER Value
    The IPv4 address
 
    .PARAMETER Credential
    PSCredential object containing the API access token
 
    .PARAMETER BaseUrl
    The base URL of the customer's API instance
    #>

  [CmdletBinding()]
  param (
    [Parameter(Mandatory = $true)]
    [ValidateScript({ $_ -match [System.Net.IPAddress]::IPv4Mask })]
    [string]$Value,

    [Parameter(Mandatory = $true)]
    [PSCredential]$Credential,

    [Parameter(Mandatory = $true)]
    [string]$BaseUrl
  )

  process {
    $queryParams = @{ value = $Value }
    Invoke-CyberintApiRequest -Endpoint "/api/v1/ipv4" -Method "GET" -Credential $Credential -QueryParams $queryParams -BaseUrl $BaseUrl
  }
}

function Get-CyberintUrl {
  <#
    .SYNOPSIS
    Retrieves IOC information for a URL.
 
    .PARAMETER Value
    The URL (max 2083 characters)
 
    .PARAMETER Credential
    PSCredential object containing the API access token
 
    .PARAMETER BaseUrl
    The base URL of the customer's API instance
    #>

  [CmdletBinding()]
  param (
    [Parameter(Mandatory = $true)]
    [ValidateLength(1, 2083)]
    [uri]$Value,

    [Parameter(Mandatory = $true)]
    [PSCredential]$Credential,

    [Parameter(Mandatory = $true)]
    [string]$BaseUrl
  )

  process {
    $queryParams = @{ value = $Value.ToString() }
    Invoke-CyberintApiRequest -Endpoint "/api/v1/url" -Method "GET" -Credential $Credential -QueryParams $queryParams -BaseUrl $BaseUrl
  }
}

Export-ModuleMember -Function Get-CyberintDomain, Get-CyberintDailyFeed, Get-CyberintFileSha256, Get-CyberintIPv4, Get-CyberintUrl

# SIG # Begin signature block
# MIIuHwYJKoZIhvcNAQcCoIIuEDCCLgwCAQExDzANBglghkgBZQMEAgEFADB5Bgor
# BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG
# KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCAcf5Vqe/QuOaCb
# h5p/LonOXCnpMSsNY0jQFaxiT6InxaCCEyswggWQMIIDeKADAgECAhAFmxtXno4h
# MuI5B72nd3VcMA0GCSqGSIb3DQEBDAUAMGIxCzAJBgNVBAYTAlVTMRUwEwYDVQQK
# EwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xITAfBgNV
# BAMTGERpZ2lDZXJ0IFRydXN0ZWQgUm9vdCBHNDAeFw0xMzA4MDExMjAwMDBaFw0z
# ODAxMTUxMjAwMDBaMGIxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJ
# bmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xITAfBgNVBAMTGERpZ2lDZXJ0
# IFRydXN0ZWQgUm9vdCBHNDCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIB
# AL/mkHNo3rvkXUo8MCIwaTPswqclLskhPfKK2FnC4SmnPVirdprNrnsbhA3EMB/z
# G6Q4FutWxpdtHauyefLKEdLkX9YFPFIPUh/GnhWlfr6fqVcWWVVyr2iTcMKyunWZ
# anMylNEQRBAu34LzB4TmdDttceItDBvuINXJIB1jKS3O7F5OyJP4IWGbNOsFxl7s
# Wxq868nPzaw0QF+xembud8hIqGZXV59UWI4MK7dPpzDZVu7Ke13jrclPXuU15zHL
# 2pNe3I6PgNq2kZhAkHnDeMe2scS1ahg4AxCN2NQ3pC4FfYj1gj4QkXCrVYJBMtfb
# BHMqbpEBfCFM1LyuGwN1XXhm2ToxRJozQL8I11pJpMLmqaBn3aQnvKFPObURWBf3
# JFxGj2T3wWmIdph2PVldQnaHiZdpekjw4KISG2aadMreSx7nDmOu5tTvkpI6nj3c
# AORFJYm2mkQZK37AlLTSYW3rM9nF30sEAMx9HJXDj/chsrIRt7t/8tWMcCxBYKqx
# YxhElRp2Yn72gLD76GSmM9GJB+G9t+ZDpBi4pncB4Q+UDCEdslQpJYls5Q5SUUd0
# viastkF13nqsX40/ybzTQRESW+UQUOsxxcpyFiIJ33xMdT9j7CFfxCBRa2+xq4aL
# T8LWRV+dIPyhHsXAj6KxfgommfXkaS+YHS312amyHeUbAgMBAAGjQjBAMA8GA1Ud
# EwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBTs1+OC0nFdZEzf
# Lmc/57qYrhwPTzANBgkqhkiG9w0BAQwFAAOCAgEAu2HZfalsvhfEkRvDoaIAjeNk
# aA9Wz3eucPn9mkqZucl4XAwMX+TmFClWCzZJXURj4K2clhhmGyMNPXnpbWvWVPjS
# PMFDQK4dUPVS/JA7u5iZaWvHwaeoaKQn3J35J64whbn2Z006Po9ZOSJTROvIXQPK
# 7VB6fWIhCoDIc2bRoAVgX+iltKevqPdtNZx8WorWojiZ83iL9E3SIAveBO6Mm0eB
# cg3AFDLvMFkuruBx8lbkapdvklBtlo1oepqyNhR6BvIkuQkRUNcIsbiJeoQjYUIp
# 5aPNoiBB19GcZNnqJqGLFNdMGbJQQXE9P01wI4YMStyB0swylIQNCAmXHE/A7msg
# dDDS4Dk0EIUhFQEI6FUy3nFJ2SgXUE3mvk3RdazQyvtBuEOlqtPDBURPLDab4vri
# RbgjU2wGb2dVf0a1TD9uKFp5JtKkqGKX0h7i7UqLvBv9R0oN32dmfrJbQdA75PQ7
# 9ARj6e/CVABRoIoqyc54zNXqhwQYs86vSYiv85KZtrPmYQ/ShQDnUBrkG5WdGaG5
# nLGbsQAe79APT0JsyQq87kP6OnGlyE0mpTX9iV28hWIdMtKgK1TtmlfB2/oQzxm3
# i0objwG2J5VT6LaJbVu8aNQj6ItRolb58KaAoNYes7wPD1N1KarqE3fk3oyBIa0H
# EEcRrYc9B9F1vM/zZn4wggawMIIEmKADAgECAhAIrUCyYNKcTJ9ezam9k67ZMA0G
# CSqGSIb3DQEBDAUAMGIxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJ
# bmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xITAfBgNVBAMTGERpZ2lDZXJ0
# IFRydXN0ZWQgUm9vdCBHNDAeFw0yMTA0MjkwMDAwMDBaFw0zNjA0MjgyMzU5NTla
# MGkxCzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5EaWdpQ2VydCwgSW5jLjFBMD8GA1UE
# AxM4RGlnaUNlcnQgVHJ1c3RlZCBHNCBDb2RlIFNpZ25pbmcgUlNBNDA5NiBTSEEz
# ODQgMjAyMSBDQTEwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDVtC9C
# 0CiteLdd1TlZG7GIQvUzjOs9gZdwxbvEhSYwn6SOaNhc9es0JAfhS0/TeEP0F9ce
# 2vnS1WcaUk8OoVf8iJnBkcyBAz5NcCRks43iCH00fUyAVxJrQ5qZ8sU7H/Lvy0da
# E6ZMswEgJfMQ04uy+wjwiuCdCcBlp/qYgEk1hz1RGeiQIXhFLqGfLOEYwhrMxe6T
# SXBCMo/7xuoc82VokaJNTIIRSFJo3hC9FFdd6BgTZcV/sk+FLEikVoQ11vkunKoA
# FdE3/hoGlMJ8yOobMubKwvSnowMOdKWvObarYBLj6Na59zHh3K3kGKDYwSNHR7Oh
# D26jq22YBoMbt2pnLdK9RBqSEIGPsDsJ18ebMlrC/2pgVItJwZPt4bRc4G/rJvmM
# 1bL5OBDm6s6R9b7T+2+TYTRcvJNFKIM2KmYoX7BzzosmJQayg9Rc9hUZTO1i4F4z
# 8ujo7AqnsAMrkbI2eb73rQgedaZlzLvjSFDzd5Ea/ttQokbIYViY9XwCFjyDKK05
# huzUtw1T0PhH5nUwjewwk3YUpltLXXRhTT8SkXbev1jLchApQfDVxW0mdmgRQRNY
# mtwmKwH0iU1Z23jPgUo+QEdfyYFQc4UQIyFZYIpkVMHMIRroOBl8ZhzNeDhFMJlP
# /2NPTLuqDQhTQXxYPUez+rbsjDIJAsxsPAxWEQIDAQABo4IBWTCCAVUwEgYDVR0T
# AQH/BAgwBgEB/wIBADAdBgNVHQ4EFgQUaDfg67Y7+F8Rhvv+YXsIiGX0TkIwHwYD
# VR0jBBgwFoAU7NfjgtJxXWRM3y5nP+e6mK4cD08wDgYDVR0PAQH/BAQDAgGGMBMG
# A1UdJQQMMAoGCCsGAQUFBwMDMHcGCCsGAQUFBwEBBGswaTAkBggrBgEFBQcwAYYY
# aHR0cDovL29jc3AuZGlnaWNlcnQuY29tMEEGCCsGAQUFBzAChjVodHRwOi8vY2Fj
# ZXJ0cy5kaWdpY2VydC5jb20vRGlnaUNlcnRUcnVzdGVkUm9vdEc0LmNydDBDBgNV
# HR8EPDA6MDigNqA0hjJodHRwOi8vY3JsMy5kaWdpY2VydC5jb20vRGlnaUNlcnRU
# cnVzdGVkUm9vdEc0LmNybDAcBgNVHSAEFTATMAcGBWeBDAEDMAgGBmeBDAEEATAN
# BgkqhkiG9w0BAQwFAAOCAgEAOiNEPY0Idu6PvDqZ01bgAhql+Eg08yy25nRm95Ry
# sQDKr2wwJxMSnpBEn0v9nqN8JtU3vDpdSG2V1T9J9Ce7FoFFUP2cvbaF4HZ+N3HL
# IvdaqpDP9ZNq4+sg0dVQeYiaiorBtr2hSBh+3NiAGhEZGM1hmYFW9snjdufE5Btf
# Q/g+lP92OT2e1JnPSt0o618moZVYSNUa/tcnP/2Q0XaG3RywYFzzDaju4ImhvTnh
# OE7abrs2nfvlIVNaw8rpavGiPttDuDPITzgUkpn13c5UbdldAhQfQDN8A+KVssIh
# dXNSy0bYxDQcoqVLjc1vdjcshT8azibpGL6QB7BDf5WIIIJw8MzK7/0pNVwfiThV
# 9zeKiwmhywvpMRr/LhlcOXHhvpynCgbWJme3kuZOX956rEnPLqR0kq3bPKSchh/j
# wVYbKyP/j7XqiHtwa+aguv06P0WmxOgWkVKLQcBIhEuWTatEQOON8BUozu3xGFYH
# Ki8QxAwIZDwzj64ojDzLj4gLDb879M4ee47vtevLt/B3E+bnKD+sEq6lLyJsQfmC
# XBVmzGwOysWGw/YmMwwHS6DTBwJqakAwSEs0qFEgu60bhQjiWQ1tygVQK+pKHJ6l
# /aCnHwZ05/LWUpD9r4VIIflXO7ScA+2GRfS0YW6/aOImYIbqyK+p/pQd52MbOoZW
# eE4wggbfMIIEx6ADAgECAhADOvN90luA0nrA93Kao14iMA0GCSqGSIb3DQEBCwUA
# MGkxCzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5EaWdpQ2VydCwgSW5jLjFBMD8GA1UE
# AxM4RGlnaUNlcnQgVHJ1c3RlZCBHNCBDb2RlIFNpZ25pbmcgUlNBNDA5NiBTSEEz
# ODQgMjAyMSBDQTEwHhcNMjQxMjE5MDAwMDAwWhcNMjYwMTE2MjM1OTU5WjBnMQsw
# CQYDVQQGEwJBVTERMA8GA1UECBMIVmljdG9yaWExFTATBgNVBAcTDE5vdHRpbmcg
# SGlsbDEWMBQGA1UEChMNSVBTZWMgUHR5IEx0ZDEWMBQGA1UEAxMNSVBTZWMgUHR5
# IEx0ZDCCAaIwDQYJKoZIhvcNAQEBBQADggGPADCCAYoCggGBAKAKgpRe3of6uvFi
# CACixkD18+fCx2CROSBlMrWeSwogIGRx2Gm/BEZhUzGLPVAXN33pPlYo95K2aben
# DHHuN6JV/fEjEphS9c3bm+QgP1q96uceh+ytVY0oq3uONcDdYIOR/kdCkH07lPo3
# jPEEkFfyKsNFH+DpaFwLqq8fmzj9euT5JSGRlZi5mC0qquZ0hEVNkFQ3vhV6vW4a
# AQ4YlkgYs4Fl7DHZKSnwwHTYCSjmZzJVaX3GcR2yZv5vrkEWGfP0IcXZAPwnHDjd
# jSWfTSmfMLu0Yh6rWmtm1Hw/2/3CWmkMGv0yYFxevuso3FkuuesnqS/sNxJP29BR
# DauxouAVbp8ipOg1oaQvpkWsFMzb36DCdKHWWSmIbCp5niUwMiLsg/8mYYRf+T1I
# JsAPZYXY5taIQssBBmlUJgiIxACEw52mc6fjy+35wK69X12OTnYRfZQ2ORa/JUIX
# SZ2VkQZ4qDLzJyZWWUwXipPyLHhXMJw7oxnNU4ocFwcxL9/SQwIDAQABo4ICAzCC
# Af8wHwYDVR0jBBgwFoAUaDfg67Y7+F8Rhvv+YXsIiGX0TkIwHQYDVR0OBBYEFBT8
# Z08ugGGhp3FyFX/0iw9X9KENMD4GA1UdIAQ3MDUwMwYGZ4EMAQQBMCkwJwYIKwYB
# BQUHAgEWG2h0dHA6Ly93d3cuZGlnaWNlcnQuY29tL0NQUzAOBgNVHQ8BAf8EBAMC
# B4AwEwYDVR0lBAwwCgYIKwYBBQUHAwMwgbUGA1UdHwSBrTCBqjBToFGgT4ZNaHR0
# cDovL2NybDMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0VHJ1c3RlZEc0Q29kZVNpZ25p
# bmdSU0E0MDk2U0hBMzg0MjAyMUNBMS5jcmwwU6BRoE+GTWh0dHA6Ly9jcmw0LmRp
# Z2ljZXJ0LmNvbS9EaWdpQ2VydFRydXN0ZWRHNENvZGVTaWduaW5nUlNBNDA5NlNI
# QTM4NDIwMjFDQTEuY3JsMIGUBggrBgEFBQcBAQSBhzCBhDAkBggrBgEFBQcwAYYY
# aHR0cDovL29jc3AuZGlnaWNlcnQuY29tMFwGCCsGAQUFBzAChlBodHRwOi8vY2Fj
# ZXJ0cy5kaWdpY2VydC5jb20vRGlnaUNlcnRUcnVzdGVkRzRDb2RlU2lnbmluZ1JT
# QTQwOTZTSEEzODQyMDIxQ0ExLmNydDAJBgNVHRMEAjAAMA0GCSqGSIb3DQEBCwUA
# A4ICAQC6aprHmEJvSXJ+yM3xzoN1W8to3bZBh2MtR6+UIuXC/q9lxCrW6ZlJTmRc
# wodjaP6aX4r4oaWwbe7DuYkCSDylP995O+WA46Tu3KqmGBrPQQWzlfLx0Uv3dMvN
# Da2I314DtOwK4Ynrl2MBgfJdxns8YK1fdk2vfVm5dMG63GSzh+Prgwt20K4AyI4C
# GCljQy61sud7pVcNlJs0jjDq7yRT4IOu9jFazx7nqrhBbyllcx/qog5w+u2W58tx
# Se/SVHbTcizoXxyluCCPfspQ+EYTVCC5BTSHpF7iRxHmthmUEamUI4/vh7cwmQG6
# Rtq0wNNYnLq29JpcvrxV4GDmtZGb2Iok0+/YZUoTuTp5zk3RZ034FAszBbTQ+vbn
# 87xa+Pckkx5PZYJsx8KCSZ1TJtPZSegy7pMMWYNfcHd5s9NNt/aOFdCqjuVSKJGH
# zaIY09oS0ClUUCHNQaVQJAF0daLWwo3WmOywaziXTmYR+5rSfNl9aGzzrW+ardL8
# IIzLURVE/VHJ+NHCdB+kiuWaE0ivHKjBxIvpKUNeoQTeSTzZ/aRbhAx1hDANa4MB
# Z1jdB4/jWsGbVE8aY4WSdmw3BOEGhm2mc3S6QVdMF8Be98V+JEqJXmg1nD9ySok4
# 55d3duhIe3KsYB/lJx9uLzn+e0bwXHDu63AAMi6pkLB1x3/hSDGCGkowghpGAgEB
# MH0waTELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDkRpZ2lDZXJ0LCBJbmMuMUEwPwYD
# VQQDEzhEaWdpQ2VydCBUcnVzdGVkIEc0IENvZGUgU2lnbmluZyBSU0E0MDk2IFNI
# QTM4NCAyMDIxIENBMQIQAzrzfdJbgNJ6wPdymqNeIjANBglghkgBZQMEAgEFAKCB
# hDAYBgorBgEEAYI3AgEMMQowCKACgAChAoAAMBkGCSqGSIb3DQEJAzEMBgorBgEE
# AYI3AgEEMBwGCisGAQQBgjcCAQsxDjAMBgorBgEEAYI3AgEVMC8GCSqGSIb3DQEJ
# BDEiBCBbtICxFqGQtWaafMwD+fE/O2/mWBqwGc9gaCgDGrLOhTANBgkqhkiG9w0B
# AQEFAASCAYBGIiIRZTsEqcwWSAJX0PQS3GANe9GtVfHzxTVcAcytQ6pGGDG1dzh7
# btTUk34mv71fn7Y1sHLQ6w6fQbNTe7xuvZdLU1GE0YI5N+PodchhsheHIVFD7FCT
# w8XH/kNrAq0zoHe9uT2slgKxQN+9FCInlxtggALCIWsXV0b/Q1DZK/LyQtY/oaG1
# RdoTMWQyCMGJnwheDJ1sNTbXv/VK7omLLXS/7y312+5SHnHXpwebKLkBXc3/xfML
# ziLKAOlpdUngDrMiABv0rXbmu6IlJ5oYw/5dLX4ryUyLJjve64o/NjjOkPwN06d8
# 4fao3r6cXICKUXDDM7Yhkr9wRwtdF4RhDyxzbsCXSCgIvE6KptbR1EQYq2NC4ma7
# iIMTU1bUmtdOCkrBqY//LPBfEtMvXqPqJkoF+D5C7HbvfRHPwTnSb4x7bUSVgIWG
# tpXEngh6rDzgAhQA6ojNNQ7D+3ICNdPe88ybyM6COlXT7IDY9wUqyfzIpe0QpfKw
# t+PGoyRTSVqhgheXMIIXkwYKKwYBBAGCNwMDATGCF4Mwghd/BgkqhkiG9w0BBwKg
# ghdwMIIXbAIBAzEPMA0GCWCGSAFlAwQCAgUAMIGHBgsqhkiG9w0BCRABBKB4BHYw
# dAIBAQYJYIZIAYb9bAcBMEEwDQYJYIZIAWUDBAICBQAEMBDaS3AYVlzUB5dmIQ2x
# CfgAnyPqnD53ALIT5l4an5iB2fHptf9uZo1EzuCxWhiyhwIQRuOS3W/vqtnM7mfb
# j6f90RgPMjAyNTA3MjkwNTE3MjFaoIITOjCCBu0wggTVoAMCAQICEAwgQ0n50PdZ
# +5gt5AgbiHswDQYJKoZIhvcNAQEMBQAwaTELMAkGA1UEBhMCVVMxFzAVBgNVBAoT
# DkRpZ2lDZXJ0LCBJbmMuMUEwPwYDVQQDEzhEaWdpQ2VydCBUcnVzdGVkIEc0IFRp
# bWVTdGFtcGluZyBSU0E0MDk2IFNIQTI1NiAyMDI1IENBMTAeFw0yNTA2MDQwMDAw
# MDBaFw0zNjA5MDMyMzU5NTlaMGMxCzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5EaWdp
# Q2VydCwgSW5jLjE7MDkGA1UEAxMyRGlnaUNlcnQgU0hBMzg0IFJTQTQwOTYgVGlt
# ZXN0YW1wIFJlc3BvbmRlciAyMDI1IDEwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAw
# ggIKAoICAQDbOVL7i3S35ckNUdj680nGm/v3iwzc7hRDJyYpFeZguz5hF/O3KXxA
# nuf9SrE1MpaaN0UNYa/jf5raiInjXLE57SwugXHwXVrPYlFNlzt2EDFud75vJ3lt
# /ZIRmUKu4bHFZKpulRjp0AZEILIE5qIVqheGSf4vXl59yiYNKtOcDlWB32m8w77t
# sz61JbgnMCIhs7aYg/IIR0pixyY+X5gG56dI/s0nD2JwvW1amfrW4zpbJQ2/hFzI
# EDP428ls1/mRMzsXjpy8HCnSVliKxlH3znLmxiPh7jJQFs8HHKtPlo0xn77m2Kzw
# YOYcKmrJUtDh4sfCmKbmLBHj1NER8RO2UQU5FZOQnaE47XPNUBazqO116nXZW0Vm
# hA6EjB1R88dKwDDf3EVV68UQV/a74NWvWw5XskAJj7FwbyFYh6o8ZVTCSLIFFROA
# Dsd4DElvSJCXgYMELpkEDjAY39qEzEXh+4mw6zXPCQ8FKdeYeSbXwfAeAg8qTbzt
# 0whyFnKObvMZwJhnhuKyhRhYv2hOBr0kJ8UxNz3KXbpcMHTOX2t1LC+I6ZphKVpF
# qcXzijEBieqAHLpnz3KQ+BadvtJGLfU3I/fn1aGiT7fp+TLFM+NKsJa8wrunNtGD
# y18hGVSfGXsblsiuQ+oxsP3MmgHv0wcWAuvmWNTuutwvDL5wR+nMUwIDAQABo4IB
# lTCCAZEwDAYDVR0TAQH/BAIwADAdBgNVHQ4EFgQUVZ6552fIkRBJtDZSjXm3JMU/
# LfgwHwYDVR0jBBgwFoAU729TSunkBnx6yuKQVvYv1Ensy04wDgYDVR0PAQH/BAQD
# AgeAMBYGA1UdJQEB/wQMMAoGCCsGAQUFBwMIMIGVBggrBgEFBQcBAQSBiDCBhTAk
# BggrBgEFBQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQuY29tMF0GCCsGAQUFBzAC
# hlFodHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vRGlnaUNlcnRUcnVzdGVkRzRU
# aW1lU3RhbXBpbmdSU0E0MDk2U0hBMjU2MjAyNUNBMS5jcnQwXwYDVR0fBFgwVjBU
# oFKgUIZOaHR0cDovL2NybDMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0VHJ1c3RlZEc0
# VGltZVN0YW1waW5nUlNBNDA5NlNIQTI1NjIwMjVDQTEuY3JsMCAGA1UdIAQZMBcw
# CAYGZ4EMAQQCMAsGCWCGSAGG/WwHATANBgkqhkiG9w0BAQwFAAOCAgEAG34LJIfY
# CWrFQedRadkkjuul0CqjQ9yKTJXjwu2TlBYWDGkc/1a2NHeWyQQA6TdOzOa43IyJ
# 3tW7EeVAmXgpx1OvlxDZgvL6XnrSl4GAzuQDgcImoap1B3ONfKuWDdgJ1+eOz3D/
# sE7zFSaUBqr8P49Nlk74yfFrf8ijJiwX4v2BZfhUnFkuWNWzkkqalKiefKwxi/sJ
# qqRCkEOYlZTYXryYstld9TTBdsPL1BBOySBwe+LJAN4HWXqOX9bA5CJI1M1p9hBR
# HZmwnms8m7U0/M7WG0rB2JSNZ6cfCrkFErUFHv4P5PAb3tQdfhXRb4m8VmnzPd3c
# bmwDs+32o7n/oBZn7TJ/yc3nwP4cABKEeafLbm3pbuoXpVJFkIikavyFsCN9sGE7
# gxjwbZT3PBUqnpKWO4qSfF3Zu6KE7fd2KgIawHq2tf77FAp/hCVhKCAW8P1lZIbj
# Kwk9g7H6FuwFMQ40W2v33Ho6AmefJWQOi50if6CZX4Gr5rYb74EtTkBc5VyUTGm6
# hRBdRkXmnexSt3bVCMX1FrTHhEPTaBLhfCDM362+5j62OE8gLBeYfcREv588ijFl
# PReDBU/7XtSpRuLlml7hh1p0blaMJMG+2aUzglWi8ZhG/IDJ+ZgknHT/RP6orTnB
# EmmDirzW84q4JA9oT0f30kJW98IMGbgqOsQwgga0MIIEnKADAgECAhANx6xXBf8h
# mS5AQyIMOkmGMA0GCSqGSIb3DQEBCwUAMGIxCzAJBgNVBAYTAlVTMRUwEwYDVQQK
# EwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xITAfBgNV
# BAMTGERpZ2lDZXJ0IFRydXN0ZWQgUm9vdCBHNDAeFw0yNTA1MDcwMDAwMDBaFw0z
# ODAxMTQyMzU5NTlaMGkxCzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5EaWdpQ2VydCwg
# SW5jLjFBMD8GA1UEAxM4RGlnaUNlcnQgVHJ1c3RlZCBHNCBUaW1lU3RhbXBpbmcg
# UlNBNDA5NiBTSEEyNTYgMjAyNSBDQTEwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAw
# ggIKAoICAQC0eDHTCphBcr48RsAcrHXbo0ZodLRRF51NrY0NlLWZloMsVO1DahGP
# NRcybEKq+RuwOnPhof6pvF4uGjwjqNjfEvUi6wuim5bap+0lgloM2zX4kftn5B1I
# pYzTqpyFQ/4Bt0mAxAHeHYNnQxqXmRinvuNgxVBdJkf77S2uPoCj7GH8BLuxBG5A
# vftBdsOECS1UkxBvMgEdgkFiDNYiOTx4OtiFcMSkqTtF2hfQz3zQSku2Ws3IfDRe
# b6e3mmdglTcaarps0wjUjsZvkgFkriK9tUKJm/s80FiocSk1VYLZlDwFt+cVFBUR
# Jg6zMUjZa/zbCclF83bRVFLeGkuAhHiGPMvSGmhgaTzVyhYn4p0+8y9oHRaQT/ao
# fEnS5xLrfxnGpTXiUOeSLsJygoLPp66bkDX1ZlAeSpQl92QOMeRxykvq6gbylsXQ
# skBBBnGy3tW/AMOMCZIVNSaz7BX8VtYGqLt9MmeOreGPRdtBx3yGOP+rx3rKWDEJ
# lIqLXvJWnY0v5ydPpOjL6s36czwzsucuoKs7Yk/ehb//Wx+5kMqIMRvUBDx6z1ev
# +7psNOdgJMoiwOrUG2ZdSoQbU2rMkpLiQ6bGRinZbI4OLu9BMIFm1UUl9VnePs6B
# aaeEWvjJSjNm2qA+sdFUeEY0qVjPKOWug/G6X5uAiynM7Bu2ayBjUwIDAQABo4IB
# XTCCAVkwEgYDVR0TAQH/BAgwBgEB/wIBADAdBgNVHQ4EFgQU729TSunkBnx6yuKQ
# VvYv1Ensy04wHwYDVR0jBBgwFoAU7NfjgtJxXWRM3y5nP+e6mK4cD08wDgYDVR0P
# AQH/BAQDAgGGMBMGA1UdJQQMMAoGCCsGAQUFBwMIMHcGCCsGAQUFBwEBBGswaTAk
# BggrBgEFBQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQuY29tMEEGCCsGAQUFBzAC
# hjVodHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vRGlnaUNlcnRUcnVzdGVkUm9v
# dEc0LmNydDBDBgNVHR8EPDA6MDigNqA0hjJodHRwOi8vY3JsMy5kaWdpY2VydC5j
# b20vRGlnaUNlcnRUcnVzdGVkUm9vdEc0LmNybDAgBgNVHSAEGTAXMAgGBmeBDAEE
# AjALBglghkgBhv1sBwEwDQYJKoZIhvcNAQELBQADggIBABfO+xaAHP4HPRF2cTC9
# vgvItTSmf83Qh8WIGjB/T8ObXAZz8OjuhUxjaaFdleMM0lBryPTQM2qEJPe36zwb
# SI/mS83afsl3YTj+IQhQE7jU/kXjjytJgnn0hvrV6hqWGd3rLAUt6vJy9lMDPjTL
# xLgXf9r5nWMQwr8Myb9rEVKChHyfpzee5kH0F8HABBgr0UdqirZ7bowe9Vj2AIMD
# 8liyrukZ2iA/wdG2th9y1IsA0QF8dTXqvcnTmpfeQh35k5zOCPmSNq1UH410ANVk
# o43+Cdmu4y81hjajV/gxdEkMx1NKU4uHQcKfZxAvBAKqMVuqte69M9J6A47OvgRa
# Ps+2ykgcGV00TYr2Lr3ty9qIijanrUR3anzEwlvzZiiyfTPjLbnFRsjsYg39OlV8
# cipDoq7+qNNjqFzeGxcytL5TTLL4ZaoBdqbhOhZ3ZRDUphPvSRmMThi0vw9vODRz
# W6AxnJll38F0cuJG7uEBYTptMSbhdhGQDpOXgpIUsWTjd6xpR6oaQf/DJbg3s6KC
# LPAlZ66RzIg9sC+NJpud/v4+7RWsWCiKi9EOLLHfMR2ZyJ/+xhCx9yHbxtl5TPau
# 1j/1MIDpMPx0LckTetiSuEtQvLsNz3Qbp7wGWqbIiOWCnb5WqxL3/BAPvIXKUjPS
# xyZsq8WhbaM2tszWkPZPubdcMIIFjTCCBHWgAwIBAgIQDpsYjvnQLefv21DiCEAY
# WjANBgkqhkiG9w0BAQwFADBlMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNl
# cnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdp
# Q2VydCBBc3N1cmVkIElEIFJvb3QgQ0EwHhcNMjIwODAxMDAwMDAwWhcNMzExMTA5
# MjM1OTU5WjBiMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkw
# FwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSEwHwYDVQQDExhEaWdpQ2VydCBUcnVz
# dGVkIFJvb3QgRzQwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC/5pBz
# aN675F1KPDAiMGkz7MKnJS7JIT3yithZwuEppz1Yq3aaza57G4QNxDAf8xukOBbr
# VsaXbR2rsnnyyhHS5F/WBTxSD1Ifxp4VpX6+n6lXFllVcq9ok3DCsrp1mWpzMpTR
# EEQQLt+C8weE5nQ7bXHiLQwb7iDVySAdYyktzuxeTsiT+CFhmzTrBcZe7FsavOvJ
# z82sNEBfsXpm7nfISKhmV1efVFiODCu3T6cw2Vbuyntd463JT17lNecxy9qTXtyO
# j4DatpGYQJB5w3jHtrHEtWoYOAMQjdjUN6QuBX2I9YI+EJFwq1WCQTLX2wRzKm6R
# AXwhTNS8rhsDdV14Ztk6MUSaM0C/CNdaSaTC5qmgZ92kJ7yhTzm1EVgX9yRcRo9k
# 98FpiHaYdj1ZXUJ2h4mXaXpI8OCiEhtmmnTK3kse5w5jrubU75KSOp493ADkRSWJ
# tppEGSt+wJS00mFt6zPZxd9LBADMfRyVw4/3IbKyEbe7f/LVjHAsQWCqsWMYRJUa
# dmJ+9oCw++hkpjPRiQfhvbfmQ6QYuKZ3AeEPlAwhHbJUKSWJbOUOUlFHdL4mrLZB
# dd56rF+NP8m800ERElvlEFDrMcXKchYiCd98THU/Y+whX8QgUWtvsauGi0/C1kVf
# nSD8oR7FwI+isX4KJpn15GkvmB0t9dmpsh3lGwIDAQABo4IBOjCCATYwDwYDVR0T
# AQH/BAUwAwEB/zAdBgNVHQ4EFgQU7NfjgtJxXWRM3y5nP+e6mK4cD08wHwYDVR0j
# BBgwFoAUReuir/SSy4IxLVGLp6chnfNtyA8wDgYDVR0PAQH/BAQDAgGGMHkGCCsG
# AQUFBwEBBG0wazAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQuY29t
# MEMGCCsGAQUFBzAChjdodHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vRGlnaUNl
# cnRBc3N1cmVkSURSb290Q0EuY3J0MEUGA1UdHwQ+MDwwOqA4oDaGNGh0dHA6Ly9j
# cmwzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJRFJvb3RDQS5jcmwwEQYD
# VR0gBAowCDAGBgRVHSAAMA0GCSqGSIb3DQEBDAUAA4IBAQBwoL9DXFXnOF+go3Qb
# PbYW1/e/Vwe9mqyhhyzshV6pGrsi+IcaaVQi7aSId229GhT0E0p6Ly23OO/0/4C5
# +KH38nLeJLxSA8hO0Cre+i1Wz/n096wwepqLsl7Uz9FDRJtDIeuWcqFItJnLnU+n
# BgMTdydE1Od/6Fmo8L8vC6bp8jQ87PcDx4eo0kxAGTVGamlUsLihVo7spNU96LHc
# /RzY9HdaXFSMb++hUD38dglohJ9vytsgjTVgHAIDyyCwrFigDkBjxZgiwbJZ9VVr
# zyerbHbObyMt9H5xaiNrIv8SuFQtJ37YOtnwtoeW/VvRXKwYw02fc7cBqZ9Xql4o
# 4rmUMYIDjDCCA4gCAQEwfTBpMQswCQYDVQQGEwJVUzEXMBUGA1UEChMORGlnaUNl
# cnQsIEluYy4xQTA/BgNVBAMTOERpZ2lDZXJ0IFRydXN0ZWQgRzQgVGltZVN0YW1w
# aW5nIFJTQTQwOTYgU0hBMjU2IDIwMjUgQ0ExAhAMIENJ+dD3WfuYLeQIG4h7MA0G
# CWCGSAFlAwQCAgUAoIHhMBoGCSqGSIb3DQEJAzENBgsqhkiG9w0BCRABBDAcBgkq
# hkiG9w0BCQUxDxcNMjUwNzI5MDUxNzIxWjArBgsqhkiG9w0BCRACDDEcMBowGDAW
# BBRyvP2gEH9JNLAHHGEP5teWUACYdzA3BgsqhkiG9w0BCRACLzEoMCYwJDAiBCAy
# 8+OxvaLXsm1PHRuM3b2Pi4R2oXie1hLNPKp6nv81wjA/BgkqhkiG9w0BCQQxMgQw
# VHW6QkizFOJPFb6hnJ+JD3FUmzcTuhii41KHjeCpeIn7BtmsseBdhhJoQQFUY0CP
# MA0GCSqGSIb3DQEBAQUABIICAKEaEuWOu7ajk6KNX0yXe/t1NJMhmOjtORNfCcyL
# pHV/Ob2Asg3U2E885gLZPF0TdCbOW1w+cmh/dDATNhUC1gtkWTqooRvccw8wDZxB
# BtZq4LGwbKx1kSYlRc41tD1j70ehfy+lKkPCR3ljZtJagwPJMkhrPUMWialfYAnO
# zhQ0XXYH3GfKd1rbPu7GX80St0+Og82HzTEYcca6nx1x7Wo2YHwp4DSvRcYnUyR/
# GvFdI5+eDsmrTQ3lUEjNix59K0RsGOHReGNKKthe1Y1Gfvg9/v9eOERvjwhM2nOw
# 7IQQcU680ISPhkAz4Ot24b+nYwXE9tUID35VGPpI9tcouVpndD2nUSsocxhI+F6J
# /QHzTA4JjwThZlxpZ8AYLfPox4OXP98QnuDQWeI1FRlnSHhYmCZwcRnZVDq1wFqI
# /KbbL99WzM66hHeBTpAL+sqeQHkJpqDV0QYFi/IxsH12e3nTT+a/cH8hkH+ARV2c
# +CMWIWFcMuweYkrT1YLDpwDHzvyP6AqSHkrRaPTMJD3pQjguy3FUR/SLabDPfQeH
# Dy/Y6p9KG1E3zCzZ5CKV4rUluFvQSheGPXfFK+iWqihg6TSD0cD5B+yCIXasRqSf
# IjvInSPFUP+2/DvxczohHkNQZ5nKfNmXaz1UJutqw5/WmQEL4r6P3Vpmgh+ev0lN
# s+pm
# SIG # End signature block