Idabus.Automation.Core.psm1

##############################################
###
### IDABUS Ressource PowerShell
### (c) 2024 Oxford Computer Group GmbH
###
##############################################

Import-Module -PassThru -Name (Join-Path $PSScriptRoot 'IDABUS.Automation.Core51.dll')

##########################################################
###
### Get the user account this session ist connected with
###
##########################################################
function Get-IdabusLogonAccount
{
    <#
    .DESCRIPTION
    Get the user account this session ist connected with.
    #>

    $user = Send-IdabusGetRequest -ResourcePath "/user/person"

    return $user|convertfrom-json

}


##########################################################
###
### Get IDABUS Resource
###
##########################################################
function Get-IdabusResource
{

    <#
    .DESCRIPTION
    Get an IDABUS resource
    #>


    [CmdletBinding(DefaultParameterSetName = 'AttributeValue')]
    param(

        [Parameter(Mandatory = $true, ParameterSetName = 'AttributeValue', Position = 0)]
        [string] $ObjectType,

        [Parameter(Mandatory = $true, ParameterSetName = 'AttributeValue', Position = 1)]
        [string] $AttributeName,

        [Parameter(Mandatory = $true, ParameterSetName = 'AttributeValue', Position = 2)]
        [string] $AttributeValue,

        [Parameter(Mandatory = $true, ParameterSetName = 'ByID', Position = 0)]
        [Guid] $ID,

        [Parameter(ParameterSetName = 'ByID')]
        [Parameter(ParameterSetName = 'AttributeValue')]
        [switch]$IncludeNull,

        [Parameter(ParameterSetName = 'ByID')]
        [Parameter(ParameterSetName = 'AttributeValue')]
        [string[]] $AttributesToGet = @("*")

    )

    $queries = @()

    foreach($attribute in $AttributesToGet)
    {
        $queries += "attributes=$attribute"
    }


    if($IncludeNull)
    {
        $queries += "queryFormat=IncludeNull"
    }

    switch ($PsCmdlet.ParameterSetName) {
        "AttributeValue" {

            $xpath = "/$ObjectType[$AttributeName='$AttributeValue']"
            $xpathQuery = [Uri]::EscapeDataString($xpath)
            $queries += "xPathQuery=$xpathQuery"

            $result = Send-IdabusGetRequest -ResourcePath "/Resources/Search" -Queries $queries

            $jsonResult = $result|ConvertFrom-Json

            return  ($jsonResult.results[0])|ConvertTo-DeltaEntry

        }
        "ByID" {
            $result = Send-IdabusGetRequest -ResourcePath "/Resources/$ID" -Queries $queries

            return ($result|ConvertFrom-Json|ConvertTo-DeltaEntry)
        }
    }
}

##########################################################
###
### Save IDABUS Resource
###
##########################################################
function Save-IdabusResource
{

    <#
    .DESCRIPTION
    Save an IDABUS resource
    -FullObject saves the complete entry instead of modified attributes only
    #>


    [CmdletBinding(SupportsShouldProcess)]
    param(

        [parameter(Mandatory=$true, ValueFromPipeline=$true, Position = 0)]
        [PSCustomObject] $InputObject,

        [switch]$FullObject
    )


    PROCESS
    {
        $content=$null
        $id=$null
        if($null -eq ($InputObject |get-member -Name "__GetDeltaEntry"))
        {
            $content = $InputObject|ConvertTo-Json
            $id = $InputObject.objectid
        }
        else
        {
            if($FullObject){

                $entry = $InputObject.__SourceEntry
                $content = $entry|ConvertTo-Json
                $id=$entry.objectid

            }else{

                $entry = $InputObject.__GetDeltaEntry()
                $content = $entry|ConvertTo-Json
                $id=$entry.objectid
            }
        }



        if([string]::IsNullOrEmpty($id))
        {
            if($PSCmdlet.ShouldProcess($content))
            {
                $result = Send-IdabusPostRequest -ResourcePath "/Resources/" -JsonContent $content
                return convertfrom-json -InputObject $result
            }
        }
        else
        {
            if($PSCmdlet.ShouldProcess($content))
            {
                $result = Send-IdabusPatchRequest -ResourcePath "/Resources/$id" -JsonContent $content
                return convertfrom-json -InputObject $result
            }
        }



    }

}

##########################################################
###
### New IDABUS Resource
###
##########################################################
function New-IdabusResource
{
    <#
    .DESCRIPTION
    Create a new IDABUS resource.
    #>


    [CmdletBinding(SupportsShouldProcess)]
    param(

        [parameter(Mandatory=$true, Position = 0)]
        [string] $ObjectType
    )

    PROCESS
    {
        if($PSCmdlet.ShouldProcess($ObjectType))
        {
            return Get-IdabusSchemaBindings $ObjectType -WriteableOnly
        }
    }
}

##########################################################
###
### Delete IDABUS Resources
###
##########################################################
function Remove-IdabusResource
{

    <#
    .DESCRIPTION
    Delete an IDABUS resource.
    #>

    [CmdletBinding(SupportsShouldProcess)]
    param(

        [parameter(Mandatory=$true,ParameterSetName = 'xpath', Position = 0)]
        [string] $XPath,

        [parameter(Mandatory=$true,ParameterSetName = 'id', Position = 0)]
        [string] $ID,

        [parameter(Mandatory=$true,ParameterSetName = 'entry', Position = 0,  ValueFromPipeline=$true)]
        [PSCustomObject] $InputObject,

        [parameter(ParameterSetName = 'xpath')]
        [switch]$DisableReferenceCleanup,

        [parameter(ParameterSetName = 'xpath')]
        [switch]$EnablePreUpdateTriggers,

        [parameter(ParameterSetName = 'xpath')]
        [switch]$EnablePostUpdateTriggers,

        [parameter(ParameterSetName = 'xpath')]
        [parameter(ParameterSetName = 'id')]
        [parameter(ParameterSetName = 'entry')]
        [string]$Comment
    )


    PROCESS
    {


        $queries = @()

        $queries+= "xpath=$([Uri]::EscapeDataString($XPath))"

        if($DisableReferenceCleanup)
        {
            $queries += "disableReferenceCleanup=true"
        }

        if($EnablePreUpdateTriggers)
        {
            $queries += "disablePreUpdateTriggers=false"
        }

        if($EnablePostUpdateTriggers)
        {
            $queries += "disablePostUpdateTriggers=false"
        }

        if(![string]::IsNullOrEmpty($Comment))
        {
            $queries += "comment=" + [Uri]::EscapeDataString($Comment)
        }



        switch ($PsCmdlet.ParameterSetName)
        {
            "id"
            {
                if($PSCmdlet.ShouldProcess($ID))
                {
                    Send-IdabusDeleteRequest -ResourcePath "/Resources/$ID" -Queries $queries
                }
            }
            "entry"
            {

                $entryID = $InputObject.objectid
                if($PSCmdlet.ShouldProcess($entryID))
                {


                    if(![String]::IsNullOrEmpty($entryID))
                    {

                        Send-IdabusDeleteRequest -ResourcePath "/Resources/$entryID" -Queries $queries
                    }
                    else
                    {
                        throw "ObjectID on 'InputObject' is empty!"
                    }
                }
            }
            "xpath"
            {
                if($PSCmdlet.ShouldProcess($XPath))
                {
                    Send-IdabusDeleteRequest -ResourcePath "/Resources/xpath" -Queries $queries
                }
            }
        }

    }


}

