param(
    [Parameter(Mandatory = $true)]
    [string]$Action,

    [Parameter(ValueFromRemainingArguments = $true)]
    [string[]]$Arguments
)

function Exit-WithUsage {
    Write-Error "Usage: upgradeClientHelper.ps1 <Action> [arguments]"
    exit 64
}

function Get-Argument {
    param(
        [int]$Index,
        [string]$Name
    )

    if ($null -eq $Arguments -or $Arguments.Length -le $Index -or [string]::IsNullOrEmpty($Arguments[$Index])) {
        Write-Error "Missing argument: $Name"
        exit 64
    }

    return $Arguments[$Index]
}

function Write-UpgradeLog {
    param(
        [string]$Message
    )

    $path = $null
    if (![string]::IsNullOrEmpty($env:FW_UPGRADE_HELPER_LOG)) {
        $path = $env:FW_UPGRADE_HELPER_LOG
    } elseif (![string]::IsNullOrEmpty($env:FW_UPGRADE_LOG)) {
        $path = $env:FW_UPGRADE_LOG
    }
    if ([string]::IsNullOrEmpty($path)) {
        return
    }

    $stamp = Get-Date -Format 'yyyy-MM-dd HH:mm:ss.fff'
    $line = '"{0} == PS helper: {1}"' -f $stamp, $Message
    try {
        Add-Content -Path $path -Value $line -ErrorAction SilentlyContinue
    } catch {
    }
}

function Trim-Log {
    $path = Get-Argument 0 'Path'
    $maxBytes = [int64](Get-Argument 1 'MaxBytes')

    if (Test-Path $path) {
        $item = Get-Item $path
        if ($item.Length -gt $maxBytes) {
            $bytes = [System.IO.File]::ReadAllBytes($path)
            [System.IO.File]::WriteAllBytes($path, $bytes[($bytes.Length - $maxBytes)..($bytes.Length - 1)])
        }
    }
}

function Test-LockStale {
    $path = Get-Argument 0 'Path'
    $maxAgeMinutes = [int](Get-Argument 1 'MaxAgeMinutes')

    if (!(Test-Path $path)) {
        exit 0
    }

    $heartbeat = Join-Path $path 'heartbeat.txt'
    $created = Join-Path $path 'created.txt'

    if (Test-Path $heartbeat) {
        $stamp = (Get-Item $heartbeat).LastWriteTime
    } elseif (Test-Path $created) {
        $stamp = (Get-Item $created).LastWriteTime
    } else {
        $stamp = (Get-Item $path).LastWriteTime
    }

    $age = ((Get-Date) - $stamp).TotalMinutes
    if ($age -gt $maxAgeMinutes) {
        exit 0
    }

    exit 1
}

function Test-MsiAvailable {
    $mutex = $null

    try {
        # TryOpenExisting only *probes* for the mutex: it never creates it and never takes
        # ownership, so the probe itself cannot make the Windows Installer look busy to every
        # other installer on the box. (The previous New-Object Mutex($true, 'Global\_MSIExecute')
        # took initial ownership for the life of the probe, which is the bug this replaces.)
        # It also returns $false instead of throwing when the mutex simply doesn't exist, so the
        # common "installer idle" path needs no exception handling at all.
        if ([System.Threading.Mutex]::TryOpenExisting('Global\_MSIExecute', [ref]$mutex)) {
            # Opened successfully -> the mutex exists -> an MSI transaction is in progress.
            Write-UpgradeLog 'Windows Installer mutex is busy.'
            exit 1
        }

        Write-UpgradeLog 'Windows Installer mutex is available.'
        exit 0
    } catch {
        # PowerShell wraps exceptions thrown by .NET methods, so unwrap before deciding.
        $exception = $_.Exception
        while ($exception -and $exception -isnot [System.UnauthorizedAccessException] -and $exception.InnerException) {
            $exception = $exception.InnerException
        }

        if ($exception -is [System.UnauthorizedAccessException]) {
            # The mutex exists but we lack the rights to open it. That is a permission problem,
            # not a busy installer, so log it distinctly instead of collapsing it into the
            # generic "busy" path. We still must not proceed, so treat it as not-available.
            Write-UpgradeLog ('Windows Installer mutex exists but is not accessible (access denied): {0}' -f $exception.Message)
            exit 2
        }

        Write-UpgradeLog ('Windows Installer mutex check failed: {0}' -f $_.Exception.Message)
        exit 2
    } finally {
        if ($mutex) {
            $mutex.Dispose()
        }
    }
}

function Read-MsiVersion {
    $path = Get-Argument 0 'MsiPath'

    try {
        if (Test-Path $path) {
            $item = Get-Item $path
            Write-UpgradeLog ('Reading MSI ProductVersion from {0}; size {1} bytes.' -f $path, $item.Length)
        } else {
            Write-UpgradeLog ('MSI path does not exist while reading ProductVersion: {0}' -f $path)
        }

        $installer = New-Object -ComObject WindowsInstaller.Installer
        $database = $installer.GetType().InvokeMember('OpenDatabase', 'InvokeMethod', $null, $installer, @($path, 0))
        $view = $database.OpenView("SELECT Value FROM Property WHERE Property = 'ProductVersion'")
        $view.Execute()
        $record = $view.Fetch()
        if ($record) {
            $version = $record.StringData(1)
            Write-UpgradeLog ('MSI ProductVersion read successfully: {0}' -f $version)
            $version
            exit 0
        }

        Write-UpgradeLog ('MSI ProductVersion record was not found in {0}.' -f $path)
        exit 1
    } catch {
        Write-UpgradeLog ('MSI ProductVersion read failed: {0}' -f $_.Exception.Message)
        Write-Error $_.Exception.Message
        exit 1
    }
}

function Get-PackageField {
    param(
        [string]$PackageName,
        [string]$FieldName
    )

    $package = Get-Package -Name $PackageName -ErrorAction SilentlyContinue
    if ($package) {
        Write-UpgradeLog ('Found package: {0}; version {1}' -f $package.Name, $package.Version)
        $package.$FieldName
        exit 0
    }

    Write-UpgradeLog ('Package not found by Get-Package: {0}' -f $PackageName)

    $application = Get-InstalledApplication $PackageName
    if ($application) {
        Write-UpgradeLog ('Found application in uninstall registry: {0}; version {1}; key {2}' -f $application.DisplayName, $application.DisplayVersion, $application.PSChildName)
        if ($FieldName -eq 'Name') {
            $application.DisplayName
        } elseif ($FieldName -eq 'Version') {
            $application.DisplayVersion
        } else {
            $application.$FieldName
        }
        exit 0
    }

    if ($PackageName -eq 'FileWave Client') {
        $fwcldVersion = Get-FwcldVersion
        if ($fwcldVersion) {
            Write-UpgradeLog ('Found FileWave Client version from installed fwcld.exe: {0}' -f $fwcldVersion)
            if ($FieldName -eq 'Name') {
                'FileWave Client'
            } elseif ($FieldName -eq 'Version') {
                $fwcldVersion
            } else {
                $fwcldVersion
            }
            exit 0
        }
    }

    Write-UpgradeLog ('Application not found in uninstall registry: {0}' -f $PackageName)
    exit 1
}

function Test-InstalledVersion {
    $expected = Get-Argument 0 'ExpectedVersion'
    $version = (Get-Package -Name 'FileWave Client' -ErrorAction SilentlyContinue).Version

    if (!$version) {
        Write-UpgradeLog 'Installed FileWave Client version was not found by Get-Package.'
        $application = Get-InstalledApplication 'FileWave Client'
        if ($application) {
            Write-UpgradeLog ('Found installed FileWave Client in uninstall registry; version {0}; key {1}' -f $application.DisplayVersion, $application.PSChildName)
            $version = $application.DisplayVersion
        }
    }

    if (!$version) {
        $version = Get-FwcldVersion
        if ($version) {
            Write-UpgradeLog ('Found installed FileWave Client version from installed fwcld.exe: {0}' -f $version)
        }
    }

    if (!$version) {
        Write-UpgradeLog 'Installed FileWave Client version was not found by Get-Package, uninstall registry, or fwcld.exe -V.'
        exit 1
    }

    $version

    if (Test-VersionMatches $version $expected) {
        Write-UpgradeLog ('Installed FileWave Client version {0} matches expected version {1}.' -f $version, $expected)
        exit 0
    }

    Write-UpgradeLog ('Installed FileWave Client version {0} does not match expected version {1}.' -f $version, $expected)
    exit 2
}

function Test-VersionMatches {
    param(
        [string]$Version,
        [string]$Expected
    )

    if ($Version -eq $Expected) {
        return $true
    }

    try {
        $actualVersion = [version]$Version
        $expectedVersion = [version]$Expected

        if ($actualVersion -eq $expectedVersion) {
            return $true
        }

        if ($expectedVersion.Revision -lt 0) {
            return $actualVersion.Major -eq $expectedVersion.Major -and
                $actualVersion.Minor -eq $expectedVersion.Minor -and
                $actualVersion.Build -eq $expectedVersion.Build
        }
    } catch {
    }

    return $false
}

function Get-InstalledApplication {
    param(
        [string]$DisplayName
    )

    $paths = @(
        'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*',
        'HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*'
    )

    Get-ItemProperty $paths -ErrorAction SilentlyContinue |
        Where-Object { $_.DisplayName -eq $DisplayName } |
        Select-Object -First 1
}

function Get-FwcldVersion {
    $paths = Get-FwcldPaths

    foreach ($path in $paths) {
        if (!(Test-Path $path)) {
            Write-UpgradeLog ('fwcld.exe candidate not found: {0}' -f $path)
            continue
        }

        $fileVersion = Get-FwcldFileVersion $path
        if ($fileVersion) {
            return $fileVersion
        }

        try {
            $output = & $path -V 2>&1
            $exitCode = $LASTEXITCODE
            Write-UpgradeLog ('fwcld.exe -V at {0} exited with {1}; output: {2}' -f $path, $exitCode, ($output -join ' '))
            if ($exitCode -ne 0) {
                continue
            }

            foreach ($line in $output) {
                if ($line -match '\b(\d+(?:\.\d+){1,3})\b') {
                    return $Matches[1]
                }
            }
        } catch {
            Write-UpgradeLog ('fwcld.exe -V failed at {0}: {1}' -f $path, $_.Exception.Message)
        }
    }

    return $null
}

function Get-FwcldPaths {
    @(
        'C:\Program Files\FileWave\client\fwcld.exe',
        'C:\Program Files\FileWave\fwcld.exe',
        'C:\Program Files (x86)\FileWave\fwcld.exe'
    )
}

function Get-FwcldFileVersion {
    param(
        [string]$Path
    )

    try {
        $versionInfo = [System.Diagnostics.FileVersionInfo]::GetVersionInfo($Path)
        foreach ($candidate in @($versionInfo.ProductVersion, $versionInfo.FileVersion)) {
            if ([string]::IsNullOrWhiteSpace($candidate)) {
                continue
            }

            Write-UpgradeLog ('fwcld.exe version resource at {0}: {1}' -f $Path, $candidate)
            if ($candidate -match '\b(\d+(?:\.\d+){1,3})\b') {
                return $Matches[1]
            }
        }
    } catch {
        Write-UpgradeLog ('Could not read fwcld.exe version resource at {0}: {1}' -f $Path, $_.Exception.Message)
    }

    return $null
}

function Test-MsiLogMissingSource {
    $path = Get-Argument 0 'MsiLogPath'

    if (!(Test-Path $path)) {
        exit 1
    }

    $patterns = @(
        '\b1706\b',
        'no valid source',
        'installation source',
        'source for this product',
        'network resource',
        'SourceList',
        'cannot find.*\.msi',
        'use source',
        'failed to resolve source'
    )

    $text = Get-Content -Path $path -Raw -ErrorAction SilentlyContinue
    foreach ($pattern in $patterns) {
        if ($text -match $pattern) {
            Write-UpgradeLog ('MSI log missing-source pattern matched: {0}' -f $pattern)
            exit 0
        }
    }

    Write-UpgradeLog 'MSI log did not contain missing-source patterns.'
    exit 1
}

function Scrub-FileWaveMsiRegistration {
    $paths = @(
        'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*',
        'HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*'
    )

    $apps = Get-ItemProperty $paths -ErrorAction SilentlyContinue | Where-Object { $_.DisplayName -like 'FileWave Client*' }
    foreach ($app in $apps) {
        $code = $app.PSChildName -replace '[-{}]', ''
        if ($code.Length -eq 32) {
            $packedCode = -join ($code[7..0] + $code[11..8] + $code[15..12] + $code[17, 16, 19, 18, 21, 20, 23, 22, 25, 24, 27, 26, 29, 28, 31, 30])
            Remove-Item "HKLM:\SOFTWARE\Classes\Installer\Products\$packedCode" -Recurse -Force -ErrorAction SilentlyContinue
            Remove-Item $app.PSPath -Recurse -Force -ErrorAction SilentlyContinue
            Write-Output "Scrubbed old MSI registration for $($app.DisplayName)"
        }
    }
}

function Count-Lines {
    $path = Get-Argument 0 'Path'

    if (Test-Path $path) {
        (Get-Content $path).Length
    } else {
        0
    }
}

if ($Action -ne 'TrimLog') {
    $argumentCount = 0
    if ($null -ne $Arguments) {
        $argumentCount = $Arguments.Length
    }
    Write-UpgradeLog ('Action {0} started with {1} argument(s).' -f $Action, $argumentCount)
}

switch ($Action) {
    'TrimLog' {
        Trim-Log
        exit 0
    }
    'IsLockStale' {
        Test-LockStale
    }
    'MsiAvailable' {
        Test-MsiAvailable
    }
    'ReadMsiVersion' {
        Read-MsiVersion
    }
    'GetPackageName' {
        $name = Get-Argument 0 'PackageName'
        Get-PackageField $name 'Name'
    }
    'GetPackageVersion' {
        $name = Get-Argument 0 'PackageName'
        Get-PackageField $name 'Version'
    }
    'VerifyInstalledVersion' {
        Test-InstalledVersion
    }
    'MsiLogMissingSource' {
        Test-MsiLogMissingSource
    }
    'ScrubFileWaveMsiRegistration' {
        Scrub-FileWaveMsiRegistration
        exit 0
    }
    'CountLines' {
        Count-Lines
        exit 0
    }
    default {
        Exit-WithUsage
    }
}

