Public/Add-LnvSUCommandLine.ps1

<#
  .SYNOPSIS
  Configure System Update AdminCommandLine
 
  .DESCRIPTION
  Run Script to set Admin command line Windows Registry settings for Lenovo System Update
 
  .PARAMETER Search
  Mandatory: True
  Data type: String
  Must be one of the following values [C, R, A]
 
  .PARAMETER Action
  Mandatory: True
  Data type: String
  Must be one of the following values [DOWNLOAD, INSTALL, LIST]
 
  .PARAMETER IncludereBootPackages
  Mandatory : False
  Data type: String
  Must be one of the following values [1, 3, 4, 5], or multiple values separated with a comma.
  1 = Update itself will force a reboot
  3 = Requires a reboot
  4 = Update itself will shut down the system after install
  5 = Within a 5 minute delay after installing one or more of these updates, will force a reboot
 
  .PARAMETER PackageTypes
  Mandatory : False
  Data type: String
  Must be one of the following values [0, 1, 2, 3, 4], or multiple values separated with a comma
  0 = Other
  1 = Application
  2 = Driver
  3 = BIOS
  4 = Firmware
 
  .PARAMETER NoReboot
  Mandatory : False
  Data type: Switch
  In normal operation, if System Update installs one or more Reboot Type 3 (Requires reboot)
  updates, it will initiate a reboot after the last installation completes. To suppress this
  reboot simply specify this parameter. This parameter only has an effect for Reboot Type 3
  packages. For Reboot Type 1 and 4, the reboot or shutdown is orchestrated by the update
  itself and is not under the control of System Update. For Reboot Type 5 packages a reboot
  must be executed immediately after the update and is forced by System Update.
 
  .PARAMETER NoIcon
  Mandatory : False
  Data type: Switch
  Suppresses the balloon tooltip from the notification area of the system tray.
 
  .PARAMETER RebootPrompt
  Mandatory : False
  Data type: Switch
  Forces the display of the reboot prompt dialog after installing updates
  that will require a restart. This parameter is only applicable when the -noicon
  parameter is used and the -noreboot parameter is NOT used. In this scenario,
  if the -rebootprompt parameter were not used, the system could be rebooted without
  any warning to the user.
 
  .PARAMETER Repository
  Mandatory : False
  Data type: String
  Must be a local folder path, a UNC file share path, or a URL to a web-hosted repository.
  If not specified, System Update will use the Lenovo Support servers.
 
  .PARAMETER ExportToWmi
  Mandatory : False
  Data type: Switch
  Causes System Update to store update history data in a WMI table:
  Root\Lenovo\Lenovo_Updates\
 
 
  .INPUTS
 
  .OUTPUTS
 
  .NOTES
  Read messages to determine the result of the script working.
#>

