OfflinePowerShellGetSetup.psm1

# Requires -RunAsAdministrator
Function Save-PowerShellGetForOffline {
    <#
.SYNOPSIS
    Acquire PowerShellGet and related modules for offline use
.DESCRIPTION
    This function acquires all the items needed to do a disconnnected setup of PowerShellGet, PackageManagement, and Nuget.exe.
    The resultant folders are prepped to be deployed directly to target devices using Install-PowerShellGetOffline
    This module currently only supports Windows PowerShell.
     
    The script sequence assumes that you are installing everything as though these steps were performed by an administrator.
    One implication is that you must run the script as admin, which will ensure that the modules work for all users.
    For details on how to do this for non-admin users, review the documentation at:
    https://docs.microsoft.com/en-us/powershell/gallery/psget/repository/bootstrapping_nuget_proivder_and_exe
 
.EXAMPLE
     
    PS C:\> Save-PowerShellGetForOffline -LocalFolder c:\temp\PowerShellGetStuff
     
.PARAMETER LocalFolder
    Required, is the path to a folder where PowerShellGet, Package Management, and NuGet.Exe will be placed.
.PARAMETER NuGetSource
    Optional, is the path to NuGetv2.exe, which is accessible from the system where this is executed
 
#>
    
   

    [CmdletBinding()]
    Param (
        # Need a local folder to store things in, temporarily
        [Parameter(Mandatory = $true)]
        [string] $LocalFolder,
  

        [Parameter(Mandatory = $false)]
        [string] $NuGetSource = "https://dist.nuget.org/win-x86-commandline/latest/nuget.exe"
    )
    
    <#
        Validate the folder exists.
        If not, create it.
        If not possible, error.
    #>



    If (-not (test-path -path $LocalFolder)) {
        write-verbose "Creating folder $LocalFolder"
        new-item $LocalFolder -itemtype Directory
    }
    
    
    <#
        Acquire NuGet.exe and place it on the local system.
 
        NOTE that this step is ONLY needed to publish items to the "repository" you will use for your offline systems.
        It is not needed for systems where you are only acquiring things from the local repository.
    #>

    
    write-verbose "Acquiring Nuget.exe"
    $destination = Join-path (Resolve-Path $LocalFolder) 'nuget.exe'
    $wc = New-Object system.net.webclient
    $wc.downloadFile($NuGetSource, $destination)
     
    <#
        Save the current PackageManagement and PowerShellGet modules to the current folder
    #>

    write-verbose "Saving Packagemanagement module locally"
    Save-Module PackageManagement -Repository psgallery -path $LocalFolder 
    
    write-verbose "Saving PowerShellGet module locally"
    Save-Module PowerShellGet -Repository PsGallery -path $LocalFolder 
    
    <#
        Unblock the files just acquired from the web
    #>

    Get-ChildItem -Path $LocalFolder -recurse | Unblock-File
    
    <#
        Delete the PSGetModuleInfo.xml file from each module folder.
        This file is created during save-module, but if it is present, test-filecatalog for these modules will fail.
    #>

    
    Get-ChildItem -Path $LocalFolder -Filter psgetmoduleinfo.xml -force -Recurse | Remove-Item -force -Verbose
    
    <#
        The contents of this folder may now be copied to a file share for use with the script OfflinePowerShellGetSetup.ps1
    #>

}


