Functions_v5/Get-XurrentData.ps1

function Get-XurrentData
{
<#
.SYNOPSIS
    Retrieves records from the Xurrent REST API.
 
.DESCRIPTION
    Universal retrieval function for all Xurrent data types. Supports three modes:
 
    - param (default): List query with optional filter parameters. Supports
      automatic paging across all pages.
    - id: Retrieves one or more records by their ID. With -Full, the complete
      detail data is loaded (including custom fields).
    - export: Data is loaded via the asynchronous Xurrent export mechanism
      (CSV file). Requires PowerShell 7.2+.
 
.PARAMETER Environment
    The Xurrent connection name. Mandatory in all parameter sets.
 
.PARAMETER Type
    The data type to retrieve (XurrentDataTypes enum, e.g. 'requests', 'tasks'). Mandatory.
 
.PARAMETER ID
    One or more IDs for targeted retrieval. Mandatory in parameter set 'id'.
 
.PARAMETER SubType
    Sub-resource of an object (e.g. 'notes', 'approvals'). Optional in parameter set 'id'.
 
.PARAMETER Parameter
    URL query parameters as a string (e.g. 'status=assigned&fields=id,subject').
    Optional in parameter sets 'id' and 'param'.
 
.PARAMETER Full
    Loads the complete detail data for each found record via a separate API call.
    Optional in parameter sets 'id' and 'param'.
 
.PARAMETER ConvertCustomFields
    Automatically converts custom fields into a PSCustomObject (via ConvertFrom-XurrentCustomFields).
    Only effective when -Full is set. Default: $true.
 
.PARAMETER Export
    Uses the asynchronous CSV export mechanism. Requires PowerShell 7.2+.
    Mandatory in parameter set 'export'.
 
.PARAMETER ConvertCustomFieldJson
    In export mode: automatically converts the JSON string in the 'Custom Fields' column.
    Default: $true.
 
.OUTPUTS
    Array of PSCustomObjects or a single PSCustomObject.
 
.EXAMPLE
    Get-XurrentData -Environment $env -Type requests -Parameter 'status=assigned'
 
    All assigned requests (with automatic paging).
 
.EXAMPLE
    Get-XurrentData -Environment $env -Type requests -ID 123456, 789012 -Full
 
    Full records for two requests including custom fields.
 
.EXAMPLE
    Get-XurrentData -Environment $env -Type tasks -ID 55 -SubType notes
 
    All notes of task 55.
 
.EXAMPLE
    Get-XurrentData -Environment $env -Type people -Export
 
    All people via CSV export (faster for large datasets).
 
.NOTES
    Alias: Get-4meData
#>

    [CmdletBinding(DefaultParameterSetName = 'param')]
    param (
        [Parameter(Mandatory = $true, ParameterSetName = 'id')]
        [Parameter(Mandatory = $true, ParameterSetName = 'param')]
        [Parameter(Mandatory = $true, ParameterSetName = 'export')]
        [ValidateScript({ $null -ne $script:XurrentAuth.$_ })]
        [string]$Environment,
        [Parameter(Mandatory = $true, ParameterSetName = 'id')]
        [Parameter(Mandatory = $true, ParameterSetName = 'param')]
        [Parameter(Mandatory = $true, ParameterSetName = 'export')]
        [XurrentDataTypes]$Type,
        [Parameter(Mandatory = $false, ParameterSetName = 'id')]
        [string]$SubType,
        [Parameter(Mandatory = $false, ParameterSetName = 'id')]
        [Parameter(Mandatory = $false, ParameterSetName = 'param')]
        [switch]$Full = $false,
        [Parameter(Mandatory = $false, ParameterSetName = 'id')]
        [Parameter(Mandatory = $false, ParameterSetName = 'param')]
        [string]$Parameter,
        [Parameter(Mandatory = $true, ParameterSetName = 'id')]
        [int[]]$ID,
        [Parameter(Mandatory = $false, ParameterSetName = 'id')]
        [Parameter(Mandatory = $false, ParameterSetName = 'param')]
        [ValidateScript({ $PSBoundParameters.full -eq $true })]
        [switch]$ConvertCustomFields = $true,
        [Parameter(Mandatory = $false, ParameterSetName = 'export')]
        [switch]$ConvertCustomFieldJson = $true,
        [Parameter(Mandatory = $true, ParameterSetName = 'export')]
        [ValidateScript({ $PSVersionTable.PSVersion -ge $Script:MinimalV7Version})]
        [switch]$Export
    )
    $url = "$($script:XurrentAuth.$Environment.URL)/$($Type)"
    $InitialURL = $null
    if ($PSCmdlet.ParameterSetName -eq 'id')
    {
        $data = @()
        foreach ($item in $ID) { $data += @{ id = $item } }
    }
    elseif ($PSCmdlet.ParameterSetName -eq 'export')
    {
        $data = @()
        Write-Verbose -Message "get data from export"
        foreach ($tmp in (Import-Csv -Path (Export-XurrentData -Environment $Environment -Type $Type)))
        {
            if ($ConvertCustomFieldJson -and $null -ne $tmp.'Custom Fields')
            {
                Write-Verbose -Message "convert custom fields"
                ConvertFrom-XurrentCustomFields -Object $tmp -DataFromExport
            }
            $data += $tmp
        }
        return $data
    }
    else
    {
        if (-not [string]::IsNullOrEmpty($Parameter))
        {
            $InitialURL = $url + "?" + $Parameter
        }
        else
        {
            $InitialURL = $url
        }
        Write-Verbose -Message "get data from $($InitialURL)"
        $tempdata = Invoke-WebRequest -Method get -Uri $InitialURL -Headers $script:XurrentAuth.$Environment.header -UseBasicParsing -Verbose:$false
        
        if ($tempdata.Headers."X-Pagination-Total-Pages" -gt 1)
        {
            $data = @()
            Write-Verbose -Message "total pages: $($tempdata.Headers."X-Pagination-Total-Pages")"
            $data += $tempdata.Content | ConvertFrom-Json
            while ($tempdata.Headers.'X-Pagination-Current-Page' -ne $tempdata.Headers."X-Pagination-Total-Pages")
            {
                $nextURL = ($tempdata.Headers.link.Split(",") | Where-Object { $_ -match 'next' }).Split(";")[0].trim("<> ")
                $tempdata = Invoke-WebRequest -Method get -Uri $nextURL -Headers $script:XurrentAuth.$Environment.header -UseBasicParsing -Verbose:$false
                $data += $tempdata.Content | ConvertFrom-Json
            }
        }
        elseif ($null -ne $tempdata)
        {
            $data = $tempdata.Content | ConvertFrom-Json
        }
        if ($Full -eq $false)
        {
            return $data
        }
    }
    Write-Verbose -Message "get full data"
    $FullData = @()
    foreach ($id in $data.id)
    {
        $tmpURL = $url + "/" + $id
        if (-not [string]::IsNullOrEmpty($SubType))
        {
            $tmpURL = $tmpURL + "/" + $SubType
        }
        if (-not [string]::IsNullOrEmpty($Parameter))
        {
            $tmpURL = $tmpURL + "?" + $Parameter
        }
        Write-Verbose "get data from $($tmpURL)"
        $tmp = Invoke-RestMethod -Method get -Uri $tmpURL -Headers $script:XurrentAuth.$Environment.header -Verbose:$false
        Write-Verbose "$($tmp.custom_fields.count)"
        if ($ConvertCustomFields -and $null -ne $tmp.custom_fields -and [string]::IsNullOrEmpty($SubType))
        {
            Write-Verbose -Message "convert custom fields"
            ConvertFrom-XurrentCustomFields -Object $tmp
        }
        $FullData += $tmp
    }
    return $FullData
}
# SIG # Begin signature block
# MIIcBQYJKoZIhvcNAQcCoIIb9jCCG/ICAQExDzANBglghkgBZQMEAgEFADB5Bgor
# BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG
# KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCD28yUm5uQbq0Qe
# akYCCoJZ/1JKcQcYJkQNeLmhxTZGpKCCFlcwggMZMIICAaADAgECAhBTsDLlq7ih
# jUMiaCh1sMC2MA0GCSqGSIb3DQEBBQUAMBQxEjAQBgNVBAMMCVJvbWFuIEVuejAe
# Fw0yNjA3MjgxOTE4MjRaFw0yNzA3MjgxOTM4MjRaMBQxEjAQBgNVBAMMCVJvbWFu
# IEVuejCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAO4pOygmDC1kxUIZ
# /O1Oe/BvnKjnfvzmQrvVKcWt74bijqJn3yFr6ZNEg/M95vDmEWIEoMg4bHiLkwVX
# rundAwMDbTo6UOeioucldqhx8Fj6viN9Z5W/PoKowb7nIFMixFCFEyQ0eh9bOEZO
# /PMUYzxwd+3fADG83Q6tQyjnOPOs0aNpL0o/f4/MEcmIkzdMd2i/jIzxxpBqZtGW
# PIPkqtzhQWJ395Re8Lxvxs9olR3hVShKjAlFcM4uig3YmHeC4Jmlsz95QCvWb1XU
# Dg9D1dthHTy3lzU8cY7wsuYaaQ7b59Kne7nme8YWAO7Ln5AXuGr5SKJbE1vJcE7+
# sk/GN30CAwEAAaNnMGUwDgYDVR0PAQH/BAQDAgeAMBMGA1UdJQQMMAoGCCsGAQUF
# BwMDMB8GA1UdIwQYMBaAFOwMoMvLXATUqlKKsXyxtAqVvg8XMB0GA1UdDgQWBBSR
# foegWMSQ38KCL4FxM1s+xM2GkzANBgkqhkiG9w0BAQUFAAOCAQEApzbbPh0Dplls
# IxgO5monL2F/YZrfpGa3onb1Jr7J9fiWDJpmbCiILjLQgis3DesvfHMbqdgczOYh
# VUZ+9bBFbuQFp8FviRq1+XM2KPRtDoO5WOHdr1+UexiuCetPR61gh/Gksob6VQgF
# jfyFcPDwzJ+FoO5MGI/7RWV1BHqJy/cLyIAkpaGFjbFR6Jk9PjBuC38atQ54UFkS
# eZf3N4jqJ34nPme1QWpiqx8XVMf21KH32HBUl8BY8V03zUmxCb0Lye6uGRF5JM8y
# HIHQ5myZCZQYsEztsj6d4RJmGJ+dbZLz0ot/mnXiR9ck+sLsDR8oVjqboP73YX1G
# 8yyTvxF88jCCBY0wggR1oAMCAQICEA6bGI750C3n79tQ4ghAGFowDQYJKoZIhvcN
# AQEMBQAwZTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcG
# A1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTEkMCIGA1UEAxMbRGlnaUNlcnQgQXNzdXJl
# ZCBJRCBSb290IENBMB4XDTIyMDgwMTAwMDAwMFoXDTMxMTEwOTIzNTk1OVowYjEL
# MAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3
# LmRpZ2ljZXJ0LmNvbTEhMB8GA1UEAxMYRGlnaUNlcnQgVHJ1c3RlZCBSb290IEc0
# MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAv+aQc2jeu+RdSjwwIjBp
# M+zCpyUuySE98orYWcLhKac9WKt2ms2uexuEDcQwH/MbpDgW61bGl20dq7J58soR
# 0uRf1gU8Ug9SH8aeFaV+vp+pVxZZVXKvaJNwwrK6dZlqczKU0RBEEC7fgvMHhOZ0
# O21x4i0MG+4g1ckgHWMpLc7sXk7Ik/ghYZs06wXGXuxbGrzryc/NrDRAX7F6Zu53
# yEioZldXn1RYjgwrt0+nMNlW7sp7XeOtyU9e5TXnMcvak17cjo+A2raRmECQecN4
# x7axxLVqGDgDEI3Y1DekLgV9iPWCPhCRcKtVgkEy19sEcypukQF8IUzUvK4bA3Vd
# eGbZOjFEmjNAvwjXWkmkwuapoGfdpCe8oU85tRFYF/ckXEaPZPfBaYh2mHY9WV1C
# doeJl2l6SPDgohIbZpp0yt5LHucOY67m1O+SkjqePdwA5EUlibaaRBkrfsCUtNJh
# besz2cXfSwQAzH0clcOP9yGyshG3u3/y1YxwLEFgqrFjGESVGnZifvaAsPvoZKYz
# 0YkH4b235kOkGLimdwHhD5QMIR2yVCkliWzlDlJRR3S+Jqy2QXXeeqxfjT/JvNNB
# ERJb5RBQ6zHFynIWIgnffEx1P2PsIV/EIFFrb7GrhotPwtZFX50g/KEexcCPorF+
# CiaZ9eRpL5gdLfXZqbId5RsCAwEAAaOCATowggE2MA8GA1UdEwEB/wQFMAMBAf8w
# HQYDVR0OBBYEFOzX44LScV1kTN8uZz/nupiuHA9PMB8GA1UdIwQYMBaAFEXroq/0
# ksuCMS1Ri6enIZ3zbcgPMA4GA1UdDwEB/wQEAwIBhjB5BggrBgEFBQcBAQRtMGsw
# JAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBDBggrBgEFBQcw
# AoY3aHR0cDovL2NhY2VydHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElE
# Um9vdENBLmNydDBFBgNVHR8EPjA8MDqgOKA2hjRodHRwOi8vY3JsMy5kaWdpY2Vy
# dC5jb20vRGlnaUNlcnRBc3N1cmVkSURSb290Q0EuY3JsMBEGA1UdIAQKMAgwBgYE
# VR0gADANBgkqhkiG9w0BAQwFAAOCAQEAcKC/Q1xV5zhfoKN0Gz22Ftf3v1cHvZqs
# oYcs7IVeqRq7IviHGmlUIu2kiHdtvRoU9BNKei8ttzjv9P+Aufih9/Jy3iS8UgPI
# TtAq3votVs/59PesMHqai7Je1M/RQ0SbQyHrlnKhSLSZy51PpwYDE3cnRNTnf+hZ
# qPC/Lwum6fI0POz3A8eHqNJMQBk1RmppVLC4oVaO7KTVPeix3P0c2PR3WlxUjG/v
# oVA9/HYJaISfb8rbII01YBwCA8sgsKxYoA5AY8WYIsGyWfVVa88nq2x2zm8jLfR+
# cWojayL/ErhULSd+2DrZ8LaHlv1b0VysGMNNn3O3AamfV6peKOK5lDCCBrQwggSc
# oAMCAQICEA3HrFcF/yGZLkBDIgw6SYYwDQYJKoZIhvcNAQELBQAwYjELMAkGA1UE
# BhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3LmRpZ2lj
# ZXJ0LmNvbTEhMB8GA1UEAxMYRGlnaUNlcnQgVHJ1c3RlZCBSb290IEc0MB4XDTI1
# MDUwNzAwMDAwMFoXDTM4MDExNDIzNTk1OVowaTELMAkGA1UEBhMCVVMxFzAVBgNV
# BAoTDkRpZ2lDZXJ0LCBJbmMuMUEwPwYDVQQDEzhEaWdpQ2VydCBUcnVzdGVkIEc0
# IFRpbWVTdGFtcGluZyBSU0E0MDk2IFNIQTI1NiAyMDI1IENBMTCCAiIwDQYJKoZI
# hvcNAQEBBQADggIPADCCAgoCggIBALR4MdMKmEFyvjxGwBysddujRmh0tFEXnU2t
# jQ2UtZmWgyxU7UNqEY81FzJsQqr5G7A6c+Gh/qm8Xi4aPCOo2N8S9SLrC6Kbltqn
# 7SWCWgzbNfiR+2fkHUiljNOqnIVD/gG3SYDEAd4dg2dDGpeZGKe+42DFUF0mR/vt
# La4+gKPsYfwEu7EEbkC9+0F2w4QJLVSTEG8yAR2CQWIM1iI5PHg62IVwxKSpO0Xa
# F9DPfNBKS7Zazch8NF5vp7eaZ2CVNxpqumzTCNSOxm+SAWSuIr21Qomb+zzQWKhx
# KTVVgtmUPAW35xUUFREmDrMxSNlr/NsJyUXzdtFUUt4aS4CEeIY8y9IaaGBpPNXK
# FifinT7zL2gdFpBP9qh8SdLnEut/GcalNeJQ55IuwnKCgs+nrpuQNfVmUB5KlCX3
# ZA4x5HHKS+rqBvKWxdCyQEEGcbLe1b8Aw4wJkhU1JrPsFfxW1gaou30yZ46t4Y9F
# 20HHfIY4/6vHespYMQmUiote8ladjS/nJ0+k6MvqzfpzPDOy5y6gqztiT96Fv/9b
# H7mQyogxG9QEPHrPV6/7umw052AkyiLA6tQbZl1KhBtTasySkuJDpsZGKdlsjg4u
# 70EwgWbVRSX1Wd4+zoFpp4Ra+MlKM2baoD6x0VR4RjSpWM8o5a6D8bpfm4CLKczs
# G7ZrIGNTAgMBAAGjggFdMIIBWTASBgNVHRMBAf8ECDAGAQH/AgEAMB0GA1UdDgQW
# BBTvb1NK6eQGfHrK4pBW9i/USezLTjAfBgNVHSMEGDAWgBTs1+OC0nFdZEzfLmc/
# 57qYrhwPTzAOBgNVHQ8BAf8EBAMCAYYwEwYDVR0lBAwwCgYIKwYBBQUHAwgwdwYI
# KwYBBQUHAQEEazBpMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdpY2VydC5j
# b20wQQYIKwYBBQUHMAKGNWh0dHA6Ly9jYWNlcnRzLmRpZ2ljZXJ0LmNvbS9EaWdp
# Q2VydFRydXN0ZWRSb290RzQuY3J0MEMGA1UdHwQ8MDowOKA2oDSGMmh0dHA6Ly9j
# cmwzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydFRydXN0ZWRSb290RzQuY3JsMCAGA1Ud
# IAQZMBcwCAYGZ4EMAQQCMAsGCWCGSAGG/WwHATANBgkqhkiG9w0BAQsFAAOCAgEA
# F877FoAc/gc9EXZxML2+C8i1NKZ/zdCHxYgaMH9Pw5tcBnPw6O6FTGNpoV2V4wzS
# UGvI9NAzaoQk97frPBtIj+ZLzdp+yXdhOP4hCFATuNT+ReOPK0mCefSG+tXqGpYZ
# 3essBS3q8nL2UwM+NMvEuBd/2vmdYxDCvwzJv2sRUoKEfJ+nN57mQfQXwcAEGCvR
# R2qKtntujB71WPYAgwPyWLKu6RnaID/B0ba2H3LUiwDRAXx1Neq9ydOal95CHfmT
# nM4I+ZI2rVQfjXQA1WSjjf4J2a7jLzWGNqNX+DF0SQzHU0pTi4dBwp9nEC8EAqox
# W6q17r0z0noDjs6+BFo+z7bKSBwZXTRNivYuve3L2oiKNqetRHdqfMTCW/NmKLJ9
# M+MtucVGyOxiDf06VXxyKkOirv6o02OoXN4bFzK0vlNMsvhlqgF2puE6FndlENSm
# E+9JGYxOGLS/D284NHNboDGcmWXfwXRy4kbu4QFhOm0xJuF2EZAOk5eCkhSxZON3
# rGlHqhpB/8MluDezooIs8CVnrpHMiD2wL40mm53+/j7tFaxYKIqL0Q4ssd8xHZnI
# n/7GELH3IdvG2XlM9q7WP/UwgOkw/HQtyRN62JK4S1C8uw3PdBunvAZapsiI5YKd
# vlarEvf8EA+8hcpSM9LHJmyrxaFtoza2zNaQ9k+5t1wwggbtMIIE1aADAgECAhAK
# gO8YS43xBYLRxHanlXRoMA0GCSqGSIb3DQEBCwUAMGkxCzAJBgNVBAYTAlVTMRcw
# FQYDVQQKEw5EaWdpQ2VydCwgSW5jLjFBMD8GA1UEAxM4RGlnaUNlcnQgVHJ1c3Rl
# ZCBHNCBUaW1lU3RhbXBpbmcgUlNBNDA5NiBTSEEyNTYgMjAyNSBDQTEwHhcNMjUw
# NjA0MDAwMDAwWhcNMzYwOTAzMjM1OTU5WjBjMQswCQYDVQQGEwJVUzEXMBUGA1UE
# ChMORGlnaUNlcnQsIEluYy4xOzA5BgNVBAMTMkRpZ2lDZXJ0IFNIQTI1NiBSU0E0
# MDk2IFRpbWVzdGFtcCBSZXNwb25kZXIgMjAyNSAxMIICIjANBgkqhkiG9w0BAQEF
# AAOCAg8AMIICCgKCAgEA0EasLRLGntDqrmBWsytXum9R/4ZwCgHfyjfMGUIwYzKo
# md8U1nH7C8Dr0cVMF3BsfAFI54um8+dnxk36+jx0Tb+k+87H9WPxNyFPJIDZHhAq
# lUPt281mHrBbZHqRK71Em3/hCGC5KyyneqiZ7syvFXJ9A72wzHpkBaMUNg7MOLxI
# 6E9RaUueHTQKWXymOtRwJXcrcTTPPT2V1D/+cFllESviH8YjoPFvZSjKs3SKO1QN
# UdFd2adw44wDcKgH+JRJE5Qg0NP3yiSyi5MxgU6cehGHr7zou1znOM8odbkqoK+l
# J25LCHBSai25CFyD23DZgPfDrJJJK77epTwMP6eKA0kWa3osAe8fcpK40uhktzUd
# /Yk0xUvhDU6lvJukx7jphx40DQt82yepyekl4i0r8OEps/FNO4ahfvAk12hE5FVs
# 9HVVWcO5J4dVmVzix4A77p3awLbr89A90/nWGjXMGn7FQhmSlIUDy9Z2hSgctaep
# ZTd0ILIUbWuhKuAeNIeWrzHKYueMJtItnj2Q+aTyLLKLM0MheP/9w6CtjuuVHJOV
# oIJ/DtpJRE7Ce7vMRHoRon4CWIvuiNN1Lk9Y+xZ66lazs2kKFSTnnkrT3pXWETTJ
# khd76CIDBbTRofOsNyEhzZtCGmnQigpFHti58CSmvEyJcAlDVcKacJ+A9/z7eacC
# AwEAAaOCAZUwggGRMAwGA1UdEwEB/wQCMAAwHQYDVR0OBBYEFOQ7/PIx7f391/OR
# cWMZUEPPYYzoMB8GA1UdIwQYMBaAFO9vU0rp5AZ8esrikFb2L9RJ7MtOMA4GA1Ud
# DwEB/wQEAwIHgDAWBgNVHSUBAf8EDDAKBggrBgEFBQcDCDCBlQYIKwYBBQUHAQEE
# gYgwgYUwJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBdBggr
# BgEFBQcwAoZRaHR0cDovL2NhY2VydHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0VHJ1
# c3RlZEc0VGltZVN0YW1waW5nUlNBNDA5NlNIQTI1NjIwMjVDQTEuY3J0MF8GA1Ud
# HwRYMFYwVKBSoFCGTmh0dHA6Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydFRy
# dXN0ZWRHNFRpbWVTdGFtcGluZ1JTQTQwOTZTSEEyNTYyMDI1Q0ExLmNybDAgBgNV
# HSAEGTAXMAgGBmeBDAEEAjALBglghkgBhv1sBwEwDQYJKoZIhvcNAQELBQADggIB
# AGUqrfEcJwS5rmBB7NEIRJ5jQHIh+OT2Ik/bNYulCrVvhREafBYF0RkP2AGr181o
# 2YWPoSHz9iZEN/FPsLSTwVQWo2H62yGBvg7ouCODwrx6ULj6hYKqdT8wv2UV+Kbz
# /3ImZlJ7YXwBD9R0oU62PtgxOao872bOySCILdBghQ/ZLcdC8cbUUO75ZSpbh1oi
# pOhcUT8lD8QAGB9lctZTTOJM3pHfKBAEcxQFoHlt2s9sXoxFizTeHihsQyfFg5fx
# UFEp7W42fNBVN4ueLaceRf9Cq9ec1v5iQMWTFQa0xNqItH3CPFTG7aEQJmmrJTV3
# Qhtfparz+BW60OiMEgV5GWoBy4RVPRwqxv7Mk0Sy4QHs7v9y69NBqycz0BZwhB9W
# OfOu/CIJnzkQTwtSSpGGhLdjnQ4eBpjtP+XB3pQCtv4E5UCSDag6+iX8MmB10nfl
# dPF9SVD7weCC3yXZi/uuhqdwkgVxuiMFzGVFwYbQsiGnoa9F5AaAyBjFBtXVLcKt
# apnMG3VH3EmAp/jsJ3FVF3+d1SVDTmjFjLbNFZUWMXuZyvgLfgyPehwJVxwC+UpX
# 2MSey2ueIu9THFVkT+um1vshETaWyQo8gmBto/m3acaP9QsuLj3FNwFlTxq25+T4
# QwX9xa6ILs84ZPvmpovq90K8eWyG2N01c4IhSOxqt81nMYIFBDCCBQACAQEwKDAU
# MRIwEAYDVQQDDAlSb21hbiBFbnoCEFOwMuWruKGNQyJoKHWwwLYwDQYJYIZIAWUD
# BAIBBQCggYQwGAYKKwYBBAGCNwIBDDEKMAigAoAAoQKAADAZBgkqhkiG9w0BCQMx
# DAYKKwYBBAGCNwIBBDAcBgorBgEEAYI3AgELMQ4wDAYKKwYBBAGCNwIBFTAvBgkq
# hkiG9w0BCQQxIgQgvQ/n355lXiKa/qsS2U9G4/RwArj7D0z6MZS0eGds+scwDQYJ
# KoZIhvcNAQEBBQAEggEAisLeiEPXFSFIgPTrtpo8kw77znXz13OYLLnoXpofWT6a
# koynuJnZI6alHj9oFhu/THEbbfjQ8nNQtQ6FqMPP9JuFnZR0N1xOcAypP1P0dawd
# jX8pXjrig+9EcwjD9fkzH6f7vRMcidHjnykOWLtcbwTpJ5T0TCWb62U5NwJSNr6L
# isUaqODW44UVAViC9yM2PI2Wh7t/eyLJ/HQDzah5EjQjWkTizwFQ1rwiQM1+7+np
# 5+AF2qr/ioCv+CZtw6OKbmYqhsJ1GGQlaASuUySnOrlhVkAGUM460lSKlrTzpaEx
# Tv8xfanEDuHMcTvNE9xbc80+FIpuHKwC9Cfl79vihKGCAyYwggMiBgkqhkiG9w0B
# CQYxggMTMIIDDwIBATB9MGkxCzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5EaWdpQ2Vy
# dCwgSW5jLjFBMD8GA1UEAxM4RGlnaUNlcnQgVHJ1c3RlZCBHNCBUaW1lU3RhbXBp
# bmcgUlNBNDA5NiBTSEEyNTYgMjAyNSBDQTECEAqA7xhLjfEFgtHEdqeVdGgwDQYJ
# YIZIAWUDBAIBBQCgaTAYBgkqhkiG9w0BCQMxCwYJKoZIhvcNAQcBMBwGCSqGSIb3
# DQEJBTEPFw0yNjA3MjgxOTMzNTJaMC8GCSqGSIb3DQEJBDEiBCC6OebvT/9FhGam
# pPkN+ShqJaFLdKO+IQksHsDKilQWKjANBgkqhkiG9w0BAQEFAASCAgCQXYD0+XyQ
# 6LM44Fw64cJyvFkQLELX1lAajYfPX7gsdWd4FK9gNu3hUPyXScyUevf4rhTmhoON
# fM/As0256IX1VsNsk641C/xYXLRTN7QWCRoGuA4mVfLYWmMiW0yyilbdxcHv4OXx
# RinQ1vwRCTRUrXcHgFWLVDHRwsHzN8BmSqTy4oHg0WwVxLTZQk9UjmFu3sfWpUsW
# 8NAE0hRul6+W873E4+5Xs7TRBkEc3lJrVWjSiQoeauyOHRxGpbd3j19mUycY/AUP
# NU3LGdS4O2s8hjfaOa/vs7nYC/8Du2iuyo1YtrSyUp9cvMNLjh9e+VcTju2wPtWi
# uUkZmWl5lpZ/kaXAHdgaibBdioG5x7Q0nMrLQ7/BCrMWgj2YWE2aVOSjFjXwdLl/
# WuqVIxaal30r+pBbGrAMShCHuBB7n4bCw+RU4JAuH3DjUvIUsyQFZPhKws/IrpxT
# Pbi4WKiaediYk8QASOkdys+OQmiVwPFYKiJNFbdsN5XLW+3sEh4FuBd44QR4cyQo
# 0zP5Ia1xxwSggm9d71B4Fx2ofnnfpAbqKU1Lhzd+Uo35qVDI2bv11tnOq9KmXmIE
# 9SCZ6mxoZ8ibFZ8lZV7WOPthVjJJ1Up+0fwtXVSErZpZnngmqB2W0aRGkZC2s8L4
# BNct5NVRdfrS/7cbUi4/N2NH+BwTV+knuQ==
# SIG # End signature block