param
(
    [parameter(Position=0,Mandatory=$false)][boolean] $useServiceFabric=$false 
)

Import-Module "$PSScriptRoot\CommonRollbackUtilities.psm1"  -ArgumentList $useServiceFabric -DisableNameChecking

$script:EnvDllsLoaded = $false
function Get-ApplicationEnvironment
{
    $ErrorActionPreference = 'Stop'

    if (-not $script:EnvDllsLoaded)
    {        
        $webroot = Get-AosWebSitePhysicalPath
        $InstalledPlatformBuildVersion = Get-ProductPlatformBuildFullVersion
        $isKeyVault = Get-IsMSIKeyVault

        if (($isKeyVault -eq $true) -and ($InstalledPlatformBuildVersion -ne $null) -and ($InstalledPlatformBuildVersion.Build -ge 5644))
        {        
            # Get-PackageRoot comes from CommonRollbackUtilities.psm1. it resolves the root of the deployable package
            $packageRoot = Get-PackageRoot
            $packageTemp = ""

            if(![string]::IsNullOrEmpty($packageRoot) -and (Test-Path $packageRoot))
            {
                $packageTemp = Join-Path $packageRoot "RunbookWorkingFolder\KeyVaultAssemblyTemp"
            }

            if ([string]::IsNullOrEmpty($packageTemp))
            {   
                $suffix = $(Get-Date).ToString("yyyyMMdd_HHmmss")
                $dirName = "AssemblyTemp_$suffix"
                $packageTemp = Join-Path $env:Temp "dirName"
            }

            if(!(Test-Path $packageTemp -PathType Container))
            {
                New-Item $packageTemp -ItemType Container | Out-Null
            }
        
            #need to load the Microsoft.Dynamics.ApplicationPlatform.Environment.dll and all the dll it referenced
            $dllPath = Join-Path $webroot 'bin\Microsoft.Dynamics.ApplicationPlatform.Environment.dll'
            CopyDllToTempFolder -dllPath $dllPath -packageTemp $packageTemp
            $dllPath = Join-Path $webroot 'bin\Microsoft.Dynamics.AX.Configuration.Base.dll'
            CopyDllToTempFolder -dllPath $dllPath -packageTemp $packageTemp
            $dllPath = Join-Path $webroot 'bin\Microsoft.Dynamics.AX.Security.Instrumentation.dll'
            CopyDllToTempFolder -dllPath $dllPath -packageTemp $packageTemp
            $dllPath = Join-Path $webroot 'bin\Microsoft.Dynamics.AX.Framework.EncryptionEngine.dll'
            CopyDllToTempFolder -dllPath $dllPath -packageTemp $packageTemp
            $dllPath = Join-Path $webroot 'bin\Microsoft.Dynamics.BusinessPlatform.SharedTypes.dll'
            CopyDllToTempFolder -dllPath $dllPath -packageTemp $packageTemp
            $dllPath = Join-Path $webroot 'bin\Microsoft.Dynamics.AX.Security.KeyVaultHelper.dll'
            CopyDllToTempFolder -dllPath $dllPath -packageTemp $packageTemp
            $dllPath = Join-Path $webroot 'bin\Microsoft.Carbon.Flighting.Runtime.dll'
            CopyDllToTempFolder -dllPath $dllPath -packageTemp $packageTemp
            $dllPath = Join-Path $webroot 'bin\Microsoft.Carbon.CertificateCommon.dll'
            CopyDllToTempFolder -dllPath $dllPath -packageTemp $packageTemp
            $dllPath = Join-Path $webroot 'bin\Microsoft.Commerce.Flighting.Common.dll'
            CopyDllToTempFolder -dllPath $dllPath -packageTemp $packageTemp
            $dllPath = Join-Path $webroot 'bin\Microsoft.Dynamics.ApplicationPlatform.Flighting.dll'
            CopyDllToTempFolder -dllPath $dllPath -packageTemp $packageTemp
            $dllPath = Join-Path $webroot 'bin\Microsoft.Dynamics.ApplicationPlatform.XppServices.Instrumentation.dll'
            CopyDllToTempFolder -dllPath $dllPath -packageTemp $packageTemp
            $dllPath = Join-Path $webroot 'bin\Microsoft.CE.VaultSDK.dll'
            CopyDllToTempFolder -dllPath $dllPath -packageTemp $packageTemp
            $dllPath = Join-Path $webroot 'bin\Microsoft.CE.VaultSDK.ADALv2.AuthHelper.dll'
            CopyDllToTempFolder -dllPath $dllPath -packageTemp $packageTemp
            $dllPath = Join-Path $webroot 'bin\Microsoft.Azure.KeyVault.Core.dll'
            CopyDllToTempFolder -dllPath $dllPath -packageTemp $packageTemp
            $dllPath = Join-Path $webroot 'bin\Microsoft.Azure.KeyVault.dll'
            CopyDllToTempFolder -dllPath $dllPath -packageTemp $packageTemp
            $dllPath = Join-Path $webroot 'bin\Microsoft.Azure.Common.dll'
            CopyDllToTempFolder -dllPath $dllPath -packageTemp $packageTemp
            $dllPath = Join-Path $webroot 'bin\Microsoft.Azure.Common.NetFramework.dll'
            CopyDllToTempFolder -dllPath $dllPath -packageTemp $packageTemp
            $dllPath = Join-Path $webroot 'bin\Hyak.Common.dll'
            CopyDllToTempFolder -dllPath $dllPath -packageTemp $packageTemp
            $dllPath = Join-Path $webroot 'bin\Microsoft.Dynamics.AX.Authentication.Instrumentation.dll'
            CopyDllToTempFolder -dllPath $dllPath -packageTemp $packageTemp
            $dllPath = Join-Path $webroot 'bin\Microsoft.Threading.Tasks.dll'
            CopyDllToTempFolder -dllPath $dllPath -packageTemp $packageTemp
            $dllPath = Join-Path $webroot 'bin\Microsoft.Threading.Tasks.Extensions.dll'
            CopyDllToTempFolder -dllPath $dllPath -packageTemp $packageTemp
            $dllPath = Join-Path $webroot 'bin\Microsoft.Threading.Tasks.Extensions.Desktop.dll'
            CopyDllToTempFolder -dllPath $dllPath -packageTemp $packageTemp
            $dllPath = Join-Path $webroot 'bin\Microsoft.IdentityModel.Clients.ActiveDirectory.dll'
            CopyDllToTempFolder -dllPath $dllPath -packageTemp $packageTemp
            $dllPath = Join-Path $webroot 'bin\Microsoft.Practices.EnterpriseLibrary.TransientFaultHandling.dll'
            CopyDllToTempFolder -dllPath $dllPath -packageTemp $packageTemp
            $dllPath = Join-Path $webroot 'bin\Newtonsoft.Json.dll'
            CopyDllToTempFolder -dllPath $dllPath -packageTemp $packageTemp
            $dllPath = Join-Path $webroot 'bin\Microsoft.Dynamics.AX.Security.SharedUtility.dll'
            CopyDllToTempFolder -dllPath $dllPath -packageTemp $packageTemp            

            try
            {
                $dllPath = Join-Path $webroot 'bin\Microsoft.Dynamics.ApplicationPlatform.Environment.dll'
                $fileTempPath =  Join-Path $packageTemp $(Get-Item $dllPath).Name
                if (Test-Path $fileTempPath)
                {
                    # Load file from temp folder
                    [System.Reflection.Assembly]::LoadFrom($fileTempPath)
                }
            }
            catch
            {    
                #write-log "Failed to load from temp folder with Exception: [$($_.Exception)]"
                throw $_
            }
        }              
        else
        {
            #need to load the Microsoft.Dynamics.ApplicationPlatform.Environment.dll and all the dll it referenced
            $dllPath = Join-Path $webroot 'bin\Microsoft.Dynamics.ApplicationPlatform.Environment.dll'
            Load-DllinMemory -dllPath $dllPath
            $dllPath = Join-Path $webroot 'bin\Microsoft.Dynamics.AX.Configuration.Base.dll'
            Load-DllinMemory -dllPath $dllPath
            $dllPath = Join-Path $webroot 'bin\Microsoft.Dynamics.AX.Security.Instrumentation.dll'
            if (Test-Path $dllPath)
            {
                Load-DllinMemory -dllPath $dllPath
            }
            $dllPath = Join-Path $webroot 'bin\Microsoft.Dynamics.AX.Framework.EncryptionEngine.dll'
            Load-DllinMemory -dllPath $dllPath
            $dllPath = Join-Path $webroot 'bin\Microsoft.Dynamics.BusinessPlatform.SharedTypes.dll'
            Load-DllinMemory -dllPath $dllPath  
        }

        $script:EnvDllsLoaded = $true
    }

    $config = [Microsoft.Dynamics.ApplicationPlatform.Environment.EnvironmentFactory]::GetApplicationEnvironment()
    
    return $config
}

function Load-DllinMemory([string] $dllPath)
{
    #try catch as not all dll exist in RTM version, some dependency/dll are introduced at update 1 or later
    #powershell cannot unload dll once it's loaded, the trick is to create an in-memory copy of the dll than load it
    #after the loading of in-memory dll, the physical dll stay unlocked

    try
    {
        if (Test-Path $dllPath)
        {
            $bytes = [System.IO.File]::ReadAllBytes($dllPath)
            [System.Reflection.Assembly]::Load($bytes) | Out-Null
        }
    }
    catch
    {}
}

