AppHandling/Replace-DependenciesInAppFile.ps1

<#
 .Synopsis
  Replaces specified dependencies in an application file
 .Description
  Investigates whether the application file contains dependencies to a specific application ID and replaces the dependency if that is the case
 .Parameter Path
  Path of the application file to investigate
 .Parameter Destination
  Path of the modified application file, where dependencies was replaced (default is to rewrite the original file)
 .Parameter replaceDependencies
  A hashtable, describing the dependencies, which needs to be replaced
 .Parameter internalsVisibleTo
  An Array of hashtable, containing id, name and publisher of an app, which should be added to internals Visible to
 .Parameter showMyCode
  With this parameter you can change or check ShowMyCode in the app file. Check will throw an error if ShowMyCode is False.
 .Parameter replacePackageId
  Add this switch to replace the package id of the app file with a new GUID
 .Parameter replaceVersionNumber
  Add this parameter to replace the version number of the app file with this version number
 .Example
  Replace-DependenciesInAppFile -containerName test -Path c:\temp\myapp.app -replaceDependencies @{ "437dbf0e-84ff-417a-965d-ed2bb9650972" = @{ "id" = "88b7902e-1655-4e7b-812e-ee9f0667b01b"; "name" = "MyBaseApp"; "publisher" = "Freddy Kristiansen"; "minversion" = "1.0.0.0" }}
 .Example
  Replace-DependenciesInAppFile -containerName test -Path c:\temp\myapp.app -internalsVisibleTo @( @{ "id" = "88b7902e-1655-4e7b-812e-ee9f0667b01b"; "name" = "MyBaseApp"; "publisher" = "Freddy Kristiansen" } )
#>

