You've already forked setup-dotnet
							
							
				mirror of
				https://github.com/actions/setup-dotnet.git
				synced 2025-11-04 00:46:36 +07:00 
			
		
		
		
	Compare commits
	
		
			2 Commits
		
	
	
		
			dependabot
			...
			testv3fail
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| a2033c1666 | |||
| ea9897a6e5 | 
							
								
								
									
										3
									
								
								.github/workflows/basic-validation.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								.github/workflows/basic-validation.yml
									
									
									
									
										vendored
									
									
								
							@ -10,8 +10,9 @@ on:
 | 
				
			|||||||
      - releases/*
 | 
					      - releases/*
 | 
				
			||||||
    paths-ignore:
 | 
					    paths-ignore:
 | 
				
			||||||
      - '**.md'
 | 
					      - '**.md'
 | 
				
			||||||
 | 
					  workflow_dispatch:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
jobs:
 | 
					jobs:
 | 
				
			||||||
  call-basic-validation:
 | 
					  call-basic-validation:
 | 
				
			||||||
    name: Basic validation
 | 
					    name: Basic validation
 | 
				
			||||||
    uses: actions/reusable-workflows/.github/workflows/basic-validation.yml@main
 | 
					    uses: actions/reusable-workflows/.github/workflows/basic-validation.yml@f29e256d8e29342dea6fe09c145121ae580b1e9c
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										32
									
								
								.github/workflows/e2e-tests.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										32
									
								
								.github/workflows/e2e-tests.yml
									
									
									
									
										vendored
									
									
								
							@ -17,7 +17,7 @@ jobs:
 | 
				
			|||||||
    strategy:
 | 
					    strategy:
 | 
				
			||||||
      fail-fast: false
 | 
					      fail-fast: false
 | 
				
			||||||
      matrix:
 | 
					      matrix:
 | 
				
			||||||
        operating-system: [ubuntu-latest, windows-latest, macOS-latest]
 | 
					        operating-system: [ubuntu-22.04, windows-latest, macOS-latest]
 | 
				
			||||||
    steps:
 | 
					    steps:
 | 
				
			||||||
      - name: Checkout
 | 
					      - name: Checkout
 | 
				
			||||||
        uses: actions/checkout@v3
 | 
					        uses: actions/checkout@v3
 | 
				
			||||||
@ -40,7 +40,7 @@ jobs:
 | 
				
			|||||||
    strategy:
 | 
					    strategy:
 | 
				
			||||||
      fail-fast: false
 | 
					      fail-fast: false
 | 
				
			||||||
      matrix:
 | 
					      matrix:
 | 
				
			||||||
        operating-system: [ubuntu-latest, windows-latest, macOS-latest]
 | 
					        operating-system: [ubuntu-22.04, windows-latest, macos-13]
 | 
				
			||||||
    steps:
 | 
					    steps:
 | 
				
			||||||
      - name: Checkout
 | 
					      - name: Checkout
 | 
				
			||||||
        uses: actions/checkout@v3
 | 
					        uses: actions/checkout@v3
 | 
				
			||||||
@ -69,7 +69,7 @@ jobs:
 | 
				
			|||||||
    strategy:
 | 
					    strategy:
 | 
				
			||||||
      fail-fast: false
 | 
					      fail-fast: false
 | 
				
			||||||
      matrix:
 | 
					      matrix:
 | 
				
			||||||
        operating-system: [ubuntu-latest, windows-latest, macOS-latest]
 | 
					        operating-system: [ubuntu-22.04, windows-latest, macOS-latest]
 | 
				
			||||||
    steps:
 | 
					    steps:
 | 
				
			||||||
      - name: Checkout
 | 
					      - name: Checkout
 | 
				
			||||||
        uses: actions/checkout@v3
 | 
					        uses: actions/checkout@v3
 | 
				
			||||||
@ -94,7 +94,7 @@ jobs:
 | 
				
			|||||||
    strategy:
 | 
					    strategy:
 | 
				
			||||||
      fail-fast: false
 | 
					      fail-fast: false
 | 
				
			||||||
      matrix:
 | 
					      matrix:
 | 
				
			||||||
        operating-system: [ubuntu-latest, windows-latest, macOS-latest]
 | 
					        operating-system: [ubuntu-22.04, windows-latest, macos-13]
 | 
				
			||||||
    steps:
 | 
					    steps:
 | 
				
			||||||
      - name: Checkout
 | 
					      - name: Checkout
 | 
				
			||||||
        uses: actions/checkout@v3
 | 
					        uses: actions/checkout@v3
 | 
				
			||||||
@ -114,7 +114,7 @@ jobs:
 | 
				
			|||||||
    strategy:
 | 
					    strategy:
 | 
				
			||||||
      fail-fast: false
 | 
					      fail-fast: false
 | 
				
			||||||
      matrix:
 | 
					      matrix:
 | 
				
			||||||
        operating-system: [ubuntu-latest, windows-latest, macOS-latest]
 | 
					        operating-system: [ubuntu-22.04, windows-latest, macOS-latest]
 | 
				
			||||||
    steps:
 | 
					    steps:
 | 
				
			||||||
      - name: Checkout
 | 
					      - name: Checkout
 | 
				
			||||||
        uses: actions/checkout@v3
 | 
					        uses: actions/checkout@v3
 | 
				
			||||||
@ -138,7 +138,7 @@ jobs:
 | 
				
			|||||||
    strategy:
 | 
					    strategy:
 | 
				
			||||||
      fail-fast: false
 | 
					      fail-fast: false
 | 
				
			||||||
      matrix:
 | 
					      matrix:
 | 
				
			||||||
        operating-system: [ubuntu-latest, windows-latest, macOS-latest]
 | 
					        operating-system: [ubuntu-22.04, windows-latest, macOS-latest]
 | 
				
			||||||
    steps:
 | 
					    steps:
 | 
				
			||||||
      - name: Checkout
 | 
					      - name: Checkout
 | 
				
			||||||
        uses: actions/checkout@v3
 | 
					        uses: actions/checkout@v3
 | 
				
			||||||
@ -159,7 +159,7 @@ jobs:
 | 
				
			|||||||
    strategy:
 | 
					    strategy:
 | 
				
			||||||
      fail-fast: false
 | 
					      fail-fast: false
 | 
				
			||||||
      matrix:
 | 
					      matrix:
 | 
				
			||||||
        operating-system: [ubuntu-latest, windows-latest, macOS-latest]
 | 
					        operating-system: [ubuntu-22.04, windows-latest, macOS-latest]
 | 
				
			||||||
    steps:
 | 
					    steps:
 | 
				
			||||||
      - name: Checkout
 | 
					      - name: Checkout
 | 
				
			||||||
        uses: actions/checkout@v3
 | 
					        uses: actions/checkout@v3
 | 
				
			||||||
@ -183,7 +183,7 @@ jobs:
 | 
				
			|||||||
    strategy:
 | 
					    strategy:
 | 
				
			||||||
      fail-fast: false
 | 
					      fail-fast: false
 | 
				
			||||||
      matrix:
 | 
					      matrix:
 | 
				
			||||||
        operating-system: [ubuntu-latest, windows-latest, macOS-latest]
 | 
					        operating-system: [ubuntu-22.04, windows-latest, macOS-latest]
 | 
				
			||||||
    steps:
 | 
					    steps:
 | 
				
			||||||
      - name: Checkout
 | 
					      - name: Checkout
 | 
				
			||||||
        uses: actions/checkout@v3
 | 
					        uses: actions/checkout@v3
 | 
				
			||||||
@ -209,7 +209,7 @@ jobs:
 | 
				
			|||||||
    strategy:
 | 
					    strategy:
 | 
				
			||||||
      fail-fast: false
 | 
					      fail-fast: false
 | 
				
			||||||
      matrix:
 | 
					      matrix:
 | 
				
			||||||
        operating-system: [ubuntu-latest, windows-latest, macOS-latest]
 | 
					        operating-system: [ubuntu-22.04, windows-latest, macOS-latest]
 | 
				
			||||||
    steps:
 | 
					    steps:
 | 
				
			||||||
      - name: Checkout
 | 
					      - name: Checkout
 | 
				
			||||||
        uses: actions/checkout@v3
 | 
					        uses: actions/checkout@v3
 | 
				
			||||||
@ -234,7 +234,7 @@ jobs:
 | 
				
			|||||||
    strategy:
 | 
					    strategy:
 | 
				
			||||||
      fail-fast: false
 | 
					      fail-fast: false
 | 
				
			||||||
      matrix:
 | 
					      matrix:
 | 
				
			||||||
        operating-system: [ubuntu-latest, windows-latest, macOS-latest]
 | 
					        operating-system: [ubuntu-22.04, windows-latest, macOS-latest]
 | 
				
			||||||
    steps:
 | 
					    steps:
 | 
				
			||||||
      - name: Checkout
 | 
					      - name: Checkout
 | 
				
			||||||
        uses: actions/checkout@v3
 | 
					        uses: actions/checkout@v3
 | 
				
			||||||
@ -256,7 +256,7 @@ jobs:
 | 
				
			|||||||
    strategy:
 | 
					    strategy:
 | 
				
			||||||
      fail-fast: false
 | 
					      fail-fast: false
 | 
				
			||||||
      matrix:
 | 
					      matrix:
 | 
				
			||||||
        operating-system: [ubuntu-latest, windows-latest, macos-latest]
 | 
					        operating-system: [ubuntu-22.04, windows-latest, macos-latest]
 | 
				
			||||||
    env:
 | 
					    env:
 | 
				
			||||||
      NUGET_PACKAGES: ${{ github.workspace }}/.nuget/packages
 | 
					      NUGET_PACKAGES: ${{ github.workspace }}/.nuget/packages
 | 
				
			||||||
    steps:
 | 
					    steps:
 | 
				
			||||||
@ -287,7 +287,7 @@ jobs:
 | 
				
			|||||||
    strategy:
 | 
					    strategy:
 | 
				
			||||||
      fail-fast: false
 | 
					      fail-fast: false
 | 
				
			||||||
      matrix:
 | 
					      matrix:
 | 
				
			||||||
        operating-system: [ubuntu-latest, windows-latest, macos-latest]
 | 
					        operating-system: [ubuntu-22.04, windows-latest, macos-latest]
 | 
				
			||||||
    env:
 | 
					    env:
 | 
				
			||||||
      NUGET_PACKAGES: ${{ github.workspace }}/.nuget/packages
 | 
					      NUGET_PACKAGES: ${{ github.workspace }}/.nuget/packages
 | 
				
			||||||
    steps:
 | 
					    steps:
 | 
				
			||||||
@ -316,7 +316,7 @@ jobs:
 | 
				
			|||||||
    strategy:
 | 
					    strategy:
 | 
				
			||||||
      fail-fast: false
 | 
					      fail-fast: false
 | 
				
			||||||
      matrix:
 | 
					      matrix:
 | 
				
			||||||
        operating-system: [ubuntu-latest, windows-latest, macOS-latest]
 | 
					        operating-system: [ubuntu-22.04, windows-latest, macOS-latest]
 | 
				
			||||||
    steps:
 | 
					    steps:
 | 
				
			||||||
      - name: Checkout
 | 
					      - name: Checkout
 | 
				
			||||||
        uses: actions/checkout@v3
 | 
					        uses: actions/checkout@v3
 | 
				
			||||||
@ -342,7 +342,7 @@ jobs:
 | 
				
			|||||||
    strategy:
 | 
					    strategy:
 | 
				
			||||||
      fail-fast: false
 | 
					      fail-fast: false
 | 
				
			||||||
      matrix:
 | 
					      matrix:
 | 
				
			||||||
        operating-system: [ubuntu-latest, windows-latest, macOS-latest]
 | 
					        operating-system: [ubuntu-22.04, windows-latest, macOS-latest]
 | 
				
			||||||
    steps:
 | 
					    steps:
 | 
				
			||||||
      - name: Checkout
 | 
					      - name: Checkout
 | 
				
			||||||
        uses: actions/checkout@v3
 | 
					        uses: actions/checkout@v3
 | 
				
			||||||
@ -366,7 +366,7 @@ jobs:
 | 
				
			|||||||
          if (-not ($version -eq '${{steps.step2.outputs.dotnet-version}}')) { throw "Unexpected output value" }
 | 
					          if (-not ($version -eq '${{steps.step2.outputs.dotnet-version}}')) { throw "Unexpected output value" }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  test-proxy:
 | 
					  test-proxy:
 | 
				
			||||||
    runs-on: ubuntu-latest
 | 
					    runs-on: ubuntu-22.04
 | 
				
			||||||
    container:
 | 
					    container:
 | 
				
			||||||
      image: ubuntu:latest
 | 
					      image: ubuntu:latest
 | 
				
			||||||
      options: --dns 127.0.0.1
 | 
					      options: --dns 127.0.0.1
 | 
				
			||||||
@ -406,7 +406,7 @@ jobs:
 | 
				
			|||||||
          __tests__/verify-dotnet.ps1 -Patterns "^6.0" -CheckNugetConfig
 | 
					          __tests__/verify-dotnet.ps1 -Patterns "^6.0" -CheckNugetConfig
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  test-bypass-proxy:
 | 
					  test-bypass-proxy:
 | 
				
			||||||
    runs-on: ubuntu-latest
 | 
					    runs-on: ubuntu-22.04
 | 
				
			||||||
    env:
 | 
					    env:
 | 
				
			||||||
      https_proxy: http://no-such-proxy:3128
 | 
					      https_proxy: http://no-such-proxy:3128
 | 
				
			||||||
      no_proxy: github.com,dotnetcli.blob.core.windows.net,download.visualstudio.microsoft.com,api.nuget.org,dotnetcli.azureedge.net
 | 
					      no_proxy: github.com,dotnetcli.blob.core.windows.net,download.visualstudio.microsoft.com,api.nuget.org,dotnetcli.azureedge.net
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										2
									
								
								.github/workflows/test-dotnet.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.github/workflows/test-dotnet.yml
									
									
									
									
										vendored
									
									
								
							@ -17,7 +17,7 @@ jobs:
 | 
				
			|||||||
    strategy:
 | 
					    strategy:
 | 
				
			||||||
      fail-fast: false
 | 
					      fail-fast: false
 | 
				
			||||||
      matrix:
 | 
					      matrix:
 | 
				
			||||||
        operating-system: [ubuntu-latest, windows-latest, macOS-latest]
 | 
					        operating-system: [ubuntu-22.04, windows-latest, macOS-latest]
 | 
				
			||||||
        dotnet-version: ['2.1', '2.2', '3.0', '3.1', '5.0', '6.0', '7.0', '8.0']
 | 
					        dotnet-version: ['2.1', '2.2', '3.0', '3.1', '5.0', '6.0', '7.0', '8.0']
 | 
				
			||||||
    steps:
 | 
					    steps:
 | 
				
			||||||
      - name: Checkout
 | 
					      - name: Checkout
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										11
									
								
								dist/setup/index.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										11
									
								
								dist/setup/index.js
									
									
									
									
										vendored
									
									
								
							@ -71264,7 +71264,13 @@ class DotnetVersionResolver {
 | 
				
			|||||||
                allowRetries: true,
 | 
					                allowRetries: true,
 | 
				
			||||||
                maxRetries: 3
 | 
					                maxRetries: 3
 | 
				
			||||||
            });
 | 
					            });
 | 
				
			||||||
            const response = yield httpClient.getJson(DotnetVersionResolver.DotNetCoreIndexUrl);
 | 
					            let response;
 | 
				
			||||||
 | 
					            try {
 | 
				
			||||||
 | 
					                response = yield httpClient.getJson(DotnetVersionResolver.DotNetCoreIndexUrl);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            catch (error) {
 | 
				
			||||||
 | 
					                response = yield httpClient.getJson(DotnetVersionResolver.DotnetCoreIndexFallbackUrl);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
            const result = response.result || {};
 | 
					            const result = response.result || {};
 | 
				
			||||||
            const releasesInfo = result['releases-index'];
 | 
					            const releasesInfo = result['releases-index'];
 | 
				
			||||||
            const releaseInfo = releasesInfo.find(info => {
 | 
					            const releaseInfo = releasesInfo.find(info => {
 | 
				
			||||||
@ -71279,7 +71285,8 @@ class DotnetVersionResolver {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
exports.DotnetVersionResolver = DotnetVersionResolver;
 | 
					exports.DotnetVersionResolver = DotnetVersionResolver;
 | 
				
			||||||
DotnetVersionResolver.DotNetCoreIndexUrl = 'https://dotnetcli.azureedge.net/dotnet/release-metadata/releases-index.json';
 | 
					DotnetVersionResolver.DotNetCoreIndexUrl = 'https://builds.dotnet.microsoft.com/dotnet/release-metadata/releases-index.json';
 | 
				
			||||||
 | 
					DotnetVersionResolver.DotnetCoreIndexFallbackUrl = 'https://dotnetcli.azureedge.net/dotnet/release-metadata/releases-index.json';
 | 
				
			||||||
class DotnetCoreInstaller {
 | 
					class DotnetCoreInstaller {
 | 
				
			||||||
    constructor(version, quality) {
 | 
					    constructor(version, quality) {
 | 
				
			||||||
        this.version = version;
 | 
					        this.version = version;
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										649
									
								
								externals/install-dotnet.ps1
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										649
									
								
								externals/install-dotnet.ps1
									
									
									
									
										vendored
									
									
								
							@ -98,6 +98,16 @@
 | 
				
			|||||||
.PARAMETER DownloadTimeout
 | 
					.PARAMETER DownloadTimeout
 | 
				
			||||||
    Determines timeout duration in seconds for dowloading of the SDK file
 | 
					    Determines timeout duration in seconds for dowloading of the SDK file
 | 
				
			||||||
    Default: 1200 seconds (20 minutes)
 | 
					    Default: 1200 seconds (20 minutes)
 | 
				
			||||||
 | 
					.PARAMETER KeepZip
 | 
				
			||||||
 | 
					    If set, downloaded file is kept
 | 
				
			||||||
 | 
					.PARAMETER ZipPath
 | 
				
			||||||
 | 
					    Use that path to store installer, generated by default
 | 
				
			||||||
 | 
					.EXAMPLE
 | 
				
			||||||
 | 
					    dotnet-install.ps1 -Version 7.0.401
 | 
				
			||||||
 | 
					    Installs the .NET SDK version 7.0.401
 | 
				
			||||||
 | 
					.EXAMPLE
 | 
				
			||||||
 | 
					    dotnet-install.ps1 -Channel 8.0 -Quality GA
 | 
				
			||||||
 | 
					    Installs the latest GA (general availability) version of the .NET 8.0 SDK
 | 
				
			||||||
#>
 | 
					#>
 | 
				
			||||||
[cmdletbinding()]
 | 
					[cmdletbinding()]
 | 
				
			||||||
param(
 | 
					param(
 | 
				
			||||||
@ -121,7 +131,10 @@ param(
 | 
				
			|||||||
    [string[]]$ProxyBypassList = @(),
 | 
					    [string[]]$ProxyBypassList = @(),
 | 
				
			||||||
    [switch]$SkipNonVersionedFiles,
 | 
					    [switch]$SkipNonVersionedFiles,
 | 
				
			||||||
    [switch]$NoCdn,
 | 
					    [switch]$NoCdn,
 | 
				
			||||||
   [int]$DownloadTimeout=1200
 | 
					    [int]$DownloadTimeout = 1200,
 | 
				
			||||||
 | 
					    [switch]$KeepZip,
 | 
				
			||||||
 | 
					    [string]$ZipPath = [System.IO.Path]::combine([System.IO.Path]::GetTempPath(), [System.IO.Path]::GetRandomFileName()),
 | 
				
			||||||
 | 
					    [switch]$Help
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Set-StrictMode -Version Latest
 | 
					Set-StrictMode -Version Latest
 | 
				
			||||||
@ -173,7 +186,24 @@ function Say-Verbose($str) {
 | 
				
			|||||||
function Measure-Action($name, $block) {
 | 
					function Measure-Action($name, $block) {
 | 
				
			||||||
    $time = Measure-Command $block
 | 
					    $time = Measure-Command $block
 | 
				
			||||||
    $totalSeconds = $time.TotalSeconds
 | 
					    $totalSeconds = $time.TotalSeconds
 | 
				
			||||||
    Say-Verbose "⏱ Action '$name' took $totalSeconds seconds"
 | 
					    Say-Verbose "Action '$name' took $totalSeconds seconds"
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function Get-Remote-File-Size($zipUri) {
 | 
				
			||||||
 | 
					    try {
 | 
				
			||||||
 | 
					        $response = Invoke-WebRequest -Uri $zipUri -Method Head
 | 
				
			||||||
 | 
					        $fileSize = $response.Headers["Content-Length"]
 | 
				
			||||||
 | 
					        if ((![string]::IsNullOrEmpty($fileSize))) {
 | 
				
			||||||
 | 
					            Say "Remote file $zipUri size is $fileSize bytes."
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					            return $fileSize
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    catch {
 | 
				
			||||||
 | 
					        Say-Verbose "Content-Length header was not extracted for $zipUri."
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return $null
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function Say-Invocation($Invocation) {
 | 
					function Say-Invocation($Invocation) {
 | 
				
			||||||
@ -219,8 +249,7 @@ function Get-Machine-Architecture() {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    try {        
 | 
					    try {        
 | 
				
			||||||
        if ( ((Get-CimInstance -ClassName CIM_OperatingSystem).OSArchitecture) -like "ARM*") {
 | 
					        if ( ((Get-CimInstance -ClassName CIM_OperatingSystem).OSArchitecture) -like "ARM*") {
 | 
				
			||||||
            if( [Environment]::Is64BitOperatingSystem )
 | 
					            if ( [Environment]::Is64BitOperatingSystem ) {
 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                return "arm64"
 | 
					                return "arm64"
 | 
				
			||||||
            }  
 | 
					            }  
 | 
				
			||||||
            return "arm"
 | 
					            return "arm"
 | 
				
			||||||
@ -249,13 +278,13 @@ function Get-CLIArchitecture-From-Architecture([string]$Architecture) {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function ValidateFeedCredential([string] $FeedCredential)
 | 
					function ValidateFeedCredential([string] $FeedCredential) {
 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    if ($Internal -and [string]::IsNullOrWhitespace($FeedCredential)) {
 | 
					    if ($Internal -and [string]::IsNullOrWhitespace($FeedCredential)) {
 | 
				
			||||||
        $message = "Provide credentials via -FeedCredential parameter."
 | 
					        $message = "Provide credentials via -FeedCredential parameter."
 | 
				
			||||||
        if ($DryRun) {
 | 
					        if ($DryRun) {
 | 
				
			||||||
            Say-Warning "$message"
 | 
					            Say-Warning "$message"
 | 
				
			||||||
        } else {
 | 
					        }
 | 
				
			||||||
 | 
					        else {
 | 
				
			||||||
            throw "$message"
 | 
					            throw "$message"
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -347,8 +376,7 @@ function Load-Assembly([string] $Assembly) {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function GetHTTPResponse([Uri] $Uri, [bool]$HeaderOnly, [bool]$DisableRedirect, [bool]$DisableFeedCredential)
 | 
					function GetHTTPResponse([Uri] $Uri, [bool]$HeaderOnly, [bool]$DisableRedirect, [bool]$DisableFeedCredential) {
 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    $cts = New-Object System.Threading.CancellationTokenSource
 | 
					    $cts = New-Object System.Threading.CancellationTokenSource
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    $downloadScript = {
 | 
					    $downloadScript = {
 | 
				
			||||||
@ -366,12 +394,14 @@ function GetHTTPResponse([Uri] $Uri, [bool]$HeaderOnly, [bool]$DisableRedirect,
 | 
				
			|||||||
                    if ($DefaultProxy -and (-not $DefaultProxy.IsBypassed($Uri))) {
 | 
					                    if ($DefaultProxy -and (-not $DefaultProxy.IsBypassed($Uri))) {
 | 
				
			||||||
                        if ($null -ne $DefaultProxy.GetProxy($Uri)) {
 | 
					                        if ($null -ne $DefaultProxy.GetProxy($Uri)) {
 | 
				
			||||||
                            $ProxyAddress = $DefaultProxy.GetProxy($Uri).OriginalString
 | 
					                            $ProxyAddress = $DefaultProxy.GetProxy($Uri).OriginalString
 | 
				
			||||||
                        } else {
 | 
					                        }
 | 
				
			||||||
 | 
					                        else {
 | 
				
			||||||
                            $ProxyAddress = $null
 | 
					                            $ProxyAddress = $null
 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
                        $ProxyUseDefaultCredentials = $true
 | 
					                        $ProxyUseDefaultCredentials = $true
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                } catch {
 | 
					                }
 | 
				
			||||||
 | 
					                catch {
 | 
				
			||||||
                    # Eat the exception and move forward as the above code is an attempt
 | 
					                    # Eat the exception and move forward as the above code is an attempt
 | 
				
			||||||
                    #    at resolving the DefaultProxy that may not have been a problem.
 | 
					                    #    at resolving the DefaultProxy that may not have been a problem.
 | 
				
			||||||
                    $ProxyAddress = $null
 | 
					                    $ProxyAddress = $null
 | 
				
			||||||
@ -387,8 +417,7 @@ function GetHTTPResponse([Uri] $Uri, [bool]$HeaderOnly, [bool]$DisableRedirect,
 | 
				
			|||||||
                    BypassList            = $ProxyBypassList;
 | 
					                    BypassList            = $ProxyBypassList;
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }       
 | 
					            }       
 | 
				
			||||||
            if ($DisableRedirect)
 | 
					            if ($DisableRedirect) {
 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                $HttpClientHandler.AllowAutoRedirect = $false
 | 
					                $HttpClientHandler.AllowAutoRedirect = $false
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            $HttpClient = New-Object System.Net.Http.HttpClient -ArgumentList $HttpClientHandler
 | 
					            $HttpClient = New-Object System.Net.Http.HttpClient -ArgumentList $HttpClientHandler
 | 
				
			||||||
@ -422,8 +451,7 @@ function GetHTTPResponse([Uri] $Uri, [bool]$HeaderOnly, [bool]$DisableRedirect,
 | 
				
			|||||||
                    $DownloadException.Data["StatusCode"] = [int] $Response.StatusCode
 | 
					                    $DownloadException.Data["StatusCode"] = [int] $Response.StatusCode
 | 
				
			||||||
                    $DownloadException.Data["ErrorMessage"] = "Unable to download $Uri. Returned HTTP status code: " + $DownloadException.Data["StatusCode"]
 | 
					                    $DownloadException.Data["ErrorMessage"] = "Unable to download $Uri. Returned HTTP status code: " + $DownloadException.Data["StatusCode"]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    if (404 -eq [int] $Response.StatusCode)
 | 
					                    if (404 -eq [int] $Response.StatusCode) {
 | 
				
			||||||
                    {
 | 
					 | 
				
			||||||
                        $cts.Cancel()
 | 
					                        $cts.Cancel()
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
@ -462,10 +490,8 @@ function GetHTTPResponse([Uri] $Uri, [bool]$HeaderOnly, [bool]$DisableRedirect,
 | 
				
			|||||||
    try {
 | 
					    try {
 | 
				
			||||||
        return Invoke-With-Retry $downloadScript $cts.Token
 | 
					        return Invoke-With-Retry $downloadScript $cts.Token
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    finally
 | 
					    finally {
 | 
				
			||||||
    {
 | 
					        if ($null -ne $cts) {
 | 
				
			||||||
        if ($null -ne $cts)
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            $cts.Dispose()
 | 
					            $cts.Dispose()
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -583,11 +609,9 @@ function Get-Download-Link([string]$AzureFeed, [string]$SpecificVersion, [string
 | 
				
			|||||||
    elseif ($Runtime -eq "windowsdesktop") {
 | 
					    elseif ($Runtime -eq "windowsdesktop") {
 | 
				
			||||||
        # The windows desktop runtime is part of the core runtime layout prior to 5.0
 | 
					        # The windows desktop runtime is part of the core runtime layout prior to 5.0
 | 
				
			||||||
        $PayloadURL = "$AzureFeed/Runtime/$SpecificVersion/windowsdesktop-runtime-$SpecificProductVersion-win-$CLIArchitecture.zip"
 | 
					        $PayloadURL = "$AzureFeed/Runtime/$SpecificVersion/windowsdesktop-runtime-$SpecificProductVersion-win-$CLIArchitecture.zip"
 | 
				
			||||||
        if ($SpecificVersion -match '^(\d+)\.(.*)$')
 | 
					        if ($SpecificVersion -match '^(\d+)\.(.*)$') {
 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            $majorVersion = [int]$Matches[1]
 | 
					            $majorVersion = [int]$Matches[1]
 | 
				
			||||||
            if ($majorVersion -ge 5)
 | 
					            if ($majorVersion -ge 5) {
 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                $PayloadURL = "$AzureFeed/WindowsDesktop/$SpecificVersion/windowsdesktop-runtime-$SpecificProductVersion-win-$CLIArchitecture.zip"
 | 
					                $PayloadURL = "$AzureFeed/WindowsDesktop/$SpecificVersion/windowsdesktop-runtime-$SpecificProductVersion-win-$CLIArchitecture.zip"
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@ -637,8 +661,7 @@ function Get-Product-Version([string]$AzureFeed, [string]$SpecificVersion, [stri
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
            if ($productVersionResponse.StatusCode -eq 200) {
 | 
					            if ($productVersionResponse.StatusCode -eq 200) {
 | 
				
			||||||
                $productVersion = $productVersionResponse.Content.ReadAsStringAsync().Result.Trim()
 | 
					                $productVersion = $productVersionResponse.Content.ReadAsStringAsync().Result.Trim()
 | 
				
			||||||
                if ($productVersion -ne $SpecificVersion)
 | 
					                if ($productVersion -ne $SpecificVersion) {
 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    Say "Using alternate version $productVersion found in $ProductVersionTxtURL"
 | 
					                    Say "Using alternate version $productVersion found in $ProductVersionTxtURL"
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                return $productVersion
 | 
					                return $productVersion
 | 
				
			||||||
@ -653,8 +676,7 @@ function Get-Product-Version([string]$AzureFeed, [string]$SpecificVersion, [stri
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # Getting the version number with productVersion.txt has failed. Try parsing the download link for a version number.
 | 
					    # Getting the version number with productVersion.txt has failed. Try parsing the download link for a version number.
 | 
				
			||||||
    if ([string]::IsNullOrEmpty($PackageDownloadLink))
 | 
					    if ([string]::IsNullOrEmpty($PackageDownloadLink)) {
 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        Say-Verbose "Using the default value '$SpecificVersion' as the product version."
 | 
					        Say-Verbose "Using the default value '$SpecificVersion' as the product version."
 | 
				
			||||||
        return $SpecificVersion
 | 
					        return $SpecificVersion
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -714,16 +736,14 @@ function Get-Product-Version-Url([string]$AzureFeed, [string]$SpecificVersion, [
 | 
				
			|||||||
    return $ProductVersionTxtURL
 | 
					    return $ProductVersionTxtURL
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function Get-ProductVersionFromDownloadLink([string]$PackageDownloadLink, [string]$SpecificVersion)
 | 
					function Get-ProductVersionFromDownloadLink([string]$PackageDownloadLink, [string]$SpecificVersion) {
 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    Say-Invocation $MyInvocation
 | 
					    Say-Invocation $MyInvocation
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    #product specific version follows the product name
 | 
					    #product specific version follows the product name
 | 
				
			||||||
    #for filename 'dotnet-sdk-3.1.404-win-x64.zip': the product version is 3.1.400
 | 
					    #for filename 'dotnet-sdk-3.1.404-win-x64.zip': the product version is 3.1.400
 | 
				
			||||||
    $filename = $PackageDownloadLink.Substring($PackageDownloadLink.LastIndexOf("/") + 1)
 | 
					    $filename = $PackageDownloadLink.Substring($PackageDownloadLink.LastIndexOf("/") + 1)
 | 
				
			||||||
    $filenameParts = $filename.Split('-')
 | 
					    $filenameParts = $filename.Split('-')
 | 
				
			||||||
    if ($filenameParts.Length -gt 2)
 | 
					    if ($filenameParts.Length -gt 2) {
 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $productVersion = $filenameParts[2]
 | 
					        $productVersion = $filenameParts[2]
 | 
				
			||||||
        Say-Verbose "Extracted product version '$productVersion' from download link '$PackageDownloadLink'."
 | 
					        Say-Verbose "Extracted product version '$productVersion' from download link '$PackageDownloadLink'."
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -741,6 +761,9 @@ function Get-User-Share-Path() {
 | 
				
			|||||||
    if (!$InstallRoot) {
 | 
					    if (!$InstallRoot) {
 | 
				
			||||||
        $InstallRoot = "$env:LocalAppData\Microsoft\dotnet"
 | 
					        $InstallRoot = "$env:LocalAppData\Microsoft\dotnet"
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    elseif ($InstallRoot -like "$env:ProgramFiles\dotnet\?*") {
 | 
				
			||||||
 | 
					        Say-Warning "The install root specified by the environment variable DOTNET_INSTALL_DIR points to the sub folder of $env:ProgramFiles\dotnet which is the default dotnet install root using .NET SDK installer. It is better to keep aligned with .NET SDK installer."
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
    return $InstallRoot
 | 
					    return $InstallRoot
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -753,6 +776,19 @@ function Resolve-Installation-Path([string]$InstallDir) {
 | 
				
			|||||||
    return $InstallDir
 | 
					    return $InstallDir
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function Test-User-Write-Access([string]$InstallDir) {
 | 
				
			||||||
 | 
					    try {
 | 
				
			||||||
 | 
					        $tempFileName = [guid]::NewGuid().ToString()
 | 
				
			||||||
 | 
					        $tempFilePath = Join-Path -Path $InstallDir -ChildPath $tempFileName
 | 
				
			||||||
 | 
					        New-Item -Path $tempFilePath -ItemType File -Force
 | 
				
			||||||
 | 
					        Remove-Item $tempFilePath -Force
 | 
				
			||||||
 | 
					        return $true
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    catch {
 | 
				
			||||||
 | 
					        return $false
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function Is-Dotnet-Package-Installed([string]$InstallRoot, [string]$RelativePathToPackage, [string]$SpecificVersion) {
 | 
					function Is-Dotnet-Package-Installed([string]$InstallRoot, [string]$RelativePathToPackage, [string]$SpecificVersion) {
 | 
				
			||||||
    Say-Invocation $MyInvocation
 | 
					    Say-Invocation $MyInvocation
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -836,8 +872,7 @@ function Extract-Dotnet-Package([string]$ZipPath, [string]$OutPath) {
 | 
				
			|||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    catch
 | 
					    catch {
 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        Say-Error "Failed to extract package. Exception: $_"
 | 
					        Say-Error "Failed to extract package. Exception: $_"
 | 
				
			||||||
        throw;
 | 
					        throw;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -869,6 +904,8 @@ function DownloadFile($Source, [string]$OutPath) {
 | 
				
			|||||||
        $File = [System.IO.File]::Create($OutPath)
 | 
					        $File = [System.IO.File]::Create($OutPath)
 | 
				
			||||||
        $Stream.CopyTo($File)
 | 
					        $Stream.CopyTo($File)
 | 
				
			||||||
        $File.Close()
 | 
					        $File.Close()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        ValidateRemoteLocalFileSizes -LocalFileOutPath $OutPath -SourceUri $Source
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    finally {
 | 
					    finally {
 | 
				
			||||||
        if ($null -ne $Stream) {
 | 
					        if ($null -ne $Stream) {
 | 
				
			||||||
@ -877,19 +914,40 @@ function DownloadFile($Source, [string]$OutPath) {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function ValidateRemoteLocalFileSizes([string]$LocalFileOutPath, $SourceUri) {
 | 
				
			||||||
 | 
					    try {
 | 
				
			||||||
 | 
					        $remoteFileSize = Get-Remote-File-Size -zipUri $SourceUri
 | 
				
			||||||
 | 
					        $fileSize = [long](Get-Item $LocalFileOutPath).Length
 | 
				
			||||||
 | 
					        Say "Downloaded file $SourceUri size is $fileSize bytes."
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					        if ((![string]::IsNullOrEmpty($remoteFileSize)) -and !([string]::IsNullOrEmpty($fileSize)) ) {
 | 
				
			||||||
 | 
					            if ($remoteFileSize -ne $fileSize) {
 | 
				
			||||||
 | 
					                Say "The remote and local file sizes are not equal. Remote file size is $remoteFileSize bytes and local size is $fileSize bytes. The local package may be corrupted."
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            else {
 | 
				
			||||||
 | 
					                Say "The remote and local file sizes are equal."
 | 
				
			||||||
 | 
					            }   
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        else {
 | 
				
			||||||
 | 
					            Say "Either downloaded or local package size can not be measured. One of them may be corrupted."
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    catch {
 | 
				
			||||||
 | 
					        Say "Either downloaded or local package size can not be measured. One of them may be corrupted."
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function SafeRemoveFile($Path) {
 | 
					function SafeRemoveFile($Path) {
 | 
				
			||||||
    try {
 | 
					    try {
 | 
				
			||||||
        if (Test-Path $Path) {
 | 
					        if (Test-Path $Path) {
 | 
				
			||||||
            Remove-Item $Path
 | 
					            Remove-Item $Path
 | 
				
			||||||
            Say-Verbose "The temporary file `"$Path`" was removed."
 | 
					            Say-Verbose "The temporary file `"$Path`" was removed."
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        else
 | 
					        else {
 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            Say-Verbose "The temporary file `"$Path`" does not exist, therefore is not removed."
 | 
					            Say-Verbose "The temporary file `"$Path`" does not exist, therefore is not removed."
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    catch
 | 
					    catch {
 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        Say-Warning "Failed to remove the temporary file: `"$Path`", remove it manually."
 | 
					        Say-Warning "Failed to remove the temporary file: `"$Path`", remove it manually."
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -901,7 +959,8 @@ function Prepend-Sdk-InstallRoot-To-Path([string]$InstallRoot) {
 | 
				
			|||||||
        if (-Not $env:path.Contains($SuffixedBinPath)) {
 | 
					        if (-Not $env:path.Contains($SuffixedBinPath)) {
 | 
				
			||||||
            Say "Adding to current process PATH: `"$BinPath`". Note: This change will not be visible if PowerShell was run as a child process."
 | 
					            Say "Adding to current process PATH: `"$BinPath`". Note: This change will not be visible if PowerShell was run as a child process."
 | 
				
			||||||
            $env:path = $SuffixedBinPath + $env:path
 | 
					            $env:path = $SuffixedBinPath + $env:path
 | 
				
			||||||
        } else {
 | 
					        }
 | 
				
			||||||
 | 
					        else {
 | 
				
			||||||
            Say-Verbose "Current process PATH already contains `"$BinPath`""
 | 
					            Say-Verbose "Current process PATH already contains `"$BinPath`""
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -910,8 +969,7 @@ function Prepend-Sdk-InstallRoot-To-Path([string]$InstallRoot) {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function PrintDryRunOutput($Invocation, $DownloadLinks)
 | 
					function PrintDryRunOutput($Invocation, $DownloadLinks) {
 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    Say "Payload URLs:"
 | 
					    Say "Payload URLs:"
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    for ($linkIndex = 0; $linkIndex -lt $DownloadLinks.count; $linkIndex++) {
 | 
					    for ($linkIndex = 0; $linkIndex -lt $DownloadLinks.count; $linkIndex++) {
 | 
				
			||||||
@ -934,12 +992,37 @@ function PrintDryRunOutput($Invocation, $DownloadLinks)
 | 
				
			|||||||
        $RepeatableCommand += " -FeedCredential `"<feedCredential>`""
 | 
					        $RepeatableCommand += " -FeedCredential `"<feedCredential>`""
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    Say "Repeatable invocation: $RepeatableCommand"
 | 
					    Say "Repeatable invocation: $RepeatableCommand"
 | 
				
			||||||
    if ($SpecificVersion -ne $EffectiveVersion)
 | 
					    if ($SpecificVersion -ne $EffectiveVersion) {
 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        Say "NOTE: Due to finding a version manifest with this runtime, it would actually install with version '$EffectiveVersion'"
 | 
					        Say "NOTE: Due to finding a version manifest with this runtime, it would actually install with version '$EffectiveVersion'"
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# grab the 'stem' of the redirect and check it against all of our configured feeds, 
 | 
				
			||||||
 | 
					# if it matches, we can be sure that the redirect is valid and we should use it for
 | 
				
			||||||
 | 
					# subsequent processing
 | 
				
			||||||
 | 
					function Sanitize-RedirectUrl([string]$url) {
 | 
				
			||||||
 | 
					    $urlSegments = ([System.Uri]$url).Segments;
 | 
				
			||||||
 | 
					    $urlStem = $urlSegments[2..($urlSegments.Length - 1)] -join "";
 | 
				
			||||||
 | 
					    Write-Verbose "Checking configured feeds for the asset at $urlStem"
 | 
				
			||||||
 | 
					    foreach ($prospectiveFeed in $feeds) {
 | 
				
			||||||
 | 
					        $trialUrl = "$prospectiveFeed/$urlStem";
 | 
				
			||||||
 | 
					        Write-Verbose "Checking $trialUrl"
 | 
				
			||||||
 | 
					        try {
 | 
				
			||||||
 | 
					            $trialResponse = Invoke-WebRequest -Uri $trialUrl -Method HEAD
 | 
				
			||||||
 | 
					            if ($trialResponse.StatusCode -eq 200) {
 | 
				
			||||||
 | 
					                Write-Verbose "Found a match at $trialUrl"
 | 
				
			||||||
 | 
					                return $trialUrl;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            else {
 | 
				
			||||||
 | 
					                Write-Verbose "No match at $trialUrl"
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        catch {
 | 
				
			||||||
 | 
					            Write-Verbose "Failed to check $trialUrl"
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function Get-AkaMSDownloadLink([string]$Channel, [string]$Quality, [bool]$Internal, [string]$Product, [string]$Architecture) {
 | 
					function Get-AkaMSDownloadLink([string]$Channel, [string]$Quality, [bool]$Internal, [string]$Product, [string]$Architecture) {
 | 
				
			||||||
    Say-Invocation $MyInvocation 
 | 
					    Say-Invocation $MyInvocation 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -963,8 +1046,7 @@ function Get-AkaMSDownloadLink([string]$Channel, [string]$Quality, [bool]$Intern
 | 
				
			|||||||
    Say-Verbose  "Constructed aka.ms link: '$akaMsLink'."
 | 
					    Say-Verbose  "Constructed aka.ms link: '$akaMsLink'."
 | 
				
			||||||
    $akaMsDownloadLink = $null
 | 
					    $akaMsDownloadLink = $null
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    for ($maxRedirections = 9; $maxRedirections -ge 0; $maxRedirections--)
 | 
					    for ($maxRedirections = 9; $maxRedirections -ge 0; $maxRedirections--) {
 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        #get HTTP response
 | 
					        #get HTTP response
 | 
				
			||||||
        #do not pass credentials as a part of the $akaMsLink and do not apply credentials in the GetHTTPResponse function
 | 
					        #do not pass credentials as a part of the $akaMsLink and do not apply credentials in the GetHTTPResponse function
 | 
				
			||||||
        #otherwise the redirect link would have credentials as well
 | 
					        #otherwise the redirect link would have credentials as well
 | 
				
			||||||
@ -978,8 +1060,7 @@ function Get-AkaMSDownloadLink([string]$Channel, [string]$Quality, [bool]$Intern
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        #if HTTP code is 301 (Moved Permanently), the redirect link exists
 | 
					        #if HTTP code is 301 (Moved Permanently), the redirect link exists
 | 
				
			||||||
        if  ($Response.StatusCode -eq 301)
 | 
					        if ($Response.StatusCode -eq 301) {
 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            try {
 | 
					            try {
 | 
				
			||||||
                $akaMsDownloadLink = $Response.Headers.GetValues("Location")[0]
 | 
					                $akaMsDownloadLink = $Response.Headers.GetValues("Location")[0]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -998,9 +1079,13 @@ function Get-AkaMSDownloadLink([string]$Channel, [string]$Quality, [bool]$Intern
 | 
				
			|||||||
                return $null
 | 
					                return $null
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        elseif ((($Response.StatusCode -lt 300) -or ($Response.StatusCode -ge 400)) -and (-not [string]::IsNullOrEmpty($akaMsDownloadLink)))
 | 
					        elseif ((($Response.StatusCode -lt 300) -or ($Response.StatusCode -ge 400)) -and (-not [string]::IsNullOrEmpty($akaMsDownloadLink))) {
 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            # Redirections have ended.
 | 
					            # Redirections have ended.
 | 
				
			||||||
 | 
					            $actualRedirectUrl = Sanitize-RedirectUrl $akaMsDownloadLink
 | 
				
			||||||
 | 
					            if ($null -ne $actualRedirectUrl) {
 | 
				
			||||||
 | 
					                $akaMsDownloadLink = $actualRedirectUrl
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            return $akaMsDownloadLink
 | 
					            return $akaMsDownloadLink
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -1049,10 +1134,11 @@ function Get-AkaMsLink-And-Version([string] $NormalizedChannel, [string] $Normal
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function Get-Feeds-To-Use()
 | 
					function Get-Feeds-To-Use() {
 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    $feeds = @(
 | 
					    $feeds = @(
 | 
				
			||||||
    "https://dotnetcli.azureedge.net/dotnet",
 | 
					        "https://builds.dotnet.microsoft.com/dotnet"
 | 
				
			||||||
 | 
					        "https://dotnetcli.azureedge.net/dotnet"
 | 
				
			||||||
 | 
					        "https://ci.dot.net/public"
 | 
				
			||||||
        "https://dotnetbuilds.azureedge.net/public"
 | 
					        "https://dotnetbuilds.azureedge.net/public"
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -1071,6 +1157,8 @@ function Get-Feeds-To-Use()
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Write-Verbose "Initialized feeds: $feeds"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return $feeds
 | 
					    return $feeds
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -1100,6 +1188,13 @@ function Resolve-AssetName-And-RelativePath([string] $Runtime) {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function Prepare-Install-Directory {
 | 
					function Prepare-Install-Directory {
 | 
				
			||||||
 | 
					    $diskSpaceWarning = "Failed to check the disk space. Installation will continue, but it may fail if you do not have enough disk space.";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if ($PSVersionTable.PSVersion.Major -lt 7) {
 | 
				
			||||||
 | 
					        Say-Verbose $diskSpaceWarning
 | 
				
			||||||
 | 
					        return
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    New-Item -ItemType Directory -Force -Path $InstallRoot | Out-Null
 | 
					    New-Item -ItemType Directory -Force -Path $InstallRoot | Out-Null
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    $installDrive = $((Get-Item $InstallRoot -Force).PSDrive.Name);
 | 
					    $installDrive = $((Get-Item $InstallRoot -Force).PSDrive.Name);
 | 
				
			||||||
@ -1108,14 +1203,20 @@ function Prepare-Install-Directory {
 | 
				
			|||||||
        $diskInfo = Get-PSDrive -Name $installDrive
 | 
					        $diskInfo = Get-PSDrive -Name $installDrive
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    catch {
 | 
					    catch {
 | 
				
			||||||
        Say-Warning "Failed to check the disk space. Installation will continue, but it may fail if you do not have enough disk space."
 | 
					        Say-Warning $diskSpaceWarning
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # The check is relevant for PS version >= 7, the result can be irrelevant for older versions. See https://github.com/PowerShell/PowerShell/issues/12442.
 | 
				
			||||||
    if ( ($null -ne $diskInfo) -and ($diskInfo.Free / 1MB -le 100)) {
 | 
					    if ( ($null -ne $diskInfo) -and ($diskInfo.Free / 1MB -le 100)) {
 | 
				
			||||||
        throw "There is not enough disk space on drive ${installDrive}:"
 | 
					        throw "There is not enough disk space on drive ${installDrive}:"
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if ($Help) {
 | 
				
			||||||
 | 
					    Get-Help $PSCommandPath -Examples
 | 
				
			||||||
 | 
					    exit
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Say-Verbose "Note that the intended use of this script is for Continuous Integration (CI) scenarios, where:"
 | 
					Say-Verbose "Note that the intended use of this script is for Continuous Integration (CI) scenarios, where:"
 | 
				
			||||||
Say-Verbose "- The SDK needs to be installed without user interaction and without admin rights."
 | 
					Say-Verbose "- The SDK needs to be installed without user interaction and without admin rights."
 | 
				
			||||||
Say-Verbose "- The SDK installation doesn't need to persist across multiple CI runs."
 | 
					Say-Verbose "- The SDK installation doesn't need to persist across multiple CI runs."
 | 
				
			||||||
@ -1139,6 +1240,10 @@ Measure-Action "Product discovery" {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
$InstallRoot = Resolve-Installation-Path $InstallDir
 | 
					$InstallRoot = Resolve-Installation-Path $InstallDir
 | 
				
			||||||
 | 
					if (-not (Test-User-Write-Access $InstallRoot)) {
 | 
				
			||||||
 | 
					    Say-Error "The current user doesn't have write access to the installation root '$InstallRoot' to install .NET. Please try specifying a different installation directory using the -InstallDir parameter, or ensure the selected directory has the appropriate permissions."
 | 
				
			||||||
 | 
					    throw
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
Say-Verbose "InstallRoot: $InstallRoot"
 | 
					Say-Verbose "InstallRoot: $InstallRoot"
 | 
				
			||||||
$ScriptName = $MyInvocation.MyCommand.Name
 | 
					$ScriptName = $MyInvocation.MyCommand.Name
 | 
				
			||||||
($assetName, $dotnetPackageRelativePath) = Resolve-AssetName-And-RelativePath -Runtime $Runtime
 | 
					($assetName, $dotnetPackageRelativePath) = Resolve-AssetName-And-RelativePath -Runtime $Runtime
 | 
				
			||||||
@ -1160,8 +1265,7 @@ if ([string]::IsNullOrEmpty($JSonFile) -and ($Version -eq "latest")) {
 | 
				
			|||||||
        
 | 
					        
 | 
				
			||||||
        if (-Not $DryRun) {
 | 
					        if (-Not $DryRun) {
 | 
				
			||||||
            Say-Verbose "Checking if the version $EffectiveVersion is already installed"
 | 
					            Say-Verbose "Checking if the version $EffectiveVersion is already installed"
 | 
				
			||||||
            if (Is-Dotnet-Package-Installed -InstallRoot $InstallRoot -RelativePathToPackage $dotnetPackageRelativePath -SpecificVersion $EffectiveVersion)
 | 
					            if (Is-Dotnet-Package-Installed -InstallRoot $InstallRoot -RelativePathToPackage $dotnetPackageRelativePath -SpecificVersion $EffectiveVersion) {
 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                Say "$assetName with version '$EffectiveVersion' is already installed."
 | 
					                Say "$assetName with version '$EffectiveVersion' is already installed."
 | 
				
			||||||
                Prepend-Sdk-InstallRoot-To-Path -InstallRoot $InstallRoot
 | 
					                Prepend-Sdk-InstallRoot-To-Path -InstallRoot $InstallRoot
 | 
				
			||||||
                return
 | 
					                return
 | 
				
			||||||
@ -1172,8 +1276,7 @@ if ([string]::IsNullOrEmpty($JSonFile) -and ($Version -eq "latest")) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
# Primary and legacy links cannot be used if a quality was specified.
 | 
					# Primary and legacy links cannot be used if a quality was specified.
 | 
				
			||||||
# If we already have an aka.ms link, no need to search the blob feeds.
 | 
					# If we already have an aka.ms link, no need to search the blob feeds.
 | 
				
			||||||
if ([string]::IsNullOrEmpty($NormalizedQuality) -and 0 -eq $DownloadLinks.count)
 | 
					if ([string]::IsNullOrEmpty($NormalizedQuality) -and 0 -eq $DownloadLinks.count) {
 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    foreach ($feed in $feeds) {
 | 
					    foreach ($feed in $feeds) {
 | 
				
			||||||
        try {
 | 
					        try {
 | 
				
			||||||
            $SpecificVersion = Get-Specific-Version-From-Version -AzureFeed $feed -Channel $Channel -Version $Version -JSonFile $JSonFile
 | 
					            $SpecificVersion = Get-Specific-Version-From-Version -AzureFeed $feed -Channel $Channel -Version $Version -JSonFile $JSonFile
 | 
				
			||||||
@ -1190,16 +1293,14 @@ if ([string]::IsNullOrEmpty($NormalizedQuality) -and 0 -eq $DownloadLinks.count)
 | 
				
			|||||||
    
 | 
					    
 | 
				
			||||||
            if (-Not $DryRun) {
 | 
					            if (-Not $DryRun) {
 | 
				
			||||||
                Say-Verbose "Checking if the version $EffectiveVersion is already installed"
 | 
					                Say-Verbose "Checking if the version $EffectiveVersion is already installed"
 | 
				
			||||||
                if (Is-Dotnet-Package-Installed -InstallRoot $InstallRoot -RelativePathToPackage $dotnetPackageRelativePath -SpecificVersion $EffectiveVersion)
 | 
					                if (Is-Dotnet-Package-Installed -InstallRoot $InstallRoot -RelativePathToPackage $dotnetPackageRelativePath -SpecificVersion $EffectiveVersion) {
 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    Say "$assetName with version '$EffectiveVersion' is already installed."
 | 
					                    Say "$assetName with version '$EffectiveVersion' is already installed."
 | 
				
			||||||
                    Prepend-Sdk-InstallRoot-To-Path -InstallRoot $InstallRoot
 | 
					                    Prepend-Sdk-InstallRoot-To-Path -InstallRoot $InstallRoot
 | 
				
			||||||
                    return
 | 
					                    return
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        catch
 | 
					        catch {
 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            Say-Verbose "Failed to acquire download links from feed $feed. Exception: $_"
 | 
					            Say-Verbose "Failed to acquire download links from feed $feed. Exception: $_"
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -1216,15 +1317,13 @@ if ($DryRun) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
Measure-Action "Installation directory preparation" { Prepare-Install-Directory }
 | 
					Measure-Action "Installation directory preparation" { Prepare-Install-Directory }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
$ZipPath = [System.IO.Path]::combine([System.IO.Path]::GetTempPath(), [System.IO.Path]::GetRandomFileName())
 | 
					 | 
				
			||||||
Say-Verbose "Zip path: $ZipPath"
 | 
					Say-Verbose "Zip path: $ZipPath"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
$DownloadSucceeded = $false
 | 
					$DownloadSucceeded = $false
 | 
				
			||||||
$DownloadedLink = $null
 | 
					$DownloadedLink = $null
 | 
				
			||||||
$ErrorMessages = @()
 | 
					$ErrorMessages = @()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
foreach ($link in $DownloadLinks)
 | 
					foreach ($link in $DownloadLinks) {
 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    Say-Verbose "Downloading `"$($link.type)`" link $($link.downloadLink)"
 | 
					    Say-Verbose "Downloading `"$($link.type)`" link $($link.downloadLink)"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    try {
 | 
					    try {
 | 
				
			||||||
@ -1244,7 +1343,8 @@ foreach ($link in $DownloadLinks)
 | 
				
			|||||||
    
 | 
					    
 | 
				
			||||||
        if ($PSItem.Exception.Data.Contains("ErrorMessage")) {
 | 
					        if ($PSItem.Exception.Data.Contains("ErrorMessage")) {
 | 
				
			||||||
            $ErrorMessage = $PSItem.Exception.Data["ErrorMessage"]
 | 
					            $ErrorMessage = $PSItem.Exception.Data["ErrorMessage"]
 | 
				
			||||||
        } else {
 | 
					        }
 | 
				
			||||||
 | 
					        else {
 | 
				
			||||||
            $ErrorMessage = $PSItem.Exception.Message
 | 
					            $ErrorMessage = $PSItem.Exception.Message
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -1289,226 +1389,231 @@ if (!$isAssetInstalled) {
 | 
				
			|||||||
    throw "`"$assetName`" with version = $($DownloadedLink.effectiveVersion) failed to install with an unknown error."
 | 
					    throw "`"$assetName`" with version = $($DownloadedLink.effectiveVersion) failed to install with an unknown error."
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if (-not $KeepZip) {
 | 
				
			||||||
    SafeRemoveFile -Path $ZipPath
 | 
					    SafeRemoveFile -Path $ZipPath
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Measure-Action "Setting up shell environment" { Prepend-Sdk-InstallRoot-To-Path -InstallRoot $InstallRoot }
 | 
					Measure-Action "Setting up shell environment" { Prepend-Sdk-InstallRoot-To-Path -InstallRoot $InstallRoot }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Say "Note that the script does not resolve dependencies during installation."
 | 
					Say "Note that the script does not ensure your Windows version is supported during the installation."
 | 
				
			||||||
Say "To check the list of dependencies, go to https://learn.microsoft.com/dotnet/core/install/windows#dependencies"
 | 
					Say "To check the list of supported versions, go to https://learn.microsoft.com/dotnet/core/install/windows#supported-versions"
 | 
				
			||||||
Say "Installed version is $($DownloadedLink.effectiveVersion)"
 | 
					Say "Installed version is $($DownloadedLink.effectiveVersion)"
 | 
				
			||||||
Say "Installation finished"
 | 
					Say "Installation finished"
 | 
				
			||||||
# SIG # Begin signature block
 | 
					# SIG # Begin signature block
 | 
				
			||||||
# MIInvwYJKoZIhvcNAQcCoIInsDCCJ6wCAQExDzANBglghkgBZQMEAgEFADB5Bgor
 | 
					# MIIoVQYJKoZIhvcNAQcCoIIoRjCCKEICAQExDzANBglghkgBZQMEAgEFADB5Bgor
 | 
				
			||||||
# BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG
 | 
					# BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG
 | 
				
			||||||
# KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCBhfTi3SRn7+vyy
 | 
					# KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCAYvsOYTXPcgaBF
 | 
				
			||||||
# uCXKPjhiawegWZ493EcaOEycbgkZcKCCDXYwggX0MIID3KADAgECAhMzAAACy7d1
 | 
					# C8M6oYBHzvQKaqKPOJVvd3P0sSBCw6CCDYUwggYDMIID66ADAgECAhMzAAAEA73V
 | 
				
			||||||
# OfsCcUI2AAAAAALLMA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNVBAYTAlVTMRMwEQYD
 | 
					# lV0POxitAAAAAAQDMA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNVBAYTAlVTMRMwEQYD
 | 
				
			||||||
# VQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNy
 | 
					# VQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNy
 | 
				
			||||||
# b3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMTH01pY3Jvc29mdCBDb2RlIFNpZ25p
 | 
					# b3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMTH01pY3Jvc29mdCBDb2RlIFNpZ25p
 | 
				
			||||||
# bmcgUENBIDIwMTEwHhcNMjIwNTEyMjA0NTU5WhcNMjMwNTExMjA0NTU5WjB0MQsw
 | 
					# bmcgUENBIDIwMTEwHhcNMjQwOTEyMjAxMTEzWhcNMjUwOTExMjAxMTEzWjB0MQsw
 | 
				
			||||||
# CQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9u
 | 
					# CQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9u
 | 
				
			||||||
# ZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMR4wHAYDVQQDExVNaWNy
 | 
					# ZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMR4wHAYDVQQDExVNaWNy
 | 
				
			||||||
# b3NvZnQgQ29ycG9yYXRpb24wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
 | 
					# b3NvZnQgQ29ycG9yYXRpb24wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
 | 
				
			||||||
# AQC3sN0WcdGpGXPZIb5iNfFB0xZ8rnJvYnxD6Uf2BHXglpbTEfoe+mO//oLWkRxA
 | 
					# AQCfdGddwIOnbRYUyg03O3iz19XXZPmuhEmW/5uyEN+8mgxl+HJGeLGBR8YButGV
 | 
				
			||||||
# wppditsSVOD0oglKbtnh9Wp2DARLcxbGaW4YanOWSB1LyLRpHnnQ5POlh2U5trg4
 | 
					# LVK38RxcVcPYyFGQXcKcxgih4w4y4zJi3GvawLYHlsNExQwz+v0jgY/aejBS2EJY
 | 
				
			||||||
# 3gQjvlNZlQB3lL+zrPtbNvMA7E0Wkmo+Z6YFnsf7aek+KGzaGboAeFO4uKZjQXY5
 | 
					# oUhLVE+UzRihV8ooxoftsmKLb2xb7BoFS6UAo3Zz4afnOdqI7FGoi7g4vx/0MIdi
 | 
				
			||||||
# RmMzE70Bwaz7hvA05jDURdRKH0i/1yK96TDuP7JyRFLOvA3UXNWz00R9w7ppMDcN
 | 
					# kwTn5N56TdIv3mwfkZCFmrsKpN0zR8HD8WYsvH3xKkG7u/xdqmhPPqMmnI2jOFw/
 | 
				
			||||||
# lXtrmbPigv3xE9FfpfmJRtiOZQKd73K72Wujmj6/Su3+DBTpOq7NgdntW2lJfX3X
 | 
					# /n2aL8W7i1Pasja8PnRXH/QaVH0M1nanL+LI9TsMb/enWfXOW65Gne5cqMN9Uofv
 | 
				
			||||||
# a6oe4F9Pk9xRhkwHsk7Ju9E/AgMBAAGjggFzMIIBbzAfBgNVHSUEGDAWBgorBgEE
 | 
					# ENtdwwEmJ3bZrcI9u4LZAkujAgMBAAGjggGCMIIBfjAfBgNVHSUEGDAWBgorBgEE
 | 
				
			||||||
# AYI3TAgBBggrBgEFBQcDAzAdBgNVHQ4EFgQUrg/nt/gj+BBLd1jZWYhok7v5/w4w
 | 
					# AYI3TAgBBggrBgEFBQcDAzAdBgNVHQ4EFgQU6m4qAkpz4641iK2irF8eWsSBcBkw
 | 
				
			||||||
# RQYDVR0RBD4wPKQ6MDgxHjAcBgNVBAsTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEW
 | 
					# VAYDVR0RBE0wS6RJMEcxLTArBgNVBAsTJE1pY3Jvc29mdCBJcmVsYW5kIE9wZXJh
 | 
				
			||||||
# MBQGA1UEBRMNMjMwMDEyKzQ3MDUyODAfBgNVHSMEGDAWgBRIbmTlUAXTgqoXNzci
 | 
					# dGlvbnMgTGltaXRlZDEWMBQGA1UEBRMNMjMwMDEyKzUwMjkyNjAfBgNVHSMEGDAW
 | 
				
			||||||
# tW2oynUClTBUBgNVHR8ETTBLMEmgR6BFhkNodHRwOi8vd3d3Lm1pY3Jvc29mdC5j
 | 
					# gBRIbmTlUAXTgqoXNzcitW2oynUClTBUBgNVHR8ETTBLMEmgR6BFhkNodHRwOi8v
 | 
				
			||||||
# b20vcGtpb3BzL2NybC9NaWNDb2RTaWdQQ0EyMDExXzIwMTEtMDctMDguY3JsMGEG
 | 
					# d3d3Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2NybC9NaWNDb2RTaWdQQ0EyMDExXzIw
 | 
				
			||||||
# CCsGAQUFBwEBBFUwUzBRBggrBgEFBQcwAoZFaHR0cDovL3d3dy5taWNyb3NvZnQu
 | 
					# MTEtMDctMDguY3JsMGEGCCsGAQUFBwEBBFUwUzBRBggrBgEFBQcwAoZFaHR0cDov
 | 
				
			||||||
# Y29tL3BraW9wcy9jZXJ0cy9NaWNDb2RTaWdQQ0EyMDExXzIwMTEtMDctMDguY3J0
 | 
					# L3d3dy5taWNyb3NvZnQuY29tL3BraW9wcy9jZXJ0cy9NaWNDb2RTaWdQQ0EyMDEx
 | 
				
			||||||
# MAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcNAQELBQADggIBAJL5t6pVjIRlQ8j4dAFJ
 | 
					# XzIwMTEtMDctMDguY3J0MAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcNAQELBQADggIB
 | 
				
			||||||
# ZnMke3rRHeQDOPFxswM47HRvgQa2E1jea2aYiMk1WmdqWnYw1bal4IzRlSVf4czf
 | 
					# AFFo/6E4LX51IqFuoKvUsi80QytGI5ASQ9zsPpBa0z78hutiJd6w154JkcIx/f7r
 | 
				
			||||||
# zx2vjOIOiaGllW2ByHkfKApngOzJmAQ8F15xSHPRvNMmvpC3PFLvKMf3y5SyPJxh
 | 
					# EBK4NhD4DIFNfRiVdI7EacEs7OAS6QHF7Nt+eFRNOTtgHb9PExRy4EI/jnMwzQJV
 | 
				
			||||||
# 922TTq0q5epJv1SgZDWlUlHL/Ex1nX8kzBRhHvc6D6F5la+oAO4A3o/ZC05OOgm4
 | 
					# NokTxu2WgHr/fBsWs6G9AcIgvHjWNN3qRSrhsgEdqHc0bRDUf8UILAdEZOMBvKLC
 | 
				
			||||||
# EJxZP9MqUi5iid2dw4Jg/HvtDpCcLj1GLIhCDaebKegajCJlMhhxnDXrGFLJfX8j
 | 
					# rmf+kJPEvPldgK7hFO/L9kmcVe67BnKejDKO73Sa56AJOhM7CkeATrJFxO9GLXos
 | 
				
			||||||
# 7k7LUvrZDsQniJZ3D66K+3SZTLhvwK7dMGVFuUUJUfDifrlCTjKG9mxsPDllfyck
 | 
					# oKvrwBvynxAg18W+pagTAkJefzneuWSmniTurPCUE2JnvW7DalvONDOtG01sIVAB
 | 
				
			||||||
# 4zGnRZv8Jw9RgE1zAghnU14L0vVUNOzi/4bE7wIsiRyIcCcVoXRneBA3n/frLXvd
 | 
					# +ahO2wcUPa2Zm9AiDVBWTMz9XUoKMcvngi2oqbsDLhbK+pYrRUgRpNt0y1sxZsXO
 | 
				
			||||||
# jDsbb2lpGu78+s1zbO5N0bhHWq4j5WMutrspBxEhqG2PSBjC5Ypi+jhtfu3+x76N
 | 
					# raGRF8lM2cWvtEkV5UL+TQM1ppv5unDHkW8JS+QnfPbB8dZVRyRmMQ4aY/tx5x5+
 | 
				
			||||||
# mBvsyKuxx9+Hm/ALnlzKxr4KyMR3/z4IRMzA1QyppNk65Ui+jB14g+w4vole33M1
 | 
					# sX6semJ//FbiclSMxSI+zINu1jYerdUwuCi+P6p7SmQmClhDM+6Q+btE2FtpsU0W
 | 
				
			||||||
# pVqVckrmSebUkmjnCshCiH12IFgHZF7gRwE4YZrJ7QjxZeoZqHaKsQLRMp653beB
 | 
					# +r6RdYFf/P+nK6j2otl9Nvr3tWLu+WXmz8MGM+18ynJ+lYbSmFWcAj7SYziAfT0s
 | 
				
			||||||
# fHfeva9zJPhBSdVcCW7x9q0c2HVPLJHX9YCUU714I+qtLpDGrdbZxD9mikPqL/To
 | 
					# IwlQRFkyC71tsIZUhBHtxPliGUu362lIO0Lpe0DOrg8lspnEWOkHnCT5JEnWCbzu
 | 
				
			||||||
# /1lDZ0ch8FtePhME7houuoPcMIIHejCCBWKgAwIBAgIKYQ6Q0gAAAAAAAzANBgkq
 | 
					# iVt8RX1IV07uIveNZuOBWLVCzWJjEGa+HhaEtavjy6i7MIIHejCCBWKgAwIBAgIK
 | 
				
			||||||
# hkiG9w0BAQsFADCBiDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24x
 | 
					# YQ6Q0gAAAAAAAzANBgkqhkiG9w0BAQsFADCBiDELMAkGA1UEBhMCVVMxEzARBgNV
 | 
				
			||||||
# EDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlv
 | 
					 | 
				
			||||||
# bjEyMDAGA1UEAxMpTWljcm9zb2Z0IFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5
 | 
					 | 
				
			||||||
# IDIwMTEwHhcNMTEwNzA4MjA1OTA5WhcNMjYwNzA4MjEwOTA5WjB+MQswCQYDVQQG
 | 
					 | 
				
			||||||
# EwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwG
 | 
					 | 
				
			||||||
# A1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSgwJgYDVQQDEx9NaWNyb3NvZnQg
 | 
					 | 
				
			||||||
# Q29kZSBTaWduaW5nIFBDQSAyMDExMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC
 | 
					 | 
				
			||||||
# CgKCAgEAq/D6chAcLq3YbqqCEE00uvK2WCGfQhsqa+laUKq4BjgaBEm6f8MMHt03
 | 
					 | 
				
			||||||
# a8YS2AvwOMKZBrDIOdUBFDFC04kNeWSHfpRgJGyvnkmc6Whe0t+bU7IKLMOv2akr
 | 
					 | 
				
			||||||
# rnoJr9eWWcpgGgXpZnboMlImEi/nqwhQz7NEt13YxC4Ddato88tt8zpcoRb0Rrrg
 | 
					 | 
				
			||||||
# OGSsbmQ1eKagYw8t00CT+OPeBw3VXHmlSSnnDb6gE3e+lD3v++MrWhAfTVYoonpy
 | 
					 | 
				
			||||||
# 4BI6t0le2O3tQ5GD2Xuye4Yb2T6xjF3oiU+EGvKhL1nkkDstrjNYxbc+/jLTswM9
 | 
					 | 
				
			||||||
# sbKvkjh+0p2ALPVOVpEhNSXDOW5kf1O6nA+tGSOEy/S6A4aN91/w0FK/jJSHvMAh
 | 
					 | 
				
			||||||
# dCVfGCi2zCcoOCWYOUo2z3yxkq4cI6epZuxhH2rhKEmdX4jiJV3TIUs+UsS1Vz8k
 | 
					 | 
				
			||||||
# A/DRelsv1SPjcF0PUUZ3s/gA4bysAoJf28AVs70b1FVL5zmhD+kjSbwYuER8ReTB
 | 
					 | 
				
			||||||
# w3J64HLnJN+/RpnF78IcV9uDjexNSTCnq47f7Fufr/zdsGbiwZeBe+3W7UvnSSmn
 | 
					 | 
				
			||||||
# Eyimp31ngOaKYnhfsi+E11ecXL93KCjx7W3DKI8sj0A3T8HhhUSJxAlMxdSlQy90
 | 
					 | 
				
			||||||
# lfdu+HggWCwTXWCVmj5PM4TasIgX3p5O9JawvEagbJjS4NaIjAsCAwEAAaOCAe0w
 | 
					 | 
				
			||||||
# ggHpMBAGCSsGAQQBgjcVAQQDAgEAMB0GA1UdDgQWBBRIbmTlUAXTgqoXNzcitW2o
 | 
					 | 
				
			||||||
# ynUClTAZBgkrBgEEAYI3FAIEDB4KAFMAdQBiAEMAQTALBgNVHQ8EBAMCAYYwDwYD
 | 
					 | 
				
			||||||
# VR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAWgBRyLToCMZBDuRQFTuHqp8cx0SOJNDBa
 | 
					 | 
				
			||||||
# BgNVHR8EUzBRME+gTaBLhklodHRwOi8vY3JsLm1pY3Jvc29mdC5jb20vcGtpL2Ny
 | 
					 | 
				
			||||||
# bC9wcm9kdWN0cy9NaWNSb29DZXJBdXQyMDExXzIwMTFfMDNfMjIuY3JsMF4GCCsG
 | 
					 | 
				
			||||||
# AQUFBwEBBFIwUDBOBggrBgEFBQcwAoZCaHR0cDovL3d3dy5taWNyb3NvZnQuY29t
 | 
					 | 
				
			||||||
# L3BraS9jZXJ0cy9NaWNSb29DZXJBdXQyMDExXzIwMTFfMDNfMjIuY3J0MIGfBgNV
 | 
					 | 
				
			||||||
# HSAEgZcwgZQwgZEGCSsGAQQBgjcuAzCBgzA/BggrBgEFBQcCARYzaHR0cDovL3d3
 | 
					 | 
				
			||||||
# dy5taWNyb3NvZnQuY29tL3BraW9wcy9kb2NzL3ByaW1hcnljcHMuaHRtMEAGCCsG
 | 
					 | 
				
			||||||
# AQUFBwICMDQeMiAdAEwAZQBnAGEAbABfAHAAbwBsAGkAYwB5AF8AcwB0AGEAdABl
 | 
					 | 
				
			||||||
# AG0AZQBuAHQALiAdMA0GCSqGSIb3DQEBCwUAA4ICAQBn8oalmOBUeRou09h0ZyKb
 | 
					 | 
				
			||||||
# C5YR4WOSmUKWfdJ5DJDBZV8uLD74w3LRbYP+vj/oCso7v0epo/Np22O/IjWll11l
 | 
					 | 
				
			||||||
# hJB9i0ZQVdgMknzSGksc8zxCi1LQsP1r4z4HLimb5j0bpdS1HXeUOeLpZMlEPXh6
 | 
					 | 
				
			||||||
# I/MTfaaQdION9MsmAkYqwooQu6SpBQyb7Wj6aC6VoCo/KmtYSWMfCWluWpiW5IP0
 | 
					 | 
				
			||||||
# wI/zRive/DvQvTXvbiWu5a8n7dDd8w6vmSiXmE0OPQvyCInWH8MyGOLwxS3OW560
 | 
					 | 
				
			||||||
# STkKxgrCxq2u5bLZ2xWIUUVYODJxJxp/sfQn+N4sOiBpmLJZiWhub6e3dMNABQam
 | 
					 | 
				
			||||||
# ASooPoI/E01mC8CzTfXhj38cbxV9Rad25UAqZaPDXVJihsMdYzaXht/a8/jyFqGa
 | 
					 | 
				
			||||||
# J+HNpZfQ7l1jQeNbB5yHPgZ3BtEGsXUfFL5hYbXw3MYbBL7fQccOKO7eZS/sl/ah
 | 
					 | 
				
			||||||
# XJbYANahRr1Z85elCUtIEJmAH9AAKcWxm6U/RXceNcbSoqKfenoi+kiVH6v7RyOA
 | 
					 | 
				
			||||||
# 9Z74v2u3S5fi63V4GuzqN5l5GEv/1rMjaHXmr/r8i+sLgOppO6/8MO0ETI7f33Vt
 | 
					 | 
				
			||||||
# Y5E90Z1WTk+/gFcioXgRMiF670EKsT/7qMykXcGhiJtXcVZOSEXAQsmbdlsKgEhr
 | 
					 | 
				
			||||||
# /Xmfwb1tbWrJUnMTDXpQzTGCGZ8wghmbAgEBMIGVMH4xCzAJBgNVBAYTAlVTMRMw
 | 
					 | 
				
			||||||
# EQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVN
 | 
					 | 
				
			||||||
# aWNyb3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMTH01pY3Jvc29mdCBDb2RlIFNp
 | 
					 | 
				
			||||||
# Z25pbmcgUENBIDIwMTECEzMAAALLt3U5+wJxQjYAAAAAAsswDQYJYIZIAWUDBAIB
 | 
					 | 
				
			||||||
# BQCgga4wGQYJKoZIhvcNAQkDMQwGCisGAQQBgjcCAQQwHAYKKwYBBAGCNwIBCzEO
 | 
					 | 
				
			||||||
# MAwGCisGAQQBgjcCARUwLwYJKoZIhvcNAQkEMSIEIFmuaTXYQ37AFvsEol24fdW+
 | 
					 | 
				
			||||||
# nRqHcc1fr+VQVdqhXc/vMEIGCisGAQQBgjcCAQwxNDAyoBSAEgBNAGkAYwByAG8A
 | 
					 | 
				
			||||||
# cwBvAGYAdKEagBhodHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20wDQYJKoZIhvcNAQEB
 | 
					 | 
				
			||||||
# BQAEggEAjY5XW5Ly7TJ1OTbeIR98xU+2dmtw7L71ws+ICnQCGhj2xJDUK+5yrTfO
 | 
					 | 
				
			||||||
# 8C98l/P4ynFi33Dl8z2YElqUCuqEXbiCzz06lIL4NuibC5DV/X80ZmICR/NYd2v1
 | 
					 | 
				
			||||||
# ww7IH+7dpsHAowBBindCYpVwQ3Ea3kDWgsjPAinAysFFushSOnNWFvrF6vi2smrs
 | 
					 | 
				
			||||||
# smbrAAhEhSfLd1Pxxdw73hQ0YjM/D3F3opaybMQ0blpHhOaqtbiyYzvk0doIzBEc
 | 
					 | 
				
			||||||
# trSH4NDIc3yLNj5VbjSczpexE+hyQNY4xCtwco4bVtXhONUihv08AIKR8+sIaI7A
 | 
					 | 
				
			||||||
# mM/SWrrwGYSSSxydKqDei7biKG4jDqGCFykwghclBgorBgEEAYI3AwMBMYIXFTCC
 | 
					 | 
				
			||||||
# FxEGCSqGSIb3DQEHAqCCFwIwghb+AgEDMQ8wDQYJYIZIAWUDBAIBBQAwggFZBgsq
 | 
					 | 
				
			||||||
# hkiG9w0BCRABBKCCAUgEggFEMIIBQAIBAQYKKwYBBAGEWQoDATAxMA0GCWCGSAFl
 | 
					 | 
				
			||||||
# AwQCAQUABCB6Hzt2gUb/WZK8fvVnOocriE4rYr6mscZi3gZnBCpiigIGZBr2iMZU
 | 
					 | 
				
			||||||
# GBMyMDIzMDMzMTE1MjEwNi41MTZaMASAAgH0oIHYpIHVMIHSMQswCQYDVQQGEwJV
 | 
					 | 
				
			||||||
# UzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UE
 | 
					 | 
				
			||||||
# ChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMS0wKwYDVQQLEyRNaWNyb3NvZnQgSXJl
 | 
					 | 
				
			||||||
# bGFuZCBPcGVyYXRpb25zIExpbWl0ZWQxJjAkBgNVBAsTHVRoYWxlcyBUU1MgRVNO
 | 
					 | 
				
			||||||
# OjA4NDItNEJFNi1DMjlBMSUwIwYDVQQDExxNaWNyb3NvZnQgVGltZS1TdGFtcCBT
 | 
					 | 
				
			||||||
# ZXJ2aWNloIIReDCCBycwggUPoAMCAQICEzMAAAGybkADf26plJIAAQAAAbIwDQYJ
 | 
					 | 
				
			||||||
# KoZIhvcNAQELBQAwfDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24x
 | 
					 | 
				
			||||||
# EDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlv
 | 
					 | 
				
			||||||
# bjEmMCQGA1UEAxMdTWljcm9zb2Z0IFRpbWUtU3RhbXAgUENBIDIwMTAwHhcNMjIw
 | 
					 | 
				
			||||||
# OTIwMjAyMjAxWhcNMjMxMjE0MjAyMjAxWjCB0jELMAkGA1UEBhMCVVMxEzARBgNV
 | 
					 | 
				
			||||||
# BAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jv
 | 
					# BAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jv
 | 
				
			||||||
# c29mdCBDb3Jwb3JhdGlvbjEtMCsGA1UECxMkTWljcm9zb2Z0IElyZWxhbmQgT3Bl
 | 
					# c29mdCBDb3Jwb3JhdGlvbjEyMDAGA1UEAxMpTWljcm9zb2Z0IFJvb3QgQ2VydGlm
 | 
				
			||||||
# cmF0aW9ucyBMaW1pdGVkMSYwJAYDVQQLEx1UaGFsZXMgVFNTIEVTTjowODQyLTRC
 | 
					# aWNhdGUgQXV0aG9yaXR5IDIwMTEwHhcNMTEwNzA4MjA1OTA5WhcNMjYwNzA4MjEw
 | 
				
			||||||
# RTYtQzI5QTElMCMGA1UEAxMcTWljcm9zb2Z0IFRpbWUtU3RhbXAgU2VydmljZTCC
 | 
					# OTA5WjB+MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UE
 | 
				
			||||||
# AiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMqiZTIde/lQ4rC+Bml5f/Wu
 | 
					# BxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSgwJgYD
 | 
				
			||||||
# q/xKTxrfbG23HofmQ+qZAN4GyO73PF3y9OAfpt7Qf2jcldWOGUB+HzBuwllYyP3f
 | 
					# VQQDEx9NaWNyb3NvZnQgQ29kZSBTaWduaW5nIFBDQSAyMDExMIICIjANBgkqhkiG
 | 
				
			||||||
# x4MY8zvuAuB37FvoytnNC2DKnVrVlHOVcGUL9CnmhDNMA2/nskjIf2IoiG9J0qLY
 | 
					# 9w0BAQEFAAOCAg8AMIICCgKCAgEAq/D6chAcLq3YbqqCEE00uvK2WCGfQhsqa+la
 | 
				
			||||||
# r8duvHdQJ9Li2Pq9guySb9mvUL60ogslCO9gkh6FiEDwMrwUr8Wja6jFpUTny8tg
 | 
					# UKq4BjgaBEm6f8MMHt03a8YS2AvwOMKZBrDIOdUBFDFC04kNeWSHfpRgJGyvnkmc
 | 
				
			||||||
# 0N0cnCN2w4fKkp5qZcbUYFYicLSb/6A7pHCtX6xnjqwhmJoib3vkKJyVxbuFLRhV
 | 
					# 6Whe0t+bU7IKLMOv2akrrnoJr9eWWcpgGgXpZnboMlImEi/nqwhQz7NEt13YxC4D
 | 
				
			||||||
# XxH95b0LHeNhifn3jvo2j+/4QV10jEpXVW+iC9BsTtR69xvTjU51ZgP7BR4YDEWq
 | 
					# dato88tt8zpcoRb0RrrgOGSsbmQ1eKagYw8t00CT+OPeBw3VXHmlSSnnDb6gE3e+
 | 
				
			||||||
# 7JsylSOv5B5THTDXRf184URzFhTyb8OZQKY7mqMh7c8J8w1sEM4XDUF2UZNy829N
 | 
					# lD3v++MrWhAfTVYoonpy4BI6t0le2O3tQ5GD2Xuye4Yb2T6xjF3oiU+EGvKhL1nk
 | 
				
			||||||
# VCzG2tfdEXZaHxF8RmxpQYBxyhZwY1rotuIS+gfN2eq+hkAT3ipGn8/KmDwDtzAb
 | 
					# kDstrjNYxbc+/jLTswM9sbKvkjh+0p2ALPVOVpEhNSXDOW5kf1O6nA+tGSOEy/S6
 | 
				
			||||||
# nfuXjApgeZqwgcYJ8pDJ+y/xU6ouzJz1Bve5TTihkiA7wQsQe6R60Zk9dPdNzw0M
 | 
					# A4aN91/w0FK/jJSHvMAhdCVfGCi2zCcoOCWYOUo2z3yxkq4cI6epZuxhH2rhKEmd
 | 
				
			||||||
# K5niRzuQZAt4GI96FhjhlUWcUZOCkv/JXM/OGu/rgSplYwdmPLzzfDtXyuy/GCU5
 | 
					# X4jiJV3TIUs+UsS1Vz8kA/DRelsv1SPjcF0PUUZ3s/gA4bysAoJf28AVs70b1FVL
 | 
				
			||||||
# I4l08g6iifXypMgoYkkceOAAz4vx1x0BOnZWfI3fSwqNUvoN7ncTT+MB4Vpvf1QB
 | 
					# 5zmhD+kjSbwYuER8ReTBw3J64HLnJN+/RpnF78IcV9uDjexNSTCnq47f7Fufr/zd
 | 
				
			||||||
# ppjBAQUuvui6eCG0MCVNAgMBAAGjggFJMIIBRTAdBgNVHQ4EFgQUmfIngFzZEZlP
 | 
					# sGbiwZeBe+3W7UvnSSmnEyimp31ngOaKYnhfsi+E11ecXL93KCjx7W3DKI8sj0A3
 | 
				
			||||||
# kjDOVluBSDDaanEwHwYDVR0jBBgwFoAUn6cVXQBeYl2D9OXSZacbUzUZ6XIwXwYD
 | 
					# T8HhhUSJxAlMxdSlQy90lfdu+HggWCwTXWCVmj5PM4TasIgX3p5O9JawvEagbJjS
 | 
				
			||||||
# VR0fBFgwVjBUoFKgUIZOaHR0cDovL3d3dy5taWNyb3NvZnQuY29tL3BraW9wcy9j
 | 
					# 4NaIjAsCAwEAAaOCAe0wggHpMBAGCSsGAQQBgjcVAQQDAgEAMB0GA1UdDgQWBBRI
 | 
				
			||||||
# cmwvTWljcm9zb2Z0JTIwVGltZS1TdGFtcCUyMFBDQSUyMDIwMTAoMSkuY3JsMGwG
 | 
					# bmTlUAXTgqoXNzcitW2oynUClTAZBgkrBgEEAYI3FAIEDB4KAFMAdQBiAEMAQTAL
 | 
				
			||||||
# CCsGAQUFBwEBBGAwXjBcBggrBgEFBQcwAoZQaHR0cDovL3d3dy5taWNyb3NvZnQu
 | 
					# BgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAWgBRyLToCMZBD
 | 
				
			||||||
# Y29tL3BraW9wcy9jZXJ0cy9NaWNyb3NvZnQlMjBUaW1lLVN0YW1wJTIwUENBJTIw
 | 
					# uRQFTuHqp8cx0SOJNDBaBgNVHR8EUzBRME+gTaBLhklodHRwOi8vY3JsLm1pY3Jv
 | 
				
			||||||
# MjAxMCgxKS5jcnQwDAYDVR0TAQH/BAIwADAWBgNVHSUBAf8EDDAKBggrBgEFBQcD
 | 
					# c29mdC5jb20vcGtpL2NybC9wcm9kdWN0cy9NaWNSb29DZXJBdXQyMDExXzIwMTFf
 | 
				
			||||||
# CDAOBgNVHQ8BAf8EBAMCB4AwDQYJKoZIhvcNAQELBQADggIBANxHtu3FzIabaDbW
 | 
					# MDNfMjIuY3JsMF4GCCsGAQUFBwEBBFIwUDBOBggrBgEFBQcwAoZCaHR0cDovL3d3
 | 
				
			||||||
# qswdKBlAhKXRCN+5CSMiv2TYa4i2QuWIm+99piwAhDhADfbqor1zyLi95Y6GQnvI
 | 
					# dy5taWNyb3NvZnQuY29tL3BraS9jZXJ0cy9NaWNSb29DZXJBdXQyMDExXzIwMTFf
 | 
				
			||||||
# WUgdeC7oL1ZtZye92zYK+EIfwYZmhS+CH4infAzUvscHZF3wlrJUfPUIDGVP0lCY
 | 
					# MDNfMjIuY3J0MIGfBgNVHSAEgZcwgZQwgZEGCSsGAQQBgjcuAzCBgzA/BggrBgEF
 | 
				
			||||||
# Vse9mguvG0dqkY4ayQPEHOvJubgZZaOdg/N8dInd6fGeOc+0DoGzB+LieObJ2Q0A
 | 
					# BQcCARYzaHR0cDovL3d3dy5taWNyb3NvZnQuY29tL3BraW9wcy9kb2NzL3ByaW1h
 | 
				
			||||||
# tEt3XN3iX8Cp6+dZTX8xwE/LvhRwPpb/+nKshO7TVuvenwdTwqB/LT6CNPaElwFe
 | 
					# cnljcHMuaHRtMEAGCCsGAQUFBwICMDQeMiAdAEwAZQBnAGEAbABfAHAAbwBsAGkA
 | 
				
			||||||
# KxKrqRTPMbHeg+i+KnBLfwmhEXsMg2s1QX7JIxfvT96md0eiMjiMEO22LbOzmLMN
 | 
					# YwB5AF8AcwB0AGEAdABlAG0AZQBuAHQALiAdMA0GCSqGSIb3DQEBCwUAA4ICAQBn
 | 
				
			||||||
# d3LINowAnRBAJtX+3/e390B9sMGMHp+a1V+hgs62AopBl0p/00li30DN5wEQ5If3
 | 
					# 8oalmOBUeRou09h0ZyKbC5YR4WOSmUKWfdJ5DJDBZV8uLD74w3LRbYP+vj/oCso7
 | 
				
			||||||
# 5Zk7b/T6pEx6rJUDYCti7zCbikjKTanBnOc99zGMlej5X+fC/k5ExUCrOs3/VzGR
 | 
					# v0epo/Np22O/IjWll11lhJB9i0ZQVdgMknzSGksc8zxCi1LQsP1r4z4HLimb5j0b
 | 
				
			||||||
# CZt5LvVQSdWqq/QMzTEmim4sbzASK9imEkjNtZZyvC1CsUcD1voFktld4mKMjE+u
 | 
					# pdS1HXeUOeLpZMlEPXh6I/MTfaaQdION9MsmAkYqwooQu6SpBQyb7Wj6aC6VoCo/
 | 
				
			||||||
# DEV3IddD+DrRk94nVzNPSuZXewfVOnXHSeqG7xM3V7fl2aL4v1OhL2+JwO1Tx3B0
 | 
					# KmtYSWMfCWluWpiW5IP0wI/zRive/DvQvTXvbiWu5a8n7dDd8w6vmSiXmE0OPQvy
 | 
				
			||||||
# irO1O9qbNdJk355bntd1RSVKgM22KFBHnoL7Js7pRhBiaKmVTQGoOb+j1Qa7q+ci
 | 
					# CInWH8MyGOLwxS3OW560STkKxgrCxq2u5bLZ2xWIUUVYODJxJxp/sfQn+N4sOiBp
 | 
				
			||||||
# xGo48Vh9k35BDsJS/DLoXFSPDl4mMIIHcTCCBVmgAwIBAgITMwAAABXF52ueAptJ
 | 
					# mLJZiWhub6e3dMNABQamASooPoI/E01mC8CzTfXhj38cbxV9Rad25UAqZaPDXVJi
 | 
				
			||||||
# mQAAAAAAFTANBgkqhkiG9w0BAQsFADCBiDELMAkGA1UEBhMCVVMxEzARBgNVBAgT
 | 
					# hsMdYzaXht/a8/jyFqGaJ+HNpZfQ7l1jQeNbB5yHPgZ3BtEGsXUfFL5hYbXw3MYb
 | 
				
			||||||
# Cldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29m
 | 
					# BL7fQccOKO7eZS/sl/ahXJbYANahRr1Z85elCUtIEJmAH9AAKcWxm6U/RXceNcbS
 | 
				
			||||||
# dCBDb3Jwb3JhdGlvbjEyMDAGA1UEAxMpTWljcm9zb2Z0IFJvb3QgQ2VydGlmaWNh
 | 
					# oqKfenoi+kiVH6v7RyOA9Z74v2u3S5fi63V4GuzqN5l5GEv/1rMjaHXmr/r8i+sL
 | 
				
			||||||
# dGUgQXV0aG9yaXR5IDIwMTAwHhcNMjEwOTMwMTgyMjI1WhcNMzAwOTMwMTgzMjI1
 | 
					# gOppO6/8MO0ETI7f33VtY5E90Z1WTk+/gFcioXgRMiF670EKsT/7qMykXcGhiJtX
 | 
				
			||||||
# WjB8MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMH
 | 
					# cVZOSEXAQsmbdlsKgEhr/Xmfwb1tbWrJUnMTDXpQzTGCGiYwghoiAgEBMIGVMH4x
 | 
				
			||||||
# UmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSYwJAYDVQQD
 | 
					# CzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRt
 | 
				
			||||||
# Ex1NaWNyb3NvZnQgVGltZS1TdGFtcCBQQ0EgMjAxMDCCAiIwDQYJKoZIhvcNAQEB
 | 
					# b25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMTH01p
 | 
				
			||||||
# BQADggIPADCCAgoCggIBAOThpkzntHIhC3miy9ckeb0O1YLT/e6cBwfSqWxOdcjK
 | 
					# Y3Jvc29mdCBDb2RlIFNpZ25pbmcgUENBIDIwMTECEzMAAAQDvdWVXQ87GK0AAAAA
 | 
				
			||||||
# NVf2AX9sSuDivbk+F2Az/1xPx2b3lVNxWuJ+Slr+uDZnhUYjDLWNE893MsAQGOhg
 | 
					# BAMwDQYJYIZIAWUDBAIBBQCgga4wGQYJKoZIhvcNAQkDMQwGCisGAQQBgjcCAQQw
 | 
				
			||||||
# fWpSg0S3po5GawcU88V29YZQ3MFEyHFcUTE3oAo4bo3t1w/YJlN8OWECesSq/XJp
 | 
					# HAYKKwYBBAGCNwIBCzEOMAwGCisGAQQBgjcCARUwLwYJKoZIhvcNAQkEMSIEINfL
 | 
				
			||||||
# rx2rrPY2vjUmZNqYO7oaezOtgFt+jBAcnVL+tuhiJdxqD89d9P6OU8/W7IVWTe/d
 | 
					# pWARcSI2v5ypXRaeSwvLuu7hP0XgYbvQaaOIuiKWMEIGCisGAQQBgjcCAQwxNDAy
 | 
				
			||||||
# vI2k45GPsjksUZzpcGkNyjYtcI4xyDUoveO0hyTD4MmPfrVUj9z6BVWYbWg7mka9
 | 
					# oBSAEgBNAGkAYwByAG8AcwBvAGYAdKEagBhodHRwOi8vd3d3Lm1pY3Jvc29mdC5j
 | 
				
			||||||
# 7aSueik3rMvrg0XnRm7KMtXAhjBcTyziYrLNueKNiOSWrAFKu75xqRdbZ2De+JKR
 | 
					# b20wDQYJKoZIhvcNAQEBBQAEggEADr/V9EQlvMcNLQduKLU/gz5PRRSoE8txgN52
 | 
				
			||||||
# Hh09/SDPc31BmkZ1zcRfNN0Sidb9pSB9fvzZnkXftnIv231fgLrbqn427DZM9itu
 | 
					# OuBIJS4+jPp3y82+4/09umeMdQ7+pwRQiuPAvmyZG0zGRoTz3PzpouceetqHnIHn
 | 
				
			||||||
# qBJR6L8FA6PRc6ZNN3SUHDSCD/AQ8rdHGO2n6Jl8P0zbr17C89XYcz1DTsEzOUyO
 | 
					# ij0lT0y4hUQ0DqmZT1AA24GJmoPnM9ab2EcRTfUp7p0t1Fq5ITOEdFvvh6EPkyc/
 | 
				
			||||||
# ArxCaC4Q6oRRRuLRvWoYWmEBc8pnol7XKHYC4jMYctenIPDC+hIK12NvDMk2ZItb
 | 
					# spxmI5bTlE0+anj9PmnLyFYnFtrGlmSywrDpIsjqnE8+ODtTabllcpAhLrZxInqu
 | 
				
			||||||
# oKaDIV1fMHSRlJTYuVD5C4lh8zYGNRiER9vcG9H9stQcxWv2XFJRXRLbJbqvUAV6
 | 
					# bHXIrT3cGjATJsRAg+38R5tYP7i6aI5sS9QGmeXhuvrJeFrOIqC2gxbV7iCJIrkE
 | 
				
			||||||
# bMURHXLvjflSxIUXk8A8FdsaN8cIFRg/eKtFtvUeh17aj54WcmnGrnu3tz5q4i6t
 | 
					# 5OGFIBZQkxLRZxt3VYdGAjBLj+pCY7OEjXpXvkdg47Xo8aQCKqGCF7AwghesBgor
 | 
				
			||||||
# AgMBAAGjggHdMIIB2TASBgkrBgEEAYI3FQEEBQIDAQABMCMGCSsGAQQBgjcVAgQW
 | 
					# BgEEAYI3AwMBMYIXnDCCF5gGCSqGSIb3DQEHAqCCF4kwgheFAgEDMQ8wDQYJYIZI
 | 
				
			||||||
# BBQqp1L+ZMSavoKRPEY1Kc8Q/y8E7jAdBgNVHQ4EFgQUn6cVXQBeYl2D9OXSZacb
 | 
					# AWUDBAIBBQAwggFaBgsqhkiG9w0BCRABBKCCAUkEggFFMIIBQQIBAQYKKwYBBAGE
 | 
				
			||||||
# UzUZ6XIwXAYDVR0gBFUwUzBRBgwrBgEEAYI3TIN9AQEwQTA/BggrBgEFBQcCARYz
 | 
					# WQoDATAxMA0GCWCGSAFlAwQCAQUABCBVg4bCpxEOAWWIN2/4kB21BawVRDfKQ35G
 | 
				
			||||||
# aHR0cDovL3d3dy5taWNyb3NvZnQuY29tL3BraW9wcy9Eb2NzL1JlcG9zaXRvcnku
 | 
					# xRhhaLpK/AIGZ2KxlnK4GBMyMDI0MTIyMzE2NDIwNy43NDJaMASAAgH0oIHZpIHW
 | 
				
			||||||
# aHRtMBMGA1UdJQQMMAoGCCsGAQUFBwMIMBkGCSsGAQQBgjcUAgQMHgoAUwB1AGIA
 | 
					# MIHTMQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMH
 | 
				
			||||||
# QwBBMAsGA1UdDwQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFNX2
 | 
					# UmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMS0wKwYDVQQL
 | 
				
			||||||
# VsuP6KJcYmjRPZSQW9fOmhjEMFYGA1UdHwRPME0wS6BJoEeGRWh0dHA6Ly9jcmwu
 | 
					# EyRNaWNyb3NvZnQgSXJlbGFuZCBPcGVyYXRpb25zIExpbWl0ZWQxJzAlBgNVBAsT
 | 
				
			||||||
# bWljcm9zb2Z0LmNvbS9wa2kvY3JsL3Byb2R1Y3RzL01pY1Jvb0NlckF1dF8yMDEw
 | 
					# Hm5TaGllbGQgVFNTIEVTTjo2QjA1LTA1RTAtRDk0NzElMCMGA1UEAxMcTWljcm9z
 | 
				
			||||||
# LTA2LTIzLmNybDBaBggrBgEFBQcBAQROMEwwSgYIKwYBBQUHMAKGPmh0dHA6Ly93
 | 
					# b2Z0IFRpbWUtU3RhbXAgU2VydmljZaCCEf4wggcoMIIFEKADAgECAhMzAAAB9oMv
 | 
				
			||||||
# d3cubWljcm9zb2Z0LmNvbS9wa2kvY2VydHMvTWljUm9vQ2VyQXV0XzIwMTAtMDYt
 | 
					# JmpUXSLBAAEAAAH2MA0GCSqGSIb3DQEBCwUAMHwxCzAJBgNVBAYTAlVTMRMwEQYD
 | 
				
			||||||
# MjMuY3J0MA0GCSqGSIb3DQEBCwUAA4ICAQCdVX38Kq3hLB9nATEkW+Geckv8qW/q
 | 
					# VQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNy
 | 
				
			||||||
# XBS2Pk5HZHixBpOXPTEztTnXwnE2P9pkbHzQdTltuw8x5MKP+2zRoZQYIu7pZmc6
 | 
					# b3NvZnQgQ29ycG9yYXRpb24xJjAkBgNVBAMTHU1pY3Jvc29mdCBUaW1lLVN0YW1w
 | 
				
			||||||
# U03dmLq2HnjYNi6cqYJWAAOwBb6J6Gngugnue99qb74py27YP0h1AdkY3m2CDPVt
 | 
					# IFBDQSAyMDEwMB4XDTI0MDcyNTE4MzEwNFoXDTI1MTAyMjE4MzEwNFowgdMxCzAJ
 | 
				
			||||||
# I1TkeFN1JFe53Z/zjj3G82jfZfakVqr3lbYoVSfQJL1AoL8ZthISEV09J+BAljis
 | 
					# BgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25k
 | 
				
			||||||
# 9/kpicO8F7BUhUKz/AyeixmJ5/ALaoHCgRlCGVJ1ijbCHcNhcy4sa3tuPywJeBTp
 | 
					# MR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xLTArBgNVBAsTJE1pY3Jv
 | 
				
			||||||
# kbKpW99Jo3QMvOyRgNI95ko+ZjtPu4b6MhrZlvSP9pEB9s7GdP32THJvEKt1MMU0
 | 
					# c29mdCBJcmVsYW5kIE9wZXJhdGlvbnMgTGltaXRlZDEnMCUGA1UECxMeblNoaWVs
 | 
				
			||||||
# sHrYUP4KWN1APMdUbZ1jdEgssU5HLcEUBHG/ZPkkvnNtyo4JvbMBV0lUZNlz138e
 | 
					# ZCBUU1MgRVNOOjZCMDUtMDVFMC1EOTQ3MSUwIwYDVQQDExxNaWNyb3NvZnQgVGlt
 | 
				
			||||||
# W0QBjloZkWsNn6Qo3GcZKCS6OEuabvshVGtqRRFHqfG3rsjoiV5PndLQTHa1V1QJ
 | 
					# ZS1TdGFtcCBTZXJ2aWNlMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA
 | 
				
			||||||
# sWkBRH58oWFsc/4Ku+xBZj1p/cvBQUl+fpO+y/g75LcVv7TOPqUxUYS8vwLBgqJ7
 | 
					# 0UJeLMR/N9WPBZhuKVFF+eWJZ68Wujdj4X6JR05cxO5CepNXo17rVazwWLkm5Aja
 | 
				
			||||||
# Fx0ViY1w/ue10CgaiQuPNtq6TPmb/wrpNPgkNWcr4A245oyZ1uEi6vAnQj0llOZ0
 | 
					# Vh19ZVjDChHzimxsoaXxNu8IDggKwpXvpAAItv4Ux50e9S2uVwfKv57p9JKG+Q7V
 | 
				
			||||||
# dFtq0Z4+7X6gMTN9vMvpe784cETRkPHIqzqKOghif9lwY1NNje6CbaUFEMFxBmoQ
 | 
					# ONShujl1NCMkcgSrPdmd/8zcsmhzcNobLomrCAIORZ8IwhYy4siVQlf1NKhlyAzm
 | 
				
			||||||
# tB1VM1izoXBm8qGCAtQwggI9AgEBMIIBAKGB2KSB1TCB0jELMAkGA1UEBhMCVVMx
 | 
					# kWJD0N+60IiogFBzg3yISsvroOx0x1xSi2PiRIQlTXE74MggZDIDKqH/hb9FT2kK
 | 
				
			||||||
# EzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoT
 | 
					# /nV/aXjuo9LMrrRmn44oYYADe/rO95F+SG3uuuhf+H4IriXr0h9ptA6SwHJPS2Vm
 | 
				
			||||||
# FU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEtMCsGA1UECxMkTWljcm9zb2Z0IElyZWxh
 | 
					# bNWCjQWq5G4YkrcqbPMax7vNXUwu7T65E8fFPd1IuE9RsG4TMAV7XkXBopmPNfvL
 | 
				
			||||||
# bmQgT3BlcmF0aW9ucyBMaW1pdGVkMSYwJAYDVQQLEx1UaGFsZXMgVFNTIEVTTjow
 | 
					# 0hjxg44kpQn384V46o+zdQqy5K9dDlWm/J6vZtp5yA1PyD3w+HbGubS0niEQ1L6w
 | 
				
			||||||
# ODQyLTRCRTYtQzI5QTElMCMGA1UEAxMcTWljcm9zb2Z0IFRpbWUtU3RhbXAgU2Vy
 | 
					# GOrPfzIm0FdOn+xFo48ERl+Fxw/3OvXM5CY1EqnzEznPjzJc7OJwhJVR3VQDHjBc
 | 
				
			||||||
# dmljZaIjCgEBMAcGBSsOAwIaAxUAjhJ+EeySRfn2KCNsjn9cF9AUSTqggYMwgYCk
 | 
					# EFTOvS9E0diNu1eocw+ZCkz4Pu/oQv+gqU+bfxL8e7PFktfRDlM6FyOzjP4zuI25
 | 
				
			||||||
# fjB8MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMH
 | 
					# gD8tO9zJg6g6fRpaZc439mAbkl3zCVzTLDgchv6SxQajJtvvoQaZxQf0tRiPcbr2
 | 
				
			||||||
# UmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSYwJAYDVQQD
 | 
					# HWfMoqqd9uiQ0hTUEhG44FBSTeUPZeEenRCWadCW4G8CAwEAAaOCAUkwggFFMB0G
 | 
				
			||||||
# Ex1NaWNyb3NvZnQgVGltZS1TdGFtcCBQQ0EgMjAxMDANBgkqhkiG9w0BAQUFAAIF
 | 
					# A1UdDgQWBBRIwZsJuOcJfScPWcXZuBA4B89K8jAfBgNVHSMEGDAWgBSfpxVdAF5i
 | 
				
			||||||
# AOfRUdUwIhgPMjAyMzAzMzEyMDM0MjlaGA8yMDIzMDQwMTIwMzQyOVowdDA6Bgor
 | 
					# XYP05dJlpxtTNRnpcjBfBgNVHR8EWDBWMFSgUqBQhk5odHRwOi8vd3d3Lm1pY3Jv
 | 
				
			||||||
# BgEEAYRZCgQBMSwwKjAKAgUA59FR1QIBADAHAgEAAgIKJDAHAgEAAgIRLzAKAgUA
 | 
					# c29mdC5jb20vcGtpb3BzL2NybC9NaWNyb3NvZnQlMjBUaW1lLVN0YW1wJTIwUENB
 | 
				
			||||||
# 59KjVQIBADA2BgorBgEEAYRZCgQCMSgwJjAMBgorBgEEAYRZCgMCoAowCAIBAAID
 | 
					# JTIwMjAxMCgxKS5jcmwwbAYIKwYBBQUHAQEEYDBeMFwGCCsGAQUFBzAChlBodHRw
 | 
				
			||||||
# B6EgoQowCAIBAAIDAYagMA0GCSqGSIb3DQEBBQUAA4GBAJlOESCa/uRR1x6GunE8
 | 
					# Oi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2NlcnRzL01pY3Jvc29mdCUyMFRp
 | 
				
			||||||
# K/WgHWTpSE31EITDOfTMvDcF4ptngCS5aOc4gfzmhNNehWfP6EOrgoSQzJYZ4YCh
 | 
					# bWUtU3RhbXAlMjBQQ0ElMjAyMDEwKDEpLmNydDAMBgNVHRMBAf8EAjAAMBYGA1Ud
 | 
				
			||||||
# fYbHNMk56f18sq8t7y2hgR7KixcEo/4HVzeSdaOclHNc4Gn7kCGpMvpT3Xz9Lzc7
 | 
					# JQEB/wQMMAoGCCsGAQUFBwMIMA4GA1UdDwEB/wQEAwIHgDANBgkqhkiG9w0BAQsF
 | 
				
			||||||
# UKWDZ0zkNKnbS8TZLNueVQwfMYIEDTCCBAkCAQEwgZMwfDELMAkGA1UEBhMCVVMx
 | 
					# AAOCAgEA13kBirH1cHu1WYR1ysj125omGtQ0PaQkEzwGb70xtqSoI+svQihsgdTY
 | 
				
			||||||
# EzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoT
 | 
					# xaPfp2IVFdgjaMaBi81wB8/nu866FfFKKdhdp3wnMZ91PpP4Ooe7Ncf6qICkgSuw
 | 
				
			||||||
# FU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEmMCQGA1UEAxMdTWljcm9zb2Z0IFRpbWUt
 | 
					# gdIdQvqE0h8VQ5QW5sDV4Q0Jnj4f7KHYx4NiM8C4jTw8SQtsuxWiTH2Hikf3QYB7
 | 
				
			||||||
# U3RhbXAgUENBIDIwMTACEzMAAAGybkADf26plJIAAQAAAbIwDQYJYIZIAWUDBAIB
 | 
					# 1a7dB9zgHOkW0hgUEeWO9mh2wWqYS/Q48ASjOqYw/ha54oVOff22WaoH+/Hxd9NT
 | 
				
			||||||
# BQCgggFKMBoGCSqGSIb3DQEJAzENBgsqhkiG9w0BCRABBDAvBgkqhkiG9w0BCQQx
 | 
					# EU/4vlvsRIMWT0jsnNI71jVArT4Q9Bt6VShWzyqraE6SKUoZrEwBpVsI0LMg2X3h
 | 
				
			||||||
# IgQgXhJRuHCXk3arJvifIY3DBe9Ce9EmlP1y6U4XkgL31DkwgfoGCyqGSIb3DQEJ
 | 
					# OLblC1vxM3+wMyOh97aFOs7sFnuemtI2Mfj8qg16BZTJxXlpPurWrG+OBj4BoTDk
 | 
				
			||||||
# EAIvMYHqMIHnMIHkMIG9BCBTeM485+E+t4PEVieUoFKX7PVyLo/nzu+htJPCG04+
 | 
					# C9AxXYB3yEtuwMs7pRWLyxIxw/wV9THKUGm+x+VE0POLwkrSMgjulSXkpfELHWWi
 | 
				
			||||||
# NTCBmDCBgKR+MHwxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAw
 | 
					# CVslJbFIIB/4Alv+jQJSKAJuo9CErbm2qeDk/zjJYlYaVGMyKuYZ+uSRVKB2qkEP
 | 
				
			||||||
# DgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24x
 | 
					# cEzG1dO9zIa1Mp32J+zzW3P7suJfjw62s3hDOLk+6lMQOR04x+2o17G3LceLkkxJ
 | 
				
			||||||
# JjAkBgNVBAMTHU1pY3Jvc29mdCBUaW1lLVN0YW1wIFBDQSAyMDEwAhMzAAABsm5A
 | 
					# m41ErdiTjAmdClen9yl6HgMpGS4okjFCJX+CpOFX7gBA3PVxQWubisAQbL5HgTFB
 | 
				
			||||||
# A39uqZSSAAEAAAGyMCIEIGGWlnNnYHrB5HguWG0/nJd/WvSrCogze+QCpenu3IM5
 | 
					# tQNEzcCdh1GYw/6nzzNNt+0GQnnobBddfOAiqkzvItqXjvGyK1QwggdxMIIFWaAD
 | 
				
			||||||
# MA0GCSqGSIb3DQEBCwUABIICADVOLTuNxeEnBOfZpb7Nv4uf91W/Ho5i99zenDSJ
 | 
					# AgECAhMzAAAAFcXna54Cm0mZAAAAAAAVMA0GCSqGSIb3DQEBCwUAMIGIMQswCQYD
 | 
				
			||||||
# x5QHVs+bKXmgc3a7/SSsliAT3zygHc7cH4zARbCZePLTivByKmeG08Ka35eyR+FK
 | 
					# VQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEe
 | 
				
			||||||
# awSNrI/X+eVIC6nw/egCwviBC1NAG8jHGkuScbHeiiGajvS6lp3ORML7UexMuE4w
 | 
					# MBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTIwMAYDVQQDEylNaWNyb3Nv
 | 
				
			||||||
# 9SEumoghljCLZMwCSvw+3WxhQoBEZroR8u+PID2RdD0vi85FjKPWcZZijVLqHeFi
 | 
					# ZnQgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgMjAxMDAeFw0yMTA5MzAxODIy
 | 
				
			||||||
# TnuFqwRCLTV0MV+dDCbjwXneIqV+AVlnqb9iDMr3ZhISlRcy9XJNpY5vQBj/wqUW
 | 
					# MjVaFw0zMDA5MzAxODMyMjVaMHwxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNo
 | 
				
			||||||
# vefrmpdz0LNkdtXYThPkyl3mha2KsoQi5SA9zSjlAjFgY3ppmXvi3Frbfqk+iL+f
 | 
					# aW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29y
 | 
				
			||||||
# l/Qc4+B71jG4t28lTWKteJiHqo+6AUXK2rlAl0d74yvhO6N8lMMtXhdJc8JABYn1
 | 
					# cG9yYXRpb24xJjAkBgNVBAMTHU1pY3Jvc29mdCBUaW1lLVN0YW1wIFBDQSAyMDEw
 | 
				
			||||||
# v2/KKZn5RvPFF8QP7Ac1saIe1+gUFNcsYOLaMm/xl8E6kefWwZnm5Rhm606g1AC/
 | 
					# MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA5OGmTOe0ciELeaLL1yR5
 | 
				
			||||||
# N5Wo08aAs0ymTPH91dEbmOURXLbA3vCyG7kbfgnhCs/j7oQHWaFDzEYuXDIA4ICT
 | 
					# vQ7VgtP97pwHB9KpbE51yMo1V/YBf2xK4OK9uT4XYDP/XE/HZveVU3Fa4n5KWv64
 | 
				
			||||||
# dxPUTltbq3OWdp0PAS8JSEKPQFaOoQEnPa4adrXWxMvOmel8IGqJiQ+BPOaLQG64
 | 
					# NmeFRiMMtY0Tz3cywBAY6GB9alKDRLemjkZrBxTzxXb1hlDcwUTIcVxRMTegCjhu
 | 
				
			||||||
# Qu2tMkH/5szb1fsEnCe8SJmy5ESF+kmpnLBtJ17Y9o+9nJHF5ddFmvzy+LUaIqDN
 | 
					# je3XD9gmU3w5YQJ6xKr9cmmvHaus9ja+NSZk2pg7uhp7M62AW36MEBydUv626GIl
 | 
				
			||||||
# cOfH
 | 
					# 3GoPz130/o5Tz9bshVZN7928jaTjkY+yOSxRnOlwaQ3KNi1wjjHINSi947SHJMPg
 | 
				
			||||||
 | 
					# yY9+tVSP3PoFVZhtaDuaRr3tpK56KTesy+uDRedGbsoy1cCGMFxPLOJiss254o2I
 | 
				
			||||||
 | 
					# 5JasAUq7vnGpF1tnYN74kpEeHT39IM9zfUGaRnXNxF803RKJ1v2lIH1+/NmeRd+2
 | 
				
			||||||
 | 
					# ci/bfV+AutuqfjbsNkz2K26oElHovwUDo9Fzpk03dJQcNIIP8BDyt0cY7afomXw/
 | 
				
			||||||
 | 
					# TNuvXsLz1dhzPUNOwTM5TI4CvEJoLhDqhFFG4tG9ahhaYQFzymeiXtcodgLiMxhy
 | 
				
			||||||
 | 
					# 16cg8ML6EgrXY28MyTZki1ugpoMhXV8wdJGUlNi5UPkLiWHzNgY1GIRH29wb0f2y
 | 
				
			||||||
 | 
					# 1BzFa/ZcUlFdEtsluq9QBXpsxREdcu+N+VLEhReTwDwV2xo3xwgVGD94q0W29R6H
 | 
				
			||||||
 | 
					# XtqPnhZyacaue7e3PmriLq0CAwEAAaOCAd0wggHZMBIGCSsGAQQBgjcVAQQFAgMB
 | 
				
			||||||
 | 
					# AAEwIwYJKwYBBAGCNxUCBBYEFCqnUv5kxJq+gpE8RjUpzxD/LwTuMB0GA1UdDgQW
 | 
				
			||||||
 | 
					# BBSfpxVdAF5iXYP05dJlpxtTNRnpcjBcBgNVHSAEVTBTMFEGDCsGAQQBgjdMg30B
 | 
				
			||||||
 | 
					# ATBBMD8GCCsGAQUFBwIBFjNodHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpb3Bz
 | 
				
			||||||
 | 
					# L0RvY3MvUmVwb3NpdG9yeS5odG0wEwYDVR0lBAwwCgYIKwYBBQUHAwgwGQYJKwYB
 | 
				
			||||||
 | 
					# BAGCNxQCBAweCgBTAHUAYgBDAEEwCwYDVR0PBAQDAgGGMA8GA1UdEwEB/wQFMAMB
 | 
				
			||||||
 | 
					# Af8wHwYDVR0jBBgwFoAU1fZWy4/oolxiaNE9lJBb186aGMQwVgYDVR0fBE8wTTBL
 | 
				
			||||||
 | 
					# oEmgR4ZFaHR0cDovL2NybC5taWNyb3NvZnQuY29tL3BraS9jcmwvcHJvZHVjdHMv
 | 
				
			||||||
 | 
					# TWljUm9vQ2VyQXV0XzIwMTAtMDYtMjMuY3JsMFoGCCsGAQUFBwEBBE4wTDBKBggr
 | 
				
			||||||
 | 
					# BgEFBQcwAoY+aHR0cDovL3d3dy5taWNyb3NvZnQuY29tL3BraS9jZXJ0cy9NaWNS
 | 
				
			||||||
 | 
					# b29DZXJBdXRfMjAxMC0wNi0yMy5jcnQwDQYJKoZIhvcNAQELBQADggIBAJ1Vffwq
 | 
				
			||||||
 | 
					# reEsH2cBMSRb4Z5yS/ypb+pcFLY+TkdkeLEGk5c9MTO1OdfCcTY/2mRsfNB1OW27
 | 
				
			||||||
 | 
					# DzHkwo/7bNGhlBgi7ulmZzpTTd2YurYeeNg2LpypglYAA7AFvonoaeC6Ce5732pv
 | 
				
			||||||
 | 
					# vinLbtg/SHUB2RjebYIM9W0jVOR4U3UkV7ndn/OOPcbzaN9l9qRWqveVtihVJ9Ak
 | 
				
			||||||
 | 
					# vUCgvxm2EhIRXT0n4ECWOKz3+SmJw7wXsFSFQrP8DJ6LGYnn8AtqgcKBGUIZUnWK
 | 
				
			||||||
 | 
					# NsIdw2FzLixre24/LAl4FOmRsqlb30mjdAy87JGA0j3mSj5mO0+7hvoyGtmW9I/2
 | 
				
			||||||
 | 
					# kQH2zsZ0/fZMcm8Qq3UwxTSwethQ/gpY3UA8x1RtnWN0SCyxTkctwRQEcb9k+SS+
 | 
				
			||||||
 | 
					# c23Kjgm9swFXSVRk2XPXfx5bRAGOWhmRaw2fpCjcZxkoJLo4S5pu+yFUa2pFEUep
 | 
				
			||||||
 | 
					# 8beuyOiJXk+d0tBMdrVXVAmxaQFEfnyhYWxz/gq77EFmPWn9y8FBSX5+k77L+Dvk
 | 
				
			||||||
 | 
					# txW/tM4+pTFRhLy/AsGConsXHRWJjXD+57XQKBqJC4822rpM+Zv/Cuk0+CQ1Zyvg
 | 
				
			||||||
 | 
					# DbjmjJnW4SLq8CdCPSWU5nR0W2rRnj7tfqAxM328y+l7vzhwRNGQ8cirOoo6CGJ/
 | 
				
			||||||
 | 
					# 2XBjU02N7oJtpQUQwXEGahC0HVUzWLOhcGbyoYIDWTCCAkECAQEwggEBoYHZpIHW
 | 
				
			||||||
 | 
					# MIHTMQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMH
 | 
				
			||||||
 | 
					# UmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMS0wKwYDVQQL
 | 
				
			||||||
 | 
					# EyRNaWNyb3NvZnQgSXJlbGFuZCBPcGVyYXRpb25zIExpbWl0ZWQxJzAlBgNVBAsT
 | 
				
			||||||
 | 
					# Hm5TaGllbGQgVFNTIEVTTjo2QjA1LTA1RTAtRDk0NzElMCMGA1UEAxMcTWljcm9z
 | 
				
			||||||
 | 
					# b2Z0IFRpbWUtU3RhbXAgU2VydmljZaIjCgEBMAcGBSsOAwIaAxUAFU9eSpdxs0a0
 | 
				
			||||||
 | 
					# 6JFIuGFHIj/I+36ggYMwgYCkfjB8MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2Fz
 | 
				
			||||||
 | 
					# aGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENv
 | 
				
			||||||
 | 
					# cnBvcmF0aW9uMSYwJAYDVQQDEx1NaWNyb3NvZnQgVGltZS1TdGFtcCBQQ0EgMjAx
 | 
				
			||||||
 | 
					# MDANBgkqhkiG9w0BAQsFAAIFAOsTx1MwIhgPMjAyNDEyMjMxMTI2MTFaGA8yMDI0
 | 
				
			||||||
 | 
					# MTIyNDExMjYxMVowdzA9BgorBgEEAYRZCgQBMS8wLTAKAgUA6xPHUwIBADAKAgEA
 | 
				
			||||||
 | 
					# AgIEpgIB/zAHAgEAAgIULjAKAgUA6xUY0wIBADA2BgorBgEEAYRZCgQCMSgwJjAM
 | 
				
			||||||
 | 
					# BgorBgEEAYRZCgMCoAowCAIBAAIDB6EgoQowCAIBAAIDAYagMA0GCSqGSIb3DQEB
 | 
				
			||||||
 | 
					# CwUAA4IBAQDkPou5w9O3fL9lm7NIu3mAwCMpezmpCbx9mCUfLb4cXznb4psGEspn
 | 
				
			||||||
 | 
					# XaDg3PGX1yGC3GR5peByH/hiarlvYv5SZbofvP+iiYFxeLGi+usbC8FQnuWrgyqh
 | 
				
			||||||
 | 
					# 7RV01Fm2Is7PGF3NXQaXbGkSQUZzrekeRr4zdV2nIKshANlifSPb/wAd6BLcKtYS
 | 
				
			||||||
 | 
					# 3Kr9xUXgZeHxo6tD88GDxJ5FDsG1RxczsdCO5mVqFZUrQqz6Cs49xt7cq2XlEwMX
 | 
				
			||||||
 | 
					# 53L40YCUrvYYiTgqvxtOzg58ksUkP1YDfeP9Rel7pGXGyzJF0Fo+FAXiY098HPcW
 | 
				
			||||||
 | 
					# eRCGaVV55Keop55er/x0vYOQK3WYmR9ZMYIEDTCCBAkCAQEwgZMwfDELMAkGA1UE
 | 
				
			||||||
 | 
					# BhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAc
 | 
				
			||||||
 | 
					# BgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEmMCQGA1UEAxMdTWljcm9zb2Z0
 | 
				
			||||||
 | 
					# IFRpbWUtU3RhbXAgUENBIDIwMTACEzMAAAH2gy8malRdIsEAAQAAAfYwDQYJYIZI
 | 
				
			||||||
 | 
					# AWUDBAIBBQCgggFKMBoGCSqGSIb3DQEJAzENBgsqhkiG9w0BCRABBDAvBgkqhkiG
 | 
				
			||||||
 | 
					# 9w0BCQQxIgQgrAY6roZynzJwSUQzsAfof3O6FxHR94SlM3Hdh+QLWTowgfoGCyqG
 | 
				
			||||||
 | 
					# SIb3DQEJEAIvMYHqMIHnMIHkMIG9BCArYUzxlF6m5USLS4f8NXL/8aoNEVdsCZRm
 | 
				
			||||||
 | 
					# F+LlQjG2ojCBmDCBgKR+MHwxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5n
 | 
				
			||||||
 | 
					# dG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9y
 | 
				
			||||||
 | 
					# YXRpb24xJjAkBgNVBAMTHU1pY3Jvc29mdCBUaW1lLVN0YW1wIFBDQSAyMDEwAhMz
 | 
				
			||||||
 | 
					# AAAB9oMvJmpUXSLBAAEAAAH2MCIEIOEmAHxbUTtc2fET28qfaLGRzaIhD4dw4/ak
 | 
				
			||||||
 | 
					# m6mLo6PCMA0GCSqGSIb3DQEBCwUABIICAH4zqNf+CV7yNKXAQwNuEZwzCHs4eJC4
 | 
				
			||||||
 | 
					# mNKMRp9e2W++JJaxtY3kLEBoGDKfz+8RYsjcLtNOg83Hd2gEmAmgvWfs/mZlhi8j
 | 
				
			||||||
 | 
					# tM5Yj9606ukzuF2797CDwZiXz5JTIs1wIm5+rWuAny0azioafaOZtcaxPqnANbUf
 | 
				
			||||||
 | 
					# UHnAYoZ0W6AkSnz99XrqRueh8b3Z7h2A5saVS1/MV1fjfImxH673GlexKRYORTFP
 | 
				
			||||||
 | 
					# A9XH8vCvVTIZobKSWa6y/KG4U5dkWrzJuLbT9Kr3x6yk0bO6epG09yy86HmlnmwQ
 | 
				
			||||||
 | 
					# bJwBedz4ZpKkvtIJ2U2PYvLti5bztm5WL/hWhDmtXBhoqKy1d/i4LDz7F4vXy9//
 | 
				
			||||||
 | 
					# 5Wy8zHMLw4ZFwfywP8/P5pZP7nlvIrordtefS2z3Ipea0thJxwyFJSU8c7OGvPof
 | 
				
			||||||
 | 
					# uHhYKMn+Lg1tj5QcIvT7KG0JGp/XWe/CEB9ruOkYZh9VKBlEU2CkDsWeTXFy5heV
 | 
				
			||||||
 | 
					# eMPMxRC/GBHPypBHHSrd8BtUsKgehcetdsfQrOI3VLV9gx8SGr8ehSU2Rg0U2UtK
 | 
				
			||||||
 | 
					# a4S5THXp0PksrjJLmykIsvBmMgl3uK4KJbu6zh3w5ACSS/OZXzrsowysGjn2QBwb
 | 
				
			||||||
 | 
					# hoIjCDhmNLLq2gupcAhPCgqUX6Ixmg8H0SlqoRp0mZTss7ZS+ErxTQoFBbLkoX5F
 | 
				
			||||||
 | 
					# 9HjkIOcM6/0F
 | 
				
			||||||
# SIG # End signature block
 | 
					# SIG # End signature block
 | 
				
			||||||
							
								
								
									
										267
									
								
								externals/install-dotnet.sh
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										267
									
								
								externals/install-dotnet.sh
									
									
									
									
										vendored
									
									
								
							@ -298,11 +298,20 @@ get_machine_architecture() {
 | 
				
			|||||||
    if command -v uname > /dev/null; then
 | 
					    if command -v uname > /dev/null; then
 | 
				
			||||||
        CPUName=$(uname -m)
 | 
					        CPUName=$(uname -m)
 | 
				
			||||||
        case $CPUName in
 | 
					        case $CPUName in
 | 
				
			||||||
 | 
					        armv1*|armv2*|armv3*|armv4*|armv5*|armv6*)
 | 
				
			||||||
 | 
					            echo "armv6-or-below"
 | 
				
			||||||
 | 
					            return 0
 | 
				
			||||||
 | 
					            ;;
 | 
				
			||||||
        armv*l)
 | 
					        armv*l)
 | 
				
			||||||
            echo "arm"
 | 
					            echo "arm"
 | 
				
			||||||
            return 0
 | 
					            return 0
 | 
				
			||||||
            ;;
 | 
					            ;;
 | 
				
			||||||
        aarch64|arm64)
 | 
					        aarch64|arm64)
 | 
				
			||||||
 | 
					            if [ "$(getconf LONG_BIT)" -lt 64 ]; then
 | 
				
			||||||
 | 
					                # This is 32-bit OS running on 64-bit CPU (for example Raspberry Pi OS)
 | 
				
			||||||
 | 
					                echo "arm"
 | 
				
			||||||
 | 
					                return 0
 | 
				
			||||||
 | 
					            fi
 | 
				
			||||||
            echo "arm64"
 | 
					            echo "arm64"
 | 
				
			||||||
            return 0
 | 
					            return 0
 | 
				
			||||||
            ;;
 | 
					            ;;
 | 
				
			||||||
@ -310,6 +319,22 @@ get_machine_architecture() {
 | 
				
			|||||||
            echo "s390x"
 | 
					            echo "s390x"
 | 
				
			||||||
            return 0
 | 
					            return 0
 | 
				
			||||||
            ;;
 | 
					            ;;
 | 
				
			||||||
 | 
					        ppc64le)
 | 
				
			||||||
 | 
					            echo "ppc64le"
 | 
				
			||||||
 | 
					            return 0
 | 
				
			||||||
 | 
					            ;;
 | 
				
			||||||
 | 
					        loongarch64)
 | 
				
			||||||
 | 
					            echo "loongarch64"
 | 
				
			||||||
 | 
					            return 0
 | 
				
			||||||
 | 
					            ;;
 | 
				
			||||||
 | 
					        riscv64)
 | 
				
			||||||
 | 
					            echo "riscv64"
 | 
				
			||||||
 | 
					            return 0
 | 
				
			||||||
 | 
					            ;;
 | 
				
			||||||
 | 
					        powerpc|ppc)
 | 
				
			||||||
 | 
					            echo "ppc"
 | 
				
			||||||
 | 
					            return 0
 | 
				
			||||||
 | 
					            ;;
 | 
				
			||||||
        esac
 | 
					        esac
 | 
				
			||||||
    fi
 | 
					    fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -326,7 +351,13 @@ get_normalized_architecture_from_architecture() {
 | 
				
			|||||||
    local architecture="$(to_lowercase "$1")"
 | 
					    local architecture="$(to_lowercase "$1")"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if [[ $architecture == \<auto\> ]]; then
 | 
					    if [[ $architecture == \<auto\> ]]; then
 | 
				
			||||||
        echo "$(get_machine_architecture)"
 | 
					        machine_architecture="$(get_machine_architecture)"
 | 
				
			||||||
 | 
					        if [[ "$machine_architecture" == "armv6-or-below" ]]; then
 | 
				
			||||||
 | 
					            say_err "Architecture \`$machine_architecture\` not supported. If you think this is a bug, report it at https://github.com/dotnet/install-scripts/issues"
 | 
				
			||||||
 | 
					            return 1
 | 
				
			||||||
 | 
					        fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        echo $machine_architecture
 | 
				
			||||||
        return 0
 | 
					        return 0
 | 
				
			||||||
    fi
 | 
					    fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -347,6 +378,14 @@ get_normalized_architecture_from_architecture() {
 | 
				
			|||||||
            echo "s390x"
 | 
					            echo "s390x"
 | 
				
			||||||
            return 0
 | 
					            return 0
 | 
				
			||||||
            ;;
 | 
					            ;;
 | 
				
			||||||
 | 
					        ppc64le)
 | 
				
			||||||
 | 
					            echo "ppc64le"
 | 
				
			||||||
 | 
					            return 0
 | 
				
			||||||
 | 
					            ;;
 | 
				
			||||||
 | 
					        loongarch64)
 | 
				
			||||||
 | 
					            echo "loongarch64"
 | 
				
			||||||
 | 
					            return 0
 | 
				
			||||||
 | 
					            ;;
 | 
				
			||||||
    esac
 | 
					    esac
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    say_err "Architecture \`$architecture\` not supported. If you think this is a bug, report it at https://github.com/dotnet/install-scripts/issues"
 | 
					    say_err "Architecture \`$architecture\` not supported. If you think this is a bug, report it at https://github.com/dotnet/install-scripts/issues"
 | 
				
			||||||
@ -384,11 +423,17 @@ get_normalized_architecture_for_specific_sdk_version() {
 | 
				
			|||||||
# args:
 | 
					# args:
 | 
				
			||||||
# version or channel - $1
 | 
					# version or channel - $1
 | 
				
			||||||
is_arm64_supported() {
 | 
					is_arm64_supported() {
 | 
				
			||||||
    #any channel or version that starts with the specified versions
 | 
					    # Extract the major version by splitting on the dot
 | 
				
			||||||
    case "$1" in
 | 
					    major_version="${1%%.*}"
 | 
				
			||||||
        ( "1"* | "2"* | "3"*  | "4"* | "5"*) 
 | 
					
 | 
				
			||||||
 | 
					    # Check if the major version is a valid number and less than 6
 | 
				
			||||||
 | 
					    case "$major_version" in
 | 
				
			||||||
 | 
					        [0-9]*)  
 | 
				
			||||||
 | 
					            if [ "$major_version" -lt 6 ]; then
 | 
				
			||||||
                echo false
 | 
					                echo false
 | 
				
			||||||
                return 0
 | 
					                return 0
 | 
				
			||||||
 | 
					            fi
 | 
				
			||||||
 | 
					            ;;
 | 
				
			||||||
    esac
 | 
					    esac
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    echo true
 | 
					    echo true
 | 
				
			||||||
@ -407,8 +452,13 @@ get_normalized_os() {
 | 
				
			|||||||
                echo "$osname"
 | 
					                echo "$osname"
 | 
				
			||||||
                return 0
 | 
					                return 0
 | 
				
			||||||
                ;;
 | 
					                ;;
 | 
				
			||||||
 | 
					            macos)
 | 
				
			||||||
 | 
					                osname='osx'
 | 
				
			||||||
 | 
					                echo "$osname"
 | 
				
			||||||
 | 
					                return 0
 | 
				
			||||||
 | 
					                ;;
 | 
				
			||||||
            *)
 | 
					            *)
 | 
				
			||||||
                say_err "'$user_defined_os' is not a supported value for --os option, supported values are: osx, linux, linux-musl, freebsd, rhel.6. If you think this is a bug, report it at https://github.com/dotnet/install-scripts/issues."
 | 
					                say_err "'$user_defined_os' is not a supported value for --os option, supported values are: osx, macos, linux, linux-musl, freebsd, rhel.6. If you think this is a bug, report it at https://github.com/dotnet/install-scripts/issues."
 | 
				
			||||||
                return 1
 | 
					                return 1
 | 
				
			||||||
                ;;
 | 
					                ;;
 | 
				
			||||||
        esac
 | 
					        esac
 | 
				
			||||||
@ -538,6 +588,40 @@ is_dotnet_package_installed() {
 | 
				
			|||||||
    fi
 | 
					    fi
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# args:
 | 
				
			||||||
 | 
					# downloaded file - $1
 | 
				
			||||||
 | 
					# remote_file_size - $2
 | 
				
			||||||
 | 
					validate_remote_local_file_sizes() 
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    eval $invocation
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    local downloaded_file="$1"
 | 
				
			||||||
 | 
					    local remote_file_size="$2"
 | 
				
			||||||
 | 
					    local file_size=''
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if [[ "$OSTYPE" == "linux-gnu"* ]]; then
 | 
				
			||||||
 | 
					        file_size="$(stat -c '%s' "$downloaded_file")"
 | 
				
			||||||
 | 
					    elif [[ "$OSTYPE" == "darwin"* ]]; then
 | 
				
			||||||
 | 
					        # hardcode in order to avoid conflicts with GNU stat
 | 
				
			||||||
 | 
					        file_size="$(/usr/bin/stat -f '%z' "$downloaded_file")"
 | 
				
			||||||
 | 
					    fi  
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    if [ -n "$file_size" ]; then
 | 
				
			||||||
 | 
					        say "Downloaded file size is $file_size bytes."
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if [ -n "$remote_file_size" ] && [ -n "$file_size" ]; then
 | 
				
			||||||
 | 
					            if [ "$remote_file_size" -ne "$file_size" ]; then
 | 
				
			||||||
 | 
					                say "The remote and local file sizes are not equal. The remote file size is $remote_file_size bytes and the local size is $file_size bytes. The local package may be corrupted."
 | 
				
			||||||
 | 
					            else
 | 
				
			||||||
 | 
					                say "The remote and local file sizes are equal."
 | 
				
			||||||
 | 
					            fi
 | 
				
			||||||
 | 
					        fi
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					        say "Either downloaded or local package size can not be measured. One of them may be corrupted."      
 | 
				
			||||||
 | 
					    fi 
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# args:
 | 
					# args:
 | 
				
			||||||
# azure_feed - $1
 | 
					# azure_feed - $1
 | 
				
			||||||
# channel - $2
 | 
					# channel - $2
 | 
				
			||||||
@ -872,6 +956,37 @@ get_absolute_path() {
 | 
				
			|||||||
    return 0
 | 
					    return 0
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# args:
 | 
				
			||||||
 | 
					# override - $1 (boolean, true or false)
 | 
				
			||||||
 | 
					get_cp_options() {
 | 
				
			||||||
 | 
					    eval $invocation
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    local override="$1"
 | 
				
			||||||
 | 
					    local override_switch=""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if [ "$override" = false ]; then
 | 
				
			||||||
 | 
					        override_switch="-n"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # create temporary files to check if 'cp -u' is supported
 | 
				
			||||||
 | 
					        tmp_dir="$(mktemp -d)"
 | 
				
			||||||
 | 
					        tmp_file="$tmp_dir/testfile"
 | 
				
			||||||
 | 
					        tmp_file2="$tmp_dir/testfile2"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        touch "$tmp_file"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # use -u instead of -n if it's available
 | 
				
			||||||
 | 
					        if cp -u "$tmp_file" "$tmp_file2" 2>/dev/null; then
 | 
				
			||||||
 | 
					            override_switch="-u"
 | 
				
			||||||
 | 
					        fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # clean up
 | 
				
			||||||
 | 
					        rm -f "$tmp_file" "$tmp_file2"
 | 
				
			||||||
 | 
					        rm -rf "$tmp_dir"
 | 
				
			||||||
 | 
					    fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    echo "$override_switch"
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# args:
 | 
					# args:
 | 
				
			||||||
# input_files - stdin
 | 
					# input_files - stdin
 | 
				
			||||||
# root_path - $1
 | 
					# root_path - $1
 | 
				
			||||||
@ -883,15 +998,7 @@ copy_files_or_dirs_from_list() {
 | 
				
			|||||||
    local root_path="$(remove_trailing_slash "$1")"
 | 
					    local root_path="$(remove_trailing_slash "$1")"
 | 
				
			||||||
    local out_path="$(remove_trailing_slash "$2")"
 | 
					    local out_path="$(remove_trailing_slash "$2")"
 | 
				
			||||||
    local override="$3"
 | 
					    local override="$3"
 | 
				
			||||||
    local osname="$(get_current_os_name)"
 | 
					    local override_switch="$(get_cp_options "$override")"
 | 
				
			||||||
    local override_switch=$(
 | 
					 | 
				
			||||||
        if [ "$override" = false ]; then
 | 
					 | 
				
			||||||
            if [ "$osname" = "linux-musl" ]; then
 | 
					 | 
				
			||||||
                printf -- "-u";
 | 
					 | 
				
			||||||
            else
 | 
					 | 
				
			||||||
                printf -- "-n";
 | 
					 | 
				
			||||||
            fi
 | 
					 | 
				
			||||||
        fi)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    cat | uniq | while read -r file_path; do
 | 
					    cat | uniq | while read -r file_path; do
 | 
				
			||||||
        local path="$(remove_beginning_slash "${file_path#$root_path}")"
 | 
					        local path="$(remove_beginning_slash "${file_path#$root_path}")"
 | 
				
			||||||
@ -906,14 +1013,39 @@ copy_files_or_dirs_from_list() {
 | 
				
			|||||||
    done
 | 
					    done
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# args:
 | 
				
			||||||
 | 
					# zip_uri - $1
 | 
				
			||||||
 | 
					get_remote_file_size() {
 | 
				
			||||||
 | 
					    local zip_uri="$1"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if machine_has "curl"; then
 | 
				
			||||||
 | 
					        file_size=$(curl -sI  "$zip_uri" | grep -i content-length | awk '{ num = $2 + 0; print num }')
 | 
				
			||||||
 | 
					    elif machine_has "wget"; then
 | 
				
			||||||
 | 
					        file_size=$(wget --spider --server-response -O /dev/null "$zip_uri" 2>&1 | grep -i 'Content-Length:' | awk '{ num = $2 + 0; print num }')
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					        say "Neither curl nor wget is available on this system."
 | 
				
			||||||
 | 
					        return
 | 
				
			||||||
 | 
					    fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if [ -n "$file_size" ]; then
 | 
				
			||||||
 | 
					        say "Remote file $zip_uri size is $file_size bytes."
 | 
				
			||||||
 | 
					        echo "$file_size"
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					        say_verbose "Content-Length header was not extracted for $zip_uri."
 | 
				
			||||||
 | 
					        echo ""
 | 
				
			||||||
 | 
					    fi
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# args:
 | 
					# args:
 | 
				
			||||||
# zip_path - $1
 | 
					# zip_path - $1
 | 
				
			||||||
# out_path - $2
 | 
					# out_path - $2
 | 
				
			||||||
 | 
					# remote_file_size - $3
 | 
				
			||||||
extract_dotnet_package() {
 | 
					extract_dotnet_package() {
 | 
				
			||||||
    eval $invocation
 | 
					    eval $invocation
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    local zip_path="$1"
 | 
					    local zip_path="$1"
 | 
				
			||||||
    local out_path="$2"
 | 
					    local out_path="$2"
 | 
				
			||||||
 | 
					    local remote_file_size="$3"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    local temp_out_path="$(mktemp -d "$temporary_file_template")"
 | 
					    local temp_out_path="$(mktemp -d "$temporary_file_template")"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -924,8 +1056,12 @@ extract_dotnet_package() {
 | 
				
			|||||||
    find "$temp_out_path" -type f | grep -Eo "$folders_with_version_regex" | sort | copy_files_or_dirs_from_list "$temp_out_path" "$out_path" false
 | 
					    find "$temp_out_path" -type f | grep -Eo "$folders_with_version_regex" | sort | copy_files_or_dirs_from_list "$temp_out_path" "$out_path" false
 | 
				
			||||||
    find "$temp_out_path" -type f | grep -Ev "$folders_with_version_regex" | copy_files_or_dirs_from_list "$temp_out_path" "$out_path" "$override_non_versioned_files"
 | 
					    find "$temp_out_path" -type f | grep -Ev "$folders_with_version_regex" | copy_files_or_dirs_from_list "$temp_out_path" "$out_path" "$override_non_versioned_files"
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
 | 
					    validate_remote_local_file_sizes "$zip_path" "$remote_file_size"
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
    rm -rf "$temp_out_path"
 | 
					    rm -rf "$temp_out_path"
 | 
				
			||||||
    rm -f "$zip_path" && say_verbose "Temporary zip file $zip_path was removed"
 | 
					    if [ -z ${keep_zip+x} ]; then
 | 
				
			||||||
 | 
					        rm -f "$zip_path" && say_verbose "Temporary archive file $zip_path was removed"
 | 
				
			||||||
 | 
					    fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if [ "$failed" = true ]; then
 | 
					    if [ "$failed" = true ]; then
 | 
				
			||||||
        say_err "Extraction failed"
 | 
					        say_err "Extraction failed"
 | 
				
			||||||
@ -1136,6 +1272,61 @@ downloadwget() {
 | 
				
			|||||||
    return 0
 | 
					    return 0
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					extract_stem() {
 | 
				
			||||||
 | 
					    local url="$1"
 | 
				
			||||||
 | 
					    # extract the protocol
 | 
				
			||||||
 | 
					    proto="$(echo $1 | grep :// | sed -e's,^\(.*://\).*,\1,g')"
 | 
				
			||||||
 | 
					    # remove the protocol
 | 
				
			||||||
 | 
					    url="${1/$proto/}"
 | 
				
			||||||
 | 
					    # extract the path (if any) - since we know all of our feeds have a first path segment, we can skip the first one. otherwise we'd use -f2- to get the full path
 | 
				
			||||||
 | 
					    full_path="$(echo $url | grep / | cut -d/ -f2-)"
 | 
				
			||||||
 | 
					    path="$(echo $full_path | cut -d/ -f2-)"
 | 
				
			||||||
 | 
					    echo $path
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					check_url_exists() {
 | 
				
			||||||
 | 
					    eval $invocation
 | 
				
			||||||
 | 
					    local url="$1"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    local code=""
 | 
				
			||||||
 | 
					    if machine_has "curl"
 | 
				
			||||||
 | 
					    then
 | 
				
			||||||
 | 
					        code=$(curl --head -o /dev/null -w "%{http_code}" -s --fail "$url");
 | 
				
			||||||
 | 
					    elif machine_has "wget"
 | 
				
			||||||
 | 
					    then
 | 
				
			||||||
 | 
					        # get the http response, grab the status code
 | 
				
			||||||
 | 
					        server_response=$(wget -qO- --method=HEAD --server-response "$url" 2>&1)
 | 
				
			||||||
 | 
					        code=$(echo "$server_response" | grep "HTTP/" | awk '{print $2}')
 | 
				
			||||||
 | 
					    fi
 | 
				
			||||||
 | 
					    if [ $code = "200" ]; then
 | 
				
			||||||
 | 
					        return 0
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					        return 1
 | 
				
			||||||
 | 
					    fi
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					sanitize_redirect_url() {
 | 
				
			||||||
 | 
					    eval $invocation
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    local url_stem
 | 
				
			||||||
 | 
					    url_stem=$(extract_stem "$1")
 | 
				
			||||||
 | 
					    say_verbose "Checking configured feeds for the asset at ${yellow:-}$url_stem${normal:-}"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for feed in "${feeds[@]}"
 | 
				
			||||||
 | 
					    do
 | 
				
			||||||
 | 
					        local trial_url="$feed/$url_stem"
 | 
				
			||||||
 | 
					        say_verbose "Checking ${yellow:-}$trial_url${normal:-}"
 | 
				
			||||||
 | 
					        if check_url_exists "$trial_url"; then
 | 
				
			||||||
 | 
					            say_verbose "Found a match at ${yellow:-}$trial_url${normal:-}"
 | 
				
			||||||
 | 
					            echo "$trial_url"
 | 
				
			||||||
 | 
					            return 0
 | 
				
			||||||
 | 
					        else
 | 
				
			||||||
 | 
					            say_verbose "No match at ${yellow:-}$trial_url${normal:-}"
 | 
				
			||||||
 | 
					        fi
 | 
				
			||||||
 | 
					    done
 | 
				
			||||||
 | 
					    return 1
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
get_download_link_from_aka_ms() {
 | 
					get_download_link_from_aka_ms() {
 | 
				
			||||||
    eval $invocation
 | 
					    eval $invocation
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -1172,6 +1363,12 @@ get_download_link_from_aka_ms() {
 | 
				
			|||||||
    http_codes=$( echo "$response" | awk '$1 ~ /^HTTP/ {print $2}' )
 | 
					    http_codes=$( echo "$response" | awk '$1 ~ /^HTTP/ {print $2}' )
 | 
				
			||||||
    # They all need to be 301, otherwise some links are broken (except for the last, which is not a redirect but 200 or 404).
 | 
					    # They all need to be 301, otherwise some links are broken (except for the last, which is not a redirect but 200 or 404).
 | 
				
			||||||
    broken_redirects=$( echo "$http_codes" | sed '$d' | grep -v '301' )
 | 
					    broken_redirects=$( echo "$http_codes" | sed '$d' | grep -v '301' )
 | 
				
			||||||
 | 
					    # The response may end without final code 2xx/4xx/5xx somehow, e.g. network restrictions on www.bing.com causes redirecting to bing.com fails with connection refused.
 | 
				
			||||||
 | 
					    # In this case it should not exclude the last.
 | 
				
			||||||
 | 
					    last_http_code=$(  echo "$http_codes" | tail -n 1 )
 | 
				
			||||||
 | 
					    if ! [[ $last_http_code =~ ^(2|4|5)[0-9][0-9]$ ]]; then
 | 
				
			||||||
 | 
					        broken_redirects=$( echo "$http_codes" | grep -v '301' )
 | 
				
			||||||
 | 
					    fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # All HTTP codes are 301 (Moved Permanently), the redirect link exists.
 | 
					    # All HTTP codes are 301 (Moved Permanently), the redirect link exists.
 | 
				
			||||||
    if [[ -z "$broken_redirects" ]]; then
 | 
					    if [[ -z "$broken_redirects" ]]; then
 | 
				
			||||||
@ -1182,6 +1379,11 @@ get_download_link_from_aka_ms() {
 | 
				
			|||||||
            return 1
 | 
					            return 1
 | 
				
			||||||
        fi
 | 
					        fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        sanitized_redirect_url=$(sanitize_redirect_url "$aka_ms_download_link")
 | 
				
			||||||
 | 
					        if [[ -n "$sanitized_redirect_url" ]]; then
 | 
				
			||||||
 | 
					            aka_ms_download_link="$sanitized_redirect_url"
 | 
				
			||||||
 | 
					        fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        say_verbose "The redirect location retrieved: '$aka_ms_download_link'."
 | 
					        say_verbose "The redirect location retrieved: '$aka_ms_download_link'."
 | 
				
			||||||
        return 0
 | 
					        return 0
 | 
				
			||||||
    else
 | 
					    else
 | 
				
			||||||
@ -1193,7 +1395,9 @@ get_download_link_from_aka_ms() {
 | 
				
			|||||||
get_feeds_to_use()
 | 
					get_feeds_to_use()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    feeds=(
 | 
					    feeds=(
 | 
				
			||||||
 | 
					    "https://builds.dotnet.microsoft.com/dotnet"
 | 
				
			||||||
    "https://dotnetcli.azureedge.net/dotnet"
 | 
					    "https://dotnetcli.azureedge.net/dotnet"
 | 
				
			||||||
 | 
					    "https://ci.dot.net/public"
 | 
				
			||||||
    "https://dotnetbuilds.azureedge.net/public"
 | 
					    "https://dotnetbuilds.azureedge.net/public"
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -1419,10 +1623,11 @@ install_dotnet() {
 | 
				
			|||||||
    eval $invocation
 | 
					    eval $invocation
 | 
				
			||||||
    local download_failed=false
 | 
					    local download_failed=false
 | 
				
			||||||
    local download_completed=false
 | 
					    local download_completed=false
 | 
				
			||||||
 | 
					    local remote_file_size=0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    mkdir -p "$install_root"
 | 
					    mkdir -p "$install_root"
 | 
				
			||||||
    zip_path="$(mktemp "$temporary_file_template")"
 | 
					    zip_path="${zip_path:-$(mktemp "$temporary_file_template")}"
 | 
				
			||||||
    say_verbose "Zip path: $zip_path"
 | 
					    say_verbose "Archive path: $zip_path"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    for link_index in "${!download_links[@]}"
 | 
					    for link_index in "${!download_links[@]}"
 | 
				
			||||||
    do
 | 
					    do
 | 
				
			||||||
@ -1446,7 +1651,7 @@ install_dotnet() {
 | 
				
			|||||||
                say "Failed to download $link_type link '$download_link': $download_error_msg"
 | 
					                say "Failed to download $link_type link '$download_link': $download_error_msg"
 | 
				
			||||||
                ;;
 | 
					                ;;
 | 
				
			||||||
            esac
 | 
					            esac
 | 
				
			||||||
            rm -f "$zip_path" 2>&1 && say_verbose "Temporary zip file $zip_path was removed"
 | 
					            rm -f "$zip_path" 2>&1 && say_verbose "Temporary archive file $zip_path was removed"
 | 
				
			||||||
        else
 | 
					        else
 | 
				
			||||||
            download_completed=true
 | 
					            download_completed=true
 | 
				
			||||||
            break
 | 
					            break
 | 
				
			||||||
@ -1459,8 +1664,10 @@ install_dotnet() {
 | 
				
			|||||||
        return 1
 | 
					        return 1
 | 
				
			||||||
    fi
 | 
					    fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    say "Extracting zip from $download_link"
 | 
					    remote_file_size="$(get_remote_file_size "$download_link")"
 | 
				
			||||||
    extract_dotnet_package "$zip_path" "$install_root" || return 1
 | 
					
 | 
				
			||||||
 | 
					    say "Extracting archive from $download_link"
 | 
				
			||||||
 | 
					    extract_dotnet_package "$zip_path" "$install_root" "$remote_file_size" || return 1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    #  Check if the SDK version is installed; if not, fail the installation.
 | 
					    #  Check if the SDK version is installed; if not, fail the installation.
 | 
				
			||||||
    # if the version contains "RTM" or "servicing"; check if a 'release-type' SDK version is installed.
 | 
					    # if the version contains "RTM" or "servicing"; check if a 'release-type' SDK version is installed.
 | 
				
			||||||
@ -1610,10 +1817,22 @@ do
 | 
				
			|||||||
            override_non_versioned_files=false
 | 
					            override_non_versioned_files=false
 | 
				
			||||||
            non_dynamic_parameters+=" $name"
 | 
					            non_dynamic_parameters+=" $name"
 | 
				
			||||||
            ;;
 | 
					            ;;
 | 
				
			||||||
 | 
					        --keep-zip|-[Kk]eep[Zz]ip)
 | 
				
			||||||
 | 
					            keep_zip=true
 | 
				
			||||||
 | 
					            non_dynamic_parameters+=" $name"
 | 
				
			||||||
 | 
					            ;;
 | 
				
			||||||
 | 
					        --zip-path|-[Zz]ip[Pp]ath)
 | 
				
			||||||
 | 
					            shift
 | 
				
			||||||
 | 
					            zip_path="$1"
 | 
				
			||||||
 | 
					            ;;
 | 
				
			||||||
        -?|--?|-h|--help|-[Hh]elp)
 | 
					        -?|--?|-h|--help|-[Hh]elp)
 | 
				
			||||||
            script_name="$(basename "$0")"
 | 
					            script_name="dotnet-install.sh"
 | 
				
			||||||
            echo ".NET Tools Installer"
 | 
					            echo ".NET Tools Installer"
 | 
				
			||||||
            echo "Usage: $script_name [-c|--channel <CHANNEL>] [-v|--version <VERSION>] [-p|--prefix <DESTINATION>]"
 | 
					            echo "Usage:"
 | 
				
			||||||
 | 
					            echo "       # Install a .NET SDK of a given Quality from a given Channel"
 | 
				
			||||||
 | 
					            echo "       $script_name [-c|--channel <CHANNEL>] [-q|--quality <QUALITY>]"
 | 
				
			||||||
 | 
					            echo "       # Install a .NET SDK of a specific public version"
 | 
				
			||||||
 | 
					            echo "       $script_name [-v|--version <VERSION>]"
 | 
				
			||||||
            echo "       $script_name -h|-?|--help"
 | 
					            echo "       $script_name -h|-?|--help"
 | 
				
			||||||
            echo ""
 | 
					            echo ""
 | 
				
			||||||
            echo "$script_name is a simple command line interface for obtaining dotnet cli."
 | 
					            echo "$script_name is a simple command line interface for obtaining dotnet cli."
 | 
				
			||||||
@ -1655,7 +1874,7 @@ do
 | 
				
			|||||||
            echo "      -InstallDir"
 | 
					            echo "      -InstallDir"
 | 
				
			||||||
            echo "  --architecture <ARCHITECTURE>      Architecture of dotnet binaries to be installed, Defaults to \`$architecture\`."
 | 
					            echo "  --architecture <ARCHITECTURE>      Architecture of dotnet binaries to be installed, Defaults to \`$architecture\`."
 | 
				
			||||||
            echo "      --arch,-Architecture,-Arch"
 | 
					            echo "      --arch,-Architecture,-Arch"
 | 
				
			||||||
            echo "          Possible values: x64, arm, arm64 and s390x"
 | 
					            echo "          Possible values: x64, arm, arm64, s390x, ppc64le and loongarch64"
 | 
				
			||||||
            echo "  --os <system>                    Specifies operating system to be used when selecting the installer."
 | 
					            echo "  --os <system>                    Specifies operating system to be used when selecting the installer."
 | 
				
			||||||
            echo "          Overrides the OS determination approach used by the script. Supported values: osx, linux, linux-musl, freebsd, rhel.6."
 | 
					            echo "          Overrides the OS determination approach used by the script. Supported values: osx, linux, linux-musl, freebsd, rhel.6."
 | 
				
			||||||
            echo "          In case any other value is provided, the platform will be determined by the script based on machine configuration."
 | 
					            echo "          In case any other value is provided, the platform will be determined by the script based on machine configuration."
 | 
				
			||||||
@ -1680,6 +1899,8 @@ do
 | 
				
			|||||||
            echo "  --no-cdn,-NoCdn                    Disable downloading from the Azure CDN, and use the uncached feed directly."
 | 
					            echo "  --no-cdn,-NoCdn                    Disable downloading from the Azure CDN, and use the uncached feed directly."
 | 
				
			||||||
            echo "  --jsonfile <JSONFILE>              Determines the SDK version from a user specified global.json file."
 | 
					            echo "  --jsonfile <JSONFILE>              Determines the SDK version from a user specified global.json file."
 | 
				
			||||||
            echo "                                     Note: global.json must have a value for 'SDK:Version'"
 | 
					            echo "                                     Note: global.json must have a value for 'SDK:Version'"
 | 
				
			||||||
 | 
					            echo "  --keep-zip,-KeepZip                If set, downloaded file is kept."
 | 
				
			||||||
 | 
					            echo "  --zip-path, -ZipPath               If set, downloaded file is stored at the specified path."
 | 
				
			||||||
            echo "  -?,--?,-h,--help,-Help             Shows this help message"
 | 
					            echo "  -?,--?,-h,--help,-Help             Shows this help message"
 | 
				
			||||||
            echo ""
 | 
					            echo ""
 | 
				
			||||||
            echo "Install Location:"
 | 
					            echo "Install Location:"
 | 
				
			||||||
 | 
				
			|||||||
@ -101,9 +101,18 @@ export class DotnetVersionResolver {
 | 
				
			|||||||
      allowRetries: true,
 | 
					      allowRetries: true,
 | 
				
			||||||
      maxRetries: 3
 | 
					      maxRetries: 3
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
    const response = await httpClient.getJson<any>(
 | 
					
 | 
				
			||||||
 | 
					    let response;
 | 
				
			||||||
 | 
					    try {
 | 
				
			||||||
 | 
					      response = await httpClient.getJson<any>(
 | 
				
			||||||
        DotnetVersionResolver.DotNetCoreIndexUrl
 | 
					        DotnetVersionResolver.DotNetCoreIndexUrl
 | 
				
			||||||
      );
 | 
					      );
 | 
				
			||||||
 | 
					    } catch (error) {
 | 
				
			||||||
 | 
					      response = await httpClient.getJson<any>(
 | 
				
			||||||
 | 
					        DotnetVersionResolver.DotnetCoreIndexFallbackUrl
 | 
				
			||||||
 | 
					      );
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const result = response.result || {};
 | 
					    const result = response.result || {};
 | 
				
			||||||
    const releasesInfo: any[] = result['releases-index'];
 | 
					    const releasesInfo: any[] = result['releases-index'];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -122,6 +131,9 @@ export class DotnetVersionResolver {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  static DotNetCoreIndexUrl =
 | 
					  static DotNetCoreIndexUrl =
 | 
				
			||||||
 | 
					    'https://builds.dotnet.microsoft.com/dotnet/release-metadata/releases-index.json';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static DotnetCoreIndexFallbackUrl =
 | 
				
			||||||
    'https://dotnetcli.azureedge.net/dotnet/release-metadata/releases-index.json';
 | 
					    'https://dotnetcli.azureedge.net/dotnet/release-metadata/releases-index.json';
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user