##########################################################
###
### Search IDABUS Resources
###
##########################################################
Function Search-IdabusResource {

    <#
    .DESCRIPTION
    Search for IDABUS resources by XPATH queries.
    #>

    [CmdletBinding(DefaultParameterSetName = 'AttributesToGet')]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', 'ExpectedObjectType',Justification='For backward compatibility')]
    param(
        [parameter(Mandatory=$true, Position = 0)]
        [string] $XPath,
        [parameter(Mandatory=$false, ParameterSetName = 'ExpectedObjectType', Position = 1)]
        [string] $ExpectedObjectType,
        [parameter(Mandatory=$false, ParameterSetName = 'AttributesToGet', Position = 1)]
        [string[]] $AttributesToGet = @("ObjectID","ObjectType"),
        [parameter(Mandatory=$false, ParameterSetName = 'Unconstrained', Position = 1)]
        [switch] $Unconstrained,
        [parameter(Mandatory=$false)]
        [ValidateRange(1,[int32]::MaxValue)]
        [int32] $PageSize = 200,
        [parameter(Mandatory=$false)]
        [ValidateRange(1,[int32]::MaxValue)]
        [int32] $MaxResults = [int32]::MaxValue,
        [parameter(Mandatory=$false)]
        [string] $SortByAttribute,
        [parameter(Mandatory=$false)]
        [switch] $Descending
    )

    begin {
        if ($MaxResults -lt $PageSize) {
            $PageSize = $MaxResults
        }

        $f_qry_body = [PSCustomObject]@{
            attributes   = $AttributesToGet
            queryFormat  = "IncludeNull" #"Standard"/"IncludeNull"/"Verbose"
            pageSize     = $PageSize #$PageSize
            includeCount = "fastonly" #"None"/"fastonly"/"Forced"
        }

        if ($SortByAttribute) {

            $f_sort_order = 'Ascending'
            if ($Descending) { $f_sort_order = 'Descending' }

            $f_qry_order = @{attribute = $SortByAttribute; order = $f_sort_order}

            Add-Member -InputObject $f_qry_body -MemberType NoteProperty -Name 'orderBy' -Value $f_qry_order
        }

        switch ($PSCmdlet.ParameterSetName) {

            'AttributesToGet' {

                $f_qry_atts = [System.Collections.Generic.List[object]]::new()

                $AttributesToGet.ForEach({
                    $f_qry_atts.Add($psitem)
                })

                $f_qry_body.attributes = $f_qry_atts.ToArray()

                break
            }

            'ExpectedObjectType' {
                $f_qry_body.attributes = @('*')
                #For backward compatibility only!
                break
            }

            'Unconstrained' {
                if($Unconstrained)
                {
                    $f_qry_body.attributes  = @('*')
                }
                break
            }

            default {
                break
            }
        }

        $f_xpath_esc = [Uri]::EscapeDataString($XPath)
        $f_qry_json  = ($f_qry_body | ConvertTo-Json -Depth 100)
    }

    process {

        [int]$f_total_results = 0

        $f_qry_results = (Send-IdabusPostRequest -ResourcePath "/Resources/Search" -Queries @("xPathQuery=$f_xpath_esc") -JsonContent $f_qry_json | ConvertFrom-Json)

        [PSCustomObject[]]$resultsEntries = $f_qry_results.results
        $f_total_results = $f_total_results + $resultsEntries.count

        Write-Output ($f_qry_results.results|ConvertTo-DeltaEntry) -NoEnumerate:$($resultsEntries.Count -lt 2)

        if ($MaxResults -le $PageSize) {
            $f_qry_results.hasMoreItems = $false
        }

        while ([boolean]::Parse($f_qry_results.hasMoreItems)) {

            # Retrieve next page
            $f_qry_results = (Send-IdabusGetRequest -ResourcePath "Resources/search/continue" -Queries @("continuationToken=$($f_qry_results.continuationToken)","pageSize=$PageSize") | ConvertFrom-Json)
            [PSCustomObject[]]$resultsEntries = $f_qry_results.results

            $f_total_results = $f_total_results + $resultsEntries.count

            if ($f_total_results -gt $MaxResults) {
                Write-Output ($resultsEntries|ConvertTo-DeltaEntry) | Select-Object -first ($f_qry_results.totalCount % $MaxResults) -NoEnumerate:$false
                break
            } else {
                Write-Output ($resultsEntries|ConvertTo-DeltaEntry) -NoEnumerate:$false
            }

            # Refresh Continuation Token
            if ($f_qry_results.continuationToken) {
                Send-IdabusGetRequest -ResourcePath "Resources/search/refreshtoken" -Queries @("continuationToken=$($f_qry_results.continuationToken)") | Out-Null
            }
        }
    }

    end {
    }
}



##########################################################
###
### Add References
###
##########################################################
function Add-IdabusReference
{
    <#
    .DESCRIPTION
    Add reference(s) to a multivalue reference attribute.
    #>


    param(

        [parameter(Mandatory=$true, Position = 0)]
        [Guid] $ResourceID,

        [parameter(Mandatory=$true, Position = 1)]
        [string] $AttributeName,

        [parameter(Mandatory=$true, Position = 2)]
        [Guid[]] $MemberIDs,

        [parameter(Mandatory=$false, Position = 3)]
        [string] $Comment,

        [parameter(Mandatory=$false)]
        [switch] $SkipInvalidReferences=$false


    )

    PROCESS
    {
        $queries = @()
        $queries += "skipInvalidReferences=$SkipInvalidReferences"
        if(![string]::IsNullOrEmpty($Comment))
        {
            $queries +="comment=$([Uri]::EscapeDataString($Comment))"
        }

        $attrib = [Uri]::EscapeDataString($AttributeName)

        $resource = "Resources/multivalued/multiple/$ResourceID/$attrib"

        $body = ConvertTo-Json $MemberIDs

        $body|Send-IdabusPutRequest -ResourcePath $resource -Queries $queries
    }
}

##########################################################
###
### Remove Reference(s)
###
##########################################################
function Remove-IdabusReference
{
    <#
    .DESCRIPTION
    Remove reference(s) from a multivalue reference attribute.
    #>

    [CmdletBinding(SupportsShouldProcess = $true)]
    param(

        [parameter(Mandatory=$true, Position = 0)]
        [Guid] $ResourceID,

        [parameter(Mandatory=$true, Position = 1)]
        [string] $AttributeName,

        [parameter(Mandatory=$true, Position = 2)]
        [Guid[]] $MemberIDs,

        [parameter(Mandatory=$false, Position = 3)]
        [string] $Comment,

        [parameter(Mandatory=$false)]
        [switch] $SkipInvalidReferences=$false
    )

    PROCESS
    {
        $queries = @()
        $queries += "skipInvalidReferences=$SkipInvalidReferences"
        if(![string]::IsNullOrEmpty($Comment))
        {
            $queries +="comment=$([Uri]::EscapeDataString($Comment))"
        }

        $attrib = [Uri]::EscapeDataString($AttributeName)

        $resource = "Resources/multivalued/multiple/$ResourceID/$attrib"

        $body = ConvertTo-Json $MemberIDs

        if($PSCmdlet.ShouldProcess($param))
        {
            $body|Send-IdabusDeleteRequest -ResourcePath $resource -Queries $queries -Confirm: $false
        }
        else
        {
            Write-Output "Removing member(s): $MemberIDs"
        }
    }
}

