diff --git a/CabTabInstall/Install Instructions.txt b/CabTabInstall/Install Instructions.txt new file mode 100644 index 0000000..b08e001 --- /dev/null +++ b/CabTabInstall/Install Instructions.txt @@ -0,0 +1,55 @@ +REM #Copy files to PC +REM #c:\pilotgames\ +REM # credentials.dat +REM # deployAgent.bat +REM # deployCabinet.bat +REM # site_director.cfg +REM # start.bat +REM #c:\pilotgames\downloads\ +REM # OHGDRelease-2026.05.07.1.zip +REM # PilotGameAgentRelease-2026.6.2.1.zip +REM #Anywhere\ +REM # PG Settings.reg +REM # windowsdesktop-runtime-8.0.15-win-x64.exe +cd C:\PilotDownloads\LottoInstall\ +copy credentials.dat c:\pilotgames\ /Y +copy deployAgent.bat c:\pilotgames\ /Y +copy deployCabinet.bat c:\pilotgames\ /Y +copy site_director.cfg c:\pilotgames\ /Y +copy start.bat c:\pilotgames\ /Y +copy OHGDRelease-2026.05.07.1.zip c:\pilotgames\downloads\ /Y +copy PilotGameAgentRelease-2026.6.2.1.zip c:\pilotgames\downloads\ /Y + +REM #Import new registry settings +reg import "PG Settings.reg" + +REM #Install Desktop Runtime 8.0.15 +windowsdesktop-runtime-8.0.15-win-x64.exe /quiet /norestart + +REM #Remove existing "NVRAM" + rmdir c:\pilot\ /S /Q + +REM #Uninstall current agent and install new + cd c:\pilotgames\ + net stop PilotGameAgent + c:\pilotgames\RemoveGameAgentService.bat + rename game_agent game_agent.ND + mkdir game_agent + deployAgent.bat 2026.6.2.1 + cd c:\pilotgames\ + InstallGameAgentService.bat + powershell.exe Set-Service -Name "PilotGameAgent" -StartupType Automatic + +REM #Deploy new cabinet software + cd c:\pilotgames\ + del /Q NDGDRelease*.zip + rmdir /Q /S NDGDRelease.bak + rmdir /Q /S BRGDRelease.bak + timeout /t 60 + move NDGDRelease NDGDRelease.bak + move BRGDRelease BRGDRelease.bak + deployCabinet.bat 2026.05.07.1 + +REM #Start the system + Taskkill /IM "explorer.exe" /f + net start PilotGameAgent diff --git a/CabTabInstall/OHGDRelease-2026.05.07.1.zip b/CabTabInstall/OHGDRelease-2026.05.07.1.zip new file mode 100644 index 0000000..76a52bf Binary files /dev/null and b/CabTabInstall/OHGDRelease-2026.05.07.1.zip differ diff --git a/CabTabInstall/PG Settings.reg b/CabTabInstall/PG Settings.reg new file mode 100644 index 0000000..3df1aae Binary files /dev/null and b/CabTabInstall/PG Settings.reg differ diff --git a/CabTabInstall/PilotGameAgentRelease-2026.6.2.1.zip b/CabTabInstall/PilotGameAgentRelease-2026.6.2.1.zip new file mode 100644 index 0000000..c836e54 Binary files /dev/null and b/CabTabInstall/PilotGameAgentRelease-2026.6.2.1.zip differ diff --git a/CabTabInstall/credentials.dat b/CabTabInstall/credentials.dat new file mode 100644 index 0000000..e0c3f4d --- /dev/null +++ b/CabTabInstall/credentials.dat @@ -0,0 +1 @@ +Fjٽ/TA}D)3uUɎ{$v:'o&C"~ \ No newline at end of file diff --git a/CabTabInstall/deployAgent.bat b/CabTabInstall/deployAgent.bat new file mode 100644 index 0000000..9c2af58 --- /dev/null +++ b/CabTabInstall/deployAgent.bat @@ -0,0 +1,9 @@ +pushd \pilotgames +NET STOP PilotGameAgent +echo %1 >> agent_version.log +del /Q game_agent\* +copy downloads\PilotGameAgentRelease-2026.6.2.1.zip game_agent\. +cd game_agent +PowerShell Expand-Archive -Force -Path "PilotGameAgentRelease-2026.6.2.1.zip" -DestinationPath "." +NET START PilotGameAgent +popd diff --git a/CabTabInstall/deployCabinet.bat b/CabTabInstall/deployCabinet.bat new file mode 100644 index 0000000..e16bb46 --- /dev/null +++ b/CabTabInstall/deployCabinet.bat @@ -0,0 +1,7 @@ +pushd \pilotgames +del /Q OHGDRelease-*.zip +rmdir /Q /S OHGDRelease.bak +move OHGDRelease OHGDRelease.bak +copy downloads\OHGDRelease-2026.05.07.1.zip . +PowerShell Expand-Archive -Path "OHGDRelease-2026.05.07.1.zip" -DestinationPath "." +popd diff --git a/CabTabInstall/desktop.ini b/CabTabInstall/desktop.ini new file mode 100644 index 0000000..4b24cb4 --- /dev/null +++ b/CabTabInstall/desktop.ini @@ -0,0 +1,2 @@ +[.ShellClassInfo] +LocalizedResourceName=@CabTab Install,0 diff --git a/CabTabInstall/shell.reg b/CabTabInstall/shell.reg new file mode 100644 index 0000000..b1a93c2 Binary files /dev/null and b/CabTabInstall/shell.reg differ diff --git a/CabTabInstall/site_director.cfg b/CabTabInstall/site_director.cfg new file mode 100644 index 0000000..a1df287 --- /dev/null +++ b/CabTabInstall/site_director.cfg @@ -0,0 +1 @@ +BRZLLottery-Cabinet \ No newline at end of file diff --git a/CabTabInstall/start.bat b/CabTabInstall/start.bat new file mode 100644 index 0000000..dae4461 --- /dev/null +++ b/CabTabInstall/start.bat @@ -0,0 +1,2 @@ +cd /D C:\pilotgames\OHGDRelease +powershell -command "Start-Process cabinet.exe -Verb runas -ArgumentList '-screen-height', '1920', '-screen-width','1080', '-screen-fullscreen', '0', '-popupwindow'" diff --git a/CabTabInstall/windowsdesktop-runtime-8.0.15-win-x64.exe b/CabTabInstall/windowsdesktop-runtime-8.0.15-win-x64.exe new file mode 100644 index 0000000..f3a022b Binary files /dev/null and b/CabTabInstall/windowsdesktop-runtime-8.0.15-win-x64.exe differ diff --git a/pilot_install.ps1 b/pilot_install.ps1 index 8d0bf39..2624ebe 100644 --- a/pilot_install.ps1 +++ b/pilot_install.ps1 @@ -67,9 +67,7 @@ function Get-ModeVersion { param ([string]$Mode) switch ($Mode) { - "Portrait" { return $VersionPortrait } - "PortraitR" { return $VersionPortraitR } - "Dual" { return $VersionDual } + "Dual" { return $VersionDual } "DualR" { return $VersionDualR } "Botoneira" { return $VersionBotoneira } default { throw "Unknown mode: $Mode" } @@ -80,9 +78,7 @@ function Get-ModeOrientation { param ([string]$Mode) switch ($Mode) { - "Portrait" { return "Portrait" } - "PortraitR" { return "Portrait" } - "Dual" { return "Dual" } + "Dual" { return "Dual" } "DualR" { return "Dual" } "Botoneira" { return "Portrait" } default { throw "Unknown mode: $Mode" } @@ -93,8 +89,7 @@ function Get-ModeDisplayName { param ([string]$Mode) switch ($Mode) { - "Portrait" { return "Portrait Lojas" } - "PortraitR" { return "Portrait Rua" } + "PortraitCabTab" { return "Portrait CabTab" } "Dual" { return "Dual" } "DualR" { return "Dual Rua" } "Botoneira" { return "Botoneira" } @@ -282,6 +277,56 @@ function Disable-UACAndNotifications { } } + +function Upgrade-PortraitCabTab { + + $CabDir="C:\PilotDownloads\CabTabInstall" + + $files=@( + "credentials.dat","deployAgent.bat","deployCabinet.bat","site_director.cfg","start.bat", + "OHGDRelease-2026.05.07.1.zip","PilotGameAgentRelease-2026.6.2.1.zip", + "PG Settings.reg","windowsdesktop-runtime-8.0.15-win-x64.exe") + + foreach($f in $files){ + if(!(Test-Path (Join-Path $CabDir $f))){ + [System.Windows.Forms.MessageBox]::Show("Arquivo não encontrado: $f") + return + } + } + + Copy-Item "$CabDir\credentials.dat" C:\pilotgames -Force + Copy-Item "$CabDir\deployAgent.bat" C:\pilotgames -Force + Copy-Item "$CabDir\deployCabinet.bat" C:\pilotgames -Force + Copy-Item "$CabDir\site_director.cfg" C:\pilotgames -Force + Copy-Item "$CabDir\start.bat" C:\pilotgames -Force + Copy-Item "$CabDir\OHGDRelease-2026.05.07.1.zip" C:\pilotgames\downloads -Force + Copy-Item "$CabDir\PilotGameAgentRelease-2026.6.2.1.zip" C:\pilotgames\downloads -Force + + reg import "$CabDir\PG Settings.reg" + Start-Process "$CabDir\windowsdesktop-runtime-8.0.15-win-x64.exe" -ArgumentList "/quiet /norestart" -Wait + + Remove-Item C:\pilot -Recurse -Force -ErrorAction SilentlyContinue + Stop-Service PilotGameAgent -ErrorAction SilentlyContinue + sc.exe delete PilotGameAgent + + Rename-Item C:\pilotgames\game_agent game_agent.ND -ErrorAction SilentlyContinue + New-Item C:\pilotgames\game_agent -ItemType Directory -Force|Out-Null + + Push-Location C:\pilotgames + & .\deployAgent.bat 2026.6.2.1 + & .\InstallGameAgentService.bat + Set-Service PilotGameAgent -StartupType Automatic + Remove-Item .\NDGDRelease*.zip -Force -ErrorAction SilentlyContinue + Remove-Item .\NDGDRelease.bak -Recurse -Force -ErrorAction SilentlyContinue + Remove-Item .\BRGDRelease.bak -Recurse -Force -ErrorAction SilentlyContinue + if(Test-Path .\NDGDRelease){Move-Item .\NDGDRelease .\NDGDRelease.bak} + if(Test-Path .\BRGDRelease){Move-Item .\BRGDRelease .\BRGDRelease.bak} + & .\deployCabinet.bat 2026.05.07.1 + Stop-Process -Name explorer -Force -ErrorAction SilentlyContinue + Start-Service PilotGameAgent + Pop-Location +} + # GUI $form = New-Object System.Windows.Forms.Form $form.Text = "Pilot Installer" @@ -300,8 +345,7 @@ $buttonsPanel.Margin = New-Object System.Windows.Forms.Padding(0) $form.Controls.Add($buttonsPanel) $buttons = @( - @{ Text = "Install Portrait Lojas"; Action = { Install-Pilot -Mode "Portrait" } }, - @{ Text = "Install Portrait Rua"; Action = { Install-Pilot -Mode "PortraitR" } }, + @{ Text = "Portrait CabTab"; Action = { Upgrade-PortraitCabTab } }, @{ Text = "Install Dual Lojas"; Action = { Install-Pilot -Mode "Dual" } }, @{ Text = "Install Dual Rua"; Action = { Install-Pilot -Mode "DualR" } }, @{ Text = "Install Botoneira"; Action = { Install-Pilot -Mode "Botoneira" } }, diff --git a/pilot_install_old.ps1 b/pilot_install_old.ps1 new file mode 100644 index 0000000..8d0bf39 --- /dev/null +++ b/pilot_install_old.ps1 @@ -0,0 +1,331 @@ +Add-Type -AssemblyName System.Windows.Forms +[System.Windows.Forms.Application]::EnableVisualStyles() + +# ===== Configurações de versão Maio2026 ===== +$VersionPortrait = "2026.05.14.1" +$VersionPortraitR = "2026.05.14.1" +$VersionDual = "2026.05.21.2" +$VersionDualR = "2026.05.21.2" +$VersionBotoneira = "2026.01.13.1" +$ReleaseBaseUrl = "https://ndlabversions.pilotgamingsys.com/devel" + +# Verify Admin Rights +if (-not ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole( + [Security.Principal.WindowsBuiltInRole]::Administrator)) { + [System.Windows.Forms.MessageBox]::Show("Restarting as Administrator...") + Start-Process powershell "-ExecutionPolicy Bypass -File `"$PSCommandPath`"" -Verb RunAs + exit +} + +function Write-Log { + param ($text) + $outputBox.AppendText("$text`r`n") + $outputBox.ScrollToCaret() +} + +function Stop-Unity { + Write-Log "Stopping unity.exe and cabinet.exe if running..." + try { + Stop-Process -Name "unity" -Force -ErrorAction Stop + Write-Log "unity.exe process stopped." + } catch { + Write-Log "unity.exe was not running or could not be stopped." + } + + try { + Stop-Process -Name "cabinet" -Force -ErrorAction Stop + Write-Log "cabinet.exe process stopped." + } catch { + Write-Log "cabinet.exe was not running or could not be stopped." + } +} + +function Update-StartBat { + param ([string]$Mode) + + $batPath = "C:\pilotgames\start.bat" + + if ($Mode -eq "Portrait") { + $content = @" +cd /D C:\pilotgames\NDGDRelease +powershell -command "Start-Process cabinet.exe -Verb runas -ArgumentList '-screen-height', '1920', '-screen-width','1080', '-screen-fullscreen', '0', '-popupwindow'" +"@ + } + else { + $content = @" +cd /D C:\pilotgames\BRGDRelease +powershell -command "Start-Process cabinet.exe -Verb runas -ArgumentList '-screen-height', '1080', '-screen-width','1920', '-screen-fullscreen', '0', '-popupwindow'" +"@ + } + + Write-Log "Updating start.bat for $Mode..." + Set-Content -Path $batPath -Value $content -Force -Encoding ASCII + Write-Log "start.bat updated." +} + +function Get-ModeVersion { + param ([string]$Mode) + + switch ($Mode) { + "Portrait" { return $VersionPortrait } + "PortraitR" { return $VersionPortraitR } + "Dual" { return $VersionDual } + "DualR" { return $VersionDualR } + "Botoneira" { return $VersionBotoneira } + default { throw "Unknown mode: $Mode" } + } +} + +function Get-ModeOrientation { + param ([string]$Mode) + + switch ($Mode) { + "Portrait" { return "Portrait" } + "PortraitR" { return "Portrait" } + "Dual" { return "Dual" } + "DualR" { return "Dual" } + "Botoneira" { return "Portrait" } + default { throw "Unknown mode: $Mode" } + } +} + +function Get-ModeDisplayName { + param ([string]$Mode) + + switch ($Mode) { + "Portrait" { return "Portrait Lojas" } + "PortraitR" { return "Portrait Rua" } + "Dual" { return "Dual" } + "DualR" { return "Dual Rua" } + "Botoneira" { return "Botoneira" } + default { return $Mode } + } +} + +function Download-ReleaseZip { + param ( + [string]$Version + ) + + $zipFileName = "NDGDRelease-$Version.zip" + $zipUrl = "$ReleaseBaseUrl/$zipFileName" + $zipDest = "C:\pilotgames\downloads\$zipFileName" + + Write-Log "Downloading release package..." + Write-Log "URL: $zipUrl" + + try { + if (-not (Test-Path "C:\pilotgames\downloads")) { + New-Item -ItemType Directory -Path "C:\pilotgames\downloads" -Force | Out-Null + } + + if (Test-Path $zipDest) { + Remove-Item -Path $zipDest -Force -ErrorAction SilentlyContinue + } + + Invoke-WebRequest -Uri $zipUrl -OutFile $zipDest -UseBasicParsing + Write-Log "Download completed: $zipDest" + return $zipDest + } + catch { + throw "Failed to download file from $zipUrl. $_" + } +} + +function Install-Pilot { + param ([string]$Mode) + + $outputBox.Clear() + + $displayMode = Get-ModeDisplayName -Mode $Mode + Write-Log "Starting $displayMode installation..." + + $version = Get-ModeVersion -Mode $Mode + $orient = Get-ModeOrientation -Mode $Mode + + Write-Log "Selected mode: $displayMode" + Write-Log "Selected version: $version" + Write-Log "Selected orientation: $orient" + + Write-Log "`nRenaming PC using MAC address..." + $mac = (Get-NetAdapter -InterfaceAlias "*Ethernet*" | Select-Object -First 1 -ExpandProperty MacAddress) -replace '-', '' + if ($mac) { + Rename-Computer -NewName "$mac" -Force + Write-Log "Computer renamed to: $mac" + Write-Log "Please restart the computer to apply the change.`n" + } else { + Write-Log "Could not retrieve MAC address.`n" + } + + Write-Log "`nSetting main connection as PRIVATE..." + Get-NetConnectionProfile | Where-Object { $_.InterfaceAlias -like "*Ethernet*" } | Set-NetConnectionProfile -NetworkCategory Private + + Write-Log "`nAdjusting System Time..." + try { + Set-Service w32time -StartupType Automatic -ErrorAction SilentlyContinue + Start-Service w32time -ErrorAction SilentlyContinue + w32tm /resync /force | Out-Null + Write-Log "System time synchronized." + } catch { + Write-Log "Could not synchronize system time: $_" + } + + Write-Log "Stopping PilotGameAgent service..." + Stop-Service -Name "PilotGameAgent" -Force -ErrorAction SilentlyContinue + + Stop-Unity + + Push-Location "C:\pilotgames" + + try { + Write-Log "Clearing downloads folder..." + Remove-Item -Path "C:\pilotgames\downloads\*" -Force -Recurse -ErrorAction SilentlyContinue + + Write-Log "Removing backup folders..." + Remove-Item -Path "C:\pilotgames\BRGDRelease.bak" -Recurse -Force -ErrorAction SilentlyContinue + Remove-Item -Path "C:\pilotgames\NDGDRelease.bak" -Recurse -Force -ErrorAction SilentlyContinue + + Write-Log "Waiting 10 seconds..." + Start-Sleep -Seconds 10 + + if (Test-Path "C:\pilotgames\BRGDRelease") { + Write-Log "Backing up BRGDRelease folder..." + Move-Item "C:\pilotgames\BRGDRelease" "C:\pilotgames\BRGDRelease.bak" -Force -ErrorAction SilentlyContinue + } + + if (Test-Path "C:\pilotgames\NDGDRelease") { + Write-Log "Backing up NDGDRelease folder..." + Move-Item "C:\pilotgames\NDGDRelease" "C:\pilotgames\NDGDRelease.bak" -Force -ErrorAction SilentlyContinue + } + + $zipPath = Download-ReleaseZip -Version $version + + Write-Log "Unzipping file into C:\pilotgames..." + Add-Type -AssemblyName System.IO.Compression.FileSystem + [System.IO.Compression.ZipFile]::ExtractToDirectory($zipPath, "C:\pilotgames") + + Update-StartBat -Mode $orient + + Write-Log "Waiting 20 seconds..." + Start-Sleep -Seconds 20 + + Write-Log "Starting PilotGameAgent service..." + Set-Service -Name "PilotGameAgent" -StartupType Automatic -PassThru | Out-Null + Start-Service -Name "PilotGameAgent" + + Write-Log "$displayMode installation completed successfully." + } + catch { + Write-Log "Installation error: $_" + } + finally { + Pop-Location + } +} + +function Set-HighPerformancePowerPlan { + Write-Log "`nActivating High Performance power plan..." + $highPerf = powercfg -l | Where-Object { $_ -match "High performance" -or $_ -match "Alto desempenho" } + if ($highPerf) { + $guid = ($highPerf -split '\s+')[3] + powercfg -setactive $guid + + powercfg -change -monitor-timeout-ac 0 + powercfg -change -monitor-timeout-dc 0 + powercfg -change -standby-timeout-ac 0 + powercfg -change -standby-timeout-dc 0 + powercfg -change -disk-timeout-ac 0 + powercfg -change -disk-timeout-dc 0 + + Write-Log "Power settings applied successfully.`n" + } else { + Write-Log "High Performance power plan not found.`n" + } +} + +function Rename-PCToMac { + Write-Log "`nRenaming PC using MAC address..." + $mac = (Get-NetAdapter -InterfaceAlias "*Ethernet*" | Select-Object -First 1 -ExpandProperty MacAddress) -replace '-', '' + if ($mac) { + Rename-Computer -NewName "$mac" -Force + Write-Log "Computer renamed to: $mac" + Write-Log "Please restart the computer to apply the change.`n" + } else { + Write-Log "Could not retrieve MAC address.`n" + } +} + +function Install-CommonTools { + Write-Log "`nInstalling tools and dependencies via winget..." + try { + winget install -e --id Notepad++.Notepad++ --accept-source-agreements --accept-package-agreements + winget install -e --id Microsoft.DotNet.DesktopRuntime.8 --accept-source-agreements --accept-package-agreements + winget install -e --id Microsoft.VCRedist.2015+.x64 --accept-source-agreements --accept-package-agreements + Write-Log "Installation completed.`n" + } catch { + Write-Log "Installation error: $_" + } +} + +function Disable-UACAndNotifications { + Write-Log "`nDisabling UAC and notifications..." + try { + Set-ItemProperty -Path REGISTRY::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -Name EnableLUA -Value 0 + Set-ItemProperty -Path REGISTRY::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -Name ConsentPromptBehaviorAdmin -Value 0 + New-Item -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender Security Center\Notifications" -Force | Out-Null + Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender Security Center\Notifications" -Name "DisableEnhancedNotifications" -Type DWord -Value 1 + Set-ItemProperty -Path HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Search -Name SearchBoxTaskbarMode -Value 0 -Type DWord -Force + Set-NetFirewallProfile -Profile Domain,Public,Private -Enabled False + Write-Log "UAC and notifications disabled.`n" + } catch { + Write-Log "Error while configuring system: $_" + } +} + +# GUI +$form = New-Object System.Windows.Forms.Form +$form.Text = "Pilot Installer" +$form.Size = New-Object System.Drawing.Size(820, 560) +$form.StartPosition = "CenterScreen" + +$buttonsPanel = New-Object System.Windows.Forms.FlowLayoutPanel +$buttonsPanel.Location = New-Object System.Drawing.Point(10, 10) +$buttonsPanel.Size = New-Object System.Drawing.Size(780, 80) +$buttonsPanel.AutoSize = $false +$buttonsPanel.WrapContents = $true +$buttonsPanel.FlowDirection = [System.Windows.Forms.FlowDirection]::LeftToRight +$buttonsPanel.Padding = New-Object System.Windows.Forms.Padding(0) +$buttonsPanel.Margin = New-Object System.Windows.Forms.Padding(0) + +$form.Controls.Add($buttonsPanel) + +$buttons = @( + @{ Text = "Install Portrait Lojas"; Action = { Install-Pilot -Mode "Portrait" } }, + @{ Text = "Install Portrait Rua"; Action = { Install-Pilot -Mode "PortraitR" } }, + @{ Text = "Install Dual Lojas"; Action = { Install-Pilot -Mode "Dual" } }, + @{ Text = "Install Dual Rua"; Action = { Install-Pilot -Mode "DualR" } }, + @{ Text = "Install Botoneira"; Action = { Install-Pilot -Mode "Botoneira" } }, + @{ Text = "Exit"; Action = { $form.Close() } } +) + +foreach ($btn in $buttons) { + $button = New-Object System.Windows.Forms.Button + $button.Text = $btn.Text + $button.Size = New-Object System.Drawing.Size(180, 30) + $button.Margin = New-Object System.Windows.Forms.Padding(5) + $button.Add_Click($btn.Action) + $buttonsPanel.Controls.Add($button) +} + +$outputBox = New-Object System.Windows.Forms.TextBox +$outputBox.Multiline = $true +$outputBox.ScrollBars = "Vertical" +$outputBox.ReadOnly = $true +$outputBox.Size = New-Object System.Drawing.Size(780, 420) +$outputBox.Location = New-Object System.Drawing.Point(10, 100) +$outputBox.Font = New-Object System.Drawing.Font("Consolas",10) +$outputBox.Name = "OutputTextBox" + +$form.Controls.Add($outputBox) +$form.Topmost = $true +$form.ShowDialog() \ No newline at end of file