Function Install-PowerShellGetOffline {
    <#
.SYNOPSIS
    Install PowerShellGet and related modules to a disconnected system
.DESCRIPTION
    This performs the steps needed for internet-disconnected systems to use PowerShellGet
    It takes a path (folder name) that has a copy of
        NuGet.Exe and
        The PowerShellGet module, unpacked and
        The PackageManagement modules, unpacked
     
    This will copy the PowerShellGet components from the LocalFolder into the proper locations for the local machine
 
    The script assumes that the installation will be done as an administrator on the target device, so that all users can use PowerShellGet after this.
    To find details on how to change the scope to the current user, see the documentation
.EXAMPLE
     
    PS C:\> Install-PowerShellGetOffline -LocalFolder \\testshare\temp\PowerShellGetStuff
     
.PARAMETER LocalFolder
    Required, is the path to a folder where PowerShellGet, Package Management, and NuGet.Exe have been placed using Save-PowerShellGetForOffline.
 
#>
    
   

[CmdletBinding()]

    Param (
        # Local folder containing NuGet, PackageManagement, and PowerShellGet
        [Parameter(Mandatory = $true)]
        [string] $LocalFolder = "C:\temp\demo"        
    )

    <#
    Confirm the LocalFolder has something resembling Nuget & the 2 modules
#>


    If ((-not(get-item $LocalFolder\nuget.exe)) -or (-not (get-item $LocalFolder\packagemanagement)) -or (-not (get-item $LocalFolder\powershellget))) {
        Throw "Error: The local folder must contain nuget.exe, the PackageManagement module, and the PowerShellGet module"
    }



    <#
 
    NuGet.exe is only required on systems used to publish to a PowerShellGet repository.
 
    Put NuGet.exe in the required location for the local system.
    Create the folder for Nuget.exe, if necessary
#>


    If (-not (Test-Path -Path "$env:ProgramData\Microsoft\Windows\PowerShell\PowerShellGet")) {

        New-Item "$env:ProgramData\Microsoft\Windows\PowerShell\PowerShellGet" -itemtype directory

    }

    
    If (-not (Test-Path -Path "$env:ProgramData\Microsoft\Windows\PowerShell\packagemanagement")) {

        New-Item "$env:ProgramData\Microsoft\Windows\PowerShell\PackageManagement" -itemtype directory

    }

    Copy-Item -Path @"
$($LocalFolder)\Nuget.exe
"@
 -Destination "$env:ProgramData\Microsoft\Windows\PowerShell\PowerShellGet"

    <#
 
    Copy the module folders for PackageManagement and PowerShellGet to the default installation location
    This script assumes that the current user is an administrator, to support copying to ProgramFiles.
     
#>


    Copy-Item -Path @"
$($LocalFolder)\PackageManagement\*.*
"@
 `
        -Recurse `
        -Destination "$env:ProgramFiles\WindowsPowerShell\modules\PackageManagement\" `
        -Force

    Copy-Item -Path @"
$($LocalFolder)\PowerShellGet\*.*
"@
 `
        -Recurse `
        -Destination "$env:ProgramFiles\WindowsPowerShell\modules\PowerShellGet\" `
        -Force

}