##########################################################
###
### Add Vaue(s)
###
##########################################################
function Add-IdabusValue
{
    <#
    .DESCRIPTION
    Add Value(s) to a multivalue attribute.
    #>


    param(

        [parameter(Mandatory=$true, Position = 0)]
        [Guid] $ResourceID,

        [parameter(Mandatory=$true, Position = 1)]
        [string] $AttributeName,

        [parameter(Mandatory=$true, Position = 2)]
        [string[]] $Values,

        [parameter(Mandatory=$false, Position = 3)]
        [string] $Comment
    )

    PROCESS
    {
        $queries = @()
        if(![string]::IsNullOrEmpty($Comment))
        {
            $queries +="comment=$([Uri]::EscapeDataString($Comment))"
        }

        $attrib = [Uri]::EscapeDataString($AttributeName)

        $resource = "Resources/multivalued/multiple/$ResourceID/$attrib"

        $body = ConvertTo-Json $Values

        $body|Send-IdabusPutRequest -ResourcePath $resource -Queries $queries
    }
}

##########################################################
###
### Remove Value(s)
###
##########################################################
function Remove-IdabusValue
{
    <#
    .DESCRIPTION
    Remove values(s) from a multivalue attribute.
    #>

    [CmdletBinding(SupportsShouldProcess = $true)]
    param(

        [parameter(Mandatory=$true, Position = 0)]
        [Guid] $ResourceID,

        [parameter(Mandatory=$true, Position = 1)]
        [string] $AttributeName,

        [parameter(Mandatory=$true, Position = 2)]
        [string[]] $Values,

        [parameter(Mandatory=$false, Position = 3)]
        [string] $Comment
    )

    PROCESS
    {
        $queries = @()
        if(![string]::IsNullOrEmpty($Comment))
        {
            $queries +="comment=$([Uri]::EscapeDataString($Comment))"
        }

        $attrib = [Uri]::EscapeDataString($AttributeName)

        $resource = "Resources/multivalued/multiple/$ResourceID/$attrib"

        $body = ConvertTo-Json $Values

        if($PSCmdlet.ShouldProcess($param))
        {
            $body|Send-IdabusDeleteRequest -ResourcePath $resource -Queries $queries -Confirm: $false
        }
        else
        {
            Write-Output "Removing values(s): $Values"
        }
    }
}

##################################################################################################################
##
## Internal Functions
##
###################################################################################################################

class DeltaEntry { #Base Class for DeltaEntries
    hidden [System.Collections.Generic.List[string]] $__ModifiedAttributes;
    hidden [PSObject] $__SourceEntry
}

##################################
##
## Delta calculation
##
##################################
function ConvertTo-DeltaEntry
{
    [CmdletBinding()]
    param(
        [parameter(Mandatory=$true, Position = 0,  ValueFromPipeline=$true)]
        [PSObject] $SourceEntry
    )

    PROCESS
    {

        $entry = [PSCustomObject]([DeltaEntry]::new())

        $entry.__ModifiedAttributes = [System.Collections.Generic.List[string]]::new()
        $entry.__SourceEntry = $SourceEntry

        #Deta function
        $getDeltaEntryFunc = {

            $deltaEntry = [PSCustomObject]@{
                objecttype = $this.__SourceEntry.objecttype
                objectid = $this.__SourceEntry.objectid
            }
            foreach($attrName in $this.__ModifiedAttributes)
            {
                $deltaEntry|Add-Member -MemberType NoteProperty -Name $attrName -Value $this.$attrName
            }
            return $deltaEntry
        }

        #Add properties
        foreach($propName in $entry.__SourceEntry.psobject.properties.name)
        {
            #Getter Method
            $getter = {
                $this.__SourceEntry.$propName
            }
            #Setter Method
            $setter = {
                $this.__SourceEntry.$propName = $args[0]
                $this.__ModifiedAttributes +=  $propName
            }
            $entry | Add-Member -MemberType 'ScriptProperty' -Name $propName -Value $getter.GetNewClosure() -SecondValue $setter.GetNewClosure()
        }

        $entry|Add-Member -MemberType ScriptMethod -Name "__GetDeltaEntry" -Value $getDeltaEntryFunc

        return $entry
    }

}

Export-ModuleMember -Function "Get-IdabusLogonAccount"
Export-ModuleMember -Function "Get-IdabusResource"
Export-ModuleMember -Function "Save-IdabusResource"
Export-ModuleMember -Function "Remove-IdabusResource"
Export-ModuleMember -Function "New-IdabusResource"
Export-ModuleMember -Function "Search-IdabusResource"
Export-ModuleMember -Function "Add-IdabusReference"
Export-ModuleMember -Function "Remove-IdabusReference"
Export-ModuleMember -Function "Add-IdabusValue"
Export-ModuleMember -Function "Remove-IdabusValue"

Export-ModuleMember -Cmdlet "Connect-IdabusService","Disconnect-IdabusService", "Reset-IdabusSchemaCache","Send-IdabusGetRequest","Send-IdabusPostRequest","Send-IdabusPutRequest","Send-IdabusPatchRequest","Send-IdabusDeleteRequest","Get-IdabusSchemaBindings"