function CopyDllToTempFolder([string] $dllPath, [string] $packageTemp)
{
    #try catch as not all dll exist in RTM version, some dependency/dll are introduced at update 1 or later    
    $fileTempPath =  Join-Path $packageTemp $(Get-Item $dllPath).Name
    try
    {
        if ((Test-Path $dllPath) -And !$(Test-Path $fileTempPath))
        {
            $Buffer = New-Object 'byte[]' 1024
            # Open file in read mode
            $SourceFile = [System.IO.File]::Open($dllPath, [System.IO.FileMode]::Open, [System.IO.FileAccess]::Read, [System.IO.FileShare]::Read)
            # Create the new file
            $DestinationFile = [System.IO.File]::Open($fileTempPath, [System.IO.FileMode]::CreateNew)
            try{
                # Copy the contents of the source file to the destination
                while(($readLength = $SourceFile.Read($Buffer, 0, $Buffer.Length)) -gt 0)
                {
                    $DestinationFile.Write($Buffer, 0, $readLength)
                }
            }
            catch{
                throw $_
            }
            finally{
                $SourceFile.Close()
                $DestinationFile.Close()
            }
        }
    }
    catch
    {
        Write-Log "Failed to copy file to temp folder with Exception: [$($_.Exception)]"
        throw $_
    }    
}

function Get-IsMSIKeyVault
{
    $webroot = Get-AosWebSitePhysicalPath
    $webconfig=join-path $webroot "web.config"
    $isMSIKeyVault=$false
    
    [System.Xml.XmlDocument] $xd=new-object System.Xml.XmlDocument
    $xd.Load($webconfig)
    $ns=New-Object System.Xml.XmlNamespaceManager($xd.NameTable)
    $ns.AddNamespace("ns",$xd.DocumentElement.NamespaceURI)

    $key="CertificateHandler.IsMSIKeyVault"

    $isKeyVaultValue = $xd.SelectSingleNode("//ns:add[@key='$key']",$ns)

    if($isKeyVaultValue -ne $null)
    {        
        $isMSIKeyVault = $isKeyVaultValue.GetAttribute("value")
    }

    return $isMSIKeyVault 
}

function GenerateMetadataModuleInstallationInfo
{
    try
    {
        $ErrorActionPreference = 'Stop'

        write-output "Creating Metadata Module Installation Info."
        
        $packagePath = Get-AOSPackageDirectory
        $CommonBin = $(Get-CommonBinDir)

        $dllPath = Join-Path $CommonBin 'bin\Microsoft.Dynamics.AX.AXInstallationInfo.dll'
        Load-DllinMemory -dllPath $dllPath
        $dllPath = Join-Path $CommonBin 'bin\Microsoft.Dynamics.AX.Metadata.Storage.dll'
        Load-DllinMemory -dllPath $dllPath
        $dllPath = Join-Path $CommonBin 'bin\Microsoft.Dynamics.AX.Metadata.dll'
        Load-DllinMemory -dllPath $dllPath
        $dllPath = Join-Path $CommonBin 'bin\Microsoft.Dynamics.AX.Metadata.Core.dll'
        Load-DllinMemory -dllPath $dllPath
        $dllPath = Join-Path $CommonBin 'bin\Microsoft.Dynamics.ApplicationPlatform.XppServices.Instrumentation.dll'
        Load-DllinMemory -dllPath $dllPath

        [Microsoft.Dynamics.AX.AXInstallationInfo.AXInstallationInfo]::ScanMetadataModelInRuntimePackage($packagePath)
    }
    catch
    {}
}

function Get-IsAppFallOrLater([Parameter(Mandatory=$false)] $webroot)
{
    $version = Get-ApplicationReleaseFromAOS -webroot:$webroot

    return $($version -ne "RTW")
}

function Get-ApplicationReleaseFromPackage
{
    $packageRoot = split-Path -parent "$(split-Path -parent $PSScriptRoot)" 
    $PackageInstallationInfo = "$packageRoot\HotfixInstallationInfo.xml"
    $XPath = '/HotfixInstallationInfo/ServiceModelList/ComponentModel/Release[../ServiceModelGroup = "Application"]'
    $ApplicationRelease =  Select-Xml -Path $PackageInstallationInfo -XPath $Xpath 
    $MRXPath = '/HotfixInstallationInfo/ServiceModelList/ComponentModel[Name = "MRApplicationService"]'
    $MRApplicationServiceModel =  Select-Xml -Path $PackageInstallationInfo -XPath $MRXpath 

    if($ApplicationRelease.Count -ge 1)
    {
        return $ApplicationRelease[0].Node.InnerText
    }
    elseif ($MRApplicationServiceModel -eq $null)
    {
        return ""
    }
    else
    {
        return "RTW"
    }
}

function Get-IsModulePartOfPlatformAsBinary ([string] $packageNugetFile)
{
    [Void][Reflection.Assembly]::LoadWithPartialName('System.IO.Compression.FileSystem') 

    try
    {
        $PackFiles = [IO.Compression.ZipFile]::OpenRead($packageNugetFile)
        $PackageSpec =  $PackFiles.Entries | where {($_.Name -like '*.nuspec')}

        if(!($PackageSpec))
        {
            Throw "Unable to get package information"
        }

        [System.Xml.XmlDocument] $xmlDoc = New-Object System.Xml.XmlDocument
        $XmlDoc.Load($PackageSpec.Open())

        $PackFiles.Dispose()

        $Description = $xmlDoc.GetElementsByTagName('description').Item(0).InnerText

        if($Description.Contains("[Platform Package]"))
        {
            return $true
        }
        else
        {
            return $false
        }        
    }
    catch
    {
        return $false
    }
}

function Get-IsModulePartOfApplicationAsBinary ([string] $PackageNugetFilePath)
{
    [Void][Reflection.Assembly]::LoadWithPartialName('System.IO.Compression.FileSystem') 

    try
    {
        $PackFiles = [IO.Compression.ZipFile]::OpenRead($PackageNugetFilePath)
        $PackageSpec =  $PackFiles.Entries | Where-Object {($_.Name -like '*.nuspec')}

        if(!($PackageSpec))
        {
            Throw "Unable to get package information"
        }

        [System.Xml.XmlDocument] $xmlDoc=new-object System.Xml.XmlDocument
        $XmlDoc.Load($PackageSpec.Open())

        $PackFiles.Dispose()

        $Description = $xmlDoc.GetElementsByTagName('description').Item(0).InnerText

        if($Description.Contains("[Application Package]"))
        {
            return $true
        }
        else
        {
            return $false
        }
    }
    catch
    {
        return $false
    }
}

function Get-IsPlatformUpdate3OrLater([Parameter(Mandatory=$false)] $webroot)
{
    if (!$webroot) {
    $webroot = Get-AosWebSitePhysicalPath
    }

    #must use job or process to load the production information provider dll or it'll lock it self
    #in memory copy is not usable as this dll have some special hard coded reference dll which won't resolve when loaded in memory.
    $job = Start-Job -ScriptBlock  {
        param($webrootBlock)
        $VersionDLLPath = Join-Path $webrootBlock 'bin\Microsoft.Dynamics.BusinessPlatform.ProductInformation.Provider.dll'
        Add-Type -Path $VersionDLLPath
        $provider = [Microsoft.Dynamics.BusinessPlatform.ProductInformation.Provider.ProductInfoProvider]::get_Provider();
        $version = $provider.get_PlatformVersion();
        $version
    } -ArgumentList $webroot
    Wait-Job -Job $job | Out-Null
    $version = Receive-Job -Job $job

    return $(($version -ne '7.0') -and ($version -ne '7.0.0.0') -and (![string]::IsNullOrEmpty($version)))    
}

function Get-IsPackageContainUpgradeBinaryForUpdate3
{
    $sourcePath = [IO.Path]::Combine($(split-Path -parent $PSScriptRoot), "Packages")
    #using a framework package from platform which customer cannot generate to identify if it's from platform update 3
    $files=get-childitem -Path:$sourcePath dynamicsax-framework-bin.*.nupkg
    foreach ($packageFile in $files) 
    {
        if(Get-IsModulePartOfPlatformAsBinary -packageNugetFile $packageFile.FullName)
        {
            return $true
        }
    }

    return $false
}

function Get-ProductPlatformBuildVersion([Parameter(Mandatory=$false)] $webroot)
{
    if (!$webroot) {
       $webroot = Get-AosWebSitePhysicalPath
    }

    #must use job or process to load the production information provider dll or it'll lock it self
    #in memory copy is not usable as this dll have some special hard coded reference dll which won't resolve when loaded in memory.
    $job = Start-Job -ScriptBlock  {
        param($webrootBlock)
        $VersionDLLPath = Join-Path $webrootBlock 'bin\Microsoft.Dynamics.BusinessPlatform.ProductInformation.Provider.dll'
        Add-Type -Path $VersionDLLPath
        $provider = [Microsoft.Dynamics.BusinessPlatform.ProductInformation.Provider.ProductInfoProvider]::get_Provider();
        $version = $provider.get_PlatformBuildVersion();
        $version
    } -ArgumentList $webroot
    Wait-Job -Job $job | Out-Null
    $version = Receive-Job -Job $job
   
    $build = [System.Version]::new()
    $releaseBuild
    if([System.Version]::TryParse($Version, [ref]$build))
    {
        $releaseBuild = $build.Build
    }
    else
    {
        #default to 0 from 7.0.0.0 
        $releaseBuild = 0
    }   

    return  $releaseBuild
}

function Get-ProductPlatformBuildFullVersion
{
    $webroot = Get-AosWebSitePhysicalPath

    #must use job or process to load the production information provider dll or it'll lock it self
    #in memory copy is not usable as this dll have some special hard coded reference dll which won't resolve when loaded in memory.
    $job = Start-Job -ScriptBlock  {
        param($webrootBlock)
        $VersionDLLPath = Join-Path $webrootBlock 'bin\Microsoft.Dynamics.BusinessPlatform.ProductInformation.Provider.dll'
        Add-Type -Path $VersionDLLPath
        $provider = [Microsoft.Dynamics.BusinessPlatform.ProductInformation.Provider.ProductInfoProvider]::get_Provider();
        $version = $provider.get_PlatformBuildVersion();
        $version
    } -ArgumentList $webroot
    Wait-Job -Job $job | Out-Null
    $version = Receive-Job -Job $job
   
    $build = [System.Version]::new()
    
    if([System.Version]::TryParse($Version, [ref]$build))
    {
        return $build
    }
    
    return $null
}