Function Replace-DependenciesInAppFile {
    Param (
        [obsolete('ContainerName is no longer needed for Replace-DependenciesInAppFile')]
        [string] $containerName = $bcContainerHelperConfig.defaultContainerName,
        [Parameter(Mandatory=$true)]
        [string] $Path,
        [string] $Destination = $Path,
        [hashtable] $replaceDependencies = $null,
        [ValidateSet('Ignore','True','False','Check')]
        [string] $ShowMyCode = "Ignore",
        [switch] $replacePackageId,
        [string] $replaceVersionNumber,
        [HashTable[]] $internalsVisibleTo = $null
    )

$telemetryScope = InitTelemetryScope -name $MyInvocation.InvocationName -parameterValues $PSBoundParameters -includeParameters @()
try {

    if ($isPsCore) {
        [System.Reflection.Assembly]::LoadWithPartialName('System.IO.Packaging') | Out-Null
    }
    else {
        [System.Reflection.Assembly]::LoadWithPartialName('WindowsBase') | Out-Null
    }
    
    $memoryStream = $null
    $fs = $null
    
    try {
    
        $fs = [System.IO.File]::OpenRead($Path)
        $binaryReader = [System.IO.BinaryReader]::new($fs)
        $magicNumber1 = $binaryReader.ReadUInt32()
        $metadataSize = $binaryReader.ReadUInt32()
        $metadataVersion = $binaryReader.ReadUInt32()
        $packageId = [Guid]::new($binaryReader.ReadBytes(16))
        $contentLength = $binaryReader.ReadInt64()
        $magicNumber2 = $binaryReader.ReadUInt32()
            
        if ($magicNumber1 -ne 0x5856414E -or 
            $magicNumber2 -ne 0x5856414E -or 
            $metadataVersion -gt 2 -or
            $fs.Position + $contentLength -gt $fs.Length)
        {
            throw "Unsupported package format"
        }

        $memoryStream = [System.IO.MemoryStream]::new()
        $fs.Seek($metadataSize, [System.IO.SeekOrigin]::Begin) | Out-Null
        $fs.CopyTo($memoryStream)
        $memoryStream.Seek(0, [System.IO.SeekOrigin]::Begin) | Out-Null
        $memoryStream.SetLength($contentLength)
        $fs.Close()
        $fs.Dispose()
        $fs = $null
            
        $package = [System.IO.Packaging.Package]::Open($memoryStream, [System.IO.FileMode]::Open, [System.IO.FileAccess]::ReadWrite)
        $manifestPart = $package.GetPart('/NavxManifest.xml')
        $manifestStream = $manifestPart.GetStream()
        $manifest = [xml]([System.IO.StreamReader]::new($manifestStream)).ReadToEnd()
        $manifestStream.Close()
        $manifestChanges = $false
        $symbolReferencePart = $package.GetPart('/SymbolReference.json')
        $symbolReferenceStream = $symbolReferencePart.GetStream()
        $symbolJson = ([System.IO.StreamReader]::new($symbolReferenceStream)).ReadToEnd()
        $symbolReferenceStream.Close()
        $symbolReference = $symbolJson | ConvertFrom-Json
        $symbolReferenceChanges = $false
    
        if ($ShowMyCode -ne "Ignore") {
            if ($ShowMyCode -eq "Check") {
                $resexp = $manifest.Package.ChildNodes | Where-Object { $_.name -eq "ResourceExposurePolicy" }
                if ($resexp) {
                    if ($resexp.allowDebugging -ne "true" -or $resexp.allowDownloadingSource -ne "true" -or $resexp.includeSourceInSymbolFile -ne "true") {
                        throw "Application has limited ResourceExposurePolicy"
                    }
                }
                elseif ($manifest.Package.App.ShowMyCode -eq "False") {
                    throw "Application has ShowMyCode set to False"
                }
            } else {
                $resexp = $manifest.Package.ChildNodes | Where-Object { $_.name -eq "ResourceExposurePolicy" }
                if ($resexp) {
                    if ($resexp.allowDebugging -ne "$ShowMyCode" -or $resexp.allowDownloadingSource -ne "$ShowMyCode" -or $resexp.includeSourceInSymbolFile -ne "$ShowMyCode") {
                        Write-Host "Changing ResourceExposurePolicy properties to $ShowMyCode"
                        $resexp.allowDebugging = "$showMyCode"
                        $resexp.allowDownloadingSource = "$showMyCode"
                        $resexp.includeSourceInSymbolFile = "$showMyCode"
                        $manifestChanges = $true
                    }
                }
                elseif ($manifest.Package.App.ShowMyCode -ne $ShowMyCode) {
                    Write-Host "Changing ShowMyCode to $ShowMyCOde"
                    $manifest.Package.App.ShowMyCode = "$ShowMyCode"
                    $manifestChanges = $true
                }
            }
        }

        if ($replaceDependencies) {
            $manifest.Package.Dependencies.GetEnumerator() | % {
                $dependency = $_
                if ($replaceDependencies.ContainsKey($dependency.id)) {
                    $newDependency = $replaceDependencies[$dependency.id]
                    Write-Host "Replacing dependency from $($dependency.id) to $($newDependency.id)"
                    $dependency.id = $newDependency.id
                    $dependency.name = $newDependency.name
                    $dependency.publisher = $newDependency.publisher
                    $dependency.minVersion = $newDependency.minVersion
                    $manifestChanges = $true
                }
            }
        }

        if ($internalsVisibleTo) {
            $internalsVisibleTo | % {
                $ivt = $_
                $existing = $manifest.Package.InternalsVisibleTo.GetEnumerator() | Where-Object { $_.id -eq $ivt.id -and $_.name -eq $ivt.name -and $_.publisher -eq $ivt.publisher }
                if (-not ($existing)) {
                    Write-Host "Adding Id=$($ivt.Id), Name=$($ivt.Name), Publisher=$($ivt.Publisher) to InternalsVisibleTo"
                    $element = $manifest.CreateElement("Module","http://schemas.microsoft.com/navx/2015/manifest")
                    $element.SetAttribute('Id',$ivt.Id)
                    $element.SetAttribute('Name',$ivt.Name)
                    $element.SetAttribute('Publisher',$ivt.Publisher)
                    $manifest.Package.InternalsVisibleTo.AppendChild($element) | Out-Null
                    $manifestChanges = $true
                    $symbolReference.InternalsVisibleToModules += @(@{
                        "AppId" = $ivt.Id
                        "Name" = $ivt.Name
                        "Publisher" = $ivt.Publisher
                    })
                    $symbolReferenceChanges = $true
                }
            }
        }

        if ($replaceVersionNumber) {
            Write-Host "Replacing Version Number with $replaceVersionNumber"
            $manifest.Package.App.Version = $replaceVersionNumber
            $manifestChanges = $true
        }

        if ($replacePackageId) {
            Write-Host "Replacing Package ID with new GUID"
            $packageId = [Guid]::NewGuid()
            $manifestChanges = $true
        }
    
        if ($manifestChanges) {
            $partStream = $manifestPart.GetStream([System.IO.FileMode]::Create)
            $manifest.Save($partStream)
            $partStream.Flush()
            
            if ($symbolReferenceChanges) {
                $partStream = $symbolReferencePart.GetStream([System.IO.FileMode]::Create)
                $memStream = [System.IO.MemoryStream]::new()
                $strWriter = [System.IO.StreamWriter]::new($memStream)
                $json = $symbolreference | ConvertTo-Json -depth 99
                $strWriter.Write($json)
                $strWriter.Flush()
                $memStream.Position = 0
                $memStream.CopyTo($partStream)
                $partStream.Flush()
            }
            $package.Close()
            
            $fs = [System.IO.FileStream]::new($Destination, [System.IO.FileMode]::Create)
            
            $binaryWriter = [System.IO.BinaryWriter]::new($fs)
            $binaryWriter.Write([UInt32](0x5856414E))
            $binaryWriter.Write([UInt32](40))
            $binaryWriter.Write([UInt32](2))
            $binaryWriter.Write($packageId.ToByteArray())
            $binaryWriter.Write([UInt64]($memoryStream.Length))
            $binaryWriter.Write([UInt32](0x5856414E))
            
            $memoryStream.Seek(0, [System.IO.SeekOrigin]::Begin) | Out-Null
            $memoryStream.CopyTo($fs)
            
            $fs.Close()
            $fs.Dispose()
            $fs = $null
        }
        else {
            if ($Path -ne $Destination) {
                Copy-Item -Path $Path -Destination $Destination -Force
            }
        }
    }
    finally {
        if ($fs) {
            $fs.Close()
        }
    }
}
catch {
    TrackException -telemetryScope $telemetryScope -errorRecord $_
    throw
}
finally {
    TrackTrace -telemetryScope $telemetryScope
}
}
Export-ModuleMember -Function Replace-DependenciesInAppFile

