Container/New-BCDevContainer.ps1

Function New-BCDevContainer {
    param (
        [Parameter(Mandatory = $false)] [ValidateSet('bricklead', 'primus-by-bricklead')][string]$DevOpsSignature = 'bricklead',
        [Parameter(Mandatory = $false)] [ValidateSet("Sandbox", "OnPrem")][string]$SubVersion = 'Sandbox',
        [Parameter(Mandatory = $false)] [ValidateSet("AppSource", "Master", "Release-Candidate")] [string]$SourceApp = 'Release-Candidate',
        [Parameter(Mandatory = $false)] [boolean]$launchBrowser = $true,
        [switch]$CopyCRONUS,
        [switch]$NoTestLibrary,
        [switch]$Insider,
        [Switch]$NoCleanArtifact
    )

    Clear-Host
    $DevOpsSignature = $DevOpsSignature.ToLower()
    $Profil = "Consultant"
    if (Test-Path "$($env:USERPROFILE)\.vscode\extensions\ms-dynamics-smb.al-*") {
        $Profil = "Developer"
    }
    if ($NoTestLibrary) {
        $Profil = "Consultant"
    }
    #Checking container permissions
    Write-Host "Checking container permissions" -foregroun Yellow
    Check-BcContainerHelperPermissions -Fix
    # Version
    Write-Host
    Write-Host "Getting D365BC $SubVersion Artifacts..." -foregroun Yellow
    $TempJson = "$env:TEMP\$([Guid]::newguid().ToString()).json"
    $SourceVersion = 'https://bribcextension.blob.core.windows.net/devops/bcartifactversion/bc' + $SubVersion
    if ($insider) {
        $SourceVersion += 'insider'
    }
    $SourceVersion += '.json'
    Get-BCDevFile -SourceURl $SourceVersion.ToLowerInvariant() -destination $TempJson
    $BCVersions = Get-Content $TempJson | ConvertFrom-Json
    Remove-Item $TempJson -Force -ErrorAction SilentlyContinue
    # Master
    $VersionMajor = $BCVersions.Major | Sort-Object | Get-Unique
    if ($VersionMajor.length -gt 1) {
        $VersionMajor = Get-Choice -ChoiceList $VersionMajor -DefaultChoice ($VersionMajor.Length - 1)
    }
    # Minor
    $VersionMinor = ($BCVersions | Where-Object Major -eq $VersionMajor).Minor | Sort-Object | Get-Unique
    if ($VersionMinor.length -gt 1) {
        $VersionMinor = Get-Choice -Caption "Please select a cumulative update" -ChoiceList $VersionMinor -DefaultChoice ($VersionMinor.Length - 1)
    }
    # Country
    $Countries = ($BCVersions | Where-Object Major -eq $VersionMajor | Where-Object Minor -EQ $VersionMinor).country
    if ($Countries.Length -gt 2) {
        $Countries = @("base") + $Countries
    }
    if ($Countries.length -gt 1) {
        $Default = ($Countries.IndexOf("fr"))
        if (($Profil -eq "Developer") -and ($Countries.IndexOf("base") -gt -1 )) {
            $Default = ($Countries.IndexOf("base"))
        }
        $Country = Get-Choice -Caption "Please select a country version" -ChoiceList $Countries -DefaultChoice $Default
    }
    # Get Artifact
    Write-Host "Getting latest D365BC $SubVersion $VersionMajor.$VersionMinor $Countru Artifacts..." -foregroun Yellow
    if ($Insider) {
        $ArtifactURL = Get-BCArtifactUrl -type $SubVersion -Version "$VersionMajor.$VersionMinor" -country $Country -storageAccount bcinsider -accept_insiderEula
    }
    else {
        $ArtifactURL = Get-BCArtifactUrl -type $SubVersion -Version "$VersionMajor.$VersionMinor" -country $Country
    }
    Write-Host
    Write-Host "Container version : $($ArtifactURL.split('/')[3]) $($ArtifactURL.split('/')[4]) $($ArtifactURL.split('/')[5])" -ForegroundColor Green
    # License File
    $LicenseTemp = "$env:TEMP\$([Guid]::newguid().ToString())"
    if ($ArtifactURL.Split('/')[4].Split('.')[0] -ge 22) { $LicenseSignature = 'bclicense' } else { $LicenseSignature = 'flf' };
    $LicenseCountry = $Country;
    if ($LicenseCountry -eq 'base') { $LicenseCountry = 'w1' };
    Try {
        $LicenseUrl = "https://bribcresource.blob.core.windows.net/resource/license/$DevOpsSignature/$VersionMajor/$LicenseCountry.$LicenseSignature".ToLowerInvariant()
        Get-BCDevFile -SourceURL $LicenseUrl -destination $LicenseTemp
        Write-Host "License : $DevOpsSignature - $VersionMajor $LicenseCountry" -ForegroundColor Green
    }
    catch {
        Try {
            $LicenseUrl = "https://bribcresource.blob.core.windows.net/resource/license/$DevOpsSignature/$VersionMajor/w1.$LicenseSignature".ToLowerInvariant()
            Get-BCDevFile -SourceURL $LicenseUrl -destination $LicenseTemp
            Write-Host "License : $DevOpsSignature - $VersionMajor w1" -ForegroundColor Green
        }
        catch {
            Try {
                $LicenseUrl = "https://bribcresource.blob.core.windows.net/resource/license/$DevOpsSignature/latest/$LicenseCountry.$LicenseSignature".ToLowerInvariant()
                Get-BCDevFile -SourceURL $LicenseUrl -destination $LicenseTemp
                Write-Host "License : $DevOpsSignature - latest $LicenseCountry" -ForegroundColor Green
            }
            catch {
                $LicenseUrl = "https://bribcresource.blob.core.windows.net/resource/license/$DevOpsSignature/latest/w1.$LicenseSignature".ToLowerInvariant()
                Get-BCDevFile -SourceURL $LicenseUrl -destination $LicenseTemp
                Write-Host "License : $DevOpsSignature - latest w1" -ForegroundColor Green
            }
        }
    }
    Remove-Item -Path $LicenseTemp -ErrorAction SilentlyContinue
    # Container Name
    $ContainerName = ($SubVersion + $VersionMajor + '-' + $VersionMinor + '-' + $Country).ToLower()
    $ContainerName = $ContainerName.Replace('-0', '').Replace('-base', '')
    Write-Host
    $ContainerName = Get-FromUser -Message "Container Name" -DefaultValue $ContainerName
    $ContainerName = $ContainerName.ToLower()
    # Select Extension to Insert
    $TempJson = "$env:TEMP\$([Guid]::NewGuid().ToString()).json"
    Get-BCDevFile -SourceURl "https://bribcextension.blob.core.windows.net/devops/availability/$DevOpsSignature/available-extensions.json" -destination $TempJson
    $ExtensionList = (Get-Content $TempJson | ConvertFrom-Json).extension.Name | Sort-Object
    Remove-Item $TempJson -Force -ErrorAction SilentlyContinue
    $AddExtensions = Get-FromList -Values $ExtensionList
    # Not a Developpement License
    if ($null -eq (Select-String -Path $LicenseTemp -Pattern "Solution Developer")) {
        $Profil = "Consultant"
    }
    # Credentials
    $AdminCredential = New-Object System.Management.Automation.PSCredential -argumentList "ADMIN", (ConvertTo-SecureString -String "P@ssword1" -AsPlainText -Force)
    # Shortcuts Folder
    $NewShortcutsFolder = "$($bcContainerHelperConfig.hostHelperFolder)\Extensions\$ContainerName\Shortcuts"
    $AppsFolder = "$($bcContainerHelperConfig.hostHelperFolder)\Extensions\$ContainerName\Apps"
    Remove-Item -Path $NewShortcutsFolder -Recurse -ErrorAction SilentlyContinue -Force | Out-Null
    # Build Container arguments
    $arguments = @{}
    $arguments.containerName = $ContainerName
    $arguments.accept_eula = $true
    $arguments.accept_insiderEula = $true
    $arguments.accept_outdated = $true
    $arguments.alwaysPull = $true
    $arguments.auth = "NavUserPassword"
    $arguments.Credential = $AdminCredential
    $arguments.artifactUrl = $ArtifactURL
    $arguments.memoryLimit = "8G"
    $arguments.licenseFile = $LicenseURL
    $arguments.shortcuts = "Desktop"
    $arguments.assignPremiumPlan = $true
    $arguments.updateHosts = $true
    $arguments.UseBestContainerOS = $true
    $arguments.enableTaskScheduler = $true
    $arguments.timeout = -1
    # $arguments.isolation = "hyperv" ### In case of fail
    if ($Profil -eq "Developer") {
        $arguments.includeTestToolkit = $true
        $arguments.includeTestLibrariesOnly = $true
        if ($VersionMajor -eq 14) {
            $arguments.includeCSide = $true
            $arguments.doNotExportObjectsToText = $true
            $arguments.enableSymbolLoading = $true
        }
    }


    Clear-Host
    # Create Container
    Write-Host "Creating Container $ContainerName" -ForegroundColor Yellow
    New-BcContainer @arguments
    # New Shortcut Folder
    New-Item -Path $NewShortcutsFolder -ItemType Directory -ErrorAction SilentlyContinue -Force | Out-Null
    # Save Log
    Write-Host
    Write-Host "Saving Container log" -ForegroundColor Yellow
    docker logs $ContainerName | Out-File "$NewShortcutsFolder\$ContainerName Container Log.txt" -Force
    # Move shortcuts
    Write-Host
    Write-Host "Moving shortcuts" -ForegroundColor Yellow
    Move-Item -Path "$([Environment]::GetFolderPath("Desktop"))\$ContainerName *" `
        -Destination "$NewShortcutsFolder\" `
        -Force
    # Adding fonts
    if (Test-Path "C:\Windows\Fonts\arial*.ttf") {
        Write-Host
        Write-Host "Adding Arial family fonts" -ForegroundColor Yellow
        Add-FontsToBcContainer -containerName $ContainerName -path @("C:\Windows\Fonts\arial*.ttf")
    }
    if (Test-Path "C:\Windows\Fonts\IDAutomation*.ttf") {
        Write-Host "Adding IDAutomation Codabar fonts" -ForegroundColor Yellow
        Add-FontsToBcContainer -containerName $ContainerName -path @("C:\Windows\Fonts\IDAutomation*.ttf")
    }
    # Insert Test Users
    if ($Profil -eq "Developer") {
        Write-Host
        Write-Host "Adding Test Users" -ForegroundColor Yellow
        Setup-BcContainerTestUsers  -containerName $ContainerName -credential $AdminCredential -Password (ConvertTo-SecureString -String "P@ssword1" -AsPlainText -Force)
    }
    # Insert Extensions
    Write-Host
    Write-Host "Searching $Source Extensions" -ForegroundColor Yellow
    New-Item -Path $AppsFolder -ItemType Directory -ErrorAction SilentlyContinue -Force | Out-Null
    $bcContainerHelperConfig.TrustedNuGetFeeds = @(
        [PSCustomObject]@{ "url" = "https://pkgs.dev.azure.com/isaISV/_packaging/$SourceApp/nuget/v3/index.json".ToLower();
            "token"              = '4gaswdlecvwh5x22ybfsgf6uagtakrpjfdxt3zpd3bwnvw24wb2a';
            "patterns"           = @("*")
        }
    )
    foreach ($Extension in $AddExtensions) {
        Download-BcNuGetPackageToFolder -packageName ".$($Extension -replace '[^a-zA-Z]', '')." -downloadDependencies allButMicrosoft -folder $AppsFolder
    }
    $AppFiles = @()
    foreach ($Files in (Get-Item "$AppsFolder\*.app")) {
        $AppFiles += $Files.FullName
    }
    Write-Host "Sorting $($AppFiles.Length) extensions..." -ForegroundColor Yellow
    $AppFiles = Sort-AppFilesByDependencies -appFiles $AppFiles
    foreach ($Files in $AppFiles) {
        Write-Host $Files.split('\')[-1]
    }
    Write-Host
    Write-Host "Publishing extensions..." -ForegroundColor Yellow
    foreach ($Files in $AppFiles) {
        try {
            Publish-BcContainerApp -containerName $ContainerName -appfile $Files -useDevEndpoint -syncMode ForceSync -install -credential $AdminCredential
        }
        catch {
            Write-Host "$Files not installed." -ForegroundColor Red
        }
    }
    # Create a Cronus Copy
    if ($CopyCRONUS) {
        Write-Host
        Write-Host "Copying CRONUS to zCompany" -ForegroundColor Yellow
        $CompanyInDocker = (Get-CompanyInNavContainer -containerName $ContainerName | Where-Object { $_.CompanyName -like "*CRONUS*" } | Select-Object -First 1).CompanyName
        try {
            Copy-CompanyInBcContainer -containerName $ContainerName `
                -sourceCompanyName $CompanyInDocker `
                -destinationCompanyName "z$CompanyInDocker"
        }
        catch {
            Write-Host "zCompany creation failed." -ForegroundColor Red
        }
    }
    # Launch Browser
    if ($launchBrowser) {
        $URL = Get-Content "$NewShortcutsFolder\$ContainerName Container Log.txt"
        $URL = $URL | Where-Object { $_ -like "Web Client*" }
        $URL = $URL.split(":")[2]
        Write-Host
        Write-Host "Launching Browser http:$URL" -ForegroundColor Yellow
        Start-Process "http:$URL"
    }
    if (!($NoCleanArtifact)) {
        Write-Host
        Write-Host "Cleaning BC Artifacts" -ForegroundColor Yellow
        Docker image prune -f
        Flush-ContainerHelperCache -cache bcartifacts -keepDays 2
    }
}
Export-ModuleMember -Function New-BCDevContainer
# SIG # Begin signature block
# MIInpAYJKoZIhvcNAQcCoIInlTCCJ5ECAQExDzANBglghkgBZQMEAgEFADB5Bgor
# BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG
# KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCCQBRkxW9dAIfz3
# 6QGCTWkv/C2ThDInA14b53IIuetmwaCCILswggWNMIIEdaADAgECAhAOmxiO+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
# twGpn1eqXijiuZQwggauMIIElqADAgECAhAHNje3JFR82Ees/ShmKl5bMA0GCSqG
# SIb3DQEBCwUAMGIxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMx
# GTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xITAfBgNVBAMTGERpZ2lDZXJ0IFRy
# dXN0ZWQgUm9vdCBHNDAeFw0yMjAzMjMwMDAwMDBaFw0zNzAzMjIyMzU5NTlaMGMx
# CzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5EaWdpQ2VydCwgSW5jLjE7MDkGA1UEAxMy
# RGlnaUNlcnQgVHJ1c3RlZCBHNCBSU0E0MDk2IFNIQTI1NiBUaW1lU3RhbXBpbmcg
# Q0EwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDGhjUGSbPBPXJJUVXH
# JQPE8pE3qZdRodbSg9GeTKJtoLDMg/la9hGhRBVCX6SI82j6ffOciQt/nR+eDzMf
# UBMLJnOWbfhXqAJ9/UO0hNoR8XOxs+4rgISKIhjf69o9xBd/qxkrPkLcZ47qUT3w
# 1lbU5ygt69OxtXXnHwZljZQp09nsad/ZkIdGAHvbREGJ3HxqV3rwN3mfXazL6IRk
# tFLydkf3YYMZ3V+0VAshaG43IbtArF+y3kp9zvU5EmfvDqVjbOSmxR3NNg1c1eYb
# qMFkdECnwHLFuk4fsbVYTXn+149zk6wsOeKlSNbwsDETqVcplicu9Yemj052FVUm
# cJgmf6AaRyBD40NjgHt1biclkJg6OBGz9vae5jtb7IHeIhTZgirHkr+g3uM+onP6
# 5x9abJTyUpURK1h0QCirc0PO30qhHGs4xSnzyqqWc0Jon7ZGs506o9UD4L/wojzK
# QtwYSH8UNM/STKvvmz3+DrhkKvp1KCRB7UK/BZxmSVJQ9FHzNklNiyDSLFc1eSuo
# 80VgvCONWPfcYd6T/jnA+bIwpUzX6ZhKWD7TA4j+s4/TXkt2ElGTyYwMO1uKIqjB
# Jgj5FBASA31fI7tk42PgpuE+9sJ0sj8eCXbsq11GdeJgo1gJASgADoRU7s7pXche
# MBK9Rp6103a50g5rmQzSM7TNsQIDAQABo4IBXTCCAVkwEgYDVR0TAQH/BAgwBgEB
# /wIBADAdBgNVHQ4EFgQUuhbZbU2FL3MpdpovdYxqII+eyG8wHwYDVR0jBBgwFoAU
# 7NfjgtJxXWRM3y5nP+e6mK4cD08wDgYDVR0PAQH/BAQDAgGGMBMGA1UdJQQMMAoG
# CCsGAQUFBwMIMHcGCCsGAQUFBwEBBGswaTAkBggrBgEFBQcwAYYYaHR0cDovL29j
# c3AuZGlnaWNlcnQuY29tMEEGCCsGAQUFBzAChjVodHRwOi8vY2FjZXJ0cy5kaWdp
# Y2VydC5jb20vRGlnaUNlcnRUcnVzdGVkUm9vdEc0LmNydDBDBgNVHR8EPDA6MDig
# NqA0hjJodHRwOi8vY3JsMy5kaWdpY2VydC5jb20vRGlnaUNlcnRUcnVzdGVkUm9v
# dEc0LmNybDAgBgNVHSAEGTAXMAgGBmeBDAEEAjALBglghkgBhv1sBwEwDQYJKoZI
# hvcNAQELBQADggIBAH1ZjsCTtm+YqUQiAX5m1tghQuGwGC4QTRPPMFPOvxj7x1Bd
# 4ksp+3CKDaopafxpwc8dB+k+YMjYC+VcW9dth/qEICU0MWfNthKWb8RQTGIdDAiC
# qBa9qVbPFXONASIlzpVpP0d3+3J0FNf/q0+KLHqrhc1DX+1gtqpPkWaeLJ7giqzl
# /Yy8ZCaHbJK9nXzQcAp876i8dU+6WvepELJd6f8oVInw1YpxdmXazPByoyP6wCeC
# RK6ZJxurJB4mwbfeKuv2nrF5mYGjVoarCkXJ38SNoOeY+/umnXKvxMfBwWpx2cYT
# gAnEtp/Nh4cku0+jSbl3ZpHxcpzpSwJSpzd+k1OsOx0ISQ+UzTl63f8lY5knLD0/
# a6fxZsNBzU+2QJshIUDQtxMkzdwdeDrknq3lNHGS1yZr5Dhzq6YBT70/O3itTK37
# xJV77QpfMzmHQXh6OOmc4d0j/R0o08f56PGYX/sr2H7yRp11LB4nLCbbbxV7HhmL
# NriT1ObyF5lZynDwN7+YAN8gFk8n+2BnFqFmut1VwDophrCYoCvtlUG3OtUVmDG0
# YgkPCr2B2RP+v6TR81fZvAT6gt4y3wSJ8ADNXcL50CN/AAvkdgIm2fBldkKmKYcJ
# RyvmfxqkhQ/8mJb2VVQrH4D6wPIOK+XW+6kvRBVK5xMOHds3OBqhK/bt1nz8MIIG
# vzCCBKegAwIBAgIRAIFOQhehKX/tWszUF/iRrXUwDQYJKoZIhvcNAQELBQAwUzEL
# MAkGA1UEBhMCQkUxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExKTAnBgNVBAMT
# IEdsb2JhbFNpZ24gQ29kZSBTaWduaW5nIFJvb3QgUjQ1MB4XDTI0MDYxOTAzMjUx
# MVoXDTM4MDcyODAwMDAwMFowWTELMAkGA1UEBhMCQkUxGTAXBgNVBAoTEEdsb2Jh
# bFNpZ24gbnYtc2ExLzAtBgNVBAMTJkdsb2JhbFNpZ24gR0NDIFI0NSBDb2RlU2ln
# bmluZyBDQSAyMDIwMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA1kJN
# +eNPxiP0bB2BpjD3SD3P0OWN5SAilgdENV0Gzw8dcGDmJlT6UyNgAqhfAgL3jslu
# Pal4Bb2O9U8ZJJl8zxEWmx97a9Kje2hld6vYsSw/03IGMlxbrFBnLCVNVgY2/MFi
# TH19hhaVml1UulDQsH+iRBnp1m5sPhPCnxHUXzRbUWgxYwr4W9DeullfMa+JaDhA
# PgjoU2dOY7Yhju/djYVBVZ4cvDfclaDEcacfG6VJbgogWX6Jo1gVlwAlad/ewmpQ
# ZU5T+2uhnxgeig5fVF694FvP8gwE0t4IoRAm97Lzei7CjpbBP86l2vRZKIw3ZaEx
# lguOpHZ3FUmEZoIl50MKd1KxmVFC/6Gy3ZzS3BjZwYapQB1Bl2KGvKj/osdjFwb9
# Zno2lAEgiXgfkPR7qVJOak9UBiqAr57HUEL6ZQrjAfSxbqwOqOOBGag4yJ4DKIak
# dKdHlX5yWip7FWocxGnmsL5AGZnL0n1VTiKcEOChW8OzLnqLxN7xSx+MKHkwRX9s
# E7Y9LP8tSooq7CgPLcrUnJiKSm1aNiwv37rL4kFKCHcYiK01YZQS86Ry6+42nqdR
# J5E896IazPyH5ZfhUYdp6SLMg8C3D0VsB+FDT9SMSs7PY7G1pBB6+Q0MKLBrNP4h
# aCdv7Pj6JoRbdULNiSZ5WZ1rq2NxYpAlDQgg8f8CAwEAAaOCAYYwggGCMA4GA1Ud
# DwEB/wQEAwIBhjATBgNVHSUEDDAKBggrBgEFBQcDAzASBgNVHRMBAf8ECDAGAQH/
# AgEAMB0GA1UdDgQWBBTas43AJJCja3fTDKBZ3SFnZHYLeDAfBgNVHSMEGDAWgBQf
# AL9GgAr8eDm3pbRD2VZQu86WOzCBkwYIKwYBBQUHAQEEgYYwgYMwOQYIKwYBBQUH
# MAGGLWh0dHA6Ly9vY3NwLmdsb2JhbHNpZ24uY29tL2NvZGVzaWduaW5ncm9vdHI0
# NTBGBggrBgEFBQcwAoY6aHR0cDovL3NlY3VyZS5nbG9iYWxzaWduLmNvbS9jYWNl
# cnQvY29kZXNpZ25pbmdyb290cjQ1LmNydDBBBgNVHR8EOjA4MDagNKAyhjBodHRw
# Oi8vY3JsLmdsb2JhbHNpZ24uY29tL2NvZGVzaWduaW5ncm9vdHI0NS5jcmwwLgYD
# VR0gBCcwJTAIBgZngQwBBAEwCwYJKwYBBAGgMgEyMAwGCisGAQQBoDIKBAIwDQYJ
# KoZIhvcNAQELBQADggIBADIQ5LwXpYMQQJ3Tqf0nz0VyqcUfSzNZbywyMXlxhNY2
# Z9WrdPzU8gY6brXWy/FCg5a9fd6VLBrtauNBHKbIiTHCWWyJvCojA1lQR0n9b1MO
# KijMSFTv8yMYW5I2TryjY9TD+wAPgNEgwsrllrrwmluqpCV6Gdv623tTT/m2o9lj
# 1XVfAaUo27YYKRRleZzbtOuImBRTUGAxDGazUeNuySkmZPAU0XN4xISNPhSlklmr
# eUFG6jTPgXZGOpF4GXO+/gb118GEOaBwTAo1AF7YKjAkHzJ3tuF837NGQeH6bY3j
# 4wufL0DZpToNZMm+jNEayWUgOuIA+k56ITdBcJmdUB+Ze3WQdHNNRaVOWH/ddmqQ
# WIlmk2Sj/lT3Tarr5SDuddeIsh0MPLyhkqBW5Ef8Zw/qeCnfj6PH2eMxeKcLKZRr
# HCddISeH4qPvyECQLlwXKCXTAUQXq4DafJSoWyP8IJ6bkaGQ/7MN5XJELEcV89SR
# cib58gXjAWf3abXeBbb+KJCMf6EpO7cs2mQiaZbE9NNXDSqFxrtoaKyL8VJLZG6q
# uLfsTRQc+qgUOM7sJevkYt01+bh7B10bQ2cCCGs9vyUjg4GWcwfu/lhaPDfaoNtf
# 0pw6RpKcxCYcCTDaJeQOHZBz1B6HTmmEgZHNZX7nNfqDgGrTNB1Gp3gIpngyJWZ6
# MIIGwjCCBKqgAwIBAgIQBUSv85SdCDmmv9s/X+VhFjANBgkqhkiG9w0BAQsFADBj
# MQswCQYDVQQGEwJVUzEXMBUGA1UEChMORGlnaUNlcnQsIEluYy4xOzA5BgNVBAMT
# MkRpZ2lDZXJ0IFRydXN0ZWQgRzQgUlNBNDA5NiBTSEEyNTYgVGltZVN0YW1waW5n
# IENBMB4XDTIzMDcxNDAwMDAwMFoXDTM0MTAxMzIzNTk1OVowSDELMAkGA1UEBhMC
# VVMxFzAVBgNVBAoTDkRpZ2lDZXJ0LCBJbmMuMSAwHgYDVQQDExdEaWdpQ2VydCBU
# aW1lc3RhbXAgMjAyMzCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAKNT
# RYcdg45brD5UsyPgz5/X5dLnXaEOCdwvSKOXejsqnGfcYhVYwamTEafNqrJq3RAp
# ih5iY2nTWJw1cb86l+uUUI8cIOrHmjsvlmbjaedp/lvD1isgHMGXlLSlUIHyz8sH
# pjBoyoNC2vx/CSSUpIIa2mq62DvKXd4ZGIX7ReoNYWyd/nFexAaaPPDFLnkPG2ZS
# 48jWPl/aQ9OE9dDH9kgtXkV1lnX+3RChG4PBuOZSlbVH13gpOWvgeFmX40QrStWV
# zu8IF+qCZE3/I+PKhu60pCFkcOvV5aDaY7Mu6QXuqvYk9R28mxyyt1/f8O52fTGZ
# ZUdVnUokL6wrl76f5P17cz4y7lI0+9S769SgLDSb495uZBkHNwGRDxy1Uc2qTGaD
# iGhiu7xBG3gZbeTZD+BYQfvYsSzhUa+0rRUGFOpiCBPTaR58ZE2dD9/O0V6MqqtQ
# FcmzyrzXxDtoRKOlO0L9c33u3Qr/eTQQfqZcClhMAD6FaXXHg2TWdc2PEnZWpST6
# 18RrIbroHzSYLzrqawGw9/sqhux7UjipmAmhcbJsca8+uG+W1eEQE/5hRwqM/vC2
# x9XH3mwk8L9CgsqgcT2ckpMEtGlwJw1Pt7U20clfCKRwo+wK8REuZODLIivK8SgT
# IUlRfgZm0zu++uuRONhRB8qUt+JQofM604qDy0B7AgMBAAGjggGLMIIBhzAOBgNV
# HQ8BAf8EBAMCB4AwDAYDVR0TAQH/BAIwADAWBgNVHSUBAf8EDDAKBggrBgEFBQcD
# CDAgBgNVHSAEGTAXMAgGBmeBDAEEAjALBglghkgBhv1sBwEwHwYDVR0jBBgwFoAU
# uhbZbU2FL3MpdpovdYxqII+eyG8wHQYDVR0OBBYEFKW27xPn783QZKHVVqllMaPe
# 1eNJMFoGA1UdHwRTMFEwT6BNoEuGSWh0dHA6Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9E
# aWdpQ2VydFRydXN0ZWRHNFJTQTQwOTZTSEEyNTZUaW1lU3RhbXBpbmdDQS5jcmww
# gZAGCCsGAQUFBwEBBIGDMIGAMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdp
# Y2VydC5jb20wWAYIKwYBBQUHMAKGTGh0dHA6Ly9jYWNlcnRzLmRpZ2ljZXJ0LmNv
# bS9EaWdpQ2VydFRydXN0ZWRHNFJTQTQwOTZTSEEyNTZUaW1lU3RhbXBpbmdDQS5j
# cnQwDQYJKoZIhvcNAQELBQADggIBAIEa1t6gqbWYF7xwjU+KPGic2CX/yyzkzepd
# IpLsjCICqbjPgKjZ5+PF7SaCinEvGN1Ott5s1+FgnCvt7T1IjrhrunxdvcJhN2hJ
# d6PrkKoS1yeF844ektrCQDifXcigLiV4JZ0qBXqEKZi2V3mP2yZWK7Dzp703DNiY
# dk9WuVLCtp04qYHnbUFcjGnRuSvExnvPnPp44pMadqJpddNQ5EQSviANnqlE0Pjl
# SXcIWiHFtM+YlRpUurm8wWkZus8W8oM3NG6wQSbd3lqXTzON1I13fXVFoaVYJmoD
# Rd7ZULVQjK9WvUzF4UbFKNOt50MAcN7MmJ4ZiQPq1JE3701S88lgIcRWR+3aEUuM
# MsOI5ljitts++V+wQtaP4xeR0arAVeOGv6wnLEHQmjNKqDbUuXKWfpd5OEhfysLc
# PTLfddY2Z1qJ+Panx+VPNTwAvb6cKmx5AdzaROY63jg7B145WPR8czFVoIARyxQM
# fq68/qTreWWqaNYiyjvrmoI1VygWy2nyMpqy0tg6uLFGhmu6F/3Ed2wVbK6rr3M6
# 6ElGt9V/zLY4wNjsHPW2obhDLN9OTH0eaHDAdwrUAuBcYLso/zjlUlrWrBciI070
# 7NMX+1Br/wd3H3GXREHJuEbTbDJ8WC9nR2XlG3O2mflrLAZG70Ee8PBf4NvZrZCA
# RK+AEEGKMIIG6zCCBNOgAwIBAgIMV5RYofTu5yaH8wNcMA0GCSqGSIb3DQEBCwUA
# MFkxCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMS8wLQYD
# VQQDEyZHbG9iYWxTaWduIEdDQyBSNDUgQ29kZVNpZ25pbmcgQ0EgMjAyMDAeFw0y
# MzA5MjYwODE1NTlaFw0yNDA5MjYwODE1NTlaMFkxCzAJBgNVBAYTAkZSMREwDwYD
# VQQIEwhNb3JiaWhhbjEPMA0GA1UEBxMGVmFubmVzMRIwEAYDVQQKEwlCUklDS0xF
# QUQxEjAQBgNVBAMTCUJSSUNLTEVBRDCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCC
# AgoCggIBALEHieTHs+UbfzaW1fy+oELDSxpRF8hpmf/5BVgYvNA/p8h8JxGuaw/n
# fsueBDiONPFgRqdl6QniVzDxqXtYZnGKnCvevpIku/IAzku1OIiW6gLW2yo3eLOA
# neniXCnBqxJ6BMAxWXcyeSxk2mGaDI09gF8InKX6uvxTPpoGZ9kecJJ1abaASBkS
# F2p1b3RXNtdKCVMMTOzJADLggNrtUjh0A63iOA6NIm7vV1fyJ3J7z6BFw23r92+J
# 4WnWDI+tslCo+hvey5df3GmY1lFw0gsgTti/5mvbHgXnN5sIRXhfeQ+JgBEHyfms
# llBOM+xLgbrADmr6RkPgNUVx8FemWs4MUaC+3ifKzZQA80MxYGVjBiHrfHkBgjuP
# ntg0tpTJrQc90Fv5vQ6ZR9mfn1fgY9Z9GvtgNTF/yVOgyEs0OHeaPISnm37AGfLz
# 0SwLJWRBd81L4OSxh3xufxFknpfSL9jMsfKbKNtiG2vlMzxs2zqAvJ4SheRc84EM
# HeOZfwQ27jkH1/a1tTRBLtbvvJb+sN2WcVg5Ddx2nbg/i3U24i1ES/touZeShUir
# V7L890wxb2umfO49EY/wfvLWAwgYBTc6OmZN6GF//UZRpvpD9QyyYhJRXE3z0hon
# UfMSjvVSIwbEwmePF7THAxXTHVVB1pnq5sglFb3wzLzuXX4UY9XFAgMBAAGjggGx
# MIIBrTAOBgNVHQ8BAf8EBAMCB4AwgZsGCCsGAQUFBwEBBIGOMIGLMEoGCCsGAQUF
# BzAChj5odHRwOi8vc2VjdXJlLmdsb2JhbHNpZ24uY29tL2NhY2VydC9nc2djY3I0
# NWNvZGVzaWduY2EyMDIwLmNydDA9BggrBgEFBQcwAYYxaHR0cDovL29jc3AuZ2xv
# YmFsc2lnbi5jb20vZ3NnY2NyNDVjb2Rlc2lnbmNhMjAyMDBWBgNVHSAETzBNMEEG
# CSsGAQQBoDIBMjA0MDIGCCsGAQUFBwIBFiZodHRwczovL3d3dy5nbG9iYWxzaWdu
# LmNvbS9yZXBvc2l0b3J5LzAIBgZngQwBBAEwCQYDVR0TBAIwADBFBgNVHR8EPjA8
# MDqgOKA2hjRodHRwOi8vY3JsLmdsb2JhbHNpZ24uY29tL2dzZ2NjcjQ1Y29kZXNp
# Z25jYTIwMjAuY3JsMBMGA1UdJQQMMAoGCCsGAQUFBwMDMB8GA1UdIwQYMBaAFNqz
# jcAkkKNrd9MMoFndIWdkdgt4MB0GA1UdDgQWBBS/mhPpyHdMGVRIA9594CwTJpWs
# ITANBgkqhkiG9w0BAQsFAAOCAgEAQOW39CVVMGJWq4Rl6BhGAb7r4oYgaGemu69C
# LYnG2lSABh991Jo145anGCXowe4/JKCULMYMrrgmYXhY7R52BE3Eo+0lCnTZPjXK
# cNKhHYmQzUb5mvQSe8Q9Jd7+lA9SyL0tzpHq/VIBmwF/sBUgsIDFrUSCnbj/S/p2
# /cScSWvEmoASYUID16bCopRbBFDhMJp52heDnuVUpZ5ara7l/owlCMFKzWY77fOV
# AWDgHZx2mrpKKcxs2CdXWaXzX6huNt93wPtNZt7V287XxvOLD88lUEYgzfVD3pKS
# wQkCcciQV0v3Ysub8B+HYHSO2bpLx2bgJ9Asc320lvfl0UUFeCxElpDX67dRNC2Z
# Ijw4FV35XyMWNiF02aUVcyOPQDKQfcwbeD1V1Gx7mffZN/yttO0MR+AqJQ1D4O61
# 3HW1onXDBHBKoJl3pbCLA3wkyGv26aEIlTWHnwwjMsTrKDcP/4MfMbYxmVKlmmqY
# wszfawoKg8T6Q8cqTCHJEo11tad3n6P8zIw1+ogdYTH0+hzQZ1I9x/Uo9c2K46mt
# CzFg98NJgD2UF+29vsCBFFnNiStfVF5szIr89b/0eqnXrt1qvzoWfSDYO63IZFCb
# qGAvUb+RsqXne6EA0vpdomH4/X9uCUksTwkUbcwRcye7MKzOGtgh+vU/1Wa3LeVh
# bDh5QVkxggY/MIIGOwIBATBpMFkxCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9i
# YWxTaWduIG52LXNhMS8wLQYDVQQDEyZHbG9iYWxTaWduIEdDQyBSNDUgQ29kZVNp
# Z25pbmcgQ0EgMjAyMAIMV5RYofTu5yaH8wNcMA0GCWCGSAFlAwQCAQUAoIGEMBgG
# CisGAQQBgjcCAQwxCjAIoAKAAKECgAAwGQYJKoZIhvcNAQkDMQwGCisGAQQBgjcC
# AQQwHAYKKwYBBAGCNwIBCzEOMAwGCisGAQQBgjcCARUwLwYJKoZIhvcNAQkEMSIE
# IEhItLSGirD7Pw26rO4n1NhOvmm7e78QW/GYLckrNAaRMA0GCSqGSIb3DQEBAQUA
# BIICAIOghNF0kU1erPtUFFuQELG6uf1kSsLokSggiWubI8yu6y2RW7BNl3dJpnMC
# m7MuoeAap8DsnXUzFswrtKGmUjIaA3QGw74MqaJUEAcvJumI/pja4AH9xsMv/hBj
# Fyn//tmegDdg2ytKAcUJf2pKLLIloyWZ7onld1fSax/GqwRR+Aqb92BuujpqIjAC
# YGPeMk8ht7Avh9fPTiq2fGXcutKekkmpcZN1gFhtwXLBjhYgF2JcgLSFo3qq1fx+
# drl9Wijx2+vQI3tcSOS7kFT1903gWq+Va+mMfG3SV8dOkY3Glg4YyUTyS8ZRN7iB
# 0tgXSdEeiGQThD7imdAB1iJmRBZ/niAXI3xB5XBq3yxHuOyA3oGrkrIEShM447gb
# Lrwb1gPN4S46cMidzgL0FDt9VSQQX24ooM+eo3ZcA6bb4I9XGaCB4skJ2yGAljna
# Cf+M4PpETY9jUgwn3NuE0gD7EPIqrwSbBjgmcUzCNnTNnnGQNTjaFn0Pi7clpdcp
# RinfaPPSB+nOiIF0dmScVQwKMJYDKdzdtyZYPvyXJSwBjJbXo1GZ+gByo8yC+dTl
# d2RlevyuEb/iw+N6NGNKrnKXRo5R2TOExt53jMtiXdPRHiJifaG2dtpbhQgvXTPA
# oueL9DzWmweEVQN2X/MuEk4saGfnEV166/Sdoluegi6tVvxdoYIDIDCCAxwGCSqG
# SIb3DQEJBjGCAw0wggMJAgEBMHcwYzELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDkRp
# Z2lDZXJ0LCBJbmMuMTswOQYDVQQDEzJEaWdpQ2VydCBUcnVzdGVkIEc0IFJTQTQw
# OTYgU0hBMjU2IFRpbWVTdGFtcGluZyBDQQIQBUSv85SdCDmmv9s/X+VhFjANBglg
# hkgBZQMEAgEFAKBpMBgGCSqGSIb3DQEJAzELBgkqhkiG9w0BBwEwHAYJKoZIhvcN
# AQkFMQ8XDTI0MDkwMzA3NDgwMVowLwYJKoZIhvcNAQkEMSIEIKyRSJPR6cl3BaIP
# npHuopQQGYiclgUqJ3V+OXihzcdzMA0GCSqGSIb3DQEBAQUABIICADzFUffMuCc8
# sZBLPApT80ZCMu8rTJ/AxvH5MHLaeCjZvUV+p5x+Cr30dHWJ4hM6Xdzor4rh4+JD
# NCbA3XrW/KSLW02m7/4AQX2AIVSGDWntUT0t7w23K+Ul8Ea3vYMf7oZaqeYIbWQ/
# rPlpBsWIfHTLm6HIQmIkEiwGq7FEZVcfvFpAaCCmwKxBgkNevEksQcaNBtbSWqs0
# Uxxag+rut1oT2lrz+G/KkIJZFRg8yeRxB0OTF9oLq7aNnm95nuBS045t74BmeM/E
# 3NUnQAlRKeYrfeD/CAhz62QCZIDW6654wZwwOFeZcelNDY3aSroJ2NrdSq6n6Ys/
# AHvqWD3+/ua8nzbBvrvyHh1ku6Qc5vVY6OrL1ixNM9xOQ0H5wuBHthvNqVsvnymY
# vhDtawQjE2GRopf6VoXHt/vjbpWM17suSdFLUOhnKDq15XiZW/WjVoSfgIO1UD+V
# 3P3f64LE22ukn2U6DfEGkRUleuucyJA2CH/SL6xa0LMVLaotZSndpnla6DdTD1da
# fjQcZuP+Q+N0wBkAAQl9nEEBaq15A7mZnoDvPIzmBPM9A/PhxaL5ypnEkCBu2Kvu
# zTyfBv1wolK8hP5XozoL+o+psAvUhcnRqe97GvvdMBYIAezjC5uhhwDe+CBP+zZ9
# UeOIObpvfh+slp3ks/s1mWvPBBbrvnmB
# SIG # End signature block