NetOwls.PSCommonFunctionSet.psm1

# -----------------------------------------------------------------------------------------------------
# FEATURE: 提供了自定义的 POWERSHELL 公共方法集。
# AUTHOR: WANG YUCAI
# CREATED TIME: 2018/11/23 9:56
# CODE FILE: NETOWLS.PSCOMMONFUNCTIONSET.PSM1
# E-MAIL ADDRESS: NETOWLS@OUTLOOK.COM
# COPYRIGHT © 2006 - 2018 WANG YUCAI. ALL RIGHTS RESERVED.
# -----------------------------------------------------------------------------------------------------

data LocalizationData
{
    ConvertFrom-StringData @'
        Default=Info
        Debug=Debug
        Trace=Trace
        Information=Info
        Warning=Warning
        Error=Error
        DateTimeFormatter=yyyy-MM-dd HH:mm:ss
        DefaultPrompt=Please choise.
'@

}

Import-LocalizedData LocalizationData -FileName "PSCommonFunctionSetResources" -ErrorAction Ignore

<#
    .SYNOPSIS
        用于在 PowerShell 控制台输出一行用于诊断的信息。
     
    .DESCRIPTION
        用于在 PowerShell 控制台输出一行用于诊断的信息。
     
    .PARAMETER Message
        需要输出的诊断信息。
     
    .PARAMETER OutFileRequired
        是否需要同时将诊断信息输出到文件。默认为 False。
     
    .PARAMETER Category
        诊断信息类别。默认 Default;即 Information。
#>

function Log-AnyCategory
{
    [OutputType([void])]
    param
    (
        [Parameter(Mandatory = $false,
                   ValueFromPipeline = $false,
                   ValueFromPipelineByPropertyName = $false,
                   Position = 0,
                   HelpMessage = '需要输出的诊断信息。')]
        [Alias('Msg')]
        [string]$Message,
        [Parameter(Mandatory = $false,
                   ValueFromPipeline = $false,
                   ValueFromPipelineByPropertyName = $false,
                   Position = 1,
                   HelpMessage = '是否需要同时将诊断信息输出到文件。默认为 False。')]
        [Alias('OutFile')]
        [bool]$OutFileRequired = $false,
        [Parameter(Mandatory = $false,
                   ValueFromPipeline = $false,
                   ValueFromPipelineByPropertyName = $false,
                   Position = 2,
                   HelpMessage = '诊断信息类别。默认 Default;即 Information。')]
        [ValidateSet('Default', 'Debug', 'Trace', 'Information', 'Warning', 'Error', IgnoreCase = $true)]
        [string]$Category = "Default"
    )
    
    $isNotEmpty = $true
    $outFilePath = "./pwsh-log-{0}.txt" -f (Get-Date -Format "yyMMdd-HH")
    
    if ([string]::IsNullOrWhiteSpace($Message))
    {
        $isNotEmpty = $false
    }
    if ($isNotEmpty)
    {
        $Message = "[{2}]: {0} <{1}>" -f $Message, (Get-Date -Format $LocalizationData.DateTimeFormatter), $LocalizationData[$Category]
    }
    if ($isNotEmpty)
    {
        switch ($Category)
        {
            "Debug" {
                Write-Host $Message -ForegroundColor Gray
            }
            "Trace" {
                Write-Host $Message -ForegroundColor DarkGray
            }
            "Warning" {
                Write-Host $Message -ForegroundColor Yellow
            }
            "Error" {
                Write-Host $Message -ForegroundColor DarkRed -BackgroundColor Yellow
            }
            default
            {
                Write-Host $Message
            }
        }
        
        if ($OutFileRequired)
        {
            Out-File -FilePath $outFilePath -Append -Encoding utf8 -InputObject $Message
        }
    }
}

<#
    .SYNOPSIS
        在 PowerShell 控制台中输出一行信息级的诊断信息。
     
    .DESCRIPTION
        在 PowerShell 控制台中输出一行信息级的诊断信息。
     
    .PARAMETER Message
        需要输出的信息。
     
    .PARAMETER OutFileRequired
        是否需要将诊断信息输出到文件。默认为 False。