function Get-ProductApplicationVersion ([Parameter(Mandatory=$false)] $webroot)
{
    if($webroot -eq $null)
    {
        $webroot = Get-AosWebSitePhysicalPath
    }

    #must use job or process to load the production information provider dll or it'll lock it self
    #in memory copy is not usable as this dll have some special hard coded reference dll which won't resolve when loaded in memory.
    $job = Start-Job -ScriptBlock  {
        param($webrootBlock)
        $VersionDLLPath = Join-Path $webrootBlock 'bin\Microsoft.Dynamics.BusinessPlatform.ProductInformation.Provider.dll'
        Add-Type -Path $VersionDLLPath
        $provider = [Microsoft.Dynamics.BusinessPlatform.ProductInformation.Provider.ProductInfoProvider]::get_Provider();
        $version = $provider.get_ApplicationBuildVersion();
        $version
    } -ArgumentList $webroot
    Wait-Job -Job $job | Out-Null
    $version = Receive-Job -Job $job    
    
    return  $version
}

function Get-DataAccessSqlPwd
{
    $Config = Get-ApplicationEnvironment
    return $Config.DataAccess.SqlPwd
}

function Get-DataAccessDatabase
{
    $Config = Get-ApplicationEnvironment
    return $Config.DataAccess.Database
}

function Get-DataAccessSqlUsr
{
    $Config = Get-ApplicationEnvironment
    return $Config.DataAccess.SqlUser
}

function Get-DataAccessDbServer
{
    $Config = Get-ApplicationEnvironment
    return $Config.DataAccess.DbServer
}


function Get-AOSPackageDirectory
{
    $Config = Get-ApplicationEnvironment
    return $Config.Aos.PackageDirectory
}

function Get-CommonBinDir
{
    $Config = Get-ApplicationEnvironment
    return $Config.Common.BinDir
}

function Get-BiReportingPersistentVirtualMachineIPAddressSSRS
{
    $Config = Get-ApplicationEnvironment
    return $Config.BiReporting.PersistentVirtualMachineIPAddressSSRS
}

function Get-BiReportingReportingServers
{
    $Config = Get-ApplicationEnvironment
    $reportingServers = $Config.BiReporting.ReportingServers
    if ([System.String]::IsNullOrWhiteSpace($reportingServers))
    {
        $reportingServers = $Config.BiReporting.PersistentVirtualMachineIPAddressSSRS
    }

    return $reportingServers
}

function Get-UseReportingCluster
{
    $webRoot = Get-AosWebSitePhysicalPath
    $webConfigPath = join-path $webRoot "web.config"
    
    if(Test-Path $webConfigPath){
        [System.Xml.XmlDocument] $webConfig = new-object System.Xml.XmlDocument
        $webConfig.Load($webConfigPath)

        $ns = New-Object System.Xml.XmlNamespaceManager($webConfig.NameTable)
        $ns.AddNamespace("ns",$webConfig.DocumentElement.NamespaceURI)
        $key = "UseReportingCluster"
        $userClusterKey = $webConfig.SelectSingleNode("//ns:add[@key='$key']",$ns)

        if($null -ne $userClusterKey){
            if($userClusterKey.Value -eq $true){
                return $true
            }
        }
    }

    return $false
}

function Get-InfrastructureClickonceAppsDirectory
{
    $Config = Get-ApplicationEnvironment
    return $Config.Infrastructure.ClickonceAppsDirectory
}

function Get-DevToolsInstalled
{
    $webroot = Get-AosWebSitePhysicalPath
    $webconfig=join-path $webroot "web.config"
    $DevInstall=$false
    
    [System.Xml.XmlDocument] $xd=new-object System.Xml.XmlDocument
    $xd.Load($webconfig)
    $ns=New-Object System.Xml.XmlNamespaceManager($xd.NameTable)
    $ns.AddNamespace("ns",$xd.DocumentElement.NamespaceURI)

    $key="Infrastructure.VSToolsCount"

    $VScount = $xd.SelectSingleNode("//ns:add[@key='$key']",$ns)

    if($VScount -ne $null){
        
        if($VScount.GetAttribute("value") -gt 0)
        {
            $DevInstall=$true
        }
    }
    return $DevInstall 
}

function Get-ProductVersionMajorMinor
{
    [string]  $productVersionMajorMinorString = '7.0'
    return $productVersionMajorMinorString
}

function Get-IsRetailProductSku
{
    $productVersion = Get-ProductVersionMajorMinor    
    $retailHQConfigurationLocationRegistryPath = "HKLM:\SOFTWARE\Microsoft\Dynamics\$productVersion\Setup\Metadata"
    if(Test-Path $retailHQConfigurationLocationRegistryPath)
    {
        $retailProductSku = Get-ItemProperty -Path $retailHQConfigurationLocationRegistryPath -Name 'ProductSku' -ErrorAction SilentlyContinue
        
        if($retailProductSku -and $retailProductSku.ProductSku -and ($retailProductSku.ProductSku -eq 'Dynamics365ForRetail'))
        {
            return $true
        }
    }

    return $false
}

function Get-IsOverlayeringDisabled
{
    $productVersion = Get-ProductVersionMajorMinor    
    $retailHQConfigurationLocationRegistryPath = "HKLM:\SOFTWARE\Microsoft\Dynamics\$productVersion\Setup\Metadata"
    if(Test-Path $retailHQConfigurationLocationRegistryPath)
    {
        $isOverlayeringDisabled = Get-ItemProperty -Path $retailHQConfigurationLocationRegistryPath -Name 'DisableOverlayering' -ErrorAction SilentlyContinue
        
        if($isOverlayeringDisabled -and $isOverlayeringDisabled.DisableOverlayering -and ($isOverlayeringDisabled.DisableOverlayering -like 'true'))
        {
            return $true
        }
    }

    return $false
}

function Get-IsAppSealed ([Parameter(Mandatory=$false)] $webroot)
{
    if($webroot -eq $null)
    {
        $webroot = Get-AosWebSitePhysicalPath
    }

    $Version = (Get-ProductApplicationVersion -webroot:$webroot)
    $build = [System.Version]::new()
    $minSealedVersion = new-object System.Version "8.1"

    if([System.Version]::TryParse($Version, [ref]$build))
    {
        # Any build major/minor 8.1+ is considered sealed.
        if($build.CompareTo($minSealedVersion) -ge 0)
        {
           return $true
        }

        # Sealing logic for 8.0 and earlier
        if($build.Major -ge "8")
        {
            ##Bug 240512: Receipt designer bits are not updated with the uptake of latest binary hotfix
            ##The appseal have a different meaning during package deployment than development
            ##if the appSeal == true we expect full binary hotfix, other wise we expect seperate x++ hotfix and special handle the remaining mofule (ie, clickonce... package)
            ##the app8.0, even though it's sealed from dev point of view, it's still releasing seperate x++ hotfix and the special handling code path for none sealed need to be used during package deployment
            if($build.Minor -ge "1") 
            {
                return $true
            }
        }
        elseif($build.Minor -ge "2")
        {
            if($build.Build.ToString().StartsWith("2"))
            {
                return $true
            }
        }
    }
    
    return $false
    
}

function Get-DependencyAXModelList([string] $sourcePath, [string] $metaPackageName)
{
    $microsoftPackages = @()
    [Void][Reflection.Assembly]::LoadWithPartialName('System.IO.Compression.FileSystem')
    $zipFile = Get-Item $sourcePath\$metaPackageName*.nupkg
    if($zipFile -ne $null)
    {
        $PackFiles = [IO.Compression.ZipFile]::OpenRead($zipFile).Entries
        $PackageSpec =  $PackFiles | where {($_.Name -like "*.nuspec")}

        if(!($PackageSpec))
        {
            Throw "Unable to get package information for $metaPackageName"
        }

        [System.Xml.XmlDocument] $xmlDoc=new-object System.Xml.XmlDocument
        $XmlDoc.Load($PackageSpec.Open())

        $Dependencies = $xmlDoc.GetElementsByTagName('dependency').id
        
        foreach($d in $Dependencies)
        {
            $microsoftPackages += $d
        }
    }
    
    return $microsoftPackages
}

function Get-ALMPackageCopyPath
{
    [string]$ALMBackupPath = ""

    # Is the ALM Service registered (environment variable "DynamicsSDK" would be set)
    if ($env:DynamicsSDK)
    {
        $RegPath = "HKLM:\SOFTWARE\Microsoft\Dynamics\AX\7.0\SDK"

        [string]$ALMBackupPath = $null
        
        # Do not fail when registry key is not found
        try
        {
            # Get the Dynamics SDK (ALM Service) registry key (throws if not found).
            $RegKey = Get-ItemProperty -Path $RegPath
            if ($RegKey -ne $null)
            {
                # Check if backup path set in registry
                $ALMBackupPath = $RegKey.BackupPath
            }
        }
        catch
        {
        }
        
        # If path not found in registry, check default paths
        if (-not $ALMBackupPath)
        {
            if (Test-Path "I:\DynamicsBackup")
            {
                $ALMBackupPath = "I:\DynamicsBackup"
            }
            elseif (Test-Path "$($env:SystemDrive)\DynamicsBackup")
            {
                $ALMBackupPath = "$($env:SystemDrive)\DynamicsBackup"
            }
        }
    }

    return $ALMBackupPath
}

function Get-EnvironmentId
{
    $Config = Get-ApplicationEnvironment
    return $Config.LCS.LCSEnvironmentId
}

