diff --git a/src/lang/ar-ye.json b/src/lang/ar-ye.json index dddeeface..079faa8e5 100644 --- a/src/lang/ar-ye.json +++ b/src/lang/ar-ye.json @@ -454,5 +454,38 @@ "keywords": "Keywords", "author": "Author", "filtered by": "Filtered by", - "clean install state": "Clean Install State" + "clean install state": "Clean Install State", + "backup created": "Backup created", + "restore completed": "Restore completed", + "restore will include": "This will restore", + "restore warning": "This action cannot be undone. Continue?", + "reload to apply": "Reload to apply changes?", + "reload app": "Reload app", + "preparing backup": "Preparing backup", + "collecting settings": "Collecting settings", + "collecting key bindings": "Collecting key bindings", + "collecting plugins": "Collecting plugin information", + "creating backup": "Creating backup file", + "validating backup": "Validating backup", + "restoring key bindings": "Restoring key bindings", + "restoring plugins": "Restoring plugins", + "restoring settings": "Restoring settings", + "legacy backup warning": "This is an older backup format. Some features may be limited.", + "checksum mismatch": "Checksum mismatch - backup file may have been modified or corrupted.", + "plugin not found": "Plugin not found in registry", + "paid plugin skipped": "Paid plugin - purchase not found", + "source not found": "Source file no longer exists", + "restored": "Restored", + "skipped": "Skipped", + "backup not valid object": "Backup file is not a valid object", + "backup no data": "Backup file contains no data to restore", + "backup legacy warning": "This is an older backup format (v1). Some features may be limited.", + "backup missing metadata": "Missing backup metadata - some info may be unavailable", + "backup checksum mismatch": "Checksum mismatch - backup file may have been modified or corrupted. Proceed with caution.", + "backup checksum verify failed": "Could not verify checksum", + "backup invalid settings": "Invalid settings format", + "backup invalid keybindings": "Invalid keyBindings format", + "backup invalid plugins": "Invalid installedPlugins format", + "issues found": "Issues found", + "error details": "Error details" } diff --git a/src/lang/be-by.json b/src/lang/be-by.json index fcd9de980..798a5f1f3 100644 --- a/src/lang/be-by.json +++ b/src/lang/be-by.json @@ -455,5 +455,38 @@ "keywords": "Keywords", "author": "Author", "filtered by": "Filtered by", - "clean install state": "Clean Install State" + "clean install state": "Clean Install State", + "backup created": "Backup created", + "restore completed": "Restore completed", + "restore will include": "This will restore", + "restore warning": "This action cannot be undone. Continue?", + "reload to apply": "Reload to apply changes?", + "reload app": "Reload app", + "preparing backup": "Preparing backup", + "collecting settings": "Collecting settings", + "collecting key bindings": "Collecting key bindings", + "collecting plugins": "Collecting plugin information", + "creating backup": "Creating backup file", + "validating backup": "Validating backup", + "restoring key bindings": "Restoring key bindings", + "restoring plugins": "Restoring plugins", + "restoring settings": "Restoring settings", + "legacy backup warning": "This is an older backup format. Some features may be limited.", + "checksum mismatch": "Checksum mismatch - backup file may have been modified or corrupted.", + "plugin not found": "Plugin not found in registry", + "paid plugin skipped": "Paid plugin - purchase not found", + "source not found": "Source file no longer exists", + "restored": "Restored", + "skipped": "Skipped", + "backup not valid object": "Backup file is not a valid object", + "backup no data": "Backup file contains no data to restore", + "backup legacy warning": "This is an older backup format (v1). Some features may be limited.", + "backup missing metadata": "Missing backup metadata - some info may be unavailable", + "backup checksum mismatch": "Checksum mismatch - backup file may have been modified or corrupted. Proceed with caution.", + "backup checksum verify failed": "Could not verify checksum", + "backup invalid settings": "Invalid settings format", + "backup invalid keybindings": "Invalid keyBindings format", + "backup invalid plugins": "Invalid installedPlugins format", + "issues found": "Issues found", + "error details": "Error details" } diff --git a/src/lang/bn-bd.json b/src/lang/bn-bd.json index ff1e6a85d..7e99886ac 100644 --- a/src/lang/bn-bd.json +++ b/src/lang/bn-bd.json @@ -454,5 +454,38 @@ "keywords": "Keywords", "author": "Author", "filtered by": "Filtered by", - "clean install state": "Clean Install State" + "clean install state": "Clean Install State", + "backup created": "Backup created", + "restore completed": "Restore completed", + "restore will include": "This will restore", + "restore warning": "This action cannot be undone. Continue?", + "reload to apply": "Reload to apply changes?", + "reload app": "Reload app", + "preparing backup": "Preparing backup", + "collecting settings": "Collecting settings", + "collecting key bindings": "Collecting key bindings", + "collecting plugins": "Collecting plugin information", + "creating backup": "Creating backup file", + "validating backup": "Validating backup", + "restoring key bindings": "Restoring key bindings", + "restoring plugins": "Restoring plugins", + "restoring settings": "Restoring settings", + "legacy backup warning": "This is an older backup format. Some features may be limited.", + "checksum mismatch": "Checksum mismatch - backup file may have been modified or corrupted.", + "plugin not found": "Plugin not found in registry", + "paid plugin skipped": "Paid plugin - purchase not found", + "source not found": "Source file no longer exists", + "restored": "Restored", + "skipped": "Skipped", + "backup not valid object": "Backup file is not a valid object", + "backup no data": "Backup file contains no data to restore", + "backup legacy warning": "This is an older backup format (v1). Some features may be limited.", + "backup missing metadata": "Missing backup metadata - some info may be unavailable", + "backup checksum mismatch": "Checksum mismatch - backup file may have been modified or corrupted. Proceed with caution.", + "backup checksum verify failed": "Could not verify checksum", + "backup invalid settings": "Invalid settings format", + "backup invalid keybindings": "Invalid keyBindings format", + "backup invalid plugins": "Invalid installedPlugins format", + "issues found": "Issues found", + "error details": "Error details" } diff --git a/src/lang/cs-cz.json b/src/lang/cs-cz.json index 721c3329a..e94ff38b0 100644 --- a/src/lang/cs-cz.json +++ b/src/lang/cs-cz.json @@ -454,5 +454,38 @@ "keywords": "Klíčová slova", "author": "Autor", "filtered by": "Filtrováno podle", - "clean install state": "Čistý stav instalace" + "clean install state": "Clean Install State", + "backup created": "Backup created", + "restore completed": "Restore completed", + "restore will include": "This will restore", + "restore warning": "This action cannot be undone. Continue?", + "reload to apply": "Reload to apply changes?", + "reload app": "Reload app", + "preparing backup": "Preparing backup", + "collecting settings": "Collecting settings", + "collecting key bindings": "Collecting key bindings", + "collecting plugins": "Collecting plugin information", + "creating backup": "Creating backup file", + "validating backup": "Validating backup", + "restoring key bindings": "Restoring key bindings", + "restoring plugins": "Restoring plugins", + "restoring settings": "Restoring settings", + "legacy backup warning": "This is an older backup format. Some features may be limited.", + "checksum mismatch": "Checksum mismatch - backup file may have been modified or corrupted.", + "plugin not found": "Plugin not found in registry", + "paid plugin skipped": "Paid plugin - purchase not found", + "source not found": "Source file no longer exists", + "restored": "Restored", + "skipped": "Skipped", + "backup not valid object": "Backup file is not a valid object", + "backup no data": "Backup file contains no data to restore", + "backup legacy warning": "This is an older backup format (v1). Some features may be limited.", + "backup missing metadata": "Missing backup metadata - some info may be unavailable", + "backup checksum mismatch": "Checksum mismatch - backup file may have been modified or corrupted. Proceed with caution.", + "backup checksum verify failed": "Could not verify checksum", + "backup invalid settings": "Invalid settings format", + "backup invalid keybindings": "Invalid keyBindings format", + "backup invalid plugins": "Invalid installedPlugins format", + "issues found": "Issues found", + "error details": "Error details" } diff --git a/src/lang/de-de.json b/src/lang/de-de.json index 44c35b38e..81e5c0fb6 100644 --- a/src/lang/de-de.json +++ b/src/lang/de-de.json @@ -454,5 +454,38 @@ "keywords": "Schlüsselwörter", "author": "Autor", "filtered by": "Gefiltert nach", - "clean install state": "Sauberer Installationsstatus" + "clean install state": "Clean Install State", + "backup created": "Backup created", + "restore completed": "Restore completed", + "restore will include": "This will restore", + "restore warning": "This action cannot be undone. Continue?", + "reload to apply": "Reload to apply changes?", + "reload app": "Reload app", + "preparing backup": "Preparing backup", + "collecting settings": "Collecting settings", + "collecting key bindings": "Collecting key bindings", + "collecting plugins": "Collecting plugin information", + "creating backup": "Creating backup file", + "validating backup": "Validating backup", + "restoring key bindings": "Restoring key bindings", + "restoring plugins": "Restoring plugins", + "restoring settings": "Restoring settings", + "legacy backup warning": "This is an older backup format. Some features may be limited.", + "checksum mismatch": "Checksum mismatch - backup file may have been modified or corrupted.", + "plugin not found": "Plugin not found in registry", + "paid plugin skipped": "Paid plugin - purchase not found", + "source not found": "Source file no longer exists", + "restored": "Restored", + "skipped": "Skipped", + "backup not valid object": "Backup file is not a valid object", + "backup no data": "Backup file contains no data to restore", + "backup legacy warning": "This is an older backup format (v1). Some features may be limited.", + "backup missing metadata": "Missing backup metadata - some info may be unavailable", + "backup checksum mismatch": "Checksum mismatch - backup file may have been modified or corrupted. Proceed with caution.", + "backup checksum verify failed": "Could not verify checksum", + "backup invalid settings": "Invalid settings format", + "backup invalid keybindings": "Invalid keyBindings format", + "backup invalid plugins": "Invalid installedPlugins format", + "issues found": "Issues found", + "error details": "Error details" } diff --git a/src/lang/en-us.json b/src/lang/en-us.json index b2fcbae24..6dbb8e75c 100644 --- a/src/lang/en-us.json +++ b/src/lang/en-us.json @@ -454,5 +454,38 @@ "keywords": "Keywords", "author": "Author", "filtered by": "Filtered by", - "clean install state": "Clean Install State" + "clean install state": "Clean Install State", + "backup created": "Backup created", + "restore completed": "Restore completed", + "restore will include": "This will restore", + "restore warning": "This action cannot be undone. Continue?", + "reload to apply": "Reload to apply changes?", + "reload app": "Reload app", + "preparing backup": "Preparing backup", + "collecting settings": "Collecting settings", + "collecting key bindings": "Collecting key bindings", + "collecting plugins": "Collecting plugin information", + "creating backup": "Creating backup file", + "validating backup": "Validating backup", + "restoring key bindings": "Restoring key bindings", + "restoring plugins": "Restoring plugins", + "restoring settings": "Restoring settings", + "legacy backup warning": "This is an older backup format. Some features may be limited.", + "checksum mismatch": "Checksum mismatch - backup file may have been modified or corrupted.", + "plugin not found": "Plugin not found in registry", + "paid plugin skipped": "Paid plugin - purchase not found", + "source not found": "Source file no longer exists", + "restored": "Restored", + "skipped": "Skipped", + "backup not valid object": "Backup file is not a valid object", + "backup no data": "Backup file contains no data to restore", + "backup legacy warning": "This is an older backup format (v1). Some features may be limited.", + "backup missing metadata": "Missing backup metadata - some info may be unavailable", + "backup checksum mismatch": "Checksum mismatch - backup file may have been modified or corrupted. Proceed with caution.", + "backup checksum verify failed": "Could not verify checksum", + "backup invalid settings": "Invalid settings format", + "backup invalid keybindings": "Invalid keyBindings format", + "backup invalid plugins": "Invalid installedPlugins format", + "issues found": "Issues found", + "error details": "Error details" } diff --git a/src/lang/es-sv.json b/src/lang/es-sv.json index b05eb6b57..43483cc4c 100644 --- a/src/lang/es-sv.json +++ b/src/lang/es-sv.json @@ -454,5 +454,38 @@ "keywords": "Keywords", "author": "Author", "filtered by": "Filtered by", - "clean install state": "Clean Install State" + "clean install state": "Clean Install State", + "backup created": "Backup created", + "restore completed": "Restore completed", + "restore will include": "This will restore", + "restore warning": "This action cannot be undone. Continue?", + "reload to apply": "Reload to apply changes?", + "reload app": "Reload app", + "preparing backup": "Preparing backup", + "collecting settings": "Collecting settings", + "collecting key bindings": "Collecting key bindings", + "collecting plugins": "Collecting plugin information", + "creating backup": "Creating backup file", + "validating backup": "Validating backup", + "restoring key bindings": "Restoring key bindings", + "restoring plugins": "Restoring plugins", + "restoring settings": "Restoring settings", + "legacy backup warning": "This is an older backup format. Some features may be limited.", + "checksum mismatch": "Checksum mismatch - backup file may have been modified or corrupted.", + "plugin not found": "Plugin not found in registry", + "paid plugin skipped": "Paid plugin - purchase not found", + "source not found": "Source file no longer exists", + "restored": "Restored", + "skipped": "Skipped", + "backup not valid object": "Backup file is not a valid object", + "backup no data": "Backup file contains no data to restore", + "backup legacy warning": "This is an older backup format (v1). Some features may be limited.", + "backup missing metadata": "Missing backup metadata - some info may be unavailable", + "backup checksum mismatch": "Checksum mismatch - backup file may have been modified or corrupted. Proceed with caution.", + "backup checksum verify failed": "Could not verify checksum", + "backup invalid settings": "Invalid settings format", + "backup invalid keybindings": "Invalid keyBindings format", + "backup invalid plugins": "Invalid installedPlugins format", + "issues found": "Issues found", + "error details": "Error details" } diff --git a/src/lang/fr-fr.json b/src/lang/fr-fr.json index ea5fe18c7..d05d5007b 100644 --- a/src/lang/fr-fr.json +++ b/src/lang/fr-fr.json @@ -454,5 +454,38 @@ "keywords": "Keywords", "author": "Author", "filtered by": "Filtered by", - "clean install state": "Clean Install State" + "clean install state": "Clean Install State", + "backup created": "Backup created", + "restore completed": "Restore completed", + "restore will include": "This will restore", + "restore warning": "This action cannot be undone. Continue?", + "reload to apply": "Reload to apply changes?", + "reload app": "Reload app", + "preparing backup": "Preparing backup", + "collecting settings": "Collecting settings", + "collecting key bindings": "Collecting key bindings", + "collecting plugins": "Collecting plugin information", + "creating backup": "Creating backup file", + "validating backup": "Validating backup", + "restoring key bindings": "Restoring key bindings", + "restoring plugins": "Restoring plugins", + "restoring settings": "Restoring settings", + "legacy backup warning": "This is an older backup format. Some features may be limited.", + "checksum mismatch": "Checksum mismatch - backup file may have been modified or corrupted.", + "plugin not found": "Plugin not found in registry", + "paid plugin skipped": "Paid plugin - purchase not found", + "source not found": "Source file no longer exists", + "restored": "Restored", + "skipped": "Skipped", + "backup not valid object": "Backup file is not a valid object", + "backup no data": "Backup file contains no data to restore", + "backup legacy warning": "This is an older backup format (v1). Some features may be limited.", + "backup missing metadata": "Missing backup metadata - some info may be unavailable", + "backup checksum mismatch": "Checksum mismatch - backup file may have been modified or corrupted. Proceed with caution.", + "backup checksum verify failed": "Could not verify checksum", + "backup invalid settings": "Invalid settings format", + "backup invalid keybindings": "Invalid keyBindings format", + "backup invalid plugins": "Invalid installedPlugins format", + "issues found": "Issues found", + "error details": "Error details" } diff --git a/src/lang/he-il.json b/src/lang/he-il.json index 28cbf14e0..62bacbda6 100644 --- a/src/lang/he-il.json +++ b/src/lang/he-il.json @@ -455,5 +455,38 @@ "keywords": "Keywords", "author": "Author", "filtered by": "Filtered by", - "clean install state": "Clean Install State" + "clean install state": "Clean Install State", + "backup created": "Backup created", + "restore completed": "Restore completed", + "restore will include": "This will restore", + "restore warning": "This action cannot be undone. Continue?", + "reload to apply": "Reload to apply changes?", + "reload app": "Reload app", + "preparing backup": "Preparing backup", + "collecting settings": "Collecting settings", + "collecting key bindings": "Collecting key bindings", + "collecting plugins": "Collecting plugin information", + "creating backup": "Creating backup file", + "validating backup": "Validating backup", + "restoring key bindings": "Restoring key bindings", + "restoring plugins": "Restoring plugins", + "restoring settings": "Restoring settings", + "legacy backup warning": "This is an older backup format. Some features may be limited.", + "checksum mismatch": "Checksum mismatch - backup file may have been modified or corrupted.", + "plugin not found": "Plugin not found in registry", + "paid plugin skipped": "Paid plugin - purchase not found", + "source not found": "Source file no longer exists", + "restored": "Restored", + "skipped": "Skipped", + "backup not valid object": "Backup file is not a valid object", + "backup no data": "Backup file contains no data to restore", + "backup legacy warning": "This is an older backup format (v1). Some features may be limited.", + "backup missing metadata": "Missing backup metadata - some info may be unavailable", + "backup checksum mismatch": "Checksum mismatch - backup file may have been modified or corrupted. Proceed with caution.", + "backup checksum verify failed": "Could not verify checksum", + "backup invalid settings": "Invalid settings format", + "backup invalid keybindings": "Invalid keyBindings format", + "backup invalid plugins": "Invalid installedPlugins format", + "issues found": "Issues found", + "error details": "Error details" } diff --git a/src/lang/hi-in.json b/src/lang/hi-in.json index dd19f0f85..95fbee698 100644 --- a/src/lang/hi-in.json +++ b/src/lang/hi-in.json @@ -455,5 +455,38 @@ "keywords": "Keywords", "author": "Author", "filtered by": "Filtered by", - "clean install state": "Clean Install State" + "clean install state": "Clean Install State", + "backup created": "Backup created", + "restore completed": "Restore completed", + "restore will include": "This will restore", + "restore warning": "This action cannot be undone. Continue?", + "reload to apply": "Reload to apply changes?", + "reload app": "Reload app", + "preparing backup": "Preparing backup", + "collecting settings": "Collecting settings", + "collecting key bindings": "Collecting key bindings", + "collecting plugins": "Collecting plugin information", + "creating backup": "Creating backup file", + "validating backup": "Validating backup", + "restoring key bindings": "Restoring key bindings", + "restoring plugins": "Restoring plugins", + "restoring settings": "Restoring settings", + "legacy backup warning": "This is an older backup format. Some features may be limited.", + "checksum mismatch": "Checksum mismatch - backup file may have been modified or corrupted.", + "plugin not found": "Plugin not found in registry", + "paid plugin skipped": "Paid plugin - purchase not found", + "source not found": "Source file no longer exists", + "restored": "Restored", + "skipped": "Skipped", + "backup not valid object": "Backup file is not a valid object", + "backup no data": "Backup file contains no data to restore", + "backup legacy warning": "This is an older backup format (v1). Some features may be limited.", + "backup missing metadata": "Missing backup metadata - some info may be unavailable", + "backup checksum mismatch": "Checksum mismatch - backup file may have been modified or corrupted. Proceed with caution.", + "backup checksum verify failed": "Could not verify checksum", + "backup invalid settings": "Invalid settings format", + "backup invalid keybindings": "Invalid keyBindings format", + "backup invalid plugins": "Invalid installedPlugins format", + "issues found": "Issues found", + "error details": "Error details" } diff --git a/src/lang/hu-hu.json b/src/lang/hu-hu.json index dbfede25e..5d23ca502 100644 --- a/src/lang/hu-hu.json +++ b/src/lang/hu-hu.json @@ -454,5 +454,38 @@ "keywords": "Kulcsszavak", "author": "Szerző", "filtered by": "Szűrési szempont", - "clean install state": "Tiszta telepítési állapot" + "clean install state": "Clean Install State", + "backup created": "Backup created", + "restore completed": "Restore completed", + "restore will include": "This will restore", + "restore warning": "This action cannot be undone. Continue?", + "reload to apply": "Reload to apply changes?", + "reload app": "Reload app", + "preparing backup": "Preparing backup", + "collecting settings": "Collecting settings", + "collecting key bindings": "Collecting key bindings", + "collecting plugins": "Collecting plugin information", + "creating backup": "Creating backup file", + "validating backup": "Validating backup", + "restoring key bindings": "Restoring key bindings", + "restoring plugins": "Restoring plugins", + "restoring settings": "Restoring settings", + "legacy backup warning": "This is an older backup format. Some features may be limited.", + "checksum mismatch": "Checksum mismatch - backup file may have been modified or corrupted.", + "plugin not found": "Plugin not found in registry", + "paid plugin skipped": "Paid plugin - purchase not found", + "source not found": "Source file no longer exists", + "restored": "Restored", + "skipped": "Skipped", + "backup not valid object": "Backup file is not a valid object", + "backup no data": "Backup file contains no data to restore", + "backup legacy warning": "This is an older backup format (v1). Some features may be limited.", + "backup missing metadata": "Missing backup metadata - some info may be unavailable", + "backup checksum mismatch": "Checksum mismatch - backup file may have been modified or corrupted. Proceed with caution.", + "backup checksum verify failed": "Could not verify checksum", + "backup invalid settings": "Invalid settings format", + "backup invalid keybindings": "Invalid keyBindings format", + "backup invalid plugins": "Invalid installedPlugins format", + "issues found": "Issues found", + "error details": "Error details" } diff --git a/src/lang/id-id.json b/src/lang/id-id.json index 63d478b06..bbcbc5785 100644 --- a/src/lang/id-id.json +++ b/src/lang/id-id.json @@ -455,5 +455,38 @@ "keywords": "Kata kunci", "author": "Pembuat", "filtered by": "Disaring oleh", - "clean install state": "Clean Install State" + "clean install state": "Clean Install State", + "backup created": "Backup created", + "restore completed": "Restore completed", + "restore will include": "This will restore", + "restore warning": "This action cannot be undone. Continue?", + "reload to apply": "Reload to apply changes?", + "reload app": "Reload app", + "preparing backup": "Preparing backup", + "collecting settings": "Collecting settings", + "collecting key bindings": "Collecting key bindings", + "collecting plugins": "Collecting plugin information", + "creating backup": "Creating backup file", + "validating backup": "Validating backup", + "restoring key bindings": "Restoring key bindings", + "restoring plugins": "Restoring plugins", + "restoring settings": "Restoring settings", + "legacy backup warning": "This is an older backup format. Some features may be limited.", + "checksum mismatch": "Checksum mismatch - backup file may have been modified or corrupted.", + "plugin not found": "Plugin not found in registry", + "paid plugin skipped": "Paid plugin - purchase not found", + "source not found": "Source file no longer exists", + "restored": "Restored", + "skipped": "Skipped", + "backup not valid object": "Backup file is not a valid object", + "backup no data": "Backup file contains no data to restore", + "backup legacy warning": "This is an older backup format (v1). Some features may be limited.", + "backup missing metadata": "Missing backup metadata - some info may be unavailable", + "backup checksum mismatch": "Checksum mismatch - backup file may have been modified or corrupted. Proceed with caution.", + "backup checksum verify failed": "Could not verify checksum", + "backup invalid settings": "Invalid settings format", + "backup invalid keybindings": "Invalid keyBindings format", + "backup invalid plugins": "Invalid installedPlugins format", + "issues found": "Issues found", + "error details": "Error details" } diff --git a/src/lang/ir-fa.json b/src/lang/ir-fa.json index 95ca111c1..99274c11a 100644 --- a/src/lang/ir-fa.json +++ b/src/lang/ir-fa.json @@ -455,5 +455,38 @@ "keywords": "Keywords", "author": "Author", "filtered by": "Filtered by", - "clean install state": "Clean Install State" + "clean install state": "Clean Install State", + "backup created": "Backup created", + "restore completed": "Restore completed", + "restore will include": "This will restore", + "restore warning": "This action cannot be undone. Continue?", + "reload to apply": "Reload to apply changes?", + "reload app": "Reload app", + "preparing backup": "Preparing backup", + "collecting settings": "Collecting settings", + "collecting key bindings": "Collecting key bindings", + "collecting plugins": "Collecting plugin information", + "creating backup": "Creating backup file", + "validating backup": "Validating backup", + "restoring key bindings": "Restoring key bindings", + "restoring plugins": "Restoring plugins", + "restoring settings": "Restoring settings", + "legacy backup warning": "This is an older backup format. Some features may be limited.", + "checksum mismatch": "Checksum mismatch - backup file may have been modified or corrupted.", + "plugin not found": "Plugin not found in registry", + "paid plugin skipped": "Paid plugin - purchase not found", + "source not found": "Source file no longer exists", + "restored": "Restored", + "skipped": "Skipped", + "backup not valid object": "Backup file is not a valid object", + "backup no data": "Backup file contains no data to restore", + "backup legacy warning": "This is an older backup format (v1). Some features may be limited.", + "backup missing metadata": "Missing backup metadata - some info may be unavailable", + "backup checksum mismatch": "Checksum mismatch - backup file may have been modified or corrupted. Proceed with caution.", + "backup checksum verify failed": "Could not verify checksum", + "backup invalid settings": "Invalid settings format", + "backup invalid keybindings": "Invalid keyBindings format", + "backup invalid plugins": "Invalid installedPlugins format", + "issues found": "Issues found", + "error details": "Error details" } diff --git a/src/lang/it-it.json b/src/lang/it-it.json index 9fbb2c7e5..f1960a29c 100644 --- a/src/lang/it-it.json +++ b/src/lang/it-it.json @@ -454,5 +454,38 @@ "keywords": "Keywords", "author": "Author", "filtered by": "Filtered by", - "clean install state": "Clean Install State" + "clean install state": "Clean Install State", + "backup created": "Backup created", + "restore completed": "Restore completed", + "restore will include": "This will restore", + "restore warning": "This action cannot be undone. Continue?", + "reload to apply": "Reload to apply changes?", + "reload app": "Reload app", + "preparing backup": "Preparing backup", + "collecting settings": "Collecting settings", + "collecting key bindings": "Collecting key bindings", + "collecting plugins": "Collecting plugin information", + "creating backup": "Creating backup file", + "validating backup": "Validating backup", + "restoring key bindings": "Restoring key bindings", + "restoring plugins": "Restoring plugins", + "restoring settings": "Restoring settings", + "legacy backup warning": "This is an older backup format. Some features may be limited.", + "checksum mismatch": "Checksum mismatch - backup file may have been modified or corrupted.", + "plugin not found": "Plugin not found in registry", + "paid plugin skipped": "Paid plugin - purchase not found", + "source not found": "Source file no longer exists", + "restored": "Restored", + "skipped": "Skipped", + "backup not valid object": "Backup file is not a valid object", + "backup no data": "Backup file contains no data to restore", + "backup legacy warning": "This is an older backup format (v1). Some features may be limited.", + "backup missing metadata": "Missing backup metadata - some info may be unavailable", + "backup checksum mismatch": "Checksum mismatch - backup file may have been modified or corrupted. Proceed with caution.", + "backup checksum verify failed": "Could not verify checksum", + "backup invalid settings": "Invalid settings format", + "backup invalid keybindings": "Invalid keyBindings format", + "backup invalid plugins": "Invalid installedPlugins format", + "issues found": "Issues found", + "error details": "Error details" } diff --git a/src/lang/ja-jp.json b/src/lang/ja-jp.json index 348172cfe..348fbc91c 100644 --- a/src/lang/ja-jp.json +++ b/src/lang/ja-jp.json @@ -454,5 +454,38 @@ "keywords": "Keywords", "author": "Author", "filtered by": "Filtered by", - "clean install state": "Clean Install State" + "clean install state": "Clean Install State", + "backup created": "Backup created", + "restore completed": "Restore completed", + "restore will include": "This will restore", + "restore warning": "This action cannot be undone. Continue?", + "reload to apply": "Reload to apply changes?", + "reload app": "Reload app", + "preparing backup": "Preparing backup", + "collecting settings": "Collecting settings", + "collecting key bindings": "Collecting key bindings", + "collecting plugins": "Collecting plugin information", + "creating backup": "Creating backup file", + "validating backup": "Validating backup", + "restoring key bindings": "Restoring key bindings", + "restoring plugins": "Restoring plugins", + "restoring settings": "Restoring settings", + "legacy backup warning": "This is an older backup format. Some features may be limited.", + "checksum mismatch": "Checksum mismatch - backup file may have been modified or corrupted.", + "plugin not found": "Plugin not found in registry", + "paid plugin skipped": "Paid plugin - purchase not found", + "source not found": "Source file no longer exists", + "restored": "Restored", + "skipped": "Skipped", + "backup not valid object": "Backup file is not a valid object", + "backup no data": "Backup file contains no data to restore", + "backup legacy warning": "This is an older backup format (v1). Some features may be limited.", + "backup missing metadata": "Missing backup metadata - some info may be unavailable", + "backup checksum mismatch": "Checksum mismatch - backup file may have been modified or corrupted. Proceed with caution.", + "backup checksum verify failed": "Could not verify checksum", + "backup invalid settings": "Invalid settings format", + "backup invalid keybindings": "Invalid keyBindings format", + "backup invalid plugins": "Invalid installedPlugins format", + "issues found": "Issues found", + "error details": "Error details" } diff --git a/src/lang/ko-kr.json b/src/lang/ko-kr.json index ae226c614..185b7aea6 100644 --- a/src/lang/ko-kr.json +++ b/src/lang/ko-kr.json @@ -454,5 +454,38 @@ "keywords": "Keywords", "author": "Author", "filtered by": "Filtered by", - "clean install state": "Clean Install State" + "clean install state": "Clean Install State", + "backup created": "Backup created", + "restore completed": "Restore completed", + "restore will include": "This will restore", + "restore warning": "This action cannot be undone. Continue?", + "reload to apply": "Reload to apply changes?", + "reload app": "Reload app", + "preparing backup": "Preparing backup", + "collecting settings": "Collecting settings", + "collecting key bindings": "Collecting key bindings", + "collecting plugins": "Collecting plugin information", + "creating backup": "Creating backup file", + "validating backup": "Validating backup", + "restoring key bindings": "Restoring key bindings", + "restoring plugins": "Restoring plugins", + "restoring settings": "Restoring settings", + "legacy backup warning": "This is an older backup format. Some features may be limited.", + "checksum mismatch": "Checksum mismatch - backup file may have been modified or corrupted.", + "plugin not found": "Plugin not found in registry", + "paid plugin skipped": "Paid plugin - purchase not found", + "source not found": "Source file no longer exists", + "restored": "Restored", + "skipped": "Skipped", + "backup not valid object": "Backup file is not a valid object", + "backup no data": "Backup file contains no data to restore", + "backup legacy warning": "This is an older backup format (v1). Some features may be limited.", + "backup missing metadata": "Missing backup metadata - some info may be unavailable", + "backup checksum mismatch": "Checksum mismatch - backup file may have been modified or corrupted. Proceed with caution.", + "backup checksum verify failed": "Could not verify checksum", + "backup invalid settings": "Invalid settings format", + "backup invalid keybindings": "Invalid keyBindings format", + "backup invalid plugins": "Invalid installedPlugins format", + "issues found": "Issues found", + "error details": "Error details" } diff --git a/src/lang/ml-in.json b/src/lang/ml-in.json index 56f551a6c..5d0c233b5 100644 --- a/src/lang/ml-in.json +++ b/src/lang/ml-in.json @@ -454,5 +454,38 @@ "keywords": "Keywords", "author": "Author", "filtered by": "Filtered by", - "clean install state": "Clean Install State" + "clean install state": "Clean Install State", + "backup created": "Backup created", + "restore completed": "Restore completed", + "restore will include": "This will restore", + "restore warning": "This action cannot be undone. Continue?", + "reload to apply": "Reload to apply changes?", + "reload app": "Reload app", + "preparing backup": "Preparing backup", + "collecting settings": "Collecting settings", + "collecting key bindings": "Collecting key bindings", + "collecting plugins": "Collecting plugin information", + "creating backup": "Creating backup file", + "validating backup": "Validating backup", + "restoring key bindings": "Restoring key bindings", + "restoring plugins": "Restoring plugins", + "restoring settings": "Restoring settings", + "legacy backup warning": "This is an older backup format. Some features may be limited.", + "checksum mismatch": "Checksum mismatch - backup file may have been modified or corrupted.", + "plugin not found": "Plugin not found in registry", + "paid plugin skipped": "Paid plugin - purchase not found", + "source not found": "Source file no longer exists", + "restored": "Restored", + "skipped": "Skipped", + "backup not valid object": "Backup file is not a valid object", + "backup no data": "Backup file contains no data to restore", + "backup legacy warning": "This is an older backup format (v1). Some features may be limited.", + "backup missing metadata": "Missing backup metadata - some info may be unavailable", + "backup checksum mismatch": "Checksum mismatch - backup file may have been modified or corrupted. Proceed with caution.", + "backup checksum verify failed": "Could not verify checksum", + "backup invalid settings": "Invalid settings format", + "backup invalid keybindings": "Invalid keyBindings format", + "backup invalid plugins": "Invalid installedPlugins format", + "issues found": "Issues found", + "error details": "Error details" } diff --git a/src/lang/mm-unicode.json b/src/lang/mm-unicode.json index b8b211fd8..175260b7b 100644 --- a/src/lang/mm-unicode.json +++ b/src/lang/mm-unicode.json @@ -454,5 +454,38 @@ "keywords": "Keywords", "author": "Author", "filtered by": "Filtered by", - "clean install state": "Clean Install State" + "clean install state": "Clean Install State", + "backup created": "Backup created", + "restore completed": "Restore completed", + "restore will include": "This will restore", + "restore warning": "This action cannot be undone. Continue?", + "reload to apply": "Reload to apply changes?", + "reload app": "Reload app", + "preparing backup": "Preparing backup", + "collecting settings": "Collecting settings", + "collecting key bindings": "Collecting key bindings", + "collecting plugins": "Collecting plugin information", + "creating backup": "Creating backup file", + "validating backup": "Validating backup", + "restoring key bindings": "Restoring key bindings", + "restoring plugins": "Restoring plugins", + "restoring settings": "Restoring settings", + "legacy backup warning": "This is an older backup format. Some features may be limited.", + "checksum mismatch": "Checksum mismatch - backup file may have been modified or corrupted.", + "plugin not found": "Plugin not found in registry", + "paid plugin skipped": "Paid plugin - purchase not found", + "source not found": "Source file no longer exists", + "restored": "Restored", + "skipped": "Skipped", + "backup not valid object": "Backup file is not a valid object", + "backup no data": "Backup file contains no data to restore", + "backup legacy warning": "This is an older backup format (v1). Some features may be limited.", + "backup missing metadata": "Missing backup metadata - some info may be unavailable", + "backup checksum mismatch": "Checksum mismatch - backup file may have been modified or corrupted. Proceed with caution.", + "backup checksum verify failed": "Could not verify checksum", + "backup invalid settings": "Invalid settings format", + "backup invalid keybindings": "Invalid keyBindings format", + "backup invalid plugins": "Invalid installedPlugins format", + "issues found": "Issues found", + "error details": "Error details" } diff --git a/src/lang/mm-zawgyi.json b/src/lang/mm-zawgyi.json index 5a57884a8..c310c6a1f 100644 --- a/src/lang/mm-zawgyi.json +++ b/src/lang/mm-zawgyi.json @@ -454,5 +454,38 @@ "keywords": "Keywords", "author": "Author", "filtered by": "Filtered by", - "clean install state": "Clean Install State" + "clean install state": "Clean Install State", + "backup created": "Backup created", + "restore completed": "Restore completed", + "restore will include": "This will restore", + "restore warning": "This action cannot be undone. Continue?", + "reload to apply": "Reload to apply changes?", + "reload app": "Reload app", + "preparing backup": "Preparing backup", + "collecting settings": "Collecting settings", + "collecting key bindings": "Collecting key bindings", + "collecting plugins": "Collecting plugin information", + "creating backup": "Creating backup file", + "validating backup": "Validating backup", + "restoring key bindings": "Restoring key bindings", + "restoring plugins": "Restoring plugins", + "restoring settings": "Restoring settings", + "legacy backup warning": "This is an older backup format. Some features may be limited.", + "checksum mismatch": "Checksum mismatch - backup file may have been modified or corrupted.", + "plugin not found": "Plugin not found in registry", + "paid plugin skipped": "Paid plugin - purchase not found", + "source not found": "Source file no longer exists", + "restored": "Restored", + "skipped": "Skipped", + "backup not valid object": "Backup file is not a valid object", + "backup no data": "Backup file contains no data to restore", + "backup legacy warning": "This is an older backup format (v1). Some features may be limited.", + "backup missing metadata": "Missing backup metadata - some info may be unavailable", + "backup checksum mismatch": "Checksum mismatch - backup file may have been modified or corrupted. Proceed with caution.", + "backup checksum verify failed": "Could not verify checksum", + "backup invalid settings": "Invalid settings format", + "backup invalid keybindings": "Invalid keyBindings format", + "backup invalid plugins": "Invalid installedPlugins format", + "issues found": "Issues found", + "error details": "Error details" } diff --git a/src/lang/pl-pl.json b/src/lang/pl-pl.json index f52669a16..9059bc685 100644 --- a/src/lang/pl-pl.json +++ b/src/lang/pl-pl.json @@ -454,5 +454,38 @@ "keywords": "Słowa kluczowe", "author": "Autor", "filtered by": "Filtrowane wg", - "clean install state": "Stan czystej instalacji" + "clean install state": "Clean Install State", + "backup created": "Backup created", + "restore completed": "Restore completed", + "restore will include": "This will restore", + "restore warning": "This action cannot be undone. Continue?", + "reload to apply": "Reload to apply changes?", + "reload app": "Reload app", + "preparing backup": "Preparing backup", + "collecting settings": "Collecting settings", + "collecting key bindings": "Collecting key bindings", + "collecting plugins": "Collecting plugin information", + "creating backup": "Creating backup file", + "validating backup": "Validating backup", + "restoring key bindings": "Restoring key bindings", + "restoring plugins": "Restoring plugins", + "restoring settings": "Restoring settings", + "legacy backup warning": "This is an older backup format. Some features may be limited.", + "checksum mismatch": "Checksum mismatch - backup file may have been modified or corrupted.", + "plugin not found": "Plugin not found in registry", + "paid plugin skipped": "Paid plugin - purchase not found", + "source not found": "Source file no longer exists", + "restored": "Restored", + "skipped": "Skipped", + "backup not valid object": "Backup file is not a valid object", + "backup no data": "Backup file contains no data to restore", + "backup legacy warning": "This is an older backup format (v1). Some features may be limited.", + "backup missing metadata": "Missing backup metadata - some info may be unavailable", + "backup checksum mismatch": "Checksum mismatch - backup file may have been modified or corrupted. Proceed with caution.", + "backup checksum verify failed": "Could not verify checksum", + "backup invalid settings": "Invalid settings format", + "backup invalid keybindings": "Invalid keyBindings format", + "backup invalid plugins": "Invalid installedPlugins format", + "issues found": "Issues found", + "error details": "Error details" } diff --git a/src/lang/pt-br.json b/src/lang/pt-br.json index 87fef2e18..a0a33ccb3 100644 --- a/src/lang/pt-br.json +++ b/src/lang/pt-br.json @@ -454,5 +454,38 @@ "keywords": "Palavras-chave", "author": "Autor", "filtered by": "Filtrado por", - "clean install state": "Estado de Instalação Limpa" + "clean install state": "Clean Install State", + "backup created": "Backup created", + "restore completed": "Restore completed", + "restore will include": "This will restore", + "restore warning": "This action cannot be undone. Continue?", + "reload to apply": "Reload to apply changes?", + "reload app": "Reload app", + "preparing backup": "Preparing backup", + "collecting settings": "Collecting settings", + "collecting key bindings": "Collecting key bindings", + "collecting plugins": "Collecting plugin information", + "creating backup": "Creating backup file", + "validating backup": "Validating backup", + "restoring key bindings": "Restoring key bindings", + "restoring plugins": "Restoring plugins", + "restoring settings": "Restoring settings", + "legacy backup warning": "This is an older backup format. Some features may be limited.", + "checksum mismatch": "Checksum mismatch - backup file may have been modified or corrupted.", + "plugin not found": "Plugin not found in registry", + "paid plugin skipped": "Paid plugin - purchase not found", + "source not found": "Source file no longer exists", + "restored": "Restored", + "skipped": "Skipped", + "backup not valid object": "Backup file is not a valid object", + "backup no data": "Backup file contains no data to restore", + "backup legacy warning": "This is an older backup format (v1). Some features may be limited.", + "backup missing metadata": "Missing backup metadata - some info may be unavailable", + "backup checksum mismatch": "Checksum mismatch - backup file may have been modified or corrupted. Proceed with caution.", + "backup checksum verify failed": "Could not verify checksum", + "backup invalid settings": "Invalid settings format", + "backup invalid keybindings": "Invalid keyBindings format", + "backup invalid plugins": "Invalid installedPlugins format", + "issues found": "Issues found", + "error details": "Error details" } diff --git a/src/lang/pu-in.json b/src/lang/pu-in.json index ff03fcb75..dbf06e1eb 100644 --- a/src/lang/pu-in.json +++ b/src/lang/pu-in.json @@ -454,5 +454,38 @@ "keywords": "Keywords", "author": "Author", "filtered by": "Filtered by", - "clean install state": "Clean Install State" + "clean install state": "Clean Install State", + "backup created": "Backup created", + "restore completed": "Restore completed", + "restore will include": "This will restore", + "restore warning": "This action cannot be undone. Continue?", + "reload to apply": "Reload to apply changes?", + "reload app": "Reload app", + "preparing backup": "Preparing backup", + "collecting settings": "Collecting settings", + "collecting key bindings": "Collecting key bindings", + "collecting plugins": "Collecting plugin information", + "creating backup": "Creating backup file", + "validating backup": "Validating backup", + "restoring key bindings": "Restoring key bindings", + "restoring plugins": "Restoring plugins", + "restoring settings": "Restoring settings", + "legacy backup warning": "This is an older backup format. Some features may be limited.", + "checksum mismatch": "Checksum mismatch - backup file may have been modified or corrupted.", + "plugin not found": "Plugin not found in registry", + "paid plugin skipped": "Paid plugin - purchase not found", + "source not found": "Source file no longer exists", + "restored": "Restored", + "skipped": "Skipped", + "backup not valid object": "Backup file is not a valid object", + "backup no data": "Backup file contains no data to restore", + "backup legacy warning": "This is an older backup format (v1). Some features may be limited.", + "backup missing metadata": "Missing backup metadata - some info may be unavailable", + "backup checksum mismatch": "Checksum mismatch - backup file may have been modified or corrupted. Proceed with caution.", + "backup checksum verify failed": "Could not verify checksum", + "backup invalid settings": "Invalid settings format", + "backup invalid keybindings": "Invalid keyBindings format", + "backup invalid plugins": "Invalid installedPlugins format", + "issues found": "Issues found", + "error details": "Error details" } diff --git a/src/lang/ru-ru.json b/src/lang/ru-ru.json index d7dcf31e7..5c2354729 100644 --- a/src/lang/ru-ru.json +++ b/src/lang/ru-ru.json @@ -454,5 +454,38 @@ "keywords": "Keywords", "author": "Author", "filtered by": "Filtered by", - "clean install state": "Clean Install State" + "clean install state": "Clean Install State", + "backup created": "Backup created", + "restore completed": "Restore completed", + "restore will include": "This will restore", + "restore warning": "This action cannot be undone. Continue?", + "reload to apply": "Reload to apply changes?", + "reload app": "Reload app", + "preparing backup": "Preparing backup", + "collecting settings": "Collecting settings", + "collecting key bindings": "Collecting key bindings", + "collecting plugins": "Collecting plugin information", + "creating backup": "Creating backup file", + "validating backup": "Validating backup", + "restoring key bindings": "Restoring key bindings", + "restoring plugins": "Restoring plugins", + "restoring settings": "Restoring settings", + "legacy backup warning": "This is an older backup format. Some features may be limited.", + "checksum mismatch": "Checksum mismatch - backup file may have been modified or corrupted.", + "plugin not found": "Plugin not found in registry", + "paid plugin skipped": "Paid plugin - purchase not found", + "source not found": "Source file no longer exists", + "restored": "Restored", + "skipped": "Skipped", + "backup not valid object": "Backup file is not a valid object", + "backup no data": "Backup file contains no data to restore", + "backup legacy warning": "This is an older backup format (v1). Some features may be limited.", + "backup missing metadata": "Missing backup metadata - some info may be unavailable", + "backup checksum mismatch": "Checksum mismatch - backup file may have been modified or corrupted. Proceed with caution.", + "backup checksum verify failed": "Could not verify checksum", + "backup invalid settings": "Invalid settings format", + "backup invalid keybindings": "Invalid keyBindings format", + "backup invalid plugins": "Invalid installedPlugins format", + "issues found": "Issues found", + "error details": "Error details" } diff --git a/src/lang/tl-ph.json b/src/lang/tl-ph.json index 1a7f24865..d87e885c9 100644 --- a/src/lang/tl-ph.json +++ b/src/lang/tl-ph.json @@ -454,5 +454,38 @@ "keywords": "Keywords", "author": "Author", "filtered by": "Filtered by", - "clean install state": "Clean Install State" + "clean install state": "Clean Install State", + "backup created": "Backup created", + "restore completed": "Restore completed", + "restore will include": "This will restore", + "restore warning": "This action cannot be undone. Continue?", + "reload to apply": "Reload to apply changes?", + "reload app": "Reload app", + "preparing backup": "Preparing backup", + "collecting settings": "Collecting settings", + "collecting key bindings": "Collecting key bindings", + "collecting plugins": "Collecting plugin information", + "creating backup": "Creating backup file", + "validating backup": "Validating backup", + "restoring key bindings": "Restoring key bindings", + "restoring plugins": "Restoring plugins", + "restoring settings": "Restoring settings", + "legacy backup warning": "This is an older backup format. Some features may be limited.", + "checksum mismatch": "Checksum mismatch - backup file may have been modified or corrupted.", + "plugin not found": "Plugin not found in registry", + "paid plugin skipped": "Paid plugin - purchase not found", + "source not found": "Source file no longer exists", + "restored": "Restored", + "skipped": "Skipped", + "backup not valid object": "Backup file is not a valid object", + "backup no data": "Backup file contains no data to restore", + "backup legacy warning": "This is an older backup format (v1). Some features may be limited.", + "backup missing metadata": "Missing backup metadata - some info may be unavailable", + "backup checksum mismatch": "Checksum mismatch - backup file may have been modified or corrupted. Proceed with caution.", + "backup checksum verify failed": "Could not verify checksum", + "backup invalid settings": "Invalid settings format", + "backup invalid keybindings": "Invalid keyBindings format", + "backup invalid plugins": "Invalid installedPlugins format", + "issues found": "Issues found", + "error details": "Error details" } diff --git a/src/lang/tr-tr.json b/src/lang/tr-tr.json index c1e7dd0b1..99e985945 100644 --- a/src/lang/tr-tr.json +++ b/src/lang/tr-tr.json @@ -454,5 +454,38 @@ "keywords": "Keywords", "author": "Author", "filtered by": "Filtered by", - "clean install state": "Clean Install State" + "clean install state": "Clean Install State", + "backup created": "Backup created", + "restore completed": "Restore completed", + "restore will include": "This will restore", + "restore warning": "This action cannot be undone. Continue?", + "reload to apply": "Reload to apply changes?", + "reload app": "Reload app", + "preparing backup": "Preparing backup", + "collecting settings": "Collecting settings", + "collecting key bindings": "Collecting key bindings", + "collecting plugins": "Collecting plugin information", + "creating backup": "Creating backup file", + "validating backup": "Validating backup", + "restoring key bindings": "Restoring key bindings", + "restoring plugins": "Restoring plugins", + "restoring settings": "Restoring settings", + "legacy backup warning": "This is an older backup format. Some features may be limited.", + "checksum mismatch": "Checksum mismatch - backup file may have been modified or corrupted.", + "plugin not found": "Plugin not found in registry", + "paid plugin skipped": "Paid plugin - purchase not found", + "source not found": "Source file no longer exists", + "restored": "Restored", + "skipped": "Skipped", + "backup not valid object": "Backup file is not a valid object", + "backup no data": "Backup file contains no data to restore", + "backup legacy warning": "This is an older backup format (v1). Some features may be limited.", + "backup missing metadata": "Missing backup metadata - some info may be unavailable", + "backup checksum mismatch": "Checksum mismatch - backup file may have been modified or corrupted. Proceed with caution.", + "backup checksum verify failed": "Could not verify checksum", + "backup invalid settings": "Invalid settings format", + "backup invalid keybindings": "Invalid keyBindings format", + "backup invalid plugins": "Invalid installedPlugins format", + "issues found": "Issues found", + "error details": "Error details" } diff --git a/src/lang/uk-ua.json b/src/lang/uk-ua.json index 4c69bd63e..446fad06a 100644 --- a/src/lang/uk-ua.json +++ b/src/lang/uk-ua.json @@ -454,5 +454,38 @@ "keywords": "Keywords", "author": "Author", "filtered by": "Filtered by", - "clean install state": "Clean Install State" + "clean install state": "Clean Install State", + "backup created": "Backup created", + "restore completed": "Restore completed", + "restore will include": "This will restore", + "restore warning": "This action cannot be undone. Continue?", + "reload to apply": "Reload to apply changes?", + "reload app": "Reload app", + "preparing backup": "Preparing backup", + "collecting settings": "Collecting settings", + "collecting key bindings": "Collecting key bindings", + "collecting plugins": "Collecting plugin information", + "creating backup": "Creating backup file", + "validating backup": "Validating backup", + "restoring key bindings": "Restoring key bindings", + "restoring plugins": "Restoring plugins", + "restoring settings": "Restoring settings", + "legacy backup warning": "This is an older backup format. Some features may be limited.", + "checksum mismatch": "Checksum mismatch - backup file may have been modified or corrupted.", + "plugin not found": "Plugin not found in registry", + "paid plugin skipped": "Paid plugin - purchase not found", + "source not found": "Source file no longer exists", + "restored": "Restored", + "skipped": "Skipped", + "backup not valid object": "Backup file is not a valid object", + "backup no data": "Backup file contains no data to restore", + "backup legacy warning": "This is an older backup format (v1). Some features may be limited.", + "backup missing metadata": "Missing backup metadata - some info may be unavailable", + "backup checksum mismatch": "Checksum mismatch - backup file may have been modified or corrupted. Proceed with caution.", + "backup checksum verify failed": "Could not verify checksum", + "backup invalid settings": "Invalid settings format", + "backup invalid keybindings": "Invalid keyBindings format", + "backup invalid plugins": "Invalid installedPlugins format", + "issues found": "Issues found", + "error details": "Error details" } diff --git a/src/lang/uz-uz.json b/src/lang/uz-uz.json index d39af9fb3..656f6ea11 100644 --- a/src/lang/uz-uz.json +++ b/src/lang/uz-uz.json @@ -454,5 +454,38 @@ "keywords": "Keywords", "author": "Author", "filtered by": "Filtered by", - "clean install state": "Clean Install State" + "clean install state": "Clean Install State", + "backup created": "Backup created", + "restore completed": "Restore completed", + "restore will include": "This will restore", + "restore warning": "This action cannot be undone. Continue?", + "reload to apply": "Reload to apply changes?", + "reload app": "Reload app", + "preparing backup": "Preparing backup", + "collecting settings": "Collecting settings", + "collecting key bindings": "Collecting key bindings", + "collecting plugins": "Collecting plugin information", + "creating backup": "Creating backup file", + "validating backup": "Validating backup", + "restoring key bindings": "Restoring key bindings", + "restoring plugins": "Restoring plugins", + "restoring settings": "Restoring settings", + "legacy backup warning": "This is an older backup format. Some features may be limited.", + "checksum mismatch": "Checksum mismatch - backup file may have been modified or corrupted.", + "plugin not found": "Plugin not found in registry", + "paid plugin skipped": "Paid plugin - purchase not found", + "source not found": "Source file no longer exists", + "restored": "Restored", + "skipped": "Skipped", + "backup not valid object": "Backup file is not a valid object", + "backup no data": "Backup file contains no data to restore", + "backup legacy warning": "This is an older backup format (v1). Some features may be limited.", + "backup missing metadata": "Missing backup metadata - some info may be unavailable", + "backup checksum mismatch": "Checksum mismatch - backup file may have been modified or corrupted. Proceed with caution.", + "backup checksum verify failed": "Could not verify checksum", + "backup invalid settings": "Invalid settings format", + "backup invalid keybindings": "Invalid keyBindings format", + "backup invalid plugins": "Invalid installedPlugins format", + "issues found": "Issues found", + "error details": "Error details" } diff --git a/src/lang/vi-vn.json b/src/lang/vi-vn.json index 3054398ea..a9144adc5 100644 --- a/src/lang/vi-vn.json +++ b/src/lang/vi-vn.json @@ -455,5 +455,38 @@ "keywords": "Keywords", "author": "Author", "filtered by": "Filtered by", - "clean install state": "Clean Install State" + "clean install state": "Clean Install State", + "backup created": "Backup created", + "restore completed": "Restore completed", + "restore will include": "This will restore", + "restore warning": "This action cannot be undone. Continue?", + "reload to apply": "Reload to apply changes?", + "reload app": "Reload app", + "preparing backup": "Preparing backup", + "collecting settings": "Collecting settings", + "collecting key bindings": "Collecting key bindings", + "collecting plugins": "Collecting plugin information", + "creating backup": "Creating backup file", + "validating backup": "Validating backup", + "restoring key bindings": "Restoring key bindings", + "restoring plugins": "Restoring plugins", + "restoring settings": "Restoring settings", + "legacy backup warning": "This is an older backup format. Some features may be limited.", + "checksum mismatch": "Checksum mismatch - backup file may have been modified or corrupted.", + "plugin not found": "Plugin not found in registry", + "paid plugin skipped": "Paid plugin - purchase not found", + "source not found": "Source file no longer exists", + "restored": "Restored", + "skipped": "Skipped", + "backup not valid object": "Backup file is not a valid object", + "backup no data": "Backup file contains no data to restore", + "backup legacy warning": "This is an older backup format (v1). Some features may be limited.", + "backup missing metadata": "Missing backup metadata - some info may be unavailable", + "backup checksum mismatch": "Checksum mismatch - backup file may have been modified or corrupted. Proceed with caution.", + "backup checksum verify failed": "Could not verify checksum", + "backup invalid settings": "Invalid settings format", + "backup invalid keybindings": "Invalid keyBindings format", + "backup invalid plugins": "Invalid installedPlugins format", + "issues found": "Issues found", + "error details": "Error details" } diff --git a/src/lang/zh-cn.json b/src/lang/zh-cn.json index 92a1aa225..59592447f 100644 --- a/src/lang/zh-cn.json +++ b/src/lang/zh-cn.json @@ -454,5 +454,38 @@ "keywords": "关键字", "author": "作者", "filtered by": "过滤条件", - "clean install state": "Clean Install State" + "clean install state": "Clean Install State", + "backup created": "Backup created", + "restore completed": "Restore completed", + "restore will include": "This will restore", + "restore warning": "This action cannot be undone. Continue?", + "reload to apply": "Reload to apply changes?", + "reload app": "Reload app", + "preparing backup": "Preparing backup", + "collecting settings": "Collecting settings", + "collecting key bindings": "Collecting key bindings", + "collecting plugins": "Collecting plugin information", + "creating backup": "Creating backup file", + "validating backup": "Validating backup", + "restoring key bindings": "Restoring key bindings", + "restoring plugins": "Restoring plugins", + "restoring settings": "Restoring settings", + "legacy backup warning": "This is an older backup format. Some features may be limited.", + "checksum mismatch": "Checksum mismatch - backup file may have been modified or corrupted.", + "plugin not found": "Plugin not found in registry", + "paid plugin skipped": "Paid plugin - purchase not found", + "source not found": "Source file no longer exists", + "restored": "Restored", + "skipped": "Skipped", + "backup not valid object": "Backup file is not a valid object", + "backup no data": "Backup file contains no data to restore", + "backup legacy warning": "This is an older backup format (v1). Some features may be limited.", + "backup missing metadata": "Missing backup metadata - some info may be unavailable", + "backup checksum mismatch": "Checksum mismatch - backup file may have been modified or corrupted. Proceed with caution.", + "backup checksum verify failed": "Could not verify checksum", + "backup invalid settings": "Invalid settings format", + "backup invalid keybindings": "Invalid keyBindings format", + "backup invalid plugins": "Invalid installedPlugins format", + "issues found": "Issues found", + "error details": "Error details" } diff --git a/src/lang/zh-hant.json b/src/lang/zh-hant.json index 990257b60..51ab570ae 100644 --- a/src/lang/zh-hant.json +++ b/src/lang/zh-hant.json @@ -454,5 +454,38 @@ "keywords": "關鍵字", "author": "作者", "filtered by": "篩選條件", - "clean install state": "Clean Install State" + "clean install state": "Clean Install State", + "backup created": "Backup created", + "restore completed": "Restore completed", + "restore will include": "This will restore", + "restore warning": "This action cannot be undone. Continue?", + "reload to apply": "Reload to apply changes?", + "reload app": "Reload app", + "preparing backup": "Preparing backup", + "collecting settings": "Collecting settings", + "collecting key bindings": "Collecting key bindings", + "collecting plugins": "Collecting plugin information", + "creating backup": "Creating backup file", + "validating backup": "Validating backup", + "restoring key bindings": "Restoring key bindings", + "restoring plugins": "Restoring plugins", + "restoring settings": "Restoring settings", + "legacy backup warning": "This is an older backup format. Some features may be limited.", + "checksum mismatch": "Checksum mismatch - backup file may have been modified or corrupted.", + "plugin not found": "Plugin not found in registry", + "paid plugin skipped": "Paid plugin - purchase not found", + "source not found": "Source file no longer exists", + "restored": "Restored", + "skipped": "Skipped", + "backup not valid object": "Backup file is not a valid object", + "backup no data": "Backup file contains no data to restore", + "backup legacy warning": "This is an older backup format (v1). Some features may be limited.", + "backup missing metadata": "Missing backup metadata - some info may be unavailable", + "backup checksum mismatch": "Checksum mismatch - backup file may have been modified or corrupted. Proceed with caution.", + "backup checksum verify failed": "Could not verify checksum", + "backup invalid settings": "Invalid settings format", + "backup invalid keybindings": "Invalid keyBindings format", + "backup invalid plugins": "Invalid installedPlugins format", + "issues found": "Issues found", + "error details": "Error details" } diff --git a/src/lang/zh-tw.json b/src/lang/zh-tw.json index 5f068530a..21f42f67a 100644 --- a/src/lang/zh-tw.json +++ b/src/lang/zh-tw.json @@ -454,5 +454,38 @@ "keywords": "Keywords", "author": "Author", "filtered by": "Filtered by", - "clean install state": "Clean Install State" + "clean install state": "Clean Install State", + "backup created": "Backup created", + "restore completed": "Restore completed", + "restore will include": "This will restore", + "restore warning": "This action cannot be undone. Continue?", + "reload to apply": "Reload to apply changes?", + "reload app": "Reload app", + "preparing backup": "Preparing backup", + "collecting settings": "Collecting settings", + "collecting key bindings": "Collecting key bindings", + "collecting plugins": "Collecting plugin information", + "creating backup": "Creating backup file", + "validating backup": "Validating backup", + "restoring key bindings": "Restoring key bindings", + "restoring plugins": "Restoring plugins", + "restoring settings": "Restoring settings", + "legacy backup warning": "This is an older backup format. Some features may be limited.", + "checksum mismatch": "Checksum mismatch - backup file may have been modified or corrupted.", + "plugin not found": "Plugin not found in registry", + "paid plugin skipped": "Paid plugin - purchase not found", + "source not found": "Source file no longer exists", + "restored": "Restored", + "skipped": "Skipped", + "backup not valid object": "Backup file is not a valid object", + "backup no data": "Backup file contains no data to restore", + "backup legacy warning": "This is an older backup format (v1). Some features may be limited.", + "backup missing metadata": "Missing backup metadata - some info may be unavailable", + "backup checksum mismatch": "Checksum mismatch - backup file may have been modified or corrupted. Proceed with caution.", + "backup checksum verify failed": "Could not verify checksum", + "backup invalid settings": "Invalid settings format", + "backup invalid keybindings": "Invalid keyBindings format", + "backup invalid plugins": "Invalid installedPlugins format", + "issues found": "Issues found", + "error details": "Error details" } diff --git a/src/settings/backupRestore.js b/src/settings/backupRestore.js index 522d572c8..a181c2d47 100644 --- a/src/settings/backupRestore.js +++ b/src/settings/backupRestore.js @@ -2,6 +2,8 @@ import fsOperation from "fileSystem"; import settingsPage from "components/settingsPage"; import toast from "components/toast"; import alert from "dialogs/alert"; +import confirm from "dialogs/confirm"; +import loader from "dialogs/loader"; import constants from "lib/constants"; import appSettings from "lib/settings"; import FileBrowser from "pages/fileBrowser"; @@ -9,6 +11,129 @@ import helpers from "utils/helpers"; import Uri from "utils/Uri"; import Url from "utils/Url"; +// Backup format version for future compatibility +const BACKUP_VERSION = 2; + +/** + * CRC32 lookup table for checksum calculation + */ +const CRC32_TABLE = (() => { + const table = new Uint32Array(256); + for (let i = 0; i < 256; i++) { + let crc = i; + for (let j = 0; j < 8; j++) { + crc = crc & 1 ? 0xedb88320 ^ (crc >>> 1) : crc >>> 1; + } + table[i] = crc >>> 0; + } + return table; +})(); + +/** + * Generates a CRC32 checksum for data integrity verification + * More robust than simple hash for detecting corrupted data + * @param {string} data + * @returns {string} + */ +function generateChecksum(data) { + let crc = 0xffffffff; + for (let i = 0; i < data.length; i++) { + const byte = data.charCodeAt(i) & 0xff; + crc = CRC32_TABLE[(crc ^ byte) & 0xff] ^ (crc >>> 8); + } + return ((crc ^ 0xffffffff) >>> 0).toString(16).padStart(8, "0"); +} + +/** + * Validates the structure of a backup object + * Supports both v1 (legacy) and v2 (new) backup formats + * @param {object} backup + * @returns {{valid: boolean, errors: string[], warnings: string[], isLegacy: boolean}} + */ +function validateBackupStructure(backup) { + const errors = []; + const warnings = []; + + if (!backup || typeof backup !== "object") { + errors.push(strings["backup not valid object"]); + return { valid: false, errors, warnings, isLegacy: false }; + } + + // Determine if this is a legacy (v1) backup + const isLegacy = !backup.version; + + if (isLegacy) { + // Legacy backup (v1) - just needs settings or installedPlugins to be valid + const hasData = + backup.settings || backup.keyBindings || backup.installedPlugins; + if (!hasData) { + errors.push(strings["backup no data"]); + } + warnings.push(strings["backup legacy warning"]); + } else { + // Version 2+ backup + if (backup.version >= 2) { + if (!backup.metadata) { + warnings.push(strings["backup missing metadata"]); + } + + // Verify checksum if present + if (backup.checksum) { + try { + const dataToCheck = JSON.stringify({ + settings: backup.settings, + keyBindings: backup.keyBindings, + installedPlugins: backup.installedPlugins, + }); + const expectedChecksum = generateChecksum(dataToCheck); + if (backup.checksum !== expectedChecksum) { + warnings.push(strings["backup checksum mismatch"]); + } + } catch (e) { + warnings.push(strings["backup checksum verify failed"]); + } + } + } + } + + // Validate settings (both versions) + if (backup.settings !== undefined && typeof backup.settings !== "object") { + errors.push(strings["backup invalid settings"]); + } + + // Validate keyBindings (both versions) + if ( + backup.keyBindings !== undefined && + typeof backup.keyBindings !== "object" + ) { + errors.push(strings["backup invalid keybindings"]); + } + + // Validate installedPlugins (both versions) + if ( + backup.installedPlugins !== undefined && + !Array.isArray(backup.installedPlugins) + ) { + errors.push(strings["backup invalid plugins"]); + } + + return { valid: errors.length === 0, errors, warnings, isLegacy }; +} + +/** + * Formats a date for backup filename + * @param {Date} date + * @returns {string} + */ +function formatDateForFilename(date) { + const year = date.getFullYear(); + const month = String(date.getMonth() + 1).padStart(2, "0"); + const day = String(date.getDate()).padStart(2, "0"); + const hours = String(date.getHours()).padStart(2, "0"); + const minutes = String(date.getMinutes()).padStart(2, "0"); + return `${year}${month}${day}_${hours}${minutes}`; +} + function backupRestore() { const title = strings.backup.capitalize() + "/" + strings.restore.capitalize(); @@ -46,35 +171,91 @@ function backupRestore() { } async function backup() { + const loaderDialog = loader.create( + strings.backup.capitalize(), + strings["preparing backup"], + ); + try { + loaderDialog.show(); + loaderDialog.setMessage(strings["collecting settings"]); + const settings = appSettings.value; - const keyBindings = await fsOperation(KEYBINDING_FILE).readFile("json"); - const plugins = await fsOperation(window.PLUGIN_DIR).lsDir(); + + // Read keybindings with fallback + loaderDialog.setMessage(strings["collecting key bindings"]); + let keyBindings = null; + try { + const keybindingsFS = fsOperation(KEYBINDING_FILE); + if (await keybindingsFS.exists()) { + keyBindings = await keybindingsFS.readFile("json"); + } + } catch (error) { + console.warn("Could not read keybindings:", error); + } + + // Collect plugin information + loaderDialog.setMessage(strings["collecting plugins"]); const installedPlugins = []; - const installedPluginsWithSource = []; + const pluginDetails = []; - for (const plugin of plugins) { - try { - const pluginJsonPath = Url.join( - window.PLUGIN_DIR, - plugin.name, - "plugin.json", - ); - const pluginJson = await fsOperation(pluginJsonPath).readFile("json"); + try { + const pluginsDir = fsOperation(window.PLUGIN_DIR); + if (await pluginsDir.exists()) { + const plugins = await pluginsDir.lsDir(); - if (pluginJson.source) { - installedPluginsWithSource.push(pluginJson.source); - } else { - installedPlugins.push(plugin.name); + for (const plugin of plugins) { + try { + const pluginJsonPath = Url.join( + window.PLUGIN_DIR, + plugin.name, + "plugin.json", + ); + const pluginJson = + await fsOperation(pluginJsonPath).readFile("json"); + + // Store detailed plugin info for better restore + const pluginInfo = { + id: pluginJson.id || plugin.name, + name: pluginJson.name || plugin.name, + version: pluginJson.version || "unknown", + source: pluginJson.source || null, + }; + pluginDetails.push(pluginInfo); + + if (pluginJson.source) { + installedPlugins.push(pluginJson.source); + } else { + installedPlugins.push(pluginJson.id || plugin.name); + } + } catch (error) { + // Fallback to just plugin name + installedPlugins.push(plugin.name); + pluginDetails.push({ + id: plugin.name, + name: plugin.name, + version: "unknown", + source: null, + }); + } } - } catch (error) { - installedPlugins.push(plugin.name); } + } catch (error) { + console.warn("Could not read plugins directory:", error); } + loaderDialog.hide(); + + // Get destination folder const { url } = await FileBrowser("folder", strings["select folder"]); - const backupFilename = "Acode.backup"; + loaderDialog.show(); + loaderDialog.setMessage( + strings["creating backup"] || "Creating backup file...", + ); + + const timestamp = formatDateForFilename(new Date()); + const backupFilename = `Acode_backup_${timestamp}.backup`; const backupDirname = "Backup"; const backupDir = Url.join(url, backupDirname); const backupFile = Url.join(backupDir, backupFilename); @@ -82,31 +263,62 @@ function backupRestore() { const backupDirFS = fsOperation(backupDir); const backupFileFS = fsOperation(backupFile); + // Create backup directory if needed if (!(await backupDirFS.exists())) { await backupStorageFS.createDirectory(backupDirname); } + // Create backup file if (!(await backupFileFS.exists())) { await backupDirFS.createFile(backupFilename); } - const backupString = JSON.stringify({ + // Prepare backup data with checksum + const backupData = { + settings, + keyBindings, + installedPlugins, + }; + + const checksum = generateChecksum(JSON.stringify(backupData)); + + const backupObject = { + version: BACKUP_VERSION, + metadata: { + createdAt: new Date().toISOString(), + appVersion: BuildInfo?.version || "unknown", + pluginCount: installedPlugins.length, + hasSettings: !!settings, + hasKeyBindings: !!keyBindings, + }, + checksum, settings, keyBindings, - installedPlugins: [...installedPlugins, ...installedPluginsWithSource], - }); + installedPlugins, + pluginDetails, // Extra detail for better restoration info + }; + const backupString = JSON.stringify(backupObject, null, 2); await backupFileFS.writeFile(backupString); + loaderDialog.destroy(); + + const message = [ + strings["backup successful"], + `
${Uri.getVirtualAddress(backupFile)}
`, + `${strings.settings || "Settings"}: ✓`, + `${strings["key bindings"] || "Key Bindings"}: ${keyBindings ? "✓" : "-"}`, + `${strings.plugins || "Plugins"}: ${installedPlugins.length}`, + ].join("
"); + + alert(strings.success.toUpperCase(), message); + } catch (error) { + loaderDialog.destroy(); + console.error("Backup error:", error); alert( - strings.success.toUpperCase(), - `${strings["backup successful"]}\n${Uri.getVirtualAddress( - backupFile, - )}.`, + strings.error.toUpperCase(), + `${strings["error details"] || "Error"}: ${error.message || error}`, ); - } catch (error) { - console.error(error); - toast(error); } } @@ -115,93 +327,365 @@ function backupRestore() { (data) => { backupRestore.restore(data.uri); }, - toast, + (error) => { + console.error("File picker error:", error); + toast(strings.error || "Error selecting file"); + }, "application/octet-stream", ); } } backupRestore.restore = async function (url) { + const loaderDialog = loader.create( + strings.restore.capitalize(), + strings["please wait..."], + ); + + const restoreResults = { + settings: { attempted: false, success: false, error: null }, + keyBindings: { attempted: false, success: false, error: null }, + plugins: { attempted: false, success: [], failed: [], skipped: [] }, + }; + try { - let fs = fsOperation(url); - let backup = await fs.readFile("utf8"); + loaderDialog.show(); + + // Read and parse backup file + const fs = fsOperation(url); + let backupContent; try { - backup = JSON.parse(backup); + backupContent = await fs.readFile("utf8"); } catch (error) { - alert(strings.error.toUpperCase(), strings["invalid backup file"]); - return; + throw new Error(`Could not read backup file: ${error.message}`); } + let backup; try { - const text = JSON.stringify(backup.keyBindings, undefined, 2); - await fsOperation(window.KEYBINDING_FILE).writeFile(text); + backup = JSON.parse(backupContent); } catch (error) { - console.error("Error restoring key bindings:", error); + loaderDialog.destroy(); + alert(strings.error.toUpperCase(), strings["invalid backup file"]); + return; + } + + // Validate backup structure + loaderDialog.setMessage(strings["validating backup"]); + const validation = validateBackupStructure(backup); + + if (!validation.valid) { + loaderDialog.destroy(); + const errorMessage = [ + strings["invalid backup file"], + "", + `${strings["issues found"]}:`, + ...validation.errors.map((e) => `• ${e}`), + ].join("\n"); + alert(strings.error.toUpperCase(), errorMessage); + return; + } + + loaderDialog.hide(); + + // Show backup info and ask for confirmation + const backupInfo = backup.metadata || {}; + const confirmParts = [ + `${strings["restore will include"]}