#>

function Log-Information
{
    [CmdletBinding(HelpUri = 'https://github.com/NetOwls/PowerShell-ToolSet/blob/master/docs/Modules/PSCommonFunctionSet.md')]
    param
    (
        [Parameter(Mandatory = $false,
                   ValueFromPipeline = $true,
                   ValueFromPipelineByPropertyName = $true,
                   Position = 0,
                   HelpMessage = '需要输出的信息。')]
        [Alias('Info')]
        [string]$Message,
        [Parameter(Mandatory = $false,
                   ValueFromPipeline = $true,
                   ValueFromPipelineByPropertyName = $true,
                   Position = 1,
                   HelpMessage = '是否需要将诊断信息输出到文件。默认为 False。')]
        [Alias('OutFile')]
        [bool]$OutFileRequired = $false
    )
    
    Log-AnyCategory -Msg $Message -OutFile $OutFileRequired -Category Default
}
Export-ModuleMember -Function Log-Information
New-Alias -Name log-info -Value Log-Information
Export-ModuleMember -Alias log-info


<#
    .SYNOPSIS
        在 PowerShell 控制台中输出一行调试级的诊断信息。
     
    .DESCRIPTION
        在 PowerShell 控制台中输出一行调试级的诊断信息。
     
    .PARAMETER Message
        需要输出的信息。
     
    .NOTES
        Additional information about the function.
#>

function Log-Debug
{
    [CmdletBinding(HelpUri = 'https://github.com/NetOwls/PowerShell-ToolSet/blob/master/docs/Modules/PSCommonFunctionSet.md')]
    param
    (
        [Parameter(Mandatory = $false,
                   ValueFromPipeline = $true,
                   ValueFromPipelineByPropertyName = $true,
                   Position = 0,
                   HelpMessage = '需要输出的信息。')]
        [Alias('Info')]
        [string]$Message
    )
    
    Log-AnyCategory -Msg $Message -OutFileRequired $false -Category Debug
}
Export-ModuleMember -Function Log-Debug


<#
    .SYNOPSIS
        在 PowerShell 控制台中输出一行追踪级的诊断信息。
     
    .DESCRIPTION
        在 PowerShell 控制台中输出一行追踪级的诊断信息。
     
    .PARAMETER Message
        需要输出的信息。
     
    .NOTES
        Additional information about the function.
#>

function Log-Trace
{
    [CmdletBinding(HelpUri = 'https://github.com/NetOwls/PowerShell-ToolSet/blob/master/docs/Modules/PSCommonFunctionSet.md')]
    param
    (
        [Parameter(Mandatory = $false,
                   ValueFromPipeline = $true,
                   ValueFromPipelineByPropertyName = $true,
                   Position = 0,
                   HelpMessage = '需要输出的信息。')]
        [Alias('Info')]
        [string]$Message
    )
    
    Log-AnyCategory -Msg $Message -OutFileRequired $false -Category Trace
}
Export-ModuleMember -Function Log-Trace

<#
    .SYNOPSIS
        在 PowerShell 控制台中输出一行警告级诊断信息。
     
    .DESCRIPTION
        在 PowerShell 控制台中输出一行警告级诊断信息。
     
    .PARAMETER Message
        需要输出的信息。
     
    .PARAMETER OutFileRequired
        是否需要将诊断信息输出到文件。默认为 True。
#>