function Get-DataAccessFlightingCachePath
{
    $Config = Get-ApplicationEnvironment
    return $Config.DataAccess.FlightingCachePath
}

function Get-DataAccessFlightingEnvironment
{
    $Config = Get-ApplicationEnvironment
    return $Config.DataAccess.FlightingEnvironment
}

function Get-DataAccessFlightingCertificateThumbprint
{
    $Config = Get-ApplicationEnvironment
    return $Config.DataAccess.FlightingCertificateThumbprint
}

function Get-DataAccessFlightingServiceCatalogID
{
    $Config = Get-ApplicationEnvironment
    return $Config.DataAccess.FlightingServiceCatalogID
}

function Get-TenantDomainGUID
{
    $Config = Get-ApplicationEnvironment
    return $Config.Aad.TenantDomainGUID
}

function Get-AADTenantId
{
    $Config = Get-ApplicationEnvironment
    return $Config.Aad.AADTenantId
}

function Get-S2SCertificate
{
    try
    {
        $config = Get-ApplicationEnvironment
        $certHandlerSetttings = $config.CertificateHandler.GetCertificateHandlerSettings()

        $certificateHandler = [Microsoft.Dynamics.AX.Configuration.CertificateHandler.CertificateHandlerFactory]::CreateCertificateHandler($certHandlerSetttings)
    
        $s2sCertificate = $certificateHandler.GetSingleCertificateForId($config.Infrastructure.S2SCertThumbprint)

        return $s2sCertificate
    }
    catch
    {
        return $null
    }
}

function Load-FlightingDlls
{
    $webroot = Get-AosWebSitePhysicalPath

    Load-DllinMemory "$webroot\bin\Microsoft.Carbon.CertificateCommon.dll"
    Load-DllinMemory "$webroot\bin\Microsoft.Carbon.Flighting.Runtime.dll"
    Load-DllinMemory "$webroot\bin\Microsoft.Commerce.Flighting.Common.dll"

    Load-DllinMemory "$webroot\bin\Microsoft.Dynamics.BusinessPlatform.SharedTypes.dll"
    Load-DllinMemory "$webroot\bin\Microsoft.Dynamics.ApplicationPlatform.XppServices.Instrumentation.dll"
    Load-DllinMemory "$webroot\bin\Microsoft.Dynamics.ApplicationPlatform.Services.Instrumentation.dll"
    Load-DllinMemory "$webroot\bin\Microsoft.Dynamics.AX.Data.Sql.Shared.dll"
    Load-DllinMemory "$webroot\bin\Microsoft.Dynamics.ApplicationPlatform.Flighting.dll"
    Load-DllinMemory "$webroot\bin\Microsoft.Dynamics.ApplicationPlatform.AOSFlighting.dll"
    Load-DllinMemory "$webroot\bin\Microsoft.Dynamics.ApplicationPlatform.PerformanceCounters.dll"
    Load-DllinMemory "$webroot\bin\Microsoft.Practices.EnterpriseLibrary.TransientFaultHandling.dll"
    Load-DllinMemory "$webroot\bin\Microsoft.Practices.EnterpriseLibrary.TransientFaultHandling.Data.dll"
    Load-DllinMemory "$webroot\bin\Newtonsoft.Json.dll"

    # Contained in XppServices.Instrumentation in earlier releases
    $dbSyncInstrumentationPath = "$webroot\bin\Microsoft.Dynamics.ApplicationPlatform.DatabaseSynchronize.Instrumentation.dll"
    if (Test-Path $dbSyncInstrumentationPath)
    {
        Load-DllinMemory $dbSyncInstrumentationPath
    }
}