# SIG # Begin signature block
# MIInbQYJKoZIhvcNAQcCoIInXjCCJ1oCAQExDzANBglghkgBZQMEAgEFADB5Bgor
# BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG
# KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCCVO3B7FIRzehQA
# 5Y2VzLC4mN9/QZY0Eqyk1EnAe/XE5qCCDMkwggYEMIID7KADAgECAhMzAAACHPrN
# xZvoL37EAAAAAAIcMA0GCSqGSIb3DQEBCwUAMFcxCzAJBgNVBAYTAlVTMR4wHAYD
# VQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMTH01pY3Jvc29mdCBD
# b2RlIFNpZ25pbmcgUENBIDIwMjQwHhcNMjYwNDE2MTg1OTQxWhcNMjcwNDE1MTg1
# OTQxWjB0MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UE
# BxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMR4wHAYD
# VQQDExVNaWNyb3NvZnQgQ29ycG9yYXRpb24wggEiMA0GCSqGSIb3DQEBAQUAA4IB
# DwAwggEKAoIBAQDVsZfgOKmM31HPfoWOoNEiw0SlCiIxUMC0I9NMWbucKOw/e9lP
# oAoehQVu6SG65V4EPzrYsnBnFPNoi4/HoOdjhz1qkrEt4I6tEcxXU6oOeY9zGveC
# /3iBeuhLYxM3M/PkcUoebF+Nednm8OkdSPoDu8imViHPQq/8CQUu0WRR4rE+dMRf
# rpVqfmNi2qWCX94T4MsepijGVkwE//tJg0ryAiYdHT34LSnlG/RSBZmQRGWZ5g8j
# qnKjRParSqMft1gvjuUTVgtWNZfgcLFSK5Wa0myrq8OPcgTGGsRgun+tnSS+IxDT
# xVsAPH1OzvPjwomguByhUe/OcvUN0D5Wmp7xAgMBAAGjggGqMIIBpjAOBgNVHQ8B
# Af8EBAMCB4AwHwYDVR0lBBgwFgYKKwYBBAGCN0wIAQYIKwYBBQUHAwMwHQYDVR0O
# BBYEFNoH7a2YDjOSwpkp6DHcmUS7J+0yMFQGA1UdEQRNMEukSTBHMS0wKwYDVQQL
# EyRNaWNyb3NvZnQgSXJlbGFuZCBPcGVyYXRpb25zIExpbWl0ZWQxFjAUBgNVBAUT
# DTIzMDAxMis1MDc1NjkwHwYDVR0jBBgwFoAUf1k/VCHarU/vBeXmo9ctBpQSCDEw
# YAYDVR0fBFkwVzBVoFOgUYZPaHR0cDovL3d3dy5taWNyb3NvZnQuY29tL3BraW9w
# cy9jcmwvTWljcm9zb2Z0JTIwQ29kZSUyMFNpZ25pbmclMjBQQ0ElMjAyMDI0LmNy
# bDBtBggrBgEFBQcBAQRhMF8wXQYIKwYBBQUHMAKGUWh0dHA6Ly93d3cubWljcm9z
# b2Z0LmNvbS9wa2lvcHMvY2VydHMvTWljcm9zb2Z0JTIwQ29kZSUyMFNpZ25pbmcl
# MjBQQ0ElMjAyMDI0LmNydDAMBgNVHRMBAf8EAjAAMA0GCSqGSIb3DQEBCwUAA4IC
# AQAUnEqhaRXe0T3hIJjvdQErEkrA/7bByjn6t5IArODkkRjzkYwtKMc2yYj2quaN
# rLutWw2YZcngKPy1b71YyDJQTy4NDRwaSh9Tw5thrk3NmcPrAHia5vtcBJ1CgtKK
# 7mQbIcQ22d/N3813ayCDDFewu1+jsZmX+r/aTEqaOM4TVxVtRSkuCy8nAXKuChOK
# Li/zA4XuH8iEYqIsj2YoNaeSxVmeGiERXpKdo3dDmYi0kO5w2D8VS4c3+9h6gElY
# BaAAg/dYErBg27qT3vv0zRDJhJufvCNylA8S7/+8H5E/PV5cng6na9VV/w9OV3qu
# uND6zdGa2EX38Glp50F9AIQk3p2xXmcvorDeM4XJ7UlWYBi6g80J1SSOQnInCYFE
# msfUNn3+1AaTJKSJL83quKArTac2pKhu0Yzzzrzo6HrsRiQKzpnRBb1/dMa6P3hz
# 75XbMRBctNsFhZC07WCmjExdLg2eHW5uV0TY8D5+6wozJf7vF3+WHkYPO85Z+BC6
# U4FkNbYNycZ9cE4j1tXRdyDCfml6c0HWPHjNVDObrv9lKt3qUqFpX38VCqVCyNOO
# 1UcXfQiVjJw32U2WUKZjt/neJKHEBsm9kFsLuWzkQ53+qcaSaytmsCnk2gOglrlD
# 5d3kKyvvAw+rzm0lT8K38P6PLxfZQHhu4W8dV7Av8N2ZmDCCBr0wggSloAMCAQIC
# EzMAAAA5O7Y3Gb8GHWcAAAAAADkwDQYJKoZIhvcNAQEMBQAwgYgxCzAJBgNVBAYT
# AlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYD
# VQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xMjAwBgNVBAMTKU1pY3Jvc29mdCBS
# b290IENlcnRpZmljYXRlIEF1dGhvcml0eSAyMDExMB4XDTI0MDgwODIwNTQxOFoX
# DTM2MDMyMjIyMTMwNFowVzELMAkGA1UEBhMCVVMxHjAcBgNVBAoTFU1pY3Jvc29m
# dCBDb3Jwb3JhdGlvbjEoMCYGA1UEAxMfTWljcm9zb2Z0IENvZGUgU2lnbmluZyBQ
# Q0EgMjAyNDCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANgBnB7jOMeq
# lRYHNa265v4IY9fH8TKhemHfPINe1gpLaV3dhg324WwH06LcHbpnsBukCDNitryo
# 0dtS/EW6I/yEL/bLSY8hKpbfQuWusBPr9qazYcDxCW/qnjb5JsI1s8bNOg3bVATv
# QVL4tcf03aTycsz8QeCdM0l/yHRObJ9QqazM1r6VPEOJ7LL+uEEb73w6QCuhs89a
# 1uv1zerOYMnsneRRwCbpyW11IcggU0cRKDDq1pjVJzIbIF6+oiXXbReOsgeI8zu1
# FyQfK0fVkaya8SmVHQ/tOf23mZ4W9k0Ri22QW9p3UgSC5OUDktKxxcCmGL6tXLfO
# GSWHIIV4YrTJTT6PNty5REojHJuZHArkF9VnHTERWoTjAzfI3kP+5b4alUdhgAZ7
# ttOu1bVnXfHaqPYl2rPs20ji03LOVWsh/radgE17es5hL+t6lV0eVHrVhsssROWJ
# uz2MXMCt7iw7lFPG9LXKGjsmonn2gotGdHIuEg5JnJMJVmixd5LRlkmgYRZKzhxS
# CwyoGIq0PhaA7Y+VPct5pCHkijcIIDm0nlkK+0KyepolcqGm0T/GYQRMhHJlGOOm
# VQop36wUVUYklUy++vDWeEgEo4s7hxN6mIbf2MSIQ/iIfMZgJxC69oukMUXCrOC3
# SkE/xIkgpfl22MM1itkZ35nNXkMolU1lAgMBAAGjggFOMIIBSjAOBgNVHQ8BAf8E
# BAMCAYYwEAYJKwYBBAGCNxUBBAMCAQAwHQYDVR0OBBYEFH9ZP1Qh2q1P7wXl5qPX
# LQaUEggxMBkGCSsGAQQBgjcUAgQMHgoAUwB1AGIAQwBBMA8GA1UdEwEB/wQFMAMB
# Af8wHwYDVR0jBBgwFoAUci06AjGQQ7kUBU7h6qfHMdEjiTQwWgYDVR0fBFMwUTBP
# oE2gS4ZJaHR0cDovL2NybC5taWNyb3NvZnQuY29tL3BraS9jcmwvcHJvZHVjdHMv
# TWljUm9vQ2VyQXV0MjAxMV8yMDExXzAzXzIyLmNybDBeBggrBgEFBQcBAQRSMFAw
# TgYIKwYBBQUHMAKGQmh0dHA6Ly93d3cubWljcm9zb2Z0LmNvbS9wa2kvY2VydHMv
# TWljUm9vQ2VyQXV0MjAxMV8yMDExXzAzXzIyLmNydDANBgkqhkiG9w0BAQwFAAOC
# AgEAFJQfOChP7onn6fLIMKrSlN1WYKwDFgAddymOUO3FrM8d7B/W/iQ6DxXsDn7D
# 5W4wMwYeLystcEqfkjz4NURRgazyMu5yRzQh4LqjA4tStTcJh1opExo7nn5PuPBY
# nbu0+THSuVHTe0VTTPVhily/piFrDo3axQ9P4C+Ol5yet+2gTfekICS5xS+cYfSI
# vgn0JksVBVMYVI5QFu/qhnLhsEFEUzG8fvv0hjgkO+lkpV9ty6GkN4vdnd7ya6Q6
# aR9y34aiM1qmxaxBi6OUnyNl6fkuun/diTFnYDLTppOkr/mg5WSfCiDVMNCxtj4w
# PKC5OmHm1DQIt/MNokbbH3UGsFP1QbzsLocuSqLCvH09Io3fDPTmscR9Y75G4qX7
# RTX8AdBPo0I6OEojf39zuFZt0qOHm65YWQE69cZM2ueE1MB05dNNgHK9gTE7zKvK
# /fg8B2qjW88MT/WF5V5uvZGtqa9FSL2RazArA+rDPuf6JGYz4HpgMZHB4S6szWSK
# YBv0VisCzfxgeU+dquXW9bd0auYlOB58DPcOYKdc3Se94g+xL4pcEhbB54JOgAkw
# YTu/9dLeH2pDqeJZAABVDWRQCaXfO5LgyKwKCLYXpigrZYCjUSBcr+Ve8PFWMhVT
# Ql0v4q8J/AUmQN5W4n101cY2L4A7GTQG1h32HHAvfQESWP0xghn6MIIZ9gIBATBu
# MFcxCzAJBgNVBAYTAlVTMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24x
# KDAmBgNVBAMTH01pY3Jvc29mdCBDb2RlIFNpZ25pbmcgUENBIDIwMjQCEzMAAAIc
# +s3Fm+gvfsQAAAAAAhwwDQYJYIZIAWUDBAIBBQCgga4wGQYJKoZIhvcNAQkDMQwG
# CisGAQQBgjcCAQQwHAYKKwYBBAGCNwIBCzEOMAwGCisGAQQBgjcCARUwLwYJKoZI
# hvcNAQkEMSIEIEutx3g7/C0jVuOVQP0VAHa8ZoYGVkn3CBs7uquJ/oFZMEIGCisG
# AQQBgjcCAQwxNDAyoBSAEgBNAGkAYwByAG8AcwBvAGYAdKEagBhodHRwOi8vd3d3
# Lm1pY3Jvc29mdC5jb20wDQYJKoZIhvcNAQEBBQAEggEABoV+Qa+jfxicrllc8JNm
# EN7yqQOVdSglj5+lBUtBZSrT+Vas2bQlUNmZ0iSKjImohJL+3smulWNLPB3xeBKp
# H6zE1jvycCe5N8+D5LXfdu4lzf5T4IfiNG1uOjLUBnJdp/VV+4M8wU8HMrxx9+sW
# Kmo8D8mFr5YeyNbRHtHIUwcgfVEEsdGMscXxj3V2ZfnxfVv6uY5Sjyl6XI3m1fLh
# T2wu+mJthOvBckGJ2XwltWpSx8uJA5Zrzu+QoOc0zZTq62aZIVqUNWQM98RvcRg4
# So4RZN0jcFmGn6wp3f5sHGA97o4uzhF+HujVoZ/R33Mmh2xdCRgOcFi6qr6mqRA2
# A6GCF6wwgheoBgorBgEEAYI3AwMBMYIXmDCCF5QGCSqGSIb3DQEHAqCCF4UwgheB
# AgEDMQ8wDQYJYIZIAWUDBAIBBQAwggFaBgsqhkiG9w0BCRABBKCCAUkEggFFMIIB
# QQIBAQYKKwYBBAGEWQoDATAxMA0GCWCGSAFlAwQCAQUABCDAaelPn2nvZKtYCzNN
# MFVMKIfzZEpLlXSvg7yMhXiWswIGauvdNCBrGBMyMDI2MTEwNTEwMjA1MS4xMjZa
# MASAAgH0oIHZpIHWMIHTMQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3Rv
# bjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0
# aW9uMS0wKwYDVQQLEyRNaWNyb3NvZnQgSXJlbGFuZCBPcGVyYXRpb25zIExpbWl0
# ZWQxJzAlBgNVBAsTHm5TaGllbGQgVFNTIEVTTjo0QzFBLTA1RTAtRDk0NzElMCMG
# A1UEAxMcTWljcm9zb2Z0IFRpbWUtU3RhbXAgU2VydmljZaCCEfowggcoMIIFEKAD
# AgECAhMzAAACNFOhZ5ThvBhHAAEAAAI0MA0GCSqGSIb3DQEBCwUAMHwxCzAJBgNV
# BAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4w
# HAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xJjAkBgNVBAMTHU1pY3Jvc29m
# dCBUaW1lLVN0YW1wIFBDQSAyMDEwMB4XDTI2MTAxNTE4Mzc0MVoXDTI4MDExMTE4
# Mzc0MVowgdMxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYD
# VQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xLTAr
# BgNVBAsTJE1pY3Jvc29mdCBJcmVsYW5kIE9wZXJhdGlvbnMgTGltaXRlZDEnMCUG
# A1UECxMeblNoaWVsZCBUU1MgRVNOOjRDMUEtMDVFMC1EOTQ3MSUwIwYDVQQDExxN
# aWNyb3NvZnQgVGltZS1TdGFtcCBTZXJ2aWNlMIICIjANBgkqhkiG9w0BAQEFAAOC
# Ag8AMIICCgKCAgEAv1DlGvKZ5zYjHEFIq54AmeMU93V3X2VTcxZ/BySJkMeKI8A9
# cHBMguy13bQX0VOzrw0R+GACXfqJ/C1Dnpxel0w8WZXI5oUKBA1raFhDUSranmSJ
# sskUdJOGz2t+kZujCSYVqOSmJusZWFgOgrR3kG1nT9TO0EtYboO5CAPFPsqxeTe7
# M6oEZ84I/YRHW0al878rKouB1L+QOyTw9NOBjVqgnsd3kikvb6Md8eLc5VW2gs7s
# SkjQkhMz6JAA1K7lOQH9zBzRJeyspelEPvIDr/HqKf3ix/2Iu6bU69r0AgfSElK4
# 8scRLppB+4owC3+QeQHoa4Zb6bXy8ypGbRotszgHA1Ye8/X4OAAzTiAEilwh9feW
# 4Sgl0Be95TCf5KqCfmb2rx+R/swujTRWBrDdcXTrp+P8gdPRueTTgrTvdGibOQte
# P0baOYOYLE1fG1MQaH8Qea+h5rf7XuTmTRp2LD//ufdTRLwa8znQTSzVTVoQsBme
# EAriPYdMUTErc4gr6b5t9jcEjFNsDbZvXjqwxOaleW6rIZo8+a0MXGrd2IxZTIdn
# mcctt7c/BVk25br29mAxazFs2hWGc1Wird/XWl7rghV1iUjPav9MVSc08AcVVeow
# pSvEUB/NsxAowa3Dy2EEOdASK/HkL5Pyi/EfT5Nxzdi19bgcVhHW6tCHpEcCAwEA
# AaOCAUkwggFFMB0GA1UdDgQWBBQExeMDLdFhgBUUI0xj7MaM+LlVAjAfBgNVHSME
# GDAWgBSfpxVdAF5iXYP05dJlpxtTNRnpcjBfBgNVHR8EWDBWMFSgUqBQhk5odHRw
# Oi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2NybC9NaWNyb3NvZnQlMjBUaW1l
# LVN0YW1wJTIwUENBJTIwMjAxMCgxKS5jcmwwbAYIKwYBBQUHAQEEYDBeMFwGCCsG
# AQUFBzAChlBodHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2NlcnRzL01p
# Y3Jvc29mdCUyMFRpbWUtU3RhbXAlMjBQQ0ElMjAyMDEwKDEpLmNydDAMBgNVHRMB
# Af8EAjAAMBYGA1UdJQEB/wQMMAoGCCsGAQUFBwMIMA4GA1UdDwEB/wQEAwIHgDAN
# BgkqhkiG9w0BAQsFAAOCAgEAknSqLDWke2i0f9l0YZ/VZUIQwMHqHGx+/oqKh6sj
# R5oMibSwrIgth02kGQv2pnpKuF3nDxPM1XR3+MjEtgO9WUIr25rvPZM93FPnLtbe
# vOkqkBNvcp3dUBEDmzx3FuKgJoeCay6OXL1bgP0BqfYlIbWyKmqez6z8o5UvjPUY
# I8K1jyr42d7OqyPThBPJUsTOKG8ggT9mWj46YxKXxmUt4BujofSh0XKQEnrtiDRM
# zrGzkYV8JniewBsyWgoYqcUJOqtLyBu0EsIbHejMrlPVb8o2XyD8wb271tjId8Pz
# vLVrhrfFt7MZtgSVQ3oxDYqsg41j/D8qmHJg5NLs9Zlj6Z/7o1WYkZuqvLpsd6kw
# an7MxX729J15uE6A2ErbeuEitTaXmxtQRujS2DR6YSm5GIlPsGU6So8hBlrcnCFm
# 5cfbwAHEWxLxNaGhwJjF+leTjyDbna3QHrq+p7z8yIsCw/ae4+LwUE8wbX8nSKnH
# g8536pWa0ovRZMPl/iu4H35e/MurwgXxquXnaYIW9JxUOz6Db0KPGzzZAIcTFdpp
# llplQ5ZMhvS+r6sMoQWqNpmZW4ziu6l7bcr1qFyLJdQzjBFvsmS95/ii13++kUhB
# bzyZrw8M98C3HQ9wtyNVlfmTEZKMsGqW1IlzwHzVYQFF5GWxBT1TckeNoyz7JfeP
# 8z8wggdxMIIFWaADAgECAhMzAAAAFcXna54Cm0mZAAAAAAAVMA0GCSqGSIb3DQEB
# CwUAMIGIMQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UE
# BxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTIwMAYD
# VQQDEylNaWNyb3NvZnQgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgMjAxMDAe
# Fw0yMTA5MzAxODIyMjVaFw0zMDA5MzAxODMyMjVaMHwxCzAJBgNVBAYTAlVTMRMw
# EQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVN
# aWNyb3NvZnQgQ29ycG9yYXRpb24xJjAkBgNVBAMTHU1pY3Jvc29mdCBUaW1lLVN0
# YW1wIFBDQSAyMDEwMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA5OGm
# TOe0ciELeaLL1yR5vQ7VgtP97pwHB9KpbE51yMo1V/YBf2xK4OK9uT4XYDP/XE/H
# ZveVU3Fa4n5KWv64NmeFRiMMtY0Tz3cywBAY6GB9alKDRLemjkZrBxTzxXb1hlDc
# wUTIcVxRMTegCjhuje3XD9gmU3w5YQJ6xKr9cmmvHaus9ja+NSZk2pg7uhp7M62A
# W36MEBydUv626GIl3GoPz130/o5Tz9bshVZN7928jaTjkY+yOSxRnOlwaQ3KNi1w
# jjHINSi947SHJMPgyY9+tVSP3PoFVZhtaDuaRr3tpK56KTesy+uDRedGbsoy1cCG
# MFxPLOJiss254o2I5JasAUq7vnGpF1tnYN74kpEeHT39IM9zfUGaRnXNxF803RKJ
# 1v2lIH1+/NmeRd+2ci/bfV+AutuqfjbsNkz2K26oElHovwUDo9Fzpk03dJQcNIIP
# 8BDyt0cY7afomXw/TNuvXsLz1dhzPUNOwTM5TI4CvEJoLhDqhFFG4tG9ahhaYQFz
# ymeiXtcodgLiMxhy16cg8ML6EgrXY28MyTZki1ugpoMhXV8wdJGUlNi5UPkLiWHz
# NgY1GIRH29wb0f2y1BzFa/ZcUlFdEtsluq9QBXpsxREdcu+N+VLEhReTwDwV2xo3
# xwgVGD94q0W29R6HXtqPnhZyacaue7e3PmriLq0CAwEAAaOCAd0wggHZMBIGCSsG
# AQQBgjcVAQQFAgMBAAEwIwYJKwYBBAGCNxUCBBYEFCqnUv5kxJq+gpE8RjUpzxD/
# LwTuMB0GA1UdDgQWBBSfpxVdAF5iXYP05dJlpxtTNRnpcjBcBgNVHSAEVTBTMFEG
# DCsGAQQBgjdMg30BATBBMD8GCCsGAQUFBwIBFjNodHRwOi8vd3d3Lm1pY3Jvc29m
# dC5jb20vcGtpb3BzL0RvY3MvUmVwb3NpdG9yeS5odG0wEwYDVR0lBAwwCgYIKwYB
# BQUHAwgwGQYJKwYBBAGCNxQCBAweCgBTAHUAYgBDAEEwCwYDVR0PBAQDAgGGMA8G
# A1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAU1fZWy4/oolxiaNE9lJBb186aGMQw
# VgYDVR0fBE8wTTBLoEmgR4ZFaHR0cDovL2NybC5taWNyb3NvZnQuY29tL3BraS9j
# cmwvcHJvZHVjdHMvTWljUm9vQ2VyQXV0XzIwMTAtMDYtMjMuY3JsMFoGCCsGAQUF
# BwEBBE4wTDBKBggrBgEFBQcwAoY+aHR0cDovL3d3dy5taWNyb3NvZnQuY29tL3Br
# aS9jZXJ0cy9NaWNSb29DZXJBdXRfMjAxMC0wNi0yMy5jcnQwDQYJKoZIhvcNAQEL
# BQADggIBAJ1VffwqreEsH2cBMSRb4Z5yS/ypb+pcFLY+TkdkeLEGk5c9MTO1OdfC
# cTY/2mRsfNB1OW27DzHkwo/7bNGhlBgi7ulmZzpTTd2YurYeeNg2LpypglYAA7AF
# vonoaeC6Ce5732pvvinLbtg/SHUB2RjebYIM9W0jVOR4U3UkV7ndn/OOPcbzaN9l
# 9qRWqveVtihVJ9AkvUCgvxm2EhIRXT0n4ECWOKz3+SmJw7wXsFSFQrP8DJ6LGYnn
# 8AtqgcKBGUIZUnWKNsIdw2FzLixre24/LAl4FOmRsqlb30mjdAy87JGA0j3mSj5m
# O0+7hvoyGtmW9I/2kQH2zsZ0/fZMcm8Qq3UwxTSwethQ/gpY3UA8x1RtnWN0SCyx
# TkctwRQEcb9k+SS+c23Kjgm9swFXSVRk2XPXfx5bRAGOWhmRaw2fpCjcZxkoJLo4
# S5pu+yFUa2pFEUep8beuyOiJXk+d0tBMdrVXVAmxaQFEfnyhYWxz/gq77EFmPWn9
# y8FBSX5+k77L+DvktxW/tM4+pTFRhLy/AsGConsXHRWJjXD+57XQKBqJC4822rpM
# +Zv/Cuk0+CQ1ZyvgDbjmjJnW4SLq8CdCPSWU5nR0W2rRnj7tfqAxM328y+l7vzhw
# RNGQ8cirOoo6CGJ/2XBjU02N7oJtpQUQwXEGahC0HVUzWLOhcGbyoYIDVTCCAj0C
# AQEwggEBoYHZpIHWMIHTMQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3Rv
# bjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0
# aW9uMS0wKwYDVQQLEyRNaWNyb3NvZnQgSXJlbGFuZCBPcGVyYXRpb25zIExpbWl0
# ZWQxJzAlBgNVBAsTHm5TaGllbGQgVFNTIEVTTjo0QzFBLTA1RTAtRDk0NzElMCMG
# A1UEAxMcTWljcm9zb2Z0IFRpbWUtU3RhbXAgU2VydmljZaIjCgEBMAcGBSsOAwIa
# AxUAVSn9cWqexOj7PU+4ciWVvBEIvEqggYMwgYCkfjB8MQswCQYDVQQGEwJVUzET
# MBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMV
# TWljcm9zb2Z0IENvcnBvcmF0aW9uMSYwJAYDVQQDEx1NaWNyb3NvZnQgVGltZS1T
# dGFtcCBQQ0EgMjAxMDANBgkqhkiG9w0BAQsFAAIFAO6WW6owIhgPMjAyNjExMDUw
# MTM0MzRaGA8yMDI2MTEwNjAxMzQzNFowczA5BgorBgEEAYRZCgQBMSswKTAKAgUA
# 7pZbqgIBADAGAgEAAgEDMAcCAQACAg7FMAoCBQDul60qAgEAMDYGCisGAQQBhFkK
# BAIxKDAmMAwGCisGAQQBhFkKAwKgCjAIAgEAAgMHoSChCjAIAgEAAgMBhqAwDQYJ
# KoZIhvcNAQELBQADggEBAErxttnFDui6C73G1GXc0eScS8Oe8eK7TR0Omxlsf/zg
# 2eEdF0bjzxBVv5uvr0bvVhqvZsoM3CE0O/WuGry0Ul32ib/aWXrZ2ZqY54pM5Ows
# FLdE6PHd/iDNRUzEltegU4q5k8VOPqyexVse942jdLbsRCgdKneghP7Re1bqzWdZ
# b5ZK5B2cTZpq8F8XAFJ6tPI6kM7ixteeiyDyNNkLqkcwOouDnIfSpj0uG+B0LM4C
# i2fwmsx8bWQf/j46lp3z1jZ1z5Gp/bTmJFZWhDGarbwnTmHJD8H6pfzwHPGiWmt/
# Fu+g5EYLibQhBe4K33EoJMrVcy9D7IgRjoJekyV1QlgxggQNMIIECQIBATCBkzB8
# MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVk
# bW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSYwJAYDVQQDEx1N
# aWNyb3NvZnQgVGltZS1TdGFtcCBQQ0EgMjAxMAITMwAAAjRToWeU4bwYRwABAAAC
# NDANBglghkgBZQMEAgEFAKCCAUowGgYJKoZIhvcNAQkDMQ0GCyqGSIb3DQEJEAEE
# MC8GCSqGSIb3DQEJBDEiBCDmt37yI7773N6pEIoSyviXtjS5BiMrHBkYFCZPnIYl
# ozCB+gYLKoZIhvcNAQkQAi8xgeowgecwgeQwgb0EIEP8vaFTrZ57k68AJbxWZVFs
# JJJaR2PAsnkp3dl7KFFkMIGYMIGApH4wfDELMAkGA1UEBhMCVVMxEzARBgNVBAgT
# Cldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29m
# dCBDb3Jwb3JhdGlvbjEmMCQGA1UEAxMdTWljcm9zb2Z0IFRpbWUtU3RhbXAgUENB
# IDIwMTACEzMAAAI0U6FnlOG8GEcAAQAAAjQwIgQg2TSl/dwKd0rhRLeac6sP3OAt
# 1wH6zc97E6X0qMFw3jowDQYJKoZIhvcNAQELBQAEggIABWKpvjEaON3On4xD56by
# uyq5dDugZF0TECBehestSDKkyJOSnWGQEPZ5vGy0cgw4CgkyV6byDSbGynSRIWJ8
# F2kV5hNVY8y/Ez3lqIIi2X2E6AeZdeYNhDrk2gBbEaCOUR67n/ZClcpCk8R95IbK
# 2/OFTkgUL5wBOJri9cnjABXBRRvyZx4hu+W1Gp8KRs2BDhqk20DK8tH/ymCKTECI
# dWvRFtgJTUnQyRn3LdmJzc36iQ7ga++QmL4n3zREPS7vW/QR5yVO0Eyebhwk9LKA
# jqkm6NaxInvDPLkKWV6t7kkfF+qqo9e1YNRilaZPXKqmVKh331mefmrUaLwB/mJk
# EVbi/pyj1mJe37Dg58ylaIU0T/0g3pzKxB1FCXnfs+TjIwSkajjHE57Qz5aXH/np
# Z+mz6A64DD7U+42WdCwrXbuuZzAisZ4iPS27usdaqfffF+HOczFrou+0eYRkhYSm
# QGdhxxH0pagexaWYHOjtOYRpa0jvCu99i+j/MdkDOnFs1jUMglwB6fhbXnGCEoDP
# Mk8JNR+fUrgdsqXqF/zeGNbJGfvGybm4JrjS9cH1laTsXbY7v1MtBdHfqoO67AW/
# AA0f3Oae4cBpWcqCDQvq8MuLv/GjwYmLDjXfb8GyDLO9YnzvOvBnI0wl04c9BGnX
# 6gA9aB9Yr2q7u6lljFAPScc=
# SIG # End signature block