<#
.SYNOPSIS
    Backup the AOS service files.

.DESCRIPTION

    Copyright © 2019 Microsoft. All rights reserved.
#>
[CmdletBinding()]
param
(
    [Parameter(Mandatory = $false, HelpMessage = "The path to the directory in which to write log files.")]
    [string]$LogDir
)

function PrepareDeltaDBsyncReportDeployment([string]$metadataPackagePath)
{
    $MetadataParentPath = Split-Path -Path $metadataPackagePath -Parent
    $deltaSyncFolder = Join-Path -Path $MetadataParentPath -ChildPath "DeltaSync"

    if (!(Test-Path -Path $deltaSyncFolder))
    {
        Write-ServicingLog "Creating delta sync folder." -Vrb
        New-Item -Path $deltaSyncFolder -ItemType Directory -Force | Out-Null
    }
    else
    {
        Write-ServicingLog "Deleting delta sync folder contents." -Vrb
        Get-ChildItem -Path $deltaSyncFolder | Remove-Item -Force -Recurse
    }

    Write-ServicingLog "Copying MD files from metadata package folder to delta sync folder." -Vrb
    $roboCopyLogFile = $null
    if ((-not [string]::IsNullOrWhiteSpace($LogDir)) -and (Test-Path -Path $LogDir))
    {
        $roboCopyLogFile = Join-Path $LogDir "DeltaSyncCopy.log"
        Write-ServicingLog "Copying MD files log: $roboCopyLogFile." -Vrb
    }

    Robocopy.exe $metadataPackagePath $deltaSyncFolder /s /W:5 /R:3 /nfl /ndl *AXSecurity*.md *AXTable*.md *AXView*.md *AXEdt*.md *.rdl *> $roboCopyLogFile
    $roboCopyExitCode = $LASTEXITCODE

    if (($roboCopyExitCode -ge 8) -or ($roboCopyExitCode -lt 0))
    {
        throw "Failed to copy MD files with RoboCopy exit code $roboCopyExitCode."
    }
    Write-ServicingLog "Copying MD files completed with RoboCopy exit code $roboCopyExitCode." -Vrb
}

# ALM Service keeps a "clean" copy of packages folder (i.e. only standard AX vanilla code) to start from on every build
# We want AOS service to backup the "Clean" state packages so rollback doesn't put custom code back
# after removing the ALM service's backup in the AOS update step.
# We can't do this in ALM Service script due to these inter-dependencies between ALM and AOS.
# This is a compromise solution awaiting ALM to do "clean" differently.
function Restore-ALMPackagesBackup
{
    $ALMPackagesCopyPath = Get-ALMPackageCopyPath
    if ($ALMPackagesCopyPath)
    {
        # Copy latest DevALMInstrumentor.ps1 before using it. This ensures we use the fix which prevents locking 
        # Microsoft.Dynamics.ApplicationPlatform.Instrumentation.dll. 
        $NewInstrumentationScript = "$PSScriptRoot\..\..\ALMService\Code\DevALMInstrumentor.ps1"
        if (Test-Path -Path $NewInstrumentationScript  -PathType leaf)
        {
            Write-ServicingLog "Copying latest DevALMInstrumentor.ps1 from $($NewInstrumentationScript) to $($env:DynamicsSDK) before using it." -Vrb
            Copy-Item $NewInstrumentationScript -Destination $env:DynamicsSDK -Force
        }

        $ALMBackupFlag = Join-Path -Path $ALMPackagesCopyPath -ChildPath "Packages\BackupComplete.txt"

        # Check if a completed backup exists.
        if (Test-Path -Path $ALMBackupFlag)
        {
            Write-ServicingLog "Restoring packages from ALM Service backup at $($ALMPackagesCopyPath)..."
            Write-ServicingLog "Calling $($ALMPackagesCopyRestore) script to restore packages..." -Vrb
            $ALMPackagesCopyRestore = Join-Path -Path $env:DynamicsSDK -ChildPath "PrepareForBuild.ps1"
            & $ALMPackagesCopyRestore
            Write-ServicingLog "Call to $($ALMPackagesCopyRestore) completed." -Vrb

            # PrepareForBuild script shuts down IIS service entirely, even though individual sites are already stopped.
            # This can break subsequent IIS web administration calls during servicing.
            # Calling Get-AosWebSitePhysicalPath will restart the service if needed
            # and leave the websites in the state they were in prior to IIS service stop
            $ALMTestWebRoot = Get-AosWebSitePhysicalPath
            Write-ServicingLog "Call to Get-AosWebSitePhysicalPath returned: $($ALMTestWebRoot)" -Vrb
        }
        else
        {
            Write-ServicingLog "Warning: No complete ALM Service backup found at $($ALMPackagesCopyPath). Skipping restore."
        }
    }
}