$script:FlightingProvider = $null
function Get-IsFlightEnabled([string] $flightName)
{
    $ErrorActionPreference = 'Stop'

    if ([String]::IsNullOrWhiteSpace($flightName))
    {
        return $false
    }

    if ($script:FlightingProvider -eq $null)
    {
        $sqlPwd    = Get-DataAccessSqlPwd
        $sqlUser   = Get-DataAccessSqlUsr
        $sqlServer = Get-DataAccessDbServer
        $sqlDB     = Get-DataAccessDatabase
        $connectionString = "Data Source=$sqlServer; " +
            "Integrated Security=False; " +
            "User Id=$sqlUser; " +
            "Password=`"$sqlPwd`"; " +
            "Initial Catalog=$sqlDB"

        $flightingCacheFolder = Get-DataAccessFlightingCachePath
        if ([String]::IsNullOrWhiteSpace($flightingCacheFolder))
        {
            $flightingCacheFolder = Get-AosWebSitePhysicalPath # webroot
        }

        Load-FlightingDlls

        $flightingConfiguration = New-Object -TypeName Microsoft.Dynamics.ApplicationPlatform.AOSFlighting.StaticFlightingServiceConfiguration -ArgumentList `
            (Get-DataAccessFlightingEnvironment), `
            (Get-DataAccessFlightingCertificateThumbprint), `
            (Get-DataAccessFlightingServiceCatalogID), `
            $flightingCacheFolder, `
            $null, # object extraInformation `
            $connectionString, `
            (60 * 60) # int refreshDataIntervalInSec

        $script:FlightingProvider = [Microsoft.Dynamics.ApplicationPlatform.AOSFlighting.AOSFlightingSystem]::InitializeFlightService($flightingConfiguration)
        $script:FlightingProvider.AddInformationToCommonContext("TenantID", (Get-TenantDomainGUID))
        $script:FlightingProvider.AddInformationToCommonContext("EnvironmentId", (Get-EnvironmentId))

        Write-Log "Flighting provider is a $($script:FlightingProvider.GetType().Name)."
    }

    return $script:FlightingProvider.IsFeatureEnabled($flightName)
}

function IsLocalServer([string] $serverName)
{
    if ($serverName -eq $null) { return $false }
    
    if ("." -eq $serverName) { return $true }
    if ("(local)" -eq $serverName) { return $true }
    if ("localhost" -eq $serverName) { return $true }
    if ("127.0.0.1" -eq $serverName) { return $true }
    if ([System.Environment]::MachineName -eq $serverName.Split('.')[0]) { return $true }

    return $false
}

function Invoke-XppStaticMethod()
{
    Param(
        [Parameter(Mandatory=$true)]
        [ValidatePattern('^[a-zA-Z0-9_]+$')]
        [String]
        $ClassName,

        [Parameter(Mandatory=$true)]
        [ValidatePattern('^[a-zA-Z0-9_]+$')]
        [String]
        $MethodName,

        [Parameter(Mandatory=$true)]
        [ValidateNotNullOrEmpty()]
        [String]
        $RedirectStandardError
    )

    $commandParameter = "-bindir `"$(Get-CommonBinDir)`""
    $commandParameter += " -metadatadir `"$(Get-AOSPackageDirectory)`""
    $commandParameter += " -sqluser `"$(Get-DataAccessSqlUsr)`""
    $commandParameter += " -sqlserver `"$(Get-DataAccessDbServer)`""
    $commandParameter += " -sqldatabase `"$(Get-DataAccessDatabase)`""
    $commandParameter += " -sqlpwd `"$(Get-DataAccessSqlPwd)`""
    $commandParameter += " -setupmode runstaticxppmethod"
    $commandParameter += " -classname $ClassName"
    $commandParameter += " -methodname $MethodName"

    $webroot = Get-AosWebSitePhysicalPath
    $startProcessArgs = @{
        FilePath = "$webroot\bin\Microsoft.Dynamics.AX.Deployment.Setup.exe"
        ArgumentList = $commandParameter
        PassThru = $true
        Wait = $true
        RedirectStandardError = $RedirectStandardError
    }

    $process = Start-Process @startProcessArgs
    
    if ($process.ExitCode -ne 0)
    {
        $errorContent = Get-Content "$RedirectStandardError"
        if ($errorContent -eq $null)
        {
            $errorContent = "Process terminated with exit code $($process.ExitCode) (error stream is empty)."
        }
        throw $errorContent
    }
}

if(!$useServiceFabric)
{
    if (Test-Path "$($PSScriptRoot)\NonAdminDevToolsInterject.ps1")
    {
        & "$($PSScriptRoot)\NonAdminDevToolsInterject.ps1"
    }
}

function Get-HotfixInstallationInfo
{
    $packageRoot = split-Path -parent "$(split-Path -parent $PSScriptRoot)"

    # Using job to load the AXInstallationInfo dll to avoid file locks
    $job = Start-Job -ScriptBlock  {
        param($packageRootBlock)
        $axInstallationInfoDLLPath = Join-Path $packageRootBlock "Microsoft.Dynamics.AX.AXInstallationInfo.dll"
        $hotfixInstallationInfoFilePath = Join-Path $packageRootBlock "HotfixInstallationInfo.xml"
        try
        {
            if (Test-Path $axInstallationInfoDLLPath)
            {
                # Load AXInstallationInfo.dll
                [void][System.Reflection.Assembly]::LoadFrom($axInstallationInfoDLLPath)
                $hotfixInstallationInfo = New-Object Microsoft.Dynamics.AX.AXInstallationInfo.HotfixInstallationInfo

                if (Test-Path $hotfixInstallationInfoFilePath)
                {
                    # Initialize HotfixInstallationInfo from HotfixInstallationInfo.xml
                    $hotfixInstallationInfo.InitFromFile($hotfixInstallationInfoFilePath)
                    # Get HotfixInstallationInfo
                    $hotfixInstallationInfo
                }
            }
        }
        catch
        {
            Write-Warning "Failed to get HotfixInstallationInfo instance from deployable package"
            return $null
        }
    } -ArgumentList $packageRoot
    Wait-Job -Job $job | Out-Null
    $hotfixInstallationInfo  = Receive-Job -Job $job

    return $hotfixInstallationInfo
}

function Get-IsBinaryPackageTypeFromPackage
{
    $hotfixInstallationInfo = Get-HotfixInstallationInfo
    # Get Package Type from HotfixInstallationInfo for the package being deployed
    $packageType = $hotfixInstallationInfo.Type
    if(![string]::IsNullOrEmpty($packageType))
    {
        return ($packageType -eq 'PlatAppBinaryHotfixPackage' -or $packageType -eq 'MergedPackage')
    }

    Write-Warning "Failed to get package type from deployable package"
    return $false
}

function Get-MetadataModuleListFromPackage
{
    $hotfixInstallationInfo = Get-HotfixInstallationInfo
    # Get Metadata Module List from HotfixInstallationInfo of the package being deployed
    $metadataModuleList = $hotfixInstallationInfo.MetadataModuleList
    if(![string]::IsNullOrEmpty($metadataModuleList))
    {
        return $metadataModuleList
    }

    Write-Warning "Failed to get metadata module list from HotfixInstallationInfo.xml."
    return ""
}

function Get-PackageNamesFromDLL([Parameter(Mandatory=$false)] $webroot, [Parameter(Mandatory=$true)][string] $productInfoDLL)
{
    if (!$webroot) {
    $webroot = Get-AosWebSitePhysicalPath
    }

    # Using job to load the Product Information dll to avoid file locks
    $job = Start-Job -ScriptBlock  {
        param($webrootBlock, $productInfoDLLBlock)
        $metadataCoreDLLPath = Join-Path $webrootBlock "bin\Microsoft.Dynamics.AX.Metadata.Core.dll"
        $productInfoDLLPath = Join-Path $webrootBlock $productInfoDLLBlock
        try
        {
            if (Test-Path $metadataCoreDLLPath)
            {
                # Load Metadata.Core.dll
                [void][System.Reflection.Assembly]::LoadFrom($metadataCoreDLLPath)
                if (Test-Path $productInfoDLLPath)
                {
                    # Get package names from Product Information dll
                    $packageNames = [Microsoft.Dynamics.AX.Metadata.Core.CoreHelper]::GetPackagesNames($productInfoDLLPath, $null)
                    $packageNames
                }
            }
        }
        catch
        {
            Write-Warning "Failed to get package names from product information dll."
            return $null
        }
    } -ArgumentList $webroot,$productInfoDLL
    Wait-Job -Job $job | Out-Null
    $packageNames  = Receive-Job -Job $job
    return $packageNames
}

Export-ModuleMember -Function Get-DataAccessSqlPwd
Export-ModuleMember -Function Get-DataAccessDatabase
Export-ModuleMember -Function Get-DataAccessSqlUsr
Export-ModuleMember -Function Get-DataAccessDbServer
Export-ModuleMember -Function Get-AOSPackageDirectory
Export-ModuleMember -Function Get-CommonBinDir
Export-ModuleMember -Function Get-BiReportingPersistentVirtualMachineIPAddressSSRS
Export-ModuleMember -Function Get-BiReportingReportingServers
Export-ModuleMember -Function Get-UseReportingCluster
Export-ModuleMember -Function Get-InfrastructureClickonceAppsDirectory
Export-ModuleMember -Function Get-DevToolsInstalled
Export-ModuleMember -Function Get-IsModulePartOfPlatformAsBinary
Export-ModuleMember -Function Get-IsAppFallOrLater
Export-ModuleMember -Function Get-IsPlatformUpdate3OrLater
Export-ModuleMember -Function Get-IsPackageContainUpgradeBinaryForUpdate3
Export-ModuleMember -Function Get-ProductPlatformBuildVersion
Export-ModuleMember -Function Get-ProductApplicationVersion
Export-ModuleMember -Function Get-ProductPlatformBuildFullVersion
Export-ModuleMember -Function Get-ApplicationReleaseFromPackage
Export-ModuleMember -Function Get-ProductVersionMajorMinor
Export-ModuleMember -Function Get-IsRetailProductSku
Export-ModuleMember -Function Get-IsOverlayeringDisabled
Export-ModuleMember -Function Get-DependencyAXModelList
Export-ModuleMember -Function Get-IsAppSealed
Export-ModuleMember -Function Get-IsModulePartOfApplicationAsBinary
Export-ModuleMember -Function Get-ALMPackageCopyPath
Export-ModuleMember -Function Get-IsFlightEnabled
Export-ModuleMember -Function GenerateMetadataModuleInstallationInfo
Export-ModuleMember -Function Get-EnvironmentId
Export-ModuleMember -Function Get-AADTenantId
Export-ModuleMember -Function Get-TenantDomainGUID
Export-ModuleMember -Function Get-S2SCertificate
Export-ModuleMember -Function IsLocalServer
Export-ModuleMember -Function Invoke-XppStaticMethod
Export-ModuleMember -Function Get-IsBinaryPackageTypeFromPackage
Export-ModuleMember -Function Get-MetadataModuleListFromPackage
Export-ModuleMember -Function Get-PackageNamesFromDLL

# SIG # Begin signature block
# MIIr/QYJKoZIhvcNAQcCoIIr7jCCK+oCAQExDzANBglghkgBZQMEAgEFADB5Bgor
# BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG
# KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCCl/ccGLqnEnnJv
# 1HCBSSXueHFuMCYkbfotpy0/Dx7f8KCCEW4wggh+MIIHZqADAgECAhM2AAAB33OB
# lxa+Mv0NAAIAAAHfMA0GCSqGSIb3DQEBCwUAMEExEzARBgoJkiaJk/IsZAEZFgNH
# QkwxEzARBgoJkiaJk/IsZAEZFgNBTUUxFTATBgNVBAMTDEFNRSBDUyBDQSAwMTAe
# Fw0yNDAxMjAwMTMzNDRaFw0yNTAxMTkwMTMzNDRaMCQxIjAgBgNVBAMTGU1pY3Jv
# c29mdCBBenVyZSBDb2RlIFNpZ24wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK
# AoIBAQDVucAmkbIWpspYysyydQyyRh2L8q5igYFcy2vDk8xGvVMRBhxwbOsJIEd0
# wY8N7WU/xgkYMnSsM4vmc2B49DGdrAjSJqbsx0zf+DLFjrBITUecdRhlq0VKGX8U
# bVOkg0aIfFNLRs4DSrCZYh26zyB8qkL/jUmB7DhcBEhhgOlXRQ4LHnUv7qf+iXqD
# uwFz9tUTAh8JGsgLRBK0oSsRfUB+FJF2KyUxzmeFXJKiEynsWz4kqoM91ag1Yw0U
# 8d0e+RgAKi3Ft1cXA+3qKM6I1H11e/NdIjh7oThvrBtfEngwlwbTF3KZOHdhLBFZ
# 18U4v8VeTlb4r94346CY2+SKnQa7AgMBAAGjggWKMIIFhjApBgkrBgEEAYI3FQoE
# HDAaMAwGCisGAQQBgjdbAQEwCgYIKwYBBQUHAwMwPQYJKwYBBAGCNxUHBDAwLgYm
# KwYBBAGCNxUIhpDjDYTVtHiE8Ys+hZvdFs6dEoFgg93NZoaUjDICAWQCAQ4wggJ2
# BggrBgEFBQcBAQSCAmgwggJkMGIGCCsGAQUFBzAChlZodHRwOi8vY3JsLm1pY3Jv
# c29mdC5jb20vcGtpaW5mcmEvQ2VydHMvQlkyUEtJQ1NDQTAxLkFNRS5HQkxfQU1F
# JTIwQ1MlMjBDQSUyMDAxKDIpLmNydDBSBggrBgEFBQcwAoZGaHR0cDovL2NybDEu
# YW1lLmdibC9haWEvQlkyUEtJQ1NDQTAxLkFNRS5HQkxfQU1FJTIwQ1MlMjBDQSUy
# MDAxKDIpLmNydDBSBggrBgEFBQcwAoZGaHR0cDovL2NybDIuYW1lLmdibC9haWEv
# QlkyUEtJQ1NDQTAxLkFNRS5HQkxfQU1FJTIwQ1MlMjBDQSUyMDAxKDIpLmNydDBS
# BggrBgEFBQcwAoZGaHR0cDovL2NybDMuYW1lLmdibC9haWEvQlkyUEtJQ1NDQTAx
# LkFNRS5HQkxfQU1FJTIwQ1MlMjBDQSUyMDAxKDIpLmNydDBSBggrBgEFBQcwAoZG
# aHR0cDovL2NybDQuYW1lLmdibC9haWEvQlkyUEtJQ1NDQTAxLkFNRS5HQkxfQU1F
# JTIwQ1MlMjBDQSUyMDAxKDIpLmNydDCBrQYIKwYBBQUHMAKGgaBsZGFwOi8vL0NO
# PUFNRSUyMENTJTIwQ0ElMjAwMSxDTj1BSUEsQ049UHVibGljJTIwS2V5JTIwU2Vy
# dmljZXMsQ049U2VydmljZXMsQ049Q29uZmlndXJhdGlvbixEQz1BTUUsREM9R0JM
# P2NBQ2VydGlmaWNhdGU/YmFzZT9vYmplY3RDbGFzcz1jZXJ0aWZpY2F0aW9uQXV0
# aG9yaXR5MB0GA1UdDgQWBBSO7i0qme7tjtjFjyuIjlmGM6cbCTAOBgNVHQ8BAf8E
# BAMCB4AwRQYDVR0RBD4wPKQ6MDgxHjAcBgNVBAsTFU1pY3Jvc29mdCBDb3Jwb3Jh
# dGlvbjEWMBQGA1UEBRMNMjM2MTY3KzUwMTk3MDCCAeYGA1UdHwSCAd0wggHZMIIB
# 1aCCAdGgggHNhj9odHRwOi8vY3JsLm1pY3Jvc29mdC5jb20vcGtpaW5mcmEvQ1JM
# L0FNRSUyMENTJTIwQ0ElMjAwMSgyKS5jcmyGMWh0dHA6Ly9jcmwxLmFtZS5nYmwv
# Y3JsL0FNRSUyMENTJTIwQ0ElMjAwMSgyKS5jcmyGMWh0dHA6Ly9jcmwyLmFtZS5n
# YmwvY3JsL0FNRSUyMENTJTIwQ0ElMjAwMSgyKS5jcmyGMWh0dHA6Ly9jcmwzLmFt
# ZS5nYmwvY3JsL0FNRSUyMENTJTIwQ0ElMjAwMSgyKS5jcmyGMWh0dHA6Ly9jcmw0
# LmFtZS5nYmwvY3JsL0FNRSUyMENTJTIwQ0ElMjAwMSgyKS5jcmyGgb1sZGFwOi8v
# L0NOPUFNRSUyMENTJTIwQ0ElMjAwMSgyKSxDTj1CWTJQS0lDU0NBMDEsQ049Q0RQ
# LENOPVB1YmxpYyUyMEtleSUyMFNlcnZpY2VzLENOPVNlcnZpY2VzLENOPUNvbmZp
# Z3VyYXRpb24sREM9QU1FLERDPUdCTD9jZXJ0aWZpY2F0ZVJldm9jYXRpb25MaXN0
# P2Jhc2U/b2JqZWN0Q2xhc3M9Y1JMRGlzdHJpYnV0aW9uUG9pbnQwHwYDVR0jBBgw
# FoAUllGE4Gtve/7YBqvD8oXmKa5q+dQwHwYDVR0lBBgwFgYKKwYBBAGCN1sBAQYI
# KwYBBQUHAwMwDQYJKoZIhvcNAQELBQADggEBAJe/YXNSCoXitLf/X5pfJZpep3cs
# jdqmBgg+8Kr++8XMjWwdm4tiLasJMUPCgmp5NYn3wC4GefGYwfF7Xm2FMSR2i6QU
# HjigGu6BjdWQh4EwGaNqXLkXlUM7Ww2Z0KrRtpCL16DCOTNZuCFPAytSHFskPWrr
# 6q3EBuiM6P5VLgFSKiAxcunldJorbrBrvZSZib1OINzFGAQszUR0ytovW6FOp+uo
# VhiQCqnOheC1ppnZPss7vnXoogyO0xgSW40bRlltGfwnlOd3IZ/43ZOj5XeeShg5
# 2SzVEiyYrZjD17MSNzQM1JKI07+mtAC7D+eZ/+g2pM/91oHcrDq9Nq4QrS0wggjo
# MIIG0KADAgECAhMfAAAAUeqP9pxzDKg7AAAAAABRMA0GCSqGSIb3DQEBCwUAMDwx
# EzARBgoJkiaJk/IsZAEZFgNHQkwxEzARBgoJkiaJk/IsZAEZFgNBTUUxEDAOBgNV
# BAMTB2FtZXJvb3QwHhcNMjEwNTIxMTg0NDE0WhcNMjYwNTIxMTg1NDE0WjBBMRMw
# EQYKCZImiZPyLGQBGRYDR0JMMRMwEQYKCZImiZPyLGQBGRYDQU1FMRUwEwYDVQQD
# EwxBTUUgQ1MgQ0EgMDEwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDJ
# mlIJfQGejVbXKpcyFPoFSUllalrinfEV6JMc7i+bZDoL9rNHnHDGfJgeuRIYO1LY
# /1f4oMTrhXbSaYRCS5vGc8145WcTZG908bGDCWr4GFLc411WxA+Pv2rteAcz0eHM
# H36qTQ8L0o3XOb2n+x7KJFLokXV1s6pF/WlSXsUBXGaCIIWBXyEchv+sM9eKDsUO
# LdLTITHYJQNWkiryMSEbxqdQUTVZjEz6eLRLkofDAo8pXirIYOgM770CYOiZrcKH
# K7lYOVblx22pdNawY8Te6a2dfoCaWV1QUuazg5VHiC4p/6fksgEILptOKhx9c+ia
# piNhMrHsAYx9pUtppeaFAgMBAAGjggTcMIIE2DASBgkrBgEEAYI3FQEEBQIDAgAC
# MCMGCSsGAQQBgjcVAgQWBBQSaCRCIUfL1Gu+Mc8gpMALI38/RzAdBgNVHQ4EFgQU
# llGE4Gtve/7YBqvD8oXmKa5q+dQwggEEBgNVHSUEgfwwgfkGBysGAQUCAwUGCCsG
# AQUFBwMBBggrBgEFBQcDAgYKKwYBBAGCNxQCAQYJKwYBBAGCNxUGBgorBgEEAYI3
# CgMMBgkrBgEEAYI3FQYGCCsGAQUFBwMJBggrBgEFBQgCAgYKKwYBBAGCN0ABAQYL
# KwYBBAGCNwoDBAEGCisGAQQBgjcKAwQGCSsGAQQBgjcVBQYKKwYBBAGCNxQCAgYK
# KwYBBAGCNxQCAwYIKwYBBQUHAwMGCisGAQQBgjdbAQEGCisGAQQBgjdbAgEGCisG
# AQQBgjdbAwEGCisGAQQBgjdbBQEGCisGAQQBgjdbBAEGCisGAQQBgjdbBAIwGQYJ
# KwYBBAGCNxQCBAweCgBTAHUAYgBDAEEwCwYDVR0PBAQDAgGGMBIGA1UdEwEB/wQI
# MAYBAf8CAQAwHwYDVR0jBBgwFoAUKV5RXmSuNLnrrJwNp4x1AdEJCygwggFoBgNV
# HR8EggFfMIIBWzCCAVegggFToIIBT4YxaHR0cDovL2NybC5taWNyb3NvZnQuY29t
# L3BraWluZnJhL2NybC9hbWVyb290LmNybIYjaHR0cDovL2NybDIuYW1lLmdibC9j
# cmwvYW1lcm9vdC5jcmyGI2h0dHA6Ly9jcmwzLmFtZS5nYmwvY3JsL2FtZXJvb3Qu
# Y3JshiNodHRwOi8vY3JsMS5hbWUuZ2JsL2NybC9hbWVyb290LmNybIaBqmxkYXA6
# Ly8vQ049YW1lcm9vdCxDTj1BTUVSb290LENOPUNEUCxDTj1QdWJsaWMlMjBLZXkl
# MjBTZXJ2aWNlcyxDTj1TZXJ2aWNlcyxDTj1Db25maWd1cmF0aW9uLERDPUFNRSxE
# Qz1HQkw/Y2VydGlmaWNhdGVSZXZvY2F0aW9uTGlzdD9iYXNlP29iamVjdENsYXNz
# PWNSTERpc3RyaWJ1dGlvblBvaW50MIIBqwYIKwYBBQUHAQEEggGdMIIBmTBHBggr
# BgEFBQcwAoY7aHR0cDovL2NybC5taWNyb3NvZnQuY29tL3BraWluZnJhL2NlcnRz
# L0FNRVJvb3RfYW1lcm9vdC5jcnQwNwYIKwYBBQUHMAKGK2h0dHA6Ly9jcmwyLmFt
# ZS5nYmwvYWlhL0FNRVJvb3RfYW1lcm9vdC5jcnQwNwYIKwYBBQUHMAKGK2h0dHA6
# Ly9jcmwzLmFtZS5nYmwvYWlhL0FNRVJvb3RfYW1lcm9vdC5jcnQwNwYIKwYBBQUH
# MAKGK2h0dHA6Ly9jcmwxLmFtZS5nYmwvYWlhL0FNRVJvb3RfYW1lcm9vdC5jcnQw
# gaIGCCsGAQUFBzAChoGVbGRhcDovLy9DTj1hbWVyb290LENOPUFJQSxDTj1QdWJs
# aWMlMjBLZXklMjBTZXJ2aWNlcyxDTj1TZXJ2aWNlcyxDTj1Db25maWd1cmF0aW9u
# LERDPUFNRSxEQz1HQkw/Y0FDZXJ0aWZpY2F0ZT9iYXNlP29iamVjdENsYXNzPWNl
# cnRpZmljYXRpb25BdXRob3JpdHkwDQYJKoZIhvcNAQELBQADggIBAFAQI7dPD+jf
# XtGt3vJp2pyzA/HUu8hjKaRpM3opya5G3ocprRd7vdTHb8BDfRN+AD0YEmeDB5HK
# QoG6xHPI5TXuIi5sm/LeADbV3C2q0HQOygS/VT+m1W7a/752hMIn+L4ZuyxVeSBp
# fwf7oQ4YSZPh6+ngZvBHgfBaVz4O9/wcfw91QDZnTgK9zAh9yRKKls2bziPEnxeO
# ZMVNaxyV0v152PY2xjqIafIkUjK6vY9LtVFjJXenVUAmn3WCPWNFC1YTIIHw/mD2
# cTfPy7QA1pT+GPARAKt0bKtq9aCd/Ym0b5tPbpgCiRtzyb7fbNS1dE740re0COE6
# 7YV2wbeo2sXixzvLftH8L7s9xv9wV+G22qyKt6lmKLjFK1yMw4Ni5fMabcgmzRvS
# jAcbqgp3tk4a8emaaH0rz8MuuIP+yrxtREPXSqL/C5bzMzsikuDW9xH10graZzSm
# PjilzpRfRdu20/9UQmC7eVPZ4j1WNa1oqPHfzET3ChIzJ6Q9G3NPCB+7KwX0OQmK
# yv7IDimj8U/GlsHD1z+EF/fYMf8YXG15LamaOAohsw/ywO6SYSreVW+5Y0mzJutn
# BC9Cm9ozj1+/4kqksrlhZgR/CSxhFH3BTweH8gP2FEISRtShDZbuYymynY1un+Ry
# fiK9+iVTLdD1h/SxyxDpZMtimb4CgJQlMYIZ5TCCGeECAQEwWDBBMRMwEQYKCZIm
# iZPyLGQBGRYDR0JMMRMwEQYKCZImiZPyLGQBGRYDQU1FMRUwEwYDVQQDEwxBTUUg
# Q1MgQ0EgMDECEzYAAAHfc4GXFr4y/Q0AAgAAAd8wDQYJYIZIAWUDBAIBBQCgga4w
# GQYJKoZIhvcNAQkDMQwGCisGAQQBgjcCAQQwHAYKKwYBBAGCNwIBCzEOMAwGCisG
# AQQBgjcCARUwLwYJKoZIhvcNAQkEMSIEIAmIPQbnwYBhhzUCEiue6gjyU6V4ndeR
# Z/uW8lLlpo+OMEIGCisGAQQBgjcCAQwxNDAyoBSAEgBNAGkAYwByAG8AcwBvAGYA
# dKEagBhodHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20wDQYJKoZIhvcNAQEBBQAEggEA
# k3qNy9oEyOpo1t0RvXV6ihqVhYPQpAEwmeuyJXct3ppv/0e/F4kxcSeGkzwhEAxB
# tiYfDyqyOS6n5Pma6h/sYoBiVWNG4y+AN8DQgfIWZ1TlruwgHpSopitF3Mai1O6z
# fuZN+shchOIE9NLLuiVkP+EfnT7JQzAcM1mAsvu6ObmhrIG/aaMUj1ouI7MYArEp
# X7F1iErmoZ309ZfhjbwVnpo3rh21PN9gggb1RjKVyOpDnjGEI9tuoG19a9MzGHK9
# ZTrwRwekIybUtW1V9Fh8u3jQNrOPvnRsJaDypq+oq4dNKa2h7x2KKIxdg0u2ZEfJ
# PqA8tP7zWWy66BvtAO2evqGCF60wghepBgorBgEEAYI3AwMBMYIXmTCCF5UGCSqG
# SIb3DQEHAqCCF4YwgheCAgEDMQ8wDQYJYIZIAWUDBAIBBQAwggFaBgsqhkiG9w0B
# CRABBKCCAUkEggFFMIIBQQIBAQYKKwYBBAGEWQoDATAxMA0GCWCGSAFlAwQCAQUA
# BCCKU+e+jQnZjBrt76nr9qxdPQWNl86z9JnfPwCQT+ipKwIGZutBJzM/GBMyMDI0
# MTAwNDE0NTk1OC4wMTJaMASAAgH0oIHZpIHWMIHTMQswCQYDVQQGEwJVUzETMBEG
# A1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWlj
# cm9zb2Z0IENvcnBvcmF0aW9uMS0wKwYDVQQLEyRNaWNyb3NvZnQgSXJlbGFuZCBP
# cGVyYXRpb25zIExpbWl0ZWQxJzAlBgNVBAsTHm5TaGllbGQgVFNTIEVTTjo0MDFB
# LTA1RTAtRDk0NzElMCMGA1UEAxMcTWljcm9zb2Z0IFRpbWUtU3RhbXAgU2Vydmlj
# ZaCCEfswggcoMIIFEKADAgECAhMzAAAB/tCowns0IQsBAAEAAAH+MA0GCSqGSIb3
# DQEBCwUAMHwxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYD
# VQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xJjAk
# BgNVBAMTHU1pY3Jvc29mdCBUaW1lLVN0YW1wIFBDQSAyMDEwMB4XDTI0MDcyNTE4
# MzExOFoXDTI1MTAyMjE4MzExOFowgdMxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpX
# YXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQg
# Q29ycG9yYXRpb24xLTArBgNVBAsTJE1pY3Jvc29mdCBJcmVsYW5kIE9wZXJhdGlv
# bnMgTGltaXRlZDEnMCUGA1UECxMeblNoaWVsZCBUU1MgRVNOOjQwMUEtMDVFMC1E
# OTQ3MSUwIwYDVQQDExxNaWNyb3NvZnQgVGltZS1TdGFtcCBTZXJ2aWNlMIICIjAN
# BgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAvLwhFxWlqA43olsE4PCegZ4mSfsH
# 2YTSKEYv8Gn3362Bmaycdf5T3tQxpP3NWm62YHUieIQXw+0u4qlay4AN3IonI+47
# Npi9fo52xdAXMX0pGrc0eqW8RWN3bfzXPKv07O18i2HjDyLuywYyKA9FmWbePjah
# f9Mwd8QgygkPtwDrVQGLyOkyM3VTiHKqhGu9BCGVRdHW9lmPMrrUlPWiYV9LVCB5
# VYd+AEUtdfqAdqlzVxA53EgxSqhp6JbfEKnTdcfP6T8Mir0HrwTTtV2h2yDBtjXb
# QIaqycKOb633GfRkn216LODBg37P/xwhodXT81ZC2aHN7exEDmmbiWssjGvFJkli
# 2g6dt01eShOiGmhbonr0qXXcBeqNb6QoF8jX/uDVtY9pvL4j8aEWS49hKUH0mzsC
# ucIrwUS+x8MuT0uf7VXCFNFbiCUNRTofxJ3B454eGJhL0fwUTRbgyCbpLgKMKDiC
# Rub65DhaeDvUAAJT93KSCoeFCoklPavbgQyahGZDL/vWAVjX5b8Jzhly9gGCdK/q
# i6i+cxZ0S8x6B2yjPbZfdBVfH/NBp/1Ln7xbeOETAOn7OT9D3UGt0q+KiWgY42Hn
# Ljyhl1bAu5HfgryAO3DCaIdV2tjvkJay2qOnF7Dgj8a60KQT9QgfJfwXnr3ZKibY
# MjaUbCNIDnxz2ykCAwEAAaOCAUkwggFFMB0GA1UdDgQWBBRvznuJ9SU2g5l/5/b+
# 5CBibbHF3TAfBgNVHSMEGDAWgBSfpxVdAF5iXYP05dJlpxtTNRnpcjBfBgNVHR8E
# WDBWMFSgUqBQhk5odHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2NybC9N
# aWNyb3NvZnQlMjBUaW1lLVN0YW1wJTIwUENBJTIwMjAxMCgxKS5jcmwwbAYIKwYB
# BQUHAQEEYDBeMFwGCCsGAQUFBzAChlBodHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20v
# cGtpb3BzL2NlcnRzL01pY3Jvc29mdCUyMFRpbWUtU3RhbXAlMjBQQ0ElMjAyMDEw
# KDEpLmNydDAMBgNVHRMBAf8EAjAAMBYGA1UdJQEB/wQMMAoGCCsGAQUFBwMIMA4G
# A1UdDwEB/wQEAwIHgDANBgkqhkiG9w0BAQsFAAOCAgEAiT4NUvO2lw+0dDMtsBux
# mX2o3lVQqnQkuITAGIGCgI+sl7ZqZOTDd8LqxsH4GWCPTztc3tr8AgBvsYIzWjFw
# ioCjCQODq1oBMWNzEsKzckHxAzYo5Sze7OPkMA3DAxVq4SSR8y+TRC2GcOd0JReZ
# 1lPlhlPl9XI+z8OgtOPmQnLLiP9qzpTHwFze+sbqSn8cekduMZdLyHJk3Niw3Ang
# lU/WTzGsQAdch9SVV4LHifUnmwTf0i07iKtTlNkq3bx1iyWg7N7jGZABRWT2mX+Y
# AVHlK27t9n+WtYbn6cOJNX6LsH8xPVBRYAIRVkWsMyEAdoP9dqfaZzwXGmjuVQ93
# 1NhzHjjG+Efw118DXjk3Vq3qUI1re34zMMTRzZZEw82FupF3viXNR3DVOlS9JH4x
# 5emfINa1uuSac6F4CeJCD1GakfS7D5ayNsaZ2e+sBUh62KVTlhEsQRHZRwCTxbix
# 1Y4iJw+PDNLc0Hf19qX2XiX0u2SM9CWTTjsz9SvCjIKSxCZFCNv/zpKIlsHx7hQN
# QHSMbKh0/wwn86uiIALEjazUszE0+X6rcObDfU4h/O/0vmbF3BMR+45rAZMAETJs
# RDPxHJCo/5XGhWdg/LoJ5XWBrODL44YNrN7FRnHEAAr06sflqZ8eeV3FuDKdP5h1
# 9WUnGWwO1H/ZjUzOoVGiV3gwggdxMIIFWaADAgECAhMzAAAAFcXna54Cm0mZAAAA
# AAAVMA0GCSqGSIb3DQEBCwUAMIGIMQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2Fz
# aGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENv
# cnBvcmF0aW9uMTIwMAYDVQQDEylNaWNyb3NvZnQgUm9vdCBDZXJ0aWZpY2F0ZSBB
# dXRob3JpdHkgMjAxMDAeFw0yMTA5MzAxODIyMjVaFw0zMDA5MzAxODMyMjVaMHwx
# CzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRt
# b25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xJjAkBgNVBAMTHU1p
# Y3Jvc29mdCBUaW1lLVN0YW1wIFBDQSAyMDEwMIICIjANBgkqhkiG9w0BAQEFAAOC
# Ag8AMIICCgKCAgEA5OGmTOe0ciELeaLL1yR5vQ7VgtP97pwHB9KpbE51yMo1V/YB
# f2xK4OK9uT4XYDP/XE/HZveVU3Fa4n5KWv64NmeFRiMMtY0Tz3cywBAY6GB9alKD
# RLemjkZrBxTzxXb1hlDcwUTIcVxRMTegCjhuje3XD9gmU3w5YQJ6xKr9cmmvHaus
# 9ja+NSZk2pg7uhp7M62AW36MEBydUv626GIl3GoPz130/o5Tz9bshVZN7928jaTj
# kY+yOSxRnOlwaQ3KNi1wjjHINSi947SHJMPgyY9+tVSP3PoFVZhtaDuaRr3tpK56
# KTesy+uDRedGbsoy1cCGMFxPLOJiss254o2I5JasAUq7vnGpF1tnYN74kpEeHT39
# IM9zfUGaRnXNxF803RKJ1v2lIH1+/NmeRd+2ci/bfV+AutuqfjbsNkz2K26oElHo
# vwUDo9Fzpk03dJQcNIIP8BDyt0cY7afomXw/TNuvXsLz1dhzPUNOwTM5TI4CvEJo
# LhDqhFFG4tG9ahhaYQFzymeiXtcodgLiMxhy16cg8ML6EgrXY28MyTZki1ugpoMh
# XV8wdJGUlNi5UPkLiWHzNgY1GIRH29wb0f2y1BzFa/ZcUlFdEtsluq9QBXpsxREd
# cu+N+VLEhReTwDwV2xo3xwgVGD94q0W29R6HXtqPnhZyacaue7e3PmriLq0CAwEA
# AaOCAd0wggHZMBIGCSsGAQQBgjcVAQQFAgMBAAEwIwYJKwYBBAGCNxUCBBYEFCqn
# Uv5kxJq+gpE8RjUpzxD/LwTuMB0GA1UdDgQWBBSfpxVdAF5iXYP05dJlpxtTNRnp
# cjBcBgNVHSAEVTBTMFEGDCsGAQQBgjdMg30BATBBMD8GCCsGAQUFBwIBFjNodHRw
# Oi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpb3BzL0RvY3MvUmVwb3NpdG9yeS5odG0w
# EwYDVR0lBAwwCgYIKwYBBQUHAwgwGQYJKwYBBAGCNxQCBAweCgBTAHUAYgBDAEEw
# CwYDVR0PBAQDAgGGMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAU1fZWy4/o
# olxiaNE9lJBb186aGMQwVgYDVR0fBE8wTTBLoEmgR4ZFaHR0cDovL2NybC5taWNy
# b3NvZnQuY29tL3BraS9jcmwvcHJvZHVjdHMvTWljUm9vQ2VyQXV0XzIwMTAtMDYt
# MjMuY3JsMFoGCCsGAQUFBwEBBE4wTDBKBggrBgEFBQcwAoY+aHR0cDovL3d3dy5t
# aWNyb3NvZnQuY29tL3BraS9jZXJ0cy9NaWNSb29DZXJBdXRfMjAxMC0wNi0yMy5j
# cnQwDQYJKoZIhvcNAQELBQADggIBAJ1VffwqreEsH2cBMSRb4Z5yS/ypb+pcFLY+
# TkdkeLEGk5c9MTO1OdfCcTY/2mRsfNB1OW27DzHkwo/7bNGhlBgi7ulmZzpTTd2Y
# urYeeNg2LpypglYAA7AFvonoaeC6Ce5732pvvinLbtg/SHUB2RjebYIM9W0jVOR4
# U3UkV7ndn/OOPcbzaN9l9qRWqveVtihVJ9AkvUCgvxm2EhIRXT0n4ECWOKz3+SmJ
# w7wXsFSFQrP8DJ6LGYnn8AtqgcKBGUIZUnWKNsIdw2FzLixre24/LAl4FOmRsqlb
# 30mjdAy87JGA0j3mSj5mO0+7hvoyGtmW9I/2kQH2zsZ0/fZMcm8Qq3UwxTSwethQ
# /gpY3UA8x1RtnWN0SCyxTkctwRQEcb9k+SS+c23Kjgm9swFXSVRk2XPXfx5bRAGO
# WhmRaw2fpCjcZxkoJLo4S5pu+yFUa2pFEUep8beuyOiJXk+d0tBMdrVXVAmxaQFE
# fnyhYWxz/gq77EFmPWn9y8FBSX5+k77L+DvktxW/tM4+pTFRhLy/AsGConsXHRWJ
# jXD+57XQKBqJC4822rpM+Zv/Cuk0+CQ1ZyvgDbjmjJnW4SLq8CdCPSWU5nR0W2rR
# nj7tfqAxM328y+l7vzhwRNGQ8cirOoo6CGJ/2XBjU02N7oJtpQUQwXEGahC0HVUz
# WLOhcGbyoYIDVjCCAj4CAQEwggEBoYHZpIHWMIHTMQswCQYDVQQGEwJVUzETMBEG
# A1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWlj
# cm9zb2Z0IENvcnBvcmF0aW9uMS0wKwYDVQQLEyRNaWNyb3NvZnQgSXJlbGFuZCBP
# cGVyYXRpb25zIExpbWl0ZWQxJzAlBgNVBAsTHm5TaGllbGQgVFNTIEVTTjo0MDFB
# LTA1RTAtRDk0NzElMCMGA1UEAxMcTWljcm9zb2Z0IFRpbWUtU3RhbXAgU2Vydmlj
# ZaIjCgEBMAcGBSsOAwIaAxUAhGNHD/a7Q0bQLWVG9JuGxgLRXseggYMwgYCkfjB8
# MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVk
# bW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSYwJAYDVQQDEx1N
# aWNyb3NvZnQgVGltZS1TdGFtcCBQQ0EgMjAxMDANBgkqhkiG9w0BAQsFAAIFAOqq
# LggwIhgPMjAyNDEwMDQwOTA0MDhaGA8yMDI0MTAwNTA5MDQwOFowdDA6BgorBgEE
# AYRZCgQBMSwwKjAKAgUA6qouCAIBADAHAgEAAgIpRjAHAgEAAgIUAjAKAgUA6qt/
# iAIBADA2BgorBgEEAYRZCgQCMSgwJjAMBgorBgEEAYRZCgMCoAowCAIBAAIDB6Eg
# oQowCAIBAAIDAYagMA0GCSqGSIb3DQEBCwUAA4IBAQBJaxfhjNQjj23RVZz83J8N
# naBLl528U/RFskOTlomGIKqhtYXUprHN36hAxM2iUwhPi+hGSLLpancLa7YnSuZT
# kPwcfSe/tZAmOL2jDVhyq6zARISDJsZHApqJlb19YrQ1MxtADHGjodgbyrwSO6R7
# jFRS0S1ptT1c8rrPgygjuBS+u/8XeCU1jQ0WTdGTNOrRmWaoIjBk2sQtHWTQlvpX
# F+tDAnUyc3P1aHxkWkMklQTePJnmjf268TA4ukbr3qsYWQ6tY7ACHo0i/PYe2ihz
# tE1tIVkbu8NT1ywT6+3J6jiyFivKdugHXkmivyp/ECCRzlpNyUiDo6xfWUwbiYrQ
# MYIEDTCCBAkCAQEwgZMwfDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0
# b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3Jh
# dGlvbjEmMCQGA1UEAxMdTWljcm9zb2Z0IFRpbWUtU3RhbXAgUENBIDIwMTACEzMA
# AAH+0KjCezQhCwEAAQAAAf4wDQYJYIZIAWUDBAIBBQCgggFKMBoGCSqGSIb3DQEJ
# AzENBgsqhkiG9w0BCRABBDAvBgkqhkiG9w0BCQQxIgQg3G/ygg1g/M0B3kaXhKn0
# wCYWNedQTMR3fitNLNW6TrAwgfoGCyqGSIb3DQEJEAIvMYHqMIHnMIHkMIG9BCAR
# hczd/FPInxjR92m2hPWqc+vGOG1+/I0WtkCstyh0eTCBmDCBgKR+MHwxCzAJBgNV
# BAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4w
# HAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xJjAkBgNVBAMTHU1pY3Jvc29m
# dCBUaW1lLVN0YW1wIFBDQSAyMDEwAhMzAAAB/tCowns0IQsBAAEAAAH+MCIEIIhj
# 7DTawG12oBUaT0i8xY4ZdU8HYgijek+CubbfnVruMA0GCSqGSIb3DQEBCwUABIIC
# AIuH3iiwB/rhKTdotsyUCusdzO/ZIS1maXCfLv6VErieB5nH50o6DMVdyycvkdN2
# hFc3nB+TtedxFI6EEbr9aKYRWLmlb6Sfb8c1AV/9GjE+KydGYiJvLwpIzZF0X+P2
# 4/rtmL2CIF8wpwwJ29GHUFvNcW4G6en3U/14F72A6a8DaKHJ/oCuXoh1oBJx0FuG
# LWsS42hjrm9lb6NPblmrGLZ7vdVE0xTZqUIPbU5VrxXJqZhyYTta7N6oeDKuLA+v
# U5R7fNTphSbcNmj/yZElZdaBhHGKoGqWhykX89UbhhkhhixgiYm7/AmSEFdlYmJ+
# pQ50/OtySx6N9mmLhd6lwjLR3/KjCwZ4IthA00k7WlD3LGxPdqwbZ5Lxmal6ACJN
# G9E9CPezBJl9XzzpE8PcPZ7tfaf7nlu1vhGzbc8IG6arleO3OWjRIw43Gepsmn9q
# 6Oyn30DOZU1hwUq6qNOSlYL57F26Yny3v77x2WcQ+9YB5q/Dqq1Vb5/cAn5aE08Z
# 6YJbIy4UBXznpi+8Io+s1py+WslEHjlc+mtwt38HPk5oDGZnIjTNjuEOBBi4x8VL
# vI2moBGwuMJdl13+FI4QtNIQzDppduTNS3TVJLctCLoJE1BoCNd/pzyj4Cc1vqYE
# WP/51vNTL8QrXLEbtWyPm7mqFXDvh33x+OWJR6/Fs+e+
# SIG # End signature block
