diff --git a/.gitattributes b/.gitattributes index 9ce6848f71..372557fbd8 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,9 +1,30 @@ -LICENSE text -*.md text -*.js text -*.json text -*.html text -*.css text -*.txt text +LICENSE text eol=lf +*.md text eol=lf +*.c text eol=lf +*.cc text eol=lf +*.h text eol=lf +*.cc text eol=lf +*.S text eol=lf +*.s text eol=lf +*.hex -crlf -diff +*.elf -crlf -diff +*.ld text eol=lf +Makefile text eol=lf +*.mk text eol=lf +*.nomk text eol=lf +*.pl text eol=lf +*.js text eol=lf +*.json text eol=lf +*.html text eol=lf +*.css text eol=lf +*.svg text eol=lf *.png -crlf -diff -*.svg -crlf -diff +*.yml text eol=lf +*.xml text eol=lf +*.mcm text eol=lf +*.nsi text eol=lf +*.nsh text eol=lf +*.lua text eol=lf +*.txt text eol=lf +*.sh text eol=lf +*.config text eol=lf diff --git a/assets/windows/UnInst.nsh b/assets/windows/UnInst.nsh index 125e6e7221..d7affa2fb4 100644 --- a/assets/windows/UnInst.nsh +++ b/assets/windows/UnInst.nsh @@ -1,377 +1,377 @@ -/* - -NSIS Uninstaller Data -Copyright 2014 Aleksandr Ivankiv - -Modified by the Betaflight Team project to let it be used out of the uninstall section -*/ - -;-------------------------------- - -!ifndef UNINST_INCLUDED -!define UNINST_INCLUDED - -!verbose push -!verbose 3 - -!ifndef UNINST_VERBOSE - !define UNINST_VERBOSE 3 -!endif - -!verbose ${UNINST_VERBOSE} - -;-------------------------------- -;Header files required by Uninstaller Data - -!include "FileFunc.nsh" -!include "TextFunc.nsh" - -;-------------------------------- -;Variables - -Var List -Var Log -Var Tmp -Var UNINST_DAT -Var UNINST_EXE -Var UNINST_DEL_FILE - -;-------------------------------- -;Default language strings - -!define UNINST_EXCLUDE_ERROR_DEFAULT "Error creating an exclusion list." -!define UNINST_DATA_ERROR_DEFAULT "Error creating the uninstaller data: $\r$\nCannot find an exclusion list." -!define UNINST_DAT_NOT_FOUND_DEFAULT "$UNINST_DAT not found, unable to perform uninstall. Manually delete files." -!define UNINST_DAT_MISSING_DEFAULT "$UNINST_DAT is missing, some elements could not be removed. These can be removed manually." -!define UNINST_DEL_FILE_DEFAULT "Delete File" - -;-------------------------------- -;Language strings macro - -!macro SETSTRING NAME - - !ifndef "${NAME}" - !ifdef UNINST_LOCALIZE - !define "${NAME}" "$(${NAME})" - !else - !define "${NAME}" "${${NAME}_DEFAULT}" - !endif - !endif - -!macroend - -;-------------------------------- -;Initialization macro - -!macro UNINST_INIT - - ;Default settings - !ifndef UninstName - !define UninstName "Uninstall" - !endif - !ifndef UninstHeader - !define UninstHeader "=========== Uninstaller Data please do not edit this file ===========" - !endif - !insertmacro SETSTRING "UNINST_EXCLUDE_ERROR" - !insertmacro SETSTRING "UNINST_DATA_ERROR" - !insertmacro SETSTRING "UNINST_DAT_NOT_FOUND" - !insertmacro SETSTRING "UNINST_DAT_MISSING" - !insertmacro SETSTRING "UNINST_DEL_FILE" - StrCpy $UNINST_DEL_FILE "${UNINST_DEL_FILE}" - StrCpy $UNINST_DAT "$OUTDIR\${UninstName}.dat" - StrCpy $UNINST_EXE "$OUTDIR\${UninstName}.exe" - -!macroend - -;-------------------------------- -;Change name of file - -!macro UNINST_NAME Name - - !ifdef UninstName - !undef UninstName - !define UninstName "${Name}" - !else - !define UninstName "${Name}" - !endif - !insertmacro UNINST_INIT - -!macroend - -;-------------------------------- -;Create an exclusion list - -!macro UNINSTALLER_DATA_BEGIN - - !insertmacro UNINST_EXCLUDE - -!macroend - -!macro UNINST_EXCLUDE - - !verbose push - !verbose ${UNINST_VERBOSE} - - !insertmacro UNINST_INIT - - StrCmp "$PLUGINSDIR" "" 0 +2 - InitPluginsDir - - GetTempFileName $Tmp $PLUGINSDIR - - IfErrors 0 UninstExclude - !ifndef UNINST_ERROR - !define UNINST_ERROR - MessageBox MB_OK|MB_ICONEXCLAMATION "${UNINST_EXCLUDE_ERROR}" /SD IDOK - Goto +3 - !endif - - UninstExclude: - FileOpen $List "$Tmp" w - ${Locate} "$OUTDIR" "/L=FD" "${ExcludeList_Func_CallBack}" - FileClose $List - - !verbose pop - -!macroend - -!macro UNINST_FUNCTION_EXCLUDELIST - - Function ExcludeList - - FileWrite $List "$R9$\r$\n" - Push $0 - - FunctionEnd - -!macroend - -!ifndef ExcludeList_Func_CallBack - !insertmacro UNINST_FUNCTION_EXCLUDELIST - !define ExcludeList_Func_CallBack "ExcludeList" -!endif - -;---------------------------------------------------------------- -;Write Uninstaller Data - -!macro UNINSTALLER_DATA_END - - !insertmacro UNINST_DATA - -!macroend - -!macro UNINST_DATA - - !verbose push - !verbose ${UNINST_VERBOSE} - - !insertmacro UNINST_INIT - - IfFileExists "$Tmp" UninstData - !ifndef UNINST_ERROR - !define UNINST_ERROR - ${GetFileName} "$UNINST_DAT" $R0 - MessageBox MB_OK|MB_ICONEXCLAMATION "${UNINST_DATA_ERROR}" /SD IDOK - !endif - Goto DoneUninstData - - UninstData: - FileOpen $Log "$UNINST_DAT" a - FileOpen $List "$Tmp" r - - FileRead $Log $1 - IfErrors 0 +2 - FileWrite $Log "${UninstHeader}$\r$\n" - - ${Locate} "$OUTDIR" "/L=FD" "${UninstallData_Func_CallBack}" - - FileClose $List - FileClose $Log - - DoneUninstData: - StrCpy $Tmp "" - - !verbose pop - -!macroend - -!macro UNINST_FUNCTION_UNINSTDATA - - Function UninstallData - - StrCmp $R9 $UNINST_DAT Done - - FileSeek $List 0 SET - - LoopReadList: - FileRead $List $1 ${NSIS_MAX_STRLEN} - IfErrors DoneReadList - - ${TrimNewLines} $1 $R0 - StrCmp $R0 $R9 Done - - Goto LoopReadList - - DoneReadList: - FileSeek $Log 0 SET - - LoopReadLog: - FileRead $Log $1 ${NSIS_MAX_STRLEN} - IfErrors DoneReadLog - - ${TrimNewLines} $1 $R0 - StrCmp $R0 $R9 Done - - Goto LoopReadLog - - DoneReadLog: - FileSeek $Log 0 END - FileWrite $Log "$R9$\r$\n" - - Done: - Push $0 - - FunctionEnd - -!macroend - -!ifndef UninstallData_Func_CallBack - !insertmacro UNINST_FUNCTION_UNINSTDATA - !define UninstallData_Func_CallBack "UninstallData" -!endif - -;---------------------------------------------------------------- -;Uninstall Files - -!macro INST_DELETE Path Name - !insertmacro UNINST_DELETE_MULTIPLE ${Path} ${Name} "" -!macroend - -!macro UNINST_DELETE Path Name - !insertmacro UNINST_DELETE_MULTIPLE ${Path} ${Name} "un." -!macroend - -!macro UNINST_DELETE_MULTIPLE Path Name un - - !verbose push - !verbose ${UNINST_VERBOSE} - - !if "${Path}" == "" - StrCpy $OUTDIR "$INSTDIR" - !else - StrCpy $OUTDIR "${Path}" - !endif - !if "${Name}" == "" - !insertmacro UNINST_NAME "Uninstall" - !else - !insertmacro UNINST_NAME "${Name}" - !endif - - !insertmacro UNINST_INIT - - IfFileExists "$UNINST_DAT" +3 - !ifdef UNINST_TERMINATE - MessageBox MB_OK|MB_ICONSTOP "${UNINST_DAT_NOT_FOUND}" /SD IDOK - Quit - !else - MessageBox MB_OK|MB_ICONEXCLAMATION "${UNINST_DAT_MISSING}" /SD IDOK - StrCpy $0 "error" - !endif - - ${If} $0 != "error" - - FileOpen $Log "$UNINST_DAT" r - Call ${un}DeleteList - FileClose $Log - - Delete "$UNINST_DAT" - - !ifdef UNINST_INTERACTIVE - ${Locate} "$OUTDIR" "/L=F" "${un.InterActive_Func_CallBack}" - ${Locate} "$OUTDIR" "/L=DE" "${un.InterActive_Func_CallBack}" - !else - Call ${un}InterActive - !endif - - ${Else} - StrCpy $0 "" - ${EndIf} - - Delete "$UNINST_EXE" - RMDir $OUTDIR - ClearErrors - - !verbose pop - -!macroend - -!macro UNINST_FUNCTION_DELETE un - - Function ${un}DeleteList - - LoopReadFile: - FileRead $Log $1 ${NSIS_MAX_STRLEN} - IfErrors DoneReadFile - - ${TrimNewLines} $1 $R0 - - IfFileExists $R0\*.* +3 - IfFileExists $R0 0 +2 - Delete $R0 - - Goto LoopReadFile - - DoneReadFile: - FileSeek $Log 0 SET - - LoopReadDIR: - FileRead $Log $1 ${NSIS_MAX_STRLEN} - IfErrors DoneReadDIR - - ${TrimNewLines} $1 $R0 - - IfFileExists $R0\*.* 0 +3 - RMDir $R0 - ClearErrors - - Goto LoopReadDIR - - DoneReadDIR: - - FunctionEnd - -!macroend - -!insertmacro UNINST_FUNCTION_DELETE "" -!insertmacro UNINST_FUNCTION_DELETE "un." - -!macro UNINST_FUNCTION_INTERACTIVE un - - Function ${un}InterActive - - StrCmp $R9 "" +8 - IfFileExists $R9\*.* 0 +3 - RMDir $R9 - Goto +4 - StrCmp $R9 $UNINST_EXE +3 - MessageBox MB_YESNO|MB_ICONQUESTION|MB_DEFBUTTON2 "$UNINST_DEL_FILE '$R9'?" /SD IDNO IDNO +2 - Delete $R9 - Push $0 - - FunctionEnd - -!macroend - -!ifndef un.InterActive_Func_CallBack - !insertmacro UNINST_FUNCTION_INTERACTIVE "un." - !define un.InterActive_Func_CallBack "un.InterActive" -!endif - -!ifndef InterActive_Func_CallBack - !insertmacro UNINST_FUNCTION_INTERACTIVE "" - !define InterActive_Func_CallBack "InterActive" -!endif - -!verbose pop - -!endif +/* + +NSIS Uninstaller Data +Copyright 2014 Aleksandr Ivankiv + +Modified by the Betaflight Team project to let it be used out of the uninstall section +*/ + +;-------------------------------- + +!ifndef UNINST_INCLUDED +!define UNINST_INCLUDED + +!verbose push +!verbose 3 + +!ifndef UNINST_VERBOSE + !define UNINST_VERBOSE 3 +!endif + +!verbose ${UNINST_VERBOSE} + +;-------------------------------- +;Header files required by Uninstaller Data + +!include "FileFunc.nsh" +!include "TextFunc.nsh" + +;-------------------------------- +;Variables + +Var List +Var Log +Var Tmp +Var UNINST_DAT +Var UNINST_EXE +Var UNINST_DEL_FILE + +;-------------------------------- +;Default language strings + +!define UNINST_EXCLUDE_ERROR_DEFAULT "Error creating an exclusion list." +!define UNINST_DATA_ERROR_DEFAULT "Error creating the uninstaller data: $\r$\nCannot find an exclusion list." +!define UNINST_DAT_NOT_FOUND_DEFAULT "$UNINST_DAT not found, unable to perform uninstall. Manually delete files." +!define UNINST_DAT_MISSING_DEFAULT "$UNINST_DAT is missing, some elements could not be removed. These can be removed manually." +!define UNINST_DEL_FILE_DEFAULT "Delete File" + +;-------------------------------- +;Language strings macro + +!macro SETSTRING NAME + + !ifndef "${NAME}" + !ifdef UNINST_LOCALIZE + !define "${NAME}" "$(${NAME})" + !else + !define "${NAME}" "${${NAME}_DEFAULT}" + !endif + !endif + +!macroend + +;-------------------------------- +;Initialization macro + +!macro UNINST_INIT + + ;Default settings + !ifndef UninstName + !define UninstName "Uninstall" + !endif + !ifndef UninstHeader + !define UninstHeader "=========== Uninstaller Data please do not edit this file ===========" + !endif + !insertmacro SETSTRING "UNINST_EXCLUDE_ERROR" + !insertmacro SETSTRING "UNINST_DATA_ERROR" + !insertmacro SETSTRING "UNINST_DAT_NOT_FOUND" + !insertmacro SETSTRING "UNINST_DAT_MISSING" + !insertmacro SETSTRING "UNINST_DEL_FILE" + StrCpy $UNINST_DEL_FILE "${UNINST_DEL_FILE}" + StrCpy $UNINST_DAT "$OUTDIR\${UninstName}.dat" + StrCpy $UNINST_EXE "$OUTDIR\${UninstName}.exe" + +!macroend + +;-------------------------------- +;Change name of file + +!macro UNINST_NAME Name + + !ifdef UninstName + !undef UninstName + !define UninstName "${Name}" + !else + !define UninstName "${Name}" + !endif + !insertmacro UNINST_INIT + +!macroend + +;-------------------------------- +;Create an exclusion list + +!macro UNINSTALLER_DATA_BEGIN + + !insertmacro UNINST_EXCLUDE + +!macroend + +!macro UNINST_EXCLUDE + + !verbose push + !verbose ${UNINST_VERBOSE} + + !insertmacro UNINST_INIT + + StrCmp "$PLUGINSDIR" "" 0 +2 + InitPluginsDir + + GetTempFileName $Tmp $PLUGINSDIR + + IfErrors 0 UninstExclude + !ifndef UNINST_ERROR + !define UNINST_ERROR + MessageBox MB_OK|MB_ICONEXCLAMATION "${UNINST_EXCLUDE_ERROR}" /SD IDOK + Goto +3 + !endif + + UninstExclude: + FileOpen $List "$Tmp" w + ${Locate} "$OUTDIR" "/L=FD" "${ExcludeList_Func_CallBack}" + FileClose $List + + !verbose pop + +!macroend + +!macro UNINST_FUNCTION_EXCLUDELIST + + Function ExcludeList + + FileWrite $List "$R9$\r$\n" + Push $0 + + FunctionEnd + +!macroend + +!ifndef ExcludeList_Func_CallBack + !insertmacro UNINST_FUNCTION_EXCLUDELIST + !define ExcludeList_Func_CallBack "ExcludeList" +!endif + +;---------------------------------------------------------------- +;Write Uninstaller Data + +!macro UNINSTALLER_DATA_END + + !insertmacro UNINST_DATA + +!macroend + +!macro UNINST_DATA + + !verbose push + !verbose ${UNINST_VERBOSE} + + !insertmacro UNINST_INIT + + IfFileExists "$Tmp" UninstData + !ifndef UNINST_ERROR + !define UNINST_ERROR + ${GetFileName} "$UNINST_DAT" $R0 + MessageBox MB_OK|MB_ICONEXCLAMATION "${UNINST_DATA_ERROR}" /SD IDOK + !endif + Goto DoneUninstData + + UninstData: + FileOpen $Log "$UNINST_DAT" a + FileOpen $List "$Tmp" r + + FileRead $Log $1 + IfErrors 0 +2 + FileWrite $Log "${UninstHeader}$\r$\n" + + ${Locate} "$OUTDIR" "/L=FD" "${UninstallData_Func_CallBack}" + + FileClose $List + FileClose $Log + + DoneUninstData: + StrCpy $Tmp "" + + !verbose pop + +!macroend + +!macro UNINST_FUNCTION_UNINSTDATA + + Function UninstallData + + StrCmp $R9 $UNINST_DAT Done + + FileSeek $List 0 SET + + LoopReadList: + FileRead $List $1 ${NSIS_MAX_STRLEN} + IfErrors DoneReadList + + ${TrimNewLines} $1 $R0 + StrCmp $R0 $R9 Done + + Goto LoopReadList + + DoneReadList: + FileSeek $Log 0 SET + + LoopReadLog: + FileRead $Log $1 ${NSIS_MAX_STRLEN} + IfErrors DoneReadLog + + ${TrimNewLines} $1 $R0 + StrCmp $R0 $R9 Done + + Goto LoopReadLog + + DoneReadLog: + FileSeek $Log 0 END + FileWrite $Log "$R9$\r$\n" + + Done: + Push $0 + + FunctionEnd + +!macroend + +!ifndef UninstallData_Func_CallBack + !insertmacro UNINST_FUNCTION_UNINSTDATA + !define UninstallData_Func_CallBack "UninstallData" +!endif + +;---------------------------------------------------------------- +;Uninstall Files + +!macro INST_DELETE Path Name + !insertmacro UNINST_DELETE_MULTIPLE ${Path} ${Name} "" +!macroend + +!macro UNINST_DELETE Path Name + !insertmacro UNINST_DELETE_MULTIPLE ${Path} ${Name} "un." +!macroend + +!macro UNINST_DELETE_MULTIPLE Path Name un + + !verbose push + !verbose ${UNINST_VERBOSE} + + !if "${Path}" == "" + StrCpy $OUTDIR "$INSTDIR" + !else + StrCpy $OUTDIR "${Path}" + !endif + !if "${Name}" == "" + !insertmacro UNINST_NAME "Uninstall" + !else + !insertmacro UNINST_NAME "${Name}" + !endif + + !insertmacro UNINST_INIT + + IfFileExists "$UNINST_DAT" +3 + !ifdef UNINST_TERMINATE + MessageBox MB_OK|MB_ICONSTOP "${UNINST_DAT_NOT_FOUND}" /SD IDOK + Quit + !else + MessageBox MB_OK|MB_ICONEXCLAMATION "${UNINST_DAT_MISSING}" /SD IDOK + StrCpy $0 "error" + !endif + + ${If} $0 != "error" + + FileOpen $Log "$UNINST_DAT" r + Call ${un}DeleteList + FileClose $Log + + Delete "$UNINST_DAT" + + !ifdef UNINST_INTERACTIVE + ${Locate} "$OUTDIR" "/L=F" "${un.InterActive_Func_CallBack}" + ${Locate} "$OUTDIR" "/L=DE" "${un.InterActive_Func_CallBack}" + !else + Call ${un}InterActive + !endif + + ${Else} + StrCpy $0 "" + ${EndIf} + + Delete "$UNINST_EXE" + RMDir $OUTDIR + ClearErrors + + !verbose pop + +!macroend + +!macro UNINST_FUNCTION_DELETE un + + Function ${un}DeleteList + + LoopReadFile: + FileRead $Log $1 ${NSIS_MAX_STRLEN} + IfErrors DoneReadFile + + ${TrimNewLines} $1 $R0 + + IfFileExists $R0\*.* +3 + IfFileExists $R0 0 +2 + Delete $R0 + + Goto LoopReadFile + + DoneReadFile: + FileSeek $Log 0 SET + + LoopReadDIR: + FileRead $Log $1 ${NSIS_MAX_STRLEN} + IfErrors DoneReadDIR + + ${TrimNewLines} $1 $R0 + + IfFileExists $R0\*.* 0 +3 + RMDir $R0 + ClearErrors + + Goto LoopReadDIR + + DoneReadDIR: + + FunctionEnd + +!macroend + +!insertmacro UNINST_FUNCTION_DELETE "" +!insertmacro UNINST_FUNCTION_DELETE "un." + +!macro UNINST_FUNCTION_INTERACTIVE un + + Function ${un}InterActive + + StrCmp $R9 "" +8 + IfFileExists $R9\*.* 0 +3 + RMDir $R9 + Goto +4 + StrCmp $R9 $UNINST_EXE +3 + MessageBox MB_YESNO|MB_ICONQUESTION|MB_DEFBUTTON2 "$UNINST_DEL_FILE '$R9'?" /SD IDNO IDNO +2 + Delete $R9 + Push $0 + + FunctionEnd + +!macroend + +!ifndef un.InterActive_Func_CallBack + !insertmacro UNINST_FUNCTION_INTERACTIVE "un." + !define un.InterActive_Func_CallBack "un.InterActive" +!endif + +!ifndef InterActive_Func_CallBack + !insertmacro UNINST_FUNCTION_INTERACTIVE "" + !define InterActive_Func_CallBack "InterActive" +!endif + +!verbose pop + +!endif diff --git a/assets/windows/installer.nsi b/assets/windows/installer.nsi index a19ebf5eb5..70ea1bc362 100644 --- a/assets/windows/installer.nsi +++ b/assets/windows/installer.nsi @@ -1,213 +1,213 @@ -!include "MUI2.nsh" -!include "FileFunc.nsh" -!include "LogicLib.nsh" -!include "UnInst.nsh" - -# Receives variables from the command line -# ${VERSION} - Version to generate (x.y.z) -# ${PLATFORM} - Platform to generate (win32 or win64) -# ${DEST_FOLDER} - Destination folder for the installer files - -# Some definitions -!define SOURCE_FILES "..\..\apps\betaflight-configurator\${PLATFORM}\*" -!define APP_NAME "Betaflight Configurator" -!define COMPANY_NAME "The Betaflight open source project." -!define GROUP_NAME "Betaflight" -!define FOLDER_NAME "Betaflight-Configurator" -!define FILE_NAME_INSTALLER "betaflight-configurator-installer_${VERSION}_${PLATFORM}.exe" -!define FILE_NAME_UNINSTALLER "uninstall-betaflight-configurator.exe" -!define FILE_NAME_EXECUTABLE "betaflight-configurator.exe" -!define LICENSE "..\..\LICENSE" -!define MUI_WELCOMEFINISHPAGE_BITMAP ".\bf_installer.bmp" - - -Name "${APP_NAME}" -BrandingText "${COMPANY_NAME}" - -# set the icon -!define MUI_ICON ".\bf_installer_icon.ico" -!define MUI_UNICON ".\bf_uninstaller_icon.ico" - -#Define uninstall list name -!define UninstName "uninbf00" - -# Request rights user level -RequestExecutionLevel highest - -# define the resulting installer's name: -OutFile "..\..\${DEST_FOLDER}\${FILE_NAME_INSTALLER}" - -# app dialogs -!insertmacro MUI_PAGE_WELCOME -!insertmacro MUI_PAGE_LICENSE ${LICENSE} -!insertmacro MUI_PAGE_DIRECTORY -!insertmacro MUI_PAGE_INSTFILES - -!define MUI_FINISHPAGE_RUN "$INSTDIR\${FILE_NAME_EXECUTABLE}" - -!insertmacro MUI_PAGE_FINISH -!insertmacro MUI_LANGUAGE "English" -!insertmacro MUI_LANGUAGE "Catalan" -!insertmacro MUI_LANGUAGE "Croatian" -!insertmacro MUI_LANGUAGE "French" -!insertmacro MUI_LANGUAGE "Galician" -!insertmacro MUI_LANGUAGE "German" -!insertmacro MUI_LANGUAGE "Indonesian" -!insertmacro MUI_LANGUAGE "Italian" -!insertmacro MUI_LANGUAGE "Japanese" -!insertmacro MUI_LANGUAGE "Korean" -!insertmacro MUI_LANGUAGE "Latvian" -!insertmacro MUI_LANGUAGE "Portuguese" -!insertmacro MUI_LANGUAGE "Russian" -!insertmacro MUI_LANGUAGE "SimpChinese" -!insertmacro MUI_LANGUAGE "Spanish" -!insertmacro MUI_LANGUAGE "Swedish" - -# detect default install folder -Function .onInit - - # Check if older version - ReadRegStr $R0 HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APP_NAME}" \ - "InstallLocation" - - ${If} $R0 != "" - StrCpy $INSTDIR $R0 - ${Else} - - # Check if older version without administrative rights - ReadRegStr $R1 HKCU "Software\${GROUP_NAME}\${APP_NAME}" \ - "InstallLocation" - - ${If} $R1 != "" - StrCpy $INSTDIR $R1 - ${Else} - - # New version, select default folder - UserInfo::GetAccountType - Pop $R2 - - ${If} $R2 == "Admin" - # set the default installation directory - !if ${PLATFORM} == 'win64' - StrCpy $INSTDIR "$PROGRAMFILES64\${GROUP_NAME}\${FOLDER_NAME}\" - !else - StrCpy $INSTDIR "$PROGRAMFILES\${GROUP_NAME}\${FOLDER_NAME}\" - !endif - ${Else} - StrCpy $INSTDIR "$DOCUMENTS\${GROUP_NAME}\${FOLDER_NAME}\" - ${Endif} - ${Endif} - ${Endif} - -FunctionEnd - -# default section start -Section - - # remove the older version, users with admin rights - ReadRegStr $R3 HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APP_NAME}" \ - "InstallLocation" - - ${If} $R3 != "" - # delete the installed files of the older version - !insertmacro INST_DELETE $R3 "${UninstName}" - - # remove installation folder if empty - RMDir "$R3" - - ${Else} - # remove the older version, users without admin rights - ReadRegStr $R4 HKCU "Software\${GROUP_NAME}\${APP_NAME}" \ - "InstallLocation" - - ${If} $R4 != "" - # delete the installed files of the older version - !insertmacro INST_DELETE $R4 "${UninstName}" - - # remove installation folder if empty - RMDir "$R4" - - ${EndIf} - ${EndIf} - - # the english shortcut is not installed in actual versions, remove the deletion in a future release - Delete "$SMPROGRAMS\${GROUP_NAME}\${FOLDER_NAME}\${APP_NAME} (English).lnk" - - # if the registry entries did not exist, we ignore the errors - ClearErrors - - # define the path to which the installer should install - SetOutPath $INSTDIR - - # create an exclusion list for the uninstaller - !insertmacro UNINSTALLER_DATA_BEGIN - - # specify the files to go in the output path - File /r ${SOURCE_FILES} - - # create the uninstaller - WriteUninstaller "$INSTDIR\${FILE_NAME_UNINSTALLER}" - - # store uninstaller data - !insertmacro UNINSTALLER_DATA_END - - # create shortcuts in the start menu and on the desktop - CreateDirectory "$SMPROGRAMS\${GROUP_NAME}\${FOLDER_NAME}" - CreateShortCut "$SMPROGRAMS\${GROUP_NAME}\${FOLDER_NAME}\${APP_NAME}.lnk" "$INSTDIR\${FILE_NAME_EXECUTABLE}" "" "$INSTDIR\images\bf_icon.ico" "0" "" "" "" - CreateShortCut "$SMPROGRAMS\${GROUP_NAME}\${FOLDER_NAME}\Uninstall ${APP_NAME}.lnk" "$INSTDIR\${FILE_NAME_UNINSTALLER}" - CreateShortCut "$DESKTOP\${APP_NAME}.lnk" "$INSTDIR\${FILE_NAME_EXECUTABLE}" "" "$INSTDIR\images\bf_icon.ico" "0" "" "" "" - - # include in add/remove programs - WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APP_NAME}" \ - "Publisher" "${COMPANY_NAME}" - WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APP_NAME}" \ - "DisplayName" "${APP_NAME}" - WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APP_NAME}" \ - "DisplayIcon" "$\"$INSTDIR\${FILE_NAME_EXECUTABLE}$\"" - WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APP_NAME}" \ - "UninstallString" "$\"$INSTDIR\${FILE_NAME_UNINSTALLER}$\"" - WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APP_NAME}" \ - "InstallLocation" "$INSTDIR" - WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APP_NAME}" \ - "DisplayVersion" "${VERSION}" - - # include for users without admin rights - WriteRegStr HKCU "Software\${GROUP_NAME}\${APP_NAME}" \ - "InstallLocation" "$INSTDIR" - - # estimate the size - ${GetSize} "$INSTDIR" "/S=0K" $0 $1 $2 - IntFmt $0 "0x%08X" $0 - WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APP_NAME}" \ - "EstimatedSize" "$0" - - -SectionEnd - -# create a section to define what the uninstaller does -Section "Uninstall" - - # terminate uninstaller if the .dat file does not exist - !define UNINST_TERMINATE - - # delete files - !insertmacro UNINST_DELETE "$INSTDIR" "${UninstName}" - - # remove installation folder if it is empty - RMDir "$INSTDIR" - - # delete the shortcuts - # the english shortcut is not installed in actual versions, remove the deletion in a future release - Delete "$SMPROGRAMS\${GROUP_NAME}\${FOLDER_NAME}\${APP_NAME}.lnk" - Delete "$SMPROGRAMS\${GROUP_NAME}\${FOLDER_NAME}\${APP_NAME} (English).lnk" - Delete "$SMPROGRAMS\${GROUP_NAME}\${FOLDER_NAME}\Uninstall ${APP_NAME}.lnk" - RMDir "$SMPROGRAMS\${GROUP_NAME}\${FOLDER_NAME}" - RMDir "$SMPROGRAMS\${GROUP_NAME}" - Delete "$DESKTOP\${APP_NAME}.lnk" - - # remove from registry - DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APP_NAME}" - DeleteRegKey HKCU "Software\${GROUP_NAME}\${APP_NAME}" - DeleteRegKey /ifempty HKCU "Software\${GROUP_NAME}" - -SectionEnd +!include "MUI2.nsh" +!include "FileFunc.nsh" +!include "LogicLib.nsh" +!include "UnInst.nsh" + +# Receives variables from the command line +# ${VERSION} - Version to generate (x.y.z) +# ${PLATFORM} - Platform to generate (win32 or win64) +# ${DEST_FOLDER} - Destination folder for the installer files + +# Some definitions +!define SOURCE_FILES "..\..\apps\betaflight-configurator\${PLATFORM}\*" +!define APP_NAME "Betaflight Configurator" +!define COMPANY_NAME "The Betaflight open source project." +!define GROUP_NAME "Betaflight" +!define FOLDER_NAME "Betaflight-Configurator" +!define FILE_NAME_INSTALLER "betaflight-configurator-installer_${VERSION}_${PLATFORM}.exe" +!define FILE_NAME_UNINSTALLER "uninstall-betaflight-configurator.exe" +!define FILE_NAME_EXECUTABLE "betaflight-configurator.exe" +!define LICENSE "..\..\LICENSE" +!define MUI_WELCOMEFINISHPAGE_BITMAP ".\bf_installer.bmp" + + +Name "${APP_NAME}" +BrandingText "${COMPANY_NAME}" + +# set the icon +!define MUI_ICON ".\bf_installer_icon.ico" +!define MUI_UNICON ".\bf_uninstaller_icon.ico" + +#Define uninstall list name +!define UninstName "uninbf00" + +# Request rights user level +RequestExecutionLevel highest + +# define the resulting installer's name: +OutFile "..\..\${DEST_FOLDER}\${FILE_NAME_INSTALLER}" + +# app dialogs +!insertmacro MUI_PAGE_WELCOME +!insertmacro MUI_PAGE_LICENSE ${LICENSE} +!insertmacro MUI_PAGE_DIRECTORY +!insertmacro MUI_PAGE_INSTFILES + +!define MUI_FINISHPAGE_RUN "$INSTDIR\${FILE_NAME_EXECUTABLE}" + +!insertmacro MUI_PAGE_FINISH +!insertmacro MUI_LANGUAGE "English" +!insertmacro MUI_LANGUAGE "Catalan" +!insertmacro MUI_LANGUAGE "Croatian" +!insertmacro MUI_LANGUAGE "French" +!insertmacro MUI_LANGUAGE "Galician" +!insertmacro MUI_LANGUAGE "German" +!insertmacro MUI_LANGUAGE "Indonesian" +!insertmacro MUI_LANGUAGE "Italian" +!insertmacro MUI_LANGUAGE "Japanese" +!insertmacro MUI_LANGUAGE "Korean" +!insertmacro MUI_LANGUAGE "Latvian" +!insertmacro MUI_LANGUAGE "Portuguese" +!insertmacro MUI_LANGUAGE "Russian" +!insertmacro MUI_LANGUAGE "SimpChinese" +!insertmacro MUI_LANGUAGE "Spanish" +!insertmacro MUI_LANGUAGE "Swedish" + +# detect default install folder +Function .onInit + + # Check if older version + ReadRegStr $R0 HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APP_NAME}" \ + "InstallLocation" + + ${If} $R0 != "" + StrCpy $INSTDIR $R0 + ${Else} + + # Check if older version without administrative rights + ReadRegStr $R1 HKCU "Software\${GROUP_NAME}\${APP_NAME}" \ + "InstallLocation" + + ${If} $R1 != "" + StrCpy $INSTDIR $R1 + ${Else} + + # New version, select default folder + UserInfo::GetAccountType + Pop $R2 + + ${If} $R2 == "Admin" + # set the default installation directory + !if ${PLATFORM} == 'win64' + StrCpy $INSTDIR "$PROGRAMFILES64\${GROUP_NAME}\${FOLDER_NAME}\" + !else + StrCpy $INSTDIR "$PROGRAMFILES\${GROUP_NAME}\${FOLDER_NAME}\" + !endif + ${Else} + StrCpy $INSTDIR "$DOCUMENTS\${GROUP_NAME}\${FOLDER_NAME}\" + ${Endif} + ${Endif} + ${Endif} + +FunctionEnd + +# default section start +Section + + # remove the older version, users with admin rights + ReadRegStr $R3 HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APP_NAME}" \ + "InstallLocation" + + ${If} $R3 != "" + # delete the installed files of the older version + !insertmacro INST_DELETE $R3 "${UninstName}" + + # remove installation folder if empty + RMDir "$R3" + + ${Else} + # remove the older version, users without admin rights + ReadRegStr $R4 HKCU "Software\${GROUP_NAME}\${APP_NAME}" \ + "InstallLocation" + + ${If} $R4 != "" + # delete the installed files of the older version + !insertmacro INST_DELETE $R4 "${UninstName}" + + # remove installation folder if empty + RMDir "$R4" + + ${EndIf} + ${EndIf} + + # the english shortcut is not installed in actual versions, remove the deletion in a future release + Delete "$SMPROGRAMS\${GROUP_NAME}\${FOLDER_NAME}\${APP_NAME} (English).lnk" + + # if the registry entries did not exist, we ignore the errors + ClearErrors + + # define the path to which the installer should install + SetOutPath $INSTDIR + + # create an exclusion list for the uninstaller + !insertmacro UNINSTALLER_DATA_BEGIN + + # specify the files to go in the output path + File /r ${SOURCE_FILES} + + # create the uninstaller + WriteUninstaller "$INSTDIR\${FILE_NAME_UNINSTALLER}" + + # store uninstaller data + !insertmacro UNINSTALLER_DATA_END + + # create shortcuts in the start menu and on the desktop + CreateDirectory "$SMPROGRAMS\${GROUP_NAME}\${FOLDER_NAME}" + CreateShortCut "$SMPROGRAMS\${GROUP_NAME}\${FOLDER_NAME}\${APP_NAME}.lnk" "$INSTDIR\${FILE_NAME_EXECUTABLE}" "" "$INSTDIR\images\bf_icon.ico" "0" "" "" "" + CreateShortCut "$SMPROGRAMS\${GROUP_NAME}\${FOLDER_NAME}\Uninstall ${APP_NAME}.lnk" "$INSTDIR\${FILE_NAME_UNINSTALLER}" + CreateShortCut "$DESKTOP\${APP_NAME}.lnk" "$INSTDIR\${FILE_NAME_EXECUTABLE}" "" "$INSTDIR\images\bf_icon.ico" "0" "" "" "" + + # include in add/remove programs + WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APP_NAME}" \ + "Publisher" "${COMPANY_NAME}" + WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APP_NAME}" \ + "DisplayName" "${APP_NAME}" + WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APP_NAME}" \ + "DisplayIcon" "$\"$INSTDIR\${FILE_NAME_EXECUTABLE}$\"" + WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APP_NAME}" \ + "UninstallString" "$\"$INSTDIR\${FILE_NAME_UNINSTALLER}$\"" + WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APP_NAME}" \ + "InstallLocation" "$INSTDIR" + WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APP_NAME}" \ + "DisplayVersion" "${VERSION}" + + # include for users without admin rights + WriteRegStr HKCU "Software\${GROUP_NAME}\${APP_NAME}" \ + "InstallLocation" "$INSTDIR" + + # estimate the size + ${GetSize} "$INSTDIR" "/S=0K" $0 $1 $2 + IntFmt $0 "0x%08X" $0 + WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APP_NAME}" \ + "EstimatedSize" "$0" + + +SectionEnd + +# create a section to define what the uninstaller does +Section "Uninstall" + + # terminate uninstaller if the .dat file does not exist + !define UNINST_TERMINATE + + # delete files + !insertmacro UNINST_DELETE "$INSTDIR" "${UninstName}" + + # remove installation folder if it is empty + RMDir "$INSTDIR" + + # delete the shortcuts + # the english shortcut is not installed in actual versions, remove the deletion in a future release + Delete "$SMPROGRAMS\${GROUP_NAME}\${FOLDER_NAME}\${APP_NAME}.lnk" + Delete "$SMPROGRAMS\${GROUP_NAME}\${FOLDER_NAME}\${APP_NAME} (English).lnk" + Delete "$SMPROGRAMS\${GROUP_NAME}\${FOLDER_NAME}\Uninstall ${APP_NAME}.lnk" + RMDir "$SMPROGRAMS\${GROUP_NAME}\${FOLDER_NAME}" + RMDir "$SMPROGRAMS\${GROUP_NAME}" + Delete "$DESKTOP\${APP_NAME}.lnk" + + # remove from registry + DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APP_NAME}" + DeleteRegKey HKCU "Software\${GROUP_NAME}\${APP_NAME}" + DeleteRegKey /ifempty HKCU "Software\${GROUP_NAME}" + +SectionEnd diff --git a/src/images/CF_settings_black.svg b/src/images/CF_settings_black.svg index 8b7f92915c..aee0eb9e96 100644 --- a/src/images/CF_settings_black.svg +++ b/src/images/CF_settings_black.svg @@ -1,24 +1,24 @@ - - - -CF_Settings_Icon - - - - - - - + + + +CF_Settings_Icon + + + + + + + diff --git a/src/images/CF_settings_white.svg b/src/images/CF_settings_white.svg index 58d66d1ddf..97afaab4d0 100644 --- a/src/images/CF_settings_white.svg +++ b/src/images/CF_settings_white.svg @@ -1,22 +1,22 @@ - - - -CF_Settings_Icon - - - - - - - + + + +CF_Settings_Icon + + + + + + + diff --git a/src/images/arrow.svg b/src/images/arrow.svg index 12b193a5f2..f945f986db 100644 --- a/src/images/arrow.svg +++ b/src/images/arrow.svg @@ -1,19 +1,19 @@ - - - - - - - - - - - - + + + + + + + + + + + + diff --git a/src/images/cf_logo_white.svg b/src/images/cf_logo_white.svg index 7c71cf3f0b..0935affffa 100644 --- a/src/images/cf_logo_white.svg +++ b/src/images/cf_logo_white.svg @@ -1,47 +1,47 @@ - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/images/icons/cf_failsafe_procedure1-dark.svg b/src/images/icons/cf_failsafe_procedure1-dark.svg index 28ec922c3d..165aac7d1d 100644 --- a/src/images/icons/cf_failsafe_procedure1-dark.svg +++ b/src/images/icons/cf_failsafe_procedure1-dark.svg @@ -1,49 +1,49 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/images/icons/cf_failsafe_procedure1.svg b/src/images/icons/cf_failsafe_procedure1.svg index ecf3c98c79..c08da3c841 100644 --- a/src/images/icons/cf_failsafe_procedure1.svg +++ b/src/images/icons/cf_failsafe_procedure1.svg @@ -1,49 +1,49 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/images/icons/cf_failsafe_procedure2-dark.svg b/src/images/icons/cf_failsafe_procedure2-dark.svg index 5e028567a2..e8b71fe4a9 100644 --- a/src/images/icons/cf_failsafe_procedure2-dark.svg +++ b/src/images/icons/cf_failsafe_procedure2-dark.svg @@ -1,53 +1,53 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/images/icons/cf_failsafe_procedure2.svg b/src/images/icons/cf_failsafe_procedure2.svg index be3e553e67..5fdb05acee 100644 --- a/src/images/icons/cf_failsafe_procedure2.svg +++ b/src/images/icons/cf_failsafe_procedure2.svg @@ -1,54 +1,54 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/images/icons/cf_failsafe_procedure3.svg b/src/images/icons/cf_failsafe_procedure3.svg index 5472a8ecde..8b931ec763 100644 --- a/src/images/icons/cf_failsafe_procedure3.svg +++ b/src/images/icons/cf_failsafe_procedure3.svg @@ -1,56 +1,56 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/images/icons/cf_failsafe_procedure4-dark.svg b/src/images/icons/cf_failsafe_procedure4-dark.svg index dc34276c71..f3f6b2c44e 100644 --- a/src/images/icons/cf_failsafe_procedure4-dark.svg +++ b/src/images/icons/cf_failsafe_procedure4-dark.svg @@ -1,78 +1,78 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/images/icons/cf_failsafe_procedure4.svg b/src/images/icons/cf_failsafe_procedure4.svg index 4555c45aae..d4af1e9a80 100644 --- a/src/images/icons/cf_failsafe_procedure4.svg +++ b/src/images/icons/cf_failsafe_procedure4.svg @@ -1,78 +1,78 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/images/icons/cf_icon_adjust_grey.svg b/src/images/icons/cf_icon_adjust_grey.svg index eed1419427..8de19cc9b9 100644 --- a/src/images/icons/cf_icon_adjust_grey.svg +++ b/src/images/icons/cf_icon_adjust_grey.svg @@ -1,13 +1,13 @@ - - - - - - - + + + + + + + diff --git a/src/images/icons/cf_icon_adjust_white.svg b/src/images/icons/cf_icon_adjust_white.svg index d3c00f07fa..55df0f446c 100644 --- a/src/images/icons/cf_icon_adjust_white.svg +++ b/src/images/icons/cf_icon_adjust_white.svg @@ -1,13 +1,13 @@ - - - - - - - + + + + + + + diff --git a/src/images/icons/cf_icon_advanced_grey.svg b/src/images/icons/cf_icon_advanced_grey.svg index d092b60388..d24fd50954 100644 --- a/src/images/icons/cf_icon_advanced_grey.svg +++ b/src/images/icons/cf_icon_advanced_grey.svg @@ -1,14 +1,14 @@ - - - - - - - - + + + + + + + + diff --git a/src/images/icons/cf_icon_advanced_white.svg b/src/images/icons/cf_icon_advanced_white.svg index 3674e41a40..18618c6ea2 100644 --- a/src/images/icons/cf_icon_advanced_white.svg +++ b/src/images/icons/cf_icon_advanced_white.svg @@ -1,14 +1,14 @@ - - - - - - - - + + + + + + + + diff --git a/src/images/icons/cf_icon_armed_active.svg b/src/images/icons/cf_icon_armed_active.svg index b76fab7ec0..6d2d96c7fe 100644 --- a/src/images/icons/cf_icon_armed_active.svg +++ b/src/images/icons/cf_icon_armed_active.svg @@ -1,16 +1,16 @@ - - - - - - - - - - + + + + + + + + + + diff --git a/src/images/icons/cf_icon_armed_grey.svg b/src/images/icons/cf_icon_armed_grey.svg index 7ae1904a82..0f99805482 100644 --- a/src/images/icons/cf_icon_armed_grey.svg +++ b/src/images/icons/cf_icon_armed_grey.svg @@ -1,16 +1,16 @@ - - - - - - - - - - + + + + + + + + + + diff --git a/src/images/icons/cf_icon_backup_grey.svg b/src/images/icons/cf_icon_backup_grey.svg index ca1a977188..238b81a874 100644 --- a/src/images/icons/cf_icon_backup_grey.svg +++ b/src/images/icons/cf_icon_backup_grey.svg @@ -1,12 +1,12 @@ - - - - - - - + + + + + + + diff --git a/src/images/icons/cf_icon_backup_white.svg b/src/images/icons/cf_icon_backup_white.svg index 7c97157a91..0bd189cb1d 100644 --- a/src/images/icons/cf_icon_backup_white.svg +++ b/src/images/icons/cf_icon_backup_white.svg @@ -1,12 +1,12 @@ - - - - - - - + + + + + + + diff --git a/src/images/icons/cf_icon_bat_grey.svg b/src/images/icons/cf_icon_bat_grey.svg index bbde282020..b6fa3d4a6a 100644 --- a/src/images/icons/cf_icon_bat_grey.svg +++ b/src/images/icons/cf_icon_bat_grey.svg @@ -1,14 +1,14 @@ - - - - - - - - + + + + + + + + diff --git a/src/images/icons/cf_icon_cli_grey.svg b/src/images/icons/cf_icon_cli_grey.svg index 879a3f65e3..c103aa40f8 100644 --- a/src/images/icons/cf_icon_cli_grey.svg +++ b/src/images/icons/cf_icon_cli_grey.svg @@ -1,17 +1,17 @@ - - - - - - - - - - - - - + + + + + + + + + + + + + diff --git a/src/images/icons/cf_icon_cli_white.svg b/src/images/icons/cf_icon_cli_white.svg index 5625f4ca3f..f396afdf7b 100644 --- a/src/images/icons/cf_icon_cli_white.svg +++ b/src/images/icons/cf_icon_cli_white.svg @@ -1,17 +1,17 @@ - - - - - - - - - - - - - + + + + + + + + + + + + + diff --git a/src/images/icons/cf_icon_config_grey.svg b/src/images/icons/cf_icon_config_grey.svg index d00c844e12..7a7ef03095 100644 --- a/src/images/icons/cf_icon_config_grey.svg +++ b/src/images/icons/cf_icon_config_grey.svg @@ -1,17 +1,17 @@ - - - - - - - - - - - + + + + + + + + + + + diff --git a/src/images/icons/cf_icon_config_white.svg b/src/images/icons/cf_icon_config_white.svg index cfd9b961dc..896abf5081 100644 --- a/src/images/icons/cf_icon_config_white.svg +++ b/src/images/icons/cf_icon_config_white.svg @@ -1,17 +1,17 @@ - - - - - - - - - - - + + + + + + + + + + + diff --git a/src/images/icons/cf_icon_data_grey.svg b/src/images/icons/cf_icon_data_grey.svg index 59107c129e..7d35512bcd 100644 --- a/src/images/icons/cf_icon_data_grey.svg +++ b/src/images/icons/cf_icon_data_grey.svg @@ -1,23 +1,23 @@ - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + diff --git a/src/images/icons/cf_icon_data_white.svg b/src/images/icons/cf_icon_data_white.svg index b4ff7f1a74..489070b944 100644 --- a/src/images/icons/cf_icon_data_white.svg +++ b/src/images/icons/cf_icon_data_white.svg @@ -1,23 +1,23 @@ - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + diff --git a/src/images/icons/cf_icon_failsafe_active.svg b/src/images/icons/cf_icon_failsafe_active.svg index e3ecd36951..60a497fb82 100644 --- a/src/images/icons/cf_icon_failsafe_active.svg +++ b/src/images/icons/cf_icon_failsafe_active.svg @@ -1,14 +1,14 @@ - - - - - - - - + + + + + + + + diff --git a/src/images/icons/cf_icon_failsafe_grey.svg b/src/images/icons/cf_icon_failsafe_grey.svg index 70dbbc4945..1e3a33cae6 100644 --- a/src/images/icons/cf_icon_failsafe_grey.svg +++ b/src/images/icons/cf_icon_failsafe_grey.svg @@ -1,15 +1,15 @@ - - - - - - - + + + + + + + \ No newline at end of file diff --git a/src/images/icons/cf_icon_failsafe_white.svg b/src/images/icons/cf_icon_failsafe_white.svg index 59b5b9f7aa..4d83049243 100644 --- a/src/images/icons/cf_icon_failsafe_white.svg +++ b/src/images/icons/cf_icon_failsafe_white.svg @@ -1,11 +1,11 @@ - - - - - - - + + + + + + + diff --git a/src/images/icons/cf_icon_filter.svg b/src/images/icons/cf_icon_filter.svg index 3aa4bae2b2..a4963d7dea 100644 --- a/src/images/icons/cf_icon_filter.svg +++ b/src/images/icons/cf_icon_filter.svg @@ -1,8 +1,8 @@ - - - - - - - + + + + + + + diff --git a/src/images/icons/cf_icon_flasher_grey.svg b/src/images/icons/cf_icon_flasher_grey.svg index 60c4a75233..5918f1eb63 100644 --- a/src/images/icons/cf_icon_flasher_grey.svg +++ b/src/images/icons/cf_icon_flasher_grey.svg @@ -1,23 +1,23 @@ - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + diff --git a/src/images/icons/cf_icon_flasher_white.svg b/src/images/icons/cf_icon_flasher_white.svg index 515c64335a..f08bed63fe 100644 --- a/src/images/icons/cf_icon_flasher_white.svg +++ b/src/images/icons/cf_icon_flasher_white.svg @@ -1,23 +1,23 @@ - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + diff --git a/src/images/icons/cf_icon_gps_grey.svg b/src/images/icons/cf_icon_gps_grey.svg index 56b17b2eb9..8153daa1cf 100644 --- a/src/images/icons/cf_icon_gps_grey.svg +++ b/src/images/icons/cf_icon_gps_grey.svg @@ -1,19 +1,19 @@ - - - - - - - - - - - - + + + + + + + + + + + + diff --git a/src/images/icons/cf_icon_gps_white.svg b/src/images/icons/cf_icon_gps_white.svg index a4d68bd1da..6bdc7bf826 100644 --- a/src/images/icons/cf_icon_gps_white.svg +++ b/src/images/icons/cf_icon_gps_white.svg @@ -1,19 +1,19 @@ - - - - - - - - - - - - + + + + + + + + + + + + diff --git a/src/images/icons/cf_icon_help_grey.svg b/src/images/icons/cf_icon_help_grey.svg index eadcced743..b11152b56d 100644 --- a/src/images/icons/cf_icon_help_grey.svg +++ b/src/images/icons/cf_icon_help_grey.svg @@ -1,15 +1,15 @@ - - - - - - - - - - - + + + + + + + + + + + diff --git a/src/images/icons/cf_icon_help_white.svg b/src/images/icons/cf_icon_help_white.svg index 571df9dd02..1c314f059e 100644 --- a/src/images/icons/cf_icon_help_white.svg +++ b/src/images/icons/cf_icon_help_white.svg @@ -1,15 +1,15 @@ - - - - - - - - - - - + + + + + + + + + + + diff --git a/src/images/icons/cf_icon_info_green.svg b/src/images/icons/cf_icon_info_green.svg index 017a7dd997..5e13dac0ef 100644 --- a/src/images/icons/cf_icon_info_green.svg +++ b/src/images/icons/cf_icon_info_green.svg @@ -1,16 +1,16 @@ - - - - - - - - + + + + + + + + diff --git a/src/images/icons/cf_icon_info_grey.svg b/src/images/icons/cf_icon_info_grey.svg index 03189e2011..6133776456 100644 --- a/src/images/icons/cf_icon_info_grey.svg +++ b/src/images/icons/cf_icon_info_grey.svg @@ -1,47 +1,47 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/images/icons/cf_icon_info_white.svg b/src/images/icons/cf_icon_info_white.svg index 87e3c01efb..d4f4be3cd7 100644 --- a/src/images/icons/cf_icon_info_white.svg +++ b/src/images/icons/cf_icon_info_white.svg @@ -1,47 +1,47 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/images/icons/cf_icon_led_grey.svg b/src/images/icons/cf_icon_led_grey.svg index 7af8e81a37..b81cd0f95e 100644 --- a/src/images/icons/cf_icon_led_grey.svg +++ b/src/images/icons/cf_icon_led_grey.svg @@ -1,10 +1,10 @@ - - - - - - - + + + + + + + diff --git a/src/images/icons/cf_icon_led_white.svg b/src/images/icons/cf_icon_led_white.svg index cb4ffdc88b..ba6bd054c1 100644 --- a/src/images/icons/cf_icon_led_white.svg +++ b/src/images/icons/cf_icon_led_white.svg @@ -1,10 +1,10 @@ - - - - - - - + + + + + + + diff --git a/src/images/icons/cf_icon_link_active.svg b/src/images/icons/cf_icon_link_active.svg index 949619279d..89c1c6de01 100644 --- a/src/images/icons/cf_icon_link_active.svg +++ b/src/images/icons/cf_icon_link_active.svg @@ -1,18 +1,18 @@ - - - - - - - - - - + + + + + + + + + + diff --git a/src/images/icons/cf_icon_link_grey.svg b/src/images/icons/cf_icon_link_grey.svg index d2c0a02753..ae867ac82e 100644 --- a/src/images/icons/cf_icon_link_grey.svg +++ b/src/images/icons/cf_icon_link_grey.svg @@ -1,18 +1,18 @@ - - - - - - - - - - + + + + + + + + + + diff --git a/src/images/icons/cf_icon_log_grey.svg b/src/images/icons/cf_icon_log_grey.svg index 561d5b5ba6..75fd4c448a 100644 --- a/src/images/icons/cf_icon_log_grey.svg +++ b/src/images/icons/cf_icon_log_grey.svg @@ -1,16 +1,16 @@ - - - - - - - - - - + + + + + + + + + + diff --git a/src/images/icons/cf_icon_log_white.svg b/src/images/icons/cf_icon_log_white.svg index e040676e61..3b07237527 100644 --- a/src/images/icons/cf_icon_log_white.svg +++ b/src/images/icons/cf_icon_log_white.svg @@ -1,16 +1,16 @@ - - - - - - - - - - + + + + + + + + + + diff --git a/src/images/icons/cf_icon_mission_grey.svg b/src/images/icons/cf_icon_mission_grey.svg index e09debff80..1e43038b68 100644 --- a/src/images/icons/cf_icon_mission_grey.svg +++ b/src/images/icons/cf_icon_mission_grey.svg @@ -1,15 +1,15 @@ - - - - - - - - - - - + + + + + + + + + + + diff --git a/src/images/icons/cf_icon_mission_white.svg b/src/images/icons/cf_icon_mission_white.svg index f3636b6a7a..3d130b899e 100644 --- a/src/images/icons/cf_icon_mission_white.svg +++ b/src/images/icons/cf_icon_mission_white.svg @@ -1,15 +1,15 @@ - - - - - - - - - - - + + + + + + + + + + + diff --git a/src/images/icons/cf_icon_modes_grey.svg b/src/images/icons/cf_icon_modes_grey.svg index 7ca364f119..4cf7fe8475 100644 --- a/src/images/icons/cf_icon_modes_grey.svg +++ b/src/images/icons/cf_icon_modes_grey.svg @@ -1,16 +1,16 @@ - - - - - - - - - - - - + + + + + + + + + + + + diff --git a/src/images/icons/cf_icon_modes_white.svg b/src/images/icons/cf_icon_modes_white.svg index bfe73e3d68..994a44ad21 100644 --- a/src/images/icons/cf_icon_modes_white.svg +++ b/src/images/icons/cf_icon_modes_white.svg @@ -1,16 +1,16 @@ - - - - - - - - - - - - + + + + + + + + + + + + diff --git a/src/images/icons/cf_icon_motor_grey.svg b/src/images/icons/cf_icon_motor_grey.svg index 7a48357b0e..3de63af6dd 100644 --- a/src/images/icons/cf_icon_motor_grey.svg +++ b/src/images/icons/cf_icon_motor_grey.svg @@ -1,9 +1,9 @@ - - - - - - + + + + + + diff --git a/src/images/icons/cf_icon_motor_white.svg b/src/images/icons/cf_icon_motor_white.svg index c0bc8e30ee..02f716f8ce 100644 --- a/src/images/icons/cf_icon_motor_white.svg +++ b/src/images/icons/cf_icon_motor_white.svg @@ -1,9 +1,9 @@ - - - - - - + + + + + + diff --git a/src/images/icons/cf_icon_pid_grey.svg b/src/images/icons/cf_icon_pid_grey.svg index 6c7657bd27..76f1242a2c 100644 --- a/src/images/icons/cf_icon_pid_grey.svg +++ b/src/images/icons/cf_icon_pid_grey.svg @@ -1,20 +1,20 @@ - - - - - - - - - - - + + + + + + + + + + + diff --git a/src/images/icons/cf_icon_pid_white.svg b/src/images/icons/cf_icon_pid_white.svg index 81a7982dda..179a8615d6 100644 --- a/src/images/icons/cf_icon_pid_white.svg +++ b/src/images/icons/cf_icon_pid_white.svg @@ -1,20 +1,20 @@ - - - - - - - - - - - + + + + + + + + + + + diff --git a/src/images/icons/cf_icon_pitch.svg b/src/images/icons/cf_icon_pitch.svg index c037ba8348..edf8687431 100644 --- a/src/images/icons/cf_icon_pitch.svg +++ b/src/images/icons/cf_icon_pitch.svg @@ -1,16 +1,16 @@ - - - - - - - - - - - + + + + + + + + + + + diff --git a/src/images/icons/cf_icon_ports_grey.svg b/src/images/icons/cf_icon_ports_grey.svg index 7ff3de2315..c52caf4402 100644 --- a/src/images/icons/cf_icon_ports_grey.svg +++ b/src/images/icons/cf_icon_ports_grey.svg @@ -1,16 +1,16 @@ - - - - - - - - - - - + + + + + + + + + + + diff --git a/src/images/icons/cf_icon_ports_white.svg b/src/images/icons/cf_icon_ports_white.svg index ebba8f182f..bdf0f4c7ec 100644 --- a/src/images/icons/cf_icon_ports_white.svg +++ b/src/images/icons/cf_icon_ports_white.svg @@ -1,16 +1,16 @@ - - - - - - - - - - - + + + + + + + + + + + diff --git a/src/images/icons/cf_icon_power_grey.svg b/src/images/icons/cf_icon_power_grey.svg index 2cb96635db..ec2b88f12b 100644 --- a/src/images/icons/cf_icon_power_grey.svg +++ b/src/images/icons/cf_icon_power_grey.svg @@ -1,14 +1,14 @@ - - - - - - - - - + + + + + + + + + diff --git a/src/images/icons/cf_icon_power_white.svg b/src/images/icons/cf_icon_power_white.svg index 1af9f1f7ad..5db7571731 100644 --- a/src/images/icons/cf_icon_power_white.svg +++ b/src/images/icons/cf_icon_power_white.svg @@ -1,14 +1,14 @@ - - - - - - - - - + + + + + + + + + diff --git a/src/images/icons/cf_icon_quad.svg b/src/images/icons/cf_icon_quad.svg index f863cd6528..d12340b67b 100644 --- a/src/images/icons/cf_icon_quad.svg +++ b/src/images/icons/cf_icon_quad.svg @@ -1,26 +1,26 @@ - - - - - - - - - - - + + + + + + + + + + + diff --git a/src/images/icons/cf_icon_roll.svg b/src/images/icons/cf_icon_roll.svg index c8e7d8fbb7..c5c792e11c 100644 --- a/src/images/icons/cf_icon_roll.svg +++ b/src/images/icons/cf_icon_roll.svg @@ -1,12 +1,12 @@ - - - - - - - + + + + + + + diff --git a/src/images/icons/cf_icon_rx_grey.svg b/src/images/icons/cf_icon_rx_grey.svg index e8224e6816..b5eaabfa9a 100644 --- a/src/images/icons/cf_icon_rx_grey.svg +++ b/src/images/icons/cf_icon_rx_grey.svg @@ -1,14 +1,14 @@ - - - - - - - - - + + + + + + + + + diff --git a/src/images/icons/cf_icon_rx_white.svg b/src/images/icons/cf_icon_rx_white.svg index ca0a5de6db..a14f130f35 100644 --- a/src/images/icons/cf_icon_rx_white.svg +++ b/src/images/icons/cf_icon_rx_white.svg @@ -1,14 +1,14 @@ - - - - - - - - - + + + + + + + + + diff --git a/src/images/icons/cf_icon_sensors_grey.svg b/src/images/icons/cf_icon_sensors_grey.svg index f725ff2349..782d0be5f6 100644 --- a/src/images/icons/cf_icon_sensors_grey.svg +++ b/src/images/icons/cf_icon_sensors_grey.svg @@ -1,14 +1,14 @@ - - - - - - - - - + + + + + + + + + diff --git a/src/images/icons/cf_icon_sensors_white.svg b/src/images/icons/cf_icon_sensors_white.svg index ffd09868f5..844ba50916 100644 --- a/src/images/icons/cf_icon_sensors_white.svg +++ b/src/images/icons/cf_icon_sensors_white.svg @@ -1,14 +1,14 @@ - - - - - - - - - + + + + + + + + + diff --git a/src/images/icons/cf_icon_servo_grey.svg b/src/images/icons/cf_icon_servo_grey.svg index dbc3d6a2e6..996db23eef 100644 --- a/src/images/icons/cf_icon_servo_grey.svg +++ b/src/images/icons/cf_icon_servo_grey.svg @@ -1,10 +1,10 @@ - - - - - - - - + + + + + + + + diff --git a/src/images/icons/cf_icon_servo_white.svg b/src/images/icons/cf_icon_servo_white.svg index 870f879a65..332883e0a5 100644 --- a/src/images/icons/cf_icon_servo_white.svg +++ b/src/images/icons/cf_icon_servo_white.svg @@ -1,10 +1,10 @@ - - - - - - - - + + + + + + + + diff --git a/src/images/icons/cf_icon_settings_white.svg b/src/images/icons/cf_icon_settings_white.svg index 4d067de0fe..4aef1de61c 100644 --- a/src/images/icons/cf_icon_settings_white.svg +++ b/src/images/icons/cf_icon_settings_white.svg @@ -1,19 +1,19 @@ - - - - - - - - + + + + + + + + diff --git a/src/images/icons/cf_icon_setup_grey.svg b/src/images/icons/cf_icon_setup_grey.svg index 4bf3254023..3be2e44c88 100644 --- a/src/images/icons/cf_icon_setup_grey.svg +++ b/src/images/icons/cf_icon_setup_grey.svg @@ -1,12 +1,12 @@ - - - - - - - + + + + + + + diff --git a/src/images/icons/cf_icon_setup_white.svg b/src/images/icons/cf_icon_setup_white.svg index d79669da5c..6c1538b4ea 100644 --- a/src/images/icons/cf_icon_setup_white.svg +++ b/src/images/icons/cf_icon_setup_white.svg @@ -1,12 +1,12 @@ - - - - - - - + + + + + + + diff --git a/src/images/icons/cf_icon_transponder_grey.svg b/src/images/icons/cf_icon_transponder_grey.svg index 2ca2c8499d..5f4c30b718 100644 --- a/src/images/icons/cf_icon_transponder_grey.svg +++ b/src/images/icons/cf_icon_transponder_grey.svg @@ -1,27 +1,27 @@ - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + diff --git a/src/images/icons/cf_icon_transponder_white.svg b/src/images/icons/cf_icon_transponder_white.svg index a58f74b19f..15b59173d5 100644 --- a/src/images/icons/cf_icon_transponder_white.svg +++ b/src/images/icons/cf_icon_transponder_white.svg @@ -1,27 +1,27 @@ - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + diff --git a/src/images/icons/cf_icon_usb1_white.svg b/src/images/icons/cf_icon_usb1_white.svg index aab69b9713..3ae27d3ce1 100644 --- a/src/images/icons/cf_icon_usb1_white.svg +++ b/src/images/icons/cf_icon_usb1_white.svg @@ -1,15 +1,15 @@ - - - - - - - - - - + + + + + + + + + + diff --git a/src/images/icons/cf_icon_usb2_white.svg b/src/images/icons/cf_icon_usb2_white.svg index 767f21878e..42dc3efeaa 100644 --- a/src/images/icons/cf_icon_usb2_white.svg +++ b/src/images/icons/cf_icon_usb2_white.svg @@ -1,13 +1,13 @@ - - - - - - - - - - + + + + + + + + + + diff --git a/src/images/icons/cf_icon_vtx_grey.svg b/src/images/icons/cf_icon_vtx_grey.svg index 0f19ae9b30..3bb4d7a7b5 100644 --- a/src/images/icons/cf_icon_vtx_grey.svg +++ b/src/images/icons/cf_icon_vtx_grey.svg @@ -1,22 +1,22 @@ - - - - - - - - - - - - + + + + + + + + + + + + diff --git a/src/images/icons/cf_icon_vtx_white.svg b/src/images/icons/cf_icon_vtx_white.svg index 13aabda356..015bd7c92f 100644 --- a/src/images/icons/cf_icon_vtx_white.svg +++ b/src/images/icons/cf_icon_vtx_white.svg @@ -1,22 +1,22 @@ - - - - - - - - - - - - + + + + + + + + + + + + diff --git a/src/images/icons/cf_icon_welcome_grey.svg b/src/images/icons/cf_icon_welcome_grey.svg index 56c96a548e..6ec2673d0e 100644 --- a/src/images/icons/cf_icon_welcome_grey.svg +++ b/src/images/icons/cf_icon_welcome_grey.svg @@ -1,22 +1,22 @@ - - - - - - - - - - - + + + + + + + + + + + diff --git a/src/images/icons/cf_icon_welcome_white.svg b/src/images/icons/cf_icon_welcome_white.svg index c5fc2a7667..9e493fa6b7 100644 --- a/src/images/icons/cf_icon_welcome_white.svg +++ b/src/images/icons/cf_icon_welcome_white.svg @@ -1,22 +1,22 @@ - - - - - - - - - - - + + + + + + + + + + + diff --git a/src/images/icons/cf_icon_wizard_grey.svg b/src/images/icons/cf_icon_wizard_grey.svg index 4fb241ef52..698edc2264 100644 --- a/src/images/icons/cf_icon_wizard_grey.svg +++ b/src/images/icons/cf_icon_wizard_grey.svg @@ -1,12 +1,12 @@ - - - - - - - + + + + + + + diff --git a/src/images/icons/cf_icon_wizard_white.svg b/src/images/icons/cf_icon_wizard_white.svg index 0df2689b9b..42c6c5f601 100644 --- a/src/images/icons/cf_icon_wizard_white.svg +++ b/src/images/icons/cf_icon_wizard_white.svg @@ -1,12 +1,12 @@ - - - - - - - + + + + + + + diff --git a/src/images/icons/cf_icon_yaw.svg b/src/images/icons/cf_icon_yaw.svg index 17901652e9..44aac00db8 100644 --- a/src/images/icons/cf_icon_yaw.svg +++ b/src/images/icons/cf_icon_yaw.svg @@ -1,18 +1,18 @@ - - - - - - - - - - - - - + + + + + + + + + + + + + diff --git a/src/images/icons/close1.svg b/src/images/icons/close1.svg index c264ebd311..e15add5029 100644 --- a/src/images/icons/close1.svg +++ b/src/images/icons/close1.svg @@ -1,41 +1,41 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/images/icons/cross2.svg b/src/images/icons/cross2.svg index 4c2ae288ca..9fb5ff0fd6 100644 --- a/src/images/icons/cross2.svg +++ b/src/images/icons/cross2.svg @@ -1,39 +1,39 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/images/icons/icon_bracket.svg b/src/images/icons/icon_bracket.svg index 656fd85873..e77f11708c 100644 --- a/src/images/icons/icon_bracket.svg +++ b/src/images/icons/icon_bracket.svg @@ -1,12 +1,12 @@ - - - - - - + + + + + + diff --git a/src/images/icons/icon_osd.svg b/src/images/icons/icon_osd.svg index 856777502f..0d7e10ac9a 100644 --- a/src/images/icons/icon_osd.svg +++ b/src/images/icons/icon_osd.svg @@ -1,25 +1,25 @@ - - - - - - - - - - + + + + + + + + + + diff --git a/src/images/icons/icon_osd_white.svg b/src/images/icons/icon_osd_white.svg index 3f953060b9..1c89e56169 100644 --- a/src/images/icons/icon_osd_white.svg +++ b/src/images/icons/icon_osd_white.svg @@ -1,25 +1,25 @@ - - - - - - - - - - + + + + + + + + + + diff --git a/src/images/icons/scroll.svg b/src/images/icons/scroll.svg index 5a68b79b8b..572326c0a8 100644 --- a/src/images/icons/scroll.svg +++ b/src/images/icons/scroll.svg @@ -1,32 +1,32 @@ - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + diff --git a/src/images/light-wide-1.svg b/src/images/light-wide-1.svg index a81b5ec892..1bacaab832 100644 --- a/src/images/light-wide-1.svg +++ b/src/images/light-wide-1.svg @@ -1,46 +1,46 @@ - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/images/light-wide-2.svg b/src/images/light-wide-2.svg index bbcab406aa..2638ef60bd 100644 --- a/src/images/light-wide-2.svg +++ b/src/images/light-wide-2.svg @@ -1,47 +1,47 @@ - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + +