Compare commits

...

8 Commits
v1.61 ... v1.69

Author SHA1 Message Date
Pete Batard
47e909f5f5 Add UEFI Shell 26H1 downloads
* Also add retry on getting the SKU languages, as it may fail on first attempt.
2026-02-27 16:57:31 +00:00
Pete Batard
ea425ffbec Add new workaround for Microsoft's pointless restrictions
* This adds the new required dance with ov-df.microsoft.com.
* Won't help with the extra IP filtering MS seems to have added to detect VPN access.
* Closes #106.
* Maybe one day Microsoft will take a page from Linux and realise that trying to ostracise
  users, by not making the ISO downloads freely accessible through wget, curl and scripts,
  WITHOUT RESTRICTIONS, is yet another great way to cement the ongoing decline of your OS.
  Then again, if Microsoft maintains its current user-aggravating direction, we may find
  out, possibly soon, if both parts of "too big to fail" Wintel can meet the same fate...
2026-02-16 15:59:03 +00:00
Pete Batard
41d5b8e79f Add UEFI Shell 25H2 downloads 2025-11-21 21:35:44 +00:00
Pete Batard
0d5a7fed87 Add Windows 11 25H2 downloads
* With thanks to @ave9858.
* Closes #100.
2025-09-30 22:27:33 +01:00
Pete Batard
2fc1739224 Add UEFI Shell 25H1 downloads 2025-06-12 17:42:16 +01:00
Pete Batard
96c3637863 Add UEFI Shell 24H2 downloads
* Also add a new -PlatformArch option, to help avoid the very time consuming WMI call to autodetect the native CPU arch.
2024-11-24 22:26:40 +00:00
Pete Batard
c034a4e72a Fix localization of error message 715-123130
* As usual, Microsoft are completely unable to properly process UTF-8 content, even if
  the response from an Invoke-WebRequest query explicitly specifies "charset=utf-8".
* So, once again, we need to force PowerShell's hand to treat the content as UTF-8.
* Also improve the default error message if we can't get it from Microsoft.
2024-11-20 13:51:17 +00:00
Pete Batard
ce405fa35c Switch to using the new JSON Windows download API
* This simplifies things quite a bit since we were converting HTML to XML to JSON before.
* Also drop the custom User Agent for now.
  We'll have to see how long it takes Microsoft to go back to filtering out PowerShell...
* Closes #98.
2024-11-19 22:42:39 +00:00

591
Fido.ps1
View File

