private/Get-Software.ps1

function Get-Software {
    param (
        [string[]]$Pattern,
        $IncludeHidden,
        $VerbosePreference
    )
    $allhotfixids = New-Object System.Collections.ArrayList
    $allcbs = Get-ChildItem 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Component Based Servicing\Packages'

    if ($psversiontable.PsVersion.Major -lt 5 -or ($psversiontable.PsVersion.Major -eq 5 -and $psversiontable.PsVersion.Major -lt 1)) {
        # using throw because it's a remote computer with no guarantee of psframework. Also the throw is caught at the bottom by PSFramework.
        throw "$env:ComputerName is running PowerShell version $psversiontalbe. Please upgrade to PowerShell version 5.1 or greater"
    }

    if ($pattern) {
        $packages = @()
        foreach ($name in $pattern) {
            $packages += Get-Package -IncludeWindowsInstaller -ProviderName msi, msu, Programs -Name "*$name*" -ErrorAction SilentlyContinue
            $packages += Get-Package -ProviderName msi, msu, Programs -Name "*$name*" -ErrorAction SilentlyContinue
            if ((Get-Service wuauserv | Where-Object StartType -ne Disabled)) {
                $session = [type]::GetTypeFromProgID("Microsoft.Update.Session")
                $wua = [activator]::CreateInstance($session)
                $updatesearcher = $wua.CreateUpdateSearcher()
                $count = $updatesearcher.GetTotalHistoryCount()
                $packages += $updatesearcher.QueryHistory(0, $count) | Where-Object Name -match $Pattern
            }
        }
    } else {
        $packages = @()
        $packages += Get-Package -IncludeWindowsInstaller -ProviderName msi, msu, Programs
        $packages += Get-Package -ProviderName msi, msu, Programs
        $packages = $packages | Sort-Object -Unique Name
        if ((Get-Service wuauserv | Where-Object StartType -ne Disabled)) {
            $session = [type]::GetTypeFromProgID("Microsoft.Update.Session")
            $wua = [activator]::CreateInstance($session)
            $updatesearcher = $wua.CreateUpdateSearcher()
            $count = $updatesearcher.GetTotalHistoryCount()
            $packages += $updatesearcher.QueryHistory(0, $count)
        }
    }

    $packages = $packages | Where-Object Name | Sort-Object -Unique Name
    # Cim never reports stuff in a package :(

    foreach ($package in $packages) {
        $null = $package | Add-Member -MemberType ScriptMethod -Name ToString -Value { $this.Name } -Force

        # Make it pretty
        $fullpath = $package.FullPath
        if ($fullpath -eq "?") {
            $fullpath = $null
        }
        $filename = $package.PackageFilename
        if ($filename -eq "?") {
            $filename = $null
        }

        $null = $package | Add-Member -MemberType ScriptMethod -Name ToString -Value { $this.Name } -Force
        if (($regpath = "$($package.FastPackageReference)".Replace("hklm64\HKEY_LOCAL_MACHINE", "HKLM:\")) -match 'HKLM') {
            $reg = Get-ItemProperty -Path $regpath -ErrorAction SilentlyContinue
            $null = $reg | Add-Member -MemberType ScriptMethod -Name ToString -Value { $this.DisplayName } -Force
            $hotfixid = Split-Path -Path $regpath -Leaf | Where-Object { "$PSItem".StartsWith("KB") }
        } else {
            $reg = $null
            $hotfixid = $null
        }

        #return the same properties as above
        if ($package.Name -match 'KB' -and -not $hotfixid) {
            #anyone want to help with regex, I'm down. Till then..
            $number = $package.Name.Split('KB') | Select-Object -Last 1
            $number = $number.Split(" ") | Select-Object -First 1
            $hotfixid = "KB$number".Trim().Replace(")", "")
        } else {
            $hotfixid = $package.HotfixId
        }
        if ($hotfixid) {
            $null = $allhotfixids.Add($hotfixid)
            $cbs = $allcbs | Where-Object Name -match $hotfixid | Get-ItemProperty
            if ($cbs) {
                # make it pretty
                $cbs | Add-Member -MemberType ScriptMethod -Name ToString -Value { "ComponentBasedServicing" } -Force
                $installclient = ($cbs | Select-Object -First 1).InstallClient
                $installuser = ($cbs | Select-Object -First 1).InstallUser
                $installname = $cbs.InstallName

                if ("$installname" -match "Package_1_for") {
                    $installname = $cbs | Where-Object InstallName -match "Package_1_for" | Select-Object -First 1 -ExpandProperty InstallName
                    $installname = $installname.Replace("Package_1_for", "Package_for")
                } elseif ("$installname" -match "Package_for") {
                    $installname = $cbs | Where-Object InstallName -match "Package_for" | Select-Object -First 1 -ExpandProperty InstallName
                }

                if ($installname.Count -gt 1) {
                    $installname | Select-Object -First 1
                }

                # props for highlighting that the installversion is important
                # https://social.technet.microsoft.com/Forums/Lync/en-US/f6594e00-2400-4276-85a1-fb06485b53e6/issues-with-wusaexe-and-windows-10-enterprise?forum=win10itprogeneral
                if ($installname) {
                    $installname = $installname.Replace(".mum", "")
                    $installversion = (($installname -split "~~")[1])
                }

                $allfiles = New-Object -TypeName System.Collections.ArrayList
                foreach ($file in $cbs) {
                    $name = $file.InstallName
                    $location = $file.InstallLocation.ToString().TrimStart("\\?\")
                    $location = "$location\$name"
                    $null = $allfiles.Add([pscustomobject]@{
                            Name = $name
                            Path = $location
                        })
                }
            }
        }

        # gotta get dism module and try that jesus christ
        if ($package.Meta.Attributes) {
            $DisplayName = $package.Meta.Attributes['DisplayName']
            $DisplayIcon = $package.Meta.Attributes['DisplayIcon']
            $UninstallString = $package.Meta.Attributes['UninstallString']
            $QuietUninstallString = $package.Meta.Attributes['QuietUninstallString']
            $InstallLocation = $package.Meta.Attributes['InstallLocation']
            $EstimatedSize = $package.Meta.Attributes['EstimatedSize']
            $Publisher = $package.Meta.Attributes['Publisher']
            $VersionMajor = $package.Meta.Attributes['VersionMajor']
            $VersionMinor = $package.Meta.Attributes['VersionMinor']
        } else {
            $DisplayIcon = $null
            $UninstallString = $null
            $QuietUninstallString = $null
            $InstallLocation = $null
            $EstimatedSize = $null
            $Publisher = $null
            $VersionMajor = $null
            $VersionMinor = $null
        }
        [pscustomobject]@{
            ComputerName         = $env:COMPUTERNAME
            Name                 = $package.Name
            ProviderName         = $package.ProviderName
            Source               = $package.Source
            Status               = $package.Status
            HotfixId             = $hotfixid
            FullPath             = $fullpath
            PackageFilename      = $filename
            Summary              = $package.Summary
            InstalledBy          = $cim.InstalledBy
            FastPackageReference = $package.FastPackageReference
            InstalledOn          = $cim.InstalledOn
            InstallDate          = $cim.InstallDate
            InstallClient        = $installclient
            InstallName          = $installname
            InstallVersion       = $installversion
            InstallFile          = $allfiles
            InstallUser          = $installuser
            FixComments          = $cim.FixComments
            ServicePackInEffect  = $cim.ServicePackInEffect
            Caption              = $cim.Caption
            DisplayName          = $DisplayName
            DisplayIcon          = $DisplayIcon
            UninstallString      = $UninstallString
            QuietUninstallString = $QuietUninstallString
            InstallLocation      = $InstallLocation
            EstimatedSize        = $EstimatedSize
            Publisher            = $Publisher
            VersionMajor         = $VersionMajor
            VersionMinor         = $VersionMinor
            TagId                = $package.TagId
            PackageObject        = $package
            RegistryObject       = $reg
            CBSPackageObject     = $cbs
            CimObject            = $cim
        }
    }

    $allcim = Get-CimInstance -ClassName Win32_QuickFixEngineering | Sort-Object HotFixID -Unique

    if ($pattern) {
        $allcim = $allcim | Where-Object HotfixId -in $pattern
    }


    foreach ($cim in $allcim) {
        #return the same properties as above
        if ($cim.Name -match 'KB' -and -not $cim.HotfixId) {
            # anyone want to help with regex, I'm down. Till then..
            $split = $cim.Name -split 'KB'
            $number = ($split[-1]).TrimEnd(")").Trim()
            $hotfixid = "KB$number"
        } else {
            $hotfixid = $cim.HotfixId
        }

        if ($hotfixid) {
            $null = $allhotfixids.Add($hotfixid)
            $cbs = $allcbs | Where-Object Name -match $hotfixid | Get-ItemProperty
            if ($cbs) {
                # make it pretty
                $cbs | Add-Member -MemberType ScriptMethod -Name ToString -Value { "ComponentBasedServicing" } -Force
                $installclient = ($cbs | Select-Object -First 1).InstallClient
                $installuser = ($cbs | Select-Object -First 1).InstallUser

                $allfiles = New-Object -TypeName System.Collections.ArrayList
                foreach ($file in $cbs) {
                    $name = $file.InstallName
                    $location = $file.InstallLocation.ToString().TrimStart("\\?\")
                    $location = "$location\$name"
                    $null = $allfiles.Add([pscustomobject]@{
                            Name = $name
                            Path = $location
                        })
                }
                # no idea why this doesn't work :(
                Add-Member -InputObject $allfiles -MemberType ScriptMethod -Name ToString -Value { $this.Name } -Force
            }
        }

        [pscustomobject]@{
            ComputerName         = $env:COMPUTERNAME
            Name                 = $cim.HotfixId
            ProviderName         = $null
            Source               = $null
            Status               = $null
            HotfixId             = $hotfixid
            FullPath             = $null
            PackageFilename      = $null
            Summary              = $null
            InstalledBy          = $cim.InstalledBy
            InstalledOn          = $cim.InstalledOn
            InstallDate          = $cim.InstallDate
            InstallClient        = $installclient
            InstallName          = $installname
            InstallVersion       = $installversion
            InstallFile          = $allfiles
            InstallUser          = $installuser
            FixComments          = $cim.FixComments
            ServicePackInEffect  = $cim.ServicePackInEffect
            Caption              = $cim.Caption
            DisplayName          = $null
            DisplayIcon          = $null
            UninstallString      = $null
            QuietUninstallString = $null
            InstallLocation      = $null
            EstimatedSize        = $null
            Publisher            = $null
            VersionMajor         = $null
            VersionMinor         = $null
            TagId                = $null
            PackageObject        = $null
            RegistryObject       = $null
            CBSPackageObject     = $cbs
            CimObject            = $cim
        }
    }

    if ($IncludeHidden) {
        #anyone want to help with regex, I'm down. Till then..
        $kbfiles = $allcbs | Get-ItemProperty | Where-Object InstallName -match '_KB' | Select-Object -ExpandProperty InstallName
        $allkbs = @()
        foreach ($file in $kbfiles) {
            $tempfile = $file.ToString().Split("_") | Where-Object { $PSItem.StartsWith("KB") }
            if ($tempfile) {
                $allkbs += $tempfile.Replace("_", "").Split("~") | Select-Object -First 1
            }
        }

        $missing = $allkbs | Where-Object { $PSitem -notin $allhotfixids } | Select-Object -Unique

        if ($Pattern) {
            $missing = $missing | Where-Object { $PSItem -in $Pattern }
        }

        foreach ($result in $missing) {
            [pscustomobject]@{
                ComputerName         = $env:COMPUTERNAME
                Name                 = $result
                ProviderName         = $null
                Source               = $null
                Status               = $null
                HotfixId             = $result
                FullPath             = $null
                PackageFilename      = $null
                Summary              = "Requires restart to finish installing"
                InstalledBy          = $null
                InstalledOn          = $null
                InstallDate          = $null
                InstallClient        = $null
                InstallName          = $null
                InstallVersion       = $null
                InstallFile          = $null
                InstallUser          = $null
                FixComments          = $null
                ServicePackInEffect  = $null
                Caption              = $null
                DisplayName          = $null
                DisplayIcon          = $null
                UninstallString      = $null
                QuietUninstallString = $null
                InstallLocation      = $null
                EstimatedSize        = $null
                Publisher            = $null
                VersionMajor         = $null
                VersionMinor         = $null
                TagId                = $null
                PackageObject        = $null
                RegistryObject       = $null
                CBSPackageObject     = $null
                CimObject            = $null
            }
        }
    }
}

# SIG # Begin signature block
# MIIjYAYJKoZIhvcNAQcCoIIjUTCCI00CAQExDzANBglghkgBZQMEAgEFADB5Bgor
# BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG
# KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCCuKEXnysUa0wtE
# R4U7MjI8KBqr2IGwT9ma/HhOmp+LLqCCHVkwggUaMIIEAqADAgECAhADBbuGIbCh
# Y1+/3q4SBOdtMA0GCSqGSIb3DQEBCwUAMHIxCzAJBgNVBAYTAlVTMRUwEwYDVQQK
# EwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xMTAvBgNV
# BAMTKERpZ2lDZXJ0IFNIQTIgQXNzdXJlZCBJRCBDb2RlIFNpZ25pbmcgQ0EwHhcN
# MjAwNTEyMDAwMDAwWhcNMjMwNjA4MTIwMDAwWjBXMQswCQYDVQQGEwJVUzERMA8G
# A1UECBMIVmlyZ2luaWExDzANBgNVBAcTBlZpZW5uYTERMA8GA1UEChMIZGJhdG9v
# bHMxETAPBgNVBAMTCGRiYXRvb2xzMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
# CgKCAQEAvL9je6vjv74IAbaY5rXqHxaNeNJO9yV0ObDg+kC844Io2vrHKGD8U5hU
# iJp6rY32RVprnAFrA4jFVa6P+sho7F5iSVAO6A+QZTHQCn7oquOefGATo43NAadz
# W2OWRro3QprMPZah0QFYpej9WaQL9w/08lVaugIw7CWPsa0S/YjHPGKQ+bYgI/kr
# EUrk+asD7lvNwckR6pGieWAyf0fNmSoevQBTV6Cd8QiUfj+/qWvLW3UoEX9ucOGX
# 2D8vSJxL7JyEVWTHg447hr6q9PzGq+91CO/c9DWFvNMjf+1c5a71fEZ54h1mNom/
# XoWZYoKeWhKnVdv1xVT1eEimibPEfQIDAQABo4IBxTCCAcEwHwYDVR0jBBgwFoAU
# WsS5eyoKo6XqcQPAYPkt9mV1DlgwHQYDVR0OBBYEFPDAoPu2A4BDTvsJ193ferHL
# 454iMA4GA1UdDwEB/wQEAwIHgDATBgNVHSUEDDAKBggrBgEFBQcDAzB3BgNVHR8E
# cDBuMDWgM6Axhi9odHRwOi8vY3JsMy5kaWdpY2VydC5jb20vc2hhMi1hc3N1cmVk
# LWNzLWcxLmNybDA1oDOgMYYvaHR0cDovL2NybDQuZGlnaWNlcnQuY29tL3NoYTIt
# YXNzdXJlZC1jcy1nMS5jcmwwTAYDVR0gBEUwQzA3BglghkgBhv1sAwEwKjAoBggr
# BgEFBQcCARYcaHR0cHM6Ly93d3cuZGlnaWNlcnQuY29tL0NQUzAIBgZngQwBBAEw
# gYQGCCsGAQUFBwEBBHgwdjAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuZGlnaWNl
# cnQuY29tME4GCCsGAQUFBzAChkJodHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5jb20v
# RGlnaUNlcnRTSEEyQXNzdXJlZElEQ29kZVNpZ25pbmdDQS5jcnQwDAYDVR0TAQH/
# BAIwADANBgkqhkiG9w0BAQsFAAOCAQEAj835cJUMH9Y2pBKspjznNJwcYmOxeBcH
# Ji+yK0y4bm+j44OGWH4gu/QJM+WjZajvkydJKoJZH5zrHI3ykM8w8HGbYS1WZfN4
# oMwi51jKPGZPw9neGS2PXrBcKjzb7rlQ6x74Iex+gyf8z1ZuRDitLJY09FEOh0BM
# LaLh+UvJ66ghmfIyjP/g3iZZvqwgBhn+01fObqrAJ+SagxJ/21xNQJchtUOWIlxR
# kuUn9KkuDYrMO70a2ekHODcAbcuHAGI8wzw4saK1iPPhVTlFijHS+7VfIt/d/18p
# MLHHArLQQqe1Z0mTfuL4M4xCUKpebkH8rI3Fva62/6osaXLD0ymERzCCBTAwggQY
# oAMCAQICEAQJGBtf1btmdVNDtW+VUAgwDQYJKoZIhvcNAQELBQAwZTELMAkGA1UE
# BhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3LmRpZ2lj
# ZXJ0LmNvbTEkMCIGA1UEAxMbRGlnaUNlcnQgQXNzdXJlZCBJRCBSb290IENBMB4X
# DTEzMTAyMjEyMDAwMFoXDTI4MTAyMjEyMDAwMFowcjELMAkGA1UEBhMCVVMxFTAT
# BgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTEx
# MC8GA1UEAxMoRGlnaUNlcnQgU0hBMiBBc3N1cmVkIElEIENvZGUgU2lnbmluZyBD
# QTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAPjTsxx/DhGvZ3cH0wsx
# SRnP0PtFmbE620T1f+Wondsy13Hqdp0FLreP+pJDwKX5idQ3Gde2qvCchqXYJawO
# eSg6funRZ9PG+yknx9N7I5TkkSOWkHeC+aGEI2YSVDNQdLEoJrskacLCUvIUZ4qJ
# RdQtoaPpiCwgla4cSocI3wz14k1gGL6qxLKucDFmM3E+rHCiq85/6XzLkqHlOzEc
# z+ryCuRXu0q16XTmK/5sy350OTYNkO/ktU6kqepqCquE86xnTrXE94zRICUj6whk
# PlKWwfIPEvTFjg/BougsUfdzvL2FsWKDc0GCB+Q4i2pzINAPZHM8np+mM6n9Gd8l
# k9ECAwEAAaOCAc0wggHJMBIGA1UdEwEB/wQIMAYBAf8CAQAwDgYDVR0PAQH/BAQD
# AgGGMBMGA1UdJQQMMAoGCCsGAQUFBwMDMHkGCCsGAQUFBwEBBG0wazAkBggrBgEF
# BQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQuY29tMEMGCCsGAQUFBzAChjdodHRw
# Oi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vRGlnaUNlcnRBc3N1cmVkSURSb290Q0Eu
# Y3J0MIGBBgNVHR8EejB4MDqgOKA2hjRodHRwOi8vY3JsNC5kaWdpY2VydC5jb20v
# RGlnaUNlcnRBc3N1cmVkSURSb290Q0EuY3JsMDqgOKA2hjRodHRwOi8vY3JsMy5k
# aWdpY2VydC5jb20vRGlnaUNlcnRBc3N1cmVkSURSb290Q0EuY3JsME8GA1UdIARI
# MEYwOAYKYIZIAYb9bAACBDAqMCgGCCsGAQUFBwIBFhxodHRwczovL3d3dy5kaWdp
# Y2VydC5jb20vQ1BTMAoGCGCGSAGG/WwDMB0GA1UdDgQWBBRaxLl7KgqjpepxA8Bg
# +S32ZXUOWDAfBgNVHSMEGDAWgBRF66Kv9JLLgjEtUYunpyGd823IDzANBgkqhkiG
# 9w0BAQsFAAOCAQEAPuwNWiSz8yLRFcgsfCUpdqgdXRwtOhrE7zBh134LYP3DPQ/E
# r4v97yrfIFU3sOH20ZJ1D1G0bqWOWuJeJIFOEKTuP3GOYw4TS63XX0R58zYUBor3
# nEZOXP+QsRsHDpEV+7qvtVHCjSSuJMbHJyqhKSgaOnEoAjwukaPAJRHinBRHoXpo
# aK+bp1wgXNlxsQyPu6j4xRJon89Ay0BEpRPw5mQMJQhCMrI2iiQC/i9yfhzXSUWW
# 6Fkd6fp0ZGuy62ZD2rOwjNXpDd32ASDOmTFjPQgaGLOBm0/GkxAG/AeB+ova+YJJ
# 92JuoVP6EpQYhS6SkepobEQysmah5xikmmRR7zCCBY0wggR1oAMCAQICEA6bGI75
# 0C3n79tQ4ghAGFowDQYJKoZIhvcNAQEMBQAwZTELMAkGA1UEBhMCVVMxFTATBgNV
# BAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTEkMCIG
# A1UEAxMbRGlnaUNlcnQgQXNzdXJlZCBJRCBSb290IENBMB4XDTIyMDgwMTAwMDAw
# MFoXDTMxMTEwOTIzNTk1OVowYjELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lD
# ZXJ0IEluYzEZMBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTEhMB8GA1UEAxMYRGln
# aUNlcnQgVHJ1c3RlZCBSb290IEc0MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC
# CgKCAgEAv+aQc2jeu+RdSjwwIjBpM+zCpyUuySE98orYWcLhKac9WKt2ms2uexuE
# DcQwH/MbpDgW61bGl20dq7J58soR0uRf1gU8Ug9SH8aeFaV+vp+pVxZZVXKvaJNw
# wrK6dZlqczKU0RBEEC7fgvMHhOZ0O21x4i0MG+4g1ckgHWMpLc7sXk7Ik/ghYZs0
# 6wXGXuxbGrzryc/NrDRAX7F6Zu53yEioZldXn1RYjgwrt0+nMNlW7sp7XeOtyU9e
# 5TXnMcvak17cjo+A2raRmECQecN4x7axxLVqGDgDEI3Y1DekLgV9iPWCPhCRcKtV
# gkEy19sEcypukQF8IUzUvK4bA3VdeGbZOjFEmjNAvwjXWkmkwuapoGfdpCe8oU85
# tRFYF/ckXEaPZPfBaYh2mHY9WV1CdoeJl2l6SPDgohIbZpp0yt5LHucOY67m1O+S
# kjqePdwA5EUlibaaRBkrfsCUtNJhbesz2cXfSwQAzH0clcOP9yGyshG3u3/y1Yxw
# LEFgqrFjGESVGnZifvaAsPvoZKYz0YkH4b235kOkGLimdwHhD5QMIR2yVCkliWzl
# DlJRR3S+Jqy2QXXeeqxfjT/JvNNBERJb5RBQ6zHFynIWIgnffEx1P2PsIV/EIFFr
# b7GrhotPwtZFX50g/KEexcCPorF+CiaZ9eRpL5gdLfXZqbId5RsCAwEAAaOCATow
# ggE2MA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFOzX44LScV1kTN8uZz/nupiu
# HA9PMB8GA1UdIwQYMBaAFEXroq/0ksuCMS1Ri6enIZ3zbcgPMA4GA1UdDwEB/wQE
# AwIBhjB5BggrBgEFBQcBAQRtMGswJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRp
# Z2ljZXJ0LmNvbTBDBggrBgEFBQcwAoY3aHR0cDovL2NhY2VydHMuZGlnaWNlcnQu
# Y29tL0RpZ2lDZXJ0QXNzdXJlZElEUm9vdENBLmNydDBFBgNVHR8EPjA8MDqgOKA2
# hjRodHRwOi8vY3JsMy5kaWdpY2VydC5jb20vRGlnaUNlcnRBc3N1cmVkSURSb290
# Q0EuY3JsMBEGA1UdIAQKMAgwBgYEVR0gADANBgkqhkiG9w0BAQwFAAOCAQEAcKC/
# Q1xV5zhfoKN0Gz22Ftf3v1cHvZqsoYcs7IVeqRq7IviHGmlUIu2kiHdtvRoU9BNK
# ei8ttzjv9P+Aufih9/Jy3iS8UgPITtAq3votVs/59PesMHqai7Je1M/RQ0SbQyHr
# lnKhSLSZy51PpwYDE3cnRNTnf+hZqPC/Lwum6fI0POz3A8eHqNJMQBk1RmppVLC4
# oVaO7KTVPeix3P0c2PR3WlxUjG/voVA9/HYJaISfb8rbII01YBwCA8sgsKxYoA5A
# Y8WYIsGyWfVVa88nq2x2zm8jLfR+cWojayL/ErhULSd+2DrZ8LaHlv1b0VysGMNN
# n3O3AamfV6peKOK5lDCCBq4wggSWoAMCAQICEAc2N7ckVHzYR6z9KGYqXlswDQYJ
# KoZIhvcNAQELBQAwYjELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IElu
# YzEZMBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTEhMB8GA1UEAxMYRGlnaUNlcnQg
# VHJ1c3RlZCBSb290IEc0MB4XDTIyMDMyMzAwMDAwMFoXDTM3MDMyMjIzNTk1OVow
# YzELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDkRpZ2lDZXJ0LCBJbmMuMTswOQYDVQQD
# EzJEaWdpQ2VydCBUcnVzdGVkIEc0IFJTQTQwOTYgU0hBMjU2IFRpbWVTdGFtcGlu
# ZyBDQTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMaGNQZJs8E9cklR
# VcclA8TykTepl1Gh1tKD0Z5Mom2gsMyD+Vr2EaFEFUJfpIjzaPp985yJC3+dH54P
# Mx9QEwsmc5Zt+FeoAn39Q7SE2hHxc7Gz7iuAhIoiGN/r2j3EF3+rGSs+QtxnjupR
# PfDWVtTnKC3r07G1decfBmWNlCnT2exp39mQh0YAe9tEQYncfGpXevA3eZ9drMvo
# hGS0UvJ2R/dhgxndX7RUCyFobjchu0CsX7LeSn3O9TkSZ+8OpWNs5KbFHc02DVzV
# 5huowWR0QKfAcsW6Th+xtVhNef7Xj3OTrCw54qVI1vCwMROpVymWJy71h6aPTnYV
# VSZwmCZ/oBpHIEPjQ2OAe3VuJyWQmDo4EbP29p7mO1vsgd4iFNmCKseSv6De4z6i
# c/rnH1pslPJSlRErWHRAKKtzQ87fSqEcazjFKfPKqpZzQmiftkaznTqj1QPgv/Ci
# PMpC3BhIfxQ0z9JMq++bPf4OuGQq+nUoJEHtQr8FnGZJUlD0UfM2SU2LINIsVzV5
# K6jzRWC8I41Y99xh3pP+OcD5sjClTNfpmEpYPtMDiP6zj9NeS3YSUZPJjAw7W4oi
# qMEmCPkUEBIDfV8ju2TjY+Cm4T72wnSyPx4JduyrXUZ14mCjWAkBKAAOhFTuzuld
# yF4wEr1GnrXTdrnSDmuZDNIztM2xAgMBAAGjggFdMIIBWTASBgNVHRMBAf8ECDAG
# AQH/AgEAMB0GA1UdDgQWBBS6FtltTYUvcyl2mi91jGogj57IbzAfBgNVHSMEGDAW
# gBTs1+OC0nFdZEzfLmc/57qYrhwPTzAOBgNVHQ8BAf8EBAMCAYYwEwYDVR0lBAww
# CgYIKwYBBQUHAwgwdwYIKwYBBQUHAQEEazBpMCQGCCsGAQUFBzABhhhodHRwOi8v
# b2NzcC5kaWdpY2VydC5jb20wQQYIKwYBBQUHMAKGNWh0dHA6Ly9jYWNlcnRzLmRp
# Z2ljZXJ0LmNvbS9EaWdpQ2VydFRydXN0ZWRSb290RzQuY3J0MEMGA1UdHwQ8MDow
# OKA2oDSGMmh0dHA6Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydFRydXN0ZWRS
# b290RzQuY3JsMCAGA1UdIAQZMBcwCAYGZ4EMAQQCMAsGCWCGSAGG/WwHATANBgkq
# hkiG9w0BAQsFAAOCAgEAfVmOwJO2b5ipRCIBfmbW2CFC4bAYLhBNE88wU86/GPvH
# UF3iSyn7cIoNqilp/GnBzx0H6T5gyNgL5Vxb122H+oQgJTQxZ822EpZvxFBMYh0M
# CIKoFr2pVs8Vc40BIiXOlWk/R3f7cnQU1/+rT4osequFzUNf7WC2qk+RZp4snuCK
# rOX9jLxkJodskr2dfNBwCnzvqLx1T7pa96kQsl3p/yhUifDVinF2ZdrM8HKjI/rA
# J4JErpknG6skHibBt94q6/aesXmZgaNWhqsKRcnfxI2g55j7+6adcq/Ex8HBanHZ
# xhOACcS2n82HhyS7T6NJuXdmkfFynOlLAlKnN36TU6w7HQhJD5TNOXrd/yVjmScs
# PT9rp/Fmw0HNT7ZAmyEhQNC3EyTN3B14OuSereU0cZLXJmvkOHOrpgFPvT87eK1M
# rfvElXvtCl8zOYdBeHo46Zzh3SP9HSjTx/no8Zhf+yvYfvJGnXUsHicsJttvFXse
# GYs2uJPU5vIXmVnKcPA3v5gA3yAWTyf7YGcWoWa63VXAOimGsJigK+2VQbc61RWY
# MbRiCQ8KvYHZE/6/pNHzV9m8BPqC3jLfBInwAM1dwvnQI38AC+R2AibZ8GV2QqYp
# hwlHK+Z/GqSFD/yYlvZVVCsfgPrA8g4r5db7qS9EFUrnEw4d2zc4GqEr9u3WfPww
# ggbAMIIEqKADAgECAhAMTWlyS5T6PCpKPSkHgD1aMA0GCSqGSIb3DQEBCwUAMGMx
# CzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5EaWdpQ2VydCwgSW5jLjE7MDkGA1UEAxMy
# RGlnaUNlcnQgVHJ1c3RlZCBHNCBSU0E0MDk2IFNIQTI1NiBUaW1lU3RhbXBpbmcg
# Q0EwHhcNMjIwOTIxMDAwMDAwWhcNMzMxMTIxMjM1OTU5WjBGMQswCQYDVQQGEwJV
# UzERMA8GA1UEChMIRGlnaUNlcnQxJDAiBgNVBAMTG0RpZ2lDZXJ0IFRpbWVzdGFt
# cCAyMDIyIC0gMjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAM/spSY6
# xqnya7uNwQ2a26HoFIV0MxomrNAcVR4eNm28klUMYfSdCXc9FZYIL2tkpP0GgxbX
# kZI4HDEClvtysZc6Va8z7GGK6aYo25BjXL2JU+A6LYyHQq4mpOS7eHi5ehbhVsbA
# umRTuyoW51BIu4hpDIjG8b7gL307scpTjUCDHufLckkoHkyAHoVW54Xt8mG8qjoH
# ffarbuVm3eJc9S/tjdRNlYRo44DLannR0hCRRinrPibytIzNTLlmyLuqUDgN5YyU
# XRlav/V7QG5vFqianJVHhoV5PgxeZowaCiS+nKrSnLb3T254xCg/oxwPUAY3ugjZ
# Naa1Htp4WB056PhMkRCWfk3h3cKtpX74LRsf7CtGGKMZ9jn39cFPcS6JAxGiS7uY
# v/pP5Hs27wZE5FX/NurlfDHn88JSxOYWe1p+pSVz28BqmSEtY+VZ9U0vkB8nt9Kr
# FOU4ZodRCGv7U0M50GT6Vs/g9ArmFG1keLuY/ZTDcyHzL8IuINeBrNPxB9Thvdld
# S24xlCmL5kGkZZTAWOXlLimQprdhZPrZIGwYUWC6poEPCSVT8b876asHDmoHOWIZ
# ydaFfxPZjXnPYsXs4Xu5zGcTB5rBeO3GiMiwbjJ5xwtZg43G7vUsfHuOy2SJ8bHE
# uOdTXl9V0n0ZKVkDTvpd6kVzHIR+187i1Dp3AgMBAAGjggGLMIIBhzAOBgNVHQ8B
# Af8EBAMCB4AwDAYDVR0TAQH/BAIwADAWBgNVHSUBAf8EDDAKBggrBgEFBQcDCDAg
# BgNVHSAEGTAXMAgGBmeBDAEEAjALBglghkgBhv1sBwEwHwYDVR0jBBgwFoAUuhbZ
# bU2FL3MpdpovdYxqII+eyG8wHQYDVR0OBBYEFGKK3tBh/I8xFO2XC809KpQU31Kc
# MFoGA1UdHwRTMFEwT6BNoEuGSWh0dHA6Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9EaWdp
# Q2VydFRydXN0ZWRHNFJTQTQwOTZTSEEyNTZUaW1lU3RhbXBpbmdDQS5jcmwwgZAG
# CCsGAQUFBwEBBIGDMIGAMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdpY2Vy
# dC5jb20wWAYIKwYBBQUHMAKGTGh0dHA6Ly9jYWNlcnRzLmRpZ2ljZXJ0LmNvbS9E
# aWdpQ2VydFRydXN0ZWRHNFJTQTQwOTZTSEEyNTZUaW1lU3RhbXBpbmdDQS5jcnQw
# DQYJKoZIhvcNAQELBQADggIBAFWqKhrzRvN4Vzcw/HXjT9aFI/H8+ZU5myXm93KK
# mMN31GT8Ffs2wklRLHiIY1UJRjkA/GnUypsp+6M/wMkAmxMdsJiJ3HjyzXyFzVOd
# r2LiYWajFCpFh0qYQitQ/Bu1nggwCfrkLdcJiXn5CeaIzn0buGqim8FTYAnoo7id
# 160fHLjsmEHw9g6A++T/350Qp+sAul9Kjxo6UrTqvwlJFTU2WZoPVNKyG39+Xgmt
# dlSKdG3K0gVnK3br/5iyJpU4GYhEFOUKWaJr5yI+RCHSPxzAm+18SLLYkgyRTzxm
# lK9dAlPrnuKe5NMfhgFknADC6Vp0dQ094XmIvxwBl8kZI4DXNlpflhaxYwzGRkA7
# zl011Fk+Q5oYrsPJy8P7mxNfarXH4PMFw1nfJ2Ir3kHJU7n/NBBn9iYymHv+XEKU
# gZSCnawKi8ZLFUrTmJBFYDOA4CPe+AOk9kVH5c64A0JH6EE2cXet/aLol3ROLtoe
# HYxayB6a1cLwxiKoT5u92ByaUcQvmvZfpyeXupYuhVfAYOd4Vn9q78KVmksRAsiC
# nMkaBXy6cbVOepls9Oie1FqYyJ+/jbsYXEP10Cro4mLueATbvdH7WwqocH7wl4R4
# 4wgDXUcsY6glOJcB0j862uXl9uab3H4szP8XTE0AotjWAQ64i+7m4HJViSwnGWH2
# dwGMMYIFXTCCBVkCAQEwgYYwcjELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lD
# ZXJ0IEluYzEZMBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTExMC8GA1UEAxMoRGln
# aUNlcnQgU0hBMiBBc3N1cmVkIElEIENvZGUgU2lnbmluZyBDQQIQAwW7hiGwoWNf
# v96uEgTnbTANBglghkgBZQMEAgEFAKCBhDAYBgorBgEEAYI3AgEMMQowCKACgACh
# AoAAMBkGCSqGSIb3DQEJAzEMBgorBgEEAYI3AgEEMBwGCisGAQQBgjcCAQsxDjAM
# BgorBgEEAYI3AgEVMC8GCSqGSIb3DQEJBDEiBCBXpOh9PRWRrBMsnnjkpFXz6Xcy
# h4jqvGlAYUXq80JY2zANBgkqhkiG9w0BAQEFAASCAQB8ZE/T6tyFdo1oRAQiVded
# azi/SHgVsfWyfyh7fWiI7Qz742DM9WkmP8I30Qq8daJR9U58oWTmrs7V6DegTdbc
# Si2GtpcwnadXbdZZ0cdWANBcrC4q+wzX4lQBIHg6zM9l8QfUwsEzk+2Js61ajP3o
# L10oArMvaeXvx60SSsHWnzABcNJ1egZIoBLcMRRnPf0R971QC6O1JEvHtMtFwkwe
# zwL48FZUh25iSAVLOD/5vRqkjhReI04vjXV8pp5rLIrVlIGy3vl0rUGRKn/M7VKc
# YJNZL49tJuIU9rxEzqEcsTeIlrS+RSyH7zP6ec4k+kp5OsgZEMTe2ih7vtjUEeql
# oYIDIDCCAxwGCSqGSIb3DQEJBjGCAw0wggMJAgEBMHcwYzELMAkGA1UEBhMCVVMx
# FzAVBgNVBAoTDkRpZ2lDZXJ0LCBJbmMuMTswOQYDVQQDEzJEaWdpQ2VydCBUcnVz
# dGVkIEc0IFJTQTQwOTYgU0hBMjU2IFRpbWVTdGFtcGluZyBDQQIQDE1pckuU+jwq
# Sj0pB4A9WjANBglghkgBZQMEAgEFAKBpMBgGCSqGSIb3DQEJAzELBgkqhkiG9w0B
# BwEwHAYJKoZIhvcNAQkFMQ8XDTIyMTAxMjEzMzgzM1owLwYJKoZIhvcNAQkEMSIE
# IKmgprp0hdUcT4p+cfQFL3ietvXPAlQ+ihYzv7Ac9AXUMA0GCSqGSIb3DQEBAQUA
# BIICAAycZeGYmovCfTt+jOc5I51RgQ2OoLdknj6tMjWzuMejfU9+Dxw12skcpdvC
# W6S82sge3Nth4sOFq7up1gUDHzM9CXBycYUnU5mU99rcTu+qK2X3e+xaUjtw3nIL
# x+wVC7s3hnD+UgfHf72WKxPaYoJFLUIEgJTdd5lzw6X5ZFPQYtf5G9Zdu5FJJhy/
# 4oySQSgziRcyULM6aYTXvnU1l0Qh9OyAO1A5MxQf7ptTqTp9RtPUEJDh0frpb67J
# M3+eRdGWiNxJH+pu9kHpfyf0gnU5FQkyYCggoD5xlUP0Cr4TxjymwgnY1ZpHR0VB
# dTxqusmx/jLhMoWSA1Q+uqFPzvStBXKM2rKa2nI4nKnKFBO8BWuheLPDkl5/PTdw
# FdBEqfhRz+UtmvPTKCtlGDG7AQ3a2v6h5D5PR6G3gHjGK+Ecqra6K9bU2Tecqjmc
# TxKYc8h+5gP4/CZBJlECusdUV7pz7ngCsKeCYbjRxqM7c8qIkuCKFUuiAQToQzVZ
# GKxhm2yIQ6r4tKF/3p9l8pvx9/JTI+0IpQh5qUoD7dUtdIpTi8JRl8CpTMb940qy
# aNcS6WQogOIZXVgiisd2MxadKrh51/aNYgtmlbLdnVOq78PQpuaPznXTeApZGvgi
# OKwE1nt8QRJxi1Nv9X24Pcf+Ur2uFWmn2GNV6pfLlPBSPCs0
# SIG # End signature block