function Log-Warning
{
    [CmdletBinding(HelpUri = 'https://github.com/NetOwls/PowerShell-ToolSet/blob/master/docs/Modules/PSCommonFunctionSet.md')]
    param
    (
        [Parameter(Mandatory = $false,
                   ValueFromPipeline = $true,
                   ValueFromPipelineByPropertyName = $true,
                   Position = 0,
                   HelpMessage = '需要输出的信息。')]
        [Alias('Warn')]
        [string]$Message,
        [Parameter(Mandatory = $false,
                   ValueFromPipeline = $true,
                   ValueFromPipelineByPropertyName = $true,
                   Position = 1,
                   HelpMessage = '是否需要将诊断信息输出到文件。默认为 True。')]
        [Alias('OutFile')]
        [bool]$OutFileRequired = $true
    )
    
    Log-AnyCategory -Msg $Message -OutFile $OutFileRequired -Category Warning
}
Export-ModuleMember -Function Log-Warning

# Optional commands to create a public alias for the function
New-Alias -Name log-warn -Value Log-Warning
Export-ModuleMember -Alias log-warn

<#
    .SYNOPSIS
        在 PowerShell 控制台中输出一行异常、错误性的诊断信息。
     
    .DESCRIPTION
        在 PowerShell 控制台中输出一行异常、错误性的诊断信息。
     
    .PARAMETER Message
        需要输出的信息。
     
    .PARAMETER OutFileRequired
        是否需要将诊断信息输出的文件。默认为 True。
#>

function Log-Error
{
    [CmdletBinding(HelpUri = 'https://github.com/NetOwls/PowerShell-ToolSet/blob/master/docs/Modules/PSCommonFunctionSet.md')]
    param
    (
        [Parameter(Mandatory = $false,
                   ValueFromPipeline = $true,
                   ValueFromPipelineByPropertyName = $true,
                   Position = 0,
                   HelpMessage = '需要输出的信息。')]
        [Alias('Error')]
        [string]$Message,
        [Parameter(Mandatory = $false,
                   ValueFromPipeline = $true,
                   ValueFromPipelineByPropertyName = $true,
                   Position = 1,
                   HelpMessage = '是否需要将诊断信息输出的文件。默认为 True。')]
        [Alias('OutFile')]
        [bool]$OutFileRequired = $true
    )
    
    Log-AnyCategory -Msg $Message -OutFile $OutFileRequired -Category Error
}
Export-ModuleMember -Function Log-Error

<#
    .SYNOPSIS
        给出一组可选择的项提示。
     
    .DESCRIPTION
        给出一组可选择的项提示。
     
    .PARAMETER Prompt
        提示信息。
     
    .PARAMETER Options
        备选项数组。
     
    .PARAMETER DefaultOption
        默认选项值。默认为 0。
#>

function Prompt-ChoiseOptions
{
    [CmdletBinding(HelpUri = 'https://github.com/NetOwls/PowerShell-ToolSet/blob/master/docs/Modules/PSCommonFunctionSet.md')]
    [OutputType([int])]
    param
    (
        [Parameter(Mandatory = $false,
                   ValueFromPipeline = $true,
                   ValueFromPipelineByPropertyName = $true,
                   Position = 0,
                   HelpMessage = '提示信息。')]
        [Alias('Msg')]
        [System.String]$Prompt,
        [Parameter(Mandatory = $false,
                   ValueFromPipeline = $true,
                   ValueFromPipelineByPropertyName = $true,
                   Position = 1,
                   HelpMessage = '备选项数组。')]
        [Alias('Opts')]
        [string[]]$Options = $null,
        [Parameter(Mandatory = $false,
                   ValueFromPipeline = $true,
                   ValueFromPipelineByPropertyName = $true,
                   Position = 2,
                   HelpMessage = '默认选项值。默认为 0。')]
        [Alias('DefaultOpt')]
        [int]$DefaultOption = 0
    )
    
    $ChooseOptIdx = -1
    
    If (($Options -ne $null) -and ($Options.Length -gt 0))
    {
        If ([string]::IsNullOrWhiteSpace($Prompt))
        {
            $Prompt = $LocalizationData["DefaultPrompt"]
        }
        $UIPromptOptions = @()
        foreach ($item in $Options)
        {
            if (-not [string]::IsNullOrEmpty($item))
            {
                $UIPromptOptions += New-Object System.Management.Automation.Host.ChoiceDescription -ArgumentList $item
            }
        }
        
        $ChooseOptIdx = $Host.UI.PromptForChoice($LocalizationData.Info, $Prompt, [System.Management.Automation.Host.ChoiceDescription[]]$UIPromptOptions, $DefaultOption)
    }
    
    $ChooseOptIdx
}
Export-ModuleMember -Function Prompt-ChoiseOptions