`, + `${strings.settings}: ${backup.settings ? strings.yes : strings.no}
`, + `${strings["key bindings"]}: ${backup.keyBindings ? strings.yes : strings.no}
`, + `${strings.plugins}: ${backup.installedPlugins?.length || 0}
`, + ]; + + if (backupInfo.createdAt) { + confirmParts.push( + `
${strings["last modified"]}: ${new Date(backupInfo.createdAt).toLocaleString()}
`, + ); + } + + // Show warnings if any (legacy backup, checksum issues, etc.) + if (validation.warnings && validation.warnings.length > 0) { + confirmParts.push(`
${strings.warning}:
`); + for (const warning of validation.warnings) { + confirmParts.push(`- ${warning}
`); + } + } + + confirmParts.push(`
${strings["restore warning"]}`); + + const shouldContinue = await confirm( + strings.restore.capitalize(), + confirmParts.join(""), + true, + ); + + if (!shouldContinue) { + return; } - const { settings, installedPlugins } = backup; + // What to restore - restore everything available + const selectedOptions = []; + if (backup.settings) selectedOptions.push("settings"); + if (backup.keyBindings) selectedOptions.push("keyBindings"); + if (backup.installedPlugins?.length) selectedOptions.push("plugins"); + + loaderDialog.show(); - const { default: installPlugin } = await import("lib/installPlugin"); + // Restore key bindings first (before settings, in case of reload) + if (selectedOptions.includes("keyBindings") && backup.keyBindings) { + restoreResults.keyBindings.attempted = true; + loaderDialog.setMessage(strings["restoring key bindings"]); + + try { + const keybindingsFS = fsOperation(window.KEYBINDING_FILE); + + // Ensure file exists + if (!(await keybindingsFS.exists())) { + const parentDir = fsOperation(DATA_STORAGE); + await parentDir.createFile(".key-bindings.json"); + } + + const text = JSON.stringify(backup.keyBindings, undefined, 2); + await keybindingsFS.writeFile(text); + restoreResults.keyBindings.success = true; + } catch (error) { + console.error("Error restoring key bindings:", error); + restoreResults.keyBindings.error = error.message; + } + } // Restore plugins - if (Array.isArray(installedPlugins)) { - for (const id of installedPlugins) { + if ( + selectedOptions.includes("plugins") && + Array.isArray(backup.installedPlugins) && + backup.installedPlugins.length > 0 + ) { + restoreResults.plugins.attempted = true; + const { default: installPlugin } = await import("lib/installPlugin"); + + const totalPlugins = backup.installedPlugins.length; + let currentPlugin = 0; + + for (const id of backup.installedPlugins) { + currentPlugin++; + + if (!id) { + restoreResults.plugins.skipped.push({ + id: "(empty)", + reason: "Empty plugin ID", + }); + continue; + } + + const pluginName = + backup.pluginDetails?.find((p) => p.id === id || p.source === id) + ?.name || id; + + loaderDialog.setMessage( + `${strings["restoring plugins"]} (${currentPlugin}/${totalPlugins}): ${pluginName}`, + ); + try { - if (!id) continue; if ( id.startsWith("content://") || id.startsWith("file://") || id.includes("/") ) { - // Local plugin case - pass URI directly - toast("Restoring plugins"); - await installPlugin(id); + // Local plugin case + try { + // Check if the source file still exists + const sourceFS = fsOperation(id); + if (!(await sourceFS.exists())) { + restoreResults.plugins.skipped.push({ + id: pluginName, + reason: strings["source not found"], + }); + continue; + } + await installPlugin(id); + restoreResults.plugins.success.push(pluginName); + } catch (error) { + restoreResults.plugins.failed.push({ + id: pluginName, + reason: error.message, + }); + } } else { // Remote plugin case - fetch from API const pluginUrl = Url.join(constants.API_BASE, `plugin/${id}`); - const remotePlugin = await fsOperation(pluginUrl) - .readFile("json") - .catch(() => null); + let remotePlugin = null; + + try { + remotePlugin = await fsOperation(pluginUrl).readFile("json"); + } catch (error) { + restoreResults.plugins.failed.push({ + id: pluginName, + reason: strings["plugin not found"], + }); + continue; + } if (remotePlugin) { let purchaseToken = null; - if (Number.parseFloat(remotePlugin.price) > 0) { + const isPaid = Number.parseFloat(remotePlugin.price) > 0; + + if (isPaid) { try { const [product] = await helpers.promisify(iap.getProducts, [ remotePlugin.sku, ]); if (product) { - async function getPurchase(sku) { - const purchases = await helpers.promisify( - iap.getPurchases, - ); - const purchase = purchases.find((p) => - p.productIds.includes(sku), - ); - return purchase; - } - const purchase = await getPurchase(product.productId); + const purchases = await helpers.promisify(iap.getPurchases); + const purchase = purchases.find((p) => + p.productIds.includes(product.productId), + ); purchaseToken = purchase?.purchaseToken; } + + if (!purchaseToken) { + restoreResults.plugins.skipped.push({ + id: pluginName, + reason: strings["paid plugin skipped"], + }); + continue; + } } catch (error) { - helpers.error(error); + restoreResults.plugins.skipped.push({ + id: pluginName, + reason: `Paid plugin - ${error.message}`, + }); + continue; } } - toast("Restoring plugins", 3000); - await installPlugin(id, remotePlugin.name, purchaseToken); + + try { + await installPlugin(id, remotePlugin.name, purchaseToken); + restoreResults.plugins.success.push(pluginName); + } catch (error) { + restoreResults.plugins.failed.push({ + id: pluginName, + reason: error.message, + }); + } } } } catch (error) { console.error(`Error restoring plugin ${id}:`, error); + restoreResults.plugins.failed.push({ + id: pluginName, + reason: error.message, + }); + } + } + } + + // Restore settings last (may trigger reload) + if (selectedOptions.includes("settings") && backup.settings) { + restoreResults.settings.attempted = true; + loaderDialog.setMessage(strings["restoring settings"]); + + try { + // Validate and merge settings carefully + const currentSettings = appSettings.value; + const restoredSettings = backup.settings; + + // Only restore known settings keys to prevent issues with outdated backups + const validSettings = {}; + for (const key of Object.keys(currentSettings)) { + if (key in restoredSettings) { + // Type check before applying + if (typeof restoredSettings[key] === typeof currentSettings[key]) { + validSettings[key] = restoredSettings[key]; + } + } } + + await appSettings.update(validSettings, false); + restoreResults.settings.success = true; + } catch (error) { + console.error("Error restoring settings:", error); + restoreResults.settings.error = error.message; } } - await appSettings.update(settings); - location.reload(); + loaderDialog.destroy(); + + // Build restore summary + const summaryParts = [ + `${strings["restore completed"]}