$ErrorActionPreference = "Stop"
Import-Module "$PSScriptRoot\CommonRollbackUtilities.psm1" -DisableNameChecking
Import-Module "$PSScriptRoot\AosEnvironmentUtilities.psm1" -Force -DisableNameChecking

# Initialize exit code.
[int]$ExitCode = 0

# Initialize the log file to use with Write-ServicingLog.
Set-ServicingLog -LogDir $LogDir -LogFileName "AosService-Backup_$([DateTime]::UtcNow.ToString("yyyyMMddHHmmss")).log"

try
{
    Write-ServicingLog "Starting AOS backup..."

    # $RunbookBackupFolder and $PSScriptRoot variables are populated directly from runbook.
    $BackupFolder = $RunbookBackupFolder

    if ([string]::IsNullOrEmpty($BackupFolder))
    {
        $BackupFolder = Join-Path -Path $PSScriptRoot -ChildPath "ManualAosServiceBackup"
    }

    # Determine if this is a developer/demo machine.
    $DeveloperBox = Get-DevToolsInstalled

    Write-ServicingLog "Backup folder: $($BackupFolder)"

    $webrootBackupFolder = Join-Path -Path $BackupFolder -ChildPath "webroot"
    $packageBackupFolder = Join-Path -Path $BackupFolder -ChildPath "packages"
    $webrootBackupFilePath = Join-Path -Path $webrootBackupFolder -ChildPath "webroot.zip"
    $packageBackupFilePath = Join-Path -Path $packageBackupFolder -ChildPath "packages.zip"
    $webrootBackupSymlinkFolder = Join-Path -Path $webrootBackupFolder -ChildPath "symlink"
    $packageBackupSymlinkFolder = Join-Path -Path $packageBackupFolder -ChildPath "symlink"

    $webroot = Get-AosWebSitePhysicalPath
    $packagePath = Get-AosPackageDirectory

    if (!(Test-Path -Path $webrootBackupFolder))
    {
        Write-ServicingLog "Creating new backup folder: $($webrootBackupFolder)" -Vrb
        New-Item -ItemType Directory -Path $webrootBackupFolder | Out-Null
    }

    if (!(Test-Path -Path $packageBackupFolder))
    {
        Write-ServicingLog "Creating new backup folder: $($packageBackupFolder)" -Vrb
        New-Item -ItemType Directory -Path $packageBackupFolder | Out-Null
    }

    if (!(Test-Path -Path $webrootBackupSymlinkFolder))
    {
        Write-ServicingLog "Creating new backup folder: $($webrootBackupSymlinkFolder)" -Vrb
        New-Item -ItemType Directory -Path $webrootBackupSymlinkFolder | Out-Null
    }

    if (!(Test-Path -Path $packageBackupSymlinkFolder))
    {
        Write-ServicingLog "Creating new backup folder: $($packageBackupSymlinkFolder)" -Vrb
        New-Item -ItemType Directory -Path $packageBackupSymlinkFolder | Out-Null
    }

    # Backup is not needed for dev/build/demo/vhd env as we don't support roll back in those environments.
    # This will save a lot fo disk space and time for those env when applying packages.
    if (!$DeveloperBox)
    {
        try
        {
            Write-ServicingLog "Creating backup of AOS webroot symlinks..."
            Copy-SymbolicLinks -SourcePath $webroot -DestinationPath $webrootBackupSymlinkFolder -Move

            $exclude = ""
            Write-ServicingLog "Creating backup of AOS webroot files..."
            Create-ZipFiles -sourceFolder:$webroot -destFile:$webrootBackupFilePath -filetypesExcluded:$exclude -zipLogDir:$LogDir

            # Restore AOS packages from complete ALM service backup if one is found.
            # Do this before creating backup of AOS package files.
            Restore-ALMPackagesBackup

            $exclude = "*.bak"
            Write-ServicingLog "Creating backup of AOS packages symlinks..."
            Copy-SymbolicLinks -SourcePath $packagePath -DestinationPath $packageBackupSymlinkFolder -Move

            Write-ServicingLog "Creating backup of AOS packages..."
            Create-ZipFiles -sourceFolder:$packagePath -destFile:$packageBackupFilePath -filetypesExcluded:$exclude -zipLogDir:$LogDir
        }
        catch
        {
            throw $_
        }
        finally
        {
            # Restore the symlinks after the backup regardless of error.
            Write-ServicingLog "Restoring AOS packages symlinks..." -Vrb
            Copy-SymbolicLinks -SourcePath $packageBackupSymlinkFolder -DestinationPath $packagePath

            Write-ServicingLog "Restoring AOS webroot symlinks..." -Vrb
            Copy-SymbolicLinks -SourcePath $webrootBackupSymlinkFolder -DestinationPath $webroot
        }
    }
    else
    {
        Write-ServicingLog "Skipping backup of AOS files as developer tools are installed."

        # Restore AOS packages from complete ALM service backup if one is found.
        Restore-ALMPackagesBackup
    }

    Write-ServicingLog "Preparing delta DbSync report deployment..."
    PrepareDeltaDBsyncReportDeployment -metadataPackagePath:$packagePath
}
catch
{
    # Ensure non-zero exit code if an exception is caught and no exit code set.
    if ($ExitCode -eq 0)
    {
        $ExitCode = 1024
    }

    $ErrorMessage = "Error during AOS backup: $($_)"

    Write-ServicingLog $ErrorMessage
    Write-ServicingLog $($_) -Vrb
    Write-ServicingLog "AOS backup script failed with exit code: $($ExitCode)."

    # Use throw to indicate error to AXUpdateInstaller.
    # In case of exceptions, the output is not captured, so only the error message and
    # log file contents will be available for diagnostics.
    throw "$($ErrorMessage) [Log: $(Get-ServicingLog)]"
}