# SIG # Begin signature block
# MIIdoAYJKoZIhvcNAQcCoIIdkTCCHY0CAQExCzAJBgUrDgMCGgUAMGkGCisGAQQB
# gjcCAQSgWzBZMDQGCisGAQQBgjcCAR4wJgIDAQAABBAfzDtgWUsITrck0sYpfvNR
# AgEAAgEAAgEAAgEAAgEAMCEwCQYFKw4DAhoFAAQUIMPe0jZ7YdGR87w9XIIvfacQ
# mtugghhuMIIE3jCCA8agAwIBAgITMwAAAP3H8MlqaaHITAAAAAAA/TANBgkqhkiG
# 9w0BAQUFADB3MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4G
# A1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSEw
# HwYDVQQDExhNaWNyb3NvZnQgVGltZS1TdGFtcCBQQ0EwHhcNMTgwODIzMjAyMDEx
# WhcNMTkxMTIzMjAyMDExWjCBzjELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hp
# bmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jw
# b3JhdGlvbjEpMCcGA1UECxMgTWljcm9zb2Z0IE9wZXJhdGlvbnMgUHVlcnRvIFJp
# Y28xJjAkBgNVBAsTHVRoYWxlcyBUU1MgRVNOOjU4NDctRjc2MS00RjcwMSUwIwYD
# VQQDExxNaWNyb3NvZnQgVGltZS1TdGFtcCBTZXJ2aWNlMIIBIjANBgkqhkiG9w0B
# AQEFAAOCAQ8AMIIBCgKCAQEAugmBPajBpzY0ZHXjUDiC9AfAkIV0Ha8AtmxzF9Jl
# V8sCiW6p+ICqQqBMZrPJP+ZpkhPZhYh5Ht7GgatuRrQCri7ofVWq7zTrUAuw2KMx
# PAMM3WCRR/EzDiJbM3szZuINNP7x1iRViw3a/k4hhsmrg8fxA99YfH/jJZTG2dyh
# VKQpKCniPj0UJBfn7NHr3pGsz9baz1/GLfcauWULHRrF5oX6KuLRRaTW0a2XncHe
# DWhb51jOGf0FPKJy9C3BZOnI1sBSt+F/3ktGWxB1X1VMOdlGUnTp7MPla3lX8Eyj
# TEHFfDHopomafcuVGywZrO2D3bYASSmgWdm4zPDJ3/OR8wIDAQABo4IBCTCCAQUw
# HQYDVR0OBBYEFCz7qm2AX+EztWS4EhA0Q9v96Q7YMB8GA1UdIwQYMBaAFCM0+NlS
# RnAK7UD7dvuzK7DDNbMPMFQGA1UdHwRNMEswSaBHoEWGQ2h0dHA6Ly9jcmwubWlj
# cm9zb2Z0LmNvbS9wa2kvY3JsL3Byb2R1Y3RzL01pY3Jvc29mdFRpbWVTdGFtcFBD
# QS5jcmwwWAYIKwYBBQUHAQEETDBKMEgGCCsGAQUFBzAChjxodHRwOi8vd3d3Lm1p
# Y3Jvc29mdC5jb20vcGtpL2NlcnRzL01pY3Jvc29mdFRpbWVTdGFtcFBDQS5jcnQw
# EwYDVR0lBAwwCgYIKwYBBQUHAwgwDQYJKoZIhvcNAQEFBQADggEBAE9ar13BCEvN
# IdYrQaKP/I2CllhWlBlgHzchX7N8UPIEQA1LwYo6SQNL7RY8oTmSaRqd7/EEUeUv
# ubwpmq3b065FKeikFnD3B1ynMJkQR7exsn6nJN+CGeBwff7T0GPTjqtrzYuZO1ZM
# 5/MjJVRNdg9l2lM0X3XtYXXyIC04fCprvomiAoAMPgK3q5khoQNldzjj+u61cEo+
# 04bcXaIRs9qw15f42XWsMcN6EWtJImEYAbTV0iYt+KC1ZG5aSls6ytrEML56uN9K
# iqeXz7hUSzw/YlPyhjTOCZX+/JMhwMmkBC/ZPbCqJ9ZGK4ZGzWsM99+tUK2ZuOl8
# 5tTL0CTU1Y8wggX/MIID56ADAgECAhMzAAABA14lHJkfox64AAAAAAEDMA0GCSqG
# SIb3DQEBCwUAMH4xCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAw
# DgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24x
# KDAmBgNVBAMTH01pY3Jvc29mdCBDb2RlIFNpZ25pbmcgUENBIDIwMTEwHhcNMTgw
# NzEyMjAwODQ4WhcNMTkwNzI2MjAwODQ4WjB0MQswCQYDVQQGEwJVUzETMBEGA1UE
# CBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9z
# b2Z0IENvcnBvcmF0aW9uMR4wHAYDVQQDExVNaWNyb3NvZnQgQ29ycG9yYXRpb24w
# ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDRlHY25oarNv5p+UZ8i4hQ
# y5Bwf7BVqSQdfjnnBZ8PrHuXss5zCvvUmyRcFrU53Rt+M2wR/Dsm85iqXVNrqsPs
# E7jS789Xf8xly69NLjKxVitONAeJ/mkhvT5E+94SnYW/fHaGfXKxdpth5opkTEbO
# ttU6jHeTd2chnLZaBl5HhvU80QnKDT3NsumhUHjRhIjiATwi/K+WCMxdmcDt66Va
# mJL1yEBOanOv3uN0etNfRpe84mcod5mswQ4xFo8ADwH+S15UD8rEZT8K46NG2/Ys
# AzoZvmgFFpzmfzS/p4eNZTkmyWPU78XdvSX+/Sj0NIZ5rCrVXzCRO+QUauuxygQj
# AgMBAAGjggF+MIIBejAfBgNVHSUEGDAWBgorBgEEAYI3TAgBBggrBgEFBQcDAzAd
# BgNVHQ4EFgQUR77Ay+GmP/1l1jjyA123r3f3QP8wUAYDVR0RBEkwR6RFMEMxKTAn
# BgNVBAsTIE1pY3Jvc29mdCBPcGVyYXRpb25zIFB1ZXJ0byBSaWNvMRYwFAYDVQQF
# Ew0yMzAwMTIrNDM3OTY1MB8GA1UdIwQYMBaAFEhuZOVQBdOCqhc3NyK1bajKdQKV
# MFQGA1UdHwRNMEswSaBHoEWGQ2h0dHA6Ly93d3cubWljcm9zb2Z0LmNvbS9wa2lv
# cHMvY3JsL01pY0NvZFNpZ1BDQTIwMTFfMjAxMS0wNy0wOC5jcmwwYQYIKwYBBQUH
# AQEEVTBTMFEGCCsGAQUFBzAChkVodHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtp
# b3BzL2NlcnRzL01pY0NvZFNpZ1BDQTIwMTFfMjAxMS0wNy0wOC5jcnQwDAYDVR0T
# AQH/BAIwADANBgkqhkiG9w0BAQsFAAOCAgEAn/XJUw0/DSbsokTYDdGfY5YGSz8e
# XMUzo6TDbK8fwAG662XsnjMQD6esW9S9kGEX5zHnwya0rPUn00iThoj+EjWRZCLR
# ay07qCwVlCnSN5bmNf8MzsgGFhaeJLHiOfluDnjYDBu2KWAndjQkm925l3XLATut
# ghIWIoCJFYS7mFAgsBcmhkmvzn1FFUM0ls+BXBgs1JPyZ6vic8g9o838Mh5gHOmw
# GzD7LLsHLpaEk0UoVFzNlv2g24HYtjDKQ7HzSMCyRhxdXnYqWJ/U7vL0+khMtWGL
# sIxB6aq4nZD0/2pCD7k+6Q7slPyNgLt44yOneFuybR/5WcF9ttE5yXnggxxgCto9
# sNHtNr9FB+kbNm7lPTsFA6fUpyUSj+Z2oxOzRVpDMYLa2ISuubAfdfX2HX1RETcn
# 6LU1hHH3V6qu+olxyZjSnlpkdr6Mw30VapHxFPTy2TUxuNty+rR1yIibar+YRcdm
# stf/zpKQdeTr5obSyBvbJ8BblW9Jb1hdaSreU0v46Mp79mwV+QMZDxGFqk+av6pX
# 3WDG9XEg9FGomsrp0es0Rz11+iLsVT9qGTlrEOlaP470I3gwsvKmOMs1jaqYWSRA
# uDpnpAdfoP7YO0kT+wzh7Qttg1DO8H8+4NkI6IwhSkHC3uuOW+4Dwx1ubuZUNWZn
# cnwa6lL2IsRyP64wggYHMIID76ADAgECAgphFmg0AAAAAAAcMA0GCSqGSIb3DQEB
# BQUAMF8xEzARBgoJkiaJk/IsZAEZFgNjb20xGTAXBgoJkiaJk/IsZAEZFgltaWNy
# b3NvZnQxLTArBgNVBAMTJE1pY3Jvc29mdCBSb290IENlcnRpZmljYXRlIEF1dGhv
# cml0eTAeFw0wNzA0MDMxMjUzMDlaFw0yMTA0MDMxMzAzMDlaMHcxCzAJBgNVBAYT
# AlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYD
# VQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xITAfBgNVBAMTGE1pY3Jvc29mdCBU
# aW1lLVN0YW1wIFBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJ+h
# bLHf20iSKnxrLhnhveLjxZlRI1Ctzt0YTiQP7tGn0UytdDAgEesH1VSVFUmUG0KS
# rphcMCbaAGvoe73siQcP9w4EmPCJzB/LMySHnfL0Zxws/HvniB3q506jocEjU8qN
# +kXPCdBer9CwQgSi+aZsk2fXKNxGU7CG0OUoRi4nrIZPVVIM5AMs+2qQkDBuh/NZ
# MJ36ftaXs+ghl3740hPzCLdTbVK0RZCfSABKR2YRJylmqJfk0waBSqL5hKcRRxQJ
# gp+E7VV4/gGaHVAIhQAQMEbtt94jRrvELVSfrx54QTF3zJvfO4OToWECtR0Nsfz3
# m7IBziJLVP/5BcPCIAsCAwEAAaOCAaswggGnMA8GA1UdEwEB/wQFMAMBAf8wHQYD
# VR0OBBYEFCM0+NlSRnAK7UD7dvuzK7DDNbMPMAsGA1UdDwQEAwIBhjAQBgkrBgEE
# AYI3FQEEAwIBADCBmAYDVR0jBIGQMIGNgBQOrIJgQFYnl+UlE/wq4QpTlVnkpKFj
# pGEwXzETMBEGCgmSJomT8ixkARkWA2NvbTEZMBcGCgmSJomT8ixkARkWCW1pY3Jv
# c29mdDEtMCsGA1UEAxMkTWljcm9zb2Z0IFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9y
# aXR5ghB5rRahSqClrUxzWPQHEy5lMFAGA1UdHwRJMEcwRaBDoEGGP2h0dHA6Ly9j
# cmwubWljcm9zb2Z0LmNvbS9wa2kvY3JsL3Byb2R1Y3RzL21pY3Jvc29mdHJvb3Rj
# ZXJ0LmNybDBUBggrBgEFBQcBAQRIMEYwRAYIKwYBBQUHMAKGOGh0dHA6Ly93d3cu
# bWljcm9zb2Z0LmNvbS9wa2kvY2VydHMvTWljcm9zb2Z0Um9vdENlcnQuY3J0MBMG
# A1UdJQQMMAoGCCsGAQUFBwMIMA0GCSqGSIb3DQEBBQUAA4ICAQAQl4rDXANENt3p
# tK132855UU0BsS50cVttDBOrzr57j7gu1BKijG1iuFcCy04gE1CZ3XpA4le7r1ia
# HOEdAYasu3jyi9DsOwHu4r6PCgXIjUji8FMV3U+rkuTnjWrVgMHmlPIGL4UD6ZEq
# JCJw+/b85HiZLg33B+JwvBhOnY5rCnKVuKE5nGctxVEO6mJcPxaYiyA/4gcaMvnM
# MUp2MT0rcgvI6nA9/4UKE9/CCmGO8Ne4F+tOi3/FNSteo7/rvH0LQnvUU3Ih7jDK
# u3hlXFsBFwoUDtLaFJj1PLlmWLMtL+f5hYbMUVbonXCUbKw5TNT2eb+qGHpiKe+i
# myk0BncaYsk9Hm0fgvALxyy7z0Oz5fnsfbXjpKh0NbhOxXEjEiZ2CzxSjHFaRkMU
# vLOzsE1nyJ9C/4B5IYCeFTBm6EISXhrIniIh0EPpK+m79EjMLNTYMoBMJipIJF9a
# 6lbvpt6Znco6b72BJ3QGEe52Ib+bgsEnVLaxaj2JoXZhtG6hE6a/qkfwEm/9ijJs
# sv7fUciMI8lmvZ0dhxJkAj0tr1mPuOQh5bWwymO0eFQF1EEuUKyUsKV4q7OglnUa
# 2ZKHE3UiLzKoCG6gW4wlv6DvhMoh1useT8ma7kng9wFlb4kLfchpyOZu6qeXzjEp
# /w7FW1zYTRuh2Povnj8uVRZryROj/TCCB3owggVioAMCAQICCmEOkNIAAAAAAAMw
# DQYJKoZIhvcNAQELBQAwgYgxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5n
# dG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9y
# YXRpb24xMjAwBgNVBAMTKU1pY3Jvc29mdCBSb290IENlcnRpZmljYXRlIEF1dGhv
# cml0eSAyMDExMB4XDTExMDcwODIwNTkwOVoXDTI2MDcwODIxMDkwOVowfjELMAkG
# A1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQx
# HjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEoMCYGA1UEAxMfTWljcm9z
# b2Z0IENvZGUgU2lnbmluZyBQQ0EgMjAxMTCCAiIwDQYJKoZIhvcNAQEBBQADggIP
# ADCCAgoCggIBAKvw+nIQHC6t2G6qghBNNLrytlghn0IbKmvpWlCquAY4GgRJun/D
# DB7dN2vGEtgL8DjCmQawyDnVARQxQtOJDXlkh36UYCRsr55JnOloXtLfm1OyCizD
# r9mpK656Ca/XllnKYBoF6WZ26DJSJhIv56sIUM+zRLdd2MQuA3WraPPLbfM6XKEW
# 9Ea64DhkrG5kNXimoGMPLdNAk/jj3gcN1Vx5pUkp5w2+oBN3vpQ97/vjK1oQH01W
# KKJ6cuASOrdJXtjt7UORg9l7snuGG9k+sYxd6IlPhBryoS9Z5JA7La4zWMW3Pv4y
# 07MDPbGyr5I4ftKdgCz1TlaRITUlwzluZH9TupwPrRkjhMv0ugOGjfdf8NBSv4yU
# h7zAIXQlXxgotswnKDglmDlKNs98sZKuHCOnqWbsYR9q4ShJnV+I4iVd0yFLPlLE
# tVc/JAPw0XpbL9Uj43BdD1FGd7P4AOG8rAKCX9vAFbO9G9RVS+c5oQ/pI0m8GLhE
# fEXkwcNyeuBy5yTfv0aZxe/CHFfbg43sTUkwp6uO3+xbn6/83bBm4sGXgXvt1u1L
# 50kppxMopqd9Z4DmimJ4X7IvhNdXnFy/dygo8e1twyiPLI9AN0/B4YVEicQJTMXU
# pUMvdJX3bvh4IFgsE11glZo+TzOE2rCIF96eTvSWsLxGoGyY0uDWiIwLAgMBAAGj
# ggHtMIIB6TAQBgkrBgEEAYI3FQEEAwIBADAdBgNVHQ4EFgQUSG5k5VAF04KqFzc3
# IrVtqMp1ApUwGQYJKwYBBAGCNxQCBAweCgBTAHUAYgBDAEEwCwYDVR0PBAQDAgGG
# MA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUci06AjGQQ7kUBU7h6qfHMdEj
# iTQwWgYDVR0fBFMwUTBPoE2gS4ZJaHR0cDovL2NybC5taWNyb3NvZnQuY29tL3Br
# aS9jcmwvcHJvZHVjdHMvTWljUm9vQ2VyQXV0MjAxMV8yMDExXzAzXzIyLmNybDBe
# BggrBgEFBQcBAQRSMFAwTgYIKwYBBQUHMAKGQmh0dHA6Ly93d3cubWljcm9zb2Z0
# LmNvbS9wa2kvY2VydHMvTWljUm9vQ2VyQXV0MjAxMV8yMDExXzAzXzIyLmNydDCB
# nwYDVR0gBIGXMIGUMIGRBgkrBgEEAYI3LgMwgYMwPwYIKwYBBQUHAgEWM2h0dHA6
# Ly93d3cubWljcm9zb2Z0LmNvbS9wa2lvcHMvZG9jcy9wcmltYXJ5Y3BzLmh0bTBA
# BggrBgEFBQcCAjA0HjIgHQBMAGUAZwBhAGwAXwBwAG8AbABpAGMAeQBfAHMAdABh
# AHQAZQBtAGUAbgB0AC4gHTANBgkqhkiG9w0BAQsFAAOCAgEAZ/KGpZjgVHkaLtPY
# dGcimwuWEeFjkplCln3SeQyQwWVfLiw++MNy0W2D/r4/6ArKO79HqaPzadtjvyI1
# pZddZYSQfYtGUFXYDJJ80hpLHPM8QotS0LD9a+M+By4pm+Y9G6XUtR13lDni6WTJ
# RD14eiPzE32mkHSDjfTLJgJGKsKKELukqQUMm+1o+mgulaAqPyprWEljHwlpblqY
# luSD9MCP80Yr3vw70L01724lruWvJ+3Q3fMOr5kol5hNDj0L8giJ1h/DMhji8MUt
# zluetEk5CsYKwsatruWy2dsViFFFWDgycScaf7H0J/jeLDogaZiyWYlobm+nt3TD
# QAUGpgEqKD6CPxNNZgvAs0314Y9/HG8VfUWnduVAKmWjw11SYobDHWM2l4bf2vP4
# 8hahmifhzaWX0O5dY0HjWwechz4GdwbRBrF1HxS+YWG18NzGGwS+30HHDiju3mUv
# 7Jf2oVyW2ADWoUa9WfOXpQlLSBCZgB/QACnFsZulP0V3HjXG0qKin3p6IvpIlR+r
# +0cjgPWe+L9rt0uX4ut1eBrs6jeZeRhL/9azI2h15q/6/IvrC4DqaTuv/DDtBEyO
# 3991bWORPdGdVk5Pv4BXIqF4ETIheu9BCrE/+6jMpF3BoYibV3FWTkhFwELJm3Zb
# CoBIa/15n8G9bW1qyVJzEw16UM0xggScMIIEmAIBATCBlTB+MQswCQYDVQQGEwJV
# UzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UE
# ChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSgwJgYDVQQDEx9NaWNyb3NvZnQgQ29k
# ZSBTaWduaW5nIFBDQSAyMDExAhMzAAABA14lHJkfox64AAAAAAEDMAkGBSsOAwIa
# BQCggbAwGQYJKoZIhvcNAQkDMQwGCisGAQQBgjcCAQQwHAYKKwYBBAGCNwIBCzEO
# MAwGCisGAQQBgjcCARUwIwYJKoZIhvcNAQkEMRYEFJMv4j4v6leELi0o4bNDi5Ra
# Db27MFAGCisGAQQBgjcCAQwxQjBAoBaAFABQAG8AdwBlAHIAUwBoAGUAbABsoSaA
# JGh0dHA6Ly93d3cubWljcm9zb2Z0LmNvbS9Qb3dlclNoZWxsIDANBgkqhkiG9w0B
# AQEFAASCAQCNqfQSXgJ1xfIWoZSJvL5ytbBHs7BVOv2rH6ZbstZcis16FE7sBvWc
# ooXC/DEcni80eyQwLoeNcaN+rO+CcFReF7i707NBRsYUf5qF3QBcYYh3bZ+7Z0Mb
# ntMPzLMb5vQb9IokXD5xtD1T7olscBE1thzRL6E8BgC/9FSlfZHIG24olu7iumO0
# X6t0455Ga/t5ScvSZGjFHAC07ib0szObwz4jISv3rXIA3A975CrR0YZruObyQayr
# Utcw79NfcMD0vAZHpO3U2M5cfIDhrbSkRAJDvAeVggoyDNyTzjjlg8hKyAxKEqFp
# w4luu+bdWlV8KUNDAdvvXwGvmgsrsYipoYICKDCCAiQGCSqGSIb3DQEJBjGCAhUw
# ggIRAgEBMIGOMHcxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAw
# DgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24x
# ITAfBgNVBAMTGE1pY3Jvc29mdCBUaW1lLVN0YW1wIFBDQQITMwAAAP3H8MlqaaHI
# TAAAAAAA/TAJBgUrDgMCGgUAoF0wGAYJKoZIhvcNAQkDMQsGCSqGSIb3DQEHATAc
# BgkqhkiG9w0BCQUxDxcNMTgxMTA2MTcxNDI3WjAjBgkqhkiG9w0BCQQxFgQUHm40
# lhGdK3Hmqt3wMUrQVUXpKy8wDQYJKoZIhvcNAQEFBQAEggEAPmt/fMN91BdSxR2b
# +uwY+fpy43wKP40+XLHmLyXuBDiVF2iGCrXMc0Wml+aDI11PKLpUlAdqY/lTPg+z
# j79LqTfRBEdxe0LKdIpl/dfGcvobncgq25zTKclP2XCQ02wE5RGsJzroNzyV0tsY
# FUwGsSrv5FyagHTFXrLMfVtGq3QDTyaZOv6RQ8FKnbk2GCAI/7+JUxYWOjnj+95M
# Q9kBNKwXTTJs4JpbAiYqPni0cJmUuXp8uEpfj5iAEfBSTTVPD/q90v1fWnvHd/8+
# Zkha/NgdzyqdU0RZtDeTqOR26K/j75IYc6/Zcogwxtepv2oA3B4MUMJgoTzAXMG7
# ypMJqQ==
# SIG # End signature block