# SIG # Begin signature block
# MII54AYJKoZIhvcNAQcCoII50TCCOc0CAQExDzANBglghkgBZQMEAgEFADB5Bgor
# BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG
# KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCBYcj98E40HZUcD
# HOM/rnVaJ/6ZF4xRyIu1zpg12IPbXqCCIgQwggXMMIIDtKADAgECAhBUmNLR1FsZ
# lUgTecgRwIeZMA0GCSqGSIb3DQEBDAUAMHcxCzAJBgNVBAYTAlVTMR4wHAYDVQQK
# ExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xSDBGBgNVBAMTP01pY3Jvc29mdCBJZGVu
# dGl0eSBWZXJpZmljYXRpb24gUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgMjAy
# MDAeFw0yMDA0MTYxODM2MTZaFw00NTA0MTYxODQ0NDBaMHcxCzAJBgNVBAYTAlVT
# MR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xSDBGBgNVBAMTP01pY3Jv
# c29mdCBJZGVudGl0eSBWZXJpZmljYXRpb24gUm9vdCBDZXJ0aWZpY2F0ZSBBdXRo
# b3JpdHkgMjAyMDCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBALORKgeD
# Bmf9np3gx8C3pOZCBH8Ppttf+9Va10Wg+3cL8IDzpm1aTXlT2KCGhFdFIMeiVPvH
# or+Kx24186IVxC9O40qFlkkN/76Z2BT2vCcH7kKbK/ULkgbk/WkTZaiRcvKYhOuD
# PQ7k13ESSCHLDe32R0m3m/nJxxe2hE//uKya13NnSYXjhr03QNAlhtTetcJtYmrV
# qXi8LW9J+eVsFBT9FMfTZRY33stuvF4pjf1imxUs1gXmuYkyM6Nix9fWUmcIxC70
# ViueC4fM7Ke0pqrrBc0ZV6U6CwQnHJFnni1iLS8evtrAIMsEGcoz+4m+mOJyoHI1
# vnnhnINv5G0Xb5DzPQCGdTiO0OBJmrvb0/gwytVXiGhNctO/bX9x2P29Da6SZEi3
# W295JrXNm5UhhNHvDzI9e1eM80UHTHzgXhgONXaLbZ7LNnSrBfjgc10yVpRnlyUK
# xjU9lJfnwUSLgP3B+PR0GeUw9gb7IVc+BhyLaxWGJ0l7gpPKWeh1R+g/OPTHU3mg
# trTiXFHvvV84wRPmeAyVWi7FQFkozA8kwOy6CXcjmTimthzax7ogttc32H83rwjj
# O3HbbnMbfZlysOSGM1l0tRYAe1BtxoYT2v3EOYI9JACaYNq6lMAFUSw0rFCZE4e7
# swWAsk0wAly4JoNdtGNz764jlU9gKL431VulAgMBAAGjVDBSMA4GA1UdDwEB/wQE
# AwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTIftJqhSobyhmYBAcnz1AQ
# T2ioojAQBgkrBgEEAYI3FQEEAwIBADANBgkqhkiG9w0BAQwFAAOCAgEAr2rd5hnn
# LZRDGU7L6VCVZKUDkQKL4jaAOxWiUsIWGbZqWl10QzD0m/9gdAmxIR6QFm3FJI9c
# Zohj9E/MffISTEAQiwGf2qnIrvKVG8+dBetJPnSgaFvlVixlHIJ+U9pW2UYXeZJF
# xBA2CFIpF8svpvJ+1Gkkih6PsHMNzBxKq7Kq7aeRYwFkIqgyuH4yKLNncy2RtNwx
# AQv3Rwqm8ddK7VZgxCwIo3tAsLx0J1KH1r6I3TeKiW5niB31yV2g/rarOoDXGpc8
# FzYiQR6sTdWD5jw4vU8w6VSp07YEwzJ2YbuwGMUrGLPAgNW3lbBeUU0i/OxYqujY
# lLSlLu2S3ucYfCFX3VVj979tzR/SpncocMfiWzpbCNJbTsgAlrPhgzavhgplXHT2
# 6ux6anSg8Evu75SjrFDyh+3XOjCDyft9V77l4/hByuVkrrOj7FjshZrM77nq81YY
# uVxzmq/FdxeDWds3GhhyVKVB0rYjdaNDmuV3fJZ5t0GNv+zcgKCf0Xd1WF81E+Al
# GmcLfc4l+gcK5GEh2NQc5QfGNpn0ltDGFf5Ozdeui53bFv0ExpK91IjmqaOqu/dk
# ODtfzAzQNb50GQOmxapMomE2gj4d8yu8l13bS3g7LfU772Aj6PXsCyM2la+YZr9T
# 03u4aUoqlmZpxJTG9F9urJh4iIAGXKKy7aIwggavMIIEl6ADAgECAhMzAAWyj2pS
# bAoGSztlAAAABbKPMA0GCSqGSIb3DQEBDAUAMFoxCzAJBgNVBAYTAlVTMR4wHAYD
# VQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xKzApBgNVBAMTIk1pY3Jvc29mdCBJ
# RCBWZXJpZmllZCBDUyBBT0MgQ0EgMDQwHhcNMjYwODMxMjE0NDA2WhcNMjYwOTAz
# MjE0NDA2WjByMQswCQYDVQQGEwJVUzEQMA4GA1UECBMHSW5kaWFuYTEVMBMGA1UE
# BxMMSW5kaWFuYXBvbGlzMRwwGgYDVQQKExNGaWxlV2F2ZSAoVVNBKSBJbmMuMRww
# GgYDVQQDExNGaWxlV2F2ZSAoVVNBKSBJbmMuMIIBojANBgkqhkiG9w0BAQEFAAOC
# AY8AMIIBigKCAYEAzrUyh6RuWIPDdoCqndS70CJ0hycwkjXmqC3zlXHTdX+lp9VI
# DTa+4RyXKcwFUViPPxOCk2BVqXP/UxpsM3qs83xyvwXE9SWUudO3gA44bg0fh8sp
# dAghlDkTjoyft3c4wkwg5JbXsADmMjI41DkGcNTFS4nU4UogTjHQV8Fm5XILMz4Y
# 9LjtezoJAIaJ/z7HjckaDh6oS23QSmIYG0FBbKQGfGf5IyDJ5VvEPoKf3wAAoPm0
# 8fk7NORrh5ITnuxVmJB79n2XJFn4NnKgNHvYofU9kqo4U/Y9mlo3gDkT8bqGi1t5
# 4yx4yJ4dTfFv362WtkWfGWtixJZfa/fZPq+XW4OLmeojzLCYQdhWC6SgNSCImD48
# byjbkAp84ajRlWhmNogfF/0RJuJCrvPx+tiHV7atbZQ0T4P1Bgay29uqNceOyDYH
# mm6z9oV2VXhXVcl0SylDOhDKI9Fs6pjZmsFE2m7ojoNKlua66J4XNc2MsbZBJOzO
# GxJ02x+qBsUud/erAgMBAAGjggHUMIIB0DAMBgNVHRMBAf8EAjAAMA4GA1UdDwEB
# /wQEAwIHgDA7BgNVHSUENDAyBgorBgEEAYI3YQEABggrBgEFBQcDAwYaKwYBBAGC
# N2G8ycRpgvKdiAWCxsqSJMvg7XMwHQYDVR0OBBYEFBN/LKwgNaL4XFe65BXOUyam
# aOJOMB8GA1UdIwQYMBaAFGslQd77a3z9GIAKLX+Pdl2qcz24MGcGA1UdHwRgMF4w
# XKBaoFiGVmh0dHA6Ly93d3cubWljcm9zb2Z0LmNvbS9wa2lvcHMvY3JsL01pY3Jv
# c29mdCUyMElEJTIwVmVyaWZpZWQlMjBDUyUyMEFPQyUyMENBJTIwMDQuY3JsMHQG
# CCsGAQUFBwEBBGgwZjBkBggrBgEFBQcwAoZYaHR0cDovL3d3dy5taWNyb3NvZnQu
# Y29tL3BraW9wcy9jZXJ0cy9NaWNyb3NvZnQlMjBJRCUyMFZlcmlmaWVkJTIwQ1Ml
# MjBBT0MlMjBDQSUyMDA0LmNydDBUBgNVHSAETTBLMEkGBFUdIAAwQTA/BggrBgEF
# BQcCARYzaHR0cDovL3d3dy5taWNyb3NvZnQuY29tL3BraW9wcy9Eb2NzL1JlcG9z
# aXRvcnkuaHRtMA0GCSqGSIb3DQEBDAUAA4ICAQCP5hdOL/OFd7KSbCN2Uo8J7qDS
# Hakciw6GAajVJ01AWoT3avm02oFnN/B/RkcggpJ+bgmtedUXdz0K5c6kQ68NE3kW
# 5wZrbawmVwo3xC5K94VnWPw3LZNNJWHoHPZPpIIgr66I+dAeudBJGCeIpclbzkN1
# wkT+hQebkhEUxd75vzhEbOO1TRSopo4TvF1cnRehAXIpipuLE/BxkVsTnWhiHenf
# /9wBMhPLfLDRy4WZQx64LfnoHzCdwZur8ATsTfVPh8qMBQ0zU5aPGfvM6CSg+RKS
# VGoJPKKBTS/dbQswVsd78e+Fo3Jvz+9cad5FwetjjHTLdbZTJ+2ISaVAbmPqzat4
# Wy2UHDVP1VgFhJIgitQLIUUUm6WtwTh6lWQrTb+sHvjKF5HKu5rsON0g3Pj1iXb/
# /LNG69X7F+Ja04shvrnMaiCTbWpXhG66mG2dG5Wea9S/hyAlCwTR0jU3uegEinDy
# DYYnOglXUSQ9GzXlETHNfOAldNhaBOiYfbvhi7yzGa0QPzPfZth/bk4ojka82gYT
# lvbxKvgjQ+wtxmnxO2E6ifemL6fhJCHxNcuQwMT9OKYq9g3Qyz4ZhtuCwiPO7N7N
# gPy5picYD+InoloJeakkh4PHcOyTFBFvFh0kNYtUIObgyj8s84VM8ZUe77xgdU5O
# r1FeHFbBJW/C8Qaa7zCCBq8wggSXoAMCAQICEzMABbKPalJsCgZLO2UAAAAFso8w
# DQYJKoZIhvcNAQEMBQAwWjELMAkGA1UEBhMCVVMxHjAcBgNVBAoTFU1pY3Jvc29m
# dCBDb3Jwb3JhdGlvbjErMCkGA1UEAxMiTWljcm9zb2Z0IElEIFZlcmlmaWVkIENT
# IEFPQyBDQSAwNDAeFw0yNjA4MzEyMTQ0MDZaFw0yNjA5MDMyMTQ0MDZaMHIxCzAJ
# BgNVBAYTAlVTMRAwDgYDVQQIEwdJbmRpYW5hMRUwEwYDVQQHEwxJbmRpYW5hcG9s
# aXMxHDAaBgNVBAoTE0ZpbGVXYXZlIChVU0EpIEluYy4xHDAaBgNVBAMTE0ZpbGVX
# YXZlIChVU0EpIEluYy4wggGiMA0GCSqGSIb3DQEBAQUAA4IBjwAwggGKAoIBgQDO
# tTKHpG5Yg8N2gKqd1LvQInSHJzCSNeaoLfOVcdN1f6Wn1UgNNr7hHJcpzAVRWI8/
# E4KTYFWpc/9TGmwzeqzzfHK/BcT1JZS507eADjhuDR+Hyyl0CCGUOROOjJ+3dzjC
# TCDkltewAOYyMjjUOQZw1MVLidThSiBOMdBXwWblcgszPhj0uO17OgkAhon/PseN
# yRoOHqhLbdBKYhgbQUFspAZ8Z/kjIMnlW8Q+gp/fAACg+bTx+Ts05GuHkhOe7FWY
# kHv2fZckWfg2cqA0e9ih9T2SqjhT9j2aWjeAORPxuoaLW3njLHjInh1N8W/frZa2
# RZ8Za2LEll9r99k+r5dbg4uZ6iPMsJhB2FYLpKA1IIiYPjxvKNuQCnzhqNGVaGY2
# iB8X/REm4kKu8/H62IdXtq1tlDRPg/UGBrLb26o1x47INgeabrP2hXZVeFdVyXRL
# KUM6EMoj0WzqmNmawUTabuiOg0qW5rronhc1zYyxtkEk7M4bEnTbH6oGxS5396sC
# AwEAAaOCAdQwggHQMAwGA1UdEwEB/wQCMAAwDgYDVR0PAQH/BAQDAgeAMDsGA1Ud
# JQQ0MDIGCisGAQQBgjdhAQAGCCsGAQUFBwMDBhorBgEEAYI3YbzJxGmC8p2IBYLG
# ypIky+DtczAdBgNVHQ4EFgQUE38srCA1ovhcV7rkFc5TJqZo4k4wHwYDVR0jBBgw
# FoAUayVB3vtrfP0YgAotf492XapzPbgwZwYDVR0fBGAwXjBcoFqgWIZWaHR0cDov
# L3d3dy5taWNyb3NvZnQuY29tL3BraW9wcy9jcmwvTWljcm9zb2Z0JTIwSUQlMjBW
# ZXJpZmllZCUyMENTJTIwQU9DJTIwQ0ElMjAwNC5jcmwwdAYIKwYBBQUHAQEEaDBm
# MGQGCCsGAQUFBzAChlhodHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2Nl
# cnRzL01pY3Jvc29mdCUyMElEJTIwVmVyaWZpZWQlMjBDUyUyMEFPQyUyMENBJTIw
# MDQuY3J0MFQGA1UdIARNMEswSQYEVR0gADBBMD8GCCsGAQUFBwIBFjNodHRwOi8v
# d3d3Lm1pY3Jvc29mdC5jb20vcGtpb3BzL0RvY3MvUmVwb3NpdG9yeS5odG0wDQYJ
# KoZIhvcNAQEMBQADggIBAI/mF04v84V3spJsI3ZSjwnuoNIdqRyLDoYBqNUnTUBa
# hPdq+bTagWc38H9GRyCCkn5uCa151Rd3PQrlzqRDrw0TeRbnBmttrCZXCjfELkr3
# hWdY/Dctk00lYegc9k+kgiCvroj50B650EkYJ4ilyVvOQ3XCRP6FB5uSERTF3vm/
# OERs47VNFKimjhO8XVydF6EBcimKm4sT8HGRWxOdaGId6d//3AEyE8t8sNHLhZlD
# Hrgt+egfMJ3Bm6vwBOxN9U+HyowFDTNTlo8Z+8zoJKD5EpJUagk8ooFNL91tCzBW
# x3vx74Wjcm/P71xp3kXB62OMdMt1tlMn7YhJpUBuY+rNq3hbLZQcNU/VWAWEkiCK
# 1AshRRSbpa3BOHqVZCtNv6we+MoXkcq7muw43SDc+PWJdv/8s0br1fsX4lrTiyG+
# ucxqIJNtaleEbrqYbZ0blZ5r1L+HICULBNHSNTe56ASKcPINhic6CVdRJD0bNeUR
# Mc184CV02FoE6Jh9u+GLvLMZrRA/M99m2H9uTiiORrzaBhOW9vEq+CND7C3GafE7
# YTqJ96Yvp+EkIfE1y5DAxP04pir2DdDLPhmG24LCI87s3s2A/LmmJxgP4ieiWgl5
# qSSHg8dw7JMUEW8WHSQ1i1Qg5uDKPyzzhUzxlR7vvGB1Tk6vUV4cVsElb8LxBprv
# MIIHKDCCBRCgAwIBAgITMwAAABYxko2SAmV7mgAAAAAAFjANBgkqhkiG9w0BAQwF
# ADBjMQswCQYDVQQGEwJVUzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9u
# MTQwMgYDVQQDEytNaWNyb3NvZnQgSUQgVmVyaWZpZWQgQ29kZSBTaWduaW5nIFBD
# QSAyMDIxMB4XDTI2MDMyNjE4MTEyOVoXDTMxMDMyNjE4MTEyOVowWjELMAkGA1UE
# BhMCVVMxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjErMCkGA1UEAxMi
# TWljcm9zb2Z0IElEIFZlcmlmaWVkIENTIEFPQyBDQSAwNDCCAiIwDQYJKoZIhvcN
# AQEBBQADggIPADCCAgoCggIBAMpV+sjb6Akwz/RtDk5Uo1284BLMttRQy9e5/5WX
# tga6h89pkdWjeAwcXmKdP4YxKkhx8hn2q1dTVQbryvLy81tC04vg2bfSJ9emojX4
# HKIBYs7VhPRafMbtc866hN55aw1m/kWaPEKxF4Fm/LPLMLJdlu7URB8nFZMfh5tT
# C0CJb2uox/14OP/BiGIR8214lXdkV6JsPbO0Iev0mEV133tducIeBChMipzTZfnG
# VEq1QYFr7460cEGOIn+7AGfNOSq7gWOlmNB4m2uZ1r66vUJPaN+VYgH/Kmfu7tX2
# 29b3Alsli38fYS0nQY41bElntMS7yNY+Kd047eXM8/tS3NL+ZUNX3ge5xZqW2ayt
# rrNIbwGgQnzsgzxBJvu9+b87jUWFiRS/z1YiPkRLY7iTHKIxJ973kIyK8K5itE/a
# Eq/Ht6A8ytaAMMGTEwuCspk72FE1Qyby+TfDlv1KiAc7IlWHHIWbxoVd8jGCoMXh
# LSDhuFuGfOWOZKUIuW6YxlxcUYOOkXa02gC7dUYUZi0e1NI1Uq9mmAHdvjKdqgOR
# s9/5aDjnbeO3hWd5qwGBmELWytkjY0KcIEF+CMurTimoQoBYSiHJbYrb0pKSQe+3
# lVoTVpzdi36jKI7MxLnu1fBAMksa8uD85cU7RU29zMOd18h9dgTEH9pvY+4xLB3l
# UgE7AgMBAAGjggHcMIIB2DAOBgNVHQ8BAf8EBAMCAYYwEAYJKwYBBAGCNxUBBAMC
# AQAwHQYDVR0OBBYEFGslQd77a3z9GIAKLX+Pdl2qcz24MFQGA1UdIARNMEswSQYE
# VR0gADBBMD8GCCsGAQUFBwIBFjNodHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtp
# b3BzL0RvY3MvUmVwb3NpdG9yeS5odG0wGQYJKwYBBAGCNxQCBAweCgBTAHUAYgBD
# AEEwEgYDVR0TAQH/BAgwBgEB/wIBADAfBgNVHSMEGDAWgBTZQSmwDw9jbO9p1/XN
# KZ6kSGow5jBwBgNVHR8EaTBnMGWgY6Bhhl9odHRwOi8vd3d3Lm1pY3Jvc29mdC5j
# b20vcGtpb3BzL2NybC9NaWNyb3NvZnQlMjBJRCUyMFZlcmlmaWVkJTIwQ29kZSUy
# MFNpZ25pbmclMjBQQ0ElMjAyMDIxLmNybDB9BggrBgEFBQcBAQRxMG8wbQYIKwYB
# BQUHMAKGYWh0dHA6Ly93d3cubWljcm9zb2Z0LmNvbS9wa2lvcHMvY2VydHMvTWlj
# cm9zb2Z0JTIwSUQlMjBWZXJpZmllZCUyMENvZGUlMjBTaWduaW5nJTIwUENBJTIw
# MjAyMS5jcnQwDQYJKoZIhvcNAQEMBQADggIBAAbVUF5UdNVEGWOVxkPciIzHA/Iy
# NDIs1oSdW7mY4ObaFEEl8fwawEsBOascBzwXjuOaTkKelQ+IiC4JvDpn8pWPgOyi
# Krbbw1Iswt7AV8YyuLu7A0YshILlxyny9R0AMMQixLZ0T5Aj07CQOm/de5QPt36E
# CBwtVww6XUCx8Rm2xl6eEa9JhSub8W4urQGoQYv0Zczlz4ej2ryj5Wf9L4ZZA3bL
# 6CRE7XmzSQjTmdSmr904PiuL2uBWzq2KkR3RhmoaAP4Jk2JplasNM5Bs0+dx3YX2
# o6xRrbSaJiu6hPk/AkBoj5BCJMTZkl4wk6Q6nOFNSCpUxnBmJ0RRkoKq51p5ADTx
# bCeRAx8rIfNpTyPjxQtxTiFTC8yy/t9K6s570YB1FAI+8XxZxIrmgMd7xVUkzi2/
# oooKb3UeovH0lqYGBEjpHZJ9jee7boQbOe7SsKD/vr3PzFabg9VwLZlovpWUpWoW
# nU2w3xiozJ/m35tsZVvT2egUpwkb9TDIaXFGZAGV94FRDHn/K2XNnOwSeGskX19M
# B+N7yPc51fmUSd49MVAtGW/NkUGpRech5Aq/d8dCML2bZ+j9nTUMgj+qnd3wuEZV
# RbQEIbTh9HAck0fyKqoIb+qh8y/6TKbYDEEOcfM2BGMvrQk4WIGCK6u8uFhA2EH3
# kpaiMUDqyFCeCCQxMIIHnjCCBYagAwIBAgITMwAAAAeHozSje6WOHAAAAAAABzAN
# BgkqhkiG9w0BAQwFADB3MQswCQYDVQQGEwJVUzEeMBwGA1UEChMVTWljcm9zb2Z0
# IENvcnBvcmF0aW9uMUgwRgYDVQQDEz9NaWNyb3NvZnQgSWRlbnRpdHkgVmVyaWZp
# Y2F0aW9uIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIwMjAwHhcNMjEwNDAx
# MjAwNTIwWhcNMzYwNDAxMjAxNTIwWjBjMQswCQYDVQQGEwJVUzEeMBwGA1UEChMV
# TWljcm9zb2Z0IENvcnBvcmF0aW9uMTQwMgYDVQQDEytNaWNyb3NvZnQgSUQgVmVy
# aWZpZWQgQ29kZSBTaWduaW5nIFBDQSAyMDIxMIICIjANBgkqhkiG9w0BAQEFAAOC
# Ag8AMIICCgKCAgEAsvDArxmIKOLdVHpMSWxpCFUJtFL/ekr4weslKPdnF3cpTeuV
# 8veqtmKVgok2rO0D05BpyvUDCg1wdsoEtuxACEGcgHfjPF/nZsOkg7c0mV8hpMT/
# GvB4uhDvWXMIeQPsDgCzUGzTvoi76YDpxDOxhgf8JuXWJzBDoLrmtThX01CE1TCC
# vH2sZD/+Hz3RDwl2MsvDSdX5rJDYVuR3bjaj2QfzZFmwfccTKqMAHlrz4B7ac8g9
# zyxlTpkTuJGtFnLBGasoOnn5NyYlf0xF9/bjVRo4Gzg2Yc7KR7yhTVNiuTGH5h4e
# B9ajm1OCShIyhrKqgOkc4smz6obxO+HxKeJ9bYmPf6KLXVNLz8UaeARo0BatvJ82
# sLr2gqlFBdj1sYfqOf00Qm/3B4XGFPDK/H04kteZEZsBRc3VT2d/iVd7OTLpSH9y
# CORV3oIZQB/Qr4nD4YT/lWkhVtw2v2s0TnRJubL/hFMIQa86rcaGMhNsJrhysLNN
# MeBhiMezU1s5zpusf54qlYu2v5sZ5zL0KvBDLHtL8F9gn6jOy3v7Jm0bbBHjrW5y
# QW7S36ALAt03QDpwW1JG1Hxu/FUXJbBO2AwwVG4Fre+ZQ5Od8ouwt59FpBxVOBGf
# N4vN2m3fZx1gqn52GvaiBz6ozorgIEjn+PhUXILhAV5Q/ZgCJ0u2+ldFGjcCAwEA
# AaOCAjUwggIxMA4GA1UdDwEB/wQEAwIBhjAQBgkrBgEEAYI3FQEEAwIBADAdBgNV
# HQ4EFgQU2UEpsA8PY2zvadf1zSmepEhqMOYwVAYDVR0gBE0wSzBJBgRVHSAAMEEw
# PwYIKwYBBQUHAgEWM2h0dHA6Ly93d3cubWljcm9zb2Z0LmNvbS9wa2lvcHMvRG9j
# cy9SZXBvc2l0b3J5Lmh0bTAZBgkrBgEEAYI3FAIEDB4KAFMAdQBiAEMAQTAPBgNV
# HRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFMh+0mqFKhvKGZgEByfPUBBPaKiiMIGE
# BgNVHR8EfTB7MHmgd6B1hnNodHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpb3Bz
# L2NybC9NaWNyb3NvZnQlMjBJZGVudGl0eSUyMFZlcmlmaWNhdGlvbiUyMFJvb3Ql
# MjBDZXJ0aWZpY2F0ZSUyMEF1dGhvcml0eSUyMDIwMjAuY3JsMIHDBggrBgEFBQcB
# AQSBtjCBszCBgQYIKwYBBQUHMAKGdWh0dHA6Ly93d3cubWljcm9zb2Z0LmNvbS9w
# a2lvcHMvY2VydHMvTWljcm9zb2Z0JTIwSWRlbnRpdHklMjBWZXJpZmljYXRpb24l
# MjBSb290JTIwQ2VydGlmaWNhdGUlMjBBdXRob3JpdHklMjAyMDIwLmNydDAtBggr
# BgEFBQcwAYYhaHR0cDovL29uZW9jc3AubWljcm9zb2Z0LmNvbS9vY3NwMA0GCSqG
# SIb3DQEBDAUAA4ICAQB/JSqe/tSr6t1mCttXI0y6XmyQ41uGWzl9xw+WYhvOL47B
# V09Dgfnm/tU4ieeZ7NAR5bguorTCNr58HOcA1tcsHQqt0wJsdClsu8bpQD9e/al+
# lUgTUJEV80Xhco7xdgRrehbyhUf4pkeAhBEjABvIUpD2LKPho5Z4DPCT5/0TlK02
# nlPwUbv9URREhVYCtsDM+31OFU3fDV8BmQXv5hT2RurVsJHZgP4y26dJDVF+3pcb
# tvh7R6NEDuYHYihfmE2HdQRq5jRvLE1Eb59PYwISFCX2DaLZ+zpU4bX0I16ntKq4
# poGOFaaKtjIA1vRElItaOKcwtc04CBrXSfyL2Op6mvNIxTk4OaswIkTXbFL81ZKG
# D+24uMCwo/pLNhn7VHLfnxlMVzHQVL+bHa9KhTyzwdG/L6uderJQn0cGpLQMStUu
# NDArxW2wF16QGZ1NtBWgKA8Kqv48M8HfFqNifN6+zt6J0GwzvU8g0rYGgTZR8zDE
# IJfeZxwWDHpSxB5FJ1VVU1LIAtB7o9PXbjXzGifaIMYTzU4YKt4vMNwwBmetQDHh
# dAtTPplOXrnI9SI6HeTtjDD3iUN/7ygbahmYOHk7VB7fwT4ze+ErCbMh6gHV1UuX
# PiLciloNxH6K4aMfZN1oLVk6YFeIJEokuPgNPa6EnTiOL60cPqfny+Fq8UiuZzGC
# FzIwghcuAgEBMHEwWjELMAkGA1UEBhMCVVMxHjAcBgNVBAoTFU1pY3Jvc29mdCBD
# b3Jwb3JhdGlvbjErMCkGA1UEAxMiTWljcm9zb2Z0IElEIFZlcmlmaWVkIENTIEFP
# QyBDQSAwNAITMwAFso9qUmwKBks7ZQAAAAWyjzANBglghkgBZQMEAgEFAKBeMBAG
# CisGAQQBgjcCAQwxAjAAMBkGCSqGSIb3DQEJAzEMBgorBgEEAYI3AgEEMC8GCSqG
# SIb3DQEJBDEiBCDtpCGqAU3bf9h++LN7Y6UE71H+6an68kM1j1zEgpjHsjANBgkq
# hkiG9w0BAQEFAASCAYBWhsa5fYqmiW0LQfEiS//4ox+t6PBV6IQaPS87JcECnvcy
# v2SiU/+qxag6ti5BMcM7cMwK87sAp6o7q2d8HcJ8VgEZYglJwlr9MiEjfAj4NLMK
# nlihNkloJ+o7KVM5wo77gris/RAb6GkTfsAN+4tXLYzEeQwTU45HhrY241mtW7qn
# FttcHuxhpu73SeCJkdZzwJfn7w5oI62QAea+ysZQCrLtmC1lKqXm+yuT8kJE3WTd
# WtkWYx5eqZ6lXY95/Vs5w6kGw7IwSqszxrNLPe2TKxxOQarJ/MDyAgtKOeuj40yP
# wb9wQV8lh72sSejR7kGflMkja3DsNpj2O4vmYk7evJkXtjqhux369KZq9asRVOd9
# Pmm4Oo6cL7QDnBlQSbR19zCrr6C5uhbP0axfTYOV8CEgjfmpYyFCFkKhrIlA+/SH
# fY3ISNkzlqe8scZgV3HM2zgh/Ki78FJbd6b0PMm1SfalEL/VbpgYuTS/QCQ8HkX2
# 6araE4Zm4dzwXSyFnYihghSyMIIUrgYKKwYBBAGCNwMDATGCFJ4wghSaBgkqhkiG
# 9w0BBwKgghSLMIIUhwIBAzEPMA0GCWCGSAFlAwQCAQUAMIIBagYLKoZIhvcNAQkQ
# AQSgggFZBIIBVTCCAVECAQEGCisGAQQBhFkKAwEwMTANBglghkgBZQMEAgEFAAQg
# f/1vYNFf3D2uhF3LV/6M8VJAq/KzYHLEeMtn55T6dv4CBmp2Cgx6uBgTMjAyNjA5
# MDIxMzU1MDMuMDM5WjAEgAIB9KCB6aSB5jCB4zELMAkGA1UEBhMCVVMxEzARBgNV
# BAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jv
# c29mdCBDb3Jwb3JhdGlvbjEtMCsGA1UECxMkTWljcm9zb2Z0IElyZWxhbmQgT3Bl
# cmF0aW9ucyBMaW1pdGVkMScwJQYDVQQLEx5uU2hpZWxkIFRTUyBFU046N0IxQS0w
# NUUwLUQ5NDcxNTAzBgNVBAMTLE1pY3Jvc29mdCBQdWJsaWMgUlNBIFRpbWUgU3Rh
# bXBpbmcgQXV0aG9yaXR5oIIPKTCCB4IwggVqoAMCAQICEzMAAAAF5c8P/2YuyYcA
# AAAAAAUwDQYJKoZIhvcNAQEMBQAwdzELMAkGA1UEBhMCVVMxHjAcBgNVBAoTFU1p
# Y3Jvc29mdCBDb3Jwb3JhdGlvbjFIMEYGA1UEAxM/TWljcm9zb2Z0IElkZW50aXR5
# IFZlcmlmaWNhdGlvbiBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAyMDIwMB4X
# DTIwMTExOTIwMzIzMVoXDTM1MTExOTIwNDIzMVowYTELMAkGA1UEBhMCVVMxHjAc
# BgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEyMDAGA1UEAxMpTWljcm9zb2Z0
# IFB1YmxpYyBSU0EgVGltZXN0YW1waW5nIENBIDIwMjAwggIiMA0GCSqGSIb3DQEB
# AQUAA4ICDwAwggIKAoICAQCefOdSY/3gxZ8FfWO1BiKjHB7X55cz0RMFvWVGR3eR
# wV1wb3+yq0OXDEqhUhxqoNv6iYWKjkMcLhEFxvJAeNcLAyT+XdM5i2CgGPGcb95W
# JLiw7HzLiBKrxmDj1EQB/mG5eEiRBEp7dDGzxKCnTYocDOcRr9KxqHydajmEkzXH
# OeRGwU+7qt8Md5l4bVZrXAhK+WSk5CihNQsWbzT1nRliVDwunuLkX1hyIWXIArCf
# rKM3+RHh+Sq5RZ8aYyik2r8HxT+l2hmRllBvE2Wok6IEaAJanHr24qoqFM9WLeBU
# Sudz+qL51HwDYyIDPSQ3SeHtKog0ZubDk4hELQSxnfVYXdTGncaBnB60QrEuazvc
# ob9n4yR65pUNBCF5qeA4QwYnilBkfnmeAjRN3LVuLr0g0FXkqfYdUmj1fFFhH8k8
# YBozrEaXnsSL3kdTD01X+4LfIWOuFzTzuoslBrBILfHNj8RfOxPgjuwNvE6YzauX
# i4orp4Sm6tF245DaFOSYbWFK5ZgG6cUY2/bUq3g3bQAqZt65KcaewEJ3ZyNEobv3
# 5Nf6xN6FrA6jF9447+NHvCjeWLCQZ3M8lgeCcnnhTFtyQX3XgCoc6IRXvFOcPVrr
# 3D9RPHCMS6Ckg8wggTrtIVnY8yjbvGOUsAdZbeXUIQAWMs0d3cRDv09SvwVRd61e
# vQIDAQABo4ICGzCCAhcwDgYDVR0PAQH/BAQDAgGGMBAGCSsGAQQBgjcVAQQDAgEA
# MB0GA1UdDgQWBBRraSg6NS9IY0DPe9ivSek+2T3bITBUBgNVHSAETTBLMEkGBFUd
# IAAwQTA/BggrBgEFBQcCARYzaHR0cDovL3d3dy5taWNyb3NvZnQuY29tL3BraW9w
# cy9Eb2NzL1JlcG9zaXRvcnkuaHRtMBMGA1UdJQQMMAoGCCsGAQUFBwMIMBkGCSsG
# AQQBgjcUAgQMHgoAUwB1AGIAQwBBMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgw
# FoAUyH7SaoUqG8oZmAQHJ89QEE9oqKIwgYQGA1UdHwR9MHsweaB3oHWGc2h0dHA6
# Ly93d3cubWljcm9zb2Z0LmNvbS9wa2lvcHMvY3JsL01pY3Jvc29mdCUyMElkZW50
# aXR5JTIwVmVyaWZpY2F0aW9uJTIwUm9vdCUyMENlcnRpZmljYXRlJTIwQXV0aG9y
# aXR5JTIwMjAyMC5jcmwwgZQGCCsGAQUFBwEBBIGHMIGEMIGBBggrBgEFBQcwAoZ1
# aHR0cDovL3d3dy5taWNyb3NvZnQuY29tL3BraW9wcy9jZXJ0cy9NaWNyb3NvZnQl
# MjBJZGVudGl0eSUyMFZlcmlmaWNhdGlvbiUyMFJvb3QlMjBDZXJ0aWZpY2F0ZSUy
# MEF1dGhvcml0eSUyMDIwMjAuY3J0MA0GCSqGSIb3DQEBDAUAA4ICAQBfiHbHfm21
# WhV150x4aPpO4dhEmSUVpbixNDmv6TvuIHv1xIs174bNGO/ilWMm+Jx5boAXrJxa
# gRhHQtiFprSjMktTliL4sKZyt2i+SXncM23gRezzsoOiBhv14YSd1Klnlkzvgs29
# XNjT+c8hIfPRe9rvVCMPiH7zPZcw5nNjthDQ+zD563I1nUJ6y59TbXWsuyUsqw7w
# XZoGzZwijWT5oc6GvD3HDokJY401uhnj3ubBhbkR83RbfMvmzdp3he2bvIUztSOu
# FzRqrLfEvsPkVHYnvH1wtYyrt5vShiKheGpXa2AWpsod4OJyT4/y0dggWi8g/tgb
# hmQlZqDUf3UqUQsZaLdIu/XSjgoZqDjamzCPJtOLi2hBwL+KsCh0Nbwc21f5xvPS
# wym0Ukr4o5sCcMUcSy6TEP7uMV8RX0eH/4JLEpGyae6Ki8JYg5v4fsNGif1OXHJ2
# IWG+7zyjTDfkmQ1snFOTgyEX8qBpefQbF0fx6URrYiarjmBprwP6ZObwtZXJ23jK
# 3Fg/9uqM3j0P01nzVygTppBabzxPAh/hHhhls6kwo3QLJ6No803jUsZcd4JQxiYH
# Hc+Q/wAMcPUnYKv/q2O444LO1+n6j01z5mggCSlRwD9faBIySAcA9S8h22hIAcRQ
# qIGEjolCK9F6nK9ZyX4lhthsGHumaABdWzCCB58wggWHoAMCAQICEzMAAABZfNpx
# 6Y1e9cAAAAAAAFkwDQYJKoZIhvcNAQEMBQAwYTELMAkGA1UEBhMCVVMxHjAcBgNV
# BAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEyMDAGA1UEAxMpTWljcm9zb2Z0IFB1
# YmxpYyBSU0EgVGltZXN0YW1waW5nIENBIDIwMjAwHhcNMjYwMTA4MTg1OTAxWhcN
# MjcwMTA3MTg1OTAxWjCB4zELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0
# b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3Jh
# dGlvbjEtMCsGA1UECxMkTWljcm9zb2Z0IElyZWxhbmQgT3BlcmF0aW9ucyBMaW1p
# dGVkMScwJQYDVQQLEx5uU2hpZWxkIFRTUyBFU046N0IxQS0wNUUwLUQ5NDcxNTAz
# BgNVBAMTLE1pY3Jvc29mdCBQdWJsaWMgUlNBIFRpbWUgU3RhbXBpbmcgQXV0aG9y
# aXR5MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEApi7n/jR4Rf6FP7mM
# VrXjpuJ3d0Dguddie2+Q/cIbDgsYBEWGe8sxIn9W2y5vMNp4WebvJvYpIzvRaYdC
# mt0JWqm9QfuXS4HiM3Du6sugBH2QocsTRWUyUNK0NLFQEjerCx2uO92a9XST73+e
# O4MSJKXMlN/sOjB3Urds7ht5HJoWFH5jy3KYQI6qU4B99isbbBl1UznX5BIFJ748
# TKSvwLo6eepKKm4Xx9m8Jvr+G6TRmbpnCxqLFIcgBPYgQa9LtzrcibyNXdrxHQrq
# LbKLDQ02WdNKnDL9l+/uLCwsHCF9uMFOf5c6XqY/MNdBDdX5JE/3FdsYo6wFPHMa
# J3tooAfDejgCGX1QZYsf2Q0/dVSiQToliSOV+m5QZnqBDKoN7B/EPhWhgiWim3gd
# nTFC+pqO4nH5yvwtH8hnnqAsubDIzN17n6+2MGiKWvL+BJnBUbCCS+QiCko8FAca
# xIHTLezOvtjvARvq/TJlqXVdS9aefPeKdNpJawIWss9XBWZfLedxjn93blWk6SG3
# 6br3sZY1u+w06EA4dFp+0T2P+GGSgzpGzIl8EueGoxwD/Bxq9/miPk17JFB0Zl4s
# pyWz1ywpLewFTM+J3HHaKI0f0I9oOr9sskQ5dqxiiFcydGKe759STzWzxU7sNBIX
# p9+fmipIehXyV/UDHq76R1KFvwECAwEAAaOCAcswggHHMB0GA1UdDgQWBBSPlucL
# XwPS+WdJGEI6I4MYa5c2djAfBgNVHSMEGDAWgBRraSg6NS9IY0DPe9ivSek+2T3b
# ITBsBgNVHR8EZTBjMGGgX6BdhltodHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtp
# b3BzL2NybC9NaWNyb3NvZnQlMjBQdWJsaWMlMjBSU0ElMjBUaW1lc3RhbXBpbmcl
# MjBDQSUyMDIwMjAuY3JsMHkGCCsGAQUFBwEBBG0wazBpBggrBgEFBQcwAoZdaHR0
# cDovL3d3dy5taWNyb3NvZnQuY29tL3BraW9wcy9jZXJ0cy9NaWNyb3NvZnQlMjBQ
# dWJsaWMlMjBSU0ElMjBUaW1lc3RhbXBpbmclMjBDQSUyMDIwMjAuY3J0MAwGA1Ud
# EwEB/wQCMAAwFgYDVR0lAQH/BAwwCgYIKwYBBQUHAwgwDgYDVR0PAQH/BAQDAgeA
# MGYGA1UdIARfMF0wUQYMKwYBBAGCN0yDfQEBMEEwPwYIKwYBBQUHAgEWM2h0dHA6
# Ly93d3cubWljcm9zb2Z0LmNvbS9wa2lvcHMvRG9jcy9SZXBvc2l0b3J5Lmh0bTAI
# BgZngQwBBAIwDQYJKoZIhvcNAQEMBQADggIBAEQyHML9lyOkb/NRETvPZinm+tTF
# SOwTldre3/ZEa8RLC9uayTdsseFIUBqOCjZdDzGgYM/exSEoIs94gJJuRW/pXyxK
# nx8nwmizrKtrB/ZhWKzy1xX447tT1LokY9DOmY+dx/NBzid7V+pnj4eIppsgMSgV
# 111BPYSCST1/PEJj8RnnZq8nbt1J+sj8gObKf1XXQ7eJCmDYX4L281OuTudWCgOg
# dr35DelivQgcadKa3mKuAZPjfrOjladc/wXEyGzAfVqLKJJmJXOGivXQL0LnZw/c
# Lz88SgwpRey0uOg87RMyR5b/UWvXzopcPjlBGAGjTEiaC1ZN3NYWeUP6nv6IMEi5
# Ks1xFcNFi6r9phloOFZIjRJh08hZWHle9e5YDfVryhDRI76g9rc2TzSTTzrjCKLI
# nUqxtKdpp5+D2+yl6CGuljyWMLDF8JS3HkdBE2AAk4jwgoAIrh3TXgyTSGVE7SVB
# VEd6CoiDb0rpeqRzfrRbZkkZRyy2UqiSRWPooAeMbKstE/N6lh+JlQmriBfLFum8
# pvVcnYU3brzZpSg1ej1HJErVyHR/rqTr7KPzyTO+4Lv68la00Oz9SkgzoeGbSRTr
# glQnswwRBwBzuSl+3sabth5Er6gqCpSBhcJ+bNtfyclclmc9rwANZWwiqy40DEIj
# QJleRQuh+qjkF7rPMYID1DCCA9ACAQEweDBhMQswCQYDVQQGEwJVUzEeMBwGA1UE
# ChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTIwMAYDVQQDEylNaWNyb3NvZnQgUHVi
# bGljIFJTQSBUaW1lc3RhbXBpbmcgQ0EgMjAyMAITMwAAAFl82nHpjV71wAAAAAAA
# WTANBglghkgBZQMEAgEFAKCCAS0wGgYJKoZIhvcNAQkDMQ0GCyqGSIb3DQEJEAEE
# MC8GCSqGSIb3DQEJBDEiBCCxDIpL5dNTRl2FIjWHW8pJJQA8GmHDHwKjaYaKCh8D
# eDCB3QYLKoZIhvcNAQkQAi8xgc0wgcowgccwgaAEIMtFurHbhumxxcQn4eOP3Gtx
# RXDtHw7LIx9IHZgYrf68MHwwZaRjMGExCzAJBgNVBAYTAlVTMR4wHAYDVQQKExVN
# aWNyb3NvZnQgQ29ycG9yYXRpb24xMjAwBgNVBAMTKU1pY3Jvc29mdCBQdWJsaWMg
# UlNBIFRpbWVzdGFtcGluZyBDQSAyMDIwAhMzAAAAWXzacemNXvXAAAAAAABZMCIE
# ICtQUS0lVj07o/+X83rAbXSBjwakSvfbptaJ6Cappy04MA0GCSqGSIb3DQEBCwUA
# BIICACdP1mfV+PwIZ82YLzCT1PBeQHNlEHHaRrjueI95PsWMLC0VuN2bs/nlaNek
# JfmwXdckA+nIpHcWrIvk8yV5oGG3ZJ+svBnFdnkXs7wzDDDFLA3C6R84YdP0R9rI
# WnICDZbVovaoUSoHIpkD3V0sZdO0zOlDIIbyvaoj0KxoPaqoNi5w8lpmhu0+T9bN
# ATgqPBk0Fe9UNWe3N2YjrImsFq0PQm7ABb7b6MjqcgiBIdmoStK404ns8MEZhFb5
# 6OC1K9Aw6UKiOhryfX4nBV6hV1+9NQ+wQWUUfBtSZuteiDo79D1aVy7t6Wi1VTqK
# /7LnSR+LZLwP2D66/tuyGMkDW7jizbG88Hvbjhsx0jYg3lZR8lQ7L9A+EvOiPG8E
# S+H/P+EhLQZ1Bjs/NiBT4CEV9vBXWgO2Ornyd2uCWHHEZau9XE/moquj5FfYk/jk
# 3OcZCxQX/vTFgFtwaTEuYwwWqbmR4IX/eueOZQpsjpIbI79Dtg0/jIHqSckWe5dn
# W82ZOLd9tOea51iyCvRSyxpmGnwF/lJNYsf/GLz61QZRuadTLJqLIWSAzgAnz742
# Zo3gzTdDkr8zE+teWEvs80/5KnjZbcvWVGMo8LGv/XAq2zaD9uvPpkeBOPdoWtBs
# wsSXMQrarhAd22bTjq8hTUAceb78zKDTAzyFyaTJrh43HRTt
# SIG # End signature block