Write-ServicingLog "AOS backup script completed with exit code: $($ExitCode)."
exit $ExitCode
# SIG # Begin signature block
# MIIr5AYJKoZIhvcNAQcCoIIr1TCCK9ECAQExDzANBglghkgBZQMEAgEFADB5Bgor
# BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG
# KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCAgK9bU5hKrnd3Z
# NU61V7Zupac4qdvaiHdSkbPSvEt4dqCCEW4wggh+MIIHZqADAgECAhM2AAACAO38
# jbec3qFIAAIAAAIAMA0GCSqGSIb3DQEBCwUAMEExEzARBgoJkiaJk/IsZAEZFgNH
# QkwxEzARBgoJkiaJk/IsZAEZFgNBTUUxFTATBgNVBAMTDEFNRSBDUyBDQSAwMTAe
# Fw0yNDExMDgxMjQzMjhaFw0yNTExMDgxMjQzMjhaMCQxIjAgBgNVBAMTGU1pY3Jv
# c29mdCBBenVyZSBDb2RlIFNpZ24wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK
# AoIBAQC5L/UPrOpwYjxcoZC0TqqvMF1WUELvwXN+k27SrA5rohJknn7Cgbxg4hGT
# XKqpcdbtsVTN3ZY896SJ20uQ+INL5OVLzpW408nCNTPYg2LtGJbqHUjpNm0hLCJ+
# gO5Jn2T8DDzIJoUijGXj1m+hRLKb2nOIicCED2GuYBmuWXnaY7INmVEaU3peryty
# ZjDuxdyGDuiPURz8lW1SUiDzoszNp1oswVr+WjDvLDUx4HlxPsG8zUjIst0NnJ6o
# z4tNFKaUBDCetcMjQxpCETn29a1CuRddxZLjPHZHfcotr5sh1S6bNQdzVaMNsxV8
# L3wjHb7XJ6ZVm662mHEiPgpyNcLhAgMBAAGjggWKMIIFhjApBgkrBgEEAYI3FQoE
# HDAaMAwGCisGAQQBgjdbAQEwCgYIKwYBBQUHAwMwPQYJKwYBBAGCNxUHBDAwLgYm
# KwYBBAGCNxUIhpDjDYTVtHiE8Ys+hZvdFs6dEoFgg93NZoaUjDICAWQCAQ4wggJ2
# BggrBgEFBQcBAQSCAmgwggJkMGIGCCsGAQUFBzAChlZodHRwOi8vY3JsLm1pY3Jv
# c29mdC5jb20vcGtpaW5mcmEvQ2VydHMvQlkyUEtJQ1NDQTAxLkFNRS5HQkxfQU1F
# JTIwQ1MlMjBDQSUyMDAxKDIpLmNydDBSBggrBgEFBQcwAoZGaHR0cDovL2NybDEu
# YW1lLmdibC9haWEvQlkyUEtJQ1NDQTAxLkFNRS5HQkxfQU1FJTIwQ1MlMjBDQSUy
# MDAxKDIpLmNydDBSBggrBgEFBQcwAoZGaHR0cDovL2NybDIuYW1lLmdibC9haWEv
# QlkyUEtJQ1NDQTAxLkFNRS5HQkxfQU1FJTIwQ1MlMjBDQSUyMDAxKDIpLmNydDBS
# BggrBgEFBQcwAoZGaHR0cDovL2NybDMuYW1lLmdibC9haWEvQlkyUEtJQ1NDQTAx
# LkFNRS5HQkxfQU1FJTIwQ1MlMjBDQSUyMDAxKDIpLmNydDBSBggrBgEFBQcwAoZG
# aHR0cDovL2NybDQuYW1lLmdibC9haWEvQlkyUEtJQ1NDQTAxLkFNRS5HQkxfQU1F
# JTIwQ1MlMjBDQSUyMDAxKDIpLmNydDCBrQYIKwYBBQUHMAKGgaBsZGFwOi8vL0NO
# PUFNRSUyMENTJTIwQ0ElMjAwMSxDTj1BSUEsQ049UHVibGljJTIwS2V5JTIwU2Vy
# dmljZXMsQ049U2VydmljZXMsQ049Q29uZmlndXJhdGlvbixEQz1BTUUsREM9R0JM
# P2NBQ2VydGlmaWNhdGU/YmFzZT9vYmplY3RDbGFzcz1jZXJ0aWZpY2F0aW9uQXV0
# aG9yaXR5MB0GA1UdDgQWBBST/HE52ZUlmsYqZcZBdrXZ5u4ZnzAOBgNVHQ8BAf8E
# BAMCB4AwRQYDVR0RBD4wPKQ6MDgxHjAcBgNVBAsTFU1pY3Jvc29mdCBDb3Jwb3Jh
# dGlvbjEWMBQGA1UEBRMNMjM2MTY3KzUwMzE1NTCCAeYGA1UdHwSCAd0wggHZMIIB
# 1aCCAdGgggHNhj9odHRwOi8vY3JsLm1pY3Jvc29mdC5jb20vcGtpaW5mcmEvQ1JM
# L0FNRSUyMENTJTIwQ0ElMjAwMSgyKS5jcmyGMWh0dHA6Ly9jcmwxLmFtZS5nYmwv
# Y3JsL0FNRSUyMENTJTIwQ0ElMjAwMSgyKS5jcmyGMWh0dHA6Ly9jcmwyLmFtZS5n
# YmwvY3JsL0FNRSUyMENTJTIwQ0ElMjAwMSgyKS5jcmyGMWh0dHA6Ly9jcmwzLmFt
# ZS5nYmwvY3JsL0FNRSUyMENTJTIwQ0ElMjAwMSgyKS5jcmyGMWh0dHA6Ly9jcmw0
# LmFtZS5nYmwvY3JsL0FNRSUyMENTJTIwQ0ElMjAwMSgyKS5jcmyGgb1sZGFwOi8v
# L0NOPUFNRSUyMENTJTIwQ0ElMjAwMSgyKSxDTj1CWTJQS0lDU0NBMDEsQ049Q0RQ
# LENOPVB1YmxpYyUyMEtleSUyMFNlcnZpY2VzLENOPVNlcnZpY2VzLENOPUNvbmZp
# Z3VyYXRpb24sREM9QU1FLERDPUdCTD9jZXJ0aWZpY2F0ZVJldm9jYXRpb25MaXN0
# P2Jhc2U/b2JqZWN0Q2xhc3M9Y1JMRGlzdHJpYnV0aW9uUG9pbnQwHwYDVR0jBBgw
# FoAUllGE4Gtve/7YBqvD8oXmKa5q+dQwHwYDVR0lBBgwFgYKKwYBBAGCN1sBAQYI
# KwYBBQUHAwMwDQYJKoZIhvcNAQELBQADggEBAEDd8Wf5RkHsB64vgn2slxDtHzSo
# It9xN/Dm3RdFjNZ0diTUPMgSPYQlSk8nIAfudnB9FLavGlvZLlyUpfrPSuikepj3
# i3pqNEFn6fNdNFv/wHMxv7hQTIDCmuoR1v1rX+w3oeleBPMnN3QmH4ff1NsynyV4
# dZdYgN9Cw9sC/S3pWZpJrbOs7YOM3vqyU6DciHhC4D9i2zByHCF2pu9nYfiQf5A2
# iUZenRvyo1E5rC+UP2VZXa4k7g66W20+zAajIKKIqEmRtWahekMkCcOIHFBY4RDA
# ybgPRSGur4VDAiZPjTXS90wQXrX9CwU20cfiCC6e76F4H95KtQjKYpzuNVAwggjo
# 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/SxyxDpZMtimb4CgJQlMYIZzDCCGcgCAQEwWDBBMRMwEQYKCZIm
# iZPyLGQBGRYDR0JMMRMwEQYKCZImiZPyLGQBGRYDQU1FMRUwEwYDVQQDEwxBTUUg
# Q1MgQ0EgMDECEzYAAAIA7fyNt5zeoUgAAgAAAgAwDQYJYIZIAWUDBAIBBQCgga4w
# GQYJKoZIhvcNAQkDMQwGCisGAQQBgjcCAQQwHAYKKwYBBAGCNwIBCzEOMAwGCisG
# AQQBgjcCARUwLwYJKoZIhvcNAQkEMSIEIK5nTrDtCE1+OV1xvdDBfQQsbUPr7rSm
# Td7ozM5bsePpMEIGCisGAQQBgjcCAQwxNDAyoBSAEgBNAGkAYwByAG8AcwBvAGYA
# dKEagBhodHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20wDQYJKoZIhvcNAQEBBQAEggEA
# FWshl33HOLx1NkCrzX5mkk6wutrlJQXSVqwEHWQ1QeKsWofOCs7Ud9oBnh4BmDxl
# /P022Z1U4qQQSxPx0heKQfPbC8dQEq07MKKNJZaIilM+9P1FGRk6je4jvuEi76LL
# 7zB4Pm0ldTkAX2s6yTbvxN8w+QkEo5mcnbLTjFo3HLoCdxZQl2RAUkOEpo8eshXB
# tI9UmwiMXQMCdFTDYhDDHOxMOMQYaZHiTaTZQZfUGmZC0QSkUo+rJ8kUz64Z+hWO
# w6xiiVzeqKsYl1cOoaI5n7wQ2tF0eqn/QjpN+CFBMw+uXn5QlgSGGJb3ltMiTr/u
# BasP+Yd5GWUULuMQhfzl1KGCF5QwgheQBgorBgEEAYI3AwMBMYIXgDCCF3wGCSqG
# SIb3DQEHAqCCF20wghdpAgEDMQ8wDQYJYIZIAWUDBAIBBQAwggFSBgsqhkiG9w0B
# CRABBKCCAUEEggE9MIIBOQIBAQYKKwYBBAGEWQoDATAxMA0GCWCGSAFlAwQCAQUA
# BCDq4X4bs6xhglu6yHl49zLrTPrQpznfQCRQEnY6/HIwHAIGaBKxCrW/GBMyMDI1
# MDUwOTExMjEzOC44MjNaMASAAgH0oIHRpIHOMIHLMQswCQYDVQQGEwJVUzETMBEG
# A1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWlj
# cm9zb2Z0IENvcnBvcmF0aW9uMSUwIwYDVQQLExxNaWNyb3NvZnQgQW1lcmljYSBP
# cGVyYXRpb25zMScwJQYDVQQLEx5uU2hpZWxkIFRTUyBFU046REMwMC0wNUUwLUQ5
# NDcxJTAjBgNVBAMTHE1pY3Jvc29mdCBUaW1lLVN0YW1wIFNlcnZpY2WgghHqMIIH
# IDCCBQigAwIBAgITMwAAAgO7HlwAOGx0ygABAAACAzANBgkqhkiG9w0BAQsFADB8
# MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVk
# bW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSYwJAYDVQQDEx1N
# aWNyb3NvZnQgVGltZS1TdGFtcCBQQ0EgMjAxMDAeFw0yNTAxMzAxOTQyNDZaFw0y
# NjA0MjIxOTQyNDZaMIHLMQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3Rv
# bjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0
# aW9uMSUwIwYDVQQLExxNaWNyb3NvZnQgQW1lcmljYSBPcGVyYXRpb25zMScwJQYD
# VQQLEx5uU2hpZWxkIFRTUyBFU046REMwMC0wNUUwLUQ5NDcxJTAjBgNVBAMTHE1p
# Y3Jvc29mdCBUaW1lLVN0YW1wIFNlcnZpY2UwggIiMA0GCSqGSIb3DQEBAQUAA4IC
# DwAwggIKAoICAQChl0MH5wAnOx8Uh8RtidF0J0yaFDHJYHTpPvRR16X1KxGDYfT8
# PrcGjCLCiaOu3K1DmUIU4Rc5olndjappNuOgzwUoj43VbbJx5PFTY/a1Z80tpqVP
# 0OoKJlUkfDPSBLFgXWj6VgayRCINtLsUasy0w5gysD7ILPZuiQjace5KxASjKf2M
# VX1qfEzYBbTGNEijSQCKwwyc0eavr4Fo3X/+sCuuAtkTWissU64k8rK60jsGRApi
# ESdfuHr0yWAmc7jTOPNeGAx6KCL2ktpnGegLDd1IlE6Bu6BSwAIFHr7zOwIlFqyQ
# uCe0SQALCbJhsT9y9iy61RJAXsU0u0TC5YYmTSbEI7g10dYx8Uj+vh9InLoKYC5D
# pKb311bYVd0bytbzlfTRslRTJgotnfCAIGMLqEqk9/2VRGu9klJi1j9nVfqyYHYr
# MPOBXcrQYW0jmKNjOL47CaEArNzhDBia1wXdJANKqMvJ8pQe2m8/cibyDM+1BVZq
# uNAov9N4tJF4ACtjX0jjXNDUMtSZoVFQH+FkWdfPWx1uBIkc97R+xRLuPjUypHZ5
# A3AALSke4TaRBvbvTBYyW2HenOT7nYLKTO4jw5Qq6cw3Z9zTKSPQ6D5lyiYpes5R
# R2MdMvJS4fCcPJFeaVOvuWFSQ/EGtVBShhmLB+5ewzFzdpf1UuJmuOQTTwIDAQAB
# o4IBSTCCAUUwHQYDVR0OBBYEFLIpWUB+EeeQ29sWe0VdzxWQGJJ9MB8GA1UdIwQY
# MBaAFJ+nFV0AXmJdg/Tl0mWnG1M1GelyMF8GA1UdHwRYMFYwVKBSoFCGTmh0dHA6
# Ly93d3cubWljcm9zb2Z0LmNvbS9wa2lvcHMvY3JsL01pY3Jvc29mdCUyMFRpbWUt
# U3RhbXAlMjBQQ0ElMjAyMDEwKDEpLmNybDBsBggrBgEFBQcBAQRgMF4wXAYIKwYB
# BQUHMAKGUGh0dHA6Ly93d3cubWljcm9zb2Z0LmNvbS9wa2lvcHMvY2VydHMvTWlj
# cm9zb2Z0JTIwVGltZS1TdGFtcCUyMFBDQSUyMDIwMTAoMSkuY3J0MAwGA1UdEwEB
# /wQCMAAwFgYDVR0lAQH/BAwwCgYIKwYBBQUHAwgwDgYDVR0PAQH/BAQDAgeAMA0G
# CSqGSIb3DQEBCwUAA4ICAQCQEMbesD6TC08R0oYCdSC452AQrGf/O89GQ54CtgEs
# bxzwGDVUcmjXFcnaJSTNedBKVXkBgawRonP1LgxH4bzzVj2eWNmzGIwO1FlhldAP
# OHAzLBEHRoSZ4pddFtaQxoabU/N1vWyICiN60It85gnF5JD4MMXyd6pS8eADIi6T
# tjfgKPoumWa0BFQ/aEzjUrfPN1r7crK+qkmLztw/ENS7zemfyx4kGRgwY1WBfFqm
# /nFlJDPQBicqeU3dOp9hj7WqD0Rc+/4VZ6wQjesIyCkv5uhUNy2LhNDi2leYtAiI
# FpmjfNk4GngLvC2Tj9IrOMv20Srym5J/Fh7yWAiPeGs3yA3QapjZTtfr7NfzpBIJ
# Q4xT/ic4WGWqhGlRlVBI5u6Ojw3ZxSZCLg3vRC4KYypkh8FdIWoKirjidEGlXsNO
# o+UP/YG5KhebiudTBxGecfJCuuUspIdRhStHAQsjv/dAqWBLlhorq2OCaP+wFhE3
# WPgnnx5pflvlujocPgsN24++ddHrl3O1FFabW8m0UkDHSKCh8QTwTkYOwu99iExB
# VWlbYZRz2qOIBjL/ozEhtCB0auKhfTLLeuNGBUaBz+oZZ+X9UAECoMhkETjb6YfN
# aI1T7vVAaiuhBoV/JCOQT+RYZrgykyPpzpmwMNFBD1vdW/29q9nkTWoEhcEOO0L9
# NzCCB3EwggVZoAMCAQICEzMAAAAVxedrngKbSZkAAAAAABUwDQYJKoZIhvcNAQEL
# BQAwgYgxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQH
# EwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xMjAwBgNV
# BAMTKU1pY3Jvc29mdCBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAyMDEwMB4X
# DTIxMDkzMDE4MjIyNVoXDTMwMDkzMDE4MzIyNVowfDELMAkGA1UEBhMCVVMxEzAR
# BgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1p
# Y3Jvc29mdCBDb3Jwb3JhdGlvbjEmMCQGA1UEAxMdTWljcm9zb2Z0IFRpbWUtU3Rh
# bXAgUENBIDIwMTAwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDk4aZM
# 57RyIQt5osvXJHm9DtWC0/3unAcH0qlsTnXIyjVX9gF/bErg4r25PhdgM/9cT8dm
# 95VTcVrifkpa/rg2Z4VGIwy1jRPPdzLAEBjoYH1qUoNEt6aORmsHFPPFdvWGUNzB
# RMhxXFExN6AKOG6N7dcP2CZTfDlhAnrEqv1yaa8dq6z2Nr41JmTamDu6GnszrYBb
# fowQHJ1S/rboYiXcag/PXfT+jlPP1uyFVk3v3byNpOORj7I5LFGc6XBpDco2LXCO
# Mcg1KL3jtIckw+DJj361VI/c+gVVmG1oO5pGve2krnopN6zL64NF50ZuyjLVwIYw
# XE8s4mKyzbnijYjklqwBSru+cakXW2dg3viSkR4dPf0gz3N9QZpGdc3EXzTdEonW
# /aUgfX782Z5F37ZyL9t9X4C626p+Nuw2TPYrbqgSUei/BQOj0XOmTTd0lBw0gg/w
# EPK3Rxjtp+iZfD9M269ewvPV2HM9Q07BMzlMjgK8QmguEOqEUUbi0b1qGFphAXPK
# Z6Je1yh2AuIzGHLXpyDwwvoSCtdjbwzJNmSLW6CmgyFdXzB0kZSU2LlQ+QuJYfM2
# BjUYhEfb3BvR/bLUHMVr9lxSUV0S2yW6r1AFemzFER1y7435UsSFF5PAPBXbGjfH
# CBUYP3irRbb1Hode2o+eFnJpxq57t7c+auIurQIDAQABo4IB3TCCAdkwEgYJKwYB
# BAGCNxUBBAUCAwEAATAjBgkrBgEEAYI3FQIEFgQUKqdS/mTEmr6CkTxGNSnPEP8v
# BO4wHQYDVR0OBBYEFJ+nFV0AXmJdg/Tl0mWnG1M1GelyMFwGA1UdIARVMFMwUQYM
# KwYBBAGCN0yDfQEBMEEwPwYIKwYBBQUHAgEWM2h0dHA6Ly93d3cubWljcm9zb2Z0
# LmNvbS9wa2lvcHMvRG9jcy9SZXBvc2l0b3J5Lmh0bTATBgNVHSUEDDAKBggrBgEF
# BQcDCDAZBgkrBgEEAYI3FAIEDB4KAFMAdQBiAEMAQTALBgNVHQ8EBAMCAYYwDwYD
# VR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAWgBTV9lbLj+iiXGJo0T2UkFvXzpoYxDBW
# BgNVHR8ETzBNMEugSaBHhkVodHRwOi8vY3JsLm1pY3Jvc29mdC5jb20vcGtpL2Ny
# bC9wcm9kdWN0cy9NaWNSb29DZXJBdXRfMjAxMC0wNi0yMy5jcmwwWgYIKwYBBQUH
# AQEETjBMMEoGCCsGAQUFBzAChj5odHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtp
# L2NlcnRzL01pY1Jvb0NlckF1dF8yMDEwLTA2LTIzLmNydDANBgkqhkiG9w0BAQsF
# AAOCAgEAnVV9/Cqt4SwfZwExJFvhnnJL/Klv6lwUtj5OR2R4sQaTlz0xM7U518Jx
# Nj/aZGx80HU5bbsPMeTCj/ts0aGUGCLu6WZnOlNN3Zi6th542DYunKmCVgADsAW+
# iehp4LoJ7nvfam++Kctu2D9IdQHZGN5tggz1bSNU5HhTdSRXud2f8449xvNo32X2
# pFaq95W2KFUn0CS9QKC/GbYSEhFdPSfgQJY4rPf5KYnDvBewVIVCs/wMnosZiefw
# C2qBwoEZQhlSdYo2wh3DYXMuLGt7bj8sCXgU6ZGyqVvfSaN0DLzskYDSPeZKPmY7
# T7uG+jIa2Zb0j/aRAfbOxnT99kxybxCrdTDFNLB62FD+CljdQDzHVG2dY3RILLFO
# Ry3BFARxv2T5JL5zbcqOCb2zAVdJVGTZc9d/HltEAY5aGZFrDZ+kKNxnGSgkujhL
# mm77IVRrakURR6nxt67I6IleT53S0Ex2tVdUCbFpAUR+fKFhbHP+CrvsQWY9af3L
# wUFJfn6Tvsv4O+S3Fb+0zj6lMVGEvL8CwYKiexcdFYmNcP7ntdAoGokLjzbaukz5
# m/8K6TT4JDVnK+ANuOaMmdbhIurwJ0I9JZTmdHRbatGePu1+oDEzfbzL6Xu/OHBE
# 0ZDxyKs6ijoIYn/ZcGNTTY3ugm2lBRDBcQZqELQdVTNYs6FwZvKhggNNMIICNQIB
# ATCB+aGB0aSBzjCByzELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24x
# EDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlv
# bjElMCMGA1UECxMcTWljcm9zb2Z0IEFtZXJpY2EgT3BlcmF0aW9uczEnMCUGA1UE
# CxMeblNoaWVsZCBUU1MgRVNOOkRDMDAtMDVFMC1EOTQ3MSUwIwYDVQQDExxNaWNy
# b3NvZnQgVGltZS1TdGFtcCBTZXJ2aWNloiMKAQEwBwYFKw4DAhoDFQDNrxRX/iz6
# ss1lBCXG8P1LFxD0e6CBgzCBgKR+MHwxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpX
# YXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQg
# Q29ycG9yYXRpb24xJjAkBgNVBAMTHU1pY3Jvc29mdCBUaW1lLVN0YW1wIFBDQSAy
# MDEwMA0GCSqGSIb3DQEBCwUAAgUA68hjlTAiGA8yMDI1MDUwOTExMjA1M1oYDzIw
# MjUwNTEwMTEyMDUzWjB0MDoGCisGAQQBhFkKBAExLDAqMAoCBQDryGOVAgEAMAcC
# AQACAgVIMAcCAQACAhaAMAoCBQDrybUVAgEAMDYGCisGAQQBhFkKBAIxKDAmMAwG
# CisGAQQBhFkKAwKgCjAIAgEAAgMHoSChCjAIAgEAAgMBhqAwDQYJKoZIhvcNAQEL
# BQADggEBAEus8nK1omtd0LrshkThZ95xL8V1hNIgKEtUGAFUbEmm2oPh5wvQZT9a
# 2a9p3+xg2KofJ3GHTohqq6XP8SjH1bvgnkS04jnbEPXE2bhl+oZOmNls+do+X8Kp
# FuNvAAeNOfwXlL2eVp23yhRi/vBFkk02fXMneh/HA5nnlSgjTODyjBQAQWSLh+A0
# vwrLp6Bd9jq+tsLKl/SVOqeCXAIWD+zGUTfD44BcnTfli2YseOhodNsulu+Hc1m2
# 4rqNQDDcR+L2/+xRkD7ypzmwsWbcwDglM2cqIhkdVYDgAhJWrKF1zYGjYKllPHBu
# Wnip8snW3QCKgQ77aa/pkGRGrC+f/gAxggQNMIIECQIBATCBkzB8MQswCQYDVQQG
# EwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwG
# A1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSYwJAYDVQQDEx1NaWNyb3NvZnQg
# VGltZS1TdGFtcCBQQ0EgMjAxMAITMwAAAgO7HlwAOGx0ygABAAACAzANBglghkgB
# ZQMEAgEFAKCCAUowGgYJKoZIhvcNAQkDMQ0GCyqGSIb3DQEJEAEEMC8GCSqGSIb3
# DQEJBDEiBCAcjGa1mNp1pxVTOsWG7UkL4dj4FeKoaq50bGaXXhkHJzCB+gYLKoZI
# hvcNAQkQAi8xgeowgecwgeQwgb0EIEsD3RtxlvaTxFOZZnpQw0DksPmVduo5SyK9
# h9w++hMtMIGYMIGApH4wfDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0
# b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3Jh
# dGlvbjEmMCQGA1UEAxMdTWljcm9zb2Z0IFRpbWUtU3RhbXAgUENBIDIwMTACEzMA
# AAIDux5cADhsdMoAAQAAAgMwIgQgQrgv+9IAI5RtzsLOrh8k5TptFrRcq3kN4Hr7
# DLEiPv4wDQYJKoZIhvcNAQELBQAEggIAfqIQ9HKoOfAOnrF4WsWZViNJn0dXDgjX
# kCOOK5tp8JBvpWy1rKNPzlYLSuJN8UmgDyVV3GA4P9fkU6Zag0wfBbKCihvclX06
# B8x2czPC5wzxxApADdKdCOk4WwsK/ePmxzl/bIN6b3/lP0B4Pty4yhEPRjdI8JGE
# o18A2+gJdlojVWPmGmyYm8GIKXuHmtqpyNyKwkOLi4JwxodCiNcPBd3C/RumFy5V
# s1iiweoAZ4w3m3tAWIxYmt9YjwTtWBkmz9YgxXbIFWtRa9JC9BRHW3tTLlvyd5gi
# msn01fA/h+DuGl01PryFCLPNWgJ4UdGZcb1z6qdTqM4SqhCAgL+Su3yR+TckCRrj
# 1fqILgM++LiOSgUwGMKXDIaZlbbiP4yf+uUv95beaAnYHtNqAowQkuxqEbaY/x8y
# FnZqpWPSh5Izu8YrjD7yEmRjgRVMDUxRT63DjrX9YjKvH2eZIjCYmLWqb3yLKbUh
# Fp141atcNrsQOwYaHPsNWfjjrfvOfPWOcUw44cbBcBKChT1Pt6MImnPxB28kFX+T
# PZB5/nYxfQW2OiyRxfz5Wh32VXRfh0w1SbgopO8t2AHdYviGEIEmdo8z3eJsi426
# 7rHWPgv4ksRoimRI50FeIgHObOYHMCzmm4fikmDICRDQr+Gx7jcKJHy8rLb2h91c
# /918XGyVEgE=
# SIG # End signature block
