public/Set-TvConfig.ps1

function Set-TvConfig {
    <#
    .SYNOPSIS
        This is an essential command which helps set required configuration values
 
    .DESCRIPTION
        This is an essential command which helps set required configuration values for both tvclient and tvbot
 
        tvbot configs are initialized only when tvbot is installed and imported
 
    .PARAMETER ClientId
        Required client id for tvclient
 
        You can get this information from Twitch or twitchtokengenerator.com
 
    .PARAMETER Token
        Required token for tvclient
 
        You can get generate this token at twitchtokengenerator.com
 
    .PARAMETER BitsIcon
        Optional tvbot configuration for the bits alert icon used when BurntToast toast popups are enabled
 
    .PARAMETER BitsImage
        Optional tvbot configuration for the bits alert image
 
    .PARAMETER BitsSound
        Optional tvbot configuration for the bits alert sound
 
        To disable sounds, set Sound to Disabled
 
    .PARAMETER BitsText
        Optional tvbot configuration for the bits alert text
 
    .PARAMETER BitsTitle
        Optional tvbot configuration for the bits alert title
 
    .PARAMETER BotClientId
        Required tvbot client id. Create a bot account then get an API key from Twitch from twitchtokengenerator.com or twitchapps.com/tmi
 
    .PARAMETER BotChannel
        Optional tvbot channel. The bot joins its own channel by default, unless this value is set
 
    .PARAMETER BotIcon
        Optional tvbot configuration for the bot icon that appears in the taskbar when Windows 10 is used
 
    .PARAMETER BotIconColor
        Optional tvbot configuration for the color of the bot icon that appears in the taskbar when Windows 10 is used
 
    .PARAMETER BotKey
        The token that the bot responds to. So in "!say hello", ! would be the key. This value defaults to !
 
    .PARAMETER BotOwner
        The bot owner or owners that can execute admin commands
 
    .PARAMETER BotToken
        The required bot token. Create a bot account then get an API key from Twitch from twitchtokengenerator.com or twitchapps.com/tmi
 
    .PARAMETER UsersToIgnore
        The list of users to ignore so that their chat messages don't appear, such as Wizebot or Nightbot
 
    .PARAMETER DefaultFont
        Default font for Show-TvViewerCount. Defaults to Segoe UI
 
    .PARAMETER DiscordWebhook
        The Discord webhook to use with Send-TvDiscordMessage with tvbot
 
    .PARAMETER FollowIcon
        Optional tvbot configuration for the follow alert icon used when BurntToast toast popups are enabled
 
    .PARAMETER FollowImage
        Optional tvbot configuration for the follow alert image
 
    .PARAMETER FollowSound
        Optional tvbot configuration for the bits alert sound. To disable sounds, set Sound to Disabled
 
    .PARAMETER FollowText
        Optional tvbot configuration for the follow alert text
 
    .PARAMETER FollowTitle
        Optional tvbot configuration for the follow alert title
 
    .PARAMETER HueHub
        The IP or hostname of the Hue Hub used in the Start-TvHueParty tvbot command
 
        Visit http://sqlps.io/hue for more information on how to find the IP of your Philips Hue Hub
 
    .PARAMETER HueToken
        The Hue Token used in the Start-TvHueParty tvbot command
 
        Visit http://sqlps.io/hue for more information on how to generate a token for your Philips Hue Hub
 
    .PARAMETER NotifyColor
        Default color for Show-TvViewerCount notify icon
 
    .PARAMETER NotifyType
        Optional tvbot configuration for the type of notifications to show
 
        Options include none, chat, join, and follow
 
        Defaults to "none"
 
    .PARAMETER RaidIcon
        Optional tvbot configuration for the raid alert icon used when BurntToast toast popups are enabled
 
    .PARAMETER RaidImage
        Optional tvbot configuration for the raid alert image
 
    .PARAMETER RaidSound
        Optional tvbot configuration for the raid alert sound
 
        To disable sounds, set Sound to Disabled
 
    .PARAMETER RaidText
        Optional tvbot configuration for the raid alert text
 
    .PARAMETER RaidTitle
        Optional tvbot configuration for the raid alert title
 
    .PARAMETER Sound
        Optional tvbot configuration to enable or disable popup sounds
 
        Options include Enabled and Disabled
 
        Defaults to Enabled
 
    .PARAMETER SubGiftedText
        Optional tvbot configuration for the gifted sub alert text
 
    .PARAMETER SubGiftedTitle
        Optional tvbot configuration for the gifted sub alert title
 
    .PARAMETER SubGiftedIcon
        Optional tvbot configuration for the gifted sub alert icon
 
    .PARAMETER SubGiftedImage
        Optional tvbot configuration for the gifted sub alert iamge
 
    .PARAMETER SubGiftedSound
        Optional tvbot configuration for the gifted alert sound
 
        To disable sounds, set Sound to Disabled
 
    .PARAMETER SubIcon
        Optional tvbot configuration for the sub alert icon
 
    .PARAMETER SubImage
        Optional tvbot configuration for the sub alert image
 
    .PARAMETER SubSound
        Optional tvbot configuration for the sub alert sound
 
        To disable sounds, set Sound to Disabled
 
    .PARAMETER SubText
        Optional tvbot configuration for the sub alert text
 
    .PARAMETER SubTitle
        Optional tvbot configuration for the sub alert title
 
    .PARAMETER AdminCommandFile
        Optional tvbot configuration for the path to the AdminCommandFile, which is in JSON format
 
        It is recommended that you use Visual Studio Code to edit this file. You can also ignore this file and just use ScriptsToProcess
 
    .PARAMETER ScriptsToProcess
        Optional tvbot configuration for the path to the ScriptsToProcess
 
        These are scripts that are processed when tvbot receives both a username and message
 
        ScriptsToProcess are also run when a new sub and new follow are detected
 
    .PARAMETER UserCommandFile
        Optional tvbot configuration for the path to the UserCommandFile, which is in JSON format
 
        It is recommended that you use Visual Studio Code to edit this file. You can also ignore this file and just use ScriptsToProcess
 
    .PARAMETER Append
        For values that can append such as ScriptsToProcess, UsersToIgnore and NotifyType, append the new value to the current value
 
    .PARAMETER Force
        By default, sensitive values are obscured, use Force to show them unobscured
 
    .PARAMETER WhatIf
        Shows what would happen if the command would run
 
    .PARAMETER Confirm
        Displays (or disables using -Confirm:$false) a confirmation prompt
 
    .EXAMPLE
        PS> Set-TvConfig -ClientId abcxyz123 -Token 321zyxcba
 
        Sets the ClientId and Token used by all tvclient commands
 
    .EXAMPLE
        PS> Set-TvConfig -NotifyType chat
 
        Sets the notify type to "chat", which is used by the tvbot module
 
    .EXAMPLE
        PS> Set-TvConfig -BotChannel janedeaux
 
        Sets the tvbot channel to janedeaux. By default, the bot joins its own channel
 
    .EXAMPLE
        PS> Set-TvConfig -DiscordWebhook https://discord.com/api/webhooks/1234567890/ABC123XYZ
 
        Sets the webhook to be used by Send-TvDiscordMessage in the tvbot module
 
    .EXAMPLE
        PS> Set-TvConfig -NotifyColor Magenta
 
        Sets the notify color used by tvbot to Magenta
 
    .EXAMPLE
        PS> Set-TvConfig -HueHub hue.lab.local -HueToken abcdefh01234567ijklmop
 
        Sets the required information to be used by the tvbot command, Start-TvHueParty
 
    .EXAMPLE
        PS> $splat = @{
                BotClientId = "abcdefh01234567ijklmop"
                BotToken = "01234567fghijklmnopqrs"
            }
 
        PS> Set-TvConfig @splat
 
        Sets the BotClientId and BotToken used by tvbot
 
#>

    [CmdletBinding(SupportsShouldProcess)]
    param
    (
        [string]$BitsIcon,
        [string]$BitsImage,
        [string]$BitsSound,
        [string]$BitsText,
        [string]$BitsTitle,
        [string]$BotClientId,
        [string]$BotChannel,
        [string]$BotIcon,
        [string]$BotIconColor,
        [string]$BotKey,
        [string]$BotOwner,
        [string]$BotToken,
        [string[]]$UsersToIgnore,
        [string]$ClientId,
        [Alias("Secret")]
        [string]$Token,
        [string]$DefaultFont,
        [string]$DiscordWebhook,
        [string]$FollowIcon,
        [string]$FollowImage,
        [string]$FollowSound,
        [string]$FollowText,
        [string]$FollowTitle,
        [string]$HueHub,
        [string]$HueToken,
        # do this to avoid a huge list of colors AND ALSO
        # to ensure that the autocomplete works as expected
        # with partial matches
        [ArgumentCompleter(
            {
                param($Command, $Parameter, $WordToComplete, $CommandAst, $FakeBoundParams)
                Get-ValidColor | Where-Object { $_ -like "$WordToComplete*" }
            }
        )]
        [string]$NotifyColor,
        [ValidateSet("chat", "leave", "join", "none")]
        [string[]]$NotifyType,
        [string]$RaidIcon,
        [string]$RaidImage,
        [string]$RaidSound,
        [string]$RaidText,
        [string]$RaidTitle,
        [parameter(DontShow)]
        [ValidateSet("Enabled", "Disabled")]
        [string]$Sound,
        [string]$SubGiftedText,
        [string]$SubGiftedTitle,
        [string]$SubGiftedIcon,
        [string]$SubGiftedImage,
        [string]$SubGiftedSound,
        [string]$SubIcon,
        [string]$SubImage,
        [string]$SubSound,
        [string]$SubText,
        [string]$SubTitle,
        [string]$AdminCommandFile,
        [string[]]$ScriptsToProcess,
        [string]$UserCommandFile,
        [switch]$Append,
        [switch]$Force
    )
    begin {
        # maybe someone deleted their config file. If so, recreate it for them.
        if (-not (Test-Path -Path $script:configfile)) {
            $null = New-ConfigFile
        }
    }
    process {
        if ($PSBoundParameters.NotifyColor -and $NotifyColor -notin (Get-ValidColor)) {
            Write-Warning -Message "$NotifyColor is not a valid color. You can tab through -NotifyColor to see a list. Resetting to Magenta"
            $PSBoundParameters.NotifyColor = "Magenta"
        }

        if ($PSBoundParameters.DefaultFont -and -not $islinux) {
            if ($DefaultFont -notin (New-Object System.Drawing.Text.InstalledFontCollection).Families) {
                Write-Warning -Message "The font $DefaultFont is not installed, using Segoe UI instead"
                $PSBoundParameters.DefaultFont = "Segoe UI"
            }
        }
        $config = Get-Content -Path $script:configfile | ConvertFrom-Json | ConvertTo-HashTable

        $ignorecommonargs = [System.Management.Automation.PSCmdlet]::CommonParameters

        foreach ($key in $PSBoundParameters.Keys) {
            $hidden = "ClientID", "Token", "DiscordWebhook", "BotClientId", "BotToken"

            if ($key -notin $ignorecommonargs -and $key -notin "Append", "Force", "WhatIf", "Confirm") {
                if ($key -in "UsersToIgnore", "NotifyType", "BotOwner", "ScriptsToProcess") {
                    if ($Append) {
                        $value = @(Get-TvConfigValue -Name $key)
                        $value += $PSBoundParameters.$key
                        $value = $value -join ", "
                    } else {
                        $value = $PSBoundParameters.$key -join ", "
                    }
                    if ($PSCmdlet.ShouldProcess($script:configfile, "Set $key to $value")) {
                        $config[$key] = $value
                    }
                } else {
                    $value = $PSBoundParameters.$key
                    $config[$key] = $value

                    if ($key -in $hidden -and -not $Force) {
                        $value = "********************** (Use -Force to see)"
                    }
                    if ($PSCmdlet.ShouldProcess($script:configfile, "Set $key to $value")) {
                        # couldn't figure out how to do this lol
                    }
                }
            }
        }

        if ($PSCmdlet.ShouldProcess($script:configfile, "Writing config file")) {
            $config | ConvertTo-Json | Set-Content -Path $script:configfile -Encoding Unicode
            Get-TvConfig -Force:$Force
        }
    }
}
# SIG # Begin signature block
# MIIZewYJKoZIhvcNAQcCoIIZbDCCGWgCAQExCzAJBgUrDgMCGgUAMGkGCisGAQQB
# gjcCAQSgWzBZMDQGCisGAQQBgjcCAR4wJgIDAQAABBAfzDtgWUsITrck0sYpfvNR
# AgEAAgEAAgEAAgEAAgEAMCEwCQYFKw4DAhoFAAQU3svH2s4Pcc3k68+WGfCo2rjJ
# 8GugghSJMIIE/jCCA+agAwIBAgIQDUJK4L46iP9gQCHOFADw3TANBgkqhkiG9w0B
# AQsFADByMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYD
# VQQLExB3d3cuZGlnaWNlcnQuY29tMTEwLwYDVQQDEyhEaWdpQ2VydCBTSEEyIEFz
# c3VyZWQgSUQgVGltZXN0YW1waW5nIENBMB4XDTIxMDEwMTAwMDAwMFoXDTMxMDEw
# NjAwMDAwMFowSDELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDkRpZ2lDZXJ0LCBJbmMu
# MSAwHgYDVQQDExdEaWdpQ2VydCBUaW1lc3RhbXAgMjAyMTCCASIwDQYJKoZIhvcN
# AQEBBQADggEPADCCAQoCggEBAMLmYYRnxYr1DQikRcpja1HXOhFCvQp1dU2UtAxQ
# tSYQ/h3Ib5FrDJbnGlxI70Tlv5thzRWRYlq4/2cLnGP9NmqB+in43Stwhd4CGPN4
# bbx9+cdtCT2+anaH6Yq9+IRdHnbJ5MZ2djpT0dHTWjaPxqPhLxs6t2HWc+xObTOK
# fF1FLUuxUOZBOjdWhtyTI433UCXoZObd048vV7WHIOsOjizVI9r0TXhG4wODMSlK
# XAwxikqMiMX3MFr5FK8VX2xDSQn9JiNT9o1j6BqrW7EdMMKbaYK02/xWVLwfoYer
# vnpbCiAvSwnJlaeNsvrWY4tOpXIc7p96AXP4Gdb+DUmEvQECAwEAAaOCAbgwggG0
# MA4GA1UdDwEB/wQEAwIHgDAMBgNVHRMBAf8EAjAAMBYGA1UdJQEB/wQMMAoGCCsG
# AQUFBwMIMEEGA1UdIAQ6MDgwNgYJYIZIAYb9bAcBMCkwJwYIKwYBBQUHAgEWG2h0
# dHA6Ly93d3cuZGlnaWNlcnQuY29tL0NQUzAfBgNVHSMEGDAWgBT0tuEgHf4prtLk
# YaWyoiWyyBc1bjAdBgNVHQ4EFgQUNkSGjqS6sGa+vCgtHUQ23eNqerwwcQYDVR0f
# BGowaDAyoDCgLoYsaHR0cDovL2NybDMuZGlnaWNlcnQuY29tL3NoYTItYXNzdXJl
# ZC10cy5jcmwwMqAwoC6GLGh0dHA6Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9zaGEyLWFz
# c3VyZWQtdHMuY3JsMIGFBggrBgEFBQcBAQR5MHcwJAYIKwYBBQUHMAGGGGh0dHA6
# Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBPBggrBgEFBQcwAoZDaHR0cDovL2NhY2VydHMu
# ZGlnaWNlcnQuY29tL0RpZ2lDZXJ0U0hBMkFzc3VyZWRJRFRpbWVzdGFtcGluZ0NB
# LmNydDANBgkqhkiG9w0BAQsFAAOCAQEASBzctemaI7znGucgDo5nRv1CclF0CiNH
# o6uS0iXEcFm+FKDlJ4GlTRQVGQd58NEEw4bZO73+RAJmTe1ppA/2uHDPYuj1UUp4
# eTZ6J7fz51Kfk6ftQ55757TdQSKJ+4eiRgNO/PT+t2R3Y18jUmmDgvoaU+2QzI2h
# F3MN9PNlOXBL85zWenvaDLw9MtAby/Vh/HUIAHa8gQ74wOFcz8QRcucbZEnYIpp1
# FUL1LTI4gdr0YKK6tFL7XOBhJCVPst/JKahzQ1HavWPWH1ub9y4bTxMd90oNcX6X
# t/Q/hOvB46NJofrOp79Wz7pZdmGJX36ntI5nePk2mOHLKNpbh6aKLzCCBRowggQC
# oAMCAQICEAMFu4YhsKFjX7/erhIE520wDQYJKoZIhvcNAQELBQAwcjELMAkGA1UE
# BhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3LmRpZ2lj
# ZXJ0LmNvbTExMC8GA1UEAxMoRGlnaUNlcnQgU0hBMiBBc3N1cmVkIElEIENvZGUg
# U2lnbmluZyBDQTAeFw0yMDA1MTIwMDAwMDBaFw0yMzA2MDgxMjAwMDBaMFcxCzAJ
# BgNVBAYTAlVTMREwDwYDVQQIEwhWaXJnaW5pYTEPMA0GA1UEBxMGVmllbm5hMREw
# DwYDVQQKEwhkYmF0b29sczERMA8GA1UEAxMIZGJhdG9vbHMwggEiMA0GCSqGSIb3
# DQEBAQUAA4IBDwAwggEKAoIBAQC8v2N7q+O/vggBtpjmteofFo140k73JXQ5sOD6
# QLzjgija+scoYPxTmFSImnqtjfZFWmucAWsDiMVVro/6yGjsXmJJUA7oD5BlMdAK
# fuiq4558YBOjjc0Bp3NbY5ZGujdCmsw9lqHRAVil6P1ZpAv3D/TyVVq6AjDsJY+x
# rRL9iMc8YpD5tiAj+SsRSuT5qwPuW83ByRHqkaJ5YDJ/R82ZKh69AFNXoJ3xCJR+
# P7+pa8tbdSgRf25w4ZfYPy9InEvsnIRVZMeDjjuGvqr0/Mar73UI79z0NYW80yN/
# 7VzlrvV8RnniHWY2ib9ehZligp5aEqdV2/XFVPV4SKaJs8R9AgMBAAGjggHFMIIB
# wTAfBgNVHSMEGDAWgBRaxLl7KgqjpepxA8Bg+S32ZXUOWDAdBgNVHQ4EFgQU8MCg
# +7YDgENO+wnX3d96scvjniIwDgYDVR0PAQH/BAQDAgeAMBMGA1UdJQQMMAoGCCsG
# AQUFBwMDMHcGA1UdHwRwMG4wNaAzoDGGL2h0dHA6Ly9jcmwzLmRpZ2ljZXJ0LmNv
# bS9zaGEyLWFzc3VyZWQtY3MtZzEuY3JsMDWgM6Axhi9odHRwOi8vY3JsNC5kaWdp
# Y2VydC5jb20vc2hhMi1hc3N1cmVkLWNzLWcxLmNybDBMBgNVHSAERTBDMDcGCWCG
# SAGG/WwDATAqMCgGCCsGAQUFBwIBFhxodHRwczovL3d3dy5kaWdpY2VydC5jb20v
# Q1BTMAgGBmeBDAEEATCBhAYIKwYBBQUHAQEEeDB2MCQGCCsGAQUFBzABhhhodHRw
# Oi8vb2NzcC5kaWdpY2VydC5jb20wTgYIKwYBBQUHMAKGQmh0dHA6Ly9jYWNlcnRz
# LmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydFNIQTJBc3N1cmVkSURDb2RlU2lnbmluZ0NB
# LmNydDAMBgNVHRMBAf8EAjAAMA0GCSqGSIb3DQEBCwUAA4IBAQCPzflwlQwf1jak
# EqymPOc0nBxiY7F4FwcmL7IrTLhub6Pjg4ZYfiC79Akz5aNlqO+TJ0kqglkfnOsc
# jfKQzzDwcZthLVZl83igzCLnWMo8Zk/D2d4ZLY9esFwqPNvuuVDrHvgh7H6DJ/zP
# Vm5EOK0sljT0UQ6HQEwtouH5S8nrqCGZ8jKM/+DeJlm+rCAGGf7TV85uqsAn5JqD
# En/bXE1AlyG1Q5YiXFGS5Sf0qS4Nisw7vRrZ6Qc4NwBty4cAYjzDPDixorWI8+FV
# OUWKMdL7tV8i393/XykwsccCstBCp7VnSZN+4vgzjEJQql5uQfysjcW9rrb/qixp
# csPTKYRHMIIFMDCCBBigAwIBAgIQBAkYG1/Vu2Z1U0O1b5VQCDANBgkqhkiG9w0B
# AQsFADBlMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYD
# VQQLExB3d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVk
# IElEIFJvb3QgQ0EwHhcNMTMxMDIyMTIwMDAwWhcNMjgxMDIyMTIwMDAwWjByMQsw
# CQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cu
# ZGlnaWNlcnQuY29tMTEwLwYDVQQDEyhEaWdpQ2VydCBTSEEyIEFzc3VyZWQgSUQg
# Q29kZSBTaWduaW5nIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA
# +NOzHH8OEa9ndwfTCzFJGc/Q+0WZsTrbRPV/5aid2zLXcep2nQUut4/6kkPApfmJ
# 1DcZ17aq8JyGpdglrA55KDp+6dFn08b7KSfH03sjlOSRI5aQd4L5oYQjZhJUM1B0
# sSgmuyRpwsJS8hRniolF1C2ho+mILCCVrhxKhwjfDPXiTWAYvqrEsq5wMWYzcT6s
# cKKrzn/pfMuSoeU7MRzP6vIK5Fe7SrXpdOYr/mzLfnQ5Ng2Q7+S1TqSp6moKq4Tz
# rGdOtcT3jNEgJSPrCGQ+UpbB8g8S9MWOD8Gi6CxR93O8vYWxYoNzQYIH5DiLanMg
# 0A9kczyen6Yzqf0Z3yWT0QIDAQABo4IBzTCCAckwEgYDVR0TAQH/BAgwBgEB/wIB
# ADAOBgNVHQ8BAf8EBAMCAYYwEwYDVR0lBAwwCgYIKwYBBQUHAwMweQYIKwYBBQUH
# AQEEbTBrMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdpY2VydC5jb20wQwYI
# KwYBBQUHMAKGN2h0dHA6Ly9jYWNlcnRzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEFz
# c3VyZWRJRFJvb3RDQS5jcnQwgYEGA1UdHwR6MHgwOqA4oDaGNGh0dHA6Ly9jcmw0
# LmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJRFJvb3RDQS5jcmwwOqA4oDaG
# NGh0dHA6Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJRFJvb3RD
# QS5jcmwwTwYDVR0gBEgwRjA4BgpghkgBhv1sAAIEMCowKAYIKwYBBQUHAgEWHGh0
# dHBzOi8vd3d3LmRpZ2ljZXJ0LmNvbS9DUFMwCgYIYIZIAYb9bAMwHQYDVR0OBBYE
# FFrEuXsqCqOl6nEDwGD5LfZldQ5YMB8GA1UdIwQYMBaAFEXroq/0ksuCMS1Ri6en
# IZ3zbcgPMA0GCSqGSIb3DQEBCwUAA4IBAQA+7A1aJLPzItEVyCx8JSl2qB1dHC06
# GsTvMGHXfgtg/cM9D8Svi/3vKt8gVTew4fbRknUPUbRupY5a4l4kgU4QpO4/cY5j
# DhNLrddfRHnzNhQGivecRk5c/5CxGwcOkRX7uq+1UcKNJK4kxscnKqEpKBo6cSgC
# PC6Ro8AlEeKcFEehemhor5unXCBc2XGxDI+7qPjFEmifz0DLQESlE/DmZAwlCEIy
# sjaKJAL+L3J+HNdJRZboWR3p+nRka7LrZkPas7CM1ekN3fYBIM6ZMWM9CBoYs4Gb
# T8aTEAb8B4H6i9r5gkn3Ym6hU/oSlBiFLpKR6mhsRDKyZqHnGKSaZFHvMIIFMTCC
# BBmgAwIBAgIQCqEl1tYyG35B5AXaNpfCFTANBgkqhkiG9w0BAQsFADBlMQswCQYD
# VQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGln
# aWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgQ0Ew
# HhcNMTYwMTA3MTIwMDAwWhcNMzEwMTA3MTIwMDAwWjByMQswCQYDVQQGEwJVUzEV
# MBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29t
# MTEwLwYDVQQDEyhEaWdpQ2VydCBTSEEyIEFzc3VyZWQgSUQgVGltZXN0YW1waW5n
# IENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvdAy7kvNj3/dqbqC
# mcU5VChXtiNKxA4HRTNREH3Q+X1NaH7ntqD0jbOI5Je/YyGQmL8TvFfTw+F+CNZq
# FAA49y4eO+7MpvYyWf5fZT/gm+vjRkcGGlV+Cyd+wKL1oODeIj8O/36V+/OjuiI+
# GKwR5PCZA207hXwJ0+5dyJoLVOOoCXFr4M8iEA91z3FyTgqt30A6XLdR4aF5FMZN
# JCMwXbzsPGBqrC8HzP3w6kfZiFBe/WZuVmEnKYmEUeaC50ZQ/ZQqLKfkdT66mA+E
# f58xFNat1fJky3seBdCEGXIX8RcG7z3N1k3vBkL9olMqT4UdxB08r8/arBD13ays
# 6Vb/kwIDAQABo4IBzjCCAcowHQYDVR0OBBYEFPS24SAd/imu0uRhpbKiJbLIFzVu
# MB8GA1UdIwQYMBaAFEXroq/0ksuCMS1Ri6enIZ3zbcgPMBIGA1UdEwEB/wQIMAYB
# Af8CAQAwDgYDVR0PAQH/BAQDAgGGMBMGA1UdJQQMMAoGCCsGAQUFBwMIMHkGCCsG
# AQUFBwEBBG0wazAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQuY29t
# MEMGCCsGAQUFBzAChjdodHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vRGlnaUNl
# cnRBc3N1cmVkSURSb290Q0EuY3J0MIGBBgNVHR8EejB4MDqgOKA2hjRodHRwOi8v
# Y3JsNC5kaWdpY2VydC5jb20vRGlnaUNlcnRBc3N1cmVkSURSb290Q0EuY3JsMDqg
# OKA2hjRodHRwOi8vY3JsMy5kaWdpY2VydC5jb20vRGlnaUNlcnRBc3N1cmVkSURS
# b290Q0EuY3JsMFAGA1UdIARJMEcwOAYKYIZIAYb9bAACBDAqMCgGCCsGAQUFBwIB
# FhxodHRwczovL3d3dy5kaWdpY2VydC5jb20vQ1BTMAsGCWCGSAGG/WwHATANBgkq
# hkiG9w0BAQsFAAOCAQEAcZUS6VGHVmnN793afKpjerN4zwY3QITvS4S/ys8DAv3F
# p8MOIEIsr3fzKx8MIVoqtwU0HWqumfgnoma/Capg33akOpMP+LLR2HwZYuhegiUe
# xLoceywh4tZbLBQ1QwRostt1AuByx5jWPGTlH0gQGF+JOGFNYkYkh2OMkVIsrymJ
# 5Xgf1gsUpYDXEkdws3XVk4WTfraSZ/tTYYmo9WuWwPRYaQ18yAGxuSh1t5ljhSKM
# Ycp5lH5Z/IwP42+1ASa2bKXuh1Eh5Fhgm7oMLSttosR+u8QlK0cCCHxJrhO24XxC
# QijGGFbPQTS2Zl22dHv1VjMiLyI2skuiSpXY9aaOUjGCBFwwggRYAgEBMIGGMHIx
# CzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3
# dy5kaWdpY2VydC5jb20xMTAvBgNVBAMTKERpZ2lDZXJ0IFNIQTIgQXNzdXJlZCBJ
# RCBDb2RlIFNpZ25pbmcgQ0ECEAMFu4YhsKFjX7/erhIE520wCQYFKw4DAhoFAKB4
# MBgGCisGAQQBgjcCAQwxCjAIoAKAAKECgAAwGQYJKoZIhvcNAQkDMQwGCisGAQQB
# gjcCAQQwHAYKKwYBBAGCNwIBCzEOMAwGCisGAQQBgjcCARUwIwYJKoZIhvcNAQkE
# MRYEFBLcckkkefCdJrUamXNs6QvLnW3cMA0GCSqGSIb3DQEBAQUABIIBAI33PPzs
# pCAxkmftFglsQCBGHy4D+jocqLZotQT+jLEgZxiHpPyMLRPep/a3mCmH7BVhYnuY
# uhwmJkS39eZjJrmWf2DD2rTPDUUGhHYpGtc+Yz4qaBREukigiBIIfeYl9V9Y7iwO
# tqeemQTZLR8nq1FxHmT0xywZb58naWxdBIav2cF92ksFGaj2t5f/mCyFO4y/kbt7
# ggwtmHPeRdbh76oSw8uwLLYBAKA06Rg4F8PMGYlgvciqWd1Xem/nce6LD4z8Jp80
# UGSDlzxGFNrj022RjzaCoDeHChAABYNAAIB6lf/bOiG6fo/AI3Op+Cw2gEO7g0+B
# RdjRZAHjAz9GAamhggIwMIICLAYJKoZIhvcNAQkGMYICHTCCAhkCAQEwgYYwcjEL
# MAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3
# LmRpZ2ljZXJ0LmNvbTExMC8GA1UEAxMoRGlnaUNlcnQgU0hBMiBBc3N1cmVkIElE
# IFRpbWVzdGFtcGluZyBDQQIQDUJK4L46iP9gQCHOFADw3TANBglghkgBZQMEAgEF
# AKBpMBgGCSqGSIb3DQEJAzELBgkqhkiG9w0BBwEwHAYJKoZIhvcNAQkFMQ8XDTIx
# MDYyMjExMDY0NlowLwYJKoZIhvcNAQkEMSIEIGFECTYoyg0cWwUXQnnqH6N9wxnR
# iVDzis9s4e5Qgy6IMA0GCSqGSIb3DQEBAQUABIIBAB2RgoUH7mTb6Vjhzr48Kooh
# wvpwwDluZYtHAZ5HKDb3T7Uly7UdL6kyXsAFXolLeaLQFHzPVQKqjQ7FkMMTLMJR
# jx/zStvGD6amyaSAgGY1XZpnSsklVX/LapnqZ6kAcJRhqZwwvsuvf8K6iYdxKuCr
# aq6TCFZ8DFGx9QUh7RAgvH+BFSt6SaUNlORi3GjJsx46g4b76SQ31L1miQr3zmaz
# 3URbye/kj3kakio5QB/j2zt2qYDKFzn/aeR+YR+UzJBValnpNRPgmiTBpr29n0H8
# gdDAvpQvtR9SHNcDG4+MBbezozbibL1hN9JeYJOcyLppb7IgJlwXsLbUk0oFY9A=
# SIG # End signature block