`, + ]; + + if (restoreResults.settings.attempted) { + const status = restoreResults.settings.success + ? `✓ ${strings.restored}` + : `✗ ${strings.failed}`; + summaryParts.push(`${strings.settings}: ${status}
`); + } + + if (restoreResults.keyBindings.attempted) { + const status = restoreResults.keyBindings.success + ? `✓ ${strings.restored}` + : `✗ ${strings.failed}`; + summaryParts.push(`${strings["key bindings"]}: ${status}
`); + } + + if (restoreResults.plugins.attempted) { + summaryParts.push(`
${strings.plugins}
`); + + if (restoreResults.plugins.success.length > 0) { + summaryParts.push( + `✓ ${strings.restored}: ${restoreResults.plugins.success.length}
`, + ); + } + + if (restoreResults.plugins.failed.length > 0) { + summaryParts.push( + `✗ ${strings.failed}: ${restoreResults.plugins.failed.length}
`, + ); + for (const f of restoreResults.plugins.failed.slice(0, 3)) { + summaryParts.push(`- ${f.id}: ${f.reason}
`); + } + if (restoreResults.plugins.failed.length > 3) { + summaryParts.push( + `...${strings.more || "and"} ${restoreResults.plugins.failed.length - 3} ${strings.more || "more"}
`, + ); + } + } + + if (restoreResults.plugins.skipped.length > 0) { + summaryParts.push( + `${strings.skipped}: ${restoreResults.plugins.skipped.length}
`, + ); + for (const s of restoreResults.plugins.skipped.slice(0, 3)) { + summaryParts.push(`- ${s.id}: ${s.reason}
`); + } + if (restoreResults.plugins.skipped.length > 3) { + summaryParts.push( + `...${strings.more} ${restoreResults.plugins.skipped.length - 3} ${strings.more}
`, + ); + } + } + } + + summaryParts.push(`
${strings["reload to apply"]}`); + + const shouldReload = await confirm( + strings["restore completed"], + summaryParts.join(""), + true, + ); + + // Reload only if user confirms + if (shouldReload) { + location.reload(); + } } catch (err) { - toast(err); + loaderDialog.destroy(); + console.error("Restore error:", err); + alert( + strings.error.toUpperCase(), + `${strings["error details"]}: ${err.message || err}`, + ); } }; diff --git a/utils/lang.js b/utils/lang.js index a3f76f7fc..d3390e426 100755 --- a/utils/lang.js +++ b/utils/lang.js @@ -4,7 +4,9 @@ const yargs = require("yargs"); const { hideBin } = require("yargs/helpers"); const readline = require("node:readline"); -const args = yargs(hideBin(process.argv)).alias("a", "all").argv; +const args = yargs(hideBin(process.argv)) + .alias("a", "all") + .alias("b", "bulk").argv; const dir = path.resolve(__dirname, "../src/lang"); const read = readline.createInterface({ input: process.stdin, @@ -35,9 +37,17 @@ switch (command) { case "check": update(); break; + case "add-all": + addToAllFiles(); + break; + case "bulk-add": + bulkAddStrings(); + break; default: console.error(`Missing/Invalid arguments. use 'add' to add a new string +use 'add-all ' to add the same string to ALL language files at once +use 'bulk-add ' to add multiple strings from a JSON file to all language files use 'remove' to remove a string use 'search' to search a string use 'update' to update a string @@ -46,6 +56,122 @@ use 'check' to check a string`); process.exit(); } +/** + * Adds a key-value pair to ALL language files at once + * Usage: pnpm lang add-all "key" "value" + */ +function addToAllFiles() { + if (!arg || !val) { + console.error('Usage: pnpm lang add-all "" ""'); + console.error('Example: pnpm lang add-all "hello world" "Hello World"'); + process.exit(1); + } + + const key = arg.toLowerCase(); + let addedCount = 0; + let skippedCount = 0; + + for (const lang of list) { + const file = path.resolve(dir, lang); + const text = fs.readFileSync(file, "utf8"); + const strings = JSON.parse(text); + + if (key in strings) { + console.log(`${lang}: Skipped (already exists)`); + skippedCount++; + continue; + } + + strings[key] = val; + const newText = JSON.stringify(strings, undefined, 2); + fs.writeFileSync(file, newText, "utf8"); + console.log(`${lang}: Added ✓`); + addedCount++; + } + + console.log( + `\nDone! Added to ${addedCount} files, skipped ${skippedCount} files.`, + ); + process.exit(0); +} + +/** + * Bulk add multiple strings from a JSON file to ALL language files + * Usage: pnpm lang bulk-add strings.json + * + * JSON file format: + * { + * "key1": "value1", + * "key2": "value2" + * } + */ +function bulkAddStrings() { + if (!arg) { + console.error("Usage: pnpm lang bulk-add "); + console.error("Example: pnpm lang bulk-add new-strings.json"); + console.error("\nJSON file format:"); + console.error("{"); + console.error(' "key1": "value1",'); + console.error(' "key2": "value2"'); + console.error("}"); + process.exit(1); + } + + const jsonFilePath = path.resolve(process.cwd(), arg); + + if (!fs.existsSync(jsonFilePath)) { + console.error(`File not found: ${jsonFilePath}`); + process.exit(1); + } + + let newStrings; + try { + const jsonContent = fs.readFileSync(jsonFilePath, "utf8"); + newStrings = JSON.parse(jsonContent); + } catch (err) { + console.error(`Error parsing JSON file: ${err.message}`); + process.exit(1); + } + + const keys = Object.keys(newStrings); + if (keys.length === 0) { + console.error("No strings found in the JSON file."); + process.exit(1); + } + + console.log( + `Adding ${keys.length} strings to ${list.length} language files...\n`, + ); + + for (const lang of list) { + const file = path.resolve(dir, lang); + const text = fs.readFileSync(file, "utf8"); + const strings = JSON.parse(text); + let addedCount = 0; + let skippedCount = 0; + + for (const key of keys) { + const lowerKey = key.toLowerCase(); + if (lowerKey in strings) { + skippedCount++; + continue; + } + strings[lowerKey] = newStrings[key]; + addedCount++; + } + + if (addedCount > 0) { + const newText = JSON.stringify(strings, undefined, 2); + fs.writeFileSync(file, newText, "utf8"); + } + + console.log(`${lang}: Added ${addedCount}, Skipped ${skippedCount}`); + } + + console.log(`\nDone! Added ${keys.length} strings to all language files.`); + process.exit(0); +} + async function update() { let key;