@@ -1,6 +1,6 @@
#
# Fido v1.61 - Feature ISO Downloader, for retail Windows images and UEFI Shell
# Copyright © 2019-2024 Pete Batard <pete@akeo.ie>
# Fido v1.69 - ISO Downloader, for Microsoft Windows and UEFI Shell
# Copyright © 2019-2026 Pete Batard <pete@akeo.ie>
# Command line support: Copyright © 2021 flx5
# ConvertTo-ImageSource: Copyright © 2016 Chris Carter
#
@@ -24,7 +24,7 @@
#region Parameters
param(
# (Optional) The title to display on the application window.
[string]$AppTitle = "Fido - Feature ISO Downloader",
[string]$AppTitle = "Fido - ISO Downloader",
# (Optional) '|' separated UI localization strings.
[string]$LocData,
# (Optional) Forced locale
@@ -46,6 +46,9 @@ param(
[string]$Arch,
# (Optional) Only display the download URL [Toggles commandline mode]
[switch]$GetUrl = $false,
# (Optional) Specify the architecture of the underlying CPU.
# This avoids a VERY TIME CONSUMING call to WMI to autodetect the arch.
[string]$PlatformArch,
# (Optional) Increase verbosity
[switch]$Verbose = $false,
# (Optional) Produce debugging information
@@ -138,12 +141,12 @@ $WindowsVersions = @(
@(
@("Windows 11", "windows11"),
@(
"24H2 (Build 26100.1742 - 2024.10)",
"25H2 (Build 26200.6584 - 2025.10)",
# Thanks to Microsoft's hare-brained decision not to treat ARM64 as a CPU arch,
# like they did for x86 and x64, we have to handle multiple IDs for each release...
@("Windows 11 Home/Pro/Edu", @(3113, 3131)),
@("Windows 11 Home China ", @(3115, 3132)),
@("Windows 11 Pro China ", @(3114, 3133))
@("Windows 11 Home/Pro/Edu", @(3262, 3265)),
@("Windows 11 Home China ", @(3263, 3266)),
@("Windows 11 Pro China ", @(3264, 3267))
)
),
@(
@@ -156,6 +159,26 @@ $WindowsVersions = @(
)
@(
@("UEFI Shell 2.2", "UEFI_SHELL 2.2"),
@(
"26H1 (edk2-stable202602)",
@("Release", 0),
@("Debug", 1)
),
@(
"25H2 (edk2-stable202511)",
@("Release", 0),
@("Debug", 1)
),
@(
"25H1 (edk2-stable202505)",
@("Release", 0),
@("Debug", 1)
),
@(
"24H2 (edk2-stable202411)",
@("Release", 0),
@("Debug", 1)
),
@(
"24H1 (edk2-stable202405)",
@("Release", 0),
@@ -346,17 +369,6 @@ function ConvertTo-ImageSource
}
}
function Throw-Error([object]$Req, [string]$Alt)
{
$Err = $(GetElementById -Request $Req -Id "errorModalMessage").innerText -replace "<[^>]+>" -replace "\s+", " "
if (!$Err) {
$Err = $Alt
} else {
$Err = [System.Text.Encoding]::UTF8.GetString([byte[]][char[]]$Err)
}
throw $Err
}
# Translate a message string
function Get-Translation([string]$Text)
{
@@ -398,14 +410,14 @@ function Get-Arch
}
}
# Some PowerShells don't have Microsoft.mshtml assembly (comes with MS Office?)
# so we can't use ParsedHtml or IHTMLDocument[2|3] features there...
function GetElementById([object]$Request, [string]$Id)
# Convert a Microsoft arch type code to a formal architecture name
function Get-Arch-From-Type([int]$Type)
{
try {
return $Request.ParsedHtml.IHTMLDocument3_GetElementByID($Id)
} catch {
return $Request.AllElements | ? {$_.id -eq $Id}
switch($Type) {
0 { return "x86" }
1 { return "x64" }
2 { return "ARM64" }
default { return "Unknown"}
}
}
@@ -422,17 +434,6 @@ function Error([string]$ErrorMessage)
$script:ExitCode = 2
}
}
function Get-RandomDate()
{
[DateTime]$Min = "1/1/2008"
[DateTime]$Max = [DateTime]::Now
$RandomGen = new-object random
$RandomTicks = [Convert]::ToInt64( ($Max.ticks * 1.0 - $Min.Ticks * 1.0 ) * $RandomGen.NextDouble() + $Min.Ticks * 1.0 )
$Date = new-object DateTime($RandomTicks)
return $Date.ToString("yyyyMMdd")
}
#endregion
#region Form
@@ -466,15 +467,9 @@ $MaxStage = 4
$SessionId = @($null) * 2
$ExitCode = 100
$Locale = $Locale
$RequestData = @{}
# This GUID applies to all visitors, regardless of their locale
$RequestData["GetLangs"] = @("a8f8f489-4c7f-463a-9ca6-5cff94d8d041", "getskuinformationbyproductedition" )
# This GUID applies to visitors of the en-US download page. Other locales may get a different GUID.
$RequestData["GetLinks"] = @("6e2a1789-ef16-4f27-a296-74ef7ef5d96b", "GetProductDownloadLinksBySku" )
# Create a semi-random Linux User-Agent string
$FirefoxVersion = Get-Random -Minimum 110 -Maximum 135
$FirefoxDate = Get-RandomDate
$UserAgent = "Mozilla/5.0 (X11; Linux i586; rv:$FirefoxVersion.0) Gecko/$FirefoxDate Firefox/$FirefoxVersion.0"
$OrgId = "y6jn8c31"
$ProfileId = "606624d44113"
$InstanceId = "560dc9f3-1aa5-4a2f-b63c-9e18f8d0e175"
$Verbosity = 1
if ($Debug) {
$Verbosity = 5
@@ -483,7 +478,9 @@ if ($Debug) {
} elseif ($Cmd -and $GetUrl) {
$Verbosity = 0
}
if (!$PlatformArch) {
$PlatformArch = Get-Arch
}
#endregion
# Localization
@@ -523,17 +520,11 @@ function Size-To-Human-Readable([uint64]$size)
function Check-Locale
{
try {
$url = "https://www.microsoft.com/" + $QueryLocale + "/software-download/"
$url = "https://www.microsoft.com/" + $QueryLocale + "/software-download/windows11"
if ($Verbosity -ge 2) {
Write-Host Querying $url
}
# Looks Microsoft are filtering our script according to the first query it performs with the spoofed user agent.
# So, to continue this pointless cat and mouse game, we simply add an extra first query with the default user agent.
# Also: "Hi Microsoft. You sure have A LOT OF RESOURCES TO WASTE to have assigned folks of yours to cripple scripts
# that merely exist because you have chosen to make the user experience from your download website utterly subpar.
# And while I am glad senpai noticed me (UwU), I feel compelled to ask: Don't you guys have better things to do?"
Invoke-WebRequest -UseBasicParsing -TimeoutSec $DefaultTimeout -MaximumRedirection 0 $url | Out-Null
Invoke-WebRequest -UseBasicParsing -TimeoutSec $DefaultTimeout -MaximumRedirection 0 -UserAgent $UserAgent $url | Out-Null
} catch {
# Of course PowerShell 7 had to BREAK $_.Exception.Status on timeouts...
if ($_.Exception.Status -eq "Timeout" -or $_.Exception.GetType().Name -eq "TaskCanceledException") {
@@ -543,6 +534,33 @@ function Check-Locale
}
}
function Get-Code-715-123130-Message
{
try {
$url = "https://www.microsoft.com/" + $QueryLocale + "/software-download/windows11"
if ($Verbosity -ge 2) {
Write-Host Querying $url
}
$r = Invoke-WebRequest -UseBasicParsing -TimeoutSec $DefaultTimeout -MaximumRedirection 0 $url
# Microsoft's handling of UTF-8 content is soooooooo *UTTERLY BROKEN*!!!
$r = [System.Text.Encoding]::UTF8.GetString($r.RawContentStream.ToArray())
# PowerShell 7 forces us to parse the HTML ourselves
$r = $r -replace "`n" -replace "`r"
$pattern = '.*<input id="msg-01" type="hidden" value="(.*?)"/>.*'
$msg = [regex]::Match($r, $pattern).Groups[1].Value
$msg = $msg -replace "&lt;", "<" -replace "<[^>]+>" -replace "\s+", " "
if (($msg -eq $null) -or !($msg -match "715-123130")) {
throw
}
} catch {
$msg = "Your IP address has been banned by Microsoft for issuing too many ISO download requests or for "
$msg += "belonging to a region of the world where sanctions currently apply. Please try again later.`r`n"
$msg += "If you believe this ban to be in error, you can try contacting Microsoft by referring to "
$msg += "message code 715-123130 and session ID "
}
return $msg
}
# Return an array of releases (e.g. 20H2, 21H1, ...) for the selected Windows version
function Get-Windows-Releases([int]$SelectedVersion)
{
@@ -583,56 +601,107 @@ function Get-Windows-Languages([int]$SelectedVersion, [object]$SelectedEdition)
$SessionIndex = 0
foreach ($EditionId in $SelectedEdition) {
$SessionId[$SessionIndex] = [guid]::NewGuid()
# Microsoft download protection now requires the sessionId to be whitelisted through vlscppe.microsoft.com/tags
$url = "https://vlscppe.microsoft.com/tags?org_id=y6jn8c31&session_id=" + $SessionId[$SessionIndex]
# Microsoft download "protection" requires the sessionId to be whitelisted through vlscppe.microsoft.com/tags
$url = "https://vlscppe.microsoft.com/tags"
$url += "?org_id=" + $OrgId
$url += "&session_id=" + $SessionId[$SessionIndex]
if ($Verbosity -ge 2) {
Write-Host Querying $url
}
try {
Invoke-WebRequest -UseBasicParsing -TimeoutSec $DefaultTimeout -MaximumRedirection 0 -UserAgent $UserAgent $url | Out-Null
Invoke-WebRequest -UseBasicParsing -TimeoutSec $DefaultTimeout -MaximumRedirection 0 $url | Out-Null
} catch {
Error($_.Exception.Message)
return @()
}
$url = "https://www.microsoft.com/" + $QueryLocale + "/api/controls/contentinclude/html"
$url += "?pageId=" + $RequestData["GetLangs"][0]
$url += "&host=www.microsoft.com"
$url += "&segments=software-download," + $WindowsVersions[$SelectedVersion][0][1]
$url += "&query=&action=" + $RequestData["GetLangs"][1]
$url += "&sessionId=" + $SessionId[$SessionIndex]
$url += "&productEditionId=" + $EditionId
$url += "&sdVersion=2"
# Microsoft download "protection" also requires an ov-df.microsoft.com request/reply
# 1) Request mdt.js to get w and rticks. InstanceId is (currently) constant.
$url = "https://ov-df.microsoft.com/mdt.js"
$url += "?instanceId=" + $InstanceId
$url += "&PageId=si"
$url += "&session_id=" + $SessionId[$SessionIndex]
if ($Verbosity -ge 2) {
Write-Host Querying $url
}
try {
$r = Invoke-WebRequest -Method Post -UseBasicParsing -TimeoutSec $DefaultTimeout -UserAgent $UserAgent -SessionVariable "Session" $url
$r = Invoke-RestMethod -UseBasicParsing -TimeoutSec $DefaultTimeout -MaximumRedirection 0 $url
if ($r -eq $null) {
throw "Could not retrieve ov-df data"
}
# Extract w and rticks parameters
if ($r -match '[?&]w=([A-F0-9]+)') {
$w = $matches[1]
}
if ($r -match 'rticks\=\"\+?(\d+)') {
$rticks = $matches[1]
}
if (!$w -or !$rticks) {
throw "Could not extract ov-df data"
}
} catch {
Error($_.Exception.Message)
return @()
}
# 2) Send a reply with session ID, current epoch and previously retrieved w and rticks
$url = "https://ov-df.microsoft.com/"
$url += "?session_id=" + $SessionId[$SessionIndex]
$url += "&CustomerId=" + $InstanceId
$url += "&PageId=si"
$url += "&w=" + $w
$url += "&mdt=" + [DateTimeOffset]::Now.ToUnixTimeMilliSeconds()
$url += "&rticks=" + $rticks
if ($Verbosity -ge 2) {
Write-Host Querying $url
}
try {
Invoke-WebRequest -UseBasicParsing -TimeoutSec $DefaultTimeout -MaximumRedirection 0 $url | Out-Null
} catch {
Error($_.Exception.Message)
return @()
}
$url = "https://www.microsoft.com/software-download-connector/api/getskuinformationbyproductedition"
$url += "?profile=" + $ProfileId
$url += "&productEditionId=" + $EditionId
$url += "&SKU=undefined"
$url += "&friendlyFileName=undefined"
$url += "&Locale=" + $QueryLocale
$url += "&sessionID=" + $SessionId[$SessionIndex]
if ($Verbosity -ge 2) {
Write-Host Querying $url
}
try {
# May require a few attempts.
$attempt = 0;
while ($true) {
if ($attempt -ne 0) { Start-Sleep -Seconds 2 }
$r = Invoke-RestMethod -UseBasicParsing -TimeoutSec $DefaultTimeout -SessionVariable "Session" $url
if ($r -eq $null) {
if ($attempt++ -le 1) { continue }
throw "Could not retrieve languages from server"
}
if ($Verbosity -ge 5) {
Write-Host "=============================================================================="
Write-Host $r
Write-Host ($r | ConvertTo-Json)
Write-Host "=============================================================================="
}
if ($r -match "errorModalMessage") {
Throw-Error -Req $r -Alt "Could not retrieve languages from server"
if ($r.Errors) {
if ($attempt++ -le 1) { continue }
throw $r.Errors[0].Value
}
$r = $r -replace "`n" -replace "`r"
$pattern = '.*<select id="product-languages"[^>]*>(.*)</select>.*'
$html = [regex]::Match($r, $pattern).Groups[1].Value
# Go through an XML conversion to keep all PowerShells happy...
$html = $html.Replace("selected value", "value")
$html = "<options>" + $html + "</options>"
$xml = [xml]$html
foreach ($var in $xml.options.option) {
$json = $var.value | ConvertFrom-Json;
if ($json) {
if (!$languages.Contains($json.language)) {
$languages[$json.language] = @{ DisplayName = $var.InnerText; Data = @() }
}
$languages[$json.language].Data += @{ SessionIndex = $SessionIndex; SkuId = $json.id }
foreach ($Sku in $r.Skus) {
if (!$languages.Contains($Sku.Language)) {
$languages[$Sku.Language] = @{ DisplayName = $Sku.LocalizedLanguage; Data = @() }
}
$languages[$Sku.Language].Data += @{ SessionIndex = $SessionIndex; SkuId = $Sku.Id }
}
if ($languages.Length -eq 0) {
Throw-Error -Req $r -Alt "Could not parse languages"
if ($attempt++ -le 1) { continue }
throw "Could not parse languages"
}
break;
}
} catch {
Error($_.Exception.Message)
@@ -682,65 +751,48 @@ function Get-Windows-Download-Links([int]$SelectedVersion, [int]$SelectedRelease
$archs += $sep + $arch
$sep = ", "
}
$links += @(New-Object PsObject -Property @{ Type = $archs; Url = $link })
$links += @(New-Object PsObject -Property @{ Arch = $archs; Url = $link })
} catch {
Error($_.Exception.Message)
return @()
}
} else {
foreach ($Entry in $SelectedLanguage.Data) {
$url = "https://www.microsoft.com/" + $QueryLocale + "/api/controls/contentinclude/html"
$url += "?pageId=" + $RequestData["GetLinks"][0]
$url += "&host=www.microsoft.com"
$url += "&segments=software-download," + $WindowsVersions[$SelectedVersion][0][1]
$url += "&query=&action=" + $RequestData["GetLinks"][1]
$url += "&sessionId=" + $SessionId[$Entry.SessionIndex]
$url += "&skuId=" + $Entry.SkuId
$url += "&language=" + $SelectedLanguage.Name
$url += "&sdVersion=2"
$url = "https://www.microsoft.com/software-download-connector/api/GetProductDownloadLinksBySku"
$url += "?profile=" + $ProfileId
$url += "&productEditionId=undefined"
$url += "&SKU=" + $Entry.SkuId
$url += "&friendlyFileName=undefined"
$url += "&Locale=" + $QueryLocale
$url += "&sessionID=" + $SessionId[$Entry.SessionIndex]
if ($Verbosity -ge 2) {
Write-Host Querying $url
}
try {
# Must add a referer for this request, else Microsoft's servers will deny it
# Must add a referer for this request, else Microsoft's servers may deny it
$ref = "https://www.microsoft.com/software-download/windows11"
$r = Invoke-WebRequest -Method Post -Headers @{ "Referer" = $ref } -UseBasicParsing -TimeoutSec $DefaultTimeout -UserAgent $UserAgent -WebSession $Session $url
$r = Invoke-RestMethod -Headers @{ "Referer" = $ref } -UseBasicParsing -TimeoutSec $DefaultTimeout -SessionVariable "Session" $url
if ($r -eq $null) {
throw "Could not retrieve architectures from server"
}
if ($Verbosity -ge 5) {
Write-Host "=============================================================================="
Write-Host $r
Write-Host ($r | ConvertTo-Json)
Write-Host "=============================================================================="
}
if ($r -match "errorModalMessage") {
$Alt = [regex]::Match($r.Content, '<p id="errorModalMessage">(.+?)<\/p>').Groups[1].Value -replace "<[^>]+>" -replace "\s+", " " -replace "\?\?\?", "-"
$Alt = [System.Text.Encoding]::UTF8.GetString([byte[]][char[]]$Alt)
if (!$Alt) {
$Alt = "Could not retrieve architectures from server"
} elseif ($Alt -match "715-123130") {
$Alt += " " + $SessionId[$Entry.SessionIndex] + "."
if ($r.Errors) {
if ( $r.Errors[0].Type -eq 9) {
$msg = Get-Code-715-123130-Message
throw $msg + $SessionId[$Entry.SessionIndex] + "."
} else {
throw $r.Errors[0].Value
}
Throw-Error -Req $r -Alt $Alt
}
$pattern = '(?s)(<input.*?></input>)'
ForEach-Object { [regex]::Matches($r, $pattern) } | ForEach-Object { $html += $_.Groups[1].value }
# Need to fix the HTML and JSON data so that it is well-formed
$html = $html.Replace("class=product-download-hidden", "")
$html = $html.Replace("type=hidden", "")
$html = $html.Replace("&nbsp;", " ")
$html = $html.Replace("IsoX86", "&quot;x86&quot;")
$html = $html.Replace("IsoX64", "&quot;x64&quot;")
# As usual Microsoft's left hand is completely uncoordinated with right hand
$html = $html.Replace("Unknown", "&quot;ARM64&quot;")
$html = "<inputs>" + $html + "</inputs>"
$xml = [xml]$html
foreach ($var in $xml.inputs.input) {
$json = $var.value | ConvertFrom-Json;
if ($json) {
$links += @(New-Object PsObject -Property @{ Type = $json.DownloadType; Url = $json.Uri })
}
foreach ($ProductDownloadOption in $r.ProductDownloadOptions) {
$links += @(New-Object PsObject -Property @{ Arch = (Get-Arch-From-Type $ProductDownloadOption.DownloadType); Url = $ProductDownloadOption.Uri })
}
if ($links.Length -eq 0) {
Throw-Error -Req $r -Alt "Could not retrieve ISO download links"
throw "Could not retrieve ISO download links"
}
} catch {
Error($_.Exception.Message)
@@ -751,7 +803,7 @@ function Get-Windows-Download-Links([int]$SelectedVersion, [int]$SelectedRelease
$i = 0
$script:SelectedIndex = 0
foreach($link in $links) {
if ($link.Type -eq $PlatformArch) {
if ($link.Arch -eq $PlatformArch) {
$script:SelectedIndex = $i
}
$i++
@@ -921,12 +973,12 @@ if ($Cmd) {
$i = 0
foreach ($link in $links) {
if ($Arch -eq "List") {
Write-Host " -" $link.Type
} elseif ((!$Arch -and $script:SelectedIndex -eq $i) -or ($Arch -and $link.Type -match $Arch)) {
Write-Host " -" $link.Arch
} elseif ((!$Arch -and $script:SelectedIndex -eq $i) -or ($Arch -and $link.Arch -match $Arch)) {
if (!$Arch -and $Verbosity -ge 1) {
Write-Host "No architecture specified (-Arch). Defaulting to '$($link.Type)'."
Write-Host "No architecture specified (-Arch). Defaulting to '$($link.Arch)'."
}
$Selected += ", [" + $link.Type + "]"
$Selected += ", [" + $link.Arch + "]"
$winLink = $link
break;
}
@@ -1032,7 +1084,7 @@ $Continue.add_click({
if ($links.Length -eq 0) {
break
}
$script:Architecture = Add-Entry $Stage "Architecture" $links "Type"
$script:Architecture = Add-Entry $Stage "Architecture" $links "Arch"
if ($PipeName) {
$XMLForm.Height += $dh / 2;
$Margin = $Continue.Margin
@@ -1102,10 +1154,10 @@ $XMLForm.ShowDialog() | Out-Null
exit $ExitCode
# SIG # Begin signature block
# MIItPAYJKoZIhvcNAQcCoIItLTCCLSkCAQExDzANBglghkgBZQMEAgEFADB5Bgor
# MIIteAYJKoZIhvcNAQcCoIItaTCCLWUCAQExDzANBglghkgBZQMEAgEFADB5Bgor
# BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG
# KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCDFXTWq2lpU/6fR
# Ct1W7yWDg6b1THz8JSMDTQ5AW7weJ6CCEkAwggVvMIIEV6ADAgECAhBI/JO0YFWU
# KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCDXxwqFQe5xW86J
# EJEwCZ5i7/F9Quz1+UVh86bzDD0Ep6CCEkAwggVvMIIEV6ADAgECAhBI/JO0YFWU
# jTanyYqJ1pQWMA0GCSqGSIb3DQEBDAUAMHsxCzAJBgNVBAYTAkdCMRswGQYDVQQI
# DBJHcmVhdGVyIE1hbmNoZXN0ZXIxEDAOBgNVBAcMB1NhbGZvcmQxGjAYBgNVBAoM
# EUNvbW9kbyBDQSBMaW1pdGVkMSEwHwYDVQQDDBhBQUEgQ2VydGlmaWNhdGUgU2Vy
@@ -1202,146 +1254,147 @@ exit $ExitCode
# 4a6KRpYwLMYE9/ZBEBP7JpfiMt42q+QF6fyS8xauGiOGBOZW4ch7Wh+GBoe3JZUu
# UPC4wZDC9LeRKz/otodtloaTEnW9YE9gPmfRttMWaNsQTg6y5sc74qLoVY0RSqcW
# B2KScXAjuVHVkJJcOoPSuLoTjOhK3Ug4XbQmRypdteoizdTSnONGmW84RJyXquzi
# rIjw9CnLTggrZiYi9EZTo7URWNaARqLbSFpu0VMkdOBpWdXq5F6x6jslMYIaUjCC
# Gk4CAQEwazBXMQswCQYDVQQGEwJHQjEYMBYGA1UEChMPU2VjdGlnbyBMaW1pdGVk
# rIjw9CnLTggrZiYi9EZTo7URWNaARqLbSFpu0VMkdOBpWdXq5F6x6jslMYIajjCC
# GooCAQEwazBXMQswCQYDVQQGEwJHQjEYMBYGA1UEChMPU2VjdGlnbyBMaW1pdGVk
# MS4wLAYDVQQDEyVTZWN0aWdvIFB1YmxpYyBDb2RlIFNpZ25pbmcgQ0EgRVYgUjM2
# AhA3xQo8HaADcccNx8YmkC/lMA0GCWCGSAFlAwQCAQUAoHwwEAYKKwYBBAGCNwIB
# DDECMAAwGQYJKoZIhvcNAQkDMQwGCisGAQQBgjcCAQQwHAYKKwYBBAGCNwIBCzEO
# MAwGCisGAQQBgjcCARUwLwYJKoZIhvcNAQkEMSIEIJOGS5HWMc2rDXvPKvX2nFz6
# Kgz3N3nMaspPXtcMKTojMA0GCSqGSIb3DQEBAQUABIICAJ74B4pGm7vaEYuhs3NT
# DVwFMiBWnu7mul6K6Van7Itz0bECfra3r9wpUvcsAoOKEqZ9VX1AmJ/zoIQhQgq3
# gPMhbPLeJuIwnjExCLHSwaJ9tXbETIMX50vMBOt6aLsVgnzT2VJTC5UTzvwcW/Lm
# Gaucxnm1bFMNmTMdeOZFLPZBB+WPaJ3dT2lgNU/usB0DyF+i5ilFPFUzesrMDzcV
# x+ijkEOz1jxNxXGbTotPvXjMPkUnBIaYsTmeKhrzn085p8O5l0eUAqjEnYPvAq/n
# WSvpohmXZa3V7pWRum5XPZ2fe4cs6GjMYmdmD+8ovW4G6KVbNkf75JFKJZ82Y9lq
# qn4VO0r5vV4ffD0erFF/KGTavhvz/VlG2par1O/jfa6ue9yPaLLpWiynThz9/lGI
# zbvmAGJuIxCjRcA/Dp/QRkl1a8+VvXtaopd3hQTwgHhlXhnOLKzDKuLoJd9CsDPL
# 0krYSqps1PD7sAdpr4rx4Gkv+iT9vLJYD+N9KSpfW8BmrHKaKp2BnK79ERxo4fQm
# bagOlVCX/FBmSYU+HW52fb2b9fwS7xVupOoruHiIksjTy7YWNgck3CW4WVKxp35y
# i6SEO4u+1ivx9uhIYQnDJ4mEcezLU1QBFoc5UG6IW1QgbnYVbBwhlrp/poF90NHp
# TC2UDXb1m+JfMPdjaOBZdothoYIXOjCCFzYGCisGAQQBgjcDAwExghcmMIIXIgYJ
# KoZIhvcNAQcCoIIXEzCCFw8CAQMxDzANBglghkgBZQMEAgEFADB4BgsqhkiG9w0B
# CRABBKBpBGcwZQIBAQYJYIZIAYb9bAcBMDEwDQYJYIZIAWUDBAIBBQAEIBw/qIiW
# ZirjZAJAqvzJLoq2PiAMMR2U/b8N3B7swhynAhEArbB7KWdDox91SH7wp5yr5hgP
# MjAyNDExMTgwMTQzNDFaoIITAzCCBrwwggSkoAMCAQICEAuuZrxaun+Vh8b56QTj
# MwQwDQYJKoZIhvcNAQELBQAwYzELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDkRpZ2lD
# ZXJ0LCBJbmMuMTswOQYDVQQDEzJEaWdpQ2VydCBUcnVzdGVkIEc0IFJTQTQwOTYg
# U0hBMjU2IFRpbWVTdGFtcGluZyBDQTAeFw0yNDA5MjYwMDAwMDBaFw0zNTExMjUy
# MzU5NTlaMEIxCzAJBgNVBAYTAlVTMREwDwYDVQQKEwhEaWdpQ2VydDEgMB4GA1UE
# AxMXRGlnaUNlcnQgVGltZXN0YW1wIDIwMjQwggIiMA0GCSqGSIb3DQEBAQUAA4IC
# DwAwggIKAoICAQC+anOf9pUhq5Ywultt5lmjtej9kR8YxIg7apnjpcH9CjAgQxK+
# CMR0Rne/i+utMeV5bUlYYSuuM4vQngvQepVHVzNLO9RDnEXvPghCaft0djvKKO+h
# Du6ObS7rJcXa/UKvNminKQPTv/1+kBPgHGlP28mgmoCw/xi6FG9+Un1h4eN6zh92
# 6SxMe6We2r1Z6VFZj75MU/HNmtsgtFjKfITLutLWUdAoWle+jYZ49+wxGE1/UXjW
# fISDmHuI5e/6+NfQrxGFSKx+rDdNMsePW6FLrphfYtk/FLihp/feun0eV+pIF496
# OVh4R1TvjQYpAztJpVIfdNsEvxHofBf1BWkadc+Up0Th8EifkEEWdX4rA/FE1Q0r
# qViTbLVZIqi6viEk3RIySho1XyHLIAOJfXG5PEppc3XYeBH7xa6VTZ3rOHNeiYnY
# +V4j1XbJ+Z9dI8ZhqcaDHOoj5KGg4YuiYx3eYm33aebsyF6eD9MF5IDbPgjvwmnA
# alNEeJPvIeoGJXaeBQjIK13SlnzODdLtuThALhGtyconcVuPI8AaiCaiJnfdzUcb
# 3dWnqUnjXkRFwLtsVAxFvGqsxUA2Jq/WTjbnNjIUzIs3ITVC6VBKAOlb2u29Vwgf
# ta8b2ypi6n2PzP0nVepsFk8nlcuWfyZLzBaZ0MucEdeBiXL+nUOGhCjl+QIDAQAB
# o4IBizCCAYcwDgYDVR0PAQH/BAQDAgeAMAwGA1UdEwEB/wQCMAAwFgYDVR0lAQH/
# BAwwCgYIKwYBBQUHAwgwIAYDVR0gBBkwFzAIBgZngQwBBAIwCwYJYIZIAYb9bAcB
# MB8GA1UdIwQYMBaAFLoW2W1NhS9zKXaaL3WMaiCPnshvMB0GA1UdDgQWBBSfVywD
# dw4oFZBmpWNe7k+SH3agWzBaBgNVHR8EUzBRME+gTaBLhklodHRwOi8vY3JsMy5k
# aWdpY2VydC5jb20vRGlnaUNlcnRUcnVzdGVkRzRSU0E0MDk2U0hBMjU2VGltZVN0
# YW1waW5nQ0EuY3JsMIGQBggrBgEFBQcBAQSBgzCBgDAkBggrBgEFBQcwAYYYaHR0
# cDovL29jc3AuZGlnaWNlcnQuY29tMFgGCCsGAQUFBzAChkxodHRwOi8vY2FjZXJ0
# cy5kaWdpY2VydC5jb20vRGlnaUNlcnRUcnVzdGVkRzRSU0E0MDk2U0hBMjU2VGlt
# ZVN0YW1waW5nQ0EuY3J0MA0GCSqGSIb3DQEBCwUAA4ICAQA9rR4fdplb4ziEEkfZ
# Q5H2EdubTggd0ShPz9Pce4FLJl6reNKLkZd5Y/vEIqFWKt4oKcKz7wZmXa5VgW9B
# 76k9NJxUl4JlKwyjUkKhk3aYx7D8vi2mpU1tKlY71AYXB8wTLrQeh83pXnWwwsxc
# 1Mt+FWqz57yFq6laICtKjPICYYf/qgxACHTvypGHrC8k1TqCeHk6u4I/VBQC9VK7
# iSpU5wlWjNlHlFFv/M93748YTeoXU/fFa9hWJQkuzG2+B7+bMDvmgF8VlJt1qQcl
# 7YFUMYgZU1WM6nyw23vT6QSgwX5Pq2m0xQ2V6FJHu8z4LXe/371k5QrN9FQBhLLI
# SZi2yemW0P8ZZfx4zvSWzVXpAb9k4Hpvpi6bUe8iK6WonUSV6yPlMwerwJZP/Gtb
# u3CKldMnn+LmmRTkTXpFIEB06nXZrDwhCGED+8RsWQSIXZpuG4WLFQOhtloDRWGo
# Cwwc6ZpPddOFkM2LlTbMcqFSzm4cd0boGhBq7vkqI1uHRz6Fq1IX7TaRQuR+0BGO
# zISkcqwXu7nMpFu3mgrlgbAW+BzikRVQ3K2YHcGkiKjA4gi4OA/kz1YCsdhIBHXq
# BzR0/Zd2QwQ/l4Gxftt/8wY3grcc/nS//TVkej9nmUYu83BDtccHHXKibMs/yXHh
# DXNkoPIdynhVAku7aRZOwqw6pDCCBq4wggSWoAMCAQICEAc2N7ckVHzYR6z9KGYq
# XlswDQYJKoZIhvcNAQELBQAwYjELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lD
# MAwGCisGAQQBgjcCARUwLwYJKoZIhvcNAQkEMSIEIA43JqiFG1pUsW+VWG66vNSe
# WesQeLIJDvPNjARLSjVJMA0GCSqGSIb3DQEBAQUABIICAI/rQjgUfZ9bWfkmeR+B
# EeezCi04TCBW9ngtWAeSqGW8k2qdm2H3uoyPqO/78QwNHpKDi33VDXUmh+hGql9K
# pmfpVVP6dKvG5EQdclGYcP/sK7f77+EGZL7BGP08MP2k6NXvEAPvpvmJST2v3cM+
# hktF0wQD8s/BWE3/FgrKUJMwIeG15ZQ1KG00xFXJjMl+CDpedNheeg46eU1iSe1R
# wPsCh+MYw7Mu/31h1AAEu2gmVBmp23+CYaoSOfdQFfC4Pa2phg7e3UUVa5TAwfrX
# KlWunPbh4U5reMa+1Z8vKGYAOOGw2/wDiI3Kg5dGczOxPvQBNGYjrovYW9DD0E1w
# ev5VtzLjmvQWjHg6Vp64JIcOmEQEcThZ/GUPDoS9SQfUpv9/a4siuHmiFhmX+Y0z
# ANVClEqN7/AW1C9c1LgWdxSZilENds8SS3BrFVDW/8ayvVEUHOLJLvux9anRgZP8
# IDosOS+rY6T2+S0eGg69rGxwDmtVgEA8N2Ev7odXEkxPB9+UWrtnwSa4LTd3Y6rZ
# ucL8MngWdNGMfXCKqlrRpK6SBNRtzxbFj7fZwAT2X6oOXieNLNcLvX5wKc9Vv1Vu
# mntM0SzZUKXin6CWgtpl6MBFy+hNNM2iazm/WXSUyC7AQEPdoYTlmahOFTOABhJK
# H6w2jf+SzXOpUwUe38vEX0tMoYIXdjCCF3IGCisGAQQBgjcDAwExghdiMIIXXgYJ
# KoZIhvcNAQcCoIIXTzCCF0sCAQMxDzANBglghkgBZQMEAgEFADB3BgsqhkiG9w0B
# CRABBKBoBGYwZAIBAQYJYIZIAYb9bAcBMDEwDQYJYIZIAWUDBAIBBQAEII+chtKC
# FdhcHUp7wTlYBcSyaAed68xF7aTBmMLNlxxnAhAVhSZL8NVuXAVE4r+F6WQ8GA8y
# MDI2MDIyNzE2NTIyMVqgghM6MIIG7TCCBNWgAwIBAgIQCoDvGEuN8QWC0cR2p5V0
# aDANBgkqhkiG9w0BAQsFADBpMQswCQYDVQQGEwJVUzEXMBUGA1UEChMORGlnaUNl
# cnQsIEluYy4xQTA/BgNVBAMTOERpZ2lDZXJ0IFRydXN0ZWQgRzQgVGltZVN0YW1w
# aW5nIFJTQTQwOTYgU0hBMjU2IDIwMjUgQ0ExMB4XDTI1MDYwNDAwMDAwMFoXDTM2
# MDkwMzIzNTk1OVowYzELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDkRpZ2lDZXJ0LCBJ
# bmMuMTswOQYDVQQDEzJEaWdpQ2VydCBTSEEyNTYgUlNBNDA5NiBUaW1lc3RhbXAg
# UmVzcG9uZGVyIDIwMjUgMTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIB
# ANBGrC0Sxp7Q6q5gVrMrV7pvUf+GcAoB38o3zBlCMGMyqJnfFNZx+wvA69HFTBdw
# bHwBSOeLpvPnZ8ZN+vo8dE2/pPvOx/Vj8TchTySA2R4QKpVD7dvNZh6wW2R6kSu9
# RJt/4QhguSssp3qome7MrxVyfQO9sMx6ZAWjFDYOzDi8SOhPUWlLnh00Cll8pjrU
# cCV3K3E0zz09ldQ//nBZZREr4h/GI6Dxb2UoyrN0ijtUDVHRXdmncOOMA3CoB/iU
# SROUINDT98oksouTMYFOnHoRh6+86Ltc5zjPKHW5KqCvpSduSwhwUmotuQhcg9tw
# 2YD3w6ySSSu+3qU8DD+nigNJFmt6LAHvH3KSuNLoZLc1Hf2JNMVL4Q1OpbybpMe4
# 6YceNA0LfNsnqcnpJeItK/DhKbPxTTuGoX7wJNdoRORVbPR1VVnDuSeHVZlc4seA
# O+6d2sC26/PQPdP51ho1zBp+xUIZkpSFA8vWdoUoHLWnqWU3dCCyFG1roSrgHjSH
# lq8xymLnjCbSLZ49kPmk8iyyizNDIXj//cOgrY7rlRyTlaCCfw7aSUROwnu7zER6
# EaJ+AliL7ojTdS5PWPsWeupWs7NpChUk555K096V1hE0yZIXe+giAwW00aHzrDch
# Ic2bQhpp0IoKRR7YufAkprxMiXAJQ1XCmnCfgPf8+3mnAgMBAAGjggGVMIIBkTAM
# BgNVHRMBAf8EAjAAMB0GA1UdDgQWBBTkO/zyMe39/dfzkXFjGVBDz2GM6DAfBgNV
# HSMEGDAWgBTvb1NK6eQGfHrK4pBW9i/USezLTjAOBgNVHQ8BAf8EBAMCB4AwFgYD
# VR0lAQH/BAwwCgYIKwYBBQUHAwgwgZUGCCsGAQUFBwEBBIGIMIGFMCQGCCsGAQUF
# BzABhhhodHRwOi8vb2NzcC5kaWdpY2VydC5jb20wXQYIKwYBBQUHMAKGUWh0dHA6
# Ly9jYWNlcnRzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydFRydXN0ZWRHNFRpbWVTdGFt
# cGluZ1JTQTQwOTZTSEEyNTYyMDI1Q0ExLmNydDBfBgNVHR8EWDBWMFSgUqBQhk5o
# dHRwOi8vY3JsMy5kaWdpY2VydC5jb20vRGlnaUNlcnRUcnVzdGVkRzRUaW1lU3Rh
# bXBpbmdSU0E0MDk2U0hBMjU2MjAyNUNBMS5jcmwwIAYDVR0gBBkwFzAIBgZngQwB
# BAIwCwYJYIZIAYb9bAcBMA0GCSqGSIb3DQEBCwUAA4ICAQBlKq3xHCcEua5gQezR
# CESeY0ByIfjk9iJP2zWLpQq1b4URGnwWBdEZD9gBq9fNaNmFj6Eh8/YmRDfxT7C0
# k8FUFqNh+tshgb4O6Lgjg8K8elC4+oWCqnU/ML9lFfim8/9yJmZSe2F8AQ/UdKFO
# tj7YMTmqPO9mzskgiC3QYIUP2S3HQvHG1FDu+WUqW4daIqToXFE/JQ/EABgfZXLW
# U0ziTN6R3ygQBHMUBaB5bdrPbF6MRYs03h4obEMnxYOX8VBRKe1uNnzQVTeLni2n
# HkX/QqvXnNb+YkDFkxUGtMTaiLR9wjxUxu2hECZpqyU1d0IbX6Wq8/gVutDojBIF
# eRlqAcuEVT0cKsb+zJNEsuEB7O7/cuvTQasnM9AWcIQfVjnzrvwiCZ85EE8LUkqR
# hoS3Y50OHgaY7T/lwd6UArb+BOVAkg2oOvol/DJgddJ35XTxfUlQ+8Hggt8l2Yv7
# roancJIFcbojBcxlRcGG0LIhp6GvReQGgMgYxQbV1S3CrWqZzBt1R9xJgKf47Cdx
# VRd/ndUlQ05oxYy2zRWVFjF7mcr4C34Mj3ocCVccAvlKV9jEnstrniLvUxxVZE/r
# ptb7IRE2lskKPIJgbaP5t2nGj/ULLi49xTcBZU8atufk+EMF/cWuiC7POGT75qaL
# 6vdCvHlshtjdNXOCIUjsarfNZzCCBrQwggScoAMCAQICEA3HrFcF/yGZLkBDIgw6
# SYYwDQYJKoZIhvcNAQELBQAwYjELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lD
# ZXJ0IEluYzEZMBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTEhMB8GA1UEAxMYRGln
# aUNlcnQgVHJ1c3RlZCBSb290IEc0MB4XDTIyMDMyMzAwMDAwMFoXDTM3MDMyMjIz
# NTk1OVowYzELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDkRpZ2lDZXJ0LCBJbmMuMTsw
# OQYDVQQDEzJEaWdpQ2VydCBUcnVzdGVkIEc0IFJTQTQwOTYgU0hBMjU2IFRpbWVT
# dGFtcGluZyBDQTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMaGNQZJ
# s8E9cklRVcclA8TykTepl1Gh1tKD0Z5Mom2gsMyD+Vr2EaFEFUJfpIjzaPp985yJ
# C3+dH54PMx9QEwsmc5Zt+FeoAn39Q7SE2hHxc7Gz7iuAhIoiGN/r2j3EF3+rGSs+
# QtxnjupRPfDWVtTnKC3r07G1decfBmWNlCnT2exp39mQh0YAe9tEQYncfGpXevA3
# eZ9drMvohGS0UvJ2R/dhgxndX7RUCyFobjchu0CsX7LeSn3O9TkSZ+8OpWNs5KbF
# Hc02DVzV5huowWR0QKfAcsW6Th+xtVhNef7Xj3OTrCw54qVI1vCwMROpVymWJy71
# h6aPTnYVVSZwmCZ/oBpHIEPjQ2OAe3VuJyWQmDo4EbP29p7mO1vsgd4iFNmCKseS
# v6De4z6ic/rnH1pslPJSlRErWHRAKKtzQ87fSqEcazjFKfPKqpZzQmiftkaznTqj
# 1QPgv/CiPMpC3BhIfxQ0z9JMq++bPf4OuGQq+nUoJEHtQr8FnGZJUlD0UfM2SU2L
# INIsVzV5K6jzRWC8I41Y99xh3pP+OcD5sjClTNfpmEpYPtMDiP6zj9NeS3YSUZPJ
# jAw7W4oiqMEmCPkUEBIDfV8ju2TjY+Cm4T72wnSyPx4JduyrXUZ14mCjWAkBKAAO
# hFTuzuldyF4wEr1GnrXTdrnSDmuZDNIztM2xAgMBAAGjggFdMIIBWTASBgNVHRMB
# Af8ECDAGAQH/AgEAMB0GA1UdDgQWBBS6FtltTYUvcyl2mi91jGogj57IbzAfBgNV
# HSMEGDAWgBTs1+OC0nFdZEzfLmc/57qYrhwPTzAOBgNVHQ8BAf8EBAMCAYYwEwYD
# VR0lBAwwCgYIKwYBBQUHAwgwdwYIKwYBBQUHAQEEazBpMCQGCCsGAQUFBzABhhho
# dHRwOi8vb2NzcC5kaWdpY2VydC5jb20wQQYIKwYBBQUHMAKGNWh0dHA6Ly9jYWNl
# cnRzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydFRydXN0ZWRSb290RzQuY3J0MEMGA1Ud
# HwQ8MDowOKA2oDSGMmh0dHA6Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydFRy
# dXN0ZWRSb290RzQuY3JsMCAGA1UdIAQZMBcwCAYGZ4EMAQQCMAsGCWCGSAGG/WwH
# ATANBgkqhkiG9w0BAQsFAAOCAgEAfVmOwJO2b5ipRCIBfmbW2CFC4bAYLhBNE88w
# U86/GPvHUF3iSyn7cIoNqilp/GnBzx0H6T5gyNgL5Vxb122H+oQgJTQxZ822EpZv
# xFBMYh0MCIKoFr2pVs8Vc40BIiXOlWk/R3f7cnQU1/+rT4osequFzUNf7WC2qk+R
# Zp4snuCKrOX9jLxkJodskr2dfNBwCnzvqLx1T7pa96kQsl3p/yhUifDVinF2ZdrM
# 8HKjI/rAJ4JErpknG6skHibBt94q6/aesXmZgaNWhqsKRcnfxI2g55j7+6adcq/E
# x8HBanHZxhOACcS2n82HhyS7T6NJuXdmkfFynOlLAlKnN36TU6w7HQhJD5TNOXrd
# /yVjmScsPT9rp/Fmw0HNT7ZAmyEhQNC3EyTN3B14OuSereU0cZLXJmvkOHOrpgFP
# vT87eK1MrfvElXvtCl8zOYdBeHo46Zzh3SP9HSjTx/no8Zhf+yvYfvJGnXUsHics
# JttvFXseGYs2uJPU5vIXmVnKcPA3v5gA3yAWTyf7YGcWoWa63VXAOimGsJigK+2V
# Qbc61RWYMbRiCQ8KvYHZE/6/pNHzV9m8BPqC3jLfBInwAM1dwvnQI38AC+R2AibZ
# 8GV2QqYphwlHK+Z/GqSFD/yYlvZVVCsfgPrA8g4r5db7qS9EFUrnEw4d2zc4GqEr
# 9u3WfPwwggWNMIIEdaADAgECAhAOmxiO+dAt5+/bUOIIQBhaMA0GCSqGSIb3DQEB
# DAUAMGUxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNV
# BAsTEHd3dy5kaWdpY2VydC5jb20xJDAiBgNVBAMTG0RpZ2lDZXJ0IEFzc3VyZWQg
# SUQgUm9vdCBDQTAeFw0yMjA4MDEwMDAwMDBaFw0zMTExMDkyMzU5NTlaMGIxCzAJ
# BgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5k
# aWdpY2VydC5jb20xITAfBgNVBAMTGERpZ2lDZXJ0IFRydXN0ZWQgUm9vdCBHNDCC
# AiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAL/mkHNo3rvkXUo8MCIwaTPs
# wqclLskhPfKK2FnC4SmnPVirdprNrnsbhA3EMB/zG6Q4FutWxpdtHauyefLKEdLk
# X9YFPFIPUh/GnhWlfr6fqVcWWVVyr2iTcMKyunWZanMylNEQRBAu34LzB4TmdDtt
# ceItDBvuINXJIB1jKS3O7F5OyJP4IWGbNOsFxl7sWxq868nPzaw0QF+xembud8hI
# qGZXV59UWI4MK7dPpzDZVu7Ke13jrclPXuU15zHL2pNe3I6PgNq2kZhAkHnDeMe2
# scS1ahg4AxCN2NQ3pC4FfYj1gj4QkXCrVYJBMtfbBHMqbpEBfCFM1LyuGwN1XXhm
# 2ToxRJozQL8I11pJpMLmqaBn3aQnvKFPObURWBf3JFxGj2T3wWmIdph2PVldQnaH
# iZdpekjw4KISG2aadMreSx7nDmOu5tTvkpI6nj3cAORFJYm2mkQZK37AlLTSYW3r
# M9nF30sEAMx9HJXDj/chsrIRt7t/8tWMcCxBYKqxYxhElRp2Yn72gLD76GSmM9GJ
# B+G9t+ZDpBi4pncB4Q+UDCEdslQpJYls5Q5SUUd0viastkF13nqsX40/ybzTQRES
# W+UQUOsxxcpyFiIJ33xMdT9j7CFfxCBRa2+xq4aLT8LWRV+dIPyhHsXAj6Kxfgom
# mfXkaS+YHS312amyHeUbAgMBAAGjggE6MIIBNjAPBgNVHRMBAf8EBTADAQH/MB0G
# A1UdDgQWBBTs1+OC0nFdZEzfLmc/57qYrhwPTzAfBgNVHSMEGDAWgBRF66Kv9JLL
# gjEtUYunpyGd823IDzAOBgNVHQ8BAf8EBAMCAYYweQYIKwYBBQUHAQEEbTBrMCQG
# CCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdpY2VydC5jb20wQwYIKwYBBQUHMAKG
# N2h0dHA6Ly9jYWNlcnRzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJRFJv
# b3RDQS5jcnQwRQYDVR0fBD4wPDA6oDigNoY0aHR0cDovL2NybDMuZGlnaWNlcnQu
# Y29tL0RpZ2lDZXJ0QXNzdXJlZElEUm9vdENBLmNybDARBgNVHSAECjAIMAYGBFUd
# IAAwDQYJKoZIhvcNAQEMBQADggEBAHCgv0NcVec4X6CjdBs9thbX979XB72arKGH
# LOyFXqkauyL4hxppVCLtpIh3bb0aFPQTSnovLbc47/T/gLn4offyct4kvFIDyE7Q
# Kt76LVbP+fT3rDB6mouyXtTP0UNEm0Mh65ZyoUi0mcudT6cGAxN3J0TU53/oWajw
# vy8LpunyNDzs9wPHh6jSTEAZNUZqaVSwuKFWjuyk1T3osdz9HNj0d1pcVIxv76FQ
# Pfx2CWiEn2/K2yCNNWAcAgPLILCsWKAOQGPFmCLBsln1VWvPJ6tsds5vIy30fnFq
# I2si/xK4VC0nftg62fC2h5b9W9FcrBjDTZ9ztwGpn1eqXijiuZQxggN2MIIDcgIB
# ATB3MGMxCzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5EaWdpQ2VydCwgSW5jLjE7MDkG
# A1UEAxMyRGlnaUNlcnQgVHJ1c3RlZCBHNCBSU0E0MDk2IFNIQTI1NiBUaW1lU3Rh
# bXBpbmcgQ0ECEAuuZrxaun+Vh8b56QTjMwQwDQYJYIZIAWUDBAIBBQCggdEwGgYJ
# KoZIhvcNAQkDMQ0GCyqGSIb3DQEJEAEEMBwGCSqGSIb3DQEJBTEPFw0yNDExMTgw
# MTQzNDFaMCsGCyqGSIb3DQEJEAIMMRwwGjAYMBYEFNvThe5i29I+e+T2cUhQhyTV
# hltFMC8GCSqGSIb3DQEJBDEiBCCLPWAm+aNyc4DrqvDwqzC7ow3BipFMugVd26EO
# cUUgxTA3BgsqhkiG9w0BCRACLzEoMCYwJDAiBCB2dp+o8mMvH0MLOiMwrtZWdf7X
# c9sF1mW5BZOYQ4+a2zANBgkqhkiG9w0BAQEFAASCAgA1D9F+ChwLLlPfrnjVN7y8
# Raa08Q1yJoUiIPZw/m4rknXNCjyL768gux2rys7Y0ofhaTL8qB2U5605DNmkuDAw
# NwDXME2bka4xBxDJrI43XFVtu3SpKRbNcv5ujZs0jF4gA3GQykM9UahyusmaxwtQ
# DILavBxCuVye9HX86Z1Bdac1wCWY6hvbtoT4ffm+/Uondgh8VzEWd36ImGOpAXQM
# +UOR8t4JG5777yIBTv51W3qnEx7e4bazezEXIgC7DdXFSq18ypjJuCkLMrb2bWgp
# /CxGT2ff4itbsv8Z++oJI2oOewhlLiA5tVMkbB0lVGQbkeEP4nqUKwAvOt7g1i7f
# uSxGdoNbaesSNefScqii1OTXHsLSjNciRQQJZMxJI44F15X7LOVdaaIbvgoLfIWy
# T9s+OgUxmAvDdZKpRcHO//tW6JqFCoi+gdW04mUSvME+MRx6RFZe1cjZNPpJEnwh
# kmKGhndTmaBjg1nJH0okrfmR87jjIhulemrdJsUZtcdzCBxT1gW5AaHFOMUuHBkR
# P9h0VG3f12fejgEotaDyTmPYBazFlwSrXtrr1uFmS0SDw681z5xGjK92279MlUpo
# 8RBOupy5LSPC59Oi1j7SSeW+xyBfS+0aiyKEAYfk1qO0f3Eql9kTQBZjaizDdKmq
# ubbhLFZ/dE5qax8nkz2Rxw==
# aUNlcnQgVHJ1c3RlZCBSb290IEc0MB4XDTI1MDUwNzAwMDAwMFoXDTM4MDExNDIz
# NTk1OVowaTELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDkRpZ2lDZXJ0LCBJbmMuMUEw
# PwYDVQQDEzhEaWdpQ2VydCBUcnVzdGVkIEc0IFRpbWVTdGFtcGluZyBSU0E0MDk2
# IFNIQTI1NiAyMDI1IENBMTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIB
# ALR4MdMKmEFyvjxGwBysddujRmh0tFEXnU2tjQ2UtZmWgyxU7UNqEY81FzJsQqr5
# G7A6c+Gh/qm8Xi4aPCOo2N8S9SLrC6Kbltqn7SWCWgzbNfiR+2fkHUiljNOqnIVD
# /gG3SYDEAd4dg2dDGpeZGKe+42DFUF0mR/vtLa4+gKPsYfwEu7EEbkC9+0F2w4QJ
# LVSTEG8yAR2CQWIM1iI5PHg62IVwxKSpO0XaF9DPfNBKS7Zazch8NF5vp7eaZ2CV
# NxpqumzTCNSOxm+SAWSuIr21Qomb+zzQWKhxKTVVgtmUPAW35xUUFREmDrMxSNlr
# /NsJyUXzdtFUUt4aS4CEeIY8y9IaaGBpPNXKFifinT7zL2gdFpBP9qh8SdLnEut/
# GcalNeJQ55IuwnKCgs+nrpuQNfVmUB5KlCX3ZA4x5HHKS+rqBvKWxdCyQEEGcbLe
# 1b8Aw4wJkhU1JrPsFfxW1gaou30yZ46t4Y9F20HHfIY4/6vHespYMQmUiote8lad
# jS/nJ0+k6MvqzfpzPDOy5y6gqztiT96Fv/9bH7mQyogxG9QEPHrPV6/7umw052Ak
# yiLA6tQbZl1KhBtTasySkuJDpsZGKdlsjg4u70EwgWbVRSX1Wd4+zoFpp4Ra+MlK
# M2baoD6x0VR4RjSpWM8o5a6D8bpfm4CLKczsG7ZrIGNTAgMBAAGjggFdMIIBWTAS
# BgNVHRMBAf8ECDAGAQH/AgEAMB0GA1UdDgQWBBTvb1NK6eQGfHrK4pBW9i/USezL
# TjAfBgNVHSMEGDAWgBTs1+OC0nFdZEzfLmc/57qYrhwPTzAOBgNVHQ8BAf8EBAMC
# AYYwEwYDVR0lBAwwCgYIKwYBBQUHAwgwdwYIKwYBBQUHAQEEazBpMCQGCCsGAQUF
# BzABhhhodHRwOi8vb2NzcC5kaWdpY2VydC5jb20wQQYIKwYBBQUHMAKGNWh0dHA6
# Ly9jYWNlcnRzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydFRydXN0ZWRSb290RzQuY3J0
# MEMGA1UdHwQ8MDowOKA2oDSGMmh0dHA6Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9EaWdp
# Q2VydFRydXN0ZWRSb290RzQuY3JsMCAGA1UdIAQZMBcwCAYGZ4EMAQQCMAsGCWCG
# SAGG/WwHATANBgkqhkiG9w0BAQsFAAOCAgEAF877FoAc/gc9EXZxML2+C8i1NKZ/
# zdCHxYgaMH9Pw5tcBnPw6O6FTGNpoV2V4wzSUGvI9NAzaoQk97frPBtIj+ZLzdp+
# yXdhOP4hCFATuNT+ReOPK0mCefSG+tXqGpYZ3essBS3q8nL2UwM+NMvEuBd/2vmd
# YxDCvwzJv2sRUoKEfJ+nN57mQfQXwcAEGCvRR2qKtntujB71WPYAgwPyWLKu6Rna
# ID/B0ba2H3LUiwDRAXx1Neq9ydOal95CHfmTnM4I+ZI2rVQfjXQA1WSjjf4J2a7j
# LzWGNqNX+DF0SQzHU0pTi4dBwp9nEC8EAqoxW6q17r0z0noDjs6+BFo+z7bKSBwZ
# XTRNivYuve3L2oiKNqetRHdqfMTCW/NmKLJ9M+MtucVGyOxiDf06VXxyKkOirv6o
# 02OoXN4bFzK0vlNMsvhlqgF2puE6FndlENSmE+9JGYxOGLS/D284NHNboDGcmWXf
# wXRy4kbu4QFhOm0xJuF2EZAOk5eCkhSxZON3rGlHqhpB/8MluDezooIs8CVnrpHM
# iD2wL40mm53+/j7tFaxYKIqL0Q4ssd8xHZnIn/7GELH3IdvG2XlM9q7WP/UwgOkw
# /HQtyRN62JK4S1C8uw3PdBunvAZapsiI5YKdvlarEvf8EA+8hcpSM9LHJmyrxaFt
# oza2zNaQ9k+5t1wwggWNMIIEdaADAgECAhAOmxiO+dAt5+/bUOIIQBhaMA0GCSqG
# SIb3DQEBDAUAMGUxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMx
# GTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xJDAiBgNVBAMTG0RpZ2lDZXJ0IEFz
# c3VyZWQgSUQgUm9vdCBDQTAeFw0yMjA4MDEwMDAwMDBaFw0zMTExMDkyMzU5NTla
# MGIxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsT
# EHd3dy5kaWdpY2VydC5jb20xITAfBgNVBAMTGERpZ2lDZXJ0IFRydXN0ZWQgUm9v
# dCBHNDCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAL/mkHNo3rvkXUo8
# MCIwaTPswqclLskhPfKK2FnC4SmnPVirdprNrnsbhA3EMB/zG6Q4FutWxpdtHauy
# efLKEdLkX9YFPFIPUh/GnhWlfr6fqVcWWVVyr2iTcMKyunWZanMylNEQRBAu34Lz
# B4TmdDttceItDBvuINXJIB1jKS3O7F5OyJP4IWGbNOsFxl7sWxq868nPzaw0QF+x
# embud8hIqGZXV59UWI4MK7dPpzDZVu7Ke13jrclPXuU15zHL2pNe3I6PgNq2kZhA
# kHnDeMe2scS1ahg4AxCN2NQ3pC4FfYj1gj4QkXCrVYJBMtfbBHMqbpEBfCFM1Lyu
# GwN1XXhm2ToxRJozQL8I11pJpMLmqaBn3aQnvKFPObURWBf3JFxGj2T3wWmIdph2
# PVldQnaHiZdpekjw4KISG2aadMreSx7nDmOu5tTvkpI6nj3cAORFJYm2mkQZK37A
# lLTSYW3rM9nF30sEAMx9HJXDj/chsrIRt7t/8tWMcCxBYKqxYxhElRp2Yn72gLD7
# 6GSmM9GJB+G9t+ZDpBi4pncB4Q+UDCEdslQpJYls5Q5SUUd0viastkF13nqsX40/
# ybzTQRESW+UQUOsxxcpyFiIJ33xMdT9j7CFfxCBRa2+xq4aLT8LWRV+dIPyhHsXA
# j6KxfgommfXkaS+YHS312amyHeUbAgMBAAGjggE6MIIBNjAPBgNVHRMBAf8EBTAD
# AQH/MB0GA1UdDgQWBBTs1+OC0nFdZEzfLmc/57qYrhwPTzAfBgNVHSMEGDAWgBRF
# 66Kv9JLLgjEtUYunpyGd823IDzAOBgNVHQ8BAf8EBAMCAYYweQYIKwYBBQUHAQEE
# bTBrMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdpY2VydC5jb20wQwYIKwYB
# BQUHMAKGN2h0dHA6Ly9jYWNlcnRzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEFzc3Vy
# ZWRJRFJvb3RDQS5jcnQwRQYDVR0fBD4wPDA6oDigNoY0aHR0cDovL2NybDMuZGln
# aWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEUm9vdENBLmNybDARBgNVHSAECjAI
# MAYGBFUdIAAwDQYJKoZIhvcNAQEMBQADggEBAHCgv0NcVec4X6CjdBs9thbX979X
# B72arKGHLOyFXqkauyL4hxppVCLtpIh3bb0aFPQTSnovLbc47/T/gLn4offyct4k
# vFIDyE7QKt76LVbP+fT3rDB6mouyXtTP0UNEm0Mh65ZyoUi0mcudT6cGAxN3J0TU
# 53/oWajwvy8LpunyNDzs9wPHh6jSTEAZNUZqaVSwuKFWjuyk1T3osdz9HNj0d1pc
# VIxv76FQPfx2CWiEn2/K2yCNNWAcAgPLILCsWKAOQGPFmCLBsln1VWvPJ6tsds5v
# Iy30fnFqI2si/xK4VC0nftg62fC2h5b9W9FcrBjDTZ9ztwGpn1eqXijiuZQxggN8
# MIIDeAIBATB9MGkxCzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5EaWdpQ2VydCwgSW5j
# LjFBMD8GA1UEAxM4RGlnaUNlcnQgVHJ1c3RlZCBHNCBUaW1lU3RhbXBpbmcgUlNB
# NDA5NiBTSEEyNTYgMjAyNSBDQTECEAqA7xhLjfEFgtHEdqeVdGgwDQYJYIZIAWUD
# BAIBBQCggdEwGgYJKoZIhvcNAQkDMQ0GCyqGSIb3DQEJEAEEMBwGCSqGSIb3DQEJ
# BTEPFw0yNjAyMjcxNjUyMjFaMCsGCyqGSIb3DQEJEAIMMRwwGjAYMBYEFN1iMKyG
# Ci0wa9o4sWh5UjAH+0F+MC8GCSqGSIb3DQEJBDEiBCAJa2JEShvGrD+39nfdQTTr
# fD9A3SWsz/cALhUAmmbGSjA3BgsqhkiG9w0BCRACLzEoMCYwJDAiBCBKoD+iLNdc
# hMVck4+CjmdrnK7Ksz/jbSaaozTxRhEKMzANBgkqhkiG9w0BAQEFAASCAgB3zxNK
# VkbNAa44aabbeTbZ2+lx4tNGpHYfAf1oz7P3rl6GwDAxDwD9Pm9NvJiCVa8cUsbO
# VuzhJXgdFU6ZHaVQn6CXaAB4V/w51mVz7mXCu+uls4qHGByO2+EW+f0D1ywiSmKE
# 9kLtS0KKQRBrX46ULMpZfokHVPT5ngur/dbXweWkQkusbaxHIJNBMh7aFnqSk42p
# vhsM4r2tS8GGYT5HhFHCx6ZFVUZHQ+JYbCyxmxnTVIAdeiTsBaM3tgkUyr2Aku5D
# 4yb8UBWBuAsOeI/16p4SKI/TOO3Z/p9AinqdXLrNQ96UMA/BiPMrO/v2G0ZQhye9
# SCImSsNK3IOCPdVkP3adjL7trymYPu27VA1YCHDe91Dhu8u77hSwQCc+5HtepJ9E
# 7OXOtHLNljNjRAd/jpIE/WLPgcadMOzwj8IkUOFVK20IrZZVxqhBma11sg1VqFMu
# GAJBDf61o1JwSr4lqUn44R+ZZWhr1jAaO/aibWMX+r1VJ3TqXLKW+Uy3XCXGZzR1
# f0+FbC0ufTkceGDB4NoAJCOm/W1Ukmj4tew6S9oKGdI26kxAXLc1qOZwH4WpTicl
# yjVHxpC9kh/YeOGzdXpR8Me6rkWJq9YIItRb2AfGgxeY1AKAH9nG8R4Ue48UGROa
# cgv9uzgXL6m8sNv+Uy7woE1dEuBv7WbFQVRhpQ==
# SIG # End signature block