function Add-LnvSUCommandLine {
  param (
    [Parameter(Mandatory = $True)]
    [ValidateSet("C","R","A")]
    [string]$Search,

    [Parameter(Mandatory = $True)]
    [ValidateSet("DOWNLOAD","INSTALL","LIST")]
    [string]$Action,

    [Parameter(Mandatory = $False)]
    [string]$IncludeRebootPackages,

    [Parameter(Mandatory = $False)]
    [string]$PackageTypes,

    [Parameter(Mandatory = $False)]
    [switch]$NoReboot,

    [Parameter(Mandatory = $False)]
    [switch]$NoIcon,

    [Parameter(Mandatory = $False)]
    [switch]$RebootPrompt,

    [Parameter(Mandatory = $False)]
    [string]$Repository,

    [Parameter(Mandatory = $False)]
    [switch]$ExportToWmi
  )

  #region Common script block

  class RegistryEntry {
    [string]$Key
    [string]$Name
    [string]$ValueType
    [SimpleValue[]]$Value

    RegistryEntry(
      [string]$key,
      [string]$name,
      [string]$valueType,
      [SimpleValue[]]$value
    ) {
      $this.Key = $key
      $this.Name = $name
      $this.ValueType = $valueType
      $this.Value = $value
    }

    [String] ToString() {
      return $this.Key + " " + $this.Name
    }
  }

  class SimpleValue {
    [string]$Value

    SimpleValue(
      [string]$value
    ) {
      $this.Value = $value
    }

    [String] ToString() {
      return $this.Value
    }
  }

  class ParameterValue:SimpleValue {
    [string]$ParameterName

    ParameterValue(
      [string]$value,
      [string]$parameterName
    ):base($value) {
      $this.ParameterName = $parameterName
    }

    [String] ToString() {
      if ($this.Value) {
        return $this.ParameterName + " " + $this.Value
      }
      else {
        return $null
      }
    }
  }

  #endregion

  #region Parameters validation
  function Confirm-ParameterStringSet {
    [CmdletBinding()]
    param(
      [Parameter(Mandatory = $True)]
      [string[]]$AllowedValues,
      [Parameter(Mandatory = $True)]
      [AllowEmptyString()]
      [string]$Value,
      [Parameter(Mandatory = $True)]
      [string]$ErrorMessage
    )

    if ($Value) {
      $result = $AllowedValues.Contains($Value)

      if ($result -ne $True) {
        Write-LogError $ErrorMessage

        return
      }
    }
  }

  function Confirm-ParameterPattern {
    [CmdletBinding()]
    param(
      [Parameter(Mandatory = $True)]
      [string]$RegEx,
      [Parameter(Mandatory = $False)]
      [AllowEmptyString()]
      [string]$Value,
      [Parameter(Mandatory = $False)]
      [string]$ErrorMessage
    )

    if ($Value) {
      $result = $Value -match $RegEx

      if ($result -ne $True) {
        Write-LogError $ErrorMessage

        return
      }
    }
  }
  #endregion

  #region Registry
  function Add-RegistryEntry {
    [CmdletBinding()]
    param(
      [Parameter(Mandatory = $True)]
      [RegistryEntry]$RegistryEntry
    )

    $resultValues = @()

    foreach ($registryValue in $RegistryEntry.Value) {
      $tempValue = $registryValue.ToString()
      if ($tempValue) {
        $resultValues += $tempValue
      }
    }

    $valueString = $resultValues -join " "

    try {
      $keyExists = Confirm-RegistryKey -Key $RegistryEntry.Key
      if ($keyExists -ne $True) {
        New-Item $RegistryEntry.Key -Force -ErrorAction Stop | New-ItemProperty -Name $RegistryEntry.Name -Value $valueString -PropertyType $RegistryEntry.ValueType -Force -ErrorAction Stop | Out-Null
      }
      else {
        $registryKey = Get-Item $RegistryEntry.Key -ErrorAction Stop
        $registryKey | New-ItemProperty -Name $RegistryEntry.Name -Value $valueString -PropertyType $RegistryEntry.ValueType -Force -ErrorAction Stop | Out-Null
      }
    }
    catch {
      Write-LogError "An error occured while adding the $($RegistryEntry.Name) registryEntry:`n $_"
      return
    }
  }

  function Confirm-RegistryKey {
    [CmdletBinding()]
    param(
      [Parameter(Mandatory = $True)]
      [string]$Key
    )
    if (Get-Item $Key  -ErrorAction SilentlyContinue ) {
      return $True
    }
    else {
      return $False
    }
  }
  #endregion

  #region Messages
  function Write-LogError {
    Param(
      [Parameter(Mandatory = $True)]
      [string]$Message
    )

    Write-Output -InputObject ("[LDMM_ERROR_$((Get-Date).ToString("yyyy-MM-ddTHH:mm:ss"))]: $Message")
  }

  function Write-LogInformation {
    Param(
      [Parameter(Mandatory = $True)]
      [string]$Message
    )

    Write-Output -InputObject ("[LDMM_INFORMATION_$((Get-Date).ToString("yyyy-MM-ddTHH:mm:ss"))]: $Message")
  }
  #endregion

  function Test-ApplicationPath {
    [CmdletBinding()]
    param(
      [Parameter(Mandatory = $True)]
      [string]$Appx64Path,

      [Parameter(Mandatory = $True)]
      [string]$Appx86Path
    )

    $x64AppExists = Test-Path -Path $Appx64Path
    $x86AppExists = Test-Path -Path $Appx86Path

    if ($x64AppExists -ne $True -and $x86AppExists -ne $True) {
      return $False
    }

    return $True;
  }
  #endregion

  #region Custom script block
  function Confirm-Parameter{
    Confirm-ParameterStringSet -AllowedValues @('C', 'R', 'A') -Value $Search -ErrorMessage " Search param must be one of the following values [C, R, A]"
    Confirm-ParameterStringSet -AllowedValues @('DOWNLOAD', 'LIST', 'INSTALL') -Value $Action -ErrorMessage "Action param must be one of the following values [DOWNLOAD, LIST, INSTALL]"
    Confirm-ParameterPattern   -RegEx '^(1|3|4|5)?(?: *, *(1|3|4|5))*$' -Value $IncludeRebootPackages -ErrorMessage "IncludereBootPackages param must be one of the following values [1, 3, 4, 5], or multiple values separated with a comma"
    Confirm-ParameterPattern -RegEx '^[1-4](,[1-4])*$' -Value $PackageTypes -ErrorMessage "PackageTypes param must be one of the following values [0, 1, 2, 3, 4], or multiple values separated with a comma"
    Confirm-ParameterPattern -RegEx "^((?:~?\/)|(?:(?:\\\\\?\\)?[a-zA-Z]+\:))(?:\/?(.*))?$|\\\\[a-zA-Z0-9\.\-_]{1,}(\\[a-zA-Z0-9\-_]{1,}){1,}[\$]{0,1}|(http:\/\/www\.|https:\/\/www\.|http:\/\/|https:\/\/)?[a-z0-9]+([\-\.]{1}[a-z0-9]+)*\.[a-z]{2,5}(:[0-9]{1,5})?(\/.*)?$" -Value $Repository -ErrorMessage "Repository param must be a local folder path, a UNC file share path, or a URL to a web-hosted repository"
  }

  Write-LogInformation "Script execution started."

  try {
    Confirm-Parameter

    $x64AppPath = Join-Path -Path $Env:Programfiles -ChildPath "Lenovo\System Update\tvsu.exe"
    $x86AppPath = Join-Path -Path ${Env:Programfiles(x86)} -ChildPath "Lenovo\System Update\tvsu.exe"

    $appPath = Test-ApplicationPath -Appx64Path $x64AppPath -Appx86Path $x86AppPath

    if (!$appPath) {
      Write-LogError "Lenovo System Update was not found at the default installation path."

      return
    }

    $startValue = [SimpleValue]::new('/CM')
    $searchValue = [ParameterValue]::new( $Search, '-search')
    $actionValue = [ParameterValue]::new( $Action, '-action')
    $IncludeRebootPackagesValue = [ParameterValue]::new( $IncludeRebootPackages, '-includerebootpackages')
    $packageTypesValue = [ParameterValue]::new( $PackageTypes, '-packagetypes')
    $noRebootValue = ''
    if ($NoReboot) {
      $noRebootValue = "-noreboot"
    }
    $noIconValue = ''
    if ($NoIcon) {
      $noIconValue = "-noicon"
    }

    $noLicenseValue = "-nolicense"

    $rebootPromtValue = ''
    if ($RebootPrompt) {
      $rebootPromtValue = "-rebootprompt"
    }

    $repositoryValue = [ParameterValue]::new( $Repository, '-repository')

    $exportToWmiValue = ''
    if ($ExportToWmi) {
      $exportToWmiValue = "-exporttowmi"
    }

    $registryEntry = [RegistryEntry]::new(
      'HKLM:\SOFTWARE\Policies\Lenovo\System Update\UserSettings\General',
      'AdminCommandLine',
      'String',
      @($startValue,
        $searchValue,
        $actionValue,
        $IncludeRebootPackagesValue,
        $packageTypesValue,
        $noRebootValue,
        $noIconValue,
        $noLicenseValue,
        $rebootPromtValue,
        $repositoryValue,
        $exportToWmiValue))

    Add-RegistryEntry $registryEntry

    Write-LogInformation "Script execution finished."
  }
  catch {
    Write-LogError "Unexpected error occurred:`n $_"

    return
  }
}
#endregion
# SIG # Begin signature block
# MIItugYJKoZIhvcNAQcCoIItqzCCLacCAQExCzAJBgUrDgMCGgUAMGkGCisGAQQB
# gjcCAQSgWzBZMDQGCisGAQQBgjcCAR4wJgIDAQAABBAfzDtgWUsITrck0sYpfvNR
# AgEAAgEAAgEAAgEAAgEAMCEwCQYFKw4DAhoFAAQUwJKTDe3cg05MYdiZVyEU5oL2
# FhaggibcMIIFjTCCBHWgAwIBAgIQDpsYjvnQLefv21DiCEAYWjANBgkqhkiG9w0B
# AQwFADBlMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYD
# VQQLExB3d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVk
# IElEIFJvb3QgQ0EwHhcNMjIwODAxMDAwMDAwWhcNMzExMTA5MjM1OTU5WjBiMQsw
# CQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cu
# ZGlnaWNlcnQuY29tMSEwHwYDVQQDExhEaWdpQ2VydCBUcnVzdGVkIFJvb3QgRzQw
# ggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC/5pBzaN675F1KPDAiMGkz
# 7MKnJS7JIT3yithZwuEppz1Yq3aaza57G4QNxDAf8xukOBbrVsaXbR2rsnnyyhHS
# 5F/WBTxSD1Ifxp4VpX6+n6lXFllVcq9ok3DCsrp1mWpzMpTREEQQLt+C8weE5nQ7
# bXHiLQwb7iDVySAdYyktzuxeTsiT+CFhmzTrBcZe7FsavOvJz82sNEBfsXpm7nfI
# SKhmV1efVFiODCu3T6cw2Vbuyntd463JT17lNecxy9qTXtyOj4DatpGYQJB5w3jH
# trHEtWoYOAMQjdjUN6QuBX2I9YI+EJFwq1WCQTLX2wRzKm6RAXwhTNS8rhsDdV14
# Ztk6MUSaM0C/CNdaSaTC5qmgZ92kJ7yhTzm1EVgX9yRcRo9k98FpiHaYdj1ZXUJ2
# h4mXaXpI8OCiEhtmmnTK3kse5w5jrubU75KSOp493ADkRSWJtppEGSt+wJS00mFt
# 6zPZxd9LBADMfRyVw4/3IbKyEbe7f/LVjHAsQWCqsWMYRJUadmJ+9oCw++hkpjPR
# iQfhvbfmQ6QYuKZ3AeEPlAwhHbJUKSWJbOUOUlFHdL4mrLZBdd56rF+NP8m800ER
# ElvlEFDrMcXKchYiCd98THU/Y+whX8QgUWtvsauGi0/C1kVfnSD8oR7FwI+isX4K
# Jpn15GkvmB0t9dmpsh3lGwIDAQABo4IBOjCCATYwDwYDVR0TAQH/BAUwAwEB/zAd
# BgNVHQ4EFgQU7NfjgtJxXWRM3y5nP+e6mK4cD08wHwYDVR0jBBgwFoAUReuir/SS
# y4IxLVGLp6chnfNtyA8wDgYDVR0PAQH/BAQDAgGGMHkGCCsGAQUFBwEBBG0wazAk
# BggrBgEFBQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQuY29tMEMGCCsGAQUFBzAC
# hjdodHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vRGlnaUNlcnRBc3N1cmVkSURS
# b290Q0EuY3J0MEUGA1UdHwQ+MDwwOqA4oDaGNGh0dHA6Ly9jcmwzLmRpZ2ljZXJ0
# LmNvbS9EaWdpQ2VydEFzc3VyZWRJRFJvb3RDQS5jcmwwEQYDVR0gBAowCDAGBgRV
# HSAAMA0GCSqGSIb3DQEBDAUAA4IBAQBwoL9DXFXnOF+go3QbPbYW1/e/Vwe9mqyh
# hyzshV6pGrsi+IcaaVQi7aSId229GhT0E0p6Ly23OO/0/4C5+KH38nLeJLxSA8hO
# 0Cre+i1Wz/n096wwepqLsl7Uz9FDRJtDIeuWcqFItJnLnU+nBgMTdydE1Od/6Fmo
# 8L8vC6bp8jQ87PcDx4eo0kxAGTVGamlUsLihVo7spNU96LHc/RzY9HdaXFSMb++h
# UD38dglohJ9vytsgjTVgHAIDyyCwrFigDkBjxZgiwbJZ9VVrzyerbHbObyMt9H5x
# aiNrIv8SuFQtJ37YOtnwtoeW/VvRXKwYw02fc7cBqZ9Xql4o4rmUMIIFkDCCA3ig
# AwIBAgIQBZsbV56OITLiOQe9p3d1XDANBgkqhkiG9w0BAQwFADBiMQswCQYDVQQG
# EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNl
# cnQuY29tMSEwHwYDVQQDExhEaWdpQ2VydCBUcnVzdGVkIFJvb3QgRzQwHhcNMTMw
# ODAxMTIwMDAwWhcNMzgwMTE1MTIwMDAwWjBiMQswCQYDVQQGEwJVUzEVMBMGA1UE
# ChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSEwHwYD
# VQQDExhEaWdpQ2VydCBUcnVzdGVkIFJvb3QgRzQwggIiMA0GCSqGSIb3DQEBAQUA
# A4ICDwAwggIKAoICAQC/5pBzaN675F1KPDAiMGkz7MKnJS7JIT3yithZwuEppz1Y
# q3aaza57G4QNxDAf8xukOBbrVsaXbR2rsnnyyhHS5F/WBTxSD1Ifxp4VpX6+n6lX
# FllVcq9ok3DCsrp1mWpzMpTREEQQLt+C8weE5nQ7bXHiLQwb7iDVySAdYyktzuxe
# TsiT+CFhmzTrBcZe7FsavOvJz82sNEBfsXpm7nfISKhmV1efVFiODCu3T6cw2Vbu
# yntd463JT17lNecxy9qTXtyOj4DatpGYQJB5w3jHtrHEtWoYOAMQjdjUN6QuBX2I
# 9YI+EJFwq1WCQTLX2wRzKm6RAXwhTNS8rhsDdV14Ztk6MUSaM0C/CNdaSaTC5qmg
# Z92kJ7yhTzm1EVgX9yRcRo9k98FpiHaYdj1ZXUJ2h4mXaXpI8OCiEhtmmnTK3kse
# 5w5jrubU75KSOp493ADkRSWJtppEGSt+wJS00mFt6zPZxd9LBADMfRyVw4/3IbKy
# Ebe7f/LVjHAsQWCqsWMYRJUadmJ+9oCw++hkpjPRiQfhvbfmQ6QYuKZ3AeEPlAwh
# HbJUKSWJbOUOUlFHdL4mrLZBdd56rF+NP8m800ERElvlEFDrMcXKchYiCd98THU/
# Y+whX8QgUWtvsauGi0/C1kVfnSD8oR7FwI+isX4KJpn15GkvmB0t9dmpsh3lGwID
# AQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4E
# FgQU7NfjgtJxXWRM3y5nP+e6mK4cD08wDQYJKoZIhvcNAQEMBQADggIBALth2X2p
# bL4XxJEbw6GiAI3jZGgPVs93rnD5/ZpKmbnJeFwMDF/k5hQpVgs2SV1EY+CtnJYY
# ZhsjDT156W1r1lT40jzBQ0CuHVD1UvyQO7uYmWlrx8GnqGikJ9yd+SeuMIW59mdN
# Oj6PWTkiU0TryF0Dyu1Qen1iIQqAyHNm0aAFYF/opbSnr6j3bTWcfFqK1qI4mfN4
# i/RN0iAL3gTujJtHgXINwBQy7zBZLq7gcfJW5GqXb5JQbZaNaHqasjYUegbyJLkJ
# EVDXCLG4iXqEI2FCKeWjzaIgQdfRnGTZ6iahixTXTBmyUEFxPT9NcCOGDErcgdLM
# MpSEDQgJlxxPwO5rIHQw0uA5NBCFIRUBCOhVMt5xSdkoF1BN5r5N0XWs0Mr7QbhD
# parTwwVETyw2m+L64kW4I1NsBm9nVX9GtUw/bihaeSbSpKhil9Ie4u1Ki7wb/UdK
# Dd9nZn6yW0HQO+T0O/QEY+nvwlQAUaCKKsnOeMzV6ocEGLPOr0mIr/OSmbaz5mEP
# 0oUA51Aa5BuVnRmhuZyxm7EAHu/QD09CbMkKvO5D+jpxpchNJqU1/YldvIViHTLS
# oCtU7ZpXwdv6EM8Zt4tKG48BtieVU+i2iW1bvGjUI+iLUaJW+fCmgKDWHrO8Dw9T
# dSmq6hN35N6MgSGtBxBHEa2HPQfRdbzP82Z+MIIGsDCCBJigAwIBAgIQCK1AsmDS
# nEyfXs2pvZOu2TANBgkqhkiG9w0BAQwFADBiMQswCQYDVQQGEwJVUzEVMBMGA1UE
# ChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSEwHwYD
# VQQDExhEaWdpQ2VydCBUcnVzdGVkIFJvb3QgRzQwHhcNMjEwNDI5MDAwMDAwWhcN
# MzYwNDI4MjM1OTU5WjBpMQswCQYDVQQGEwJVUzEXMBUGA1UEChMORGlnaUNlcnQs
# IEluYy4xQTA/BgNVBAMTOERpZ2lDZXJ0IFRydXN0ZWQgRzQgQ29kZSBTaWduaW5n
# IFJTQTQwOTYgU0hBMzg0IDIwMjEgQ0ExMIICIjANBgkqhkiG9w0BAQEFAAOCAg8A
# MIICCgKCAgEA1bQvQtAorXi3XdU5WRuxiEL1M4zrPYGXcMW7xIUmMJ+kjmjYXPXr
# NCQH4UtP03hD9BfXHtr50tVnGlJPDqFX/IiZwZHMgQM+TXAkZLON4gh9NH1MgFcS
# a0OamfLFOx/y78tHWhOmTLMBICXzENOLsvsI8IrgnQnAZaf6mIBJNYc9URnokCF4
# RS6hnyzhGMIazMXuk0lwQjKP+8bqHPNlaJGiTUyCEUhSaN4QvRRXXegYE2XFf7JP
# hSxIpFaENdb5LpyqABXRN/4aBpTCfMjqGzLmysL0p6MDDnSlrzm2q2AS4+jWufcx
# 4dyt5Big2MEjR0ezoQ9uo6ttmAaDG7dqZy3SvUQakhCBj7A7CdfHmzJawv9qYFSL
# ScGT7eG0XOBv6yb5jNWy+TgQ5urOkfW+0/tvk2E0XLyTRSiDNipmKF+wc86LJiUG
# soPUXPYVGUztYuBeM/Lo6OwKp7ADK5GyNnm+960IHnWmZcy740hQ83eRGv7bUKJG
# yGFYmPV8AhY8gyitOYbs1LcNU9D4R+Z1MI3sMJN2FKZbS110YU0/EpF23r9Yy3IQ
# KUHw1cVtJnZoEUETWJrcJisB9IlNWdt4z4FKPkBHX8mBUHOFECMhWWCKZFTBzCEa
# 6DgZfGYczXg4RTCZT/9jT0y7qg0IU0F8WD1Hs/q27IwyCQLMbDwMVhECAwEAAaOC
# AVkwggFVMBIGA1UdEwEB/wQIMAYBAf8CAQAwHQYDVR0OBBYEFGg34Ou2O/hfEYb7
# /mF7CIhl9E5CMB8GA1UdIwQYMBaAFOzX44LScV1kTN8uZz/nupiuHA9PMA4GA1Ud
# DwEB/wQEAwIBhjATBgNVHSUEDDAKBggrBgEFBQcDAzB3BggrBgEFBQcBAQRrMGkw
# JAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBBBggrBgEFBQcw
# AoY1aHR0cDovL2NhY2VydHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0VHJ1c3RlZFJv
# b3RHNC5jcnQwQwYDVR0fBDwwOjA4oDagNIYyaHR0cDovL2NybDMuZGlnaWNlcnQu
# Y29tL0RpZ2lDZXJ0VHJ1c3RlZFJvb3RHNC5jcmwwHAYDVR0gBBUwEzAHBgVngQwB
# AzAIBgZngQwBBAEwDQYJKoZIhvcNAQEMBQADggIBADojRD2NCHbuj7w6mdNW4AIa
# pfhINPMstuZ0ZveUcrEAyq9sMCcTEp6QRJ9L/Z6jfCbVN7w6XUhtldU/SfQnuxaB
# RVD9nL22heB2fjdxyyL3WqqQz/WTauPrINHVUHmImoqKwba9oUgYftzYgBoRGRjN
# YZmBVvbJ43bnxOQbX0P4PpT/djk9ntSZz0rdKOtfJqGVWEjVGv7XJz/9kNF2ht0c
# sGBc8w2o7uCJob054ThO2m67Np375SFTWsPK6Wrxoj7bQ7gzyE84FJKZ9d3OVG3Z
# XQIUH0AzfAPilbLCIXVzUstG2MQ0HKKlS43Nb3Y3LIU/Gs4m6Ri+kAewQ3+ViCCC
# cPDMyu/9KTVcH4k4Vfc3iosJocsL6TEa/y4ZXDlx4b6cpwoG1iZnt5LmTl/eeqxJ
# zy6kdJKt2zyknIYf48FWGysj/4+16oh7cGvmoLr9Oj9FpsToFpFSi0HASIRLlk2r
# REDjjfAVKM7t8RhWByovEMQMCGQ8M4+uKIw8y4+ICw2/O/TOHnuO77Xry7fwdxPm
# 5yg/rBKupS8ibEH5glwVZsxsDsrFhsP2JjMMB0ug0wcCampAMEhLNKhRILutG4UI
# 4lkNbcoFUCvqShyepf2gpx8GdOfy1lKQ/a+FSCH5Vzu0nAPthkX0tGFuv2jiJmCG
# 6sivqf6UHedjGzqGVnhOMIIGtDCCBJygAwIBAgIQDcesVwX/IZkuQEMiDDpJhjAN
# BgkqhkiG9w0BAQsFADBiMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQg
# SW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSEwHwYDVQQDExhEaWdpQ2Vy
# dCBUcnVzdGVkIFJvb3QgRzQwHhcNMjUwNTA3MDAwMDAwWhcNMzgwMTE0MjM1OTU5
# WjBpMQswCQYDVQQGEwJVUzEXMBUGA1UEChMORGlnaUNlcnQsIEluYy4xQTA/BgNV
# BAMTOERpZ2lDZXJ0IFRydXN0ZWQgRzQgVGltZVN0YW1waW5nIFJTQTQwOTYgU0hB
# MjU2IDIwMjUgQ0ExMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAtHgx
# 0wqYQXK+PEbAHKx126NGaHS0URedTa2NDZS1mZaDLFTtQ2oRjzUXMmxCqvkbsDpz
# 4aH+qbxeLho8I6jY3xL1IusLopuW2qftJYJaDNs1+JH7Z+QdSKWM06qchUP+AbdJ
# gMQB3h2DZ0Mal5kYp77jYMVQXSZH++0trj6Ao+xh/AS7sQRuQL37QXbDhAktVJMQ
# bzIBHYJBYgzWIjk8eDrYhXDEpKk7RdoX0M980EpLtlrNyHw0Xm+nt5pnYJU3Gmq6
# bNMI1I7Gb5IBZK4ivbVCiZv7PNBYqHEpNVWC2ZQ8BbfnFRQVESYOszFI2Wv82wnJ
# RfN20VRS3hpLgIR4hjzL0hpoYGk81coWJ+KdPvMvaB0WkE/2qHxJ0ucS638ZxqU1
# 4lDnki7CcoKCz6eum5A19WZQHkqUJfdkDjHkccpL6uoG8pbF0LJAQQZxst7VvwDD
# jAmSFTUms+wV/FbWBqi7fTJnjq3hj0XbQcd8hjj/q8d6ylgxCZSKi17yVp2NL+cn
# T6Toy+rN+nM8M7LnLqCrO2JP3oW//1sfuZDKiDEb1AQ8es9Xr/u6bDTnYCTKIsDq
# 1BtmXUqEG1NqzJKS4kOmxkYp2WyODi7vQTCBZtVFJfVZ3j7OgWmnhFr4yUozZtqg
# PrHRVHhGNKlYzyjlroPxul+bgIspzOwbtmsgY1MCAwEAAaOCAV0wggFZMBIGA1Ud
# EwEB/wQIMAYBAf8CAQAwHQYDVR0OBBYEFO9vU0rp5AZ8esrikFb2L9RJ7MtOMB8G
# A1UdIwQYMBaAFOzX44LScV1kTN8uZz/nupiuHA9PMA4GA1UdDwEB/wQEAwIBhjAT
# BgNVHSUEDDAKBggrBgEFBQcDCDB3BggrBgEFBQcBAQRrMGkwJAYIKwYBBQUHMAGG
# GGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBBBggrBgEFBQcwAoY1aHR0cDovL2Nh
# Y2VydHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0VHJ1c3RlZFJvb3RHNC5jcnQwQwYD
# VR0fBDwwOjA4oDagNIYyaHR0cDovL2NybDMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0
# VHJ1c3RlZFJvb3RHNC5jcmwwIAYDVR0gBBkwFzAIBgZngQwBBAIwCwYJYIZIAYb9
# bAcBMA0GCSqGSIb3DQEBCwUAA4ICAQAXzvsWgBz+Bz0RdnEwvb4LyLU0pn/N0IfF
# iBowf0/Dm1wGc/Do7oVMY2mhXZXjDNJQa8j00DNqhCT3t+s8G0iP5kvN2n7Jd2E4
# /iEIUBO41P5F448rSYJ59Ib61eoalhnd6ywFLerycvZTAz40y8S4F3/a+Z1jEMK/
# DMm/axFSgoR8n6c3nuZB9BfBwAQYK9FHaoq2e26MHvVY9gCDA/JYsq7pGdogP8HR
# trYfctSLANEBfHU16r3J05qX3kId+ZOczgj5kjatVB+NdADVZKON/gnZruMvNYY2
# o1f4MXRJDMdTSlOLh0HCn2cQLwQCqjFbqrXuvTPSegOOzr4EWj7PtspIHBldNE2K
# 9i697cvaiIo2p61Ed2p8xMJb82Yosn0z4y25xUbI7GIN/TpVfHIqQ6Ku/qjTY6hc
# 3hsXMrS+U0yy+GWqAXam4ToWd2UQ1KYT70kZjE4YtL8Pbzg0c1ugMZyZZd/BdHLi
# Ru7hAWE6bTEm4XYRkA6Tl4KSFLFk43esaUeqGkH/wyW4N7OigizwJWeukcyIPbAv
# jSabnf7+Pu0VrFgoiovRDiyx3zEdmcif/sYQsfch28bZeUz2rtY/9TCA6TD8dC3J
# E3rYkrhLULy7Dc90G6e8BlqmyIjlgp2+VqsS9/wQD7yFylIz0scmbKvFoW2jNrbM
# 1pD2T7m3XDCCBu0wggTVoAMCAQICEAqA7xhLjfEFgtHEdqeVdGgwDQYJKoZIhvcN
# AQELBQAwaTELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDkRpZ2lDZXJ0LCBJbmMuMUEw
# PwYDVQQDEzhEaWdpQ2VydCBUcnVzdGVkIEc0IFRpbWVTdGFtcGluZyBSU0E0MDk2
# IFNIQTI1NiAyMDI1IENBMTAeFw0yNTA2MDQwMDAwMDBaFw0zNjA5MDMyMzU5NTla
# MGMxCzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5EaWdpQ2VydCwgSW5jLjE7MDkGA1UE
# AxMyRGlnaUNlcnQgU0hBMjU2IFJTQTQwOTYgVGltZXN0YW1wIFJlc3BvbmRlciAy
# MDI1IDEwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDQRqwtEsae0Oqu
# YFazK1e6b1H/hnAKAd/KN8wZQjBjMqiZ3xTWcfsLwOvRxUwXcGx8AUjni6bz52fG
# Tfr6PHRNv6T7zsf1Y/E3IU8kgNkeECqVQ+3bzWYesFtkepErvUSbf+EIYLkrLKd6
# qJnuzK8Vcn0DvbDMemQFoxQ2Dsw4vEjoT1FpS54dNApZfKY61HAldytxNM89PZXU
# P/5wWWURK+IfxiOg8W9lKMqzdIo7VA1R0V3Zp3DjjANwqAf4lEkTlCDQ0/fKJLKL
# kzGBTpx6EYevvOi7XOc4zyh1uSqgr6UnbksIcFJqLbkIXIPbcNmA98Oskkkrvt6l
# PAw/p4oDSRZreiwB7x9ykrjS6GS3NR39iTTFS+ENTqW8m6THuOmHHjQNC3zbJ6nJ
# 6SXiLSvw4Smz8U07hqF+8CTXaETkVWz0dVVZw7knh1WZXOLHgDvundrAtuvz0D3T
# +dYaNcwafsVCGZKUhQPL1naFKBy1p6llN3QgshRta6Eq4B40h5avMcpi54wm0i2e
# PZD5pPIssoszQyF4//3DoK2O65Uck5Wggn8O2klETsJ7u8xEehGifgJYi+6I03Uu
# T1j7FnrqVrOzaQoVJOeeStPeldYRNMmSF3voIgMFtNGh86w3ISHNm0IaadCKCkUe
# 2LnwJKa8TIlwCUNVwppwn4D3/Pt5pwIDAQABo4IBlTCCAZEwDAYDVR0TAQH/BAIw
# ADAdBgNVHQ4EFgQU5Dv88jHt/f3X85FxYxlQQ89hjOgwHwYDVR0jBBgwFoAU729T
# SunkBnx6yuKQVvYv1Ensy04wDgYDVR0PAQH/BAQDAgeAMBYGA1UdJQEB/wQMMAoG
# CCsGAQUFBwMIMIGVBggrBgEFBQcBAQSBiDCBhTAkBggrBgEFBQcwAYYYaHR0cDov
# L29jc3AuZGlnaWNlcnQuY29tMF0GCCsGAQUFBzAChlFodHRwOi8vY2FjZXJ0cy5k
# aWdpY2VydC5jb20vRGlnaUNlcnRUcnVzdGVkRzRUaW1lU3RhbXBpbmdSU0E0MDk2
# U0hBMjU2MjAyNUNBMS5jcnQwXwYDVR0fBFgwVjBUoFKgUIZOaHR0cDovL2NybDMu
# ZGlnaWNlcnQuY29tL0RpZ2lDZXJ0VHJ1c3RlZEc0VGltZVN0YW1waW5nUlNBNDA5
# NlNIQTI1NjIwMjVDQTEuY3JsMCAGA1UdIAQZMBcwCAYGZ4EMAQQCMAsGCWCGSAGG
# /WwHATANBgkqhkiG9w0BAQsFAAOCAgEAZSqt8RwnBLmuYEHs0QhEnmNAciH45PYi
# T9s1i6UKtW+FERp8FgXRGQ/YAavXzWjZhY+hIfP2JkQ38U+wtJPBVBajYfrbIYG+
# Dui4I4PCvHpQuPqFgqp1PzC/ZRX4pvP/ciZmUnthfAEP1HShTrY+2DE5qjzvZs7J
# IIgt0GCFD9ktx0LxxtRQ7vllKluHWiKk6FxRPyUPxAAYH2Vy1lNM4kzekd8oEARz
# FAWgeW3az2xejEWLNN4eKGxDJ8WDl/FQUSntbjZ80FU3i54tpx5F/0Kr15zW/mJA
# xZMVBrTE2oi0fcI8VMbtoRAmaaslNXdCG1+lqvP4FbrQ6IwSBXkZagHLhFU9HCrG
# /syTRLLhAezu/3Lr00GrJzPQFnCEH1Y58678IgmfORBPC1JKkYaEt2OdDh4GmO0/
# 5cHelAK2/gTlQJINqDr6JfwyYHXSd+V08X1JUPvB4ILfJdmL+66Gp3CSBXG6IwXM
# ZUXBhtCyIaehr0XkBoDIGMUG1dUtwq1qmcwbdUfcSYCn+OwncVUXf53VJUNOaMWM
# ts0VlRYxe5nK+At+DI96HAlXHAL5SlfYxJ7La54i71McVWRP66bW+yERNpbJCjyC
# YG2j+bdpxo/1Cy4uPcU3AWVPGrbn5PhDBf3Froguzzhk++ami+r3Qrx5bIbY3TVz
# giFI7Gq3zWcwggdWMIIFPqADAgECAhADMlFYfN/evhzf5XYSzZUnMA0GCSqGSIb3
# DQEBCwUAMGkxCzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5EaWdpQ2VydCwgSW5jLjFB
# MD8GA1UEAxM4RGlnaUNlcnQgVHJ1c3RlZCBHNCBDb2RlIFNpZ25pbmcgUlNBNDA5
# NiBTSEEzODQgMjAyMSBDQTEwHhcNMjUwMzIwMDAwMDAwWhcNMjYwNjAzMjM1OTU5
# WjBeMQswCQYDVQQGEwJVUzEXMBUGA1UECBMOTm9ydGggQ2Fyb2xpbmExFDASBgNV
# BAcTC01vcnJpc3ZpbGxlMQ8wDQYDVQQKEwZMZW5vdm8xDzANBgNVBAMTBkxlbm92
# bzCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAOPjJ/+Kdi4SqmdpYRYm
# 5E/ctl9H/KHwC3GK10hQmHGetCCuJkcx+STyvxLIuuzh6CIupbxzDPXQ2x2/5jA6
# 2EROThgMKl/0fV+hwvZhVl45idBUi0qo+91jYeK9kXjjLrxXEsX6A5Uu4Lgl56vr
# 8h6cGZg/te9ozF3k2JN80MIzSj/F769/ZpuGq9i4j1HQ7xq/aoXFlrTD86zSC7YG
# AVU5PSU06ZOOTMAAvGm7ifKv/xQyeO8EE4acIgFB5a8RRC0JQj19eIRBhtfkh1dy
# TX/ocPdsBQICpqo0VXvRb/9iaHj3+r9CWSPtx0kQxRkpHMv/qCtM7kBscljbejLA
# VOXuhWKmNemNGIu7UMIZyro3+XzI4s1biJlGp6bTShs02EbmzlyUJTgithsYgC5n
# X/WRcaHbshvy5S1EJo8m1fi5v/4bj9OTBUOjaYAVKvOjzYE7QR4PhuN/ww8HpGdR
# jLS/eS8Sz3Jxz7EVApPNSzwycDkxAR6Y0w4ymaGy3ZnTOUJjESfwqJvqigjYMcbZ
# +LJOqbLE6bQEmQ+tZiclcdoU4FhleAqQlfksb9kLc5GcU23uIp1aKQ1nji6pxMif
# IHtE5OcMgJzy60tyX/dPpxBGbR3l6+K02v5KI1/GtrVSWxvJHKlXnIMQ4EcgIZBz
# U+NPRgmPG7ZSzYRhpZl/+PrhAgMBAAGjggIDMIIB/zAfBgNVHSMEGDAWgBRoN+Dr
# tjv4XxGG+/5hewiIZfROQjAdBgNVHQ4EFgQUcBJh2GrEdlUHxwi/fkRtYI55VfAw
# PgYDVR0gBDcwNTAzBgZngQwBBAEwKTAnBggrBgEFBQcCARYbaHR0cDovL3d3dy5k
# aWdpY2VydC5jb20vQ1BTMA4GA1UdDwEB/wQEAwIHgDATBgNVHSUEDDAKBggrBgEF
# BQcDAzCBtQYDVR0fBIGtMIGqMFOgUaBPhk1odHRwOi8vY3JsMy5kaWdpY2VydC5j
# b20vRGlnaUNlcnRUcnVzdGVkRzRDb2RlU2lnbmluZ1JTQTQwOTZTSEEzODQyMDIx
# Q0ExLmNybDBToFGgT4ZNaHR0cDovL2NybDQuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0
# VHJ1c3RlZEc0Q29kZVNpZ25pbmdSU0E0MDk2U0hBMzg0MjAyMUNBMS5jcmwwgZQG
# CCsGAQUFBwEBBIGHMIGEMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdpY2Vy
# dC5jb20wXAYIKwYBBQUHMAKGUGh0dHA6Ly9jYWNlcnRzLmRpZ2ljZXJ0LmNvbS9E
# aWdpQ2VydFRydXN0ZWRHNENvZGVTaWduaW5nUlNBNDA5NlNIQTM4NDIwMjFDQTEu
# Y3J0MAkGA1UdEwQCMAAwDQYJKoZIhvcNAQELBQADggIBACeB1ob7bkUKbCC40mTr
# HpXQHQbaeE7ymacNpXKyHefcQij+Op9DsduyOHNLbEojHm24k8GiGjx3ZnaZGKTh
# RQHiijGN+H8Qy27SDvw2MzLnyB7XNg+uCPqIf6xWLdtdQ65T7MaBon6BIX/shzxQ
# t+Jpkr1+qcAP6wWCQ0Q0W5I0w5PKb19dMaT26mw6mnGd06pnTvgpCVRnVy8UJtb7
# Ltt7dfE1G0Cz3LdWW9iBVCI73n/DGWhO8fbiK4D4NpdiNnWVfsxhJ7DSb+6RKJXP
# eG3GwGbmuyDD3D2N9mJnW/6VYAiBwnewGRqwA6D20QKPB0QFHlqVHwkyoYIynVcE
# dfM4K3dtxP8mh6IrEEbWfctNLRgnvRsEE/GnAEmpHxLyzWRx+FILzlaZmRPSyYAO
# O8bE4nWNOTKLdpa/OMum6r/qDJmjcLs80aqMlRiG1k4F2grobscDV+lzy65du9+W
# a8qUeY6rZsnHK02DGOf4iWLqEgaUf36QH10MUpGgj/dkK5cwLCpA1+/d+mySgEF3
# 1N2RHkf5bRVq0DsR8AGT76npVtpyRdnIlIHksfB0G8dDjioKEzCneATEUkketoL1
# ML+ZOcM8t2uURmjK8ZecklHZF74jmrkYVyve2HrxcHOr2qPuwOkRQ5NLnYluYKQo
# Qv4KrbHKxS/bQKd55kJZVzTbMYIGSDCCBkQCAQEwfTBpMQswCQYDVQQGEwJVUzEX
# MBUGA1UEChMORGlnaUNlcnQsIEluYy4xQTA/BgNVBAMTOERpZ2lDZXJ0IFRydXN0
# ZWQgRzQgQ29kZSBTaWduaW5nIFJTQTQwOTYgU0hBMzg0IDIwMjEgQ0ExAhADMlFY
# fN/evhzf5XYSzZUnMAkGBSsOAwIaBQCgeDAYBgorBgEEAYI3AgEMMQowCKACgACh
# AoAAMBkGCSqGSIb3DQEJAzEMBgorBgEEAYI3AgEEMBwGCisGAQQBgjcCAQsxDjAM
# BgorBgEEAYI3AgEVMCMGCSqGSIb3DQEJBDEWBBSQqQcDpCguSjxRHAFf2vLpAe3o
# TjANBgkqhkiG9w0BAQEFAASCAgDZnxHnDSE8sNw56aNNkybty8gZKHUxUsN12W2a
# 7oJsrB372qEu428wN/ZnDzVULKkpe3JQf6tqtrJoiHQBj+/Z91ROyetzPWyM9eXI
# /WIK+Z28VrdTi5EZlTOjb2VLecsql4gaC59Zwggl5mTliV/hfh8h3Wz3gDOkiwbh
# rDLjqHofmDjp5Gfu8FTIubVm1cgIQrzLYPxNF9jR23bL3oxO96AyYCNXCEbbRN0N
# 5OdDNvv5pP00UB/kDpckdqvVvr+cr7E3LINEfAAZJDBKP7vg2CogCuzvgRr2MySw
# ENdXLb2TQpLtkIo8tzK0Pc2nivrwtKMTiX9mjEzMc93Td8LYSt0gfVKmVGathyd5
# DK/BtMidZXvJt5PAVr5bLXLa3r0HbuQkCFOZAAFm0I93+NrzAN0XqAOD/gvgFOqs
# 4QX9F9CFxl+RFxMKJsP9hd9rJs9W2bydpl8gyB/SfpvotRxKvunQBhnSc8rIynHt
# rLSD0NIZ15y0RzlP3WTC+XlAXcKlZhozrci5W6nwSC4ke84vTh/+kFMKo+GHUvmZ
# EtwiDOm8x9JROQU2UIXr0BO4vkvcB9nfSC/ld1+6bvit6Mqj18PvGbVQiXpPAwoA
# lNEqkC8B9ZgfCQh7gGH/RWsDyaDDvHYR3JvEydij98op6IvsjmbBc/LNMg1nI0KP
# 948uqqGCAyYwggMiBgkqhkiG9w0BCQYxggMTMIIDDwIBATB9MGkxCzAJBgNVBAYT
# AlVTMRcwFQYDVQQKEw5EaWdpQ2VydCwgSW5jLjFBMD8GA1UEAxM4RGlnaUNlcnQg
# VHJ1c3RlZCBHNCBUaW1lU3RhbXBpbmcgUlNBNDA5NiBTSEEyNTYgMjAyNSBDQTEC
# EAqA7xhLjfEFgtHEdqeVdGgwDQYJYIZIAWUDBAIBBQCgaTAYBgkqhkiG9w0BCQMx
# CwYJKoZIhvcNAQcBMBwGCSqGSIb3DQEJBTEPFw0yNTA2MTIxNzM4MThaMC8GCSqG
# SIb3DQEJBDEiBCBFCoNYwsxzJ+NCw/GOCsXefRzi07uVtTSf+03kaARCMTANBgkq
# hkiG9w0BAQEFAASCAgAKbaV+SapjpDN0qKIio1mLRUqcSL+v4idXGItD6dcc1NoW
# ZhQlu/otI53068NrYkPwcLn7u2Sp0LKEGRxegKqVA04zI4mMMcf46pi6ifsvJqEt
# rk+3rYxsMZU76zFM4otrZWwy4T/QIDVxidRCt1w81voeZ1zcWQxLRth0moNGTlrF
# s32lWFW3BzYlao02OSHRWKf28n8azps18CbE+jsOf1//ptAIKzyYMa0wnq91pSvq
# p8zP6JKFfCKCT9XzqHn5OtBAQxzH/1tTgbQGxBNjum3SZpTh/M7AVYp+EqZHiUwO
# DhmcIBCAB/wiMw53TmLUkDKsudy0PQ/1Fi2eEKHgigCvwtvbd8m+W7jQYX79BXii
# 1DmaXEK8q9krnJsHr7LA0xD1xL6yVsmvl99QG7Ek9TEBaFYvj4R8WpgrRvWPHWhD
# 6mczwhXcf/YJr0aQzXL2L9N4a/5QU8nkchWABixHqXUJhSQXgvyZTGmrmUa7ojhL
# 825GS1JDozIZ+o4UUkP7AFvmOqdbE7vZjb7dlElg1jPytP/T/ErfVMey5fCTqqP0
# YrGEuj+cpg6kF70mf73d9KvL2fH0GiBtkMeI8VLkx4U/pacCaAMhcjc+id7bsOEk
# 6Wwl78RI/pQ984cxIikc6pLys6pCYe1OjOl5Y0oWEOY0yFpGoDjJXjtSjujgQg==
# SIG # End signature block