Public/New-ADFSTkInstitutionConfiguration.ps1

#Requires -Version 5.1

function New-ADFSTkInstitutionConfiguration {
[cmdletbinding()]
    Param (
    )


    #Get All paths
    if ([string]::IsNullOrEmpty($Global:ADFSTkPaths))
    {
        $Global:ADFSTkPaths = Get-ADFSTKPaths
    }
   
    #Create main dirs
    ADFSTk-TestAndCreateDir -Path $Global:ADFSTkPaths.mainDir               -PathName "ADFSTk install directory" #C:\ADFSToolkit
    ADFSTk-TestAndCreateDir -Path $Global:ADFSTkPaths.mainConfigDir         -PathName "Main configuration" #C:\ADFSToolkit\config
    ADFSTk-TestAndCreateDir -Path $Global:ADFSTkPaths.mainBackupDir         -PathName "Main backup" #C:\ADFSToolkit\config\backup
    ADFSTk-TestAndCreateDir -Path $Global:ADFSTkPaths.cacheDir              -PathName "Cache directory" #C:\ADFSToolkit\cache
    ADFSTk-TestAndCreateDir -Path $Global:ADFSTkPaths.institutionDir        -PathName "Institution config directory" #C:\ADFSToolkit\config\institution
    ADFSTk-TestAndCreateDir -Path $Global:ADFSTkPaths.institutionBackupDir  -PathName "Institution backup directory" #C:\ADFSToolkit\config\institution\backup
    ADFSTk-TestAndCreateDir -Path $Global:ADFSTkPaths.federationDir         -PathName "Federation config directory" #C:\ADFSToolkit\config\federation
    
    try {
        $mainConfiguration = Get-ADFSTkConfiguration
    }
    catch {
        #inform that we need a main config and that we will call that now
        Write-ADFSTkHost -WriteLine -AddSpaceAfter
        Write-ADFSTkHost confNeedMainConfigurationMessage -Style Info -AddSpaceAfter
        $mainConfiguration = New-ADFSTkConfiguration -Passthru
    }

    Write-ADFSTkHost confCreateNewConfigurationFile -Style Info -AddLinesOverAndUnder

    # Detect and prep previousConfig to source values for defaults from it
    #[xml]$previousConfig = ""
    #
    #
    #if ([string]::IsNullOrEmpty($MigrationConfig))
    #{
    # Write-Verbose (Get-ADFSTkLanguageText confNoPreviousFile)
    #}
    #else
    #{
    # if (Test-Path -Path $MigrationConfig)
    # {
    # $previousConfig = Get-Content $MigrationConfig
    # Write-ADFSTkHost confUsingPreviousFileForDefaulValues -f $MigrationConfig -ForegroundColor Red -AddSpaceAfter
    # }
    # else
    # {
    # Throw (Get-ADFSTkLanguageText confPreviousFileNotExist -f $MigrationConfig)
    # }
    #}
 
    # Use a default template from to start with
    #$mainConfiguration.FederationConfig.Federation

    $federationName = $mainConfiguration.FederationConfig.Federation.FederationName
    if ([string]::IsNullOrEmpty($federationName))
    {
        $defaultConfigFile = $Global:ADFSTkPaths.defaultConfigFile
        #[xml]$config = Get-Content $Global:ADFSTkPaths.defaultConfigFile
    }
    else
    {
        $defaultFederationConfigDir = Join-Path $Global:ADFSTkPaths.federationDir $federationName
        
        #Check if the federation dir exists and if not, create it
        ADFSTk-TestAndCreateDir -Path $defaultFederationConfigDir -PathName "$federationName config directory"

        Write-ADFSTkHost confCopyFederationDefaultFolderMessage -Style Info -AddSpaceAfter -f $Global:ADFSTkPaths.federationDir
        Read-Host (Get-ADFSTkLanguageText cPressEnterKey) | Out-Null
        
        $defaultFederationConfigFiles = Get-ChildItem -Path $defaultFederationConfigDir -Filter "*_defaultConfigFile.xml"
        
        if ($defaultFederationConfigFiles -eq $null)
        {
            $defaultConfigFile = $null
        }
        elseif ($defaultFederationConfigFiles -is [System.IO.FileSystemInfo])
        {
            $defaultConfigFile = $defaultFederationConfigFiles.FullName
            #[xml]$config = Get-Content $defaultFederationConfigFiles.FullName
        }
        elseif ($defaultFederationConfigFiles -is [System.Array])
        {
            $defaultConfigFile = $defaultFederationConfigFiles | Out-GridView -Title "Select the default federation configuration file you want to use" -OutputMode Single | Select -ExpandProperty FullName
        }
        else
        {
            #We should never be here...
        }

        if ([string]::IsNullOrEmpty($defaultConfigFile))
        {
            if (Get-ADFSTkAnswer (Get-ADFSTkLanguageText confFederationDefaultConfigNotFoundQuestion -f $federationName) -DefaultYes)
            {
                $defaultConfigFile = $Global:ADFSTkPaths.defaultConfigFile
                #[xml]$config = Get-Content $Global:ADFSTkPaths.defaultConfigFile
            }
            else
            {
                Write-ADFSTkLog (Get-ADFSTkLanguageText confFederationDefaultConfigNotFound) -MajorFault
            }
        }

    }

    try {
        [xml]$defaultConfig = Get-Content $defaultConfigFile

        if ($defaultConfig.configuration.ConfigVersion -ne '1.2')
        {
            Write-ADFSTkLog (Get-ADFSTkLanguageText confDefaultConfigIncorrectVersion -f $defaultConfigFile,$config.configuration.ConfigVersion,'1.2') -MajorFault
        }
    }
    catch {
        Write-ADFSTkLog (Get-ADFSTkLanguageText confCouldNotOpenFederationDefaultConfig -f $defaultConfigFile,$_) -MajorFault
    }

    [xml]$newConfig = $defaultConfig.Clone()


    Write-ADFSTkHost confStartMessage -Style Info -AddSpaceAfter
    Write-ADFSTkHost -WriteLine
    
    
       
    #Just set the value...
    #(Select-Xml -Xml $config -XPath "configuration/Federation").Node.'#text' = $chosenFed
    
    #Set-ADFSTkConfigItem -XPath "configuration/metadataURL" `
    # -ExampleValue 'https://metadata.federationOperator.org/path/to/metadata.xml' `
    # -Config $config `
    # -DefaultConfig $previousConfig
    #
    #Set-ADFSTkConfigItem -XPath "configuration/signCertFingerprint" `
    # -ExampleValue '0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF' `
    # -Config $config `
    # -DefaultConfig $previousConfig
    #
    #Set-ADFSTkConfigItem -XPath "configuration/MetadataPrefix" `
    # -ExampleValue 'ADFSTk/SWAMID/CANARIE/INCOMMON' `
    # -Config $config `
    # -DefaultConfig $previousConfig
    #
    #Set-ADFSTkConfigItem -XPath "configuration/staticValues/o" `
    # -ExampleValue 'ABC University' `
    # -Config $config `
    # -DefaultConfig $previousConfig
    #
    #Set-ADFSTkConfigItem -XPath "configuration/staticValues/co" `
    # -ExampleValue 'Canada, Sweden' `
    # -Config $config `
    # -DefaultConfig $previousConfig
    #
    #Set-ADFSTkConfigItem -XPath "configuration/staticValues/c" `
    # -ExampleValue 'CA, SE' `
    # -Config $config `
    # -DefaultConfig $previousConfig
    #
    #Set-ADFSTkConfigItem -XPath "configuration/staticValues/schacHomeOrganization" `
    # -ExampleValue 'institution.edu' `
    # -Config $config `
    # -DefaultConfig $previousConfig
    #
    #Set-ADFSTkConfigItem -XPath "configuration/staticValues/norEduOrgAcronym" `
    # -ExampleValue 'CA' `
    # -Config $config `
    # -DefaultConfig $previousConfig
    #
    #Set-ADFSTkConfigItem -XPath "configuration/staticValues/ADFSExternalDNS" `
    # -ExampleValue 'adfs.institution.edu' `
    # -Config $config `
    # -DefaultConfig $previousConfig
    #
    #Set-ADFSTkConfigItem -XPath "configuration/eduPersonPrincipalNameRessignable" `
    # -ExampleValue 'false' `
    # -Config $config `
    # -DefaultConfig $previousConfig

    Set-ADFSTkConfigItem -XPath "configuration/metadataURL" `
                         -ExampleValue 'https://metadata.federationOperator.org/path/to/metadata.xml' `
                         -DefaultConfig $defaultConfig `
                         -NewConfig $newConfig
                       
    Set-ADFSTkConfigItem -XPath "configuration/signCertFingerprint" `
                         -ExampleValue '0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF' `
                         -DefaultConfig $defaultConfig `
                         -NewConfig $newConfig

    Set-ADFSTkConfigItem -XPath "configuration/MetadataPrefix" `
                         -ExampleValue 'ADFSTk/CANARIE/INCOMMON/SWAMID' `
                         -DefaultConfig $defaultConfig `
                         -NewConfig $newConfig
                  
    Set-ADFSTkConfigItem -XPath "configuration/staticValues/co" `
                         -ExampleValue 'Canada, Sweden, USA' `
                         -DefaultConfig $defaultConfig `
                         -NewConfig $newConfig

    Set-ADFSTkConfigItem -XPath "configuration/staticValues/c" `
                         -ExampleValue 'CA, SE, US' `
                         -DefaultConfig $defaultConfig `
                         -NewConfig $newConfig

    Set-ADFSTkConfigItem -XPath "configuration/staticValues/o" `
                         -ExampleValue 'University Of Example' `
                         -DefaultConfig $defaultConfig `
                         -NewConfig $newConfig

    Set-ADFSTkConfigItem -XPath "configuration/staticValues/schacHomeOrganization" `
                         -ExampleValue 'universityofexample.edu' `
                         -DefaultConfig $defaultConfig `
                         -NewConfig $newConfig

    Set-ADFSTkConfigItem -XPath "configuration/staticValues/norEduOrgAcronym" `
                         -ExampleValue 'UoE' `
                         -DefaultConfig $defaultConfig `
                         -NewConfig $newConfig

    Set-ADFSTkConfigItem -XPath "configuration/staticValues/ADFSExternalDNS" `
                         -ExampleValue 'adfs.universityofexample.edu' `
                         -DefaultConfig $defaultConfig `
                         -NewConfig $newConfig

    Set-ADFSTkConfigItem -XPath "configuration/eduPersonPrincipalNameRessignable" `
                         -ExampleValue 'false' `
                         -DefaultConfig $defaultConfig `
                         -NewConfig $newConfig

    
    #Adding eduPersonScopedAffiliation based on eduPersonAffiliation added with @schackHomeOrganization
    $epa = $newConfig.configuration.storeConfig.attributes.attribute | ? type -eq "urn:mace:dir:attribute-def:eduPersonAffiliation" 
    $epsa = $newConfig.configuration.storeConfig.attributes.attribute | ? type -eq "urn:mace:dir:attribute-def:eduPersonScopedAffiliation"
    

    $epa.ChildNodes | % {
        $node = $_.Clone()    
        $node.InnerText += "@$($newConfig.configuration.staticValues.schacHomeOrganization)"

        $epsa.AppendChild($node) | Out-Null
    }

    # various useful items for minting our configuration

    # user entered
    $myPrefix = (Select-Xml -Xml $newConfig -XPath "configuration/MetadataPrefix").Node.InnerText

    # For the ADFSTk functionality, we desire to associate certain cache files to certain things and bake a certain default location
 
    #(Select-Xml -Xml $config -XPath "configuration/WorkingPath").Node.'#text' = "$myADFSTkInstallDir" #Do we really need this?
    (Select-Xml -Xml $newConfig -XPath "configuration/SPHashFile").Node.InnerText = "$myPrefix-SPHashfile.xml"
    (Select-Xml -Xml $newConfig -XPath "configuration/MetadataCacheFile").Node.InnerText = "$myPrefix-metadata.cached.xml"

    $newConfigFile = Join-Path $Global:ADFSTkPaths.institutionDir "config.$myPrefix.xml"

    if (Test-path $newConfigFile)
    {
        #Should we recommend to do an upgrade instead?
        if (Get-ADFSTkAnswer -Caption (Get-ADFSTkLanguageText confConfigurationAlreadyExistsCaption) `
                             -Message (Get-ADFSTkLanguageText confOverwriteConfiguration) `
                             -DefaultYes)
        {
            $newConfigFileObject = Get-ChildItem $newConfigFile
            $myConfigFileBkpName = Join-Path $Global:ADFSTkPaths.institutionBackupDir ("{0}.{1}{2}" -f $newConfigFileObject.BaseName, (get-date -Format o).Replace(':','.'), $newConfigFileObject.Extension)

            Write-ADFSTkHost confCreatingNewConfigHere -f $newConfigFile -Style Value
            Write-ADFSTkHost confOldConfigurationFile -f $myConfigFileBkpName -Style Value

            Move-Item -Path $newConfigFile -Destination $myConfigFileBkpName

            $newConfig.Save($newConfigFile)
        } 
        else 
        {
            Write-ADFSTkLog (Get-ADFSTkLanguageText confDontOverwriteFileExit) -MajorFault
        }
    }
    else
    {
        Write-ADFSTkHost confInstConfigCreated -f $newConfigFile -Style Value
        $newConfig.Save($newConfigFile)
    }


    
    #Add $configFile to Main Config File

    Write-ADFSTkHost confAddFileToMainConfigMessage -Style Info -AddLinesOverAndUnder

    Add-ADFSTkConfigurationItem -ConfigurationItem $newConfigFile

    Write-ADFSTkHost -WriteLine -AddSpaceAfter

    Write-ADFSTkHost confConfigurationFileSavedHere -f $newConfigFile -Style Value
    
#region get-ADFSTkLocalManualSpSettings.ps1

    Write-ADFSTkHost confLocalManualSettingsMessage -Style Info -AddLinesOverAndUnder

    # Prepare our template for ADFSTkManualSPSettings to be copied into place, safely of course, after directories are confirmed to be there.

    #$myADFSTkManualSpSettingsDistroTemplateFile = Join-Path $Global:ADFSTkPaths.modulePath -ChildPath "config\default\en-US\get-ADFSTkLocalManualSpSettings-dist.ps1"
    $myADFSTkManualSpSettingsInstallTemplateFile = Join-Path $Global:ADFSTkPaths.institutionDir -ChildPath "get-ADFSTkLocalManualSpSettings.ps1"

    if (Test-path $myADFSTkManualSpSettingsInstallTemplateFile ) 
    {
        if (Get-ADFSTkAnswer -Caption (Get-ADFSTkLanguageText confInstLocalSPFileExistsCaption) `
                             -Message (Get-ADFSTkLanguageText confOverwriteInstLocalSPFileMessage -f $myADFSTkManualSpSettingsInstallTemplateFile))
        {
            Write-ADFSTkHost confOverwriteInstLocalSPFileConfirmed -f $myADFSTkManualSpSettingsInstallTemplateFile -Style Value

            $mySPFileBkpName = "$myADFSTkManualSpSettingsInstallTemplateFile.$myConfigFileBkpExt"

            Write-ADFSTkHost confCreateNewInstLocalSPFile -f $Global:ADFSTkPaths.defaultInstitutionLocalSPFile -Style Value
            Write-ADFSTkHost confOldInstLocalSPFile -f $mySPFileBkpName -Style Value

            # Make backup
            Move-Item -Path $myADFSTkManualSpSettingsInstallTemplateFile -Destination $mySPFileBkpName

            Copy-item -Path $Global:ADFSTkPaths.defaultInstitutionLocalSPFile -Destination $myADFSTkManualSpSettingsInstallTemplateFile


            # Detect and strip signature from file we ship
            #$myFileContent = Get-Content $Global:ADFSTkPaths.defaultInstitutionLocalSPFile
            #$mySigLine = ($myFileContent | Select-String "SIG # Begin signature block").LineNumber
            #$sigOffset = 2
            #$mySigLocation = $mySigLine-$sigOffset
            #
            ## detection is anything greater than zero with offset as the signature block will be big.
            #if ($mySigLocation -gt 0 )
            #{
            # $myFileContent = $myFileContent[0..$mySigLocation]
            # Write-ADFSTkHost confFileSignedWillRemoveSignature -Style Info
            #}
            #else
            #{
            # Write-ADFSTkHost confFileNotSignedWillCopy -Style Info
            #}
            #
            #$myFileContent | Set-Content $myADFSTkManualSpSettingsInstallTemplateFile
        } 
        else 
        {
            Write-ADFSTkHost confDontOverwriteFileJustProceed -Style Info -AddSpaceAfter
        }
    }
    else
    {
        Write-ADFSTkHost confNoExistingFileSaveTo -f $myADFSTkManualSpSettingsInstallTemplateFile -Style Value -AddSpaceAfter
        Copy-item -Path $Global:ADFSTkPaths.defaultInstitutionLocalSPFile -Destination $myADFSTkManualSpSettingsInstallTemplateFile
    }

#endregion
    
    Write-ADFSTkHost confHowToRunMetadataImport -Style Info -AddLinesOverAndUnder

    if (Get-ADFSTkAnswer (Get-ADFSTkLanguageText confCreateScheduledTask))
    {
        $stAction = New-ScheduledTaskAction -Execute 'Powershell.exe' `
                                            -Argument "-NoProfile -WindowStyle Hidden -Command 'Sync-ADFSTkAggregates'"

        $stTrigger =  New-ScheduledTaskTrigger -Daily -DaysInterval 1 -At (Get-Date)
        $stSettings = New-ScheduledTaskSettingsSet -Disable -MultipleInstances IgnoreNew -ExecutionTimeLimit ([timespan]::FromHours(12))

        Register-ScheduledTask -Action $stAction `
                               -Trigger $stTrigger `
                               -TaskName (Get-ADFSTkLanguageText confImportMetadata) `
                               -Description (Get-ADFSTkLanguageText confTHisSchedTaskWillDoTheImport) `
                               -RunLevel Highest `
                               -Settings $stSettings `
                               -TaskPath "\ADFSToolkit\"
    }

    Write-ADFSTkHost -WriteLine -AddSpaceAfter
    Write-ADFSTkHost cAllDone -Style Done

<#
.SYNOPSIS
Create or migrats an ADFSToolkit configuration file per aggregate.
 
.DESCRIPTION
 
This command creates a new or migrates an older configuration to a newer one when invoked.
 
How this Powershell Cmdlet works:
  
When loaded we:
   - seek out a template configuration in $Module-home/config/default/en/config.ADFSTk.default*.xml
   -- where * is the language designation, usually 'en'
   - if invoked with -MigrateConfig, the configuration attempts to detect the previous answers as defaults to the new ones where possible
 
    
.INPUTS
 
zero or more inputs of an array of string to command
 
.OUTPUTS
 
configuration file(s) for use with current ADFSToolkit that this command is associated with
 
.EXAMPLE
new-ADFSTkConfiguration
 
.EXAMPLE
 
"C:\ADFSToolkit\0.0.0.0\config\config.file.xml" | new-ADFSTkConfiguration
 
.EXAMPLE
 
"C:\ADFSToolkit\0.0.0.0\config\config.file.xml","C:\ADFSToolkit\0.0.0.0\config\config.file2.xml" | new-ADFSTkConfiguration
 
#>


}



# SIG # Begin signature block
# MIIczwYJKoZIhvcNAQcCoIIcwDCCHLwCAQExCzAJBgUrDgMCGgUAMGkGCisGAQQB
# gjcCAQSgWzBZMDQGCisGAQQBgjcCAR4wJgIDAQAABBAfzDtgWUsITrck0sYpfvNR
# AgEAAgEAAgEAAgEAAgEAMCEwCQYFKw4DAhoFAAQUJQtvhQUHx2xhisrfPwagg9RY
# i4SgghcwMIIEFDCCAvygAwIBAgILBAAAAAABL07hUtcwDQYJKoZIhvcNAQEFBQAw
# VzELMAkGA1UEBhMCQkUxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExEDAOBgNV
# BAsTB1Jvb3QgQ0ExGzAZBgNVBAMTEkdsb2JhbFNpZ24gUm9vdCBDQTAeFw0xMTA0
# MTMxMDAwMDBaFw0yODAxMjgxMjAwMDBaMFIxCzAJBgNVBAYTAkJFMRkwFwYDVQQK
# ExBHbG9iYWxTaWduIG52LXNhMSgwJgYDVQQDEx9HbG9iYWxTaWduIFRpbWVzdGFt
# cGluZyBDQSAtIEcyMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAlO9l
# +LVXn6BTDTQG6wkft0cYasvwW+T/J6U00feJGr+esc0SQW5m1IGghYtkWkYvmaCN
# d7HivFzdItdqZ9C76Mp03otPDbBS5ZBb60cO8eefnAuQZT4XljBFcm05oRc2yrmg
# jBtPCBn2gTGtYRakYua0QJ7D/PuV9vu1LpWBmODvxevYAll4d/eq41JrUJEpxfz3
# zZNl0mBhIvIG+zLdFlH6Dv2KMPAXCae78wSuq5DnbN96qfTvxGInX2+ZbTh0qhGL
# 2t/HFEzphbLswn1KJo/nVrqm4M+SU4B09APsaLJgvIQgAIMboe60dAXBKY5i0Eex
# +vBTzBj5Ljv5cH60JQIDAQABo4HlMIHiMA4GA1UdDwEB/wQEAwIBBjASBgNVHRMB
# Af8ECDAGAQH/AgEAMB0GA1UdDgQWBBRG2D7/3OO+/4Pm9IWbsN1q1hSpwTBHBgNV
# HSAEQDA+MDwGBFUdIAAwNDAyBggrBgEFBQcCARYmaHR0cHM6Ly93d3cuZ2xvYmFs
# c2lnbi5jb20vcmVwb3NpdG9yeS8wMwYDVR0fBCwwKjAooCagJIYiaHR0cDovL2Ny
# bC5nbG9iYWxzaWduLm5ldC9yb290LmNybDAfBgNVHSMEGDAWgBRge2YaRQ2XyolQ
# L30EzTSo//z9SzANBgkqhkiG9w0BAQUFAAOCAQEATl5WkB5GtNlJMfO7FzkoG8IW
# 3f1B3AkFBJtvsqKa1pkuQJkAVbXqP6UgdtOGNNQXzFU6x4Lu76i6vNgGnxVQ380W
# e1I6AtcZGv2v8Hhc4EvFGN86JB7arLipWAQCBzDbsBJe/jG+8ARI9PBw+DpeVoPP
# PfsNvPTF7ZedudTbpSeE4zibi6c1hkQgpDttpGoLoYP9KOva7yj2zIhd+wo7AKvg
# IeviLzVsD440RZfroveZMzV+y5qKu0VN5z+fwtmK+mWybsd+Zf/okuEsMaL3sCc2
# SI8mbzvuTXYfecPlf5Y1vC0OzAGwjn//UYCAp5LUs0RGZIyHTxZjBzFLY7Df8zCC
# BH0wggNloAMCAQICAxvnFTANBgkqhkiG9w0BAQsFADBjMQswCQYDVQQGEwJVUzEh
# MB8GA1UEChMYVGhlIEdvIERhZGR5IEdyb3VwLCBJbmMuMTEwLwYDVQQLEyhHbyBE
# YWRkeSBDbGFzcyAyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTE0MDEwMTA3
# MDAwMFoXDTMxMDUzMDA3MDAwMFowgYMxCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdB
# cml6b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMRowGAYDVQQKExFHb0RhZGR5LmNv
# bSwgSW5jLjExMC8GA1UEAxMoR28gRGFkZHkgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRo
# b3JpdHkgLSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL9xYgjx
# +lk09xvJGKP3gElY6SKDE6bFIEMBO4Tx5oVJnyfq9oQbTqC023CYxzIBsQU+B07u
# 9PpPL1kwIuerGVZr4oAH/PMWdYA5UXvl+TW2dE6pjYIT5LY/qQOD+qK+ihVqf94L
# w7YZFAXK6sOoBJQ7RnwyDfMAZiLIjWltNowRGLfTshxgtDj6AozO091GB94KPutd
# fMh8+7ArU6SSYmlRJQVhGkSBjCypQ5Yj36w6gZoOKcUcqeldHraenjAKOc7xiID7
# S13MMuyFYkMlNAJWJwGRtDtwKj9useiciAF9n9T521NtYJ2/LOdYq7hfRvzOxBsD
# PAnrSTFcaUaz4EcCAwEAAaOCARcwggETMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0P
# AQH/BAQDAgEGMB0GA1UdDgQWBBQ6moUHEGcotu/2vQVBbiDBlNoP3jAfBgNVHSME
# GDAWgBTSxLDSkdRMEXGzYcs9of7dqGrU4zA0BggrBgEFBQcBAQQoMCYwJAYIKwYB
# BQUHMAGGGGh0dHA6Ly9vY3NwLmdvZGFkZHkuY29tLzAyBgNVHR8EKzApMCegJaAj
# hiFodHRwOi8vY3JsLmdvZGFkZHkuY29tL2dkcm9vdC5jcmwwRgYDVR0gBD8wPTA7
# BgRVHSAAMDMwMQYIKwYBBQUHAgEWJWh0dHBzOi8vY2VydHMuZ29kYWRkeS5jb20v
# cmVwb3NpdG9yeS8wDQYJKoZIhvcNAQELBQADggEBAFkLU72ShhGnJHvtWzHPHR9s
# cMW4br5Ou/a+l1DhMH+6KFxilMLjfjP3+0J2hduVHIwiWHUJDIhlZzkKFgnFoDiX
# pMUjkz+0GKYBBkSR46dpJ7RaJX86tzLN3YT/KjgpM6TdZ7KF/qGIIBxQicjcKvZC
# AzdM5ojf1a8k8rHD38y17OCZXrdJVCA8lBgMxxxSGEmkbeGzWAvJ2OzZrhwyjihw
# DeL+pheehA+9V3CzWukfoIZTu+98/2kL4EjDt5MLyApUxKxdFGc3bMqlLzEIN6pu
# b4y8m+JXXSSBr5eXnIStbKw3TGbzYZERIOS+MJ96pCkJsOE0X2R3GEBR34wwpq8w
# ggSfMIIDh6ADAgECAhIRIdaZp2SXPvH4Qn7pGcxTQRQwDQYJKoZIhvcNAQEFBQAw
# UjELMAkGA1UEBhMCQkUxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExKDAmBgNV
# BAMTH0dsb2JhbFNpZ24gVGltZXN0YW1waW5nIENBIC0gRzIwHhcNMTYwNTI0MDAw
# MDAwWhcNMjcwNjI0MDAwMDAwWjBgMQswCQYDVQQGEwJTRzEfMB0GA1UEChMWR01P
# IEdsb2JhbFNpZ24gUHRlIEx0ZDEwMC4GA1UEAxMnR2xvYmFsU2lnbiBUU0EgZm9y
# IE1TIEF1dGhlbnRpY29kZSAtIEcyMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
# CgKCAQEAsBeuotO2BDBWHlgPse1VpNZUy9j2czrsXV6rJf02pfqEw2FAxUa1WVI7
# QqIuXxNiEKlb5nPWkiWxfSPjBrOHOg5D8NcAiVOiETFSKG5dQHI88gl3p0mSl9Rs
# kKB2p/243LOd8gdgLE9YmABr0xVU4Prd/4AsXximmP/Uq+yhRVmyLm9iXeDZGayL
# V5yoJivZF6UQ0kcIGnAsM4t/aIAqtaFda92NAgIpA6p8N7u7KU49U5OzpvqP0liT
# FUy5LauAo6Ml+6/3CGSwekQPXBDXX2E3qk5r09JTJZ2Cc/os+XKwqRk5KlD6qdA8
# OsroW+/1X1H0+QrZlzXeaoXmIwRCrwIDAQABo4IBXzCCAVswDgYDVR0PAQH/BAQD
# AgeAMEwGA1UdIARFMEMwQQYJKwYBBAGgMgEeMDQwMgYIKwYBBQUHAgEWJmh0dHBz
# Oi8vd3d3Lmdsb2JhbHNpZ24uY29tL3JlcG9zaXRvcnkvMAkGA1UdEwQCMAAwFgYD
# VR0lAQH/BAwwCgYIKwYBBQUHAwgwQgYDVR0fBDswOTA3oDWgM4YxaHR0cDovL2Ny
# bC5nbG9iYWxzaWduLmNvbS9ncy9nc3RpbWVzdGFtcGluZ2cyLmNybDBUBggrBgEF
# BQcBAQRIMEYwRAYIKwYBBQUHMAKGOGh0dHA6Ly9zZWN1cmUuZ2xvYmFsc2lnbi5j
# b20vY2FjZXJ0L2dzdGltZXN0YW1waW5nZzIuY3J0MB0GA1UdDgQWBBTUooRKOFoY
# f7pPMFC9ndV6h9YJ9zAfBgNVHSMEGDAWgBRG2D7/3OO+/4Pm9IWbsN1q1hSpwTAN
# BgkqhkiG9w0BAQUFAAOCAQEAj6kakW0EpjcgDoOW3iPTa24fbt1kPWghIrX4RzZp
# juGlRcckoiK3KQnMVFquxrzNY46zPVBI5bTMrs2SjZ4oixNKEaq9o+/Tsjb8tKFy
# v22XY3mMRLxwL37zvN2CU6sa9uv6HJe8tjecpBwwvKu8LUc235IgA+hxxlj2dQWa
# NPALWVqCRDSqgOQvhPZHXZbJtsrKnbemuuRQ09Q3uLogDtDTkipbxFm7oW3bPM5E
# ncE4Kq3jjb3NCXcaEL5nCgI2ZIi5sxsm7ueeYMRGqLxhM2zPTrmcuWrwnzf+tT1P
# mtNN/94gjk6Xpv2fCbxNyhh2ybBNhVDygNIdBvVYBAexGDCCBNAwggO4oAMCAQIC
# AQcwDQYJKoZIhvcNAQELBQAwgYMxCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6
# b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMRowGAYDVQQKExFHb0RhZGR5LmNvbSwg
# SW5jLjExMC8GA1UEAxMoR28gRGFkZHkgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3Jp
# dHkgLSBHMjAeFw0xMTA1MDMwNzAwMDBaFw0zMTA1MDMwNzAwMDBaMIG0MQswCQYD
# VQQGEwJVUzEQMA4GA1UECBMHQXJpem9uYTETMBEGA1UEBxMKU2NvdHRzZGFsZTEa
# MBgGA1UEChMRR29EYWRkeS5jb20sIEluYy4xLTArBgNVBAsTJGh0dHA6Ly9jZXJ0
# cy5nb2RhZGR5LmNvbS9yZXBvc2l0b3J5LzEzMDEGA1UEAxMqR28gRGFkZHkgU2Vj
# dXJlIENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcyMIIBIjANBgkqhkiG9w0BAQEF
# AAOCAQ8AMIIBCgKCAQEAueDLENSvdr3Uk2LrMGS4gQhswwTZYheOL/8+Zc+PzmLm
# PFIc2hZFS1WreGtjg2KQzg9pbJnIGhSLTMxFM+qI3J6jryv+gGGdeVfEzy70PzA8
# XUf8mha8wzeWQVGOEUtU+Ci+0Iy+8DA4HvOwJvhmR2Nt3nEmR484R1PRRh2049wA
# 6kWsvbxx2apvANvbzTA6eU9fTEf4He9bwsSdYDuxskOR2KQzTuqz1idPrSWKpcb0
# 1dCmrnQFZFeItURV1C0qOj74uL3pMgoClGTEFjpQ8Uqu53kzrwwgB3/o3wQ5wmkC
# bGNS+nfBG8h0h8i5kxhQVDVLaU68O9NJLh/cwdJS+wIDAQABo4IBGjCCARYwDwYD
# VR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFEDCvSeOzDSD
# MKIz1/tss/C0LIDOMB8GA1UdIwQYMBaAFDqahQcQZyi27/a9BUFuIMGU2g/eMDQG
# CCsGAQUFBwEBBCgwJjAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuZ29kYWRkeS5j
# b20vMDUGA1UdHwQuMCwwKqAooCaGJGh0dHA6Ly9jcmwuZ29kYWRkeS5jb20vZ2Ry
# b290LWcyLmNybDBGBgNVHSAEPzA9MDsGBFUdIAAwMzAxBggrBgEFBQcCARYlaHR0
# cHM6Ly9jZXJ0cy5nb2RhZGR5LmNvbS9yZXBvc2l0b3J5LzANBgkqhkiG9w0BAQsF
# AAOCAQEACH5skxDIOLiWqZBL/6FfTwTvbD6ciAbJUI+mc/dXMRu+vOQv2/i601vg
# tOfmeWIODKLXamNzMbX1qEikOwgtol2Q17R8JU8RVjDEtkSdeyyd5V7m7wxhqr/k
# KhvuhJ64g33BQ85EpxNwDZEf9MgTrYNg2dhyqHMkHrWsIg7KF4liWEQbq4klAQAP
# zcQbYttRtNMPUSqb9Lxz/HbONqTN2dgs6q6b9SqykNFNdRiKP4pBkCN9W0v+pANY
# m0ayw2Bgg/h9UEHOwqGQw7vvAi/SFVTuRBXZCq6nijPtsS12NibcBOuf92EfFdyH
# b+5GliitoSZ9CgmnLgSjjbz4vAQwATCCBRwwggQEoAMCAQICCDeMqUwECkf0MA0G
# CSqGSIb3DQEBCwUAMIG0MQswCQYDVQQGEwJVUzEQMA4GA1UECBMHQXJpem9uYTET
# MBEGA1UEBxMKU2NvdHRzZGFsZTEaMBgGA1UEChMRR29EYWRkeS5jb20sIEluYy4x
# LTArBgNVBAsTJGh0dHA6Ly9jZXJ0cy5nb2RhZGR5LmNvbS9yZXBvc2l0b3J5LzEz
# MDEGA1UEAxMqR28gRGFkZHkgU2VjdXJlIENlcnRpZmljYXRlIEF1dGhvcml0eSAt
# IEcyMB4XDTIwMDEwODExMjIyNFoXDTIxMDMwODE4NTgwMFowXjELMAkGA1UEBhMC
# Q0ExEDAOBgNVBAgTB09udGFyaW8xDzANBgNVBAcTBk90dGF3YTEVMBMGA1UEChMM
# Q0FOQVJJRSBJbmMuMRUwEwYDVQQDEwxDQU5BUklFIEluYy4wggEiMA0GCSqGSIb3
# DQEBAQUAA4IBDwAwggEKAoIBAQDZhfCjFqiTmN1uLoySixnwaOjf/ZAL9P6SvjlC
# aBA2mutoorEgnzUP8HnOIcvMRgEMPmpaZ8egM93Bmx9d41xoarsQpCN3DhYOo+b3
# fWnPucVtpxbul2OFePv63mw/uvr+dqkv4b/f3Tg+ilQbpsNonbvh9MKEFv8Pn9ko
# j0ySV+qxz34PxTVAe6g//pel3/3i9fqilCnIEcx4zg/+NKBeOWROSs4oXo3IvBjV
# runmz+YuieSr78TqIE6hD8JF2q1wKwfMB3+x7dEXZAus9WtIU/qITATtEfO9QAgr
# rYL4F1MLN+osSp8my5eCOjnLTQc47q574V3zQhsIHW7yBXLdAgMBAAGjggGFMIIB
# gTAMBgNVHRMBAf8EAjAAMBMGA1UdJQQMMAoGCCsGAQUFBwMDMA4GA1UdDwEB/wQE
# AwIHgDA1BgNVHR8ELjAsMCqgKKAmhiRodHRwOi8vY3JsLmdvZGFkZHkuY29tL2dk
# aWcyczUtNS5jcmwwXQYDVR0gBFYwVDBIBgtghkgBhv1tAQcXAjA5MDcGCCsGAQUF
# BwIBFitodHRwOi8vY2VydGlmaWNhdGVzLmdvZGFkZHkuY29tL3JlcG9zaXRvcnkv
# MAgGBmeBDAEEATB2BggrBgEFBQcBAQRqMGgwJAYIKwYBBQUHMAGGGGh0dHA6Ly9v
# Y3NwLmdvZGFkZHkuY29tLzBABggrBgEFBQcwAoY0aHR0cDovL2NlcnRpZmljYXRl
# cy5nb2RhZGR5LmNvbS9yZXBvc2l0b3J5L2dkaWcyLmNydDAfBgNVHSMEGDAWgBRA
# wr0njsw0gzCiM9f7bLPwtCyAzjAdBgNVHQ4EFgQUUPnMg2nmYS8l7rmax3weVkrg
# z5AwDQYJKoZIhvcNAQELBQADggEBAIYabiARaY4KhO6oWgNHPOBjoHuqUH7NwRGN
# /ztYJznRBZbdD50smoK5GR0FvUZ8TXhYoZOazXe4NlFM4e6YcudU+EA/OF+sZHFB
# Wziz1VS6U3sS+cGyJcxvelSoid0q3W3i9/Zy6Nv2kk/DEJp49O47mPNovpL15yyk
# X3Vo26GwC9peo4s/cKMzthmgrcF2uLkT+LW44xKhaL7nBTGDMhjno+a3t00SWCId
# 7wzgQadIJ1QlFOKm0xgmuiW3LIqCG0apvaOfvWKTPKq68q+FbDPOO48oKrvw1c9K
# /m8gcnBLz6PX1REVIs5u3pvdOYBCz6uXyKxnt+Q5jDEK0NskLu0xggUJMIIFBQIB
# ATCBwTCBtDELMAkGA1UEBhMCVVMxEDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcT
# ClNjb3R0c2RhbGUxGjAYBgNVBAoTEUdvRGFkZHkuY29tLCBJbmMuMS0wKwYDVQQL
# EyRodHRwOi8vY2VydHMuZ29kYWRkeS5jb20vcmVwb3NpdG9yeS8xMzAxBgNVBAMT
# KkdvIERhZGR5IFNlY3VyZSBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMgIIN4yp
# TAQKR/QwCQYFKw4DAhoFAKB4MBgGCisGAQQBgjcCAQwxCjAIoAKAAKECgAAwGQYJ
# KoZIhvcNAQkDMQwGCisGAQQBgjcCAQQwHAYKKwYBBAGCNwIBCzEOMAwGCisGAQQB
# gjcCARUwIwYJKoZIhvcNAQkEMRYEFPocB2PwFl8dLSiQey6D3HSyeINxMA0GCSqG
# SIb3DQEBAQUABIIBANdp4957FN9DWX1uupMtGyoiLfMyK/b//iJLNlDP5QQKTQLo
# dTOrzgnCOCW+zN6B44/SPMxw3je35ykLhf4DzUrkXwCuTLFoN8uZRCjoAc/4ivwt
# CpQoCJ/o6yqmcnd081A63g2rkjhqWQrwI/Sn04qr/vYJ8r4z0boWMDL+9ZlitsEj
# rT2bHMi/F34S7Y7dpaPq8A6qPbPAp1nSxSUKVUHQFlyCIxQ8WegNUQxCOpYq1Y0k
# WEfvC5tvkwzhvkaC+UXLFyO/EawBGuh5uCxd7ViTyjb+GTy6Vsns34AAko6/cXnZ
# 8O9MOU69Pn6n2KIN0WkdgawkLVx6YVt4GZIpLlOhggKiMIICngYJKoZIhvcNAQkG
# MYICjzCCAosCAQEwaDBSMQswCQYDVQQGEwJCRTEZMBcGA1UEChMQR2xvYmFsU2ln
# biBudi1zYTEoMCYGA1UEAxMfR2xvYmFsU2lnbiBUaW1lc3RhbXBpbmcgQ0EgLSBH
# MgISESHWmadklz7x+EJ+6RnMU0EUMAkGBSsOAwIaBQCggf0wGAYJKoZIhvcNAQkD
# MQsGCSqGSIb3DQEHATAcBgkqhkiG9w0BCQUxDxcNMjAwNTE1MTQzNzM3WjAjBgkq
# hkiG9w0BCQQxFgQUKPIC18jFjSOY9HsF5qlvCYkxTpswgZ0GCyqGSIb3DQEJEAIM
# MYGNMIGKMIGHMIGEBBRjuC+rYfWDkJaVBQsAJJxQKTPseTBsMFakVDBSMQswCQYD
# VQQGEwJCRTEZMBcGA1UEChMQR2xvYmFsU2lnbiBudi1zYTEoMCYGA1UEAxMfR2xv
# YmFsU2lnbiBUaW1lc3RhbXBpbmcgQ0EgLSBHMgISESHWmadklz7x+EJ+6RnMU0EU
# MA0GCSqGSIb3DQEBAQUABIIBAEZJLqVL/wsenc5+7+kxJiaA7MR22Z+Y90sG8t4v
# bUreAlB4m05yLK/dmzE2Ivz53MSoz3uRveRuAadTSGDqDSOIIUzJZcA3kEZ9Yi+z
# Ax8TMzoXG6GFiDieAvrsWMQrVePaUYooL1I83BA6QMK2QIFd7dZ42DydToPMJIVH
# nNaGjzYndJVVG0W/4ZwOTS9IA8i8dH3j122dxOyA0+3oHVpr1yXtvZ5hcxctiQHm
# 3EMMXgmZkgU+U5lMomgG2QA6IhY78yM3VEz/VlagN5yLtb7hcx3hbv1xnXwztUs9
# gBkIZCXyOb7XeUJQaqIjB9HksoLaO3r5wqpHSqfP267C78w=
# SIG # End signature block