From 2e13ca8362f43eeb02f8b616e717d6c2e0953a2e Mon Sep 17 00:00:00 2001 From: Aman Harwara Date: Sat, 7 Aug 2021 14:03:42 +0530 Subject: [PATCH] Add basic multi-language support --- locales/en/translation.json | 40 ++ locales/en/translation.missing.json | 0 locales/hi/translation.json | 40 ++ locales/hi/translation.missing.json | 0 package.json | 2 + src/i18next.conf.js | 24 + src/index.js | 14 +- src/lang.conf.js | 5 + src/util/menu.js | 664 ++++++++++++++-------------- yarn.lock | 86 ++++ 10 files changed, 552 insertions(+), 323 deletions(-) create mode 100644 locales/en/translation.json create mode 100644 locales/en/translation.missing.json create mode 100644 locales/hi/translation.json create mode 100644 locales/hi/translation.missing.json create mode 100644 src/i18next.conf.js create mode 100644 src/lang.conf.js diff --git a/locales/en/translation.json b/locales/en/translation.json new file mode 100644 index 00000000..c26ca857 --- /dev/null +++ b/locales/en/translation.json @@ -0,0 +1,40 @@ +{ + "&File": "&File", + "Force &Reload": "Force &Reload", + "&Quit": "&Quit", + "&Edit": "&Edit", + "Undo": "Undo", + "Redo": "Redo", + "Cut": "Cut", + "Copy": "Copy", + "Paste": "Paste", + "Select All": "Select All", + "Language": "Language", + "en": "English (en)", + "hi": "हिंदी (hi)", + "Tab": "Tab", + "Add New Tab": "Add New Tab", + "Edit Active Tab": "Edit Active Tab", + "Close Active Tab": "Close Active Tab", + "Open Tab DevTools": "Open Tab DevTools", + "Restore Tab": "Restore Tab", + "Go to Next Tab": "Go to Next Tab", + "Go to Previous Tab": "Go to Previous Tab", + "Go to First Tab": "Go to First Tab", + "Go to Last Tab": "Go to Last Tab", + "&View": "&View", + "Toggle Fullscreen": "Toggle Fullscreen", + "Toggle Tab Bar": "Toggle Tab Bar", + "Themes": "Themes", + "Theme Manager": "Theme Manager", + "&Settings": "&Settings", + "&Help": "&Help", + "&About": "&About", + "Donate": "Donate", + "Check For &Updates": "Check For &Updates", + "Links": "Links", + "Report Bugs/Issues": "Report Bugs/Issues", + "Website": "Website", + "Repository": "Repository", + "Open &DevTools": "Open &DevTools" +} diff --git a/locales/en/translation.missing.json b/locales/en/translation.missing.json new file mode 100644 index 00000000..e69de29b diff --git a/locales/hi/translation.json b/locales/hi/translation.json new file mode 100644 index 00000000..4cbf95e0 --- /dev/null +++ b/locales/hi/translation.json @@ -0,0 +1,40 @@ +{ + "&File": "फ़ाइल", + "Force &Reload": "रीलोड करें", + "&Quit": "बंद करे", + "&Edit": "बदल", + "Undo": "पूर्ववत् करें", + "Redo": "फिर से करें", + "Cut": "कट करें", + "Copy": "कापी करें", + "Paste": "पेस्ट करें", + "Select All": "सभी का चयन करे", + "Language": "भाषा", + "en": "English (en)", + "hi": "हिंदी (hi)", + "Tab": "Tab", + "Add New Tab": "नया टैब खोलें", + "Edit Active Tab": "मौजूदा टैब बदलें", + "Close Active Tab": "मौजूदा टैब बंद करें", + "Open Tab DevTools": "टैब DevTools खोलें", + "Restore Tab": "पिछला टैब पुनः खोलें", + "Go to Next Tab": "अगले टैब पर जाएँ", + "Go to Previous Tab": "पिछले टैब पर जाएँ", + "Go to First Tab": "पहले टैब पर जाएँ", + "Go to Last Tab": "आखरी टैब पर जाएँ", + "&View": "दृश्य", + "Toggle Fullscreen": "Toggle Fullscreen", + "Toggle Tab Bar": "Toggle Tab Bar", + "Themes": "दिखावट", + "Theme Manager": "Theme Manager", + "&Settings": "सेटिंग्स", + "&Help": "मदद", + "&About": "Altus के बारे में", + "Donate": "योगदान करें", + "Check For &Updates": "अपडेट के लिये जांचें", + "Links": "लिंक", + "Report Bugs/Issues": "समस्या की सूचना दें", + "Website": "वेबसाइट", + "Repository": "GitHub", + "Open &DevTools": "DevTools खोलें" +} diff --git a/locales/hi/translation.missing.json b/locales/hi/translation.missing.json new file mode 100644 index 00000000..e69de29b diff --git a/package.json b/package.json index 07e183ae..d3a8ab4b 100644 --- a/package.json +++ b/package.json @@ -104,6 +104,8 @@ "electron-dl": "^3.2.1", "electron-reload": "^1.5.0", "electron-store": "^8.0.0", + "i18next": "^20.3.5", + "i18next-node-fs-backend": "^2.1.3", "node-fetch": "^2.6.1", "sass": "^1.35.2", "sirv-cli": "^1.0.12", diff --git a/src/i18next.conf.js b/src/i18next.conf.js new file mode 100644 index 00000000..45f70e29 --- /dev/null +++ b/src/i18next.conf.js @@ -0,0 +1,24 @@ +const i18n = require("i18next"); +const backend = require("i18next-node-fs-backend"); +const langConf = require("./lang.conf"); + +const i18nOptions = { + backend: { + loadPath: "./locales/{{lng}}/{{ns}}.json", + addPath: "./locales/{{lng}}/{{ns}}.missing.json", + jsonIndent: 2, + }, + interpolation: { + espaceValue: true, + }, + saveMissing: true, + fallbackLng: langConf.fallbackLang, + whitelist: langConf.languages, + react: { + wait: false, + }, +}; + +i18n.use(backend); + +module.exports = { i18n, i18nOptions }; diff --git a/src/index.js b/src/index.js index abf392a8..81e9800b 100644 --- a/src/index.js +++ b/src/index.js @@ -26,6 +26,7 @@ const contextMenu = require("electron-context-menu"); const handleWhatsappLinks = require("./util/handleWhatsappLinks"); const electronDL = require("electron-dl"); const createCloneableMenuItem = require("./util/createCloneableMenuItem"); +const { i18n, i18nOptions } = require("./i18next.conf"); let settings = new Store({ name: "settings", @@ -120,7 +121,18 @@ const createMainWindow = () => { windowState.store = mainWindow.getBounds(); }); - Menu.setApplicationMenu(mainMenu); + if (!i18n.isInitialized) { + i18n.init(i18nOptions, (err, _) => { + i18n.on("loaded", () => { + i18n.changeLanguage(app.getLocale()); + i18n.off("loaded"); + }); + + i18n.on("languageChanged", (lang) => { + Menu.setApplicationMenu(mainMenu(i18n)); + }); + }); + } }; const singleInstanceLock = app.requestSingleInstanceLock(); diff --git a/src/lang.conf.js b/src/lang.conf.js new file mode 100644 index 00000000..a485b3a3 --- /dev/null +++ b/src/lang.conf.js @@ -0,0 +1,5 @@ +module.exports = { + languages: ["en", "hi"], + fallbackLang: "en", + namespace: "translation", +}; diff --git a/src/util/menu.js b/src/util/menu.js index 83bf737b..9c4352b1 100644 --- a/src/util/menu.js +++ b/src/util/menu.js @@ -9,357 +9,377 @@ const { const os = require("os"); const { mainIcon } = require("./icons"); const checkUpdates = require("./checkUpdates"); +const langConf = require("../lang.conf"); -let menuTemplate = [ - { - label: "&File", - id: "file", - submenu: [ - { - role: "forceReload", - id: "forceReload", - }, - { - label: "&Quit", - id: "quit", - accelerator: "CmdOrCtrl+Q", - click() { - app.exit(0); +const mainMenu = (i18n) => { + let menuTemplate = [ + { + label: i18n.t("&File"), + id: "file", + submenu: [ + { + label: i18n.t("Force &Reload"), + role: "forceReload", + id: "forceReload", }, - }, - ], - }, - { - label: "&Edit", - id: "edit", - submenu: [ - { - label: "Undo", - accelerator: "CmdOrCtrl+Z", - selector: "undo:", - id: "undo", - }, - { - label: "Redo", - accelerator: "Shift+CmdOrCtrl+Z", - selector: "redo:", - id: "redo", - }, - { - type: "separator", - }, - { - label: "Cut", - accelerator: "CmdOrCtrl+X", - selector: "cut:", - id: "cut", - }, - { - label: "Copy", - accelerator: "CmdOrCtrl+C", - selector: "copy:", - id: "copy", - }, - { - label: "Paste", - accelerator: "CmdOrCtrl+V", - selector: "paste:", - id: "paste", - }, - { - label: "Select All", - accelerator: "CmdOrCtrl+A", - selector: "selectAll:", - id: "selectAll", - }, - ], - }, - { - label: "Tab", - id: "tab", - submenu: [ - { - label: "Add New Tab", - accelerator: "CmdOrCtrl+T", - click() { - let window = BrowserWindow.getFocusedWindow(); - window.webContents.send("add-new-tab"); + { + label: i18n.t("&Quit"), + id: "quit", + accelerator: "CmdOrCtrl+Q", + click() { + app.exit(0); + }, }, - id: "addNewTab", - }, - { - label: "Edit Active Tab", - accelerator: "CmdOrCtrl+E", - click() { - let window = BrowserWindow.getFocusedWindow(); - window.webContents.send("edit-tab"); + ], + }, + { + label: i18n.t("&Edit"), + id: "edit", + submenu: [ + { + label: i18n.t("Undo"), + accelerator: "CmdOrCtrl+Z", + selector: "undo:", + id: "undo", }, - id: "editActiveTab", - }, - { - label: "Close Active Tab", - accelerator: "CmdOrCtrl+W", - click() { - let window = BrowserWindow.getFocusedWindow(); - window.webContents.send("prompt-before-closing-tab"); + { + label: i18n.t("Redo"), + accelerator: "Shift+CmdOrCtrl+Z", + selector: "redo:", + id: "redo", }, - id: "closeActiveTab", - }, - { - label: "Open Tab DevTools", - accelerator: "CmdOrCtrl+Shift+D", - click() { - let window = BrowserWindow.getFocusedWindow(); - window.webContents.send("open-tab-devtools"); + { + type: "separator", }, - id: "openDevTools", - }, - { - label: "Restore Tab", - accelerator: "CmdOrCtrl+Shift+T", - click() { - let window = BrowserWindow.getFocusedWindow(); - window.webContents.send("restore-tab"); + { + label: i18n.t("Cut"), + accelerator: "CmdOrCtrl+X", + selector: "cut:", + id: "cut", }, - id: "restoreTab", - }, - { - type: "separator", - }, - { - label: "Go to Next Tab", - accelerator: "CmdOrCtrl+Tab", - click() { - let window = BrowserWindow.getFocusedWindow(); - window.webContents.send("next-tab"); + { + label: i18n.t("Copy"), + accelerator: "CmdOrCtrl+C", + selector: "copy:", + id: "copy", }, - id: "gotoNextTab", - }, - { - label: "Go to Previous Tab", - accelerator: "CmdOrCtrl+Shift+Tab", - click() { - let window = BrowserWindow.getFocusedWindow(); - window.webContents.send("previous-tab"); + { + label: i18n.t("Paste"), + accelerator: "CmdOrCtrl+V", + selector: "paste:", + id: "paste", }, - id: "gotoPreviousTab", - }, - { - type: "separator", - }, - { - label: "Go to First Tab", - accelerator: "CmdOrCtrl+1", - click() { - let window = BrowserWindow.getFocusedWindow(); - window.webContents.send("first-tab"); + { + label: i18n.t("Select All"), + accelerator: "CmdOrCtrl+A", + selector: "selectAll:", + id: "selectAll", }, - id: "gotoFirstTab", - }, - { - label: "Go to Last Tab", - accelerator: "CmdOrCtrl+9", - click() { - let window = BrowserWindow.getFocusedWindow(); - window.webContents.send("last-tab"); + { + type: "separator", }, - id: "gotoLastTab", - }, - ], - }, - { - label: "&View", - id: "view", - submenu: [ - { - label: "Toggle Fullscreen", - accelerator: "F11", - click() { - let window = BrowserWindow.getFocusedWindow(); - window.setFullScreen(!window.fullScreen); + { + label: i18n.t("Language"), + submenu: langConf.languages.map((lang) => { + return { + label: i18n.t(lang), + type: "radio", + checked: i18n.language === lang, + click: () => { + i18n.changeLanguage(lang); + }, + }; + }), }, - id: "toggleFullscreen", - }, - { - label: "Toggle Tab Bar", - accelerator: "CmdOrCtrl+Shift+B", - click() { - let window = BrowserWindow.getFocusedWindow(); - window.webContents.send("toggle-tab-bar"); + ], + }, + { + label: i18n.t("Tab"), + id: "tab", + submenu: [ + { + label: i18n.t("Add New Tab"), + accelerator: "CmdOrCtrl+T", + click() { + let window = BrowserWindow.getFocusedWindow(); + window.webContents.send("add-new-tab"); + }, + id: "addNewTab", }, - id: "toggleTabBar", - }, - ], - }, - { - label: "Themes", - id: "themes", - submenu: [ - { - label: "Theme Manager", - accelerator: "Alt+T", - click() { - let window = BrowserWindow.getFocusedWindow(); - window.webContents.send("open-theme-manager"); + { + label: i18n.t("Edit Active Tab"), + accelerator: "CmdOrCtrl+E", + click() { + let window = BrowserWindow.getFocusedWindow(); + window.webContents.send("edit-tab"); + }, + id: "editActiveTab", }, - id: "themeManager", - }, - ], - }, - { - label: "&Settings", - id: "settingsMenu", - submenu: [ - { - label: "&Settings", - accelerator: "Ctrl+,", - click() { - let window = BrowserWindow.getFocusedWindow(); - window.webContents.send("open-settings"); + { + label: i18n.t("Close Active Tab"), + accelerator: "CmdOrCtrl+W", + click() { + let window = BrowserWindow.getFocusedWindow(); + window.webContents.send("prompt-before-closing-tab"); + }, + id: "closeActiveTab", }, - id: "settings", - }, - ], - }, - { - label: "&Help", - id: "help", - submenu: [ - { - label: "&About", - click() { - let versionInfo = `Altus: ${app.getVersion()} -Electron: ${process.versions.electron} -Chrome: ${process.versions.chrome} -V8: ${process.versions.v8} -OS: ${os.type()} ${os.arch()} ${os.release()}`; - - dialog - .showMessageBox({ - type: "info", - title: `Altus v${app.getVersion()}`, - message: `Made by Aman Harwara.`, - detail: `With help from: MarceloZapatta, Dafnik, dmcdo, insign, srevinsaju. - -Thanks to: vednoc for Dark WhatsApp theme. + { + label: i18n.t("Open Tab DevTools"), + accelerator: "CmdOrCtrl+Shift+D", + click() { + let window = BrowserWindow.getFocusedWindow(); + window.webContents.send("open-tab-devtools"); + }, + id: "openDevTools", + }, + { + label: i18n.t("Restore Tab"), + accelerator: "CmdOrCtrl+Shift+T", + click() { + let window = BrowserWindow.getFocusedWindow(); + window.webContents.send("restore-tab"); + }, + id: "restoreTab", + }, + { + type: "separator", + }, + { + label: i18n.t("Go to Next Tab"), + accelerator: "CmdOrCtrl+Tab", + click() { + let window = BrowserWindow.getFocusedWindow(); + window.webContents.send("next-tab"); + }, + id: "gotoNextTab", + }, + { + label: i18n.t("Go to Previous Tab"), + accelerator: "CmdOrCtrl+Shift+Tab", + click() { + let window = BrowserWindow.getFocusedWindow(); + window.webContents.send("previous-tab"); + }, + id: "gotoPreviousTab", + }, + { + type: "separator", + }, + { + label: i18n.t("Go to First Tab"), + accelerator: "CmdOrCtrl+1", + click() { + let window = BrowserWindow.getFocusedWindow(); + window.webContents.send("first-tab"); + }, + id: "gotoFirstTab", + }, + { + label: i18n.t("Go to Last Tab"), + accelerator: "CmdOrCtrl+9", + click() { + let window = BrowserWindow.getFocusedWindow(); + window.webContents.send("last-tab"); + }, + id: "gotoLastTab", + }, + ], + }, + { + label: i18n.t("&View"), + id: "view", + submenu: [ + { + label: i18n.t("Toggle Fullscreen"), + accelerator: "F11", + click() { + let window = BrowserWindow.getFocusedWindow(); + window.setFullScreen(!window.fullScreen); + }, + id: "toggleFullscreen", + }, + { + label: i18n.t("Toggle Tab Bar"), + accelerator: "CmdOrCtrl+Shift+B", + click() { + let window = BrowserWindow.getFocusedWindow(); + window.webContents.send("toggle-tab-bar"); + }, + id: "toggleTabBar", + }, + ], + }, + { + label: i18n.t("Themes"), + id: "themes", + submenu: [ + { + label: i18n.t("Theme Manager"), + accelerator: "Alt+T", + click() { + let window = BrowserWindow.getFocusedWindow(); + window.webContents.send("open-theme-manager"); + }, + id: "themeManager", + }, + ], + }, + { + label: i18n.t("&Settings"), + id: "settingsMenu", + submenu: [ + { + label: i18n.t("&Settings"), + accelerator: "Ctrl+,", + click() { + let window = BrowserWindow.getFocusedWindow(); + window.webContents.send("open-settings"); + }, + id: "settings", + }, + ], + }, + { + label: i18n.t("&Help"), + id: "help", + submenu: [ + { + label: i18n.t("&About"), + click() { + let versionInfo = `Altus: ${app.getVersion()} + Electron: ${process.versions.electron} + Chrome: ${process.versions.chrome} + V8: ${process.versions.v8} + OS: ${os.type()} ${os.arch()} ${os.release()}`; -${versionInfo}`, - icon: mainIcon, - buttons: ["Copy Version Info", "OK"], - }) - .then((res) => { - let buttonClicked = res.response; - switch (buttonClicked) { - case 0: - clipboard.write({ - text: versionInfo, - }); - break; - } - }) - .catch((err) => { - console.error(err); - }); + dialog + .showMessageBox({ + type: "info", + title: `Altus v${app.getVersion()}`, + message: `Made by Aman Harwara.`, + detail: `With help from: MarceloZapatta, Dafnik, dmcdo, insign, srevinsaju. + + Thanks to: vednoc for Dark WhatsApp theme. + + ${versionInfo}`, + icon: mainIcon, + buttons: ["Copy Version Info", "OK"], + }) + .then((res) => { + let buttonClicked = res.response; + switch (buttonClicked) { + case 0: + clipboard.write({ + text: versionInfo, + }); + break; + } + }) + .catch((err) => { + console.error(err); + }); + }, + id: "about", }, - id: "about", - }, - { - label: "Donate", - submenu: [ - { - label: "Liberapay", - id: "liberapay", - click() { - shell.openExternal("https://liberapay.com/aman_harwara/"); + { + label: i18n.t("Donate"), + submenu: [ + { + label: "Liberapay", + id: "liberapay", + click() { + shell.openExternal("https://liberapay.com/aman_harwara/"); + }, }, - }, - { - label: "Ko-Fi", - id: "kofi", - click() { - shell.openExternal("https://ko-fi.com/amanharwara"); + { + label: "Ko-Fi", + id: "kofi", + click() { + shell.openExternal("https://ko-fi.com/amanharwara"); + }, }, - }, - { - label: "Buy Me a Coffee", - id: "buymeacoffee", - click() { - shell.openExternal("https://buymeacoffee.com/amanharwara"); + { + label: "Buy Me a Coffee", + id: "buymeacoffee", + click() { + shell.openExternal("https://buymeacoffee.com/amanharwara"); + }, }, - }, - { - label: "Other Links", - id: "otherlinks", - click() { - shell.openExternal( - "https://github.com/amanharwara/altus#support" - ); + { + label: "Other Links", + id: "otherlinks", + click() { + shell.openExternal( + "https://github.com/amanharwara/altus#support" + ); + }, }, + ], + id: "donate", + }, + { + label: i18n.t("Check For &Updates"), + accelerator: "CmdOrCtrl+Shift+U", + click() { + dialog + .showMessageBox({ + type: "question", + message: "Check for Updates?", + detail: `Current version: v${app.getVersion()}`, + buttons: ["Yes", "No"], + }) + .then((res) => { + let buttonClicked = res.response; + if (buttonClicked === 0) { + checkUpdates().catch((err) => console.error(err)); + } + }) + .catch((err) => console.error(err)); }, - ], - id: "donate", - }, - { - label: "Check For &Updates", - accelerator: "CmdOrCtrl+Shift+U", - click() { - dialog - .showMessageBox({ - type: "question", - message: "Check for Updates?", - detail: `Current version: v${app.getVersion()}`, - buttons: ["Yes", "No"], - }) - .then((res) => { - let buttonClicked = res.response; - if (buttonClicked === 0) { - checkUpdates().catch((err) => console.error(err)); - } - }) - .catch((err) => console.error(err)); + id: "checkForUpdates", }, - id: "checkForUpdates", - }, - { - label: "Links", - submenu: [ - { - label: "Report Bugs/Issues", - click: () => { - shell.openExternal( - "https://gitlab.com/amanharwara/altus/-/issues" - ); + { + label: i18n.t("Links"), + submenu: [ + { + label: i18n.t("Report Bugs/Issues"), + click: () => { + shell.openExternal( + "https://gitlab.com/amanharwara/altus/-/issues" + ); + }, }, - }, - { - label: "Website", - click: () => { - shell.openExternal("https://amanharwara.com"); + { + label: i18n.t("Website"), + click: () => { + shell.openExternal("https://amanharwara.com"); + }, }, - }, - { - label: "Repository", - click: () => { - shell.openExternal("https://www.gitlab.com/amanharwara/altus"); + { + label: i18n.t("Repository"), + click: () => { + shell.openExternal("https://www.gitlab.com/amanharwara/altus"); + }, }, + ], + id: "links", + }, + { + label: i18n.t("Open &DevTools"), + accelerator: "CmdOrCtrl+Shift+I", + click() { + let window = BrowserWindow.getFocusedWindow(); + window.webContents.openDevTools(); }, - ], - id: "links", - }, - { - label: "Open &DevTools", - accelerator: "CmdOrCtrl+Shift+I", - click() { - let window = BrowserWindow.getFocusedWindow(); - window.webContents.openDevTools(); + id: "openWindowDevTools", }, - id: "openWindowDevTools", - }, - ], - }, -]; + ], + }, + ]; -let mainMenu = Menu.buildFromTemplate(menuTemplate); + return Menu.buildFromTemplate(menuTemplate); +}; const trayContextMenu = Menu.buildFromTemplate([ { diff --git a/yarn.lock b/yarn.lock index 951308ce..c1e1f9de 100644 --- a/yarn.lock +++ b/yarn.lock @@ -59,6 +59,15 @@ __metadata: languageName: node linkType: hard +"@babel/runtime@npm:^7.12.0": + version: 7.14.8 + resolution: "@babel/runtime@npm:7.14.8" + dependencies: + regenerator-runtime: ^0.13.4 + checksum: ebadb3e013a26e0f62abea0da6f6f5d83c9566f0d900e65069885f93088066c64586076d15dcbe6e093c536f66cffc9e2e136ad5d8b3e66235af62f0051afa42 + languageName: node + linkType: hard + "@develar/schema-utils@npm:~2.6.5": version: 2.6.5 resolution: "@develar/schema-utils@npm:2.6.5" @@ -462,6 +471,8 @@ __metadata: electron-dl: ^3.2.1 electron-reload: ^1.5.0 electron-store: ^8.0.0 + i18next: ^20.3.5 + i18next-node-fs-backend: ^2.1.3 node-fetch: ^2.6.1 rollup: ^2.53.2 rollup-plugin-css-only: ^3.1.0 @@ -619,6 +630,15 @@ __metadata: languageName: node linkType: hard +"argparse@npm:^1.0.7": + version: 1.0.10 + resolution: "argparse@npm:1.0.10" + dependencies: + sprintf-js: ~1.0.2 + checksum: 435adaef5f6671c3ef1478a22be6fd54bdb99fdbbce8f5561b9cbbb05068ccce87b7df3b9f3322ff52a6ebb9cab2b427cbedac47a07611690a9beaa5184093e2 + languageName: node + linkType: hard + "argparse@npm:^2.0.1": version: 2.0.1 resolution: "argparse@npm:2.0.1" @@ -1854,6 +1874,16 @@ __metadata: languageName: node linkType: hard +"esprima@npm:^4.0.0": + version: 4.0.1 + resolution: "esprima@npm:4.0.1" + bin: + esparse: ./bin/esparse.js + esvalidate: ./bin/esvalidate.js + checksum: 5df45a3d9c95c36800d028ba76d8d4e04e199932b58c2939f462f859fd583e7d39b4a12d3f97986cf272a28a5fe5948ee6e49e36ef63f67b5b48d82a635c5081 + languageName: node + linkType: hard + "estree-walker@npm:^0.6.1": version: 0.6.1 resolution: "estree-walker@npm:0.6.1" @@ -2364,6 +2394,25 @@ fsevents@~2.3.2: languageName: node linkType: hard +"i18next-node-fs-backend@npm:^2.1.3": + version: 2.1.3 + resolution: "i18next-node-fs-backend@npm:2.1.3" + dependencies: + js-yaml: 3.13.1 + json5: 2.0.0 + checksum: 59215ef168e65d3a940ed9c22dfe0ebcadb89d332b38eef467b8934138bbf0c949392f1e84e3e64f0de9399e0001c00c867116db53244a70054c6fd12520157f + languageName: node + linkType: hard + +"i18next@npm:^20.3.5": + version: 20.3.5 + resolution: "i18next@npm:20.3.5" + dependencies: + "@babel/runtime": ^7.12.0 + checksum: 7bcbcd656312adf0b6c347e21d248b65e46471417272b1eb8869bbb7db478020f498ab64e008dd022f1c8b69a541c2284eca3ed98b3aca7857a6d106e4380dd8 + languageName: node + linkType: hard + "iconv-corefoundation@npm:^1.1.6": version: 1.1.6 resolution: "iconv-corefoundation@npm:1.1.6" @@ -2675,6 +2724,18 @@ fsevents@~2.3.2: languageName: node linkType: hard +"js-yaml@npm:3.13.1": + version: 3.13.1 + resolution: "js-yaml@npm:3.13.1" + dependencies: + argparse: ^1.0.7 + esprima: ^4.0.0 + bin: + js-yaml: bin/js-yaml.js + checksum: 277157fdf235757b71cfbf24f6bef57576a26d9b4cf89b63d89c9044da7b0f9d16c3629c8b5fd549ae343523727a0df1598794e9a4429763cee4e17056ff8523 + languageName: node + linkType: hard + "js-yaml@npm:^4.1.0": version: 4.1.0 resolution: "js-yaml@npm:4.1.0" @@ -2742,6 +2803,17 @@ fsevents@~2.3.2: languageName: node linkType: hard +"json5@npm:2.0.0": + version: 2.0.0 + resolution: "json5@npm:2.0.0" + dependencies: + minimist: ^1.2.0 + bin: + json5: lib/cli.js + checksum: 1bfba1f84c73dfda48fc8df3d2f1890cbecf93f8a77cc1bf146f13f7547839dbdaa540955115ed6a440aed19428a3d6e8d69e83a12cb08f0869adf724230961e + languageName: node + linkType: hard + "json5@npm:^2.2.0": version: 2.2.0 resolution: "json5@npm:2.2.0" @@ -3535,6 +3607,13 @@ fsevents@~2.3.2: languageName: node linkType: hard +"regenerator-runtime@npm:^0.13.4": + version: 0.13.9 + resolution: "regenerator-runtime@npm:0.13.9" + checksum: 8587f99ed63493b9ce34375f426b8ec61bf380681a374d5f2460c14ae2c289114702bed1f565a2499e809f2ba6d8ecd25a8dfee54bc224171f20a95a249be242 + languageName: node + linkType: hard + "registry-auth-token@npm:^4.0.0": version: 4.2.1 resolution: "registry-auth-token@npm:4.2.1" @@ -4090,6 +4169,13 @@ fsevents@~2.3.2: languageName: node linkType: hard +"sprintf-js@npm:~1.0.2": + version: 1.0.3 + resolution: "sprintf-js@npm:1.0.3" + checksum: 51df1bce9e577287f56822d79ac5bd94f6c634fccf193895f2a1d2db2e975b6aa7bc97afae9cf11d49b7c37fe4afc188ff5c4878be91f2c86eabd11c5df8b62c + languageName: node + linkType: hard + "sshpk@npm:^1.7.0": version: 1.16.1 resolution: "sshpk@npm:1.16.1"