CompilerFolderHandling/New-BcCompilerFolder.ps1
<#
.SYNOPSIS Create a new Compiler Folder .DESCRIPTION Create a folder containing all the necessary pieces from the artifacts to compile apps without the need of a container Returns a compilerFolder path, which can be used for functions like Compile-AppWithBcCompilerFolder or Remove-BcCompilerFolder .PARAMETER artifactUrl Artifacts URL to download the compiler and all .app files from .PARAMETER containerName Name of the folder in which to create the compiler folder or empty to use a default name consisting of type-version-country .PARAMETER cacheFolder If present: - if the cacheFolder exists, the artifacts will be grabbed from here instead of downloaded. - if the cacheFolder doesn't exist, it is created and populated with the needed content from the ArtifactURL .PARAMETER packagesFolder If present, the symbols/apps will be copied from the compiler folder to this folder as well .PARAMETER vsixFile If present, use this vsixFile instead of the one included in the artifacts .PARAMETER includeAL Include this switch in order to populate folder with AL files (like New-BcContainer) .EXAMPLE $version = $artifactURL.Split('/')[4] $country = $artifactURL.Split('/')[5] $compilerFolder = New-BcCompilerFolder -artifactUrl $artifactURL -includeAL $baseAppSource = Join-Path $compilerFolder "BaseApp" Copy-Item -Path (Join-Path $bcContainerHelperConfig.hostHelperFolder "Extensions\Original-$version-$country-al") $baseAppSource -Container -Recurse Compile-AppWithBcCompilerFolder ` -compilerFolder $compilerFolder ` -appProjectFolder $baseAppSource ` -appOutputFolder (Join-Path $compilerFolder '.output') ` -appSymbolsFolder (Join-Path $compilerFolder 'symbols') ` -CopyAppToSymbolsFolder #> function New-BcCompilerFolder { Param( [string] $artifactUrl, [string] $containerName = '', [string] $cacheFolder = '', [string] $packagesFolder = '', [string] $vsixFile = '', [switch] $includeAL ) $telemetryScope = InitTelemetryScope -name $MyInvocation.InvocationName -parameterValues $PSBoundParameters -includeParameters @() try { $parts = $artifactUrl.Split('?')[0].Split('/') if ($parts.Count -lt 6) { throw "Invalid artifact URL" } $type = $parts[3] $version = [System.Version]($parts[4]) $country = $parts[5] $vsixFile = DetermineVsixFile -vsixFile $vsixFile if ($version -lt "16.0.0.0") { throw "Containerless compiling is not supported with versions before 16.0" } if (!$containerName) { $containerName = [GUID]::NewGuid().ToString() } $compilerFolder = Join-Path $bcContainerHelperConfig.hostHelperFolder "compiler\$containerName" if (Test-Path $compilerFolder) { Remove-Item -Path $compilerFolder -Force -Recurse -ErrorAction Ignore } New-Item -Path $compilerFolder -ItemType Directory -ErrorAction Ignore | Out-Null # Populate artifacts cache if ($cacheFolder) { $symbolsPath = Join-Path $cacheFolder 'symbols' $compilerPath = Join-Path $cacheFolder 'compiler' $dllsPath = Join-Path $cacheFolder 'dlls' } else { $symbolsPath = Join-Path $compilerFolder 'symbols' $compilerPath = Join-Path $compilerFolder 'compiler' $dllsPath = Join-Path $compilerFolder 'dlls' } $newtonSoftDllPath = '' if ($includeAL -or !(Test-Path $symbolsPath)) { $artifactPaths = Download-Artifacts -artifactUrl $artifactUrl -includePlatform $appArtifactPath = $artifactPaths[0] $platformArtifactPath = $artifactPaths[1] $newtonSoftDllPath = Join-Path $platformArtifactPath "ServiceTier\program files\Microsoft Dynamics NAV\*\Service\Newtonsoft.Json.dll" -Resolve } # IncludeAL will populate folder with AL files (like New-BcContainer) if ($includeAL) { $alFolder = Join-Path $bcContainerHelperConfig.hostHelperFolder "Extensions\Original-$version-$country-al" if (!(Test-Path $alFolder) -or (Get-ChildItem -Path $alFolder -Recurse | Measure-Object).Count -eq 0) { if (!(Test-Path $alFolder)) { New-Item $alFolder -ItemType Directory | Out-Null } $countryApplicationsFolder = Join-Path $appArtifactPath "Applications.$country" if (Test-Path $countryApplicationsFolder) { $baseAppSource = @(get-childitem -Path $countryApplicationsFolder -recurse -filter "Base Application.Source.zip") } else { $baseAppSource = @(get-childitem -Path (Join-Path $platformArtifactPath "Applications") -recurse -filter "Base Application.Source.zip") } if ($baseAppSource.Count -ne 1) { throw "Unable to locate Base Application.Source.zip" } Write-Host "Extracting $($baseAppSource[0].FullName)" Expand-7zipArchive -Path $baseAppSource[0].FullName -DestinationPath $alFolder } } # Populate cache folder (or compiler folder) if (!(Test-Path $symbolsPath)) { New-Item $symbolsPath -ItemType Directory | Out-Null New-Item $compilerPath -ItemType Directory | Out-Null New-Item $dllsPath -ItemType Directory | Out-Null $modernDevFolder = Join-Path $platformArtifactPath "ModernDev\program files\Microsoft Dynamics NAV\*\AL Development Environment" -Resolve Copy-Item -Path (Join-Path $modernDevFolder 'System.app') -Destination $symbolsPath if ($cacheFolder -or !$vsixFile) { # Only unpack the artifact vsix file if we are populating a cache folder - or no vsixFile was specified Expand-7zipArchive -Path (Join-Path $modernDevFolder 'ALLanguage.vsix') -DestinationPath $compilerPath } $serviceTierFolder = Join-Path $platformArtifactPath "ServiceTier\program files\Microsoft Dynamics NAV\*\Service" -Resolve Copy-Item -Path $serviceTierFolder -Filter '*.dll' -Destination $dllsPath -Recurse $newtonSoftDllPath = Join-Path $dllsPath "Newtonsoft.Json.dll" Remove-Item -Path (Join-Path $dllsPath 'Service\Management') -Recurse -Force -ErrorAction SilentlyContinue Remove-Item -Path (Join-Path $dllsPath 'Service\WindowsServiceInstaller') -Recurse -Force -ErrorAction SilentlyContinue Remove-Item -Path (Join-Path $dllsPath 'Service\SideServices') -Recurse -Force -ErrorAction SilentlyContinue New-Item -Path (Join-Path $dllsPath 'OpenXML') -ItemType Directory | Out-Null Copy-Item -Path (Join-Path $dllsPath 'Service\DocumentFormat.OpenXml.dll') -Destination (Join-Path $dllsPath 'OpenXML') -Force -ErrorAction SilentlyContinue $testAssembliesFolder = Join-Path $platformArtifactPath "Test Assemblies" -Resolve $testAssembliesDestination = Join-Path $dllsPath "Test Assemblies" New-Item -Path $testAssembliesDestination -ItemType Directory | Out-Null Copy-Item -Path (Join-Path $testAssembliesFolder 'Newtonsoft.Json.dll') -Destination $testAssembliesDestination -Force -ErrorAction SilentlyContinue Copy-Item -Path (Join-Path $testAssembliesFolder 'Microsoft.Dynamics.Framework.UI.Client.dll') -Destination $testAssembliesDestination -Force $mockAssembliesFolder = Join-Path $testAssembliesFolder "Mock Assemblies" -Resolve Copy-Item -Path $mockAssembliesFolder -Filter '*.dll' -Destination $dllsPath -Recurse $extensionsFolder = Join-Path $appArtifactPath 'Extensions' if (Test-Path $extensionsFolder -PathType Container) { Copy-Item -Path (Join-Path $extensionsFolder '*.app') -Destination $symbolsPath $platformAppsPath = Join-Path $platformArtifactPath 'Applications' $appAppsPath = Join-Path $AppArtifactPath 'Applications.*' -Resolve $platformApps = @(Get-ChildItem -Path $platformAppsPath -Filter '*.app' -Recurse) $appApps = @() if ($appAppsPath) { $appApps = @(Get-ChildItem -Path $appAppsPath -Filter '*.app' -Recurse) } 'Microsoft_Tests-*.app','Microsoft_Performance Toolkit Samples*.app','Microsoft_Performance Toolkit Tests*.app','Microsoft_System Application Test Library*.app','Microsoft_TestRunner-Internal*.app','Microsoft_Business Foundation Test Libraries*.app','Microsoft_AI Test Toolkit*.app' | ForEach-Object { $appName = $_ $apps = $appApps | Where-Object { $_.Name -like $appName } if (!$apps) { $apps = $platformApps | Where-Object { $_.Name -like $appName } } $apps | ForEach-Object { Copy-Item -Path $_.FullName -Destination $symbolsPath } } } else { $platformAppsPath = Join-Path $platformArtifactPath 'Applications' $appAppsPath = Join-Path $AppArtifactPath 'Applications' if (Test-Path $appAppsPath -PathType Container) { Get-ChildItem -Path $appAppsPath -Filter '*.app' -Recurse | ForEach-Object { Copy-Item -Path $_.FullName -Destination $symbolsPath } } else { Get-ChildItem -Path $platformAppsPath -Filter '*.app' -Recurse | ForEach-Object { Copy-Item -Path $_.FullName -Destination $symbolsPath } } } } $dotNetSharedFolder = Join-Path $dllsPath 'shared' if ($version -ge "22.0.0.0" -and (!(Test-Path $dotNetSharedFolder)) -and ($dotNetRuntimeVersionInstalled -lt [System.Version]$bcContainerHelperConfig.MinimumDotNetRuntimeVersionStr)) { if ("$dotNetRuntimeVersionInstalled" -eq "0.0.0") { Write-Host "dotnet runtime version is not installed/cannot be used" } else { Write-Host "dotnet runtime version $dotNetRuntimeVersionInstalled is installed, but minimum required version is $($bcContainerHelperConfig.MinimumDotNetRuntimeVersionStr)" } Write-Host "Downloading minimum required dotnet version from $($bcContainerHelperConfig.MinimumDotNetRuntimeVersionUrl)" $dotnetFolder = Join-Path $compilerFolder 'dotnet' $dotnetZipFile = "$($dotnetFolder).zip" Download-File -sourceUrl $bcContainerHelperConfig.MinimumDotNetRuntimeVersionUrl -destinationFile $dotnetZipFile Expand-7zipArchive -Path $dotnetZipFile -DestinationPath $dotnetFolder Move-Item -Path (Join-Path $dotnetFolder 'shared') -Destination $dllsPath Remove-Item -Path $dotnetZipFile -Force Remove-Item -Path $dotnetFolder -Recurse -Force } $containerCompilerPath = Join-Path $compilerFolder 'compiler' if ($vsixFile) { # If a vsix file was specified unpack directly to compilerfolder Write-Host "Using $vsixFile" $tempZip = Join-Path ([System.IO.Path]::GetTempPath()) "alc.$containerName.zip" Download-File -sourceUrl $vsixFile -destinationFile $tempZip Expand-7zipArchive -Path $tempZip -DestinationPath $containerCompilerPath if ($isWindows -and $newtonSoftDllPath) { Copy-Item -Path $newtonSoftDllPath -Destination (Join-Path $containerCompilerPath 'extension\bin') -Force -ErrorAction SilentlyContinue } Remove-Item -Path $tempZip -Force -ErrorAction SilentlyContinue } # If a cacheFolder was specified, the cache folder has been populated if ($cacheFolder) { Write-Host "Copying DLLs from cache" Copy-Item -Path $dllsPath -Filter '*.dll' -Destination $compilerFolder -Recurse -Force Write-Host "Copying symbols from cache" Copy-Item -Path $symbolsPath -Filter '*.app' -Destination $compilerFolder -Recurse -Force # If a vsix file was specified, the compiler folder has been populated if (!$vsixFile) { Write-Host "Copying compiler from cache" Copy-Item -Path $compilerPath -Destination $compilerFolder -Recurse -Force } } # If a packagesFolder was specified, copy symbols from CompilerFolder if ($packagesFolder) { Write-Host "Copying symbols to packagesFolder" New-Item -Path $packagesFolder -ItemType Directory -Force | Out-Null Copy-Item -Path $symbolsPath -Filter '*.app' -Destination $packagesFolder -Force -Recurse } if ($isLinux -or $isMacOS) { $compilerPlatform = 'linux' if ($isMacOS) { $compilerPlatform = 'darwin' } $alcExePath = Join-Path $containerCompilerPath "extension/bin/$($compilerPlatform)/alc" $alToolExePath = Join-Path $containerCompilerPath "extension/bin/$($compilerPlatform)/altool" if (Test-Path $alcExePath) { if (Test-Path $alToolExePath) { # Set execute permissions on altool Write-Host "Setting execute permissions on altool" if ($isLinux) { & /usr/bin/env sudo pwsh -command "& chmod +x $alToolExePath" } else { & chmod +x $alToolExePath } } # Set execute permissions on alc Write-Host "Setting execute permissions on alc" if ($isLinux) { & /usr/bin/env sudo pwsh -command "& chmod +x $alcExePath" } else { & chmod +x $alcExePath } } else { # Patch alc.runtimeconfig.json for use with Linux or macOS Write-Host "Patching alc.runtimeconfig.json for use with $($compilerPlatform)" $alcConfigPath = Join-Path $containerCompilerPath 'extension/bin/win32/alc.runtimeconfig.json' if (Test-Path $alcConfigPath) { $oldAlcConfig = Get-Content -Path $alcConfigPath -Encoding UTF8 | ConvertFrom-Json if ($oldAlcConfig.runtimeOptions.PSObject.Properties.Name -eq 'includedFrameworks') { $newAlcConfig = @{ "runtimeOptions" = @{ "tfm" = "net6.0" "framework" = @{ "name" = "Microsoft.NETCore.App" "version" = $oldAlcConfig.runtimeOptions.includedFrameworks[0].version } "configProperties" = @{ "System.Reflection.Metadata.MetadataUpdater.IsSupported" = $false } } } $newAlcConfig | ConvertTo-Json | Set-Content -Path $alcConfigPath -Encoding utf8NoBOM } } } } Write-Host "Enumerating Apps in $symbolsPath" $compilerFolderAppFiles = @(Get-ChildItem -Path (Join-Path $symbolsPath '*.app') | Select-Object -ExpandProperty FullName) GetAppInfo -AppFiles $compilerFolderAppFiles -compilerFolder $compilerFolder -cacheAppinfoPath (Join-Path $symbolsPath 'cache_AppInfo.json') | Out-Null if ($cacheFolder) { Write-Host "Copying symbols cache" Copy-Item -Path (Join-Path $symbolsPath 'cache_AppInfo.json') -Destination (Join-Path $compilerFolder 'symbols') -Force } $compilerFolder } catch { TrackException -telemetryScope $telemetryScope -errorRecord $_ throw } finally { TrackTrace -telemetryScope $telemetryScope } } Export-ModuleMember -Function New-BcCompilerFolder # SIG # Begin signature block # MIImZgYJKoZIhvcNAQcCoIImVzCCJlMCAQExDzANBglghkgBZQMEAgEFADB5Bgor # BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG # KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCD17WEQm0unz5I6 # BojJv3usb5dOZDnC+SyvcaX2WU4DyqCCH34wggWNMIIEdaADAgECAhAOmxiO+dAt # 5+/bUOIIQBhaMA0GCSqGSIb3DQEBDAUAMGUxCzAJBgNVBAYTAlVTMRUwEwYDVQQK # EwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xJDAiBgNV # BAMTG0RpZ2lDZXJ0IEFzc3VyZWQgSUQgUm9vdCBDQTAeFw0yMjA4MDEwMDAwMDBa # Fw0zMTExMDkyMzU5NTlaMGIxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2Vy # dCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xITAfBgNVBAMTGERpZ2lD # ZXJ0IFRydXN0ZWQgUm9vdCBHNDCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoC # ggIBAL/mkHNo3rvkXUo8MCIwaTPswqclLskhPfKK2FnC4SmnPVirdprNrnsbhA3E # MB/zG6Q4FutWxpdtHauyefLKEdLkX9YFPFIPUh/GnhWlfr6fqVcWWVVyr2iTcMKy # unWZanMylNEQRBAu34LzB4TmdDttceItDBvuINXJIB1jKS3O7F5OyJP4IWGbNOsF # xl7sWxq868nPzaw0QF+xembud8hIqGZXV59UWI4MK7dPpzDZVu7Ke13jrclPXuU1 # 5zHL2pNe3I6PgNq2kZhAkHnDeMe2scS1ahg4AxCN2NQ3pC4FfYj1gj4QkXCrVYJB # MtfbBHMqbpEBfCFM1LyuGwN1XXhm2ToxRJozQL8I11pJpMLmqaBn3aQnvKFPObUR # WBf3JFxGj2T3wWmIdph2PVldQnaHiZdpekjw4KISG2aadMreSx7nDmOu5tTvkpI6 # nj3cAORFJYm2mkQZK37AlLTSYW3rM9nF30sEAMx9HJXDj/chsrIRt7t/8tWMcCxB # YKqxYxhElRp2Yn72gLD76GSmM9GJB+G9t+ZDpBi4pncB4Q+UDCEdslQpJYls5Q5S # UUd0viastkF13nqsX40/ybzTQRESW+UQUOsxxcpyFiIJ33xMdT9j7CFfxCBRa2+x # q4aLT8LWRV+dIPyhHsXAj6KxfgommfXkaS+YHS312amyHeUbAgMBAAGjggE6MIIB # NjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTs1+OC0nFdZEzfLmc/57qYrhwP # TzAfBgNVHSMEGDAWgBRF66Kv9JLLgjEtUYunpyGd823IDzAOBgNVHQ8BAf8EBAMC # AYYweQYIKwYBBQUHAQEEbTBrMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdp # Y2VydC5jb20wQwYIKwYBBQUHMAKGN2h0dHA6Ly9jYWNlcnRzLmRpZ2ljZXJ0LmNv # bS9EaWdpQ2VydEFzc3VyZWRJRFJvb3RDQS5jcnQwRQYDVR0fBD4wPDA6oDigNoY0 # aHR0cDovL2NybDMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEUm9vdENB # LmNybDARBgNVHSAECjAIMAYGBFUdIAAwDQYJKoZIhvcNAQEMBQADggEBAHCgv0Nc # Vec4X6CjdBs9thbX979XB72arKGHLOyFXqkauyL4hxppVCLtpIh3bb0aFPQTSnov # Lbc47/T/gLn4offyct4kvFIDyE7QKt76LVbP+fT3rDB6mouyXtTP0UNEm0Mh65Zy # oUi0mcudT6cGAxN3J0TU53/oWajwvy8LpunyNDzs9wPHh6jSTEAZNUZqaVSwuKFW # juyk1T3osdz9HNj0d1pcVIxv76FQPfx2CWiEn2/K2yCNNWAcAgPLILCsWKAOQGPF # mCLBsln1VWvPJ6tsds5vIy30fnFqI2si/xK4VC0nftg62fC2h5b9W9FcrBjDTZ9z # twGpn1eqXijiuZQwggYaMIIEAqADAgECAhBiHW0MUgGeO5B5FSCJIRwKMA0GCSqG # SIb3DQEBDAUAMFYxCzAJBgNVBAYTAkdCMRgwFgYDVQQKEw9TZWN0aWdvIExpbWl0 # ZWQxLTArBgNVBAMTJFNlY3RpZ28gUHVibGljIENvZGUgU2lnbmluZyBSb290IFI0 # NjAeFw0yMTAzMjIwMDAwMDBaFw0zNjAzMjEyMzU5NTlaMFQxCzAJBgNVBAYTAkdC # MRgwFgYDVQQKEw9TZWN0aWdvIExpbWl0ZWQxKzApBgNVBAMTIlNlY3RpZ28gUHVi # bGljIENvZGUgU2lnbmluZyBDQSBSMzYwggGiMA0GCSqGSIb3DQEBAQUAA4IBjwAw # ggGKAoIBgQCbK51T+jU/jmAGQ2rAz/V/9shTUxjIztNsfvxYB5UXeWUzCxEeAEZG # bEN4QMgCsJLZUKhWThj/yPqy0iSZhXkZ6Pg2A2NVDgFigOMYzB2OKhdqfWGVoYW3 # haT29PSTahYkwmMv0b/83nbeECbiMXhSOtbam+/36F09fy1tsB8je/RV0mIk8XL/ # tfCK6cPuYHE215wzrK0h1SWHTxPbPuYkRdkP05ZwmRmTnAO5/arnY83jeNzhP06S # hdnRqtZlV59+8yv+KIhE5ILMqgOZYAENHNX9SJDm+qxp4VqpB3MV/h53yl41aHU5 # pledi9lCBbH9JeIkNFICiVHNkRmq4TpxtwfvjsUedyz8rNyfQJy/aOs5b4s+ac7I # H60B+Ja7TVM+EKv1WuTGwcLmoU3FpOFMbmPj8pz44MPZ1f9+YEQIQty/NQd/2yGg # W+ufflcZ/ZE9o1M7a5Jnqf2i2/uMSWymR8r2oQBMdlyh2n5HirY4jKnFH/9gRvd+ # QOfdRrJZb1sCAwEAAaOCAWQwggFgMB8GA1UdIwQYMBaAFDLrkpr/NZZILyhAQnAg # NpFcF4XmMB0GA1UdDgQWBBQPKssghyi47G9IritUpimqF6TNDDAOBgNVHQ8BAf8E # BAMCAYYwEgYDVR0TAQH/BAgwBgEB/wIBADATBgNVHSUEDDAKBggrBgEFBQcDAzAb # BgNVHSAEFDASMAYGBFUdIAAwCAYGZ4EMAQQBMEsGA1UdHwREMEIwQKA+oDyGOmh0 # dHA6Ly9jcmwuc2VjdGlnby5jb20vU2VjdGlnb1B1YmxpY0NvZGVTaWduaW5nUm9v # dFI0Ni5jcmwwewYIKwYBBQUHAQEEbzBtMEYGCCsGAQUFBzAChjpodHRwOi8vY3J0 # LnNlY3RpZ28uY29tL1NlY3RpZ29QdWJsaWNDb2RlU2lnbmluZ1Jvb3RSNDYucDdj # MCMGCCsGAQUFBzABhhdodHRwOi8vb2NzcC5zZWN0aWdvLmNvbTANBgkqhkiG9w0B # AQwFAAOCAgEABv+C4XdjNm57oRUgmxP/BP6YdURhw1aVcdGRP4Wh60BAscjW4HL9 # hcpkOTz5jUug2oeunbYAowbFC2AKK+cMcXIBD0ZdOaWTsyNyBBsMLHqafvIhrCym # laS98+QpoBCyKppP0OcxYEdU0hpsaqBBIZOtBajjcw5+w/KeFvPYfLF/ldYpmlG+ # vd0xqlqd099iChnyIMvY5HexjO2AmtsbpVn0OhNcWbWDRF/3sBp6fWXhz7DcML4i # TAWS+MVXeNLj1lJziVKEoroGs9Mlizg0bUMbOalOhOfCipnx8CaLZeVme5yELg09 # Jlo8BMe80jO37PU8ejfkP9/uPak7VLwELKxAMcJszkyeiaerlphwoKx1uHRzNyE6 # bxuSKcutisqmKL5OTunAvtONEoteSiabkPVSZ2z76mKnzAfZxCl/3dq3dUNw4rg3 # sTCggkHSRqTqlLMS7gjrhTqBmzu1L90Y1KWN/Y5JKdGvspbOrTfOXyXvmPL6E52z # 1NZJ6ctuMFBQZH3pwWvqURR8AgQdULUvrxjUYbHHj95Ejza63zdrEcxWLDX6xWls # /GDnVNueKjWUH3fTv1Y8Wdho698YADR7TNx8X8z2Bev6SivBBOHY+uqiirZtg0y9 # ShQoPzmCcn63Syatatvx157YK9hlcPmVoa1oDE5/L9Uo2bC5a4CH2RwwggZZMIIE # waADAgECAhANIM3qwHRbWKHw+Zq6JhzlMA0GCSqGSIb3DQEBDAUAMFQxCzAJBgNV # BAYTAkdCMRgwFgYDVQQKEw9TZWN0aWdvIExpbWl0ZWQxKzApBgNVBAMTIlNlY3Rp # Z28gUHVibGljIENvZGUgU2lnbmluZyBDQSBSMzYwHhcNMjExMDIyMDAwMDAwWhcN # MjQxMDIxMjM1OTU5WjBdMQswCQYDVQQGEwJESzEUMBIGA1UECAwLSG92ZWRzdGFk # ZW4xGzAZBgNVBAoMEkZyZWRkeSBLcmlzdGlhbnNlbjEbMBkGA1UEAwwSRnJlZGR5 # IEtyaXN0aWFuc2VuMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAgYC5 # tlg+VRktRRkahxxaV8+DAd6vHoDpcO6w7yT24lnSoMuA6nR7kgy90Y/sHIwKE9Ww # t/px/GAY8eBePWjJrFpG8fBtJbXadRTVd/470Hs/q9t+kh6A/0ELj7wYsKSNOyuF # Poy4rtClOv9ZmrRpoDVnh8Epwg2DpklX2BNzykzBQxIbkpp+xVo2mhPNWDIesntc # 4/BnSebLGw1Vkxmu2acKkIjYrne/7lsuyL9ue0vk8TGk9JBPNPbGKJvHu9szP9oG # oH36fU1sEZ+AacXrp+onsyPf/hkkpAMHAhzQHl+5Ikvcus/cDm06twm7VywmZcas # 2rFAV5MyE6WMEaYAolwAHiPz9WAs2GDhFtZZg1tzbRjJIIgPpR+doTIcpcDBcHnN # dSdgWKrTkr2f339oT5bnJfo7oVzc/2HGWvb8Fom6LQAqSC11vWmznHYsCm72g+fo # TKqW8lLDfLF0+aFvToLosrtW9l6Z+l+RQ8MtJ9EHOm2Ny8cFLzZCDZYw32BydwcL # V5rKdy4Ica9on5xZvyMOLiFwuL4v2V4pjEgKJaGSS/IVSMEGjrM9DHT6YS4/oq9q # 20rQUmMZZQmGmEyyKQ8t11si8VHtScN5m0Li8peoWfCU9mRFxSESwTWow8d462+o # 9/SzmDxCACdFwzvfKx4JqDMm55cL+beunIvc0NsCAwEAAaOCAZwwggGYMB8GA1Ud # IwQYMBaAFA8qyyCHKLjsb0iuK1SmKaoXpM0MMB0GA1UdDgQWBBTZD6uy9ZWIIqQh # 3srYu1FlUhdM0TAOBgNVHQ8BAf8EBAMCB4AwDAYDVR0TAQH/BAIwADATBgNVHSUE # DDAKBggrBgEFBQcDAzARBglghkgBhvhCAQEEBAMCBBAwSgYDVR0gBEMwQTA1Bgwr # BgEEAbIxAQIBAwIwJTAjBggrBgEFBQcCARYXaHR0cHM6Ly9zZWN0aWdvLmNvbS9D # UFMwCAYGZ4EMAQQBMEkGA1UdHwRCMEAwPqA8oDqGOGh0dHA6Ly9jcmwuc2VjdGln # by5jb20vU2VjdGlnb1B1YmxpY0NvZGVTaWduaW5nQ0FSMzYuY3JsMHkGCCsGAQUF # BwEBBG0wazBEBggrBgEFBQcwAoY4aHR0cDovL2NydC5zZWN0aWdvLmNvbS9TZWN0 # aWdvUHVibGljQ29kZVNpZ25pbmdDQVIzNi5jcnQwIwYIKwYBBQUHMAGGF2h0dHA6 # Ly9vY3NwLnNlY3RpZ28uY29tMA0GCSqGSIb3DQEBDAUAA4IBgQASEbZACurQeQN8 # WDTR+YyNpoQ29YAbbdBRhhzHkT/1ao7LE0QIOgGR4GwKRzufCAwu8pCBiMOUTDHT # ezkh0rQrG6khxBX2nSTBL5i4LwKMR08HgZBsbECciABy15yexYWoB/D0H8WuGe63 # PhGWueR4IFPbIz+jEVxfW0Nyyr7bXTecpKd1iprm+TOmzc2E6ab95dkcXdJVx6Zy # s++QrrOfQ+a57qEXkS/wnjjbN9hukL0zg+g8L4DHLKTodzfiQOampvV8QzbnB7Y8 # YjNcxR9s/nptnlQH3jorNFhktiBXvD62jc8pAIg6wyH6NxSMjtTsn7QhkIp2kusw # IQwD8hN/fZ/m6gkXZhRJWFr2WRZOz+edZ62Jf25C/NYWscwfBwn2hzRZf1HgyxkX # Al88dvvUA3kw1T6uo8aAB9IcL6Owiy7q4T+RLRF7oqx0vcw0193Yhq/gPOaUFlqz # ExP6TQ5TR9XWVPQk+a1B1ATKMLi1JShO6KWTmNkFkgkgpkW69BEwggauMIIElqAD # AgECAhAHNje3JFR82Ees/ShmKl5bMA0GCSqGSIb3DQEBCwUAMGIxCzAJBgNVBAYT # AlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2Vy # dC5jb20xITAfBgNVBAMTGERpZ2lDZXJ0IFRydXN0ZWQgUm9vdCBHNDAeFw0yMjAz # MjMwMDAwMDBaFw0zNzAzMjIyMzU5NTlaMGMxCzAJBgNVBAYTAlVTMRcwFQYDVQQK # Ew5EaWdpQ2VydCwgSW5jLjE7MDkGA1UEAxMyRGlnaUNlcnQgVHJ1c3RlZCBHNCBS # U0E0MDk2IFNIQTI1NiBUaW1lU3RhbXBpbmcgQ0EwggIiMA0GCSqGSIb3DQEBAQUA # A4ICDwAwggIKAoICAQDGhjUGSbPBPXJJUVXHJQPE8pE3qZdRodbSg9GeTKJtoLDM # g/la9hGhRBVCX6SI82j6ffOciQt/nR+eDzMfUBMLJnOWbfhXqAJ9/UO0hNoR8XOx # s+4rgISKIhjf69o9xBd/qxkrPkLcZ47qUT3w1lbU5ygt69OxtXXnHwZljZQp09ns # ad/ZkIdGAHvbREGJ3HxqV3rwN3mfXazL6IRktFLydkf3YYMZ3V+0VAshaG43IbtA # rF+y3kp9zvU5EmfvDqVjbOSmxR3NNg1c1eYbqMFkdECnwHLFuk4fsbVYTXn+149z # k6wsOeKlSNbwsDETqVcplicu9Yemj052FVUmcJgmf6AaRyBD40NjgHt1biclkJg6 # OBGz9vae5jtb7IHeIhTZgirHkr+g3uM+onP65x9abJTyUpURK1h0QCirc0PO30qh # HGs4xSnzyqqWc0Jon7ZGs506o9UD4L/wojzKQtwYSH8UNM/STKvvmz3+DrhkKvp1 # KCRB7UK/BZxmSVJQ9FHzNklNiyDSLFc1eSuo80VgvCONWPfcYd6T/jnA+bIwpUzX # 6ZhKWD7TA4j+s4/TXkt2ElGTyYwMO1uKIqjBJgj5FBASA31fI7tk42PgpuE+9sJ0 # sj8eCXbsq11GdeJgo1gJASgADoRU7s7pXcheMBK9Rp6103a50g5rmQzSM7TNsQID # AQABo4IBXTCCAVkwEgYDVR0TAQH/BAgwBgEB/wIBADAdBgNVHQ4EFgQUuhbZbU2F # L3MpdpovdYxqII+eyG8wHwYDVR0jBBgwFoAU7NfjgtJxXWRM3y5nP+e6mK4cD08w # DgYDVR0PAQH/BAQDAgGGMBMGA1UdJQQMMAoGCCsGAQUFBwMIMHcGCCsGAQUFBwEB # BGswaTAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQuY29tMEEGCCsG # AQUFBzAChjVodHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vRGlnaUNlcnRUcnVz # dGVkUm9vdEc0LmNydDBDBgNVHR8EPDA6MDigNqA0hjJodHRwOi8vY3JsMy5kaWdp # Y2VydC5jb20vRGlnaUNlcnRUcnVzdGVkUm9vdEc0LmNybDAgBgNVHSAEGTAXMAgG # BmeBDAEEAjALBglghkgBhv1sBwEwDQYJKoZIhvcNAQELBQADggIBAH1ZjsCTtm+Y # qUQiAX5m1tghQuGwGC4QTRPPMFPOvxj7x1Bd4ksp+3CKDaopafxpwc8dB+k+YMjY # C+VcW9dth/qEICU0MWfNthKWb8RQTGIdDAiCqBa9qVbPFXONASIlzpVpP0d3+3J0 # FNf/q0+KLHqrhc1DX+1gtqpPkWaeLJ7giqzl/Yy8ZCaHbJK9nXzQcAp876i8dU+6 # WvepELJd6f8oVInw1YpxdmXazPByoyP6wCeCRK6ZJxurJB4mwbfeKuv2nrF5mYGj # VoarCkXJ38SNoOeY+/umnXKvxMfBwWpx2cYTgAnEtp/Nh4cku0+jSbl3ZpHxcpzp # SwJSpzd+k1OsOx0ISQ+UzTl63f8lY5knLD0/a6fxZsNBzU+2QJshIUDQtxMkzdwd # eDrknq3lNHGS1yZr5Dhzq6YBT70/O3itTK37xJV77QpfMzmHQXh6OOmc4d0j/R0o # 08f56PGYX/sr2H7yRp11LB4nLCbbbxV7HhmLNriT1ObyF5lZynDwN7+YAN8gFk8n # +2BnFqFmut1VwDophrCYoCvtlUG3OtUVmDG0YgkPCr2B2RP+v6TR81fZvAT6gt4y # 3wSJ8ADNXcL50CN/AAvkdgIm2fBldkKmKYcJRyvmfxqkhQ/8mJb2VVQrH4D6wPIO # K+XW+6kvRBVK5xMOHds3OBqhK/bt1nz8MIIGvDCCBKSgAwIBAgIQC65mvFq6f5WH # xvnpBOMzBDANBgkqhkiG9w0BAQsFADBjMQswCQYDVQQGEwJVUzEXMBUGA1UEChMO # RGlnaUNlcnQsIEluYy4xOzA5BgNVBAMTMkRpZ2lDZXJ0IFRydXN0ZWQgRzQgUlNB # NDA5NiBTSEEyNTYgVGltZVN0YW1waW5nIENBMB4XDTI0MDkyNjAwMDAwMFoXDTM1 # MTEyNTIzNTk1OVowQjELMAkGA1UEBhMCVVMxETAPBgNVBAoTCERpZ2lDZXJ0MSAw # HgYDVQQDExdEaWdpQ2VydCBUaW1lc3RhbXAgMjAyNDCCAiIwDQYJKoZIhvcNAQEB # BQADggIPADCCAgoCggIBAL5qc5/2lSGrljC6W23mWaO16P2RHxjEiDtqmeOlwf0K # MCBDEr4IxHRGd7+L660x5XltSVhhK64zi9CeC9B6lUdXM0s71EOcRe8+CEJp+3R2 # O8oo76EO7o5tLuslxdr9Qq82aKcpA9O//X6QE+AcaU/byaCagLD/GLoUb35SfWHh # 43rOH3bpLEx7pZ7avVnpUVmPvkxT8c2a2yC0WMp8hMu60tZR0ChaV76Nhnj37DEY # TX9ReNZ8hIOYe4jl7/r419CvEYVIrH6sN00yx49boUuumF9i2T8UuKGn9966fR5X # 6kgXj3o5WHhHVO+NBikDO0mlUh902wS/Eeh8F/UFaRp1z5SnROHwSJ+QQRZ1fisD # 8UTVDSupWJNstVkiqLq+ISTdEjJKGjVfIcsgA4l9cbk8Smlzddh4EfvFrpVNnes4 # c16Jidj5XiPVdsn5n10jxmGpxoMc6iPkoaDhi6JjHd5ibfdp5uzIXp4P0wXkgNs+ # CO/CacBqU0R4k+8h6gYldp4FCMgrXdKWfM4N0u25OEAuEa3JyidxW48jwBqIJqIm # d93NRxvd1aepSeNeREXAu2xUDEW8aqzFQDYmr9ZONuc2MhTMizchNULpUEoA6Vva # 7b1XCB+1rxvbKmLqfY/M/SdV6mwWTyeVy5Z/JkvMFpnQy5wR14GJcv6dQ4aEKOX5 # AgMBAAGjggGLMIIBhzAOBgNVHQ8BAf8EBAMCB4AwDAYDVR0TAQH/BAIwADAWBgNV # HSUBAf8EDDAKBggrBgEFBQcDCDAgBgNVHSAEGTAXMAgGBmeBDAEEAjALBglghkgB # hv1sBwEwHwYDVR0jBBgwFoAUuhbZbU2FL3MpdpovdYxqII+eyG8wHQYDVR0OBBYE # FJ9XLAN3DigVkGalY17uT5IfdqBbMFoGA1UdHwRTMFEwT6BNoEuGSWh0dHA6Ly9j # cmwzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydFRydXN0ZWRHNFJTQTQwOTZTSEEyNTZU # aW1lU3RhbXBpbmdDQS5jcmwwgZAGCCsGAQUFBwEBBIGDMIGAMCQGCCsGAQUFBzAB # hhhodHRwOi8vb2NzcC5kaWdpY2VydC5jb20wWAYIKwYBBQUHMAKGTGh0dHA6Ly9j # YWNlcnRzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydFRydXN0ZWRHNFJTQTQwOTZTSEEy # NTZUaW1lU3RhbXBpbmdDQS5jcnQwDQYJKoZIhvcNAQELBQADggIBAD2tHh92mVvj # OIQSR9lDkfYR25tOCB3RKE/P09x7gUsmXqt40ouRl3lj+8QioVYq3igpwrPvBmZd # rlWBb0HvqT00nFSXgmUrDKNSQqGTdpjHsPy+LaalTW0qVjvUBhcHzBMutB6Hzele # dbDCzFzUy34VarPnvIWrqVogK0qM8gJhh/+qDEAIdO/KkYesLyTVOoJ4eTq7gj9U # FAL1UruJKlTnCVaM2UeUUW/8z3fvjxhN6hdT98Vr2FYlCS7Mbb4Hv5swO+aAXxWU # m3WpByXtgVQxiBlTVYzqfLDbe9PpBKDBfk+rabTFDZXoUke7zPgtd7/fvWTlCs30 # VAGEsshJmLbJ6ZbQ/xll/HjO9JbNVekBv2Tgem+mLptR7yIrpaidRJXrI+UzB6vA # lk/8a1u7cIqV0yef4uaZFORNekUgQHTqddmsPCEIYQP7xGxZBIhdmm4bhYsVA6G2 # WgNFYagLDBzpmk9104WQzYuVNsxyoVLObhx3RugaEGru+SojW4dHPoWrUhftNpFC # 5H7QEY7MhKRyrBe7ucykW7eaCuWBsBb4HOKRFVDcrZgdwaSIqMDiCLg4D+TPVgKx # 2EgEdeoHNHT9l3ZDBD+XgbF+23/zBjeCtxz+dL/9NWR6P2eZRi7zcEO1xwcdcqJs # yz/JceENc2Sg8h3KeFUCS7tpFk7CrDqkMYIGPjCCBjoCAQEwaDBUMQswCQYDVQQG # EwJHQjEYMBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMSswKQYDVQQDEyJTZWN0aWdv # IFB1YmxpYyBDb2RlIFNpZ25pbmcgQ0EgUjM2AhANIM3qwHRbWKHw+Zq6JhzlMA0G # CWCGSAFlAwQCAQUAoIGEMBgGCisGAQQBgjcCAQwxCjAIoAKAAKECgAAwGQYJKoZI # hvcNAQkDMQwGCisGAQQBgjcCAQQwHAYKKwYBBAGCNwIBCzEOMAwGCisGAQQBgjcC # ARUwLwYJKoZIhvcNAQkEMSIEIMyl7TsUS5D+1PHjoTfL1dA5oX78X7EoU2dsbYNx # VXtxMA0GCSqGSIb3DQEBAQUABIICAEmnYrnGgXZA/OJzml39TvOAIIEVPmXU3FcR # vuBCdEX0q30812odpGwzuzjXXyptv3n9amQIeVasjxWoU+WtWcwpEtDD/49GAc42 # +YKRFJuPnZy3CQ8QSDbFfkN2rheBwSRBe09M4ljEjcahVoTGNO3s0dVJB/08AScI # lnO2FXx3L74YPNu2cgWDXlTd4PDXxvljMqoXHbUD3Mda6hjV2ZoL75KiQ0r0cgNC # I4Rgpj+4tNPR9bW5Ul+Uy0PuR8qw/OvMM0aAiNTP4UOOnkE0NTbgTDy+5Chua8OP # fpGBV6noHesMg2fV4s0iC+/Yqy/uemHA7gB84/nvhhH8PU7ouQrA31nbKUSKn+zE # Sm/rTs1lT6QI2iVFCgglqHOx0ws++CMTYs1EeVj0Mz5CeOCIfIxnZpFw/ANbunew # c9M2sAM3k0rVRlomtRIuvGE1QxbcdxnuUgT1JUzhTndq4Ic8kXkmr5Q3qoIMkJes # E7l1EQCFTHpS5vVW1ue6wVGRkynpA6ghgLSmToYtWGppCFZ6U3HERSMV1aksGj9S # NHCaBLLVOAd7uxZtSReAp8+vjIYh4jqy0n1ovJIwFU3qSdVA6qWyoOJowa8eSjJJ # NL2rt7odBBATezb+vjipBtnTyOZLPE+5AOxcYEt/98VDsCo5KENrR72k9jbJONDH # kFHi4OZCoYIDIDCCAxwGCSqGSIb3DQEJBjGCAw0wggMJAgEBMHcwYzELMAkGA1UE # BhMCVVMxFzAVBgNVBAoTDkRpZ2lDZXJ0LCBJbmMuMTswOQYDVQQDEzJEaWdpQ2Vy # dCBUcnVzdGVkIEc0IFJTQTQwOTYgU0hBMjU2IFRpbWVTdGFtcGluZyBDQQIQC65m # vFq6f5WHxvnpBOMzBDANBglghkgBZQMEAgEFAKBpMBgGCSqGSIb3DQEJAzELBgkq # hkiG9w0BBwEwHAYJKoZIhvcNAQkFMQ8XDTI0MTAxNTA4NTIwOVowLwYJKoZIhvcN # AQkEMSIEIHV0GU6FYaQF9Bv4NIIFhLE7ochSfESJ1zPRUddRQcSkMA0GCSqGSIb3 # DQEBAQUABIICALhd9Yy7ryw6DotebNgRWqvf6YeYEFCcSMp3El8b2U4FWV3hVib8 # J3JF8mteuh2BP5UyuJ91c/bkeQHZKdS+MSDcSmN31gvbB2vpWrfeDJQw9gll/uTr # 8FLTXitLVFyZS9LGzdrKBI+AhDaKOFSjxEOkBTcxORHkIX7IdOzGOgKbWihXopJy # T2TPQQlb4yJrYnloKGDiojrS8SB0BiuxLr2YGlmrerduzAj+VzsQE9aQuG3d7xGX # t7I87tcodEmFTTVZ4I/ru5nReKv2hrwr+YkpJCY3h+exDzjoEd53JdO8BPXL/P09 # UTEpF8NV+bo2p6156qZGI7zxOENhT4NHeXrjEXjf3wJJsWSoIXzbj6MiKq0Pbcxz # UQvEj0TeOr59VK4OWIsb14G+BKehkk6WTszTU2nDz5rXuaoO0lyAeKmqeDL0N/XW # zuIar6puG6q701Pe+KlBSe6H2544DmZwkMkYVL0gltH+VPouYkg/Oc0LvnBgk0o7 # VFbwYPo1Hvd6jBU2b5fFq821bKNziLcGjPIyRaOCrVOi/W1DRFRbCcC9RoA5EzVe # 4GWk39JwCXMx7eX6ouXq87hV/0c9Pv/ypPewiab+KGg4EFB0HigEEvKsLj4KzzuE # +tgHUX3JXe2YZYA2HSK6eX+AE9qDbVeW2KQfrUZdXW5ceyuU6wGPTIwW # SIG # End signature block |