# SIG # Begin signature block
# MIIuKAYJKoZIhvcNAQcCoIIuGTCCLhUCAQExCzAJBgUrDgMCGgUAMGkGCisGAQQB
# gjcCAQSgWzBZMDQGCisGAQQBgjcCAR4wJgIDAQAABBAfzDtgWUsITrck0sYpfvNR
# AgEAAgEAAgEAAgEAAgEAMCEwCQYFKw4DAhoFAAQUvq6bSIVJi0g2EizSWDmd0lxM
# 65iggidhMIIFcjCCA1qgAwIBAgIQdlP+rHVGSJP15ddKSDpO+DANBgkqhkiG9w0B
# AQwFADBTMQswCQYDVQQGEwJCRTEZMBcGA1UEChMQR2xvYmFsU2lnbiBudi1zYTEp
# MCcGA1UEAxMgR2xvYmFsU2lnbiBDb2RlIFNpZ25pbmcgUm9vdCBSNDUwHhcNMjAw
# MzE4MDAwMDAwWhcNNDUwMzE4MDAwMDAwWjBTMQswCQYDVQQGEwJCRTEZMBcGA1UE
# ChMQR2xvYmFsU2lnbiBudi1zYTEpMCcGA1UEAxMgR2xvYmFsU2lnbiBDb2RlIFNp
# Z25pbmcgUm9vdCBSNDUwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC2
# LcUw3Xroq5A9A3KwOkuZFmGy5f+lZx03HOV+7JODqoT1o0ObmEWKuGNXXZsAiAQl
# 6fhokkuC2EvJSgPzqH9qj4phJ72hRND99T8iwqNPkY2zBbIogpFd+1mIBQuXBsKY
# +CynMyTuUDpBzPCgsHsdTdKoWDiW6d/5G5G7ixAs0sdDHaIJdKGAr3vmMwoMWWuO
# vPSrWpd7f65V+4TwgP6ETNfiur3EdaFvvWEQdESymAfidKv/aNxsJj7pH+XgBIet
# MNMMjQN8VbgWcFwkeCAl62dniKu6TjSYa3AR3jjK1L6hwJzh3x4CAdg74WdDhLbP
# /HS3L4Sjv7oJNz1nbLFFXBlhq0GD9awd63cNRkdzzr+9lZXtnSuIEP76WOinV+Gz
# z6ha6QclmxLEnoByPZPcjJTfO0TmJoD80sMD8IwM0kXWLuePmJ7mBO5Cbmd+QhZx
# YucE+WDGZKG2nIEhTivGbWiUhsaZdHNnMXqR8tSMeW58prt+Rm9NxYUSK8+aIkQI
# qIU3zgdhVwYXEiTAxDFzoZg1V0d+EDpF2S2kUZCYqaAHN8RlGqocaxZ396eX7D8Z
# MJlvMfvqQLLn0sT6ydDwUHZ0WfqNbRcyvvjpfgP054d1mtRKkSyFAxMCK0KA8olq
# Ns/ITKDOnvjLja0Wp9Pe1ZsYp8aSOvGCY/EuDiRk3wIDAQABo0IwQDAOBgNVHQ8B
# Af8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUHwC/RoAK/Hg5t6W0
# Q9lWULvOljswDQYJKoZIhvcNAQEMBQADggIBAF4runSXNERfdkgoQIST7gFu6aGz
# 1oAl5nvkvAmRPQ/8dq3X1DAgu49g0JHWHPKc73gaK5QyAsEkllJSAtDz0fzymzlu
# meEfjkNBfZoeW8ldmoT8JuaH83RyJq2kG9k9O2pSoDwJHi8ee7MztEXH96yxr5Ng
# rXauuLIVeOuDauv/20arJOXuAvqQH1nAL13Wt12kXBC3clP4QU7M+ngaJUrK/oVi
# Q2HDtDeqgdL01joPvY1ZfjBH3itr5yFQM1/UZ5vUuGefPCeZA/+FQ45zEsogzehh
# 1bFm3BfWOW0P288jN6GCiU4caz/WoM2qB50+Qiaq1wzu+ke/GlJ+0XWB08mKYhdt
# T4igIaAmPq9t2WIwH+mYKK5ujdWOTHJmk4CNKuNVx2BnkEJWXCJRD7PcTjnuTd3Z
# HXgQVDtu0JdvA7UesiNzxhKymmTQ/JWFJKj/36Gw3JFArt8JM6u53ZK38cyRdDtp
# 62eXG5C/58egb3G7V7+3j1rtekBqFs2AhC0v4QLUJJRDsxX8DCsb/XFv/Mu8dRc6
# XoPSybMvG9WcjX9U/n5+5Fajh6ed4VlSlEGPbVu+hpWa/xp23UDSUUpwtB8zYyN3
# P+wnHlnkCIftNIJKDz/+oB3B9WdzRYZ49Kop6SeHxhnbxhMUwzlJh02gl+BlE/Wd
# d1bp2rNYxzrywM2CMIIFjTCCBHWgAwIBAgIQDpsYjvnQLefv21DiCEAYWjANBgkq
# hkiG9w0BAQwFADBlMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5j
# MRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBB
# c3N1cmVkIElEIFJvb3QgQ0EwHhcNMjIwODAxMDAwMDAwWhcNMzExMTA5MjM1OTU5
# WjBiMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQL
# ExB3d3cuZGlnaWNlcnQuY29tMSEwHwYDVQQDExhEaWdpQ2VydCBUcnVzdGVkIFJv
# b3QgRzQwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC/5pBzaN675F1K
# PDAiMGkz7MKnJS7JIT3yithZwuEppz1Yq3aaza57G4QNxDAf8xukOBbrVsaXbR2r
# snnyyhHS5F/WBTxSD1Ifxp4VpX6+n6lXFllVcq9ok3DCsrp1mWpzMpTREEQQLt+C
# 8weE5nQ7bXHiLQwb7iDVySAdYyktzuxeTsiT+CFhmzTrBcZe7FsavOvJz82sNEBf
# sXpm7nfISKhmV1efVFiODCu3T6cw2Vbuyntd463JT17lNecxy9qTXtyOj4DatpGY
# QJB5w3jHtrHEtWoYOAMQjdjUN6QuBX2I9YI+EJFwq1WCQTLX2wRzKm6RAXwhTNS8
# rhsDdV14Ztk6MUSaM0C/CNdaSaTC5qmgZ92kJ7yhTzm1EVgX9yRcRo9k98FpiHaY
# dj1ZXUJ2h4mXaXpI8OCiEhtmmnTK3kse5w5jrubU75KSOp493ADkRSWJtppEGSt+
# wJS00mFt6zPZxd9LBADMfRyVw4/3IbKyEbe7f/LVjHAsQWCqsWMYRJUadmJ+9oCw
# ++hkpjPRiQfhvbfmQ6QYuKZ3AeEPlAwhHbJUKSWJbOUOUlFHdL4mrLZBdd56rF+N
# P8m800ERElvlEFDrMcXKchYiCd98THU/Y+whX8QgUWtvsauGi0/C1kVfnSD8oR7F
# wI+isX4KJpn15GkvmB0t9dmpsh3lGwIDAQABo4IBOjCCATYwDwYDVR0TAQH/BAUw
# AwEB/zAdBgNVHQ4EFgQU7NfjgtJxXWRM3y5nP+e6mK4cD08wHwYDVR0jBBgwFoAU
# Reuir/SSy4IxLVGLp6chnfNtyA8wDgYDVR0PAQH/BAQDAgGGMHkGCCsGAQUFBwEB
# BG0wazAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQuY29tMEMGCCsG
# AQUFBzAChjdodHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vRGlnaUNlcnRBc3N1
# cmVkSURSb290Q0EuY3J0MEUGA1UdHwQ+MDwwOqA4oDaGNGh0dHA6Ly9jcmwzLmRp
# Z2ljZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJRFJvb3RDQS5jcmwwEQYDVR0gBAow
# CDAGBgRVHSAAMA0GCSqGSIb3DQEBDAUAA4IBAQBwoL9DXFXnOF+go3QbPbYW1/e/
# Vwe9mqyhhyzshV6pGrsi+IcaaVQi7aSId229GhT0E0p6Ly23OO/0/4C5+KH38nLe
# JLxSA8hO0Cre+i1Wz/n096wwepqLsl7Uz9FDRJtDIeuWcqFItJnLnU+nBgMTdydE
# 1Od/6Fmo8L8vC6bp8jQ87PcDx4eo0kxAGTVGamlUsLihVo7spNU96LHc/RzY9Hda
# XFSMb++hUD38dglohJ9vytsgjTVgHAIDyyCwrFigDkBjxZgiwbJZ9VVrzyerbHbO
# byMt9H5xaiNrIv8SuFQtJ37YOtnwtoeW/VvRXKwYw02fc7cBqZ9Xql4o4rmUMIIG
# rjCCBJagAwIBAgIQBzY3tyRUfNhHrP0oZipeWzANBgkqhkiG9w0BAQsFADBiMQsw
# CQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cu
# ZGlnaWNlcnQuY29tMSEwHwYDVQQDExhEaWdpQ2VydCBUcnVzdGVkIFJvb3QgRzQw
# HhcNMjIwMzIzMDAwMDAwWhcNMzcwMzIyMjM1OTU5WjBjMQswCQYDVQQGEwJVUzEX
# MBUGA1UEChMORGlnaUNlcnQsIEluYy4xOzA5BgNVBAMTMkRpZ2lDZXJ0IFRydXN0
# ZWQgRzQgUlNBNDA5NiBTSEEyNTYgVGltZVN0YW1waW5nIENBMIICIjANBgkqhkiG
# 9w0BAQEFAAOCAg8AMIICCgKCAgEAxoY1BkmzwT1ySVFVxyUDxPKRN6mXUaHW0oPR
# nkyibaCwzIP5WvYRoUQVQl+kiPNo+n3znIkLf50fng8zH1ATCyZzlm34V6gCff1D
# tITaEfFzsbPuK4CEiiIY3+vaPcQXf6sZKz5C3GeO6lE98NZW1OcoLevTsbV15x8G
# ZY2UKdPZ7Gnf2ZCHRgB720RBidx8ald68Dd5n12sy+iEZLRS8nZH92GDGd1ftFQL
# IWhuNyG7QKxfst5Kfc71ORJn7w6lY2zkpsUdzTYNXNXmG6jBZHRAp8ByxbpOH7G1
# WE15/tePc5OsLDnipUjW8LAxE6lXKZYnLvWHpo9OdhVVJnCYJn+gGkcgQ+NDY4B7
# dW4nJZCYOjgRs/b2nuY7W+yB3iIU2YIqx5K/oN7jPqJz+ucfWmyU8lKVEStYdEAo
# q3NDzt9KoRxrOMUp88qqlnNCaJ+2RrOdOqPVA+C/8KI8ykLcGEh/FDTP0kyr75s9
# /g64ZCr6dSgkQe1CvwWcZklSUPRR8zZJTYsg0ixXNXkrqPNFYLwjjVj33GHek/45
# wPmyMKVM1+mYSlg+0wOI/rOP015LdhJRk8mMDDtbiiKowSYI+RQQEgN9XyO7ZONj
# 4KbhPvbCdLI/Hgl27KtdRnXiYKNYCQEoAA6EVO7O6V3IXjASvUaetdN2udIOa5kM
# 0jO0zbECAwEAAaOCAV0wggFZMBIGA1UdEwEB/wQIMAYBAf8CAQAwHQYDVR0OBBYE
# FLoW2W1NhS9zKXaaL3WMaiCPnshvMB8GA1UdIwQYMBaAFOzX44LScV1kTN8uZz/n
# upiuHA9PMA4GA1UdDwEB/wQEAwIBhjATBgNVHSUEDDAKBggrBgEFBQcDCDB3Bggr
# BgEFBQcBAQRrMGkwJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNv
# bTBBBggrBgEFBQcwAoY1aHR0cDovL2NhY2VydHMuZGlnaWNlcnQuY29tL0RpZ2lD
# ZXJ0VHJ1c3RlZFJvb3RHNC5jcnQwQwYDVR0fBDwwOjA4oDagNIYyaHR0cDovL2Ny
# bDMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0VHJ1c3RlZFJvb3RHNC5jcmwwIAYDVR0g
# BBkwFzAIBgZngQwBBAIwCwYJYIZIAYb9bAcBMA0GCSqGSIb3DQEBCwUAA4ICAQB9
# WY7Ak7ZvmKlEIgF+ZtbYIULhsBguEE0TzzBTzr8Y+8dQXeJLKftwig2qKWn8acHP
# HQfpPmDI2AvlXFvXbYf6hCAlNDFnzbYSlm/EUExiHQwIgqgWvalWzxVzjQEiJc6V
# aT9Hd/tydBTX/6tPiix6q4XNQ1/tYLaqT5Fmniye4Iqs5f2MvGQmh2ySvZ180HAK
# fO+ovHVPulr3qRCyXen/KFSJ8NWKcXZl2szwcqMj+sAngkSumScbqyQeJsG33irr
# 9p6xeZmBo1aGqwpFyd/EjaDnmPv7pp1yr8THwcFqcdnGE4AJxLafzYeHJLtPo0m5
# d2aR8XKc6UsCUqc3fpNTrDsdCEkPlM05et3/JWOZJyw9P2un8WbDQc1PtkCbISFA
# 0LcTJM3cHXg65J6t5TRxktcma+Q4c6umAU+9Pzt4rUyt+8SVe+0KXzM5h0F4ejjp
# nOHdI/0dKNPH+ejxmF/7K9h+8kaddSweJywm228Vex4Ziza4k9Tm8heZWcpw8De/
# mADfIBZPJ/tgZxahZrrdVcA6KYawmKAr7ZVBtzrVFZgxtGIJDwq9gdkT/r+k0fNX
# 2bwE+oLeMt8EifAAzV3C+dAjfwAL5HYCJtnwZXZCpimHCUcr5n8apIUP/JiW9lVU
# Kx+A+sDyDivl1vupL0QVSucTDh3bNzgaoSv27dZ8/DCCBsIwggSqoAMCAQICEAVE
# r/OUnQg5pr/bP1/lYRYwDQYJKoZIhvcNAQELBQAwYzELMAkGA1UEBhMCVVMxFzAV
# BgNVBAoTDkRpZ2lDZXJ0LCBJbmMuMTswOQYDVQQDEzJEaWdpQ2VydCBUcnVzdGVk
# IEc0IFJTQTQwOTYgU0hBMjU2IFRpbWVTdGFtcGluZyBDQTAeFw0yMzA3MTQwMDAw
# MDBaFw0zNDEwMTMyMzU5NTlaMEgxCzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5EaWdp
# Q2VydCwgSW5jLjEgMB4GA1UEAxMXRGlnaUNlcnQgVGltZXN0YW1wIDIwMjMwggIi
# MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCjU0WHHYOOW6w+VLMj4M+f1+XS
# 512hDgncL0ijl3o7Kpxn3GIVWMGpkxGnzaqyat0QKYoeYmNp01icNXG/OpfrlFCP
# HCDqx5o7L5Zm42nnaf5bw9YrIBzBl5S0pVCB8s/LB6YwaMqDQtr8fwkklKSCGtpq
# utg7yl3eGRiF+0XqDWFsnf5xXsQGmjzwxS55DxtmUuPI1j5f2kPThPXQx/ZILV5F
# dZZ1/t0QoRuDwbjmUpW1R9d4KTlr4HhZl+NEK0rVlc7vCBfqgmRN/yPjyobutKQh
# ZHDr1eWg2mOzLukF7qr2JPUdvJscsrdf3/Dudn0xmWVHVZ1KJC+sK5e+n+T9e3M+
# Mu5SNPvUu+vUoCw0m+PebmQZBzcBkQ8ctVHNqkxmg4hoYru8QRt4GW3k2Q/gWEH7
# 2LEs4VGvtK0VBhTqYggT02kefGRNnQ/fztFejKqrUBXJs8q818Q7aESjpTtC/XN9
# 7t0K/3k0EH6mXApYTAA+hWl1x4Nk1nXNjxJ2VqUk+tfEayG66B80mC866msBsPf7
# Kobse1I4qZgJoXGybHGvPrhvltXhEBP+YUcKjP7wtsfVx95sJPC/QoLKoHE9nJKT
# BLRpcCcNT7e1NtHJXwikcKPsCvERLmTgyyIryvEoEyFJUX4GZtM7vvrrkTjYUQfK
# lLfiUKHzOtOKg8tAewIDAQABo4IBizCCAYcwDgYDVR0PAQH/BAQDAgeAMAwGA1Ud
# EwEB/wQCMAAwFgYDVR0lAQH/BAwwCgYIKwYBBQUHAwgwIAYDVR0gBBkwFzAIBgZn
# gQwBBAIwCwYJYIZIAYb9bAcBMB8GA1UdIwQYMBaAFLoW2W1NhS9zKXaaL3WMaiCP
# nshvMB0GA1UdDgQWBBSltu8T5+/N0GSh1VapZTGj3tXjSTBaBgNVHR8EUzBRME+g
# TaBLhklodHRwOi8vY3JsMy5kaWdpY2VydC5jb20vRGlnaUNlcnRUcnVzdGVkRzRS
# U0E0MDk2U0hBMjU2VGltZVN0YW1waW5nQ0EuY3JsMIGQBggrBgEFBQcBAQSBgzCB
# gDAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQuY29tMFgGCCsGAQUF
# BzAChkxodHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vRGlnaUNlcnRUcnVzdGVk
# RzRSU0E0MDk2U0hBMjU2VGltZVN0YW1waW5nQ0EuY3J0MA0GCSqGSIb3DQEBCwUA
# A4ICAQCBGtbeoKm1mBe8cI1PijxonNgl/8ss5M3qXSKS7IwiAqm4z4Co2efjxe0m
# gopxLxjdTrbebNfhYJwr7e09SI64a7p8Xb3CYTdoSXej65CqEtcnhfOOHpLawkA4
# n13IoC4leCWdKgV6hCmYtld5j9smViuw86e9NwzYmHZPVrlSwradOKmB521BXIxp
# 0bkrxMZ7z5z6eOKTGnaiaXXTUOREEr4gDZ6pRND45Ul3CFohxbTPmJUaVLq5vMFp
# GbrPFvKDNzRusEEm3d5al08zjdSNd311RaGlWCZqA0Xe2VC1UIyvVr1MxeFGxSjT
# redDAHDezJieGYkD6tSRN+9NUvPJYCHEVkft2hFLjDLDiOZY4rbbPvlfsELWj+MX
# kdGqwFXjhr+sJyxB0JozSqg21Llyln6XeThIX8rC3D0y33XWNmdaifj2p8flTzU8
# AL2+nCpseQHc2kTmOt44OwdeOVj0fHMxVaCAEcsUDH6uvP6k63llqmjWIso765qC
# NVcoFstp8jKastLYOrixRoZruhf9xHdsFWyuq69zOuhJRrfVf8y2OMDY7Bz1tqG4
# QyzfTkx9HmhwwHcK1ALgXGC7KP845VJa1qwXIiNO9OzTF/tQa/8Hdx9xl0RBybhG
# 02wyfFgvZ0dl5Rtztpn5aywGRu9BHvDwX+Db2a2QgESvgBBBijCCBugwggTQoAMC
# AQICEHe9DgW3WQu2HUdhUx4/de0wDQYJKoZIhvcNAQELBQAwUzELMAkGA1UEBhMC
# QkUxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExKTAnBgNVBAMTIEdsb2JhbFNp
# Z24gQ29kZSBTaWduaW5nIFJvb3QgUjQ1MB4XDTIwMDcyODAwMDAwMFoXDTMwMDcy
# ODAwMDAwMFowXDELMAkGA1UEBhMCQkUxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYt
# c2ExMjAwBgNVBAMTKUdsb2JhbFNpZ24gR0NDIFI0NSBFViBDb2RlU2lnbmluZyBD
# QSAyMDIwMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAyyDvlx65ATJD
# oFupiiP9IF6uOBKLyizU/0HYGlXUGVO3/aMX53o5XMD3zhGj+aXtAfq1upPvr5Pc
# +OKzGUyDsEpEUAR4hBBqpNaWkI6B+HyrL7WjVzPSWHuUDm0PpZEmKrODT3Kxintk
# ktDwtFVflgsR5Zq1LLIRzyUbfVErmB9Jo1/4E541uAMC2qQTL4VK78QvcA7B1Mwz
# Euy9QJXTEcrmzbMFnMhT61LXeExRAZKC3hPzB450uoSAn9KkFQ7or+v3ifbfcfDR
# vqeyQTMgdcyx1e0dBxnE6yZ38qttF5NJqbfmw5CcxrjszMl7ml7FxSSTY29+EIth
# z5hVoySiiDby+Z++ky6yBp8mwAwBVhLhsoqfDh7cmIsuz9riiTSmHyagqK54beyh
# iBU8wurut9itYaWvcDaieY7cDXPA8eQsq5TsWAY5NkjWO1roIs50Dq8s8RXa0bSV
# 6KzVSW3lr92ba2MgXY5+O7JD2GI6lOXNtJizNxkkEnJzqwSwCdyF5tQiBO9AKh0u
# bcdp0263AWwN4JenFuYmi4j3A0SGX2JnTLWnN6hV3AM2jG7PbTYm8Q6PsD1xwOEy
# p4LktjICMjB8tZPIIf08iOZpY/judcmLwqvvujr96V6/thHxvvA9yjI+bn3eD36b
# lcQSh+cauE7uLMHfoWXoJIPJKsL9uVMCAwEAAaOCAa0wggGpMA4GA1UdDwEB/wQE
# AwIBhjATBgNVHSUEDDAKBggrBgEFBQcDAzASBgNVHRMBAf8ECDAGAQH/AgEAMB0G
# A1UdDgQWBBQlndD8WQmGY8Xs87ETO1ccA5I2ETAfBgNVHSMEGDAWgBQfAL9GgAr8
# eDm3pbRD2VZQu86WOzCBkwYIKwYBBQUHAQEEgYYwgYMwOQYIKwYBBQUHMAGGLWh0
# dHA6Ly9vY3NwLmdsb2JhbHNpZ24uY29tL2NvZGVzaWduaW5ncm9vdHI0NTBGBggr
# BgEFBQcwAoY6aHR0cDovL3NlY3VyZS5nbG9iYWxzaWduLmNvbS9jYWNlcnQvY29k
# ZXNpZ25pbmdyb290cjQ1LmNydDBBBgNVHR8EOjA4MDagNKAyhjBodHRwOi8vY3Js
# Lmdsb2JhbHNpZ24uY29tL2NvZGVzaWduaW5ncm9vdHI0NS5jcmwwVQYDVR0gBE4w
# TDBBBgkrBgEEAaAyAQIwNDAyBggrBgEFBQcCARYmaHR0cHM6Ly93d3cuZ2xvYmFs
# c2lnbi5jb20vcmVwb3NpdG9yeS8wBwYFZ4EMAQMwDQYJKoZIhvcNAQELBQADggIB
# ACV1oAnJObq3oTmJLxifq9brHUvolHwNB2ibHJ3vcbYXamsCT7M/hkWHzGWbTONY
# BgIiZtVhAsVjj9Si8bZeJQt3lunNcUAziCns7vOibbxNtT4GS8lzM8oIFC09TOiw
# unWmdC2kWDpsE0n4pRUKFJaFsWpoNCVCr5ZW9BD6JH3xK3LBFuFr6+apmMc+WvTQ
# GJ39dJeGd0YqPSN9KHOKru8rG5q/bFOnFJ48h3HAXo7I+9MqkjPqV01eB17KwRis
# gS0aIfpuz5dhe99xejrKY/fVMEQ3Mv67Q4XcuvymyjMZK3dt28sF8H5fdS6itr81
# qjZjyc5k2b38vCzzSVYAyBIrxie7N69X78TPHinE9OItziphz1ft9QpA4vUY1h7p
# kC/K04dfk4pIGhEd5TeFny5mYppegU6VrFVXQ9xTiyV+PGEPigu69T+m1473BFZe
# Ibuf12pxgL+W3nID2NgiK/MnFk846FFADK6S7749ffeAxkw2V4SVp4QVSDAOUicI
# jY6ivSLHGcmmyg6oejbbarphXxEklaTijmjuGalJmV7QtDS91vlAxxCXMVI5NSkR
# hyTTxPupY8t3SNX6Yvwk4AR6TtDkbt7OnjhQJvQhcWXXCSXUyQcAerjH83foxdTi
# VdDTHvZ/UuJJjbkRcgyIRCYzZgFE3+QzDiHeYolIB9r1MIIH8jCCBdqgAwIBAgIM
# AyNmMwaozFNbTkBCMA0GCSqGSIb3DQEBCwUAMFwxCzAJBgNVBAYTAkJFMRkwFwYD
# VQQKExBHbG9iYWxTaWduIG52LXNhMTIwMAYDVQQDEylHbG9iYWxTaWduIEdDQyBS
# NDUgRVYgQ29kZVNpZ25pbmcgQ0EgMjAyMDAeFw0yMzAxMTYxNTQxMTFaFw0yNjAz
# MzAxNDM4MzFaMIIBQDEdMBsGA1UEDwwUUHJpdmF0ZSBPcmdhbml6YXRpb24xEzAR
# BgNVBAUTCkhSQiAxNzA3MzMxEzARBgsrBgEEAYI3PAIBAxMCREUxFzAVBgsrBgEE
# AYI3PAIBAhMGQmF5ZXJuMRkwFwYLKwYBBAGCNzwCAQETCE11ZW5jaGVuMQswCQYD
# VQQGEwJERTEPMA0GA1UECBMGQmF5ZXJuMQ8wDQYDVQQHEwZFcmRpbmcxGTAXBgNV
# BAkTEEdpZXNzZXJlaXN0ci4gMTYxIzAhBgNVBAoTGk94Zm9yZCBDb21wdXRlciBH
# cm91cCBHbWJIMRMwEQYDVQQLEwpDb25zdWx0aW5nMSMwIQYDVQQDExpPeGZvcmQg
# Q29tcHV0ZXIgR3JvdXAgR21iSDEYMBYGCSqGSIb3DQEJARYJcmJAb2NnLmRlMIIC
# IjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAwRyA3OnH2xcOzDJXAJswtqaN
# wgEgHvfVKqqYVe72KsXa5+ssuqato3Qzoss3DAcsypF4pkFMWWaei2RvYEvfkmTz
# +85OwYCZcOiBq07hf62ZfqurEZ18K0wtjW0aPMuFGUmR9F2z+Ws73yOy2zGVPr7I
# igEUSERPf4REcTlLBAeJIYt0owxkN1/i2Z/1m4rWeKST5rd5h3uQGeVeDDEErhnZ
# jqMsVbaI1BwvuzKEjtA1yXsBUUhQiM3x4cgUfQxfwGQiUzPjroaAEnO+EpMYyr/c
# uEYfEnClzJlKUJpS5lAurIObagkNOFegnn1NbB4Kik+slRH6ltHpg4O/j61fKWWO
# x8YothvhibkITe57PgLYqtjuRfEp+5ie4fRZ+4T8l/ELqLdbJmbC7tmf2tfdd/pg
# wxOJKzuhXX+orNB2XD3LjVlTN+KInnI0b4/AIV1conwmsRspLO3ys1ZRT7bYCX8l
# fP/7Z9LvtnRHg7AL5objVq4uzwOsi+QBsZgRkzpRpzirYS+in5/y78yJ+IhcVIF/
# bBQ7EpVP+69c1Wl5KhZkP64jlmZyWwX8iAslPOp4w6Z6UCu2HTtwAYRwBbs/PZqD
# U+q3VYuM305hpf7OE7YCMhUQ1B9JHtf5FVOTOzOnb1qnPmHIEGr5SFTwcrb0BPtL
# MDHqt+Y8Q0UKy9fraaECAwEAAaOCAcwwggHIMA4GA1UdDwEB/wQEAwIHgDCBnwYI
# KwYBBQUHAQEEgZIwgY8wTAYIKwYBBQUHMAKGQGh0dHA6Ly9zZWN1cmUuZ2xvYmFs
# c2lnbi5jb20vY2FjZXJ0L2dzZ2NjcjQ1ZXZjb2Rlc2lnbmNhMjAyMC5jcnQwPwYI
# KwYBBQUHMAGGM2h0dHA6Ly9vY3NwLmdsb2JhbHNpZ24uY29tL2dzZ2NjcjQ1ZXZj
# b2Rlc2lnbmNhMjAyMDBVBgNVHSAETjBMMEEGCSsGAQQBoDIBAjA0MDIGCCsGAQUF
# BwIBFiZodHRwczovL3d3dy5nbG9iYWxzaWduLmNvbS9yZXBvc2l0b3J5LzAHBgVn
# gQwBAzAJBgNVHRMEAjAAMEcGA1UdHwRAMD4wPKA6oDiGNmh0dHA6Ly9jcmwuZ2xv
# YmFsc2lnbi5jb20vZ3NnY2NyNDVldmNvZGVzaWduY2EyMDIwLmNybDAUBgNVHREE
# DTALgQlyYkBvY2cuZGUwEwYDVR0lBAwwCgYIKwYBBQUHAwMwHwYDVR0jBBgwFoAU
# JZ3Q/FkJhmPF7POxEztXHAOSNhEwHQYDVR0OBBYEFNg6ADF/xhP2iS0HFaTik7W/
# e/y8MA0GCSqGSIb3DQEBCwUAA4ICAQAoDywPR+p2DMh6rjCQkt6rF6h+Awcu3WHR
# Sq5tR5c11ijhVyEQZ4nhAXZ7s10/41/VMPWq99ahg9kFSIeRHYeVZ3252Ijto7au
# mbg/ND0+K1s90q7eXP7j05yA8g8ZUlnS9eLaohPk1e1K/Y++2LHWgPFCGcqRACGG
# oLRB79gqRfoQO5wh8PIbXNQyKB69QPxZOfi7sH2/+d53FGzjDLGgdrSSnYR5BboQ
# WHQw/xQLFE7K7WFVtkFpkTm0IFn3MzlG3Zfl3C3ELxETQRd4ZAFfrhqtZPPkug0S
# /E/ibcZqv+qfITLnTaXT02t1lTFdN8/H4wOyxb1yXKVhxtZ9t51EdqBr+cE6I+l4
# Uj/ZEN2go2c/CJmxYqlciGGwErmL0yD3Eqdq5UB/LR8ab/6GR0XiJ3GI73P6gZqn
# 05WaAMJsBmIkMeh+QY6cw3UUt7B6rNdJeeWkS2Yhe9nvNHRNuoFL2/KIVomjPpgR
# PuStt+/ukuBEJZdznw8KXmV1d0xvztvPYJog/VdkvAoWBjcg9A7sqBM7wPLYomAt
# gUAQliwed8Td+7Yu3Tb0vZEYCNm2Hg4hp5dPIVWfHurZav/G4+ode+EoPrCp2kmS
# nsf4Zi9j1GmcSsX7S5W7Q0uGZ81BE9MGbAhAv/9eFD1BazGHV3yMIZ7ElAR5PYUp
# XKNak4E9dDGCBjEwggYtAgEBMGwwXDELMAkGA1UEBhMCQkUxGTAXBgNVBAoTEEds
# b2JhbFNpZ24gbnYtc2ExMjAwBgNVBAMTKUdsb2JhbFNpZ24gR0NDIFI0NSBFViBD
# b2RlU2lnbmluZyBDQSAyMDIwAgwDI2YzBqjMU1tOQEIwCQYFKw4DAhoFAKB4MBgG
# CisGAQQBgjcCAQwxCjAIoAKAAKECgAAwGQYJKoZIhvcNAQkDMQwGCisGAQQBgjcC
# AQQwHAYKKwYBBAGCNwIBCzEOMAwGCisGAQQBgjcCARUwIwYJKoZIhvcNAQkEMRYE
# FHhNzhmflozUpRCyd6nW99oP7dqXMA0GCSqGSIb3DQEBAQUABIICAK09bsOYpNin
# DI9Xc/aHieKqpp3UKIIfRW1nrKmKTk+HlZDPPasRoKlc6uyw9gm4hMlmGYwEVzkl
# 5md0Bjzk/RA3TaPncctUXmTD5awMK48C3FQ9cvIKgTv/BAt2x0YnO3NA3bd+IqDL
# 2/BS5K/voX77a3SUuJ263ooOOM0MXdr9ODzXH5Cfq3gXueON5ejSBzOnhwnqMzx2
# GhAPlEPNe0X5N+LjA68DxqAtQ8Q0u6IMhcC5x8sc8pkPDz3X845/mqjHxLvZy3Qs
# 4HP1mrzBJyxaK3haRca/8vBrh71FmUz2m2Oe0Ec42XR3wlfAWbbqRUU+W8aaPCHr
# MefpD8v0uUujNxxtN/d3nwXV3q2b/eaBlvhRKKvRR8nwy9YSGC+zVhUJELF1mq4/
# ww5YmIobwxT4sK8Z9NfOTaSGHqyG/128zxMtuAzUanbSFLuv8OO0dh4pVta1gdxP
# g5wjzxpG3tGOys3AHOiwglZeIpEOMigWrPkZxxa1ZEb063dc32t3KRnVUl2ta6p/
# LKM2dmpMyVsrUZWOBSX+KYfvbOJQhyFTVNoJs7M7GMDzRVhf5vr9l6+7k9zac7zX
# q02b2mehbxRUcMaERVIwkEaAurlZeJxzOKtejSH3lDqovjbBp5417KJI659wzKPW
# 8DZaQnCx9UUSlejAbaL1+gSwB+x6mDdloYIDIDCCAxwGCSqGSIb3DQEJBjGCAw0w
# ggMJAgEBMHcwYzELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDkRpZ2lDZXJ0LCBJbmMu
# MTswOQYDVQQDEzJEaWdpQ2VydCBUcnVzdGVkIEc0IFJTQTQwOTYgU0hBMjU2IFRp
# bWVTdGFtcGluZyBDQQIQBUSv85SdCDmmv9s/X+VhFjANBglghkgBZQMEAgEFAKBp
# MBgGCSqGSIb3DQEJAzELBgkqhkiG9w0BBwEwHAYJKoZIhvcNAQkFMQ8XDTI0MDgw
# NzA5NDkwNVowLwYJKoZIhvcNAQkEMSIEIIu8N8JyH7K/8dKIzd/pBOephGerlAlF
# zMe6YitpHIuIMA0GCSqGSIb3DQEBAQUABIICAGmD1iVIojh5eIymuh3zz5uhNtyt
# ge2QLWnnN3uvb5TzzRV0LqZmDLJbQkSYYXpwxp53krxVZh6ZL88BaGFGlSD5PWuo
# GVcULv/H3G2Nyseps4c2fPIBx57NCX39IBmPPbuqIwGBgOA5o4C/HjQc3S6/rr0P
# 4agXSuSt+ZN7MzzwxKbGVWtcQzZuiGcTnL+R/wDSZxjkLEqO7G/ax2hIQ74g8lnB
# KJu0VVXQS3WWVLJmsaFyoyqsj5rURdAsA6YIPe/dIPKOBCXTdzQpYgcf04UvhoYt
# +zb0xs9vlop8ABiDJoEUCwt/gNLh/2ZJxO2ZtxsGGBAFimz8nKEWG4ZVVhbt29XS
# 7uD0oGi4DpxpXaR3EcZn8sl7FphlC+RNFgPwVlOvI0N91KTtwm/AXeL80Xu182xo
# UfI7GfIydEaJe/HjXWm/ZWRRnfu1OUr2/SbKtCsIIcinK9+9sQbTIuv6sWRN/4pa
# MlBMkaSV3+WhhQGwd9BsLMmNKky4+JTLe9f9LTOqTOZnopxrihFge8inQ0j9QKf1
# R6D6OSaKgVN0GIu2CF4ZtYXj+O8qjk34pMXJP38vIW2R5rXZ2nu5QiZYukm7wlX7
# G0MREPHDhzATvM18YyiMRaE1+2nmUVO+5nqj3CzoPEnC0ynV5FrnBDgXMfz+UvVC
# if8OI4XzGZdFgbHU
# SIG # End signature block