Repository: st3v3nmw/obsidian-spaced-repetition
Pull request #1094 (2024-09-25 15:53:14)

refactor: update settings


Patch:
diff --git a/src/algorithms/base/isrs-algorithm.ts b/src/algorithms/base/isrs-algorithm.ts
index 7cc867b..fabd579 100644
--- a/src/algorithms/base/isrs-algorithm.ts
+++ b/src/algorithms/base/isrs-algorithm.ts
@@ -4,6 +4,10 @@ import { OsrNoteGraph } from "src/algorithms/osr/osr-note-graph";
 import { DueDateHistogram } from "src/due-date-histogram";
 import { Note } from "src/note";
 
+export enum Algorithm {
+    SM_2_OSR = "SM-2-OSR",
+}
+
 export interface ISrsAlgorithm {
     noteOnLoadedNote(path: string, note: Note, noteEase: number): void;
     noteCalcNewSchedule(
diff --git a/src/data-stores/base/data-store.ts b/src/data-stores/base/data-store.ts
index 9fb5c7c..8a60c42 100644
--- a/src/data-stores/base/data-store.ts
+++ b/src/data-stores/base/data-store.ts
@@ -2,6 +2,10 @@ import { RepItemScheduleInfo } from "src/algorithms/base/rep-item-schedule-info"
 import { RepItemStorageInfo } from "src/data-stores/base/rep-item-storage-info";
 import { Question } from "src/question";
 
+export enum DataStoreName {
+    NOTES = "NOTES",
+}
+
 export interface IDataStore {
     questionCreateSchedule(
         originalQuestionText: string,
diff --git a/src/data-stores/store-in-note/note.ts b/src/data-stores/notes/notes.ts
similarity index 98%
rename from src/data-stores/store-in-note/note.ts
rename to src/data-stores/notes/notes.ts
index cfc9989..ecf5827 100644
--- a/src/data-stores/store-in-note/note.ts
+++ b/src/data-stores/notes/notes.ts
@@ -11,7 +11,7 @@ import { Question } from "src/question";
 import { SRSettings } from "src/settings";
 import { DateUtil, formatDate_YYYY_MM_DD, globalDateProvider } from "src/utils/dates";
 
-export class StoreInNote implements IDataStore {
+export class StoreInNotes implements IDataStore {
     private settings: SRSettings;
     app: App;
     easeByPath: NoteEaseList;
diff --git a/src/gui/tabs.tsx b/src/gui/tabs.tsx
index a4d29ae..6e97443 100644
--- a/src/gui/tabs.tsx
+++ b/src/gui/tabs.tsx
@@ -16,8 +16,9 @@
  *
  * Contact the author (Jarkko Linnanvirta): https://github.com/Taitava/
  */
-
 import { setIcon } from "obsidian";
+// eslint-disable-next-line @typescript-eslint/no-unused-vars
+import h from "vhtml";
 
 export interface Tab {
     title: string;
@@ -63,7 +64,9 @@ export function createTabs(
     const tab_buttons: TabButtons = {};
     const tab_structure: TabStructure = {
         header: tab_header,
-        active_tab_id: Object.keys(tabs)[0] as string, // Indicate that the first tab is active. This does not affect what tab is active in practise, it just reports the active tab.
+        // Indicate that the first tab is active.
+        // This does not affect what tab is active in practise, it just reports the active tab.
+        active_tab_id: Object.keys(tabs)[0] as string,
         buttons: tab_buttons,
         contentContainers: tab_content_containers,
         contentGeneratorPromises: {},
@@ -80,7 +83,9 @@ export function createTabs(
             },
         });
         button.onclick = function (event: MouseEvent) {
-            const tab_button = this as HTMLElement; // Use 'this' instead of event.target because this way we'll always get a button element, not an element inside the  button (i.e. an icon).
+            // Use 'this' instead of event.target because this way we'll always get a button element,
+            //  not an element inside the  button (i.e. an icon).
+            const tab_button = this as HTMLElement;
 
             // Hide all tab contents and get the max dimensions
             let max_width = 0;
@@ -95,7 +100,10 @@ export function createTabs(
                     "Container element is missing. Did not get a parent from tab header.",
                 );
             }
-            const tab_contents = container_element.findAll("div.sr-tab-content"); // Do not get all tab contents that exist, because there might be multiple tab systems open at the same time.
+
+            // Do not get all tab contents that exist,
+            //  because there might be multiple tab systems open at the same time.
+            const tab_contents = container_element.findAll("div.sr-tab-content");
             const is_main_settings_modal = container_element.hasClass("vertical-tab-content");
             for (const index in tab_contents) {
                 const tab_content = tab_contents[index];
@@ -103,7 +111,8 @@ export function createTabs(
                 // Get the maximum tab dimensions so that all tabs can have the same dimensions.
                 // But don't do it if this is the main settings modal
                 if (!is_main_settings_modal) {
-                    tab_content.addClass("sr-tab-active"); // Need to make the tab visible temporarily in order to get the dimensions.
+                    // Need to make the tab visible temporarily in order to get the dimensions.
+                    tab_content.addClass("sr-tab-active");
                     if (tab_content.offsetHeight > max_height) {
                         max_height = tab_content.offsetHeight;
                     }
@@ -117,7 +126,9 @@ export function createTabs(
             }
 
             // Remove active status from all buttons
-            const adjacent_tab_buttons = tab_header.findAll(".sr-tab-header-button"); // Do not get all tab buttons that exist, because there might be multiple tab systems open at the same time.
+            // Do not get all tab buttons that exist,
+            //  because there might be multiple tab systems open at the same time.
+            const adjacent_tab_buttons = tab_header.findAll(".sr-tab-header-button");
             for (const index in adjacent_tab_buttons) {
                 const tab_button = adjacent_tab_buttons[index];
                 tab_button.removeClass("sr-tab-active");
@@ -142,10 +153,12 @@ export function createTabs(
             tab_content.addClass("sr-tab-active");
 
             // Mark the clicked tab as active in TabStructure (just to report which tab is currently active)
-            tab_structure.active_tab_id = activate_tab_id.replace(/^sr-tab-/, ""); // Remove "sr-tab" prefix.
+            // Remove "sr-tab" prefix.
+            tab_structure.active_tab_id = activate_tab_id.replace(/^sr-tab-/, "");
 
             // Focus an element (if a focusable element is present)
-            tab_content.find(".sr-focus-element-on-tab-opening")?.focus(); // ? = If not found, do nothing.
+            // ? = If not found, do nothing.
+            tab_content.find(".sr-focus-element-on-tab-opening")?.focus();
 
             // Apply the max dimensions to this tab
             // But don't do it if this is the main settings modal
@@ -159,7 +172,7 @@ export function createTabs(
         };
         if (tab.icon) setIcon(button, tab.icon);
 
-        button.insertAdjacentText("beforeend", " " + tab.title);
+        button.insertAdjacentHTML("beforeend", <span style="padding-left: 5px;">{tab.title}</span>);
         tab_buttons[tab_id] = button;
 
         // Create content container
diff --git a/src/lang/locale/ar.ts b/src/lang/locale/ar.ts
index 9a68d0d..3a1e8d6 100644
--- a/src/lang/locale/ar.ts
+++ b/src/lang/locale/ar.ts
@@ -55,6 +55,7 @@ export default {
     GROUP_FLASHCARD_REVIEW: "Flashcard Review",
     GROUP_FLASHCARD_SEPARATORS: "Flashcard Separators",
     GROUP_DATA_STORAGE: "Storage of Scheduling Data",
+    GROUP_DATA_STORAGE_DESC: "Choose where to store the scheduling data",
     GROUP_FLASHCARDS_NOTES: "Flashcards & Notes",
     GROUP_CONTRIBUTING: "Contributing",
     CHECK_WIKI: '.<a href="${wiki_url}">wiki</a> لمزيد من المعلومات ، تحقق من',
@@ -63,11 +64,11 @@ export default {
     GITHUB_ISSUES:
         'Raise an issue <a href="${issues_url}">here</a> if you have a feature request or a bug report.',
     GITHUB_SOURCE_CODE:
-        'Project source code available on <a href="${github_project_url}">GitHub</a>',
+        'The project\'s source code is available on <a href="${github_project_url}">GitHub</a>.',
     CODE_CONTRIBUTION_INFO:
-        'Information on <a href="${code_contribution_url}">code contributions</a>',
+        '<a href="${code_contribution_url}">Here\'s</a> how to contribute code to the plugin.',
     TRANSLATION_CONTRIBUTION_INFO:
-        'Information on <a href="${translation_contribution_url}">translating the plugin</a> to your language',
+        '<a href="${translation_contribution_url}">Here\'s</a> how to translate the plugin to another language.',
     PROJECT_CONTRIBUTIONS:
         'Raise an issue <a href="${issues_url}">here</a> if you have a feature request or a bug report',
     FOLDERS_TO_IGNORE: "مجلدات لتجاهلها",
@@ -81,7 +82,7 @@ export default {
     FLASHCARD_EASY_DESC: '"تخصيص التسمية للزر "سهل',
     FLASHCARD_GOOD_DESC: '"تخصيص التسمية للزر "جيد',
     FLASHCARD_HARD_DESC: '"تخصيص التسمية للزر "صعب',
-    REVIEW_BUTTON_DELAY: "Button press delay (ms)",
+    REVIEW_BUTTON_DELAY: "Button Press Delay (ms)",
     REVIEW_BUTTON_DELAY_DESC: "Add a delay to the review buttons before they can be pressed again.",
     FLASHCARD_TAGS: "وُسوم البطاقات",
     FLASHCARD_TAGS_DESC: "#2أدخل الوُسوم مفصولة بمسافات أو أسطر جديدة ، أي بطاقات# رزمة3# رزمة",
@@ -137,7 +138,7 @@ export default {
     MAX_N_DAYS_REVIEW_QUEUE: "الحد الأقصى لعدد الأيام التي يجب عرضها على اللوحة اليمنى",
     MIN_ONE_DAY: "يجب أن يكون عدد الأيام 1 على الأقل",
     VALID_NUMBER_WARNING: "يرجى تقديم رقم صالح",
-    UI_PREFERENCES: "تفضيلات واجهة المستخدم",
+    UI: "User Interface",
     SHOW_STATUS_BAR: "Show status bar",
     SHOW_STATUS_BAR_DESC:
         "Turn this off to hide the flashcard's review status in Obsidian's status bar",
@@ -148,8 +149,8 @@ export default {
     INITIALLY_EXPAND_SUBDECKS_IN_TREE_DESC:
         " عطل هذا الخيار لطي الرُزم المتداخلة في نفس البطاقة , مفيد إذا كان لديك بطاقات تنتمي إلى العديد من الرُزم في نفس الملف",
     ALGORITHM: "خوارزمية",
-    CHECK_ALGORITHM_WIKI:
-        '<a href="${algo_url}">algorithm implementation</a> :لمزيد من المعلومات تحقق من',
+    CHECK_ALGORITHM_WIKI: '<a href="${algo_url}">algorithm details</a> :لمزيد من المعلومات تحقق من',
+    SM2_OSR_VARIANT: "OSR's variant of SM-2",
     BASE_EASE: "سهولة القاعدة",
     BASE_EASE_DESC: "الحد الأدنى = 130 ، ويفضل حوالي 250.",
     BASE_EASE_MIN_WARNING: "يجب أن تكون سهولة القاعدة 130 على الأقل.",
@@ -165,9 +166,12 @@ export default {
     MAX_LINK_CONTRIB: "أقصى مساهمة ارتباط",
     MAX_LINK_CONTRIB_DESC: "أقصى مساهمة للسهولة المرجحة للملاحظات المرتبطة بالسهولة الأولية.",
     LOGGING: "تسجيل",
-    DISPLAY_DEBUG_INFO: "عرض معلومات التصحيح على وحدة تحكم المطور",
-    DISPLAY_PARSER_DEBUG_INFO:
-        "Display debugging information for the parser on the developer console",
+    DISPLAY_SCHEDULING_DEBUG_INFO: "عرض معلومات التصحيح على وحدة تحكم المطور",
+    DISPLAY_PARSER_DEBUG_INFO: "Show the parser's debugging information on the developer console",
+    SCHEDULING: "Scheduling",
+    EXPERIMENTAL: "Experimental",
+    HELP: "Help",
+    STORE_IN_NOTES: "In the notes",
 
     // sidebar.ts
     NOTES_REVIEW_QUEUE: "ملاحظات قائمة المراجعة",
diff --git a/src/lang/locale/cz.ts b/src/lang/locale/cz.ts
index 61d6859..307e9bc 100644
--- a/src/lang/locale/cz.ts
+++ b/src/lang/locale/cz.ts
@@ -55,6 +55,7 @@ export default {
     GROUP_FLASHCARD_REVIEW: "Flashcard Review",
     GROUP_FLASHCARD_SEPARATORS: "Flashcard Separators",
     GROUP_DATA_STORAGE: "Storage of Scheduling Data",
+    GROUP_DATA_STORAGE_DESC: "Choose where to store the scheduling data",
     GROUP_FLASHCARDS_NOTES: "Flashcards & Notes",
     GROUP_CONTRIBUTING: "Contributing",
     CHECK_WIKI: 'Pro více informací jděte na <a href="${wiki_url}">wiki</a>.',
@@ -63,11 +64,11 @@ export default {
     GITHUB_ISSUES:
         'Raise an issue <a href="${issues_url}">here</a> if you have a feature request or a bug report.',
     GITHUB_SOURCE_CODE:
-        'Project source code available on <a href="${github_project_url}">GitHub</a>',
+        'The project\'s source code is available on <a href="${github_project_url}">GitHub</a>.',
     CODE_CONTRIBUTION_INFO:
-        'Information on <a href="${code_contribution_url}">code contributions</a>',
+        '<a href="${code_contribution_url}">Here\'s</a> how to contribute code to the plugin.',
     TRANSLATION_CONTRIBUTION_INFO:
-        'Information on <a href="${translation_contribution_url}">translating the plugin</a> to your language',
+        '<a href="${translation_contribution_url}">Here\'s</a> how to translate the plugin to another language.',
     PROJECT_CONTRIBUTIONS:
         'Raise an issue <a href="${issues_url}">here</a> if you have a feature request or a bug report',
     FOLDERS_TO_IGNORE: "Ignorované složky",
@@ -81,7 +82,7 @@ export default {
     FLASHCARD_EASY_DESC: 'Customize the label for the "Easy" Button',
     FLASHCARD_GOOD_DESC: 'Customize the label for the "Good" Button',
     FLASHCARD_HARD_DESC: 'Customize the label for the "Hard" Button',
-    REVIEW_BUTTON_DELAY: "Button press delay (ms)",
+    REVIEW_BUTTON_DELAY: "Button Press Delay (ms)",
     REVIEW_BUTTON_DELAY_DESC: "Add a delay to the review buttons before they can be pressed again.",
     FLASHCARD_TAGS: "Tag pro kartičky",
     FLASHCARD_TAGS_DESC:
@@ -141,7 +142,7 @@ export default {
     MAX_N_DAYS_REVIEW_QUEUE: "Maximální počet dní zobrazených v pravém panelu",
     MIN_ONE_DAY: "Počet dní musí být minimálně 1.",
     VALID_NUMBER_WARNING: "Prosím zadejte validní číslo.",
-    UI_PREFERENCES: "Předvolby uživatelského rozhraní",
+    UI: "Předvolby uživatelského rozhraní",
     SHOW_STATUS_BAR: "Show status bar",
     SHOW_STATUS_BAR_DESC:
         "Turn this off to hide the flashcard's review status in Obsidian's status bar",
@@ -153,6 +154,7 @@ export default {
         "Vypněte toto, chcete-li sbalit vnořené balíčky na stejné kartě. To je užitečné, pokud máte kartičky, které patří k mnoha balíčkům ve stejném souboru.",
     ALGORITHM: "Algoritmus",
     CHECK_ALGORITHM_WIKI: 'Pro více informací jděte na <a href="${algo_url}">popis algoritmu</a>.',
+    SM2_OSR_VARIANT: "OSR's variant of SM-2",
     BASE_EASE: "Základní složitost",
     BASE_EASE_DESC: "minimum = 130, nejlépe přibližně 250.",
     BASE_EASE_MIN_WARNING: "Základní složitost musí být minimálně 130.",
@@ -169,9 +171,12 @@ export default {
     MAX_LINK_CONTRIB_DESC:
         "Maximální příspěvek vážené složitosti prolinkovaných poznámek použitý pro určení počáteční složitosti.",
     LOGGING: "Zaznamenávám",
-    DISPLAY_DEBUG_INFO: "Zobrazit informace pro ladění na vývojářské konzoli",
-    DISPLAY_PARSER_DEBUG_INFO:
-        "Display debugging information for the parser on the developer console",
+    DISPLAY_SCHEDULING_DEBUG_INFO: "Zobrazit informace pro ladění na vývojářské konzoli",
+    DISPLAY_PARSER_DEBUG_INFO: "Show the parser's debugging information on the developer console",
+    SCHEDULING: "Scheduling",
+    EXPERIMENTAL: "Experimental",
+    HELP: "Help",
+    STORE_IN_NOTES: "In the notes",
 
     // sidebar.ts
     NOTES_REVIEW_QUEUE: "Fronta poznámek k revizi",
diff --git a/src/lang/locale/de.ts b/src/lang/locale/de.ts
index 573892b..72e046c 100644
--- a/src/lang/locale/de.ts
+++ b/src/lang/locale/de.ts
@@ -61,6 +61,7 @@ export default {
     GROUP_FLASHCARD_REVIEW: "Flashcard Review",
     GROUP_FLASHCARD_SEPARATORS: "Flashcard Separators",
     GROUP_DATA_STORAGE: "Storage of Scheduling Data",
+    GROUP_DATA_STORAGE_DESC: "Choose where to store the scheduling data",
     GROUP_FLASHCARDS_NOTES: "Flashcards & Notes",
     GROUP_CONTRIBUTING: "Contributing",
     CHECK_WIKI: 'Weitere Informationen gibt es im <a href="${wiki_url}">Wiki</a> (english).',
@@ -69,11 +70,11 @@ export default {
     GITHUB_ISSUES:
         'Raise an issue <a href="${issues_url}">here</a> if you have a feature request or a bug report.',
     GITHUB_SOURCE_CODE:
-        'Project source code available on <a href="${github_project_url}">GitHub</a>',
+        'The project\'s source code is available on <a href="${github_project_url}">GitHub</a>.',
     CODE_CONTRIBUTION_INFO:
-        'Information on <a href="${code_contribution_url}">code contributions</a>',
+        '<a href="${code_contribution_url}">Here\'s</a> how to contribute code to the plugin.',
     TRANSLATION_CONTRIBUTION_INFO:
-        'Information on <a href="${translation_contribution_url}">translating the plugin</a> to your language',
+        '<a href="${translation_contribution_url}">Here\'s</a> how to translate the plugin to another language.',
     PROJECT_CONTRIBUTIONS:
         'Raise an issue <a href="${issues_url}">here</a> if you have a feature request or a bug report',
     FOLDERS_TO_IGNORE: "Ausgeschlossene Ordner",
@@ -157,7 +158,7 @@ export default {
         "Maximale Anzahl anstehender Notizen, die im rechten Fensterbereich angezeigt werden",
     MIN_ONE_DAY: "Anzahl der Tage muss mindestens 1 sein.",
     VALID_NUMBER_WARNING: "Bitte eine gültige Zahl eingeben.",
-    UI_PREFERENCES: "Einstellungen der Benutzeroberfläche",
+    UI: "User Interface",
     SHOW_STATUS_BAR: "Show status bar",
     SHOW_STATUS_BAR_DESC:
         "Turn this off to hide the flashcard's review status in Obsidian's status bar",
@@ -170,6 +171,7 @@ export default {
     ALGORITHM: "Algorithmus",
     CHECK_ALGORITHM_WIKI:
         'Weiterführende Informationen: <a href="${algo_url}">Implementierung des Algorithmus</a> (english).',
+    SM2_OSR_VARIANT: "OSR's variant of SM-2",
     BASE_EASE: "Basis der Schwierigkeit",
     BASE_EASE_DESC: "Minimum ist 130. Empfohlen wird ca. 250.",
     BASE_EASE_MIN_WARNING: "Basis der Schwierigkeit muss mindestens 130 sein.",
@@ -188,9 +190,13 @@ export default {
     MAX_LINK_CONTRIB_DESC:
         "Maximaler Einfluss der Einfachheiten verlinkter Notizen zur gewichteten initialen Einfachheit einer neuen Lernkarte.",
     LOGGING: "Protokollierung",
-    DISPLAY_DEBUG_INFO: "Informationen zum Debugging in der Entwicklerkonsole anzeigen",
+    DISPLAY_SCHEDULING_DEBUG_INFO: "Informationen zum Debugging in der Entwicklerkonsole anzeigen",
     DISPLAY_PARSER_DEBUG_INFO:
         "Informationen zum parser Debugging in der Entwicklerkonsole anzeigen",
+    SCHEDULING: "Scheduling",
+    EXPERIMENTAL: "Experimental",
+    HELP: "Help",
+    STORE_IN_NOTES: "In the notes",
 
     // sidebar.ts
     NOTES_REVIEW_QUEUE: "Anstehende Notizen zur Wiederholung",
diff --git a/src/lang/locale/en.ts b/src/lang/locale/en.ts
index 4980441..8eab666 100644
--- a/src/lang/locale/en.ts
+++ b/src/lang/locale/en.ts
@@ -55,6 +55,7 @@ export default {
     GROUP_FLASHCARD_REVIEW: "Flashcard Review",
     GROUP_FLASHCARD_SEPARATORS: "Flashcard Separators",
     GROUP_DATA_STORAGE: "Storage of Scheduling Data",
+    GROUP_DATA_STORAGE_DESC: "Choose where to store the scheduling data",
     GROUP_FLASHCARDS_NOTES: "Flashcards & Notes",
     GROUP_CONTRIBUTING: "Contributing",
     CHECK_WIKI: 'For more information, check the <a href="${wiki_url}">wiki</a>.',
@@ -63,11 +64,11 @@ export default {
     GITHUB_ISSUES:
         'Raise an issue <a href="${issues_url}">here</a> if you have a feature request or a bug report.',
     GITHUB_SOURCE_CODE:
-        'Project source code available on <a href="${github_project_url}">GitHub</a>',
+        'The project\'s source code is available on <a href="${github_project_url}">GitHub</a>.',
     CODE_CONTRIBUTION_INFO:
-        'Information on <a href="${code_contribution_url}">code contributions</a>',
+        '<a href="${code_contribution_url}">Here\'s</a> how to contribute code to the plugin.',
     TRANSLATION_CONTRIBUTION_INFO:
-        'Information on <a href="${translation_contribution_url}">translating the plugin</a> to your language',
+        '<a href="${translation_contribution_url}">Here\'s</a> how to translate the plugin to another language.',
     PROJECT_CONTRIBUTIONS:
         'Raise an issue <a href="${issues_url}">here</a> if you have a feature request or a bug report',
     FOLDERS_TO_IGNORE: "Folders to ignore",
@@ -81,7 +82,7 @@ export default {
     FLASHCARD_EASY_DESC: 'Customize the label for the "Easy" Button',
     FLASHCARD_GOOD_DESC: 'Customize the label for the "Good" Button',
     FLASHCARD_HARD_DESC: 'Customize the label for the "Hard" Button',
-    REVIEW_BUTTON_DELAY: "Button press delay (ms)",
+    REVIEW_BUTTON_DELAY: "Button Press Delay (ms)",
     REVIEW_BUTTON_DELAY_DESC: "Add a delay to the review buttons before they can be pressed again.",
     FLASHCARD_TAGS: "Flashcard tags",
     FLASHCARD_TAGS_DESC:
@@ -133,10 +134,10 @@ export default {
     OPEN_RANDOM_NOTE: "Open a random note for review",
     OPEN_RANDOM_NOTE_DESC: "When you turn this off, notes are ordered by importance (PageRank).",
     AUTO_NEXT_NOTE: "Open next note automatically after a review",
-    MAX_N_DAYS_REVIEW_QUEUE: "Maximum number of days to display on right panel",
+    MAX_N_DAYS_REVIEW_QUEUE: "Maximum number of days to display on note review panel",
     MIN_ONE_DAY: "The number of days must be at least 1.",
     VALID_NUMBER_WARNING: "Please provide a valid number.",
-    UI_PREFERENCES: "UI Preferences",
+    UI: "User Interface",
     SHOW_STATUS_BAR: "Show status bar",
     SHOW_STATUS_BAR_DESC:
         "Turn this off to hide the flashcard's review status in Obsidian's status bar",
@@ -151,7 +152,8 @@ export default {
         "Turn this off to collapse nested decks in the same card. Useful if you have cards which belong to many decks in the same file.",
     ALGORITHM: "Algorithm",
     CHECK_ALGORITHM_WIKI:
-        'For more information, check the <a href="${algo_url}">algorithm implementation</a>.',
+        'For more information, check the <a href="${algo_url}">algorithm details</a>.',
+    SM2_OSR_VARIANT: "OSR's variant of SM-2",
     BASE_EASE: "Base ease",
     BASE_EASE_DESC: "minimum = 130, preferrably approximately 250.",
     BASE_EASE_MIN_WARNING: "The base ease must be at least 130.",
@@ -168,9 +170,13 @@ export default {
     MAX_LINK_CONTRIB_DESC:
         "Maximum contribution of the weighted ease of linked notes to the initial ease.",
     LOGGING: "Logging",
-    DISPLAY_DEBUG_INFO: "Display debugging information on the developer console",
-    DISPLAY_PARSER_DEBUG_INFO:
-        "Display debugging information for the parser on the developer console",
+    DISPLAY_SCHEDULING_DEBUG_INFO:
+        "Show the scheduler's debugging information on the developer console",
+    DISPLAY_PARSER_DEBUG_INFO: "Show the parser's debugging information on the developer console",
+    SCHEDULING: "Scheduling",
+    EXPERIMENTAL: "Experimental",
+    HELP: "Help",
+    STORE_IN_NOTES: "In the notes",
 
     // sidebar.ts
     NOTES_REVIEW_QUEUE: "Notes Review Queue",
diff --git a/src/lang/locale/es.ts b/src/lang/locale/es.ts
index ce5d496..26f7524 100644
--- a/src/lang/locale/es.ts
+++ b/src/lang/locale/es.ts
@@ -55,6 +55,7 @@ export default {
     GROUP_FLASHCARD_REVIEW: "Flashcard Review",
     GROUP_FLASHCARD_SEPARATORS: "Flashcard Separators",
     GROUP_DATA_STORAGE: "Storage of Scheduling Data",
+    GROUP_DATA_STORAGE_DESC: "Choose where to store the scheduling data",
     GROUP_FLASHCARDS_NOTES: "Flashcards & Notes",
     GROUP_CONTRIBUTING: "Contributing",
     CHECK_WIKI: 'Para más información revisa la <a href="${wiki_url}">wiki</a>.',
@@ -63,11 +64,11 @@ export default {
     GITHUB_ISSUES:
         'Raise an issue <a href="${issues_url}">here</a> if you have a feature request or a bug report.',
     GITHUB_SOURCE_CODE:
-        'Project source code available on <a href="${github_project_url}">GitHub</a>',
+        'The project\'s source code is available on <a href="${github_project_url}">GitHub</a>.',
     CODE_CONTRIBUTION_INFO:
-        'Information on <a href="${code_contribution_url}">code contributions</a>',
+        '<a href="${code_contribution_url}">Here\'s</a> how to contribute code to the plugin.',
     TRANSLATION_CONTRIBUTION_INFO:
-        'Information on <a href="${translation_contribution_url}">translating the plugin</a> to your language',
+        '<a href="${translation_contribution_url}">Here\'s</a> how to translate the plugin to another language.',
     PROJECT_CONTRIBUTIONS:
         'Raise an issue <a href="${issues_url}">here</a> if you have a feature request or a bug report',
     FOLDERS_TO_IGNORE: "Directorios a ignorar",
@@ -81,7 +82,7 @@ export default {
     FLASHCARD_EASY_DESC: "Personalize la etiqueta para el botón: Fácil",
     FLASHCARD_GOOD_DESC: "Personalize la etiqueta para el botón: Bien",
     FLASHCARD_HARD_DESC: "Personalize la etiqueta para el botón: Difícil",
-    REVIEW_BUTTON_DELAY: "Button press delay (ms)",
+    REVIEW_BUTTON_DELAY: "Button Press Delay (ms)",
     REVIEW_BUTTON_DELAY_DESC: "Add a delay to the review buttons before they can be pressed again.",
     FLASHCARD_TAGS: "Etiquetas de las Tarjetas de Memorización",
     FLASHCARD_TAGS_DESC:
@@ -145,7 +146,7 @@ export default {
     MAX_N_DAYS_REVIEW_QUEUE: "Número máximo de días a mostrar en el panel derecho.",
     MIN_ONE_DAY: "El número de días debe ser al menos uno.",
     VALID_NUMBER_WARNING: "Por favor especifique un número válido.",
-    UI_PREFERENCES: "Preferencias de la interfaz de usuario.",
+    UI: "User Interface",
     SHOW_STATUS_BAR: "Show status bar",
     SHOW_STATUS_BAR_DESC:
         "Turn this off to hide the flashcard's review status in Obsidian's status bar",
@@ -157,6 +158,7 @@ export default {
     ALGORITHM: "Algoritmo",
     CHECK_ALGORITHM_WIKI:
         'Para más información, revisa la <a href="${algo_url}">implementación del algoritmo</a>.',
+    SM2_OSR_VARIANT: "OSR's variant of SM-2",
     BASE_EASE: "Base ease",
     BASE_EASE_DESC: "El mínimo es 130, es preferible que esté aproximado a 250.",
     BASE_EASE_MIN_WARNING: "La facilidad base de las tarjetas debe ser al menos 130.",
@@ -175,9 +177,13 @@ export default {
     MAX_LINK_CONTRIB_DESC:
         "Contribución máxima de la facilidad ponderada de las notas vinculadas a la facilidad inicial.",
     LOGGING: "Registro",
-    DISPLAY_DEBUG_INFO: "¿Mostrar información de depuración en la consola de desarrollador",
-    DISPLAY_PARSER_DEBUG_INFO:
-        "Display debugging information for the parser on the developer console",
+    DISPLAY_SCHEDULING_DEBUG_INFO:
+        "¿Mostrar información de depuración en la consola de desarrollador",
+    DISPLAY_PARSER_DEBUG_INFO: "Show the parser's debugging information on the developer console",
+    SCHEDULING: "Scheduling",
+    EXPERIMENTAL: "Experimental",
+    HELP: "Help",
+    STORE_IN_NOTES: "In the notes",
 
     // sidebar.ts
     NOTES_REVIEW_QUEUE: "Cola de notas a revisar",
diff --git a/src/lang/locale/fr.ts b/src/lang/locale/fr.ts
index fe5a12c..d0892ba 100644
--- a/src/lang/locale/fr.ts
+++ b/src/lang/locale/fr.ts
@@ -56,6 +56,7 @@ export default {
     GROUP_FLASHCARD_REVIEW: "Apprentissage des flashcards",
     GROUP_FLASHCARD_SEPARATORS: "Séparateurs de flashcards",
     GROUP_DATA_STORAGE: "Stockage des informations de planification",
+    GROUP_DATA_STORAGE_DESC: "Choose where to store the scheduling data",
     GROUP_FLASHCARDS_NOTES: "Flashcards & Notes",
     GROUP_CONTRIBUTING: "Contribuer",
     CHECK_WIKI: 'Pour plus d\'informations, visitez le <a href="${wiki_url}">wiki</a>.',
@@ -82,7 +83,7 @@ export default {
     FLASHCARD_EASY_DESC: "Changez le texte du bouton Facile",
     FLASHCARD_GOOD_DESC: "Changez le texte du bouton Correct",
     FLASHCARD_HARD_DESC: "Changez le texte du bouton Difficile",
-    REVIEW_BUTTON_DELAY: "Button press delay (ms)",
+    REVIEW_BUTTON_DELAY: "Button Press Delay (ms)",
     REVIEW_BUTTON_DELAY_DESC: "Add a delay to the review buttons before they can be pressed again.",
     FLASHCARD_TAGS: "Tags des flashcards",
     FLASHCARD_TAGS_DESC:
@@ -140,7 +141,7 @@ export default {
     MAX_N_DAYS_REVIEW_QUEUE: "Jours maximum affichés dans la barre de droite",
     MIN_ONE_DAY: "Le nombre de jours doit être au moins 1.",
     VALID_NUMBER_WARNING: "Entrez un nombre valide.",
-    UI_PREFERENCES: "Préférences UI",
+    UI: "User Interface",
     SHOW_STATUS_BAR: "Show status bar",
     SHOW_STATUS_BAR_DESC:
         "Turn this off to hide the flashcard's review status in Obsidian's status bar",
@@ -157,6 +158,7 @@ export default {
     ALGORITHM: "Algorithme",
     CHECK_ALGORITHM_WIKI:
         "Pour en savoir plus, lisez l'<a href=\"${algo_url}\">implémentation de l'algorithme</a>.",
+    SM2_OSR_VARIANT: "OSR's variant of SM-2",
     BASE_EASE: "Facilité de base",
     BASE_EASE_DESC: "minimum = 130, recommandé = vers 250.",
     BASE_EASE_MIN_WARNING: "La facilité de base doit être supérieure à 130.",
@@ -175,9 +177,14 @@ export default {
     MAX_LINK_CONTRIB_DESC:
         "Contribution maximum de la facilité pondérée des notes liées à la facilité initiale.",
     LOGGING: "Logging",
-    DISPLAY_DEBUG_INFO: "Afficher les informations de débogage dans la console de développement",
+    DISPLAY_SCHEDULING_DEBUG_INFO:
+        "Afficher les informations de débogage dans la console de développement",
     DISPLAY_PARSER_DEBUG_INFO:
         "Afficher les informations de débogage pour le parser dans la console de développement",
+    SCHEDULING: "Scheduling",
+    EXPERIMENTAL: "Experimental",
+    HELP: "Help",
+    STORE_IN_NOTES: "In the notes",
 
     // sidebar.ts
     NOTES_REVIEW_QUEUE: "Cartes à apprendre",
diff --git a/src/lang/locale/it.ts b/src/lang/locale/it.ts
index 81e270b..cedff08 100644
--- a/src/lang/locale/it.ts
+++ b/src/lang/locale/it.ts
@@ -56,6 +56,7 @@ export default {
     GROUP_FLASHCARD_REVIEW: "Flashcard Review",
     GROUP_FLASHCARD_SEPARATORS: "Flashcard Separators",
     GROUP_DATA_STORAGE: "Storage of Scheduling Data",
+    GROUP_DATA_STORAGE_DESC: "Choose where to store the scheduling data",
     GROUP_FLASHCARDS_NOTES: "Flashcards & Notes",
     GROUP_CONTRIBUTING: "Contributing",
     CHECK_WIKI: 'Per maggiori informazioni, rivolgersi alla <a href="${wiki_url}">wiki</a>.',
@@ -64,11 +65,11 @@ export default {
     GITHUB_ISSUES:
         'Raise an issue <a href="${issues_url}">here</a> if you have a feature request or a bug report.',
     GITHUB_SOURCE_CODE:
-        'Project source code available on <a href="${github_project_url}">GitHub</a>',
+        'The project\'s source code is available on <a href="${github_project_url}">GitHub</a>.',
     CODE_CONTRIBUTION_INFO:
-        'Information on <a href="${code_contribution_url}">code contributions</a>',
+        '<a href="${code_contribution_url}">Here\'s</a> how to contribute code to the plugin.',
     TRANSLATION_CONTRIBUTION_INFO:
-        'Information on <a href="${translation_contribution_url}">translating the plugin</a> to your language',
+        '<a href="${translation_contribution_url}">Here\'s</a> how to translate the plugin to another language.',
     PROJECT_CONTRIBUTIONS:
         'Raise an issue <a href="${issues_url}">here</a> if you have a feature request or a bug report',
     FOLDERS_TO_IGNORE: "Cartelle da ignorare",
@@ -82,7 +83,7 @@ export default {
     FLASHCARD_EASY_DESC: 'Personalizza il testo per il pulsante "Facile"',
     FLASHCARD_GOOD_DESC: 'Personalizza il testo per il pulsante "Buono"',
     FLASHCARD_HARD_DESC: 'Personalizza il testo per il pulsante "Difficile"',
-    REVIEW_BUTTON_DELAY: "Button press delay (ms)",
+    REVIEW_BUTTON_DELAY: "Button Press Delay (ms)",
     REVIEW_BUTTON_DELAY_DESC: "Add a delay to the review buttons before they can be pressed again.",
     FLASHCARD_TAGS: "Etichette delle schede",
     FLASHCARD_TAGS_DESC:
@@ -148,7 +149,7 @@ export default {
     MAX_N_DAYS_REVIEW_QUEUE: "Numero di giorni massimi da visualizzare nel pannello di destra",
     MIN_ONE_DAY: "Il numero di giorni deve essere almeno 1.",
     VALID_NUMBER_WARNING: "Per favore, mettere un numero valido.",
-    UI_PREFERENCES: "Preferenze di interfaccia",
+    UI: "User Interface",
     SHOW_STATUS_BAR: "Show status bar",
     SHOW_STATUS_BAR_DESC:
         "Turn this off to hide the flashcard's review status in Obsidian's status bar",
@@ -161,6 +162,7 @@ export default {
     ALGORITHM: "Algoritmo",
     CHECK_ALGORITHM_WIKI:
         "Per maggiori informazioni, visita <a href='${algo_url}'>l'implementazione dell'algoritmo</a>.",
+    SM2_OSR_VARIANT: "OSR's variant of SM-2",
     BASE_EASE: "Difficoltà base",
     BASE_EASE_DESC: "mino = 130, preferibilmente circa 250.",
     BASE_EASE_MIN_WARNING: "La difficoltà base deve essere di almeno 130.",
@@ -178,9 +180,14 @@ export default {
     MAX_LINK_CONTRIB_DESC:
         "Contributo massimo della difficoltà pasata delle note collegate alla difficoltà iniziale.",
     LOGGING: "Registrando",
-    DISPLAY_DEBUG_INFO: "Visualizza informazione di debug sulla console per sviluppatori",
+    DISPLAY_SCHEDULING_DEBUG_INFO:
+        "Visualizza informazione di debug sulla console per sviluppatori",
     DISPLAY_PARSER_DEBUG_INFO:
         "Visualizza informazione di debug riguardanti il parser sulla console per sviluppatori",
+    SCHEDULING: "Scheduling",
+    EXPERIMENTAL: "Experimental",
+    HELP: "Help",
+    STORE_IN_NOTES: "In the notes",
 
     // sidebar.ts
     NOTES_REVIEW_QUEUE: "Coda di note da rivedere",
diff --git a/src/lang/locale/ja.ts b/src/lang/locale/ja.ts
index 3a7e630..8175405 100644
--- a/src/lang/locale/ja.ts
+++ b/src/lang/locale/ja.ts
@@ -56,6 +56,7 @@ export default {
     GROUP_FLASHCARD_REVIEW: "Flashcard Review",
     GROUP_FLASHCARD_SEPARATORS: "Flashcard Separators",
     GROUP_DATA_STORAGE: "Storage of Scheduling Data",
+    GROUP_DATA_STORAGE_DESC: "Choose where to store the scheduling data",
     GROUP_FLASHCARDS_NOTES: "Flashcards & Notes",
     GROUP_CONTRIBUTING: "Contributing",
     CHECK_WIKI: '詳細については<a href="${wiki_url}">wiki</a>を確認してください。',
@@ -64,11 +65,11 @@ export default {
     GITHUB_ISSUES:
         'Raise an issue <a href="${issues_url}">here</a> if you have a feature request or a bug report.',
     GITHUB_SOURCE_CODE:
-        'Project source code available on <a href="${github_project_url}">GitHub</a>',
+        'The project\'s source code is available on <a href="${github_project_url}">GitHub</a>.',
     CODE_CONTRIBUTION_INFO:
-        'Information on <a href="${code_contribution_url}">code contributions</a>',
+        '<a href="${code_contribution_url}">Here\'s</a> how to contribute code to the plugin.',
     TRANSLATION_CONTRIBUTION_INFO:
-        'Information on <a href="${translation_contribution_url}">translating the plugin</a> to your language',
+        '<a href="${translation_contribution_url}">Here\'s</a> how to translate the plugin to another language.',
     PROJECT_CONTRIBUTIONS:
         'Raise an issue <a href="${issues_url}">here</a> if you have a feature request or a bug report',
     FOLDERS_TO_IGNORE: "無視するフォルダ",
@@ -82,7 +83,7 @@ export default {
     FLASHCARD_EASY_DESC: 'Customize the label for the "Easy" Button',
     FLASHCARD_GOOD_DESC: 'Customize the label for the "Good" Button',
     FLASHCARD_HARD_DESC: 'Customize the label for the "Hard" Button',
-    REVIEW_BUTTON_DELAY: "Button press delay (ms)",
+    REVIEW_BUTTON_DELAY: "Button Press Delay (ms)",
     REVIEW_BUTTON_DELAY_DESC: "Add a delay to the review buttons before they can be pressed again.",
     FLASHCARD_TAGS: "フラッシュカードに使用するタグ",
     FLASHCARD_TAGS_DESC:
@@ -145,7 +146,7 @@ export default {
     MAX_N_DAYS_REVIEW_QUEUE: "右パネルに表示する最大の日数",
     MIN_ONE_DAY: "日数には1以上の数字を指定してください。",
     VALID_NUMBER_WARNING: "有効な数字を入力してください。",
-    UI_PREFERENCES: "ユーザー インターフェイスの設定",
+    UI: "User Interface",
     SHOW_STATUS_BAR: "Show status bar",
     SHOW_STATUS_BAR_DESC:
         "Turn this off to hide the flashcard's review status in Obsidian's status bar",
@@ -157,6 +158,7 @@ export default {
     ALGORITHM: "アルゴリズム",
     CHECK_ALGORITHM_WIKI:
         '詳細については<a href="${algo_url}">アルゴリズムの実装</a>を確認してください。',
+    SM2_OSR_VARIANT: "OSR's variant of SM-2",
     BASE_EASE: "ベースの易しさ",
     BASE_EASE_DESC: "最小値は130ですが、 適正値はおおよそ250です。",
     BASE_EASE_MIN_WARNING: "ベースの易しさには130以上の数字を指定してください。",
@@ -173,9 +175,12 @@ export default {
     MAX_LINK_CONTRIB_DESC:
         "最初の易しさに対して、リンクされたノートの重み付けされた易しさが寄与する最大値を指定してください。",
     LOGGING: "ログ管理",
-    DISPLAY_DEBUG_INFO: "デベロッパーコンソールにてデバッグ情報を表示しますか",
-    DISPLAY_PARSER_DEBUG_INFO:
-        "Display debugging information for the parser on the developer console",
+    DISPLAY_SCHEDULING_DEBUG_INFO: "デベロッパーコンソールにてデバッグ情報を表示しますか",
+    DISPLAY_PARSER_DEBUG_INFO: "Show the parser's debugging information on the developer console",
+    SCHEDULING: "Scheduling",
+    EXPERIMENTAL: "Experimental",
+    HELP: "Help",
+    STORE_IN_NOTES: "In the notes",
 
     // sidebar.ts
     NOTES_REVIEW_QUEUE: "ノートレビューのキュー",
diff --git a/src/lang/locale/ko.ts b/src/lang/locale/ko.ts
index fde76dc..f8140e5 100644
--- a/src/lang/locale/ko.ts
+++ b/src/lang/locale/ko.ts
@@ -55,6 +55,7 @@ export default {
     GROUP_FLASHCARD_REVIEW: "Flashcard Review",
     GROUP_FLASHCARD_SEPARATORS: "Flashcard Separators",
     GROUP_DATA_STORAGE: "Storage of Scheduling Data",
+    GROUP_DATA_STORAGE_DESC: "Choose where to store the scheduling data",
     GROUP_FLASHCARDS_NOTES: "Flashcards & Notes",
     GROUP_CONTRIBUTING: "Contributing",
     CHECK_WIKI: '더 많은 정보를 원하시면, <a href="${wiki_url}">wiki</a>를 확인해주세요.',
@@ -63,11 +64,11 @@ export default {
     GITHUB_ISSUES:
         'Raise an issue <a href="${issues_url}">here</a> if you have a feature request or a bug report.',
     GITHUB_SOURCE_CODE:
-        'Project source code available on <a href="${github_project_url}">GitHub</a>',
+        'The project\'s source code is available on <a href="${github_project_url}">GitHub</a>.',
     CODE_CONTRIBUTION_INFO:
-        'Information on <a href="${code_contribution_url}">code contributions</a>',
+        '<a href="${code_contribution_url}">Here\'s</a> how to contribute code to the plugin.',
     TRANSLATION_CONTRIBUTION_INFO:
-        'Information on <a href="${translation_contribution_url}">translating the plugin</a> to your language',
+        '<a href="${translation_contribution_url}">Here\'s</a> how to translate the plugin to another language.',
     PROJECT_CONTRIBUTIONS:
         'Raise an issue <a href="${issues_url}">here</a> if you have a feature request or a bug report',
     FOLDERS_TO_IGNORE: "무시할 폴더들",
@@ -81,7 +82,7 @@ export default {
     FLASHCARD_EASY_DESC: 'Customize the label for the "Easy" Button',
     FLASHCARD_GOOD_DESC: 'Customize the label for the "Good" Button',
     FLASHCARD_HARD_DESC: 'Customize the label for the "Hard" Button',
-    REVIEW_BUTTON_DELAY: "Button press delay (ms)",
+    REVIEW_BUTTON_DELAY: "Button Press Delay (ms)",
     REVIEW_BUTTON_DELAY_DESC: "Add a delay to the review buttons before they can be pressed again.",
     FLASHCARD_TAGS: "플래시카드 태그",
     FLASHCARD_TAGS_DESC:
@@ -142,7 +143,7 @@ export default {
     MAX_N_DAYS_REVIEW_QUEUE: "오른쪽 패널에 표시할 최대 일수",
     MIN_ONE_DAY: "적어도 1이상이어야 합니다.",
     VALID_NUMBER_WARNING: "유효한 숫자를 입력해주세요.",
-    UI_PREFERENCES: "사용자 인터페이스 기본 설정",
+    UI: "User Interface",
     SHOW_STATUS_BAR: "Show status bar",
     SHOW_STATUS_BAR_DESC:
         "Turn this off to hide the flashcard's review status in Obsidian's status bar",
@@ -153,7 +154,8 @@ export default {
         "같은 카드에 중첩된 덱을 접으려면 이 옵션을 끄십시오. 같은 파일에 여러 덱에 속한 카드가 있는 경우 유용합니다.",
     ALGORITHM: "알고리즘",
     CHECK_ALGORITHM_WIKI:
-        '더 많은 정보를 원하시면, <a href="${algo_url}">algorithm implementation</a>을 확인해주세요.',
+        '더 많은 정보를 원하시면, <a href="${algo_url}">algorithm details</a>을 확인해주세요.',
+    SM2_OSR_VARIANT: "OSR's variant of SM-2",
     BASE_EASE: "기본 ease",
     BASE_EASE_DESC: "최솟값 = 130, 적정치는 대략 250입니다.",
     BASE_EASE_MIN_WARNING: "기본 ease는 적어도 130 이어야 합니다.",
@@ -170,9 +172,12 @@ export default {
     MAX_LINK_CONTRIB_DESC:
         "링크된 노트의 초기 ease에 대한 가중치가 적용된 ease의 최대 기여도입니다.",
     LOGGING: "로깅",
-    DISPLAY_DEBUG_INFO: "디버깅 정보를 개발자 콘솔에 표시하시겠습니까",
-    DISPLAY_PARSER_DEBUG_INFO:
-        "Display debugging information for the parser on the developer console",
+    DISPLAY_SCHEDULING_DEBUG_INFO: "디버깅 정보를 개발자 콘솔에 표시하시겠습니까",
+    DISPLAY_PARSER_DEBUG_INFO: "Show the parser's debugging information on the developer console",
+    SCHEDULING: "Scheduling",
+    EXPERIMENTAL: "Experimental",
+    HELP: "Help",
+    STORE_IN_NOTES: "In the notes",
 
     // sidebar.ts
     NOTES_REVIEW_QUEUE: "리뷰할 노트 대기열",
diff --git a/src/lang/locale/pl.ts b/src/lang/locale/pl.ts
index fe32d62..28b1a92 100644
--- a/src/lang/locale/pl.ts
+++ b/src/lang/locale/pl.ts
@@ -55,6 +55,7 @@ export default {
     GROUP_FLASHCARD_REVIEW: "Flashcard Review",
     GROUP_FLASHCARD_SEPARATORS: "Flashcard Separators",
     GROUP_DATA_STORAGE: "Storage of Scheduling Data",
+    GROUP_DATA_STORAGE_DESC: "Choose where to store the scheduling data",
     GROUP_FLASHCARDS_NOTES: "Flashcards & Notes",
     GROUP_CONTRIBUTING: "Contributing",
     CHECK_WIKI: 'Aby uzyskać więcej informacji, sprawdź <a href="${wiki_url}">wiki</a>.',
@@ -63,11 +64,11 @@ export default {
     GITHUB_ISSUES:
         'Raise an issue <a href="${issues_url}">here</a> if you have a feature request or a bug report.',
     GITHUB_SOURCE_CODE:
-        'Project source code available on <a href="${github_project_url}">GitHub</a>',
+        'The project\'s source code is available on <a href="${github_project_url}">GitHub</a>.',
     CODE_CONTRIBUTION_INFO:
-        'Information on <a href="${code_contribution_url}">code contributions</a>',
+        '<a href="${code_contribution_url}">Here\'s</a> how to contribute code to the plugin.',
     TRANSLATION_CONTRIBUTION_INFO:
-        'Information on <a href="${translation_contribution_url}">translating the plugin</a> to your language',
+        '<a href="${translation_contribution_url}">Here\'s</a> how to translate the plugin to another language.',
     PROJECT_CONTRIBUTIONS:
         'Raise an issue <a href="${issues_url}">here</a> if you have a feature request or a bug report',
     FOLDERS_TO_IGNORE: "Foldery do zignorowania",
@@ -81,7 +82,7 @@ export default {
     FLASHCARD_EASY_DESC: 'Dostosuj etykietę dla przycisku "Łatwe"',
     FLASHCARD_GOOD_DESC: 'Dostosuj etykietę dla przycisku "Średnio trudne"',
     FLASHCARD_HARD_DESC: 'Dostosuj etykietę dla przycisku "Trudne"',
-    REVIEW_BUTTON_DELAY: "Button press delay (ms)",
+    REVIEW_BUTTON_DELAY: "Button Press Delay (ms)",
     REVIEW_BUTTON_DELAY_DESC: "Add a delay to the review buttons before they can be pressed again.",
     FLASHCARD_TAGS: "Tagi fiszek",
     FLASHCARD_TAGS_DESC:
@@ -146,7 +147,7 @@ export default {
     MAX_N_DAYS_REVIEW_QUEUE: "Maksymalna liczba dni do wyświetlenia w panelu prawym",
     MIN_ONE_DAY: "Liczba dni musi wynosić co najmniej 1.",
     VALID_NUMBER_WARNING: "Podaj prawidłową liczbę.",
-    UI_PREFERENCES: "Preferencje interfejsu użytkownika",
+    UI: "User Interface",
     SHOW_STATUS_BAR: "Show status bar",
     SHOW_STATUS_BAR_DESC:
         "Turn this off to hide the flashcard's review status in Obsidian's status bar",
@@ -158,6 +159,7 @@ export default {
     ALGORITHM: "Algorytm",
     CHECK_ALGORITHM_WIKI:
         'Aby uzyskać więcej informacji, sprawdź <a href="${algo_url}">implementację algorytmu</a>.',
+    SM2_OSR_VARIANT: "OSR's variant of SM-2",
     BASE_EASE: "Podstawowa łatwość",
     BASE_EASE_DESC: "minimum = 130, preferowana wartość to około 250.",
     BASE_EASE_MIN_WARNING: "Podstawowa łatwość musi wynosić co najmniej 130.",
@@ -174,11 +176,14 @@ export default {
     MAX_LINK_CONTRIB_DESC:
         "Maksymalny wkład ważonej łatwości połączonych notatek do początkowej łatwości.",
     LOGGING: "Logowanie",
-    DISPLAY_DEBUG_INFO: "Wyświetl informacje debugowania w konsoli deweloperskiej", // sidebar.ts
-    DISPLAY_PARSER_DEBUG_INFO:
-        "Display debugging information for the parser on the developer console",
+    DISPLAY_SCHEDULING_DEBUG_INFO: "Wyświetl informacje debugowania w konsoli deweloperskiej",
+    DISPLAY_PARSER_DEBUG_INFO: "Show the parser's debugging information on the developer console",
+    SCHEDULING: "Scheduling",
+    EXPERIMENTAL: "Experimental",
+    HELP: "Help",
+    STORE_IN_NOTES: "In the notes",
 
-    //sidebar.ts
+    // sidebar.ts
     NOTES_REVIEW_QUEUE: "Kolejka przeglądu notatek",
     CLOSE: "Zamknij",
     NEW: "Nowe",
diff --git a/src/lang/locale/pt-br.ts b/src/lang/locale/pt-br.ts
index e9eafdf..d853921 100644
--- a/src/lang/locale/pt-br.ts
+++ b/src/lang/locale/pt-br.ts
@@ -57,6 +57,7 @@ export default {
     GROUP_FLASHCARD_REVIEW: "Flashcard Review",
     GROUP_FLASHCARD_SEPARATORS: "Flashcard Separators",
     GROUP_DATA_STORAGE: "Storage of Scheduling Data",
+    GROUP_DATA_STORAGE_DESC: "Choose where to store the scheduling data",
     GROUP_FLASHCARDS_NOTES: "Flashcards & Notes",
     GROUP_CONTRIBUTING: "Contributing",
     CHECK_WIKI: 'Para mais informações, cheque a <a href="${wiki_url}">wiki</a>.',
@@ -65,11 +66,11 @@ export default {
     GITHUB_ISSUES:
         'Raise an issue <a href="${issues_url}">here</a> if you have a feature request or a bug report.',
     GITHUB_SOURCE_CODE:
-        'Project source code available on <a href="${github_project_url}">GitHub</a>',
+        'The project\'s source code is available on <a href="${github_project_url}">GitHub</a>.',
     CODE_CONTRIBUTION_INFO:
-        'Information on <a href="${code_contribution_url}">code contributions</a>',
+        '<a href="${code_contribution_url}">Here\'s</a> how to contribute code to the plugin.',
     TRANSLATION_CONTRIBUTION_INFO:
-        'Information on <a href="${translation_contribution_url}">translating the plugin</a> to your language',
+        '<a href="${translation_contribution_url}">Here\'s</a> how to translate the plugin to another language.',
     PROJECT_CONTRIBUTIONS:
         'Raise an issue <a href="${issues_url}">here</a> if you have a feature request or a bug report',
     FOLDERS_TO_IGNORE: "Pastas para ignorar",
@@ -83,7 +84,7 @@ export default {
     FLASHCARD_EASY_DESC: 'Customize o rótulo para o botão de "Fácil"',
     FLASHCARD_GOOD_DESC: 'Customize o rótulo para o botão de "OK"',
     FLASHCARD_HARD_DESC: 'Customize o rótulo para o botão de "Difícil"',
-    REVIEW_BUTTON_DELAY: "Button press delay (ms)",
+    REVIEW_BUTTON_DELAY: "Button Press Delay (ms)",
     REVIEW_BUTTON_DELAY_DESC: "Add a delay to the review buttons before they can be pressed again.",
     FLASHCARD_TAGS: "Etiquetas dos Flashcards",
     FLASHCARD_TAGS_DESC:
@@ -145,7 +146,7 @@ export default {
     MAX_N_DAYS_REVIEW_QUEUE: "Número máximo de dias para exibir no painel direito",
     MIN_ONE_DAY: "O número de dias deve ser pelo menos 1.",
     VALID_NUMBER_WARNING: "Por favor Insira um número válido.",
-    UI_PREFERENCES: "Preferências de UI",
+    UI: "User Interface",
     SHOW_STATUS_BAR: "Show status bar",
     SHOW_STATUS_BAR_DESC:
         "Turn this off to hide the flashcard's review status in Obsidian's status bar",
@@ -158,6 +159,7 @@ export default {
     ALGORITHM: "Algorítmo",
     CHECK_ALGORITHM_WIKI:
         'Para mais informações, cheque a <a href="${algo_url}">implementação do algorítmo</a>.',
+    SM2_OSR_VARIANT: "OSR's variant of SM-2",
     BASE_EASE: "Facilidade base",
     BASE_EASE_DESC: "mínimo = 130, preferivelmente por volta de 250.",
     BASE_EASE_MIN_WARNING: "A facilidade base deve ser pelo menos 130.",
@@ -176,9 +178,12 @@ export default {
     MAX_LINK_CONTRIB_DESC:
         "Contribuição máxima da facilidade ponderada das notas linkadas à facilidade inicial.",
     LOGGING: "Logging",
-    DISPLAY_DEBUG_INFO: "Mostrar informação de debugging no console de desenvolvimento",
-    DISPLAY_PARSER_DEBUG_INFO:
-        "Display debugging information for the parser on the developer console",
+    DISPLAY_SCHEDULING_DEBUG_INFO: "Mostrar informação de debugging no console de desenvolvimento",
+    DISPLAY_PARSER_DEBUG_INFO: "Show the parser's debugging information on the developer console",
+    SCHEDULING: "Scheduling",
+    EXPERIMENTAL: "Experimental",
+    HELP: "Help",
+    STORE_IN_NOTES: "In the notes",
 
     // sidebar.ts
     NOTES_REVIEW_QUEUE: "Fila de Notas para Revisar",
diff --git a/src/lang/locale/ru.ts b/src/lang/locale/ru.ts
index e916273..897d3bd 100644
--- a/src/lang/locale/ru.ts
+++ b/src/lang/locale/ru.ts
@@ -64,6 +64,7 @@ export default {
     GROUP_FLASHCARD_REVIEW: "Flashcard Review",
     GROUP_FLASHCARD_SEPARATORS: "Flashcard Separators",
     GROUP_DATA_STORAGE: "Storage of Scheduling Data",
+    GROUP_DATA_STORAGE_DESC: "Choose where to store the scheduling data",
     GROUP_FLASHCARDS_NOTES: "Flashcards & Notes",
     GROUP_CONTRIBUTING: "Contributing",
     CHECK_WIKI: 'Для дополнительной информации посетите: <a href="${wiki_url}">wiki</a>.',
@@ -72,11 +73,11 @@ export default {
     GITHUB_ISSUES:
         'Raise an issue <a href="${issues_url}">here</a> if you have a feature request or a bug report.',
     GITHUB_SOURCE_CODE:
-        'Project source code available on <a href="${github_project_url}">GitHub</a>',
+        'The project\'s source code is available on <a href="${github_project_url}">GitHub</a>.',
     CODE_CONTRIBUTION_INFO:
-        'Information on <a href="${code_contribution_url}">code contributions</a>',
+        '<a href="${code_contribution_url}">Here\'s</a> how to contribute code to the plugin.',
     TRANSLATION_CONTRIBUTION_INFO:
-        'Information on <a href="${translation_contribution_url}">translating the plugin</a> to your language',
+        '<a href="${translation_contribution_url}">Here\'s</a> how to translate the plugin to another language.',
     PROJECT_CONTRIBUTIONS:
         'Raise an issue <a href="${issues_url}">here</a> if you have a feature request or a bug report',
     FOLDERS_TO_IGNORE: "Игнорируемые папки",
@@ -90,7 +91,7 @@ export default {
     FLASHCARD_EASY_DESC: 'Настроить ярлык для кнопки "Легко"',
     FLASHCARD_GOOD_DESC: 'Настроить ярлык для кнопки "Нормально"',
     FLASHCARD_HARD_DESC: 'Настроить ярлык для кнопки "Сложно"',
-    REVIEW_BUTTON_DELAY: "Button press delay (ms)",
+    REVIEW_BUTTON_DELAY: "Button Press Delay (ms)",
     REVIEW_BUTTON_DELAY_DESC: "Add a delay to the review buttons before they can be pressed again.",
     FLASHCARD_TAGS: "Теги карточек",
     FLASHCARD_TAGS_DESC:
@@ -152,7 +153,7 @@ export default {
     MAX_N_DAYS_REVIEW_QUEUE: "Наибольшее количество дней для отображение на панели справа",
     MIN_ONE_DAY: "Количество дней не меньше 1.",
     VALID_NUMBER_WARNING: "Пожалуйста, введите подходящее число.",
-    UI_PREFERENCES: "Пользовательский интерфейс - Настройки",
+    UI: "User Interface",
     SHOW_STATUS_BAR: "Show status bar",
     SHOW_STATUS_BAR_DESC:
         "Turn this off to hide the flashcard's review status in Obsidian's status bar",
@@ -165,6 +166,7 @@ export default {
     ALGORITHM: "Алгоритм",
     CHECK_ALGORITHM_WIKI:
         'За дополнительной информацией обращайтесь к <a href="${algo_url}">реализация алгоритма</a>.',
+    SM2_OSR_VARIANT: "OSR's variant of SM-2",
     BASE_EASE: "Базовая Лёгкость",
     BASE_EASE_DESC: "минимум = 130, предпочтительно около 250.",
     BASE_EASE_MIN_WARNING: "Лёгкость должна быть минимум 130.",
@@ -183,9 +185,12 @@ export default {
     MAX_LINK_CONTRIB_DESC:
         'Максимальный вклад среднего значения "Лёгкости" связанных заметок в начальную "Лёгкость".',
     LOGGING: "Журналирование",
-    DISPLAY_DEBUG_INFO: "Отображать отладочную информацию в консоли разработчика",
-    DISPLAY_PARSER_DEBUG_INFO:
-        "Display debugging information for the parser on the developer console",
+    DISPLAY_SCHEDULING_DEBUG_INFO: "Отображать отладочную информацию в консоли разработчика",
+    DISPLAY_PARSER_DEBUG_INFO: "Show the parser's debugging information on the developer console",
+    SCHEDULING: "Scheduling",
+    EXPERIMENTAL: "Experimental",
+    HELP: "Help",
+    STORE_IN_NOTES: "In the notes",
 
     // sidebar.ts
     NOTES_REVIEW_QUEUE: "Очередь заметок на повторение",
diff --git a/src/lang/locale/tr.ts b/src/lang/locale/tr.ts
index 4c50450..73a7ca5 100644
--- a/src/lang/locale/tr.ts
+++ b/src/lang/locale/tr.ts
@@ -55,6 +55,7 @@ export default {
     GROUP_FLASHCARD_REVIEW: "Flash Kartları Gözden Geçirme",
     GROUP_FLASHCARD_SEPARATORS: "Flash Kart Ayırıcıları",
     GROUP_DATA_STORAGE: "Planlama Verilerinin Saklanması",
+    GROUP_DATA_STORAGE_DESC: "Choose where to store the scheduling data",
     GROUP_FLASHCARDS_NOTES: "Flash Kartlar ve Notlar",
     GROUP_CONTRIBUTING: "Katkıda Bulunma",
     CHECK_WIKI: 'Daha fazla bilgi için <a href="${wiki_url}">wiki</a> sayfasına göz atın.',
@@ -81,7 +82,7 @@ export default {
     FLASHCARD_EASY_DESC: '"Kolay" butonunun metnini özelleştirin',
     FLASHCARD_GOOD_DESC: '"Orta" butonunun metnini özelleştirin',
     FLASHCARD_HARD_DESC: '"Zor" butonunun metnini özelleştirin',
-    REVIEW_BUTTON_DELAY: "Button press delay (ms)",
+    REVIEW_BUTTON_DELAY: "Button Press Delay (ms)",
     REVIEW_BUTTON_DELAY_DESC: "Add a delay to the review buttons before they can be pressed again.",
     FLASHCARD_TAGS: "Flash Kart Etiketleri",
     FLASHCARD_TAGS_DESC:
@@ -138,7 +139,7 @@ export default {
     MAX_N_DAYS_REVIEW_QUEUE: "Sağ panelde gösterilecek maksimum gün sayısı",
     MIN_ONE_DAY: "Gün sayısı en az 1 olmalıdır.",
     VALID_NUMBER_WARNING: "Lütfen geçerli bir sayı girin.",
-    UI_PREFERENCES: "Kullanıcı Arayüzü Tercihleri",
+    UI: "User Interface",
     SHOW_STATUS_BAR: "Show status bar",
     SHOW_STATUS_BAR_DESC:
         "Turn this off to hide the flashcard's review status in Obsidian's status bar",
@@ -155,6 +156,7 @@ export default {
     ALGORITHM: "Algoritma",
     CHECK_ALGORITHM_WIKI:
         'Daha fazla bilgi için <a href="${algo_url}">algoritma uygulamasına</a> göz atın.',
+    SM2_OSR_VARIANT: "OSR's variant of SM-2",
     BASE_EASE: "Temel kolaylık",
     BASE_EASE_DESC: "minimum = 130, tercihen yaklaşık 250.",
     BASE_EASE_MIN_WARNING: "Temel kolaylık en az 130 olmalıdır.",
@@ -171,9 +173,13 @@ export default {
     MAX_LINK_CONTRIB_DESC:
         "Bağlantılı notların ağırlıklı kolaylık değerinin başlangıç kolaylığına maksimum katkısı.",
     LOGGING: "Kayıt tutma",
-    DISPLAY_DEBUG_INFO: "Geliştirici konsolunda hata ayıklama bilgilerini göster",
+    DISPLAY_SCHEDULING_DEBUG_INFO: "Geliştirici konsolunda hata ayıklama bilgilerini göster",
     DISPLAY_PARSER_DEBUG_INFO:
         "Ayrıştırıcı için hata ayıklama bilgilerini geliştirici konsolunda göster",
+    SCHEDULING: "Scheduling",
+    EXPERIMENTAL: "Experimental",
+    HELP: "Help",
+    STORE_IN_NOTES: "In the notes",
 
     // sidebar.ts
     NOTES_REVIEW_QUEUE: "Not İnceleme Sırası",
diff --git a/src/lang/locale/zh-cn.ts b/src/lang/locale/zh-cn.ts
index ea8cb9f..bb9de82 100644
--- a/src/lang/locale/zh-cn.ts
+++ b/src/lang/locale/zh-cn.ts
@@ -55,6 +55,7 @@ export default {
     GROUP_FLASHCARD_REVIEW: "Flashcard Review",
     GROUP_FLASHCARD_SEPARATORS: "Flashcard Separators",
     GROUP_DATA_STORAGE: "Storage of Scheduling Data",
+    GROUP_DATA_STORAGE_DESC: "Choose where to store the scheduling data",
     GROUP_FLASHCARDS_NOTES: "Flashcards & Notes",
     GROUP_CONTRIBUTING: "Contributing",
     CHECK_WIKI: '了解更多, 请点击<a href="${wiki_url}">wiki</a>.',
@@ -63,11 +64,11 @@ export default {
     GITHUB_ISSUES:
         'Raise an issue <a href="${issues_url}">here</a> if you have a feature request or a bug report.',
     GITHUB_SOURCE_CODE:
-        'Project source code available on <a href="${github_project_url}">GitHub</a>',
+        'The project\'s source code is available on <a href="${github_project_url}">GitHub</a>.',
     CODE_CONTRIBUTION_INFO:
-        'Information on <a href="${code_contribution_url}">code contributions</a>',
+        '<a href="${code_contribution_url}">Here\'s</a> how to contribute code to the plugin.',
     TRANSLATION_CONTRIBUTION_INFO:
-        'Information on <a href="${translation_contribution_url}">translating the plugin</a> to your language',
+        '<a href="${translation_contribution_url}">Here\'s</a> how to translate the plugin to another language.',
     PROJECT_CONTRIBUTIONS:
         'Raise an issue <a href="${issues_url}">here</a> if you have a feature request or a bug report',
     FOLDERS_TO_IGNORE: "忽略此文件夹",
@@ -81,7 +82,7 @@ export default {
     FLASHCARD_EASY_DESC: "自定义“简单”按钮的标签",
     FLASHCARD_GOOD_DESC: "自定义“记得”按钮的标签",
     FLASHCARD_HARD_DESC: "自定义“较难”按钮的标签",
-    REVIEW_BUTTON_DELAY: "Button press delay (ms)",
+    REVIEW_BUTTON_DELAY: "Button Press Delay (ms)",
     REVIEW_BUTTON_DELAY_DESC: "Add a delay to the review buttons before they can be pressed again.",
     FLASHCARD_TAGS: "卡片标签",
     FLASHCARD_TAGS_DESC: "输入标签，用空格或新建行分隔，例如：#flashcards #deck2 #deck3.",
@@ -131,7 +132,7 @@ export default {
     MAX_N_DAYS_REVIEW_QUEUE: "右边栏中显示的最大天数",
     MIN_ONE_DAY: "天数最小值为1",
     VALID_NUMBER_WARNING: "请输入有效的数字。",
-    UI_PREFERENCES: "用户界面首选项",
+    UI: "User Interface",
     SHOW_STATUS_BAR: "Show status bar",
     SHOW_STATUS_BAR_DESC:
         "Turn this off to hide the flashcard's review status in Obsidian's status bar",
@@ -142,6 +143,7 @@ export default {
         "关闭此选项可折叠同一张卡片中的嵌套牌组。如果您的卡片属于同一文件中的许多套牌，则很有用。",
     ALGORITHM: "算法",
     CHECK_ALGORITHM_WIKI: '了解更多, 请点击<a href="${algo_url}">算法实现</a>.',
+    SM2_OSR_VARIANT: "OSR's variant of SM-2",
     BASE_EASE: "基础掌握程度",
     BASE_EASE_DESC: "最小值130，推荐值约250.",
     BASE_EASE_MIN_WARNING: "基础掌握程度的最小值为130。",
@@ -156,9 +158,12 @@ export default {
     MAX_LINK_CONTRIB: "最大链接收益",
     MAX_LINK_CONTRIB_DESC: "链接笔记的加权掌握程度对原始掌握程度的最大贡献。",
     LOGGING: "记录中",
-    DISPLAY_DEBUG_INFO: "在开发者控制台中显示调试信息",
-    DISPLAY_PARSER_DEBUG_INFO:
-        "Display debugging information for the parser on the developer console",
+    DISPLAY_SCHEDULING_DEBUG_INFO: "在开发者控制台中显示调试信息",
+    DISPLAY_PARSER_DEBUG_INFO: "Show the parser's debugging information on the developer console",
+    SCHEDULING: "Scheduling",
+    EXPERIMENTAL: "Experimental",
+    HELP: "Help",
+    STORE_IN_NOTES: "In the notes",
 
     // sidebar.ts
     NOTES_REVIEW_QUEUE: "笔记复习序列",
diff --git a/src/lang/locale/zh-tw.ts b/src/lang/locale/zh-tw.ts
index 2976fdd..4321d38 100644
--- a/src/lang/locale/zh-tw.ts
+++ b/src/lang/locale/zh-tw.ts
@@ -55,6 +55,7 @@ export default {
     GROUP_FLASHCARD_REVIEW: "Flashcard Review",
     GROUP_FLASHCARD_SEPARATORS: "Flashcard Separators",
     GROUP_DATA_STORAGE: "Storage of Scheduling Data",
+    GROUP_DATA_STORAGE_DESC: "Choose where to store the scheduling data",
     GROUP_FLASHCARDS_NOTES: "Flashcards & Notes",
     GROUP_CONTRIBUTING: "Contributing",
     CHECK_WIKI: '瞭解更多, 請點選<a href="${wiki_url}">wiki</a>.',
@@ -63,11 +64,11 @@ export default {
     GITHUB_ISSUES:
         'Raise an issue <a href="${issues_url}">here</a> if you have a feature request or a bug report.',
     GITHUB_SOURCE_CODE:
-        'Project source code available on <a href="${github_project_url}">GitHub</a>',
+        'The project\'s source code is available on <a href="${github_project_url}">GitHub</a>.',
     CODE_CONTRIBUTION_INFO:
-        'Information on <a href="${code_contribution_url}">code contributions</a>',
+        '<a href="${code_contribution_url}">Here\'s</a> how to contribute code to the plugin.',
     TRANSLATION_CONTRIBUTION_INFO:
-        'Information on <a href="${translation_contribution_url}">translating the plugin</a> to your language',
+        '<a href="${translation_contribution_url}">Here\'s</a> how to translate the plugin to another language.',
     PROJECT_CONTRIBUTIONS:
         'Raise an issue <a href="${issues_url}">here</a> if you have a feature request or a bug report',
     FOLDERS_TO_IGNORE: "忽略此資料夾",
@@ -81,7 +82,7 @@ export default {
     FLASHCARD_EASY_DESC: "自訂「簡單」按鈕的標籤",
     FLASHCARD_GOOD_DESC: "自訂「記得」按鈕的標籤",
     FLASHCARD_HARD_DESC: "自訂「較難」按鈕的標籤",
-    REVIEW_BUTTON_DELAY: "Button press delay (ms)",
+    REVIEW_BUTTON_DELAY: "Button Press Delay (ms)",
     REVIEW_BUTTON_DELAY_DESC: "Add a delay to the review buttons before they can be pressed again.",
     FLASHCARD_TAGS: "卡片標籤",
     FLASHCARD_TAGS_DESC: "輸入標籤（用空白或換行字元分隔），例如：#flashcards #deck2 #deck3.",
@@ -131,7 +132,7 @@ export default {
     MAX_N_DAYS_REVIEW_QUEUE: "右邊面板顯示的最大天數",
     MIN_ONE_DAY: "天數最小值為1",
     VALID_NUMBER_WARNING: "請輸入有效的數字。",
-    UI_PREFERENCES: "用戶介面首選項",
+    UI: "User Interface",
     SHOW_STATUS_BAR: "Show status bar",
     SHOW_STATUS_BAR_DESC:
         "Turn this off to hide the flashcard's review status in Obsidian's status bar",
@@ -142,6 +143,7 @@ export default {
         "關閉此選項可摺疊同一張卡片中的巢狀牌組。如果您的卡片屬於同一檔案中的許多套牌，則很有用。",
     ALGORITHM: "演算法",
     CHECK_ALGORITHM_WIKI: '瞭解更多, 請點選<a href="${algo_url}">算法實現</a>.',
+    SM2_OSR_VARIANT: "OSR's variant of SM-2",
     BASE_EASE: "基礎掌握程度",
     BASE_EASE_DESC: "最小值130，推薦值約250.",
     BASE_EASE_MIN_WARNING: "基礎掌握程度的最小值為130。",
@@ -156,9 +158,12 @@ export default {
     MAX_LINK_CONTRIB: "最大鏈接貢獻",
     MAX_LINK_CONTRIB_DESC: "鏈接筆記的加權掌握程度對原始掌握程度的最大貢獻。",
     LOGGING: "記錄中",
-    DISPLAY_DEBUG_INFO: "在開發者控制台中顯示除錯資訊",
-    DISPLAY_PARSER_DEBUG_INFO:
-        "Display debugging information for the parser on the developer console",
+    DISPLAY_SCHEDULING_DEBUG_INFO: "在開發者控制台中顯示除錯資訊",
+    DISPLAY_PARSER_DEBUG_INFO: "Show the parser's debugging information on the developer console",
+    SCHEDULING: "Scheduling",
+    EXPERIMENTAL: "Experimental",
+    HELP: "Help",
+    STORE_IN_NOTES: "In the notes",
 
     // sidebar.ts
     NOTES_REVIEW_QUEUE: "筆記復習序列",
diff --git a/src/main.ts b/src/main.ts
index faa40bb..a69582f 100644
--- a/src/main.ts
+++ b/src/main.ts
@@ -8,7 +8,7 @@ import { OsrAppCore } from "src/app-core";
 import { DataStoreAlgorithm } from "src/data-store-algorithm/data-store-algorithm";
 import { DataStoreInNote_AlgorithmOsr } from "src/data-store-algorithm/data-store-in-note-algorithm-osr";
 import { DataStore } from "src/data-stores/base/data-store";
-import { StoreInNote } from "src/data-stores/store-in-note/note";
+import { StoreInNotes } from "src/data-stores/notes/notes";
 import { CardListType, Deck, DeckTreeFilter } from "src/deck";
 import {
     CardOrder,
@@ -353,7 +353,7 @@ export default class SRPlugin extends Plugin {
 
         await this.osrAppCore.loadVault();
 
-        if (this.data.settings.showDebugMessages) {
+        if (this.data.settings.showSchedulingDebugMessages) {
             console.log(`SR: ${t("DECKS")}`, this.osrAppCore.reviewableDeckTree);
             console.log(
                 "SR: " +
@@ -436,14 +436,14 @@ export default class SRPlugin extends Plugin {
         if (loadedData?.settings) upgradeSettings(loadedData.settings);
         this.data = Object.assign({}, DEFAULT_DATA, loadedData);
         this.data.settings = Object.assign({}, DEFAULT_SETTINGS, this.data.settings);
-        setDebugParser(this.data.settings.showPaserDebugMessages);
+        setDebugParser(this.data.settings.showParserDebugMessages);
 
         this.setupDataStoreAndAlgorithmInstances(this.data.settings);
     }
 
     setupDataStoreAndAlgorithmInstances(settings: SRSettings) {
-        // For now we can hardcoded as we only support the one data store and one algorithm
-        DataStore.instance = new StoreInNote(settings);
+        // For now we can hardcode as we only support the one data store and one algorithm
+        DataStore.instance = new StoreInNotes(settings);
         SrsAlgorithm.instance = new SrsAlgorithm_Osr(settings);
         DataStoreAlgorithm.instance = new DataStoreInNote_AlgorithmOsr(settings);
     }
diff --git a/src/settings.ts b/src/settings.ts
index c19ea8b..10c0493 100644
--- a/src/settings.ts
+++ b/src/settings.ts
@@ -1,5 +1,7 @@
 import { App, Notice, Platform, PluginSettingTab, Setting } from "obsidian";
 
+import { Algorithm } from "src/algorithms/base/isrs-algorithm";
+import { DataStoreName } from "src/data-stores/base/data-store";
 import { createTabs, TabStructure } from "src/gui/tabs";
 import { t } from "src/lang/helpers";
 import type SRPlugin from "src/main";
@@ -14,7 +16,6 @@ export interface SRSettings {
     reviewButtonDelay: number;
     flashcardTags: string[];
     convertFoldersToDecks: boolean;
-    cardCommentOnSameLine: boolean;
     burySiblingCards: boolean;
     showContextInCards: boolean;
     flashcardHeightPercentage: number;
@@ -47,15 +48,20 @@ export interface SRSettings {
     initiallyExpandAllSubdecksInTree: boolean;
 
     // algorithm
+    algorithm: string;
     baseEase: number;
     lapsesIntervalChange: number;
     easyBonus: number;
     maximumInterval: number;
     maxLinkFactor: number;
 
+    // storage
+    dataStore: string;
+    cardCommentOnSameLine: boolean;
+
     // logging
-    showDebugMessages: boolean;
-    showPaserDebugMessages: boolean;
+    showSchedulingDebugMessages: boolean;
+    showParserDebugMessages: boolean;
 }
 
 export const DEFAULT_SETTINGS: SRSettings = {
@@ -66,7 +72,6 @@ export const DEFAULT_SETTINGS: SRSettings = {
     reviewButtonDelay: 0,
     flashcardTags: ["#flashcards"],
     convertFoldersToDecks: false,
-    cardCommentOnSameLine: false,
     burySiblingCards: false,
     showContextInCards: true,
     flashcardHeightPercentage: Platform.isMobile ? 100 : 80,
@@ -99,15 +104,20 @@ export const DEFAULT_SETTINGS: SRSettings = {
     initiallyExpandAllSubdecksInTree: false,
 
     // algorithm
+    algorithm: Algorithm.SM_2_OSR,
     baseEase: 250,
     lapsesIntervalChange: 0.5,
     easyBonus: 1.3,
     maximumInterval: 36525,
     maxLinkFactor: 1.0,
 
+    // storage
+    dataStore: DataStoreName.NOTES,
+    cardCommentOnSameLine: false,
+
     // logging
-    showDebugMessages: false,
-    showPaserDebugMessages: false,
+    showSchedulingDebugMessages: false,
+    showParserDebugMessages: false,
 };
 
 export function upgradeSettings(settings: SRSettings) {
@@ -116,7 +126,6 @@ export function upgradeSettings(settings: SRSettings) {
         settings.flashcardCardOrder == null &&
         settings.flashcardDeckOrder == null
     ) {
-        console.log(`loadPluginData: Upgrading settings: ${settings.randomizeCardOrder}`);
         settings.flashcardCardOrder = settings.randomizeCardOrder
             ? "DueFirstRandom"
             : "DueFirstSequential";
@@ -201,37 +210,37 @@ export class SRSettingTab extends PluginSettingTab {
             {
                 "main-flashcards": {
                     title: t("FLASHCARDS"),
-                    icon: null, // "SpacedRepIcon",
+                    icon: "SpacedRepIcon",
                     content_generator: (container_element: HTMLElement) =>
                         this.tabFlashcards(container_element),
                 },
                 "main-notes": {
                     title: t("NOTES"),
-                    icon: null, // "note-glyph",
+                    icon: "book-text",
                     content_generator: (container_element: HTMLElement) =>
                         this.tabNotes(container_element),
                 },
                 "main-algorithm": {
-                    title: "Algorithm",
-                    icon: null, // "dot-network",
+                    title: t("SCHEDULING"),
+                    icon: "calendar",
                     content_generator: (container_element: HTMLElement) =>
-                        this.tabAlgorithm(container_element),
+                        this.tabScheduling(container_element),
                 },
                 "main-ui-preferences": {
-                    title: t("UI_PREFERENCES"),
-                    icon: null, // "presentation",
+                    title: t("UI"),
+                    icon: "presentation",
                     content_generator: (container_element: HTMLElement) =>
                         this.tabUiPreferences(container_element),
                 },
-                "main-developer": {
-                    title: "Developer",
-                    icon: null, // "code-glyph",
+                "main-experimental": {
+                    title: t("STATS_TITLE"),
+                    icon: "bar-chart-3",
                     content_generator: (container_element: HTMLElement) =>
-                        this.tabDeveloper(container_element),
+                        this.tabExperimental(container_element),
                 },
                 "main-help": {
-                    title: "Help",
-                    icon: null, // "help",
+                    title: t("HELP"),
+                    icon: "badge-help",
                     content_generator: (container_element: HTMLElement) =>
                         this.tabHelp(container_element),
                 },
@@ -240,8 +249,8 @@ export class SRSettingTab extends PluginSettingTab {
         );
 
         // KEEP THIS AFTER CREATING ALL ELEMENTS:
-        // Scroll to the position when the settings modal was last open, but do it after content generating has finished.
-        // In practise, shell command previews may take some time to appear.
+        // Scroll to the position when the settings modal was last open,
+        //  but do it after content generating has finished.
         this.tab_structure.contentGeneratorPromises[this.tab_structure.active_tab_id].then(() => {
             this.rememberLastPosition(containerEl);
         });
@@ -249,302 +258,271 @@ export class SRSettingTab extends PluginSettingTab {
 
     private async tabFlashcards(containerEl: HTMLElement): Promise<void> {
         containerEl.createEl("h3", { text: t("GROUP_TAGS_FOLDERS") });
-        {
-            new Setting(containerEl)
-                .setName(t("FLASHCARD_TAGS"))
-                .setDesc(t("FLASHCARD_TAGS_DESC"))
-                .addTextArea((text) =>
-                    text
-                        .setValue(this.plugin.data.settings.flashcardTags.join(" "))
-                        .onChange((value) => {
-                            applySettingsUpdate(async () => {
-                                this.plugin.data.settings.flashcardTags = value.split(/\s+/);
-                                await this.plugin.savePluginData();
-                            });
-                        }),
-                );
-
-            new Setting(containerEl)
-                .setName(t("CONVERT_FOLDERS_TO_DECKS"))
-                .setDesc(t("CONVERT_FOLDERS_TO_DECKS_DESC"))
-                .addToggle((toggle) =>
-                    toggle
-                        .setValue(this.plugin.data.settings.convertFoldersToDecks)
-                        .onChange(async (value) => {
-                            this.plugin.data.settings.convertFoldersToDecks = value;
+        new Setting(containerEl)
+            .setName(t("FLASHCARD_TAGS"))
+            .setDesc(t("FLASHCARD_TAGS_DESC"))
+            .addTextArea((text) =>
+                text
+                    .setValue(this.plugin.data.settings.flashcardTags.join(" "))
+                    .onChange((value) => {
+                        applySettingsUpdate(async () => {
+                            this.plugin.data.settings.flashcardTags = value.split(/\s+/);
                             await this.plugin.savePluginData();
-                        }),
-                );
-            this.createSetting_FoldersToIgnore(containerEl);
-        }
+                        });
+                    }),
+            );
 
-        containerEl.createEl("h3", { text: t("GROUP_FLASHCARD_REVIEW") });
-        {
-            new Setting(containerEl)
-                .setName(t("BURY_SIBLINGS_TILL_NEXT_DAY"))
-                .setDesc(t("BURY_SIBLINGS_TILL_NEXT_DAY_DESC"))
-                .addToggle((toggle) =>
-                    toggle
-                        .setValue(this.plugin.data.settings.burySiblingCards)
-                        .onChange(async (value) => {
-                            this.plugin.data.settings.burySiblingCards = value;
-                            await this.plugin.savePluginData();
-                        }),
-                );
-
-            new Setting(containerEl)
-                .setName(t("REVIEW_CARD_ORDER_WITHIN_DECK"))
-                .addDropdown((dropdown) =>
-                    dropdown
-                        .addOptions({
-                            NewFirstSequential: t("REVIEW_CARD_ORDER_NEW_FIRST_SEQUENTIAL"),
-                            DueFirstSequential: t("REVIEW_CARD_ORDER_DUE_FIRST_SEQUENTIAL"),
-                            NewFirstRandom: t("REVIEW_CARD_ORDER_NEW_FIRST_RANDOM"),
-                            DueFirstRandom: t("REVIEW_CARD_ORDER_DUE_FIRST_RANDOM"),
-                            EveryCardRandomDeckAndCard: t("REVIEW_CARD_ORDER_RANDOM_DECK_AND_CARD"),
-                        })
-                        .setValue(this.plugin.data.settings.flashcardCardOrder)
-                        .onChange(async (value) => {
-                            this.plugin.data.settings.flashcardCardOrder = value;
-                            await this.plugin.savePluginData();
+        new Setting(containerEl)
+            .setName(t("CONVERT_FOLDERS_TO_DECKS"))
+            .setDesc(t("CONVERT_FOLDERS_TO_DECKS_DESC"))
+            .addToggle((toggle) =>
+                toggle
+                    .setValue(this.plugin.data.settings.convertFoldersToDecks)
+                    .onChange(async (value) => {
+                        this.plugin.data.settings.convertFoldersToDecks = value;
+                        await this.plugin.savePluginData();
+                    }),
+            );
 
-                            // Need to redisplay as changing this setting affects the "deck order" setting
-                            this.display();
-                        }),
-                );
+        this.createSetting_FoldersToIgnore(containerEl);
 
-            const deckOrderEnabled: boolean =
-                this.plugin.data.settings.flashcardCardOrder != "EveryCardRandomDeckAndCard";
-            new Setting(containerEl).setName(t("REVIEW_DECK_ORDER")).addDropdown((dropdown) =>
+        containerEl.createEl("h3", { text: t("GROUP_FLASHCARD_REVIEW") });
+        new Setting(containerEl)
+            .setName(t("BURY_SIBLINGS_TILL_NEXT_DAY"))
+            .setDesc(t("BURY_SIBLINGS_TILL_NEXT_DAY_DESC"))
+            .addToggle((toggle) =>
+                toggle
+                    .setValue(this.plugin.data.settings.burySiblingCards)
+                    .onChange(async (value) => {
+                        this.plugin.data.settings.burySiblingCards = value;
+                        await this.plugin.savePluginData();
+                    }),
+            );
+
+        new Setting(containerEl)
+            .setName(t("REVIEW_CARD_ORDER_WITHIN_DECK"))
+            .addDropdown((dropdown) =>
                 dropdown
-                    .addOptions(
-                        deckOrderEnabled
-                            ? {
-                                  PrevDeckComplete_Sequential: t(
-                                      "REVIEW_DECK_ORDER_PREV_DECK_COMPLETE_SEQUENTIAL",
-                                  ),
-                                  PrevDeckComplete_Random: t(
-                                      "REVIEW_DECK_ORDER_PREV_DECK_COMPLETE_RANDOM",
-                                  ),
-                              }
-                            : {
-                                  EveryCardRandomDeckAndCard: t(
-                                      "REVIEW_DECK_ORDER_RANDOM_DECK_AND_CARD",
-                                  ),
-                              },
-                    )
-                    .setValue(
-                        deckOrderEnabled
-                            ? this.plugin.data.settings.flashcardDeckOrder
-                            : "EveryCardRandomDeckAndCard",
-                    )
-                    .setDisabled(!deckOrderEnabled)
+                    .addOptions({
+                        NewFirstSequential: t("REVIEW_CARD_ORDER_NEW_FIRST_SEQUENTIAL"),
+                        DueFirstSequential: t("REVIEW_CARD_ORDER_DUE_FIRST_SEQUENTIAL"),
+                        NewFirstRandom: t("REVIEW_CARD_ORDER_NEW_FIRST_RANDOM"),
+                        DueFirstRandom: t("REVIEW_CARD_ORDER_DUE_FIRST_RANDOM"),
+                        EveryCardRandomDeckAndCard: t("REVIEW_CARD_ORDER_RANDOM_DECK_AND_CARD"),
+                    })
+                    .setValue(this.plugin.data.settings.flashcardCardOrder)
                     .onChange(async (value) => {
-                        this.plugin.data.settings.flashcardDeckOrder = value;
+                        this.plugin.data.settings.flashcardCardOrder = value;
                         await this.plugin.savePluginData();
+
+                        // Need to redisplay as changing this setting affects the "deck order" setting
+                        this.display();
                     }),
             );
-        }
+
+        const deckOrderEnabled: boolean =
+            this.plugin.data.settings.flashcardCardOrder != "EveryCardRandomDeckAndCard";
+        new Setting(containerEl).setName(t("REVIEW_DECK_ORDER")).addDropdown((dropdown) =>
+            dropdown
+                .addOptions(
+                    deckOrderEnabled
+                        ? {
+                              PrevDeckComplete_Sequential: t(
+                                  "REVIEW_DECK_ORDER_PREV_DECK_COMPLETE_SEQUENTIAL",
+                              ),
+                              PrevDeckComplete_Random: t(
+                                  "REVIEW_DECK_ORDER_PREV_DECK_COMPLETE_RANDOM",
+                              ),
+                          }
+                        : {
+                              EveryCardRandomDeckAndCard: t(
+                                  "REVIEW_DECK_ORDER_RANDOM_DECK_AND_CARD",
+                              ),
+                          },
+                )
+                .setValue(
+                    deckOrderEnabled
+                        ? this.plugin.data.settings.flashcardDeckOrder
+                        : "EveryCardRandomDeckAndCard",
+                )
+                .setDisabled(!deckOrderEnabled)
+                .onChange(async (value) => {
+                    this.plugin.data.settings.flashcardDeckOrder = value;
+                    await this.plugin.savePluginData();
+                }),
+        );
 
         containerEl.createEl("h3", { text: t("GROUP_FLASHCARD_SEPARATORS") });
-        {
-            new Setting(containerEl)
-                .setName(t("CONVERT_HIGHLIGHTS_TO_CLOZES"))
-                .addToggle((toggle) =>
-                    toggle
-                        .setValue(this.plugin.data.settings.convertHighlightsToClozes)
-                        .onChange(async (value) => {
-                            this.plugin.data.settings.convertHighlightsToClozes = value;
-                            this.plugin.debouncedGenerateParser();
-                            await this.plugin.savePluginData();
-                        }),
-                );
+        new Setting(containerEl).setName(t("CONVERT_HIGHLIGHTS_TO_CLOZES")).addToggle((toggle) =>
+            toggle
+                .setValue(this.plugin.data.settings.convertHighlightsToClozes)
+                .onChange(async (value) => {
+                    this.plugin.data.settings.convertHighlightsToClozes = value;
+                    this.plugin.debouncedGenerateParser();
+                    await this.plugin.savePluginData();
+                }),
+        );
 
-            new Setting(containerEl).setName(t("CONVERT_BOLD_TEXT_TO_CLOZES")).addToggle((toggle) =>
+        new Setting(containerEl).setName(t("CONVERT_BOLD_TEXT_TO_CLOZES")).addToggle((toggle) =>
+            toggle
+                .setValue(this.plugin.data.settings.convertBoldTextToClozes)
+                .onChange(async (value) => {
+                    this.plugin.data.settings.convertBoldTextToClozes = value;
+                    this.plugin.debouncedGenerateParser();
+                    await this.plugin.savePluginData();
+                }),
+        );
+
+        new Setting(containerEl)
+            .setName(t("CONVERT_CURLY_BRACKETS_TO_CLOZES"))
+            .addToggle((toggle) =>
                 toggle
-                    .setValue(this.plugin.data.settings.convertBoldTextToClozes)
+                    .setValue(this.plugin.data.settings.convertCurlyBracketsToClozes)
                     .onChange(async (value) => {
-                        this.plugin.data.settings.convertBoldTextToClozes = value;
+                        this.plugin.data.settings.convertCurlyBracketsToClozes = value;
                         this.plugin.debouncedGenerateParser();
                         await this.plugin.savePluginData();
                     }),
             );
 
-            new Setting(containerEl)
-                .setName(t("CONVERT_CURLY_BRACKETS_TO_CLOZES"))
-                .addToggle((toggle) =>
-                    toggle
-                        .setValue(this.plugin.data.settings.convertCurlyBracketsToClozes)
-                        .onChange(async (value) => {
-                            this.plugin.data.settings.convertCurlyBracketsToClozes = value;
-                            this.plugin.debouncedGenerateParser();
-                            await this.plugin.savePluginData();
-                        }),
-                );
-
-            new Setting(containerEl)
-                .setName(t("INLINE_CARDS_SEPARATOR"))
-                .setDesc(t("FIX_SEPARATORS_MANUALLY_WARNING"))
-                .addText((text) =>
-                    text
-                        .setValue(this.plugin.data.settings.singleLineCardSeparator)
-                        .onChange((value) => {
-                            applySettingsUpdate(async () => {
-                                this.plugin.data.settings.singleLineCardSeparator = value;
-                                this.plugin.debouncedGenerateParser();
-                                await this.plugin.savePluginData();
-                            });
-                        }),
-                )
-                .addExtraButton((button) => {
-                    button
-                        .setIcon("reset")
-                        .setTooltip(t("RESET_DEFAULT"))
-                        .onClick(async () => {
-                            this.plugin.data.settings.singleLineCardSeparator =
-                                DEFAULT_SETTINGS.singleLineCardSeparator;
+        new Setting(containerEl)
+            .setName(t("INLINE_CARDS_SEPARATOR"))
+            .setDesc(t("FIX_SEPARATORS_MANUALLY_WARNING"))
+            .addText((text) =>
+                text
+                    .setValue(this.plugin.data.settings.singleLineCardSeparator)
+                    .onChange((value) => {
+                        applySettingsUpdate(async () => {
+                            this.plugin.data.settings.singleLineCardSeparator = value;
                             this.plugin.debouncedGenerateParser();
                             await this.plugin.savePluginData();
-                            this.display();
                         });
-                });
-
-            new Setting(containerEl)
-                .setName(t("INLINE_REVERSED_CARDS_SEPARATOR"))
-                .setDesc(t("FIX_SEPARATORS_MANUALLY_WARNING"))
-                .addText((text) =>
-                    text
-                        .setValue(this.plugin.data.settings.singleLineReversedCardSeparator)
-                        .onChange((value) => {
-                            applySettingsUpdate(async () => {
-                                this.plugin.data.settings.singleLineReversedCardSeparator = value;
-                                this.plugin.debouncedGenerateParser();
-                                await this.plugin.savePluginData();
-                            });
-                        }),
-                )
-                .addExtraButton((button) => {
-                    button
-                        .setIcon("reset")
-                        .setTooltip(t("RESET_DEFAULT"))
-                        .onClick(async () => {
-                            this.plugin.data.settings.singleLineReversedCardSeparator =
-                                DEFAULT_SETTINGS.singleLineReversedCardSeparator;
+                    }),
+            )
+            .addExtraButton((button) => {
+                button
+                    .setIcon("reset")
+                    .setTooltip(t("RESET_DEFAULT"))
+                    .onClick(async () => {
+                        this.plugin.data.settings.singleLineCardSeparator =
+                            DEFAULT_SETTINGS.singleLineCardSeparator;
+                        this.plugin.debouncedGenerateParser();
+                        await this.plugin.savePluginData();
+                        this.display();
+                    });
+            });
+
+        new Setting(containerEl)
+            .setName(t("INLINE_REVERSED_CARDS_SEPARATOR"))
+            .setDesc(t("FIX_SEPARATORS_MANUALLY_WARNING"))
+            .addText((text) =>
+                text
+                    .setValue(this.plugin.data.settings.singleLineReversedCardSeparator)
+                    .onChange((value) => {
+                        applySettingsUpdate(async () => {
+                            this.plugin.data.settings.singleLineReversedCardSeparator = value;
                             this.plugin.debouncedGenerateParser();
                             await this.plugin.savePluginData();
-                            this.display();
                         });
-                });
-
-            new Setting(containerEl)
-                .setName(t("MULTILINE_CARDS_SEPARATOR"))
-                .setDesc(t("FIX_SEPARATORS_MANUALLY_WARNING"))
-                .addText((text) =>
-                    text
-                        .setValue(this.plugin.data.settings.multilineCardSeparator)
-                        .onChange((value) => {
-                            applySettingsUpdate(async () => {
-                                this.plugin.data.settings.multilineCardSeparator = value;
-                                this.plugin.debouncedGenerateParser();
-                                await this.plugin.savePluginData();
-                            });
-                        }),
-                )
-                .addExtraButton((button) => {
-                    button
-                        .setIcon("reset")
-                        .setTooltip(t("RESET_DEFAULT"))
-                        .onClick(async () => {
-                            this.plugin.data.settings.multilineCardSeparator =
-                                DEFAULT_SETTINGS.multilineCardSeparator;
+                    }),
+            )
+            .addExtraButton((button) => {
+                button
+                    .setIcon("reset")
+                    .setTooltip(t("RESET_DEFAULT"))
+                    .onClick(async () => {
+                        this.plugin.data.settings.singleLineReversedCardSeparator =
+                            DEFAULT_SETTINGS.singleLineReversedCardSeparator;
+                        this.plugin.debouncedGenerateParser();
+                        await this.plugin.savePluginData();
+                        this.display();
+                    });
+            });
+
+        new Setting(containerEl)
+            .setName(t("MULTILINE_CARDS_SEPARATOR"))
+            .setDesc(t("FIX_SEPARATORS_MANUALLY_WARNING"))
+            .addText((text) =>
+                text
+                    .setValue(this.plugin.data.settings.multilineCardSeparator)
+                    .onChange((value) => {
+                        applySettingsUpdate(async () => {
+                            this.plugin.data.settings.multilineCardSeparator = value;
                             this.plugin.debouncedGenerateParser();
                             await this.plugin.savePluginData();
-                            this.display();
                         });
-                });
-
-            new Setting(containerEl)
-                .setName(t("MULTILINE_REVERSED_CARDS_SEPARATOR"))
-                .setDesc(t("FIX_SEPARATORS_MANUALLY_WARNING"))
-                .addText((text) =>
-                    text
-                        .setValue(this.plugin.data.settings.multilineReversedCardSeparator)
-                        .onChange((value) => {
-                            applySettingsUpdate(async () => {
-                                this.plugin.data.settings.multilineReversedCardSeparator = value;
-                                this.plugin.debouncedGenerateParser();
-                                await this.plugin.savePluginData();
-                            });
-                        }),
-                )
-                .addExtraButton((button) => {
-                    button
-                        .setIcon("reset")
-                        .setTooltip(t("RESET_DEFAULT"))
-                        .onClick(async () => {
-                            this.plugin.data.settings.multilineReversedCardSeparator =
-                                DEFAULT_SETTINGS.multilineReversedCardSeparator;
+                    }),
+            )
+            .addExtraButton((button) => {
+                button
+                    .setIcon("reset")
+                    .setTooltip(t("RESET_DEFAULT"))
+                    .onClick(async () => {
+                        this.plugin.data.settings.multilineCardSeparator =
+                            DEFAULT_SETTINGS.multilineCardSeparator;
+                        this.plugin.debouncedGenerateParser();
+                        await this.plugin.savePluginData();
+                        this.display();
+                    });
+            });
+
+        new Setting(containerEl)
+            .setName(t("MULTILINE_REVERSED_CARDS_SEPARATOR"))
+            .setDesc(t("FIX_SEPARATORS_MANUALLY_WARNING"))
+            .addText((text) =>
+                text
+                    .setValue(this.plugin.data.settings.multilineReversedCardSeparator)
+                    .onChange((value) => {
+                        applySettingsUpdate(async () => {
+                            this.plugin.data.settings.multilineReversedCardSeparator = value;
                             this.plugin.debouncedGenerateParser();
                             await this.plugin.savePluginData();
-                            this.display();
                         });
-                });
-
-            new Setting(containerEl)
-                .setName(t("MULTILINE_CARDS_END_MARKER"))
-                .setDesc(t("FIX_SEPARATORS_MANUALLY_WARNING"))
-                .addText((text) =>
-                    text
-                        .setValue(this.plugin.data.settings.multilineCardEndMarker)
-                        .onChange((value) => {
-                            applySettingsUpdate(async () => {
-                                this.plugin.data.settings.multilineCardEndMarker = value;
-                                this.plugin.debouncedGenerateParser();
-                                await this.plugin.savePluginData();
-                            });
-                        }),
-                )
-                .addExtraButton((button) => {
-                    button
-                        .setIcon("reset")
-                        .setTooltip(t("RESET_DEFAULT"))
-                        .onClick(async () => {
-                            this.plugin.data.settings.multilineCardEndMarker =
-                                DEFAULT_SETTINGS.multilineCardEndMarker;
+                    }),
+            )
+            .addExtraButton((button) => {
+                button
+                    .setIcon("reset")
+                    .setTooltip(t("RESET_DEFAULT"))
+                    .onClick(async () => {
+                        this.plugin.data.settings.multilineReversedCardSeparator =
+                            DEFAULT_SETTINGS.multilineReversedCardSeparator;
+                        this.plugin.debouncedGenerateParser();
+                        await this.plugin.savePluginData();
+                        this.display();
+                    });
+            });
+
+        new Setting(containerEl)
+            .setName(t("MULTILINE_CARDS_END_MARKER"))
+            .setDesc(t("FIX_SEPARATORS_MANUALLY_WARNING"))
+            .addText((text) =>
+                text
+                    .setValue(this.plugin.data.settings.multilineCardEndMarker)
+                    .onChange((value) => {
+                        applySettingsUpdate(async () => {
+                            this.plugin.data.settings.multilineCardEndMarker = value;
                             this.plugin.debouncedGenerateParser();
                             await this.plugin.savePluginData();
-                            this.display();
                         });
-                });
-        }
-
-        containerEl.createEl("h3", { text: t("GROUP_DATA_STORAGE") });
-        {
-            new Setting(containerEl)
-                .setName(t("INLINE_SCHEDULING_COMMENTS"))
-                .setDesc(t("INLINE_SCHEDULING_COMMENTS_DESC"))
-                .addToggle((toggle) =>
-                    toggle
-                        .setValue(this.plugin.data.settings.cardCommentOnSameLine)
-                        .onChange(async (value) => {
-                            this.plugin.data.settings.cardCommentOnSameLine = value;
-                            await this.plugin.savePluginData();
-                        }),
-                );
-        }
+                    }),
+            )
+            .addExtraButton((button) => {
+                button
+                    .setIcon("reset")
+                    .setTooltip(t("RESET_DEFAULT"))
+                    .onClick(async () => {
+                        this.plugin.data.settings.multilineCardEndMarker =
+                            DEFAULT_SETTINGS.multilineCardEndMarker;
+                        this.plugin.debouncedGenerateParser();
+                        await this.plugin.savePluginData();
+                        this.display();
+                    });
+            });
     }
 
     private async tabNotes(containerEl: HTMLElement): Promise<void> {
-        containerEl.createEl("br");
-        new Setting(containerEl).setName(t("REVIEW_PANE_ON_STARTUP")).addToggle((toggle) =>
-            toggle
-                .setValue(this.plugin.data.settings.enableNoteReviewPaneOnStartup)
-                .onChange(async (value) => {
-                    this.plugin.data.settings.enableNoteReviewPaneOnStartup = value;
-                    await this.plugin.savePluginData();
-                }),
-        );
-
+        containerEl.createEl("h3", { text: t("GROUP_TAGS_FOLDERS") });
         new Setting(containerEl)
             .setName(t("TAGS_TO_REVIEW"))
             .setDesc(t("TAGS_TO_REVIEW_DESC"))
@@ -561,6 +539,14 @@ export class SRSettingTab extends PluginSettingTab {
 
         this.createSetting_FoldersToIgnore(containerEl);
 
+        containerEl.createEl("h3", { text: t("NOTES_REVIEW_QUEUE") });
+        new Setting(containerEl).setName(t("AUTO_NEXT_NOTE")).addToggle((toggle) =>
+            toggle.setValue(this.plugin.data.settings.autoNextNote).onChange(async (value) => {
+                this.plugin.data.settings.autoNextNote = value;
+                await this.plugin.savePluginData();
+            }),
+        );
+
         new Setting(containerEl)
             .setName(t("OPEN_RANDOM_NOTE"))
             .setDesc(t("OPEN_RANDOM_NOTE_DESC"))
@@ -573,11 +559,13 @@ export class SRSettingTab extends PluginSettingTab {
                     }),
             );
 
-        new Setting(containerEl).setName(t("AUTO_NEXT_NOTE")).addToggle((toggle) =>
-            toggle.setValue(this.plugin.data.settings.autoNextNote).onChange(async (value) => {
-                this.plugin.data.settings.autoNextNote = value;
-                await this.plugin.savePluginData();
-            }),
+        new Setting(containerEl).setName(t("REVIEW_PANE_ON_STARTUP")).addToggle((toggle) =>
+            toggle
+                .setValue(this.plugin.data.settings.enableNoteReviewPaneOnStartup)
+                .onChange(async (value) => {
+                    this.plugin.data.settings.enableNoteReviewPaneOnStartup = value;
+                    await this.plugin.savePluginData();
+                }),
         );
 
         new Setting(containerEl)
@@ -632,6 +620,7 @@ export class SRSettingTab extends PluginSettingTab {
                                 .map((v) => v.trim())
                                 .filter((v) => v);
                             await this.plugin.savePluginData();
+                            this.display();
                         });
                     }),
             );
@@ -847,13 +836,26 @@ export class SRSettingTab extends PluginSettingTab {
             });
     }
 
-    private async tabAlgorithm(containerEl: HTMLElement): Promise<void> {
-        containerEl.createEl("p").insertAdjacentHTML(
+    private async tabScheduling(containerEl: HTMLElement): Promise<void> {
+        containerEl.createEl("h3", { text: t("ALGORITHM") });
+        const algoSettingEl = new Setting(containerEl).setName(t("ALGORITHM"));
+        algoSettingEl.descEl.insertAdjacentHTML(
             "beforeend",
             t("CHECK_ALGORITHM_WIKI", {
-                algo_url: "https://www.stephenmwangi.com/obsidian-spaced-repetition/",
+                algo_url: "https://www.stephenmwangi.com/obsidian-spaced-repetition/algorithms/",
             }),
         );
+        algoSettingEl.addDropdown((dropdown) =>
+            dropdown
+                .addOptions({
+                    "SM-2-OSR": t("SM2_OSR_VARIANT"),
+                })
+                .setValue(this.plugin.data.settings.algorithm)
+                .onChange(async (value) => {
+                    this.plugin.data.settings.algorithm = value;
+                    await this.plugin.savePluginData();
+                }),
+        );
 
         new Setting(containerEl)
             .setName(t("BASE_EASE"))
@@ -1011,25 +1013,82 @@ export class SRSettingTab extends PluginSettingTab {
                         this.display();
                     });
             });
+
+        containerEl.createEl("h3", { text: t("GROUP_DATA_STORAGE") });
+        new Setting(containerEl)
+            .setName(t("GROUP_DATA_STORAGE"))
+            .setDesc(t("GROUP_DATA_STORAGE_DESC"))
+            .addDropdown((dropdown) =>
+                dropdown
+                    .addOptions({
+                        NOTES: t("STORE_IN_NOTES"),
+                    })
+                    .setValue(this.plugin.data.settings.dataStore)
+                    .onChange(async (value) => {
+                        this.plugin.data.settings.dataStore = value;
+                        await this.plugin.savePluginData();
+                    }),
+            );
+
+        new Setting(containerEl)
+            .setName(t("INLINE_SCHEDULING_COMMENTS"))
+            .setDesc(t("INLINE_SCHEDULING_COMMENTS_DESC"))
+            .addToggle((toggle) =>
+                toggle
+                    .setValue(this.plugin.data.settings.cardCommentOnSameLine)
+                    .onChange(async (value) => {
+                        this.plugin.data.settings.cardCommentOnSameLine = value;
+                        await this.plugin.savePluginData();
+                    }),
+            );
     }
 
-    private async tabDeveloper(containerEl: HTMLElement): Promise<void> {
-        containerEl.createEl("h3", { text: `${t("LOGGING")}` });
-        new Setting(containerEl).setName(t("DISPLAY_DEBUG_INFO")).addToggle((toggle) =>
-            toggle.setValue(this.plugin.data.settings.showDebugMessages).onChange(async (value) => {
-                this.plugin.data.settings.showDebugMessages = value;
-                await this.plugin.savePluginData();
+    private async tabExperimental(_: HTMLElement): Promise<void> {}
+
+    private async tabHelp(containerEl: HTMLElement): Promise<void> {
+        containerEl.createEl("h3", { text: `${t("HELP")}` });
+        containerEl.createEl("p").insertAdjacentHTML(
+            "beforeend",
+            t("CHECK_WIKI", {
+                wiki_url: "https://www.stephenmwangi.com/obsidian-spaced-repetition/",
+            }),
+        );
+
+        containerEl.createEl("p").insertAdjacentHTML(
+            "beforeend",
+            t("GITHUB_DISCUSSIONS", {
+                discussions_url:
+                    "https://github.com/st3v3nmw/obsidian-spaced-repetition/discussions/",
+            }),
+        );
+
+        containerEl.createEl("p").insertAdjacentHTML(
+            "beforeend",
+            t("GITHUB_ISSUES", {
+                issues_url: "https://github.com/st3v3nmw/obsidian-spaced-repetition/issues/",
             }),
         );
+
+        containerEl.createEl("h3", { text: `${t("LOGGING")}` });
+        new Setting(containerEl).setName(t("DISPLAY_SCHEDULING_DEBUG_INFO")).addToggle((toggle) =>
+            toggle
+                .setValue(this.plugin.data.settings.showSchedulingDebugMessages)
+                .onChange(async (value) => {
+                    this.plugin.data.settings.showSchedulingDebugMessages = value;
+                    await this.plugin.savePluginData();
+                }),
+        );
+
         new Setting(containerEl).setName(t("DISPLAY_PARSER_DEBUG_INFO")).addToggle((toggle) =>
             toggle
-                .setValue(this.plugin.data.settings.showPaserDebugMessages)
+                .setValue(this.plugin.data.settings.showParserDebugMessages)
                 .onChange(async (value) => {
-                    this.plugin.data.settings.showPaserDebugMessages = value;
-                    setDebugParser(this.plugin.data.settings.showPaserDebugMessages);
+                    this.plugin.data.settings.showParserDebugMessages = value;
+                    setDebugParser(this.plugin.data.settings.showParserDebugMessages);
                     await this.plugin.savePluginData();
                 }),
         );
+
         containerEl.createEl("h3", { text: t("GROUP_CONTRIBUTING") });
         containerEl.createEl("p").insertAdjacentHTML(
             "beforeend",
@@ -1037,6 +1096,7 @@ export class SRSettingTab extends PluginSettingTab {
                 github_project_url: "https://github.com/st3v3nmw/obsidian-spaced-repetition",
             }),
         );
+
         containerEl.createEl("p").insertAdjacentHTML(
             "beforeend",
             t("CODE_CONTRIBUTION_INFO", {
@@ -1044,6 +1104,7 @@ export class SRSettingTab extends PluginSettingTab {
                     "https://www.stephenmwangi.com/obsidian-spaced-repetition/contributing/#code",
             }),
         );
+
         containerEl.createEl("p").insertAdjacentHTML(
             "beforeend",
             t("TRANSLATION_CONTRIBUTION_INFO", {
@@ -1053,41 +1114,6 @@ export class SRSettingTab extends PluginSettingTab {
         );
     }
 
-    private async tabHelp(containerEl: HTMLElement): Promise<void> {
-        // Documentation link & GitHub links
-        containerEl.createEl("p").insertAdjacentHTML(
-            "beforeend",
-            t("CHECK_WIKI", {
-                wiki_url: "https://www.stephenmwangi.com/obsidian-spaced-repetition/",
-            }),
-        );
-
-        containerEl.createEl("p").insertAdjacentHTML(
-            "beforeend",
-            t("GITHUB_DISCUSSIONS", {
-                discussions_url:
-                    "https://github.com/st3v3nmw/obsidian-spaced-repetition/discussions/",
-            }),
-        );
-
-        containerEl.createEl("p").insertAdjacentHTML(
-            "beforeend",
-            t("GITHUB_ISSUES", {
-                issues_url: "https://github.com/st3v3nmw/obsidian-spaced-repetition/issues/",
-            }),
-        );
-        /*
-        // Documentation link & GitHub links
-        containerEl.createEl("hr").insertAdjacentHTML("beforeend");
-
-        // Copyright notice
-        const copyright_paragraph = containerEl.createEl("p");
-        copyright_paragraph.addClass("sr-small-font");
-        copyright_paragraph.insertAdjacentHTML("beforeend", `
-            <em>Shell commands</em> plugin Copyright &copy; 2021 - 2023 Jarkko Linnanvirta. This program comes with ABSOLUTELY NO WARRANTY. This is free software, and you are welcome to redistribute it under certain conditions. See more information in the license: <a href="${GitHub.license}">GNU GPL-3.0</a>.
-        `);     */
-    }
-
     private last_position: {
         scroll_position: number;
         tab_name: string;
@@ -1100,14 +1126,12 @@ export class SRSettingTab extends PluginSettingTab {
 
         // Go to last position now
         this.tab_structure.buttons[last_position.tab_name].click();
-        // window.setTimeout(() => { // Need to delay the scrolling a bit. Without this, something else would override scrolling and scroll back to 0.
+        // Need to delay the scrolling a bit.
+        // Without this, something else would override scrolling and scroll back to 0.
         container_element.scrollTo({
             top: this.last_position.scroll_position,
             behavior: "auto",
         });
-        // }, 0); // 'timeout' can be 0 ms, no need to wait any longer.
-        // I guess there's no need for setTimeout() anymore, as rememberLastPosition() is now called after waiting for asynchronous tab content generating is finished.
-        // TODO: Remove the commented code after a while.
 
         // Listen to changes
         container_element.addEventListener("scroll", (_) => {


Test patch:
diff --git a/tests/unit/helpers/unit-test-setup.ts b/tests/unit/helpers/unit-test-setup.ts
index 015db7a..fc34a49 100644
--- a/tests/unit/helpers/unit-test-setup.ts
+++ b/tests/unit/helpers/unit-test-setup.ts
@@ -3,11 +3,11 @@ import { SrsAlgorithm_Osr } from "src/algorithms/osr/srs-algorithm-osr";
 import { DataStoreAlgorithm } from "src/data-store-algorithm/data-store-algorithm";
 import { DataStoreInNote_AlgorithmOsr } from "src/data-store-algorithm/data-store-in-note-algorithm-osr";
 import { DataStore } from "src/data-stores/base/data-store";
-import { StoreInNote } from "src/data-stores/store-in-note/note";
+import { StoreInNotes } from "src/data-stores/notes/notes";
 import { SRSettings } from "src/settings";
 
 export function unitTestSetup_StandardDataStoreAlgorithm(settings: SRSettings) {
-    DataStore.instance = new StoreInNote(settings);
+    DataStore.instance = new StoreInNotes(settings);
     SrsAlgorithm.instance = new SrsAlgorithm_Osr(settings);
     DataStoreAlgorithm.instance = new DataStoreInNote_AlgorithmOsr(settings);
 }