# Optional commands to create a public alias for the function
New-Alias -Name prompt-choise -Value Prompt-ChoiseOptions
Export-ModuleMember -Alias prompt-choise


# SIG # Begin signature block
# MIIWFgYJKoZIhvcNAQcCoIIWBzCCFgMCAQExCzAJBgUrDgMCGgUAMGkGCisGAQQB
# gjcCAQSgWzBZMDQGCisGAQQBgjcCAR4wJgIDAQAABBAfzDtgWUsITrck0sYpfvNR
# AgEAAgEAAgEAAgEAAgEAMCEwCQYFKw4DAhoFAAQUL0iUplOuSSlrAK77jdcz0Bor
# 8Iyggg9bMIIEFDCCAvygAwIBAgILBAAAAAABL07hUtcwDQYJKoZIhvcNAQEFBQAw
# 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
# BJ8wggOHoAMCAQICEhEh1pmnZJc+8fhCfukZzFNBFDANBgkqhkiG9w0BAQUFADBS
# MQswCQYDVQQGEwJCRTEZMBcGA1UEChMQR2xvYmFsU2lnbiBudi1zYTEoMCYGA1UE
# AxMfR2xvYmFsU2lnbiBUaW1lc3RhbXBpbmcgQ0EgLSBHMjAeFw0xNjA1MjQwMDAw
# MDBaFw0yNzA2MjQwMDAwMDBaMGAxCzAJBgNVBAYTAlNHMR8wHQYDVQQKExZHTU8g
# R2xvYmFsU2lnbiBQdGUgTHRkMTAwLgYDVQQDEydHbG9iYWxTaWduIFRTQSBmb3Ig
# TVMgQXV0aGVudGljb2RlIC0gRzIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK
# AoIBAQCwF66i07YEMFYeWA+x7VWk1lTL2PZzOuxdXqsl/Tal+oTDYUDFRrVZUjtC
# oi5fE2IQqVvmc9aSJbF9I+MGs4c6DkPw1wCJU6IRMVIobl1AcjzyCXenSZKX1GyQ
# oHan/bjcs53yB2AsT1iYAGvTFVTg+t3/gCxfGKaY/9Sr7KFFWbIub2Jd4NkZrItX
# nKgmK9kXpRDSRwgacCwzi39ogCq1oV1r3Y0CAikDqnw3u7spTj1Tk7Om+o/SWJMV
# TLktq4CjoyX7r/cIZLB6RA9cENdfYTeqTmvT0lMlnYJz+iz5crCpGTkqUPqp0Dw6
# yuhb7/VfUfT5CtmXNd5qheYjBEKvAgMBAAGjggFfMIIBWzAOBgNVHQ8BAf8EBAMC
# B4AwTAYDVR0gBEUwQzBBBgkrBgEEAaAyAR4wNDAyBggrBgEFBQcCARYmaHR0cHM6
# Ly93d3cuZ2xvYmFsc2lnbi5jb20vcmVwb3NpdG9yeS8wCQYDVR0TBAIwADAWBgNV
# HSUBAf8EDDAKBggrBgEFBQcDCDBCBgNVHR8EOzA5MDegNaAzhjFodHRwOi8vY3Js
# Lmdsb2JhbHNpZ24uY29tL2dzL2dzdGltZXN0YW1waW5nZzIuY3JsMFQGCCsGAQUF
# BwEBBEgwRjBEBggrBgEFBQcwAoY4aHR0cDovL3NlY3VyZS5nbG9iYWxzaWduLmNv
# bS9jYWNlcnQvZ3N0aW1lc3RhbXBpbmdnMi5jcnQwHQYDVR0OBBYEFNSihEo4Whh/
# uk8wUL2d1XqH1gn3MB8GA1UdIwQYMBaAFEbYPv/c477/g+b0hZuw3WrWFKnBMA0G
# CSqGSIb3DQEBBQUAA4IBAQCPqRqRbQSmNyAOg5beI9Nrbh9u3WQ9aCEitfhHNmmO
# 4aVFxySiIrcpCcxUWq7GvM1jjrM9UEjltMyuzZKNniiLE0oRqr2j79OyNvy0oXK/
# bZdjeYxEvHAvfvO83YJTqxr26/ocl7y2N5ykHDC8q7wtRzbfkiAD6HHGWPZ1BZo0
# 8AtZWoJENKqA5C+E9kddlsm2ysqdt6a65FDT1De4uiAO0NOSKlvEWbuhbds8zkSd
# wTgqreONvc0JdxoQvmcKAjZkiLmzGybu555gxEaovGEzbM9OuZy5avCfN/61PU+a
# 003/3iCOTpem/Z8JvE3KGHbJsE2FUPKA0h0G9VgEB7EYMIIGnDCCBISgAwIBAgIB
# bzANBgkqhkiG9w0BAQ0FADCB1zELMAkGA1UEBhMCQ0gxEDAOBgNVBAgTB0JlaWpp
# bmcxEDAOBgNVBAcTB0hhaWRpYW4xETAPBgNVBAoTCFBlcnNvbmFsMRIwEAYDVQQL
# EwlXYW5nWXVjYWkxIjAgBgkqhkiG9w0BCQEWE05ldE93bHNAb3V0bG9vay5jb20x
# GzAZBgNVBAUTEjExMDIyMTE5ODMwOTE1ODMxMTEXMBUGA1UEDBMOLk5FVCBEZXZl
# bG9wZXIxDjAMBgNVBAQTBVl1Y2FpMRMwEQYDVQQpEwpXYW5nIFl1Y2FpMB4XDTE4
# MDkxNDA1MjEwMFoXDTIwMDkxNDA1MjEwMFowgdcxCzAJBgNVBAYTAkNIMRAwDgYD
# VQQIEwdCZWlqaW5nMRAwDgYDVQQHEwdIYWlkaWFuMREwDwYDVQQKEwhQZXJzb25h
# bDESMBAGA1UECxMJV2FuZ1l1Y2FpMSIwIAYJKoZIhvcNAQkBFhNOZXRPd2xzQG91
# dGxvb2suY29tMRswGQYDVQQFExIxMTAyMjExOTgzMDkxNTgzMTExFzAVBgNVBAwT
# Di5ORVQgRGV2ZWxvcGVyMQ4wDAYDVQQEEwVZdWNhaTETMBEGA1UEKRMKV2FuZyBZ
# dWNhaTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMIZsqv4W1xxyimF
# 3Rs3a7gbo38NktB59MJAPUDFezw+hCvVr6jZNW2sMKq/lZNScVSKEOPAPHFAq2Db
# hUcThdmwzexyD0T1VwDZwtpetibUZ34LWjdDLmoYOmLbd9M//x9tkoE4sEaT/DBq
# mbS6YWWLsWmWvpGyYNFv5pWM+p2mMULlPwX5SSY/rbgCwLcWknQQFl6ZOCmp0JW1
# ozxpwEv6iF75gfIL69CXZRKdjf1wmMC2hlAKfPSm1kGcXzce1CVowAqj0Pc2wa1I
# cXz+z/CcGt0TuIcKkmtHxJDbBPZTfkGI/Emkva/mtHUPTZaTM9yfD1uBUJaMb/xE
# RLg5TdxdkzWjfCc7n1ZGSmedg6UWJQVLywU+tBuO4ggR7iIpEA3z7YjrlkIS2xPn
# UXoWQs1okqJBpemeNMG1suc4gS3pHObtbsR+avjM2bNN2xTOzWYi4OyegS0rpVDp
# vEGMSAtQXe9j10W9CHxZhrOcBdRzwcpdMT34MjG7p9cxDmbsA/K0YsAQmroPfQ1b
# BaD5CCpo+xsbipI5NPPxPIr079bmJBIeAQQX29waMRVfoHiP4zsdq6f5YQ0FVXnb
# cIsUJtDZvZWGB5NlNeva22F+9AAnTCWolz6X/D9bO3963Yd9g484InnmJmjqmaow
# H7gKZ7ZNu4qh6MW9fnIa85G2BLZJAgMBAAGjcTBvMAwGA1UdEwQFMAMBAf8wDwYD
# VR0PAQH/BAUDAwcBgDAuBgNVHSUBAf8EJDAiBggrBgEFBQcDAwYKKwYBBAGCNwIB
# FQYKKwYBBAGCNwIBFjAeBglghkgBhvhCAQ0EERYPeGNhIGNlcnRpZmljYXRlMA0G
# CSqGSIb3DQEBDQUAA4ICAQCzJcuYq20ELsCgWQF4O3YHrltZ+2jzFySNhHgd1D/l
# S+s//aNztHqiUXgTMCOHnKN8vl60mUMloPDP6mb0fgUPZxM4L6T1aiuH63kvHXLZ
# 5VMdJ6L1l0qu2hXUyP7y0ap3tlgM6NyYwkUWTeKydYNZQZg7lJ9D1BBEoaGj95WM
# Cs9sAm9eX53ZX5eJOuhhjUAU2lqY9cTUqTq2FHwSpzqJ/KoOA2bg9d/Zr1lZU18Z
# ASN+PND34Ri+EPRFuKPWdXomt1YLMewuEJ/C4IOvjxbKMbCERG/UAvJz+TZfOqrn
# Dqn4O52y+iVPnWxalolU2b1VWzq35tGvJKO8SWMxvDtr39lUauxmdZ3xc1Sbp80O
# xa2Bzb10mr0a8YzL8pGTq9fBxV/6A8OPdJVKqw+vgwRofT0cYkh4O3YwNxawdGqS
# mrpTefIg8PGOLqlPquUVjvgiYNTo8m3chzaFAuVP92o/QlUX+CEr+fvjgU+wxjJX
# w8rhPXpdz9nGRuq1+6FFFggK+Lid5uTVP4BwKaxSy+4Zmir6LZUOVk7GmkDor8Jp
# oxgpV4dkI6E/063g1Ti2yjNxyG8IFhHPwH5asNkMDeeJcbHJdxVniO/7BlghtLgF
# uQp5IZeEe0kBuLmsm41+RaeRWzdCHJyuAb4q15SpB6VMby1AEicb/ju2VGN9CJXo
# HDGCBiUwggYhAgEBMIHdMIHXMQswCQYDVQQGEwJDSDEQMA4GA1UECBMHQmVpamlu
# ZzEQMA4GA1UEBxMHSGFpZGlhbjERMA8GA1UEChMIUGVyc29uYWwxEjAQBgNVBAsT
# CVdhbmdZdWNhaTEiMCAGCSqGSIb3DQEJARYTTmV0T3dsc0BvdXRsb29rLmNvbTEb
# MBkGA1UEBRMSMTEwMjIxMTk4MzA5MTU4MzExMRcwFQYDVQQMEw4uTkVUIERldmVs
# b3BlcjEOMAwGA1UEBBMFWXVjYWkxEzARBgNVBCkTCldhbmcgWXVjYWkCAW8wCQYF
# Kw4DAhoFAKB4MBgGCisGAQQBgjcCAQwxCjAIoAKAAKECgAAwGQYJKoZIhvcNAQkD
# MQwGCisGAQQBgjcCAQQwHAYKKwYBBAGCNwIBCzEOMAwGCisGAQQBgjcCARYwIwYJ
# KoZIhvcNAQkEMRYEFO6ERpppfHtXezR4+xhlu4zLZ8kXMA0GCSqGSIb3DQEBAQUA
# BIICAL9RpFu3Ts+VmlVPWMvn4+TN1AGyEiXdu4KCfrKvZ7OSQVmph/ArKhgO/Az+
# gtM59C2Mo2Owpd+dsiGgMvR7vFtKZB31HdNYasnMjgnopIF2nqh3CA5LvQOsBjYv
# cLNYeZWjTkyA8dR2eJ/V92pEWWX+fj4KCHWAQ098RYjAwfB0kxMmQD+fZ9k5DoXQ
# uaccAvcreaR9GtfQV4F6H1MlhiiEo8nO5K0XNBueHQ29RVTZIKZxEMMGij8WDFao
# /2xZIcpFaGjUkUIRQDX2ntyW6OcWZ26Jur2CeoUCc59KXhc4SyjxvqVVfcOFj3bT
# L0P75LjdXKqT06XP0fAhf4qtQS39Bz1yyQHlTH5lrGzwZ/AYqAS2V2YYRgPUjaOd
# M0ffE28hW4QXoryOWTv+h/G/kKSgLgdejIwIQhizNDiaoXb5Ts+gURdsP14Uv+x7
# 7nIfjBb3EzLeFUW/xHyi+G2/fLz13siqRpCa4t5fi3IHtkfARM4Owm1onvOvNVWb
# Jl8goWd/QkgFDj6llsMpFBEnM5CpVqGmvAe08Ph9cgOQiU80OB2/SabgtZBwP5NB
# PHDGq6DasZ+VjXogQPsiIqv46P5MxBHsBuHY8amcLZBiroeITlYWCpH/TwAJAUcB
# QXLACBknAuI0UoVQGWywNXkqI3bgCj5/OkmACS7AUV8ahLrIoYICojCCAp4GCSqG
# SIb3DQEJBjGCAo8wggKLAgEBMGgwUjELMAkGA1UEBhMCQkUxGTAXBgNVBAoTEEds
# b2JhbFNpZ24gbnYtc2ExKDAmBgNVBAMTH0dsb2JhbFNpZ24gVGltZXN0YW1waW5n
# IENBIC0gRzICEhEh1pmnZJc+8fhCfukZzFNBFDAJBgUrDgMCGgUAoIH9MBgGCSqG
# SIb3DQEJAzELBgkqhkiG9w0BBwEwHAYJKoZIhvcNAQkFMQ8XDTE4MTEyNjAyMTYy
# NFowIwYJKoZIhvcNAQkEMRYEFEM6DB9TM/iFq7p1LAF6PJirAPYeMIGdBgsqhkiG
# 9w0BCRACDDGBjTCBijCBhzCBhAQUY7gvq2H1g5CWlQULACScUCkz7HkwbDBWpFQw
# UjELMAkGA1UEBhMCQkUxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExKDAmBgNV
# BAMTH0dsb2JhbFNpZ24gVGltZXN0YW1waW5nIENBIC0gRzICEhEh1pmnZJc+8fhC
# fukZzFNBFDANBgkqhkiG9w0BAQEFAASCAQBbOczMpVqPJWlVIAy27en0kPbl+wbK
# Ooxe28xbQV2dLXp0Q4NMbzJBpzEZYv/FIuOxwGmDdpCxmnu0UIVmacddRpQt+nNS
# gMor0Hif4TmJ7zmbPPJs4FQ2dq2dHYLcTLjXOBaebUCwCMtJxXZixuzoaFWHKuuc
# Nmcm2JF/hpGoE7Ynle2czpdejiJuH4jVhVPT/kOcvsMvWjflP+Ut/VVGLXPoJ072
# EKqzYb0Fer+EA+yaL+WvfDRV8eCUZbNWHGWwWwuzsLLdvsxQvrshcTlvBXfH99Lm
# heNtg/D8f/src3sUPnoT339RhNRKSzgBHgYdtbZQgpHoYcmzzy9U4Ssr
# SIG # End signature block