@@ -1,6 +1,6 @@
#
# Fido v1.37 - Feature ISO Downloader, for retail Windows images and UEFI Shell
# Copyright © 2019-2022 Pete Batard <pete@akeo.ie>
# Fido v1.44 - Feature ISO Downloader, for retail Windows images and UEFI Shell
# Copyright © 2019-2023 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 - Retail Windows ISO Downloader " ,
[ string ] $AppTitle = " Fido - Feature ISO Downloader " ,
# (Optional) '|' separated UI localization strings.
[ string ] $LocData ,
# (Optional) Path to a file that should be used for the UI icon.
@@ -45,9 +45,7 @@ param(
# (Optional) Only display the download URL [Toggles commandline mode]
[ switch ] $GetUrl = $False ,
# (Optional) Increase verbosity
[ switch ] $Verbose = $False ,
# (Optional) Disable the progress bar
[ switch ] $DisableProgress = $False
[ switch ] $Verbose = $False
)
#endregion
@@ -60,6 +58,28 @@ if ($Win -or $Rel -or $Ed -or $Lang -or $Arch -or $GetUrl) {
$Cmd = $True
}
# Return a decimal Windows version that we can then check for platform support.
# Note that because we don't want to have to support this script on anything
# other than Windows, this call returns 0.0 for PowerShell running on Linux/Mac.
function Get-Platform-Version ( )
{
$version = 0.0
$platform = [ string][System.Environment ] :: OSVersion . Platform
# This will filter out non Windows platforms
if ( $platform . StartsWith ( " Win " ) ) {
# Craft a decimal numeric version of Windows
$version = [ System.Environment ] :: OSVersion . Version . Major * 1.0 + [ System.Environment ] :: OSVersion . Version . Minor * 0.1
}
return $version
}
$winver = Get-Platform -Version
# The default TLS for Windows 8.x doesn't work with Microsoft's servers so we must force it
if ( $winver -lt 10.0 ) {
[ Net.ServicePointManager ] :: SecurityProtocol = [ Net.SecurityProtocolType ] :: Tls -bor [ Net.SecurityProtocolType ] :: Tls11 -bor [ Net.SecurityProtocolType ] :: Tls12
}
#region Assembly Types
$code = @"
[ D l l I m p o r t ( " s h e l l 3 2 . d l l " , C h a r S e t = C h a r S e t . A u t o , S e t L a s t E r r o r = t r u e , B e s t F i t M a p p i n g = f a l s e , T h r o w O n U n m a p p a b l e C h a r = t r u e ) ]
@@ -499,7 +519,7 @@ function ConvertTo-ImageSource
function Throw-Error([object]$Req , [ string ] $Alt )
{
$Err = $ ( GetElementById -Request $r -Id " errorModalMessage " ) . innerText
$Err = $ ( GetElementById -Request $Req -Id " errorModalMessage " ) . innerText -replace " <[^>]+> " -replace " \s+ " , " "
if ( -not $Err ) {
$Err = $Alt
} else {
@@ -602,7 +622,7 @@ $RequestData["GetLangs"] = @("a8f8f489-4c7f-463a-9ca6-5cff94d8d041", "getskuinfo
# 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 5 0 -Maximum 9 0
$FirefoxVersion = Get-Random -Minimum 9 0 -Maximum 11 0
$FirefoxDate = Get-RandomDate
$UserAgent = " Mozilla/5.0 (X11; Linux i586; rv: $FirefoxVersion .0) Gecko/ $FirefoxDate Firefox/ $FirefoxVersion .0 "
$Verbosity = 2
@@ -617,30 +637,25 @@ if ($Cmd) {
# Localization
$EnglishMessages = " en-US|Version|Release|Edition|Language|Architecture|Download|Continue|Back|Close|Cancel|Error|Please wait...| " +
" Download using a browser|Temporarily banned by Microsoft for requesting too many downloads - Please try again later.. .| " +
" PowerShell 3.0 or later is required to run this script.|Do you want to go online and download it? "
" Download using a browser|Download of Windows ISOs is unavailable due to Microsoft having altered their website to prevent it .| " +
" PowerShell 3.0 or later is required to run this script.|Do you want to go online and download it?| " +
" This feature is not available on this platform. "
[ string[] ] $English = $EnglishMessages . Split ( '|' )
[ string[] ] $Localized = $null
if ( $LocData -and ( -not $LocData . StartsWith ( " en-US " ) ) ) {
$Localized = $LocData . Split ( '|' )
if ( $Localized . Length -ne $English . Length ) {
Write-Host " Error: Missing or extra translated messages provided ( $ ( $Localized . Length) / $( $English . Length ) ) "
exit 101
# Adjust the $Localized array if we have more or fewer strings than in $EnglishMessages
if ($Localized . Length -lt $English . Length ) {
while ( $Localized . Length -ne $English . Length ) {
$Localized + = $English [ $Localized . Length ]
}
} elseif ( $Localized . Length -gt $English . Length ) {
$Localized = $LocData . Split ( '|' ) [ 0 . . ( $English . Length - 1 ) ]
}
$Locale = $Localized [ 0 ]
}
$QueryLocale = $Locale
# Make sure PowerShell 3.0 or later is used (for Invoke-WebRequest)
if ( $PSVersionTable . PSVersion . Major -lt 3 ) {
Write-Host Error : PowerShell 3.0 or later is required to run this script .
$Msg = " $( Get-Translation ( $English [ 15 ] ) ) `n $( Get-Translation ( $English [ 16 ] ) ) "
if ( [ System.Windows.MessageBox ] :: Show ( $Msg , $ ( Get-Translation ( " Error " ) ) , " YesNo " , " Error " ) -eq " Yes " ) {
Start-Process -FilePath https : / / www . microsoft . com / download / details . aspx ? id = 34595
}
exit 102
}
# Convert a size in bytes to a human readable string
function Size-To-Human-Readable([uint64]$size )
{
@@ -654,7 +669,8 @@ function Size-To-Human-Readable([uint64]$size)
}
# Check if the locale we want is available - Fall back to en-US otherwise
function Check-Locale {
function Check-Locale
{
try {
$url = " https://www.microsoft.com/ " + $QueryLocale + " /software-download/ "
if ( $Verbosity -ge 2 ) {
@@ -710,6 +726,17 @@ function Get-Windows-Languages([int]$SelectedVersion, [int]$SelectedEdition)
} elseif ( $WindowsVersions [ $SelectedVersion ] [ 0 ] [ 1 ] . StartsWith ( " UEFI_SHELL " ) ) {
$languages + = @ ( New-Object PsObject -Property @ { DisplayLanguage = " English (US) " ; Language = " en-us " ; Id = 0 } )
} else {
# 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
if ( $Verbosity -ge 2 ) {
Write-Host Querying $url
}
try {
Invoke-WebRequest -UseBasicParsing -MaximumRedirection 0 -UserAgent $UserAgent $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 "
@@ -724,11 +751,12 @@ function Get-Windows-Languages([int]$SelectedVersion, [int]$SelectedEdition)
$script:SelectedIndex = 0
try {
$r = Invoke-WebRequest -UseBasicParsing -UserAgent $UserAgent -SessionVariable " Session " $url
$r = Invoke-WebRequest -Method Post -UseBasicParsing -UserAgent $UserAgent -SessionVariable " Session " $url
if ( $r -match " errorModalMessage " ) {
Throw-Error -Req $r -Alt " Could not retrieve languages from server "
}
$pattern = '(?s)<select id="product-languages">(.*)?</select>'
$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 " )
@@ -811,20 +839,17 @@ function Get-Windows-Download-Links([int]$SelectedVersion, [int]$SelectedRelease
try {
$Is64 = [ Environment ] :: Is64BitOperatingSystem
# Must add a referer for POST requests , else Microsoft's servers will deny them
# Must add a referer for this request, else Microsoft's servers will deny i t
$ref = " https://www.microsoft.com/software-download/windows11 "
$w r = [ System.Net.WebRequest ] :: Create ( $url )
# Windows 7 PowerShell doesn't support 'Invoke-WebRequest -Headers @{"Referer" = $ref}'
# (produces "The 'Referer' header must be modified using the appropriate property or method")
# so we use StreamReader() with GetResponseStream() and do this whole gymkhana instead...
$wr . Method = " POST "
$wr . Referer = $ref
$wr . UserAgent = $UserAgent
$wr . ContentLength = 0
$sr = New-Object System . IO . StreamReader ( $wr . GetResponse ( ) . GetResponseStream ( ) )
$r = $sr . ReadToEnd ( )
$r = Invoke-WebRequest -Method Post -Headers @ { " Referer " = $ref } -UseBasicParsing -UserAgent $UserAgent -WebSession $Session $url
if ( $r -match " errorModalMessage " ) {
Throw-Error -Req $r -Alt " Could not retrieve architectures from server "
$Alt = [ regex ] :: Match ( $r , '<p id="errorModalMessage">(.+?)<\/p>' ) . Groups [ 1 ] . Value -replace " <[^>]+> " -replace " \s+ " , " " -replace " \?\?\? " , " - "
if ( -not $Alt ) {
$Alt = " Could not retrieve architectures from server "
} else {
$Alt + = " " + $SessionId + " . "
}
Throw-Error -Req $r -Alt $Alt
}
$pattern = '(?s)(<input.*?></input>)'
ForEach-Object { [ regex ] :: Matches ( $r , $pattern ) } | ForEach-Object { $html + = $_ . Groups [ 1 ] . value }
@@ -872,10 +897,7 @@ function Process-Download-Link([string]$Url)
$tmp_size = [ uint64 ] :: Parse ( $str_size )
$Size = Size-To -Human -Readable $tmp_size
Write-Host " Downloading ' $File ' ( $Size )... "
if ( $DisableProgress ) {
$ProgressPreference = 'SilentlyContinue'
}
Invoke-WebRequest -UseBasicParsing -Uri $Url -OutFile $File
Start-BitsTransfer -Source $Url -Destination $File
} else {
Write-Host Download Link : $Url
Start-Process -FilePath $Url
@@ -896,6 +918,12 @@ if ($Cmd) {
$winLanguageName = $null
$winLink = $null
# Windows 7 and non Windows platforms are too much of a liability
if ( $winver -le 6.1 ) {
Error ( Get-Translation ( " This feature is not available on this platform. " ) )
exit 403
}
$i = 0
$Selected = " "
if ( $Win -eq " List " ) {
@@ -956,7 +984,7 @@ if ($Cmd) {
if ( ! $Ed -and $Verbosity -ge 1 ) {
Write-Host " No edition specified (-Ed). Defaulting to ' $( $edition . Edition ) '. "
}
$Selected + = " , " + $edition . Edition -replace " Windows [0-9\.]* " , " "
$Selected + = " , " + $edition . Edition -replace " Windows [0-9\.]* "
$winEditionId = $edition . Id
break ;
}
@@ -1054,7 +1082,7 @@ $XMLForm.Title = $AppTitle
if ( $Icon ) {
$XMLForm . Icon = $Icon
} else {
$XMLForm . Icon = [ Gui.Utils ] :: ExtractIcon ( " shell32 .dll" , -41 , $true ) | ConvertTo-ImageSource
$XMLForm . Icon = [ Gui.Utils ] :: ExtractIcon ( " imageres .dll" , -5205 , $true ) | ConvertTo-ImageSource
}
if ( $Locale . StartsWith ( " ar " ) -or $Locale . StartsWith ( " fa " ) -or $Locale . StartsWith ( " he " ) ) {
$XMLForm . FlowDirection = " RightToLeft "
@@ -1063,6 +1091,12 @@ $WindowsVersionTitle.Text = Get-Translation("Version")
$Continue . Content = Get-Translation ( " Continue " )
$Back . Content = Get-Translation ( " Close " )
# Windows 7 and non Windows platforms are too much of a liability
if ( $winver -le 6.1 ) {
Error ( Get-Translation ( " This feature is not available on this platform. " ) )
exit 403
}
# Populate the Windows versions
$i = 0
$versions = @ ( )
@@ -1190,10 +1224,10 @@ $XMLForm.ShowDialog() | Out-Null
exit $ExitCode
# SIG # Begin signature block
# MIIkWA YJKoZIhvcNAQcCoIIkST CCJEU CAQExDzANBglghkgBZQMEAgEFADB5Bgor
# MIIkWQ YJKoZIhvcNAQcCoIIkSj CCJEY CAQExDzANBglghkgBZQMEAgEFADB5Bgor
# BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG
# KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCCIu9oI700HZxb3
# w6BvRyJWzIrL4aGutJadchpCiPvxia CCElkwggVvMIIEV6ADAgECAhBI/JO0YFWU
# KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCDCpZpntjuU2uHY
# z3/0OsY2UtUKjz1UjCN6T8dRzpny96 CCElkwggVvMIIEV6ADAgECAhBI/JO0YFWU
# jTanyYqJ1pQWMA0GCSqGSIb3DQEBDAUAMHsxCzAJBgNVBAYTAkdCMRswGQYDVQQI
# DBJHcmVhdGVyIE1hbmNoZXN0ZXIxEDAOBgNVBAcMB1NhbGZvcmQxGjAYBgNVBAoM
# EUNvbW9kbyBDQSBMaW1pdGVkMSEwHwYDVQQDDBhBQUEgQ2VydGlmaWNhdGUgU2Vy
@@ -1291,97 +1325,97 @@ exit $ExitCode
# QTYOb9goARWPNlkKbyF9bndu5kLWIlZcOS7IIznOcS4y1J5ZJewBRH4kbuNfCbSl
# HMZS/rmpFprXXFdje6TRXwgvBs6UOR1zTe5ycumyo5FYBVEFGR1Ps6ZC3z62yLPk
# pb5YSma1/ut/KplOxOnK74ELd/vTS2i10qmsqP5+m+U2jznmCEwm8g8V1mg94acL
# iyM9uR5+U3y6OrVRkMnG9K9ZuTGCEVU wghFR AgEBMGwwVzELMAkGA1UEBhMCR0Ix
# iyM9uR5+U3y6OrVRkMnG9K9ZuTGCEVY wghFS AgEBMGwwVzELMAkGA1UEBhMCR0Ix
# GDAWBgNVBAoTD1NlY3RpZ28gTGltaXRlZDEuMCwGA1UEAxMlU2VjdGlnbyBQdWJs
# aWMgQ29kZSBTaWduaW5nIENBIEVWIFIzNgIRAL+xUAG79ZLUlip3l+pzb6MwDQYJ
# YIZIAWUDBAIBBQCgfDAQBgorBgEEAYI3AgEMMQIwADAZBgkqhkiG9w0BCQMxDAYK
# KwYBBAGCNwIBBDAcBgorBgEEAYI3AgELMQ4wDAYKKwYBBAGCNwIBFTAvBgkqhkiG
# 9w0BCQQxIgQg6jgFb4FuL7yvtN2F8EfthVB5EwLiVoFh5/z9lnLw0f0 wDQYJKoZI
# hvcNAQEBBQAEggIAIaiHGVVcr5tUwEGY+uNs717INqUf4s8L/GYWuVYrpTAB6xtK
# z9UgpjfhiP8Rg+nebNxzAQSKG+ylUomqvFIswH6olcZI74Dn8VqE9zGDB029gMbI
# hnJcNgwvhiggl7PjQClo6JMVCD0xa7ChYIJRYa+c7SNF6OJXrHbQAlOoVeyv+2mb
# UOGKRK0D8oR1tCVCkBCb+2/V8ryjOFo3DjxVvNxCRmItoB0HntL2JVQiJjXZd2mv
# 1RjhW1g11x9ILsRWq4913/p3eF3zH0janBBs0APdzyw8Zp4LM4vPYLzeaWp0/olq
# U8Hga4NkEBLZzMSyuESgYCZPpLRJKEbLNxA/EUKM+5k0BLQ+Wx/sOQMkyU+PbhL+
# fLwifZmy7kYmQLfS36T8je/LgVVa7iBhvM8WOu/gkXEAJMn9E3IhiPKOSskTZvdJ
# bZTZZHKiYFk9JoDaAAFSSFZ0EJnV2V4kbTFzc+4q4kpDMVPa2yrhsoNW0j108xXl
# sOIaiD3urr8HisC15XV941/AHz1tJsVIbrKLvP4UbSgx4GRdstHHdNe9YI+SQ0fX
# YbqmO85mUkPhytCTmQYXkC3zOuncRt9B6X5a1RtrByBqleMdHzY/0udp9YEUK0D7
# yzRjx9+knXP+e4UsGrpg+5ql+l0krqfmacNfdWwd10PG/2qkvij0oSm/yJ2 hgg48
# MIIOOA YKKwYBBAGCNwMDATGCDig wgg4k BgkqhkiG9w0BBwKggg4V MIIOEQ IBAzEN
# MAsGCWCGSAFlAwQCATCCAQ4 GCyqGSIb3DQEJEAEEoIH+ BIH7 MIH4 AgEBBgtghkgB
# hvhFAQcXAzAxMA0GCWCGSAFlAwQCAQUABCCl76O7SS4cwM8X83mI8r35FZLf3rWC
# 8lvQfpcD2cvmVwIULSw32zIonkqtoMhGBCMfzXK+f4EYDzIwMjIxMjE1MDAxODI0
# WjADAgEeoIGGpIGDMIGAMQswCQYDVQQGEwJVUzEdMBs GA1UEC hMUU3ltYW50ZWMg
# Q29ycG9yYXRpb24xHzAdBgNVBAsTFlN5bWFudGVjIFRydXN0IE5ldHdvcmsxMTAv
# BgNVBAMTKFN5bWFudGVjIFNIQTI1NiBUaW1lU3RhbXBpbmcgU2lnbmVyIC0gRzOg
# ggqLMIIFODCCBCCgAwIBAgIQewWx1EloUUT3yYnSnBmdEjANBgkqhkiG9w0BAQsF
# ADCBvTELMAkGA1UEBhMCVVMxF zAV BgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYD
# VQQLExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwOCBW
# ZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MTgwNgYDVQQD
# Ey9WZXJpU2lnbiBVbml2ZXJzYWwgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0
# eTAeFw0xNjAx MTI wMDAwMDBaFw0z MTA xMTEyMzU5NTlaMHcxCzAJBgNVBAYTAlVT
# MR0wGwYDVQQKExRTeW1hbnRlYyBDb3Jwb3JhdGlvbjEf MB0 GA1UECxMW U3ltYW50
# ZWMgVHJ1c3QgTmV0d29yazEoMCYGA1UEAxMfU3ltYW50ZWMgU0hBMjU2IFRpbWVT
# dGFtcGluZyBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALtZnVlV
# T52Mcl0agaLrVfOwAa08cawyjwVrhponADKXak3JZBRLKbvC2Sm5Luxjs+HPPwtW
# kPhiG37rpgfi3n9ebUA41JEG50F8eRzLy60bv9iVkfPw7mz4rZY5Ln/BJ7h4OcWE
# pe3tr4eOzo3HberSmLU6Hx45ncP0mqj0hOHE0XxxxgYptD/kgw0mw3sIPk35Crcz
# Sf/KO9T1sptL4YiZGvXA6TMU1t/HgNuR7v68kldyd/TNqMz+CfWTN76ViGrF3PSx
# S9TO6AmRX7WEeTWKeKwZMo8jwTJBG1kOqT6xzPnWK++32OTVHW0ROpL2k8mc40ju
# u1MO1DaXhnjFoTcCAwEAAaOCAXcwggFzMA4GA1UdDwEB/wQEAwIBBjASBgNVHRMB
# Af8ECDAG AQH/AgEAMGYGA1UdIARfMF0wWwYLYIZIAYb4RQEHFwMwTDAjBggrBgEF
# BQcCARYXaHR0cHM6Ly9kLnN5bWNiLmNvbS9jcHMwJQYIKwYBBQUHAgIwGRoXaHR 0
# cHM6Ly9kLnN5bWNiLmNvbS9ycGEwLgYIKwYBBQUHAQEEIjAgMB4GCCsGAQUFBzAB
# hhJodHRwOi8vcy5zeW1jZC5jb20wNgYDVR0fBC8wLTAroCmgJ4YlaHR0cDovL3Mu
# c3ltY2IuY29tL3VuaXZlcnNhbC1yb290LmNybDATBgNVHSUEDDAKBggrBgEFBQcD
# CDAoBgNVHREEITAfpB0wGzEZMBcGA1UEAxMQVGltZVN0YW1wLTIwNDgtMzAdBgNV
# HQ4EFgQUr2PWyqNOhXLgp7xB8ymiOH+AdWIwHwYDVR0jBBgwFoAUtnf6aUhHn1MS
# 1cLqBzJ2B9GXBxkwDQYJKoZIhvcNAQELBQADggEBAHXqsC3VNBlcMkX+DuHUT6Z4
# wW/X6t3cT/OhyIGI96ePFeZAKa3mXfSi2VZkhHEwKt0eYRdmIFYGmBmNXXHy+Je8
# Cf0ckUfJ4uiNA/vMkC/WCmxOM+zWtJPITJBjSDlAIcTd1m6JmDy1mJfoqQa3CcmP
# U1dBkC/hHk1O3MoQeGxCbvC2xfhhXFL1TvZrjfdKer7zzf0D19n2A6gP41P3CnXs
# xnUuqmaFBJm3+AZX4cYO9uiv2uybGB+queM6AL/OipTLAduexzi7D1Kr0eOUA2AK
# TaD+J20UMvw/l0Dhv5mJ2+Q5FL3a5NPD6itas5VYVQR9x5rsIwONhSrS/66pYYEw
# ggVLMIIEM6ADAgECAhB71OWvuswHP6EBIwQiQU0SMA0GCSqGSIb3DQEBCwUAMHcx
# CzAJBgNVBAYTAlVTMR0wGwYDVQQKExRTeW1hbnRlYyBDb3Jwb3JhdGlvbjEfMB0G
# A1UECxMWU3ltYW50ZWMgVHJ1c3QgTmV0d29yazEoMCYGA1UEAxMfU3ltYW50ZWMg
# U0hBMjU2IFRpbWVTdGFtcGluZyBDQTAeFw0xNzEyMjMwMDAwMDBaFw0yOTAzMj Iy
# MzU5NTlaMIGAMQswCQYDVQQGEwJVUzEdMBs GA1UEC hMUU3ltYW50ZWMgQ29ycG9y
# YXRpb24xHzAdBgNVBAsTFlN5bWFudGVjIFRydXN0IE5ldHdvcmsxMTAvBgNVBAMT
# KFN5bWFudGVjIFNIQTI1NiBUaW1lU3RhbXBpbmcgU2lnbmVyIC0gRzMwggEiMA0G
# CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvDoqq+Ny/aXtUF3FHCb2NPIH4dBV3
# Z5Cc/d5OAp5LdvblNj5l1SQgbTD53R2D6T8nSjNObRaK5I1AjSKqvqcLG9IHtjy1
# GiQo+BtyUT3ICYgmCDr5+kMjdUdwDLNfW48IHXJIV2VNrwI8QPf03TI4kz/lLKbz
# WSPLgN4TTfkQyaoKGGxVYVfR8QIsxLWr8mwj0p8NDxlsrYViaf1OhcGKUjGrW9jJ
# dFLjV2wiv1V/b8oGqz9KtyJ2ZezsNvKWlYEmLP27mKoBONOvJUCbCVPwKVeFWF7q
# hUhBIYfl3rTTJrJ7QFNYeY5SMQZNlANFxM48A+y3API6IsW0b+XvsIqbAgMBAAGj
# ggHHMIIBwzAMBgNVHRMBAf8EAjAAMGYGA1UdIARfMF0wWwYLYIZIAYb4RQEHFwMw
# TDAjBggrBgEFBQcCARYXaHR0cHM6Ly9kLnN5bWNiLmNvbS9jcHMwJQYIKwYBB QUH
# AgIwGRoXaHR0cHM6Ly9kLnN5bWNiLmNvbS9ycGEwQAYDVR0fBDkwNzA1oDOgMYYv
# aHR0cDovL3RzLWNybC53cy5zeW1hbnRlYy5jb20vc2hhMjU2LXRzcy1jYS5jcmww
# FgYDVR0lAQH/BAwwCgYIKwYBBQUHAwgwDgYDVR0PAQH/BAQDAgeAMHcGCCsGAQU F
# BwEBBGswaTAqBggrBgEFBQcwAYYeaHR0cDovL3RzLW9jc3Aud3Muc3ltYW50ZWMu
# Y29tMDsGCCsGAQUFBzAChi9odHRwOi8vdHMtYWlhLndzLnN5bWFudGVjLmNvbS9z
# aGEyNTYtdHNzLWNhLmNlcjAoBgNVHREEITAfpB0wGzEZMBcGA1UEAxMQVGltZVN0
# YW1wLTIwNDgtNjAdBgNVHQ4EFgQUpRMBqZ+FzBtuFh5fOzGqeTYAex0wHwYDVR0j
# BBgwFoAUr2PWyqNOhXLgp7xB8ymiOH+AdWIwDQYJKoZIhvcNAQELBQADggEBAEae
# r/C4ol+imUjPqCdLIc2yuaZycGMv41UpezlGTud+ZQZYi7xXipINCNgQujYk+gp7
# +zvTYr9KlBXmgtuKVG3/KP5nz3E/5jMJ2aJZEPQeSv5lzN7Ua+NSKXUASiulzMub
# 6KlN97QXWZJBw7c/hub2wH9EPEZcF1rjpDvVaSbVIX3hgGd+Yqy3Ti4VmuWcI69b
# EepxqUH5DXk4qaENz7Sx2j6aescixXTN30cJhsT8kSWyG5bphQjo3ep0YG5gpVZ6
# DchEWNzm+UgUnuW/3gC9d7GYFHIUJN/HESwfAD/DSxTGZxzMHgajkF9cVIs+4zNb
# gg/Ft4YCTnGf6WZFP3YxggJaMIICVgIBATCBizB3MQswCQYDVQQGEwJVUzEdMBsG
# A1UEChMUU3ltYW50ZWMgQ29ycG9yYXRpb24xHzAd BgNVBAs TFl N5bWFudGVjIFRy
# dXN0IE5ldHdvcmsxKDAmBgNVBAMTH1N5bWFudGVjIFNIQTI1NiBUaW1lU3RhbXBp
# bmcgQ0ECEHvU5a+6zAc/oQEjBCJBTRIwCwYJYIZIAWUDBAIBoIGkMBoGCSqGSIb3
# DQEJAzENBgsqhkiG9w0BCRABBDAcBgkqhkiG9w0BCQUxDxcNMjIxMjE1MDAxODI0
# WjAvBgkqhkiG9w0BCQQxIgQgsw9WKFlYqvyfplQHJTt3QEkl2HZAxohscRE4ony+
# 88owNwYLKoZIhvcNAQkQAi8xKDAmMCQwIgQgxHTOdgB9AjlODaXk3nwUxoD54oIB
# PP72U+9dtx/fYfgwCwYJKoZIhvcNAQEBBIIBADj8Kp9BIS2MqfSVaaxBzdwoWM0m
# 7f2eqqbMymXmX0msLnW3fITTw19Hun1fo9YebTmgXd5XttgHvFmjdHUkZnQAZDt7
# dk9h3KkGNqd5PMPiVAZnI8/ubaqV9Py+dGWT2bmdyBMan2CoU2U9sfAyIclGHxvn
# 1dbDS9NZpruOH4GTYtcPqROkN/sePoCKWqu5hzdq7HuAdsyQmf/6OP6JL7yft1R b
# ZKHERak8wQqsgu5B/6f5j+M3vE01ZIWHvgaMrC/a6+EzeormRQAuF3B8Eg9a7/AU
# 0C/w9SiFOKg4NYuUu2i+68HTNGTVhBUZ3eas1gZdz4AvYRj47BYIG62Ijhw=
# 9w0BCQQxIgQgH+Kly8R4u5iFMlpWglzfc5lMDQgs38C2FS0CujFgfdM wDQYJKoZI
# hvcNAQEBBQAEggIAqDdE38CiBnf6ksVoNbp+EAUi5M1rD/b885OIuaXqUUjCMOaR
# R34hPylb/Lc9CbCJ1aiqjhyap/hnNryeXBSkr+HIfP5UyDGXjCsfFFwyPVyRPd72
# BKM8tYfuUvZbIvWmsFUJfe24VTEGTbh5XTM5s6RgQCQZ4V/M6ePCH6LxiHuIufWL
# DCaKS6/AO0icPkF0CtQQiGk/z0nlrp6T6IppDkGS7yAYip5/flBxmQsRCkNlL9mw
# XTL63kd1ar9cZTR1knAXwM2qXfkkOxGX8OGQ04P01/wWjEBMoYBUmUbHIWKgcg1T
# QmXZEObFJHRkNMfPU+F+oc/kDwd4SXCv6x7E6XOgxB4C9B9sE88ZEOOv26FTS4fa
# +VVFPffxfmdQT+pKch8j3h/OGgJM2OAqnEoK8KTZYlCoJO781YfAjertrewXKHv/
# HzlJ7gu5t3Ji7WrzoCusHEszv+LYl3TupZ2VZNmQDY57/br3LxNHOxRmjFAigI6z
# 3OyVwOx6L+onBr+jg5LGkA+XPhTjdAhBJ2bI9ayUYURKv5/jNUbyk6RZHUncTKUj
# Oze0eaX15F/UpGbJZaR9wCCj28jCk4zxbqSTqQcSjxM8zfp23fcxd2NICtd8UhFt
# pGfR1jleAJsKuDJts+k8WcfT2SaEGQmmklM/wIusRaIWn6KHr8wAFBgz8hu hgg49
# MIIOOQ YKKwYBBAGCNwMDATGCDik wgg4l BgkqhkiG9w0BBwKggg4W MIIOEg IBAzEN
# MAsGCWCGSAFlAwQCATCCAQ8 GCyqGSIb3DQEJEAEEoIH/ BIH8 MIH5 AgEBBgtghkgB
# hvhFAQcXAzAxMA0GCWCGSAFlAwQCAQUABCBIdB9A36e59U63AWbaDgc60655s3pE
# PaBLt9XKx9DWuQIVAKmmRn4m0Gad1QsRv95QHHuKDBOzGA8yMDIzMDMwNzEyMTEz
# MFowAwIBHqCBhqSBgzCBgDELMAk GA1UEB hMCVVMxHTAbBgNVBAoTFFN5bWFudGVj
# IENvcnBvcmF0aW9uMR8wHQYDVQQLExZTeW1hbnRlYyBUcnVzdCBOZXR3b3JrMTEw
# LwYDVQQDEyhTeW1hbnRlYyBTSEEyNTYgVGltZVN0YW1waW5nIFNpZ25lciAtIEcz
# oIIKizCCBTgwggQgoAMCAQICEHsFsdRJaFFE98mJ0pwZnRIwDQYJKoZIhvcNAQEL
# BQAwgb0xC zAJ BgNVBAYTAlVTMRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjEfMB0G
# A1UECxMWVmVyaVNpZ24gVHJ1c3QgTmV0d29yazE6MDgGA1UECxMxKGMpIDIwMDgg
# VmVyaVNpZ24sIEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTE4MDYGA1UE
# AxMvVmVyaVNpZ24gVW5pdmVyc2FsIFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3Jp
# dHkwHhcN MTY wMTEyM DAwMDAwWhcNMzEw MTE xMjM1OTU5WjB3MQswCQYDVQQGEwJV
# UzEd MBs GA1UEChMU U3ltYW50ZWMgQ29ycG9yYXRpb24xHzAdBgNVBAsTFlN5bWFu
# dGVjIFRydXN0IE5ldHdvcmsxKDAmBgNVBAMTH1N5bWFudGVjIFNIQTI1NiBUaW1l
# U3RhbXBpbmcgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC7WZ1Z
# VU+djHJdGoGi61XzsAGtPHGsMo8Fa4aaJwAyl2pNyWQUSym7wtkpuS7sY7Phzz8L
# VpD4Yht+66YH4t5/Xm1AONSRBudBfHkcy8utG7/YlZHz8O5s+K2WOS5/wSe4eDnF
# hKXt7a+Hjs6Nx23q0pi1Oh8eOZ3D9Jqo9IThxNF8ccYGKbQ/5IMNJsN7CD5N+Qq3
# M0n/yjvU9bKbS+GImRr1wOkzFNbfx4Dbke7+vJJXcnf0zajM/gn1kze+lYhqxdz0
# sUvUzugJkV+1hHk1inisGTKPI8EyQRtZDqk+scz51ivvt9jk1R1tETqS9pPJnONI
# 7rtTDtQ2l4Z4xaE3AgMBAAGjggF3MIIBczAOBgNVHQ8BAf8EBAMCAQYwEgYDVR0T
# AQH/B AgwBgEB/wIBADBmBgNVHSAEXzBdMFsGC2CGSAGG+EUBBxcDMEwwIwYIKwYB
# BQUHAgEWF2h0dHBzOi8vZC5zeW1jYi5jb20vY3BzMCUGCCsGAQUFBwICMBkaF2h 0
# dHBzOi8vZC5zeW1jYi5jb20vcnBhMC4GCCsGAQUFBwEBBCIwIDAeBggrBgEFBQcw
# AYYSaHR0cDovL3Muc3ltY2QuY29tMDYGA1UdHwQvMC0wK6ApoCeGJWh0dHA6Ly9z
# LnN5bWNiLmNvbS91bml2ZXJzYWwtcm9vdC5jcmwwEwYDVR0lBAwwCgYIKwYBBQUH
# AwgwKAYDVR0RBCEwH6QdMBsxGTAXBgNVBAMTEFRpbWVTdGFtcC0yMDQ4LTMwHQYD
# VR0OBBYEFK9j1sqjToVy4Ke8QfMpojh/gHViMB8GA1UdIwQYMBaAFLZ3+mlIR59T
# EtXC6gcydgfRlwcZMA0GCSqGSIb3DQEBCwUAA4IBAQB16rAt1TQZXDJF/g7h1E+m
# eMFv1+rd3E/zociBiPenjxXmQCmt5l30otlWZIRxMCrdHmEXZiBWBpgZjV1x8viX
# vAn9HJFHyeLojQP7zJAv1gpsTjPs1rSTyEyQY0g5QCHE3dZuiZg8tZiX6KkGtwnJ
# j1NXQZAv4R5NTtzKEHhsQm7wtsX4YVxS9U72a433Snq+8839A9fZ9gOoD+NT9wp1
# 7MZ1LqpmhQSZt/gGV+HGDvbor9rsmxgfqrnjOgC/zoqUywHbnsc4uw9Sq9HjlANg
# Ck2g/idtFDL8P5dA4b+ZidvkORS92uTTw+orWrOVWFUEfcea7CMDjYUq0v+uqWGB
# MIIFSzCCBDOgAwIBAgIQe9Tlr7rMBz+hASMEIkFNEjANBgkqhkiG9w0BAQsFADB3
# MQswCQYDVQQGEwJVUzEdMBsGA1UEChMUU3ltYW50ZWMgQ29ycG9yYXRpb24xHzAd
# BgNVBAsTFlN5bWFudGVjIFRydXN0IE5ldHdvcmsxKDAmBgNVBAMTH1N5bWFudGVj
# IFNIQTI1NiBUaW1lU3RhbXBpbmcgQ0EwHhcNMTcxMjIzMDAwMDAwWhcNMjkwMz Iy
# MjM1OTU5WjCBgDELMAk GA1UEB hMCVVMxHTAbBgNVBAoTFFN5bWFudGVjIENvcnBv
# cmF0aW9uMR8wHQYDVQQLExZTeW1hbnRlYyBUcnVzdCBOZXR3b3JrMTEwLwYDVQQD
# EyhTeW1hbnRlYyBTSEEyNTYgVGltZVN0YW1waW5nIFNpZ25lciAtIEczMIIBIjAN
# BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArw6Kqvjcv2l7VBdxRwm9jTyB+HQV
# d2eQnP3eTgKeS3b25TY+ZdUkIG0w+d0dg+k/J0ozTm0WiuSNQI0iqr6nCxvSB7Y8
# tRokKPgbclE9yAmIJgg6+fpDI3VHcAyzX1uPCB1ySFdlTa8CPED39N0yOJM/5Sym
# 81kjy4DeE035EMmqChhsVWFX0fECLMS1q/JsI9KfDQ8ZbK2FYmn9ToXBilIxq1vY
# yXRS41dsIr9Vf2/KBqs/SrcidmXs7DbylpWBJiz9u5iqATjTryVAmwlT8ClXhVhe
# 6oVIQSGH5d600yaye0BTWHmOUjEGTZQDRcTOPAPstwDyOiLFtG/l77CKmwIDAQAB
# o4IBxzCCAcMwDAYDVR0TAQH/BAIwADBmBgNVHSAEXzBdMFsGC2CGSAGG+EUBBxcD
# MEwwIwYIKwYBBQUHAgEWF2h0dHBzOi8vZC5zeW1jYi5jb20vY3BzMCUGCCsGA QUF
# BwICMBkaF2h0dHBzOi8vZC5zeW1jYi5jb20vcnBhMEAGA1UdHwQ5MDcwNaAzoDGG
# L2h0dHA6Ly90cy1jcmwud3Muc3ltYW50ZWMuY29tL3NoYTI1Ni10c3MtY2EuY3Js
# MBYGA1UdJQEB/wQMMAoGCCsGAQUFBwMIMA4GA1UdDwEB/wQEAwIHgDB3BggrBgE F
# BQcBAQRrMGkwKgYIKwYBBQUHMAGGHmh0dHA6Ly90cy1vY3NwLndzLnN5bWFudGVj
# LmNvbTA7BggrBgEFBQcwAoYvaHR0cDovL3RzLWFpYS53cy5zeW1hbnRlYy5jb20v
# c2hhMjU2LXRzcy1jYS5jZXIwKAYDVR0RBCEwH6QdMBsxGTAXBgNVBAMTEFRpbWVT
# dGFtcC0yMDQ4LTYwHQYDVR0OBBYEFKUTAamfhcwbbhYeXzsxqnk2AHsdMB8GA1Ud
# IwQYMBaAFK9j1sqjToVy4Ke8QfMpojh/gHViMA0GCSqGSIb3DQEBCwUAA4IBAQBG
# nq/wuKJfoplIz6gnSyHNsrmmcnBjL+NVKXs5Rk7nfmUGWIu8V4qSDQjYELo2JPoK
# e/s702K/SpQV5oLbilRt/yj+Z89xP+YzCdmiWRD0Hkr+Zcze1GvjUil1AEorpczL
# m+ipTfe0F1mSQcO3P4bm9sB/RDxGXBda46Q71Wkm1SF94YBnfmKst04uFZrlnCOv
# WxHqcalB+Q15OKmhDc+0sdo+mnrHIsV0zd9HCYbE/JElshuW6YUI6N3qdGBuYKVW
# eg3IRFjc5vlIFJ7lv94AvXexmBRyFCTfxxEsHwA/w0sUxmcczB4Go5BfXFSLPuMz
# W4IPxbeGAk5xn+lmRT92MYICWjCCAlYCAQEwgYswdzELMAkGA1UEBhMCVVMxHTAb
# BgNVBAo TFF N5bWFudGVjIENvcnBvcmF0aW9uMR8wHQYDVQQLExZTeW1hbnRlYyBU
# cnVzdCBOZXR3b3JrMSgwJgYDVQQDEx9TeW1hbnRlYyBTSEEyNTYgVGltZVN0YW1w
# aW5nIENBAhB71OWvuswHP6EBIwQiQU0SMAsGCWCGSAFlAwQCAaCBpDAaBgkqhkiG
# 9w0BCQMxDQYLKoZIhvcNAQkQAQQwHAYJKoZIhvcNAQkFMQ8XDTIzMDMwNzEyMTEz
# MFowLwYJKoZIhvcNAQkEMSIEIBi+xZssYhAdmjF0gLXZv2WCNOM3iW02zqjWyiHi
# 3ZVhMDcGCyqGSIb3DQEJEAIvMSgwJjAkMCIEIMR0znYAfQI5Tg2l5N58FMaA+eKC
# ATz+9lPvXbcf32H4MAsGCSqGSIb3DQEBAQSCAQAQ/Kq0P6rLFJ66lXNqtLxRuZtB
# MUMdYUhBiKy3RCJwf1SMi4nhV/aHEw43hQz+GsxrxENwy24VFfxOg6kguqI1Qm0b
# w5+rCqFykHUntTAsIND27MthzzXn69wkoFv0n2IKjq05KuUEXgEy+eemStG1G0tU
# efXWl2eFR+8ItErCzAi7Dt7R76vhRG7Sj1Ik2PlltdnK0+SuSdLfeVbTrrYQ2Ku b
# ueVJWMFFE4CX0LvFJ6fdytVVqTD8GXNj/bdt2La5zLEobYoQXHzXwJHXGY+Nj9d8
# 5fiYgMP7RA04944Xjkoc761EySwFWPHNJjg8DTSAz+NKrnFdvb9K3hoik1wT
# SIG # End signature block