From 616614304633f70ad74af2460cb2ebc9fd52eee4 Mon Sep 17 00:00:00 2001
From: zhaosi <zhaosi@yoyohr.com>
Date: Thu, 29 Feb 2024 14:17:30 +0800
Subject: [PATCH 1/9] feat: Added the ability to throw errors and customize
 error messages for the workflow-state task block.

---
 .../workflow/edit/EditWorkflowState.vue       | 19 ++++++
 src/locales/en/blocks.json                    |  6 +-
 src/locales/zh/blocks.json                    |  6 +-
 src/utils/shared.js                           |  3 +
 .../blocksHandler/handlerWorkflowState.js     | 60 +++++++++++--------
 5 files changed, 68 insertions(+), 26 deletions(-)

diff --git a/src/components/newtab/workflow/edit/EditWorkflowState.vue b/src/components/newtab/workflow/edit/EditWorkflowState.vue
index 11ca5298f..ac8abfcc9 100644
--- a/src/components/newtab/workflow/edit/EditWorkflowState.vue
+++ b/src/components/newtab/workflow/edit/EditWorkflowState.vue
@@ -30,6 +30,25 @@
     >
       Execpt for the current workflow
     </ui-checkbox>
+    <!-- 停止当前工作流 是否抛出错误及自定义错误信息 -->
+    <template v-if="data.type === 'stop-current'">
+      <ui-checkbox
+        :model-value="data.throwError"
+        block
+        class="block-variable mt-4"
+        @change="updateData({ throwError: $event })"
+      >
+        {{ t(`workflow.blocks.workflow-state.error.throwError`) }}
+      </ui-checkbox>
+      <ui-input
+        v-if="data.throwError"
+        :model-value="data.errorMessage"
+        :placeholder="t(`workflow.blocks.workflow-state.error.message`)"
+        :title="t(`workflow.blocks.workflow-state.error.message`)"
+        class="mt-2 w-full"
+        @change="updateData({ errorMessage: $event })"
+      />
+    </template>
     <div
       v-if="data.type === 'stop-specific'"
       class="bg-input focus-within:bg-box-transparent-2 mt-4 rounded-lg transition"
diff --git a/src/locales/en/blocks.json b/src/locales/en/blocks.json
index dffd6e5e4..b5d6fa401 100644
--- a/src/locales/en/blocks.json
+++ b/src/locales/en/blocks.json
@@ -133,6 +133,10 @@
         "description": "Manage workflows states",
         "actions": {
           "stop": "Stop workflows"
+        },
+        "error": {
+          "throwError": "Throw error",
+          "message": "Error message"
         }
       },
       "regex-variable": {
@@ -803,4 +807,4 @@
       }
     }
   }
-}
+}
\ No newline at end of file
diff --git a/src/locales/zh/blocks.json b/src/locales/zh/blocks.json
index 3ed210bf2..e354b7cfa 100644
--- a/src/locales/zh/blocks.json
+++ b/src/locales/zh/blocks.json
@@ -133,6 +133,10 @@
         "description": "管理工作流状态",
         "actions": {
           "stop": "停止工作流"
+        },
+        "error": {
+          "throwError": "Throw error",
+          "message": "Error message"
         }
       },
       "regex-variable": {
@@ -796,4 +800,4 @@
       }
     }
   }
-}
+}
\ No newline at end of file
diff --git a/src/utils/shared.js b/src/utils/shared.js
index 6761a815d..3aa17f623 100644
--- a/src/utils/shared.js
+++ b/src/utils/shared.js
@@ -1446,12 +1446,15 @@ export const tasks = {
     outputs: 1,
     allowedInputs: true,
     maxConnection: 1,
+    refDataKeys: ['errorMessage'],
     data: {
       disableBlock: false,
       description: '',
       type: 'stop-current',
       exceptCurrent: false,
       workflowsToStop: [],
+      throwError: false,
+      errorMessage: '',
     },
   },
   'parameter-prompt': {
diff --git a/src/workflowEngine/blocksHandler/handlerWorkflowState.js b/src/workflowEngine/blocksHandler/handlerWorkflowState.js
index f325b9ff5..eb9efb639 100644
--- a/src/workflowEngine/blocksHandler/handlerWorkflowState.js
+++ b/src/workflowEngine/blocksHandler/handlerWorkflowState.js
@@ -1,33 +1,45 @@
 export default async function ({ data, id }) {
-  let stopCurrent = false;
+  try {
+    let stopCurrent = false;
 
-  if (data.type === 'stop-current') {
-    return {};
-  }
-  if (['stop-specific', 'stop-all'].includes(data.type)) {
-    const ids = [];
-    const isSpecific = data.type === 'stop-specific';
-    this.engine.states.getAll.forEach((state) => {
-      const workflowNotIncluded =
-        isSpecific && !data.workflowsToStop.includes(state.workflowId);
-      if (workflowNotIncluded) return;
+    if (data.type === 'stop-current') {
+      // 如果需要抛出错误
+      if (data.throwError) {
+        throw new Error(data.errorMessage || 'Workflow stopped manually');
+      } else {
+        return {};
+      }
+    }
+    if (['stop-specific', 'stop-all'].includes(data.type)) {
+      const ids = [];
+      const isSpecific = data.type === 'stop-specific';
+      this.engine.states.getAll.forEach((state) => {
+        const workflowNotIncluded =
+          isSpecific && !data.workflowsToStop.includes(state.workflowId);
+        if (workflowNotIncluded) return;
 
-      ids.push(state.id);
-    });
+        ids.push(state.id);
+      });
 
-    for (const stateId of ids) {
-      if (stateId === this.engine.id) {
-        stopCurrent = isSpecific ? true : !data.exceptCurrent;
-      } else {
-        await this.engine.states.stop(stateId);
+      for (const stateId of ids) {
+        if (stateId === this.engine.id) {
+          stopCurrent = isSpecific ? true : !data.exceptCurrent;
+        } else {
+          await this.engine.states.stop(stateId);
+        }
       }
     }
-  }
 
-  if (stopCurrent) return {};
+    if (stopCurrent) return {};
 
-  return {
-    data: '',
-    nextBlockId: this.getBlockConnections(id),
-  };
+    return {
+      data: '',
+      nextBlockId: this.getBlockConnections(id),
+    };
+  } catch (error) {
+    error.data = error.data || {};
+    console.error(error);
+
+    throw error;
+  }
 }

From 503fee4051f4d3713a4d53ba9a4cd9cd4a70e9c7 Mon Sep 17 00:00:00 2001
From: zhaosi <zhaosi@yoyohr.com>
Date: Thu, 29 Feb 2024 14:36:04 +0800
Subject: [PATCH 2/9] feat: Add the globalData parameter to the
 workflowEventHandler method.

---
 src/workflowEngine/index.js | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/workflowEngine/index.js b/src/workflowEngine/index.js
index ca7789b8b..071e8f930 100644
--- a/src/workflowEngine/index.js
+++ b/src/workflowEngine/index.js
@@ -116,6 +116,7 @@ export function startWorkflowExec(workflowData, options, isPopup = true) {
         workflowEventHandler(event.action, {
           workflow: workflowRefData,
           variables: { ...engine.referenceData.variables },
+          globalData: { ...engine.referenceData.globalData },
         });
       });
     }

From 630d06fed7cc20c6bd3c3f97667531866e9b30d0 Mon Sep 17 00:00:00 2001
From: zhaosi <zhaosi@yoyohr.com>
Date: Thu, 29 Feb 2024 14:54:57 +0800
Subject: [PATCH 3/9] feat: When a task block throws an error, users can
 customize the error message.

---
 .../workflow/edit/BlockSetting/BlockSettingOnError.vue     | 7 +++++++
 src/components/newtab/workflow/edit/EditBlockSettings.vue  | 1 +
 src/locales/en/blocks.json                                 | 6 +++++-
 src/locales/zh/blocks.json                                 | 6 +++++-
 src/workflowEngine/WorkflowWorker.js                       | 6 ++++++
 5 files changed, 24 insertions(+), 2 deletions(-)

diff --git a/src/components/newtab/workflow/edit/BlockSetting/BlockSettingOnError.vue b/src/components/newtab/workflow/edit/BlockSetting/BlockSettingOnError.vue
index 67e05c521..f21082b6f 100644
--- a/src/components/newtab/workflow/edit/BlockSetting/BlockSettingOnError.vue
+++ b/src/components/newtab/workflow/edit/BlockSetting/BlockSettingOnError.vue
@@ -79,6 +79,13 @@
             {{ t(`workflow.blocks.base.onError.toDo.${type}`) }}
           </option>
         </ui-select>
+        <ui-input
+          v-if="state.toDo === 'error'"
+          v-model="state.errorMessage"
+          :placeholder="t(`workflow.blocks.workflow-state.error.message`)"
+          :title="t(`workflow.blocks.workflow-state.error.message`)"
+          class="mt-1 ml-2 w-56"
+        />
         <div class="mt-4 flex items-center justify-between">
           <label class="inline-flex">
             <ui-switch v-model="state.insertData" />
diff --git a/src/components/newtab/workflow/edit/EditBlockSettings.vue b/src/components/newtab/workflow/edit/EditBlockSettings.vue
index 6c09d5ffe..57abdf83e 100644
--- a/src/components/newtab/workflow/edit/EditBlockSettings.vue
+++ b/src/components/newtab/workflow/edit/EditBlockSettings.vue
@@ -75,6 +75,7 @@ const defaultSettings = {
     retryTimes: 1,
     retryInterval: 2,
     toDo: 'error',
+    errorMessage: '',
     insertData: false,
     dataToInsert: [],
   },
diff --git a/src/locales/en/blocks.json b/src/locales/en/blocks.json
index dffd6e5e4..b5d6fa401 100644
--- a/src/locales/en/blocks.json
+++ b/src/locales/en/blocks.json
@@ -133,6 +133,10 @@
         "description": "Manage workflows states",
         "actions": {
           "stop": "Stop workflows"
+        },
+        "error": {
+          "throwError": "Throw error",
+          "message": "Error message"
         }
       },
       "regex-variable": {
@@ -803,4 +807,4 @@
       }
     }
   }
-}
+}
\ No newline at end of file
diff --git a/src/locales/zh/blocks.json b/src/locales/zh/blocks.json
index 3ed210bf2..536d95af6 100644
--- a/src/locales/zh/blocks.json
+++ b/src/locales/zh/blocks.json
@@ -133,6 +133,10 @@
         "description": "管理工作流状态",
         "actions": {
           "stop": "停止工作流"
+        },
+        "error": {
+          "throwError": "抛出错误",
+          "message": "错误消息"
         }
       },
       "regex-variable": {
@@ -796,4 +800,4 @@
       }
     }
   }
-}
+}
\ No newline at end of file
diff --git a/src/workflowEngine/WorkflowWorker.js b/src/workflowEngine/WorkflowWorker.js
index 79f5192c8..798b0d228 100644
--- a/src/workflowEngine/WorkflowWorker.js
+++ b/src/workflowEngine/WorkflowWorker.js
@@ -415,6 +415,12 @@ class WorkflowWorker {
 
           return;
         }
+
+        // 抛出错误并且存在自定义的错误信息
+        if (blockOnError.toDo === 'error' && blockOnError.errorMessage.trim()) {
+          errorLogData.message = blockOnError.errorMessage;
+          error.message = blockOnError.errorMessage;
+        }
       }
 
       const errorLogItem = errorLogData;

From 54cddd2db1b09e74fe22969b4a308ee20cc406d3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E5=B0=8F=E6=81=90=E9=BE=99?=
 <xkonglong@users.noreply.github.com>
Date: Thu, 21 Mar 2024 09:18:13 +0800
Subject: [PATCH 4/9] Update blocks.json

update ZH
---
 src/locales/zh/blocks.json | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/src/locales/zh/blocks.json b/src/locales/zh/blocks.json
index 3ed210bf2..314b82427 100644
--- a/src/locales/zh/blocks.json
+++ b/src/locales/zh/blocks.json
@@ -207,6 +207,7 @@
           "press-key": "按下一个按键",
           "multiple-keys": "按下多个按键"
         }
+        "press-time": "按下时间 (毫秒)"
       },
       "save-assets": {
         "name": "保存资源",
@@ -566,6 +567,7 @@
         "name": "新建标签页",
         "description": "",
         "url": "新建标签页 URL",
+        "tab-zoom": "标签页缩放",
         "customUserAgent": "使用自定义 User-Agent",
         "activeTab": "设为活动标签页",
         "tabToGroup": "标签页分组",
@@ -587,6 +589,11 @@
           "name": "属性名称",
           "checkbox": "插入到表格",
           "column": "选择列",
+          "value": "属性值",
+          "action": {
+            "get": "获取属性值",
+            "set": "设置属性值"
+          },
           "extraRow": {
             "checkbox": "添加额外的行",
             "placeholder": "值",

From 61cafd4394e62c35a7fee31009d7e9a51db6abd3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E5=B0=8F=E6=81=90=E9=BE=99?=
 <xkonglong@users.noreply.github.com>
Date: Thu, 21 Mar 2024 09:21:20 +0800
Subject: [PATCH 5/9] Update common.json

update ZH
---
 src/locales/zh/common.json | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/locales/zh/common.json b/src/locales/zh/common.json
index 9822a4f7c..17a27a151 100644
--- a/src/locales/zh/common.json
+++ b/src/locales/zh/common.json
@@ -48,6 +48,7 @@
     "category": "分类",
     "optional": "可选",
     "0disable": "0 到禁用"
+    "millisecond": "毫秒 | 毫秒"
   },
   "message": {
     "noBlock": "没有模块",

From 0ba8d9413afb152a09b5d2d414752d9e3de04148 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E5=B0=8F=E6=81=90=E9=BE=99?=
 <xkonglong@users.noreply.github.com>
Date: Thu, 21 Mar 2024 09:24:24 +0800
Subject: [PATCH 6/9] Update newtab.json

update ZH
---
 src/locales/zh/newtab.json | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/src/locales/zh/newtab.json b/src/locales/zh/newtab.json
index 4ee998380..23cc5d34f 100644
--- a/src/locales/zh/newtab.json
+++ b/src/locales/zh/newtab.json
@@ -42,6 +42,7 @@
     "title": "存储",
     "table": {
       "add": "添加表格",
+      "edit": "编辑表格",
       "createdAt": "创建于",
       "modifiedAt": "修改于",
       "rowsCount": "行数",
@@ -123,6 +124,10 @@
       "snapGrid": {
         "title": "对齐网格",
         "description": "移动模块时对齐网格"
+      },
+      "saveWhenExecute": {
+        "title": "执行工作流程时自动保存",
+        "description": "执行工作流程时将自动保存更改的工作流程"
       }
     },
     "deleteLog": {

From 1c4a545aa3a54747ecc82f26c36f378df00f98c7 Mon Sep 17 00:00:00 2001
From: AMendoza1890 <allanmaleman@gmail.com>
Date: Tue, 16 Apr 2024 13:41:22 -0700
Subject: [PATCH 7/9] feat(locale): add langId locale es - spanish

---
 src/lib/dayjs.js           |   1 +
 src/locales/es/blocks.json | 806 +++++++++++++++++++++++++++++++++++++
 src/locales/es/common.json |  77 ++++
 src/locales/es/newtab.json | 516 ++++++++++++++++++++++++
 src/locales/es/popup.json  |  32 ++
 src/utils/shared.js        |   1 +
 6 files changed, 1433 insertions(+)
 create mode 100644 src/locales/es/blocks.json
 create mode 100644 src/locales/es/common.json
 create mode 100644 src/locales/es/newtab.json
 create mode 100644 src/locales/es/popup.json

diff --git a/src/lib/dayjs.js b/src/lib/dayjs.js
index 0b7e57c41..a27b1c850 100644
--- a/src/lib/dayjs.js
+++ b/src/lib/dayjs.js
@@ -7,6 +7,7 @@ import 'dayjs/locale/fr';
 import 'dayjs/locale/it';
 import 'dayjs/locale/uk';
 import 'dayjs/locale/tr';
+import 'dayjs/locale/es';
 
 dayjs.extend(relativeTime);
 
diff --git a/src/locales/es/blocks.json b/src/locales/es/blocks.json
new file mode 100644
index 000000000..c97f61876
--- /dev/null
+++ b/src/locales/es/blocks.json
@@ -0,0 +1,806 @@
+{
+  "collection": {
+    "blocks": {
+      "export-result": {
+        "name": "Exportar los resultados",
+        "description": "Exportar el resultado de la recogida como JSON"
+      }
+    }
+  },
+  "workflow": {
+    "blocks": {
+      "base": {
+        "title": "Bloques",
+        "moveToGroup": "Mover bloque a grupo de bloques",
+        "selector": "Selector de elementos",
+        "selectorOptions": "Opciones de selección",
+        "timeout": "Tiempo de espera (milisegundos)",
+        "noPermission": "Automa no tiene permisos suficientes para realizar esta acción",
+        "grantPermission": "Conceder permiso",
+        "action": "Acción",
+        "element": {
+          "select": "Seleccione un elemento",
+          "verify": "Verificar selector"
+        },
+        "settings": {
+          "title": "Ajustes del bloque",
+          "blockTimeout": {
+            "title": "Tiempo de espera de ejecución del bloque (milisegundo)",
+            "description": "El tiempo máximo de ejecución del bloque (de 0 a desactivar)"
+          },
+          "line": {
+            "title": "Líneas",
+            "label": "Etiqueta",
+            "animated": "Animated",
+            "select": "Seleccionar línea",
+            "to": "Línea a {name} bloque",
+            "lineColor": "Color"
+          }
+        },
+        "toggle": {
+          "enable": "Habilitar bloque",
+          "disable": "Deshabilitar bloque"
+        },
+        "onError": {
+          "info": "Estas normas se aplicarán cuando se produzca un error en el bloque",
+          "button": "error",
+          "title": "En caso de error",
+          "retry": "Reintentar acción",
+          "fallbackTitle": "Se ejecutará cuando se produzca un error en el bloque",
+          "times": {
+            "name": "Tiempo",
+            "description": "El número de veces que se debe reintentar la acción"
+          },
+          "interval": {
+            "name": "Intervalo",
+            "description": "El intervalo de tiempo a esperar entre cada intento",
+            "second": "Segundos"
+          },
+          "toDo": {
+            "error": "Lanzar error",
+            "continue": "Seguir fluyendo",
+            "fallback": "Ejecutar fallback",
+            "restart": "Reiniciar el flujo"
+          },
+          "insertData": {
+            "name": "Insertar datos"
+          }
+        },
+        "table": {
+          "checkbox": "Insertar en tabla",
+          "select": "Seleccionar columna",
+          "extraRow": {
+            "checkbox": "Agregar una fila extra",
+            "placeholder": "Valor",
+            "title": "Valor de la fila extra"
+          }
+        },
+        "findElement": {
+          "placeholder": "Encontrar elemento por",
+          "options": {
+            "cssSelector": "CSS Selector",
+            "xpath": "XPath"
+          }
+        },
+        "markElement": {
+          "title": "Un elemento no se seleccionará si ya se ha seleccionado antes",
+          "text": "Elemento de marca"
+        },
+        "multiple": {
+          "title": "Seleccionar varios elementos",
+          "text": "Multiples"
+        },
+        "waitSelector": {
+          "title": "Esperar al selector",
+          "timeout": "Tiempo de espera del selector (ms)"
+        },
+        "downloads": {
+          "onConflict": {
+            "uniquify": "Uniquify",
+            "overwrite": "Sobrescribir",
+            "prompt": "Prompt"
+          }
+        }
+      },
+      "wait-connections": {
+        "name": "Conexiones de espera",
+        "description": "Esperar todas las conexiones antes de continuar con el siguiente bloque",
+        "specificFlow": "Continuar sólo un flujo específico",
+        "selectFlow": "Seleccionar flujo"
+      },
+      "cookie": {
+        "name": "Cookie",
+        "description": "Obtener, establecer o eliminar cookies",
+        "types": {
+          "get": "Obtener cookie",
+          "set": "Establecer cookie",
+          "remove": "Eliminar cookies",
+          "getAll": "Obtener todas las cookies"
+        },
+        "useJson": "Utilizar el formato JSON"
+      },
+      "note": {
+        "name": "Nota"
+      },
+      "slice-variable": {
+        "name": "Variable de corte",
+        "description": "Extrae una sección del valor de una variable",
+        "start": "Iniciar index",
+        "end": "Finalizar index"
+      },
+      "workflow-state": {
+        "name": "Estado del Flujo de Trabajo",
+        "description": "Gestionar los estados de los flujos de trabajo",
+        "actions": {
+          "stop": "Detener flujos de trabajo"
+        }
+      },
+      "regex-variable": {
+        "name": "RegEx variable",
+        "description": "Comparación de un valor variable con una expresión regular"
+      },
+      "data-mapping": {
+        "source": "Fuente",
+        "destination": "Destino",
+        "name": "mappeando Datos",
+        "edit": "Editar los datos del mapa",
+        "dataSource": "Fuente de Datos",
+        "description": "Asignar datos de una variable o tabla",
+        "addSource": "Añadir fuente",
+        "addDestination": "Añadir destino"
+      },
+      "sort-data": {
+        "name": "Ordenar datos",
+        "description": "Ordenar los elementos de datos",
+        "property": "Ordenar por la propiedad del artículo",
+        "addProperty": "Añadir propiedad"
+      },
+      "increase-variable": {
+        "name": "Aumento variable",
+        "description": "Aumentar el valor de una variable en una cantidad específica",
+        "increase": "Aumentar en"
+      },
+      "notification": {
+        "name": "notificación",
+        "description": "Mostrar una notificación",
+        "title": "Titulo",
+        "message": "Mensaje",
+        "imageUrl": "Imagen URL (opcional)",
+        "iconUrl": "Icono URL (opcional)"
+      },
+      "delete-data": {
+        "name": "Borrar datos",
+        "description": "Borrar datos de tablas o variables",
+        "from": "Datos de",
+        "allColumns": "[All columns]"
+      },
+      "log-data": {
+        "name": "Obtener datos de registro",
+        "description": "Obtener los últimos datos de registro de un flujo de trabajo",
+        "data": "Log data"
+      },
+      "tab-url": {
+        "name": "Get tab URL",
+        "description": "Obtener la URL de la pestaña",
+        "select": "Seleccionar pestaña",
+        "types": {
+          "active-tab": "Pestaña Activa",
+          "all": "All tabs"
+        },
+        "query": {
+          "title": "Query",
+          "matchPatterns": "@:workflow.blocks.switch-tab.matchPattern (opcional)",
+          "tabTitle": "Titulo de la pestaña (opcional)"
+        }
+      },
+      "reload-tab": {
+        "name": "Recargar pestaña",
+        "description": "Recargar la pestaña activa"
+      },
+      "press-key": {
+        "name": "Presionar tecla",
+        "description": "Presionar una tecla o una combinación",
+        "target": "Elemento objetivo (opcional)",
+        "key": "Key",
+        "detect": "Detect key",
+        "actions": {
+          "press-key": "Presione una tecla",
+          "multiple-keys": "Presione muchas teclas"
+        },
+        "press-time": "Tiempo de pulsación (milisegundos)"
+      },
+      "save-assets": {
+        "name": "Guardar activos",
+        "description": "Guardar activos (image, video, audio, or file) de un elemento o URL",
+        "filename": "Nombre del archivo (opcional)",
+        "saveDownloadIds": "Guardar los ID de descarga de los artículos",
+        "contentTypes": {
+          "title": "Type",
+          "element": "Elemento multimedia (imagen, audio o vídeo)",
+          "url": "URL"
+        }
+      },
+      "handle-dialog": {
+        "name": "Handle dialog",
+        "description": "Acepta o rechaza un cuadro de diálogo iniciado por JavaScript (alerta, confirmación, aviso).)",
+        "accept": "Aceptar diálogo",
+        "promptText": {
+          "label": "Prompt text (opcional)",
+          "description": "El texto a introducir en el diálogo antes de aceptar"
+        }
+      },
+      "handle-download": {
+        "name": "Handle download",
+        "description": "Handle downloaded file",
+        "timeout": "Tiempo de espera (milisegundos)",
+        "noPermission": "No tiene permiso para acceder a las descargas",
+        "onConflict": "En conflicto",
+        "waitFile": "Espere a que se descargue el archivo",
+        "downloadId": "ID de descarga de archivos (opcional)",
+        "filePath": "Ruta del archivo"
+      },
+      "insert-data": {
+        "name": "Insertar datos",
+        "description": "Insertar datos en una tabla o variable"
+      },
+      "clipboard": {
+        "name": "Portapapeles",
+        "description": "Obtener el texto copiado del portapapeles",
+        "data": "Datos del Portapapeles",
+        "noPermission": "No tiene permiso para acceder al portapapeles",
+        "grantPermission": "Conceder permiso",
+        "copySelection": "Copiar el texto seleccionado en la página",
+        "types": {
+          "get": "Obtener datos del portapapeles",
+          "insert": "Insertar texto en el portapapeles"
+        }
+      },
+      "hover-element": {
+        "name": "Hover element",
+        "description": "Hover over an element"
+      },
+      "create-element": {
+        "name": "Crear elemento",
+        "description": "Crear un elemento e insertarlo en la página",
+        "edit": "Editar elemento",
+        "wrap": "Envolver el elemento",
+        "insertEl": {
+          "title": "Insertar elemento",
+          "items": {
+            "before": "As first child",
+            "after": "As last child",
+            "next-sibling": "As next sibling",
+            "prev-sibling": "As previous sibling",
+            "replace": "Sustituir elemento de destino"
+          }
+        }
+      },
+      "upload-file": {
+        "name": "Cargar archivo",
+        "description": "Upload file into <input type=\"file\"> element",
+        "filePath": "URL o ruta de archivo",
+        "addFile": "Añadir archivo",
+        "onlyURL": "El navegador Firefox sólo admite la carga de archivos desde una URL.",
+        "requirement": "Lea los requisitos antes de utilizar este bloque",
+        "noFileAccess": "Automa no tiene acceso a los archivos"
+      },
+      "browser-event": {
+        "name": "Evento del navegador",
+        "description": "Ejecuta el siguiente bloque cuando se activa el evento especificado",
+        "events": "Eventos",
+        "timeout": "Tiempo de espera (milisegundos)",
+        "activeTabLoaded": "Pestaña Activa",
+        "setAsActiveTab": "Establecer como Pestaña Activa"
+      },
+      "blocks-group-2": {
+        "name": "@:workflow.blocks.blocks-group.name 2",
+        "description": "@:workflow.blocks.blocks-group.description"
+      },
+      "blocks-group": {
+        "name": "Grupo de Bloques",
+        "groupName": "Nombre del grupo",
+        "description": "Agrupando Bloques",
+        "dropText": "Arrastra y suelta el bloque aquí",
+        "cantAdd": "No se puede añadir \"{blockName}\" bloque al grupo"
+      },
+      "trigger": {
+        "name": "Trigger",
+        "description": "Bloque donde comenzará a ejecutarse el flujo de trabajo",
+        "addTime": "Añadir tiempo",
+        "selectDay": "Seleccionar día",
+        "timeExist": "Ya ha añadido un activador en {time} en {day}",
+        "fixedDelay": "Retraso fijo",
+        "contextMenus": {
+          "noPermission": "Este activador requiere \"contextMenus\" permiso para trabajar",
+          "grantPermission": "Conceder permiso",
+          "appearIn": "Aparecerá en",
+          "contextName": "Nombre del flujo de trabajo en el menú contextual"
+        },
+        "days": [
+          "Domingo",
+          "Lunes",
+          "Martes",
+          "Miércoles",
+          "Jueves",
+          "Viernes",
+          "Sábado"
+        ],
+        "useRegex": "Use regex",
+        "shortcut": {
+          "tooltip": "Atajo de registro",
+          "stopRecord": "Detener la grabación",
+          "checkboxTitle": "Ejecutar acceso directo incluso cuando estás en un elemento de entrada",
+          "checkbox": "Activo en entrada",
+          "note": "Nota: el atajo de teclado sólo funciona cuando estás en una página web"
+        },
+        "forms": {
+          "triggerWorkflow": "Trigger workflow",
+          "interval": "Intervalo (minutos)",
+          "delay": "Retraso (minutos)",
+          "date": "Fecha",
+          "time": "Tiempo",
+          "url": "URL or Regex",
+          "shortcut": "Atajo",
+          "cron-expression": "Expresión Cron"
+        },
+        "element-change": {
+          "target": "Elemento objetivo a observar",
+          "optionsInfo": "Qué mutación de elemento activará el flujo de trabajo",
+          "targetWebsite": "El patrón de coincidencia del sitio web en el que se encuentra el elemento de destino (haga clic para ver más ejemplos de patrones de coincidencia)",
+          "baseEl": {
+            "title": "Base element (opcional)",
+            "description": "Automa reiniciará la observación del elemento de destino cuando este elemento cambie"
+          },
+          "subtree": {
+            "title": "Incluir subárbol",
+            "description": "Ampliar la supervisión a todo el subárbol del elemento de destino"
+          },
+          "childList": {
+            "title": "Child list",
+            "description": "Supervisar la adición de nuevos elementos hijo o la eliminación de los existentes."
+          },
+          "attributes": {
+            "title": "Atributos",
+            "description": "Vigilar los cambios en los valores de los atributos del elemento de destino"
+          },
+          "attributeFilter": {
+            "title": "Filtro de atributos",
+            "separate": "Usa comas (,) Para separar los nombre de los atributos",
+            "description": "Supervisar sólo atributos específicos (dejar en blanco para supervisar todos)"
+          },
+          "characterData": {
+            "title": "Character data",
+            "description": "Supervisar los cambios en los datos de caracteres/texto dentro del elemento de destino."
+          }
+        },
+        "items": {
+          "manual": "Manualmente",
+          "interval": "Intervalo",
+          "cron-job": "Cron job",
+          "date": "En una fecha determinada",
+          "context-menu": "Menú contextual",
+          "element-change": "Al cambiar de elemento",
+          "specific-day": "En un día concreto",
+          "visit-web": "Al visitar un sitio web",
+          "on-startup": "Al iniciar el navegador",
+          "keyboard-shortcut": "Atajo de teclado"
+        }
+      },
+      "execute-workflow": {
+        "name": "Ejecutar flujo de trabajo",
+        "overwriteNote": "Esto sobrescribirá los datos globales del flujo de trabajo seleccionado",
+        "select": "Seleccionar flujo de trabajo",
+        "executeId": "Id de ejecución (opcional)",
+        "description": "",
+        "insertAllVars": "Utilizar todas las variables de flujo de trabajo actuales",
+        "insertVars": "Insertar variables de flujo de trabajo actuales",
+        "useCommas": "Utilice comas para separar el nombre de la variable",
+        "insertAllGlobalData": "Utilizar todo el flujo de trabajo actual globalData"
+      },
+      "google-sheets-drive": {
+        "name": "@:workflow.blocks.google-sheets.name (GDrive)",
+        "description": "@:workflow.blocks.google-sheets.description",
+        "connected": "Connected sheets",
+        "select": "Seleccionar hoja",
+        "connect": "Conectar hoja"
+      },
+      "google-drive": {
+        "name": "Google Drive",
+        "description": "Cargar archivos en Google Drive",
+        "actions": {
+          "upload": "Cargar archivos"
+        }
+      },
+      "google-sheets": {
+        "name": "Hojas de cálculo de Google",
+        "description": "Leer o actualizar datos de Google Sheets",
+        "previewData": "Previsualizar datos",
+        "firstRow": "Utilizar la primera fila como clave",
+        "keysAsFirstRow": "Utilizar llaves como primera fila",
+        "insertData": "Insertar datos",
+        "valueInputOption": "Opción de entrada de valor",
+        "insertDataOption": "Opción de insertar datos",
+        "rangeToSearch": "Rango para iniciar la búsqueda",
+        "dataFrom": {
+          "label": "Data from",
+          "options": {
+            "data-columns": "Table",
+            "custom": "Custom"
+          }
+        },
+        "refKey": {
+          "label": "Clave de referencia (opcional)",
+          "placeholder": "Key name"
+        },
+        "spreadsheetId": {
+          "label": "Id de hoja de cálculo",
+          "link": "Ver cómo obtener el Id de hoja de cálculo"
+        },
+        "range": {
+          "label": "Rango",
+          "link": "Haga clic para ver más ejemplos"
+        },
+        "select": {
+          "get": "Obtener los valores de las celdas de una hoja de cálculo",
+          "getRange": "Obtener rango de hoja de cálculo",
+          "update": "Actualizar los valores de las celdas de una hoja de cálculo",
+          "append": "Añadir valores de celdas de una hoja de cálculo",
+          "clear": "Borrar los valores de las celdas de una hoja de cálculo",
+          "create": "Crear una hoja de cálculo",
+          "add-sheet": "Añadir hoja"
+        }
+      },
+      "active-tab": {
+        "name": "Pestaña Activa",
+        "description": "Establece la pestaña en la que estás como Pestaña Activa"
+      },
+      "proxy": {
+        "name": "Proxy",
+        "description": "Establecer el proxy del navegador",
+        "clear": "Borrar todos los proxies",
+        "bypass": {
+          "label": "Bypass list",
+          "note": "Utilice comas (,) para separar las URL"
+        }
+      },
+      "new-window": {
+        "name": "Nueva ventana",
+        "description": "Crear una nueva ventana",
+        "top": "arriba",
+        "left": "izquierda",
+        "height": "alto",
+        "width": "ancho",
+        "note": "Nota: utilice 0 para desactivar",
+        "position": "Posición de la ventana",
+        "size": "Tamaño de la ventana",
+        "windowState": {
+          "placeholder": "Estado de la ventana",
+          "options": {
+            "normal": "Normal",
+            "minimized": "Minimizado",
+            "maximized": "Maximizado",
+            "fullscreen": "Pantalla completa"
+          }
+        },
+        "incognito": {
+          "text": "Establecer como ventana de incógnito",
+          "note": "Primero debe activar la opción 'Permitir en incógnito' para esta extensión."
+        }
+      },
+      "go-back": {
+        "name": "Volver atrás",
+        "description": "Volver a la página anterior"
+      },
+      "forward-page": {
+        "name": "Seguir adelante",
+        "description": "Pasar a la página siguiente"
+      },
+      "close-tab": {
+        "name": "Cerrar pestaña/ventana",
+        "description": "",
+        "url": "Patrones de coincidencia",
+        "activeTab": "Cerrar Pestaña Activa",
+        "allWindows": "Cerrar todas las ventanas"
+      },
+      "event-click": {
+        "name": "Elemento de clic",
+        "description": ""
+      },
+      "delay": {
+        "name": "Retraso",
+        "description": "Añade un retardo antes de ejecutar el siguiente bloque",
+        "input": {
+          "title": "Retraso en los milisegundos",
+          "placeholder": "(milisegundos)"
+        }
+      },
+      "parameter-prompt": {
+        "name": "Parameter Prompt"
+      },
+      "get-text": {
+        "name": "Obtener texto",
+        "description": "Obtener texto de un elemento",
+        "checkbox": "Insertar en tabla",
+        "includeTags": "Incluir etiquetas HTML",
+        "prefixText": {
+          "placeholder": "Text prefix",
+          "title": "Add prefix to the text"
+        },
+        "suffixText": {
+          "placeholder": "Text suffix",
+          "title": "Add suffix to the text"
+        }
+      },
+      "export-data": {
+        "name": "Exportar datos",
+        "description": "Exportar datos del flujo de trabajo",
+        "exportAs": "Exportar como",
+        "refKey": "Clave de referencia",
+        "bomHeader": "Add UTF-8 BOM",
+        "dataToExport": {
+          "placeholder": "Datos a exportar",
+          "options": {
+            "data-columns": "Table",
+            "google-sheets": "Hojas de cálculo de Google",
+            "variable": "Variable"
+          }
+        }
+      },
+      "element-scroll": {
+        "name": "Elemento de desplazamiento",
+        "description": "",
+        "scrollY": "Desplazamiento vertical",
+        "scrollX": "Desplazamiento horizontal",
+        "intoView": "Desplazarse a la vista",
+        "smooth": "Desplazamiento suave",
+        "incScrollX": "Incremento del desplazamiento horizontal",
+        "incScrollY": "Incrementar el desplazamiento vertical"
+      },
+      "switch-tab": {
+        "name": "Cambiar Pestaña",
+        "description": "Cambiar entre pestañas",
+        "matchPattern": "Match Patterns",
+        "url": "URL de la nueva pestaña",
+        "createIfNoMatch": "Crear si no hay coincidencias"
+      },
+      "new-tab": {
+        "name": "Nueva pestaña",
+        "description": "",
+        "url": "Nueva pestaña URL",
+        "tab-zoom": "Tab zoom",
+        "customUserAgent": "Use custom User-Agent",
+        "activeTab": "Establecer como Pestaña Activa",
+        "tabToGroup": "Agregar pestaña a un grupo",
+        "waitTabLoaded": "Espere a que se cargue la pestaña",
+        "updatePrevTab": {
+          "title": "Utilizar la pestaña abierta anteriormente en lugar de crear una nueva.",
+          "text": "Actualizar pestaña abierta anteriormente"
+        }
+      },
+      "link": {
+        "name": "Link",
+        "description": "Abrir elemento de enlace",
+        "openInNewTab": "Abrir en una nueva pestaña"
+      },
+      "attribute-value": {
+        "name": "Valor del atributo",
+        "description": "Obtener el valor de un atributo de un elemento",
+        "forms": {
+          "name": "Nombre del atributo",
+          "checkbox": "Insertar en tabla",
+          "column": "Seleccionar columna",
+          "value": "Valor del atributo",
+          "action": {
+            "get": "Obtener valor de atributo",
+            "set": "Establecer valor de atributo"
+          },
+          "extraRow": {
+            "checkbox": "Agregar fila extra",
+            "placeholder": "Valor",
+            "title": "Valor de la fila extra"
+          }
+        }
+      },
+      "forms": {
+        "name": "Formuario",
+        "description": "",
+        "selected": "Seleccionado",
+        "type": "Tipo de formulario",
+        "getValue": "Obtener valor del formulario",
+        "text-field": {
+          "name": "Campo de texto",
+          "value": "Valor",
+          "clearValue": "Borrar valor del formulario",
+          "delay": {
+            "placeholder": "Retraso",
+            "label": "Retraso al teclear (milisegundos)(0 para desactivar)"
+          }
+        },
+        "select": {
+          "name": "Select"
+        },
+        "radio": {
+          "name": "Radio"
+        },
+        "checkbox": {
+          "name": "Checkbox"
+        }
+      },
+      "repeat-task": {
+        "name": "Repetir la tarea",
+        "description": "",
+        "times": "tiempo",
+        "repeatFrom": "Repetir desde"
+      },
+      "javascript-code": {
+        "name": "codigo JavaScript",
+        "description": "Ejecute su código JavaScript en la página web",
+        "availabeFuncs": "Funciones disponibles:",
+        "removeAfterExec": "Eliminar tras la ejecución del bloque",
+        "everyNewTab": "Ejecutar en cada nueva pestaña",
+        "context": {
+          "name": "Contexto de ejecución",
+          "items": {
+            "website": "Pestaña Activa",
+            "background": "Background"
+          }
+        },
+        "modal": {
+          "tabs": {
+            "code": "Codigo JavaScript",
+            "preloadScript": "Script de precarga"
+          }
+        },
+        "timeout": {
+          "placeholder": "Tiempo de espera (milisegundos)",
+          "title": "Tiempo de espera de ejecución de código JavaScript"
+        }
+      },
+      "trigger-event": {
+        "name": "Evento desencadenante",
+        "description": "",
+        "selectEvent": "Seleccionar evento"
+      },
+      "conditions": {
+        "name": "Condiciones",
+        "add": "Añadir ruta",
+        "retryConditions": "Reintentar si no se cumplen las condiciones",
+        "description": "Bloque condicional",
+        "refresh": "Actualizar conexiones de condiciones",
+        "fallbackTitle": "Se ejecuta cuando todas las comparaciones no cumplen el requisito",
+        "equals": "Es igual a",
+        "gt": "Mayor que",
+        "gte": "Mayor o igual que",
+        "lt": "Menos de",
+        "lte": "Menor o igual que",
+        "ne": "No es igual",
+        "contains": "Contiene"
+      },
+      "element-exists": {
+        "name": "El elemento existe",
+        "description": "Comprobar si existe un elemento",
+        "selector": "Selector de elementos",
+        "fallbackTitle": "Se ejecuta cuando el elemento no existe",
+        "throwError": "Lanza un error si no existe",
+        "tryFor": {
+          "title": "Cuántas veces hay que intentar comprobar si el elemento existe",
+          "label": "Inténtalo"
+        },
+        "timeout": {
+          "label": "Tiempo de espera (milisegundos)",
+          "title": "Tiempo de espera para cada intento"
+        }
+      },
+      "webhook": {
+        "name": "Solicitud HTTP",
+        "description": "Realizar una solicitud HTTP",
+        "contentType": "Tipo de contenido",
+        "method": "Método de solicitud",
+        "url": "Solicitar URL",
+        "fallback": "Se ejecuta cuando falla la petición HTTP",
+        "buttons": {
+          "header": "Add header"
+        },
+        "timeout": {
+          "placeholder": "Tiempo de espera",
+          "title": "Tiempo de espera de ejecución de la solicitud HTTP (ms)"
+        },
+        "tabs": {
+          "headers": "Headers",
+          "body": "Body",
+          "response": "Respuesta"
+        }
+      },
+      "while-loop": {
+        "name": "Bucle while",
+        "description": "Ejecuta bloques mientras se cumple la condición",
+        "editCondition": "Editar condición",
+        "fallback": "Se ejecuta cuando la condición es falsa"
+      },
+      "loop-elements": {
+        "name": "Elementos de bucle",
+        "description": "Iterar por los elementos",
+        "loadMore": "Cargar más elementos",
+        "scrollToBottom": "Desplácese hasta abajo",
+        "scrollToTop": "Ir arriba",
+        "actions": {
+          "none": "Ninguno",
+          "click-element": "Haga clic en un elemento",
+          "scroll": "Desplácese",
+          "click-link": "Haga clic en un enlace",
+          "scroll-up": "Desplácese hacia arriba"
+        }
+      },
+      "loop-data": {
+        "name": "Datos del bucle",
+        "description": "Iterar a través de una tabla o de sus datos personalizados",
+        "loopId": "ID de bucle",
+        "refKey": "Clave de referencia",
+        "startIndex": "Empezar desde el índice",
+        "resumeLastWorkflow": "Reanudar el último flujo de trabajo",
+        "reverse": "Invertir el orden de los bucles",
+        "modal": {
+          "fileTooLarge": "Archivo demasiado grande para editar",
+          "maxFile": "El tamaño máximo del archivo es de 1 MB",
+          "options": {
+            "firstRow": "Utilizar la primera fila como clave"
+          }
+        },
+        "buttons": {
+          "clear": "Limpiar datos",
+          "insert": "Insertar datos",
+          "import": "Importar fichero"
+        },
+        "maxLoop": {
+          "title": "Número máximo de datos en bucle",
+          "label": "Datos máximos en bucle (0 para desactivar)"
+        },
+        "loopThrough": {
+          "placeholder": "En bucle",
+          "fromNumber": "From number",
+          "toNumber": "Al número",
+          "options": {
+            "numbers": "Números",
+            "variable": "Variable",
+            "data-columns": "Datos en columna",
+            "table": "Cuadro",
+            "custom-data": "Datos personalizados",
+            "google-sheets": "Hojas de cálculo de Google",
+            "elements": "Elementos"
+          }
+        }
+      },
+      "loop-breakpoint": {
+        "name": "Punto de interrupción del bucle",
+        "description": "Para indicar dónde debe detenerse el bloque Loop Data"
+      },
+      "take-screenshot": {
+        "name": "Hacer una captura de pantalla",
+        "fullPage": "Captura de pantalla de página completa",
+        "description": "Haz una captura de pantalla de la Pestaña Activa actual",
+        "imageQuality": "Calidad de la imagen",
+        "saveToColumn": "Insertar una captura de pantalla en una tabla",
+        "saveToComputer": "Guardar captura de pantalla en el ordenador",
+        "types": {
+          "title": "Haga una captura de pantalla de",
+          "page": "Una página",
+          "fullpage": "Una página completa",
+          "element": "Un elemento"
+        }
+      },
+      "switch-to": {
+        "name": "Switch frame",
+        "description": "Cambiar entre la ventana principal y un iframe",
+        "iframeSelector": "Selector de elementos",
+        "windowTypes": {
+          "main": "Ventana principal",
+          "iframe": "Iframe"
+        }
+      },
+      "debugMode": {
+        "title": "Modo depuración",
+        "description": "Ejecutar bloque utilizando el protocolo DevTools de Chrome"
+      }
+    }
+  }
+}
diff --git a/src/locales/es/common.json b/src/locales/es/common.json
new file mode 100644
index 000000000..2fccbebf4
--- /dev/null
+++ b/src/locales/es/common.json
@@ -0,0 +1,77 @@
+{
+  "common": {
+    "dashboard": "Dashboard",
+    "workflow": "Flujo de Trabajo | Flujos de Trabajo",
+    "collection": "Coleccion | Colecciones",
+    "log": "Log | Logs",
+    "block": "Bloque | Bloques",
+    "schedule": "Horario",
+    "folder": "Carpeta | Carpetas",
+    "new": "Nuevo",
+    "docs": "Documentacion",
+    "search": "Buscar",
+    "example": "Ejemplo | Ejemplos",
+    "import": "Importar",
+    "export": "Exportar",
+    "rename": "Renombrar",
+    "execute": "Ejecutar",
+    "delete": "Eliminar",
+    "cancel": "Cancelar",
+    "settings": "Ajustes",
+    "options": "Opciones",
+    "confirm": "Confirmar",
+    "name": "Nombre",
+    "all": "Todo",
+    "add": "Agregar",
+    "save": "Guardar",
+    "data": "Dato",
+    "stop": "Detener",
+    "sheet": "Hoja",
+    "pause": "Pausar",
+    "resume": "Resumen",
+    "action": "Accion | Acciones",
+    "packages": "Paquete",
+    "storage": "Almacenamiento",
+    "editor": "editor",
+    "running": "Ejecutando",
+    "globalData": "Datos Globales",
+    "fileName": "Nombre del fichero",
+    "description": "Descripcion",
+    "disable": "Desactivar",
+    "disabled": "Desactivado",
+    "enable": "Habilitar",
+    "fallback": "Respuesta",
+    "update": "Actualizacion",
+    "feature": "Característica",
+    "duplicate": "Duplicado",
+    "password": "Contraseña",
+    "category": "Categoria",
+    "optional": "Opcional",
+    "0disable": "0 para desactivar",
+    "millisecond": "milisegundo | milisegundos"
+  },
+  "message": {
+    "noBlock": "Ningún bloque",
+    "noData": "No hay datos que lo demuestren",
+    "noTriggerBlock": "No puedo encontrar un bloque desencadenador",
+    "useDynamicData": "Aprende a añadir datos dinámicos",
+    "delete": "¿Estás seguro de que quieres borrar \"{name}\"?",
+    "empty": "Ups... Parece que usted no tiene ningún artículo",
+    "maxSizeExceeded": "El tamaño del archivo ha superado el máximo permitido",
+    "notSaved": "¿De verdad quieres irte? ¡Tienes cambios sin guardar!",
+    "somethingWrong": "Algo salió mal",
+    "limitExceeded": "Ha superado el límite"
+  },
+  "sort": {
+    "sortBy": "Ordenar por",
+    "name": "Nombre",
+    "createdAt": "Fecha de creación",
+    "updatedAt": "Última actualización",
+    "mostUsed": "Los más utilizados"
+  },
+  "logStatus": {
+    "stopped": "parado",
+    "error": "error",
+    "success": "éxito"
+  }
+}
diff --git a/src/locales/es/newtab.json b/src/locales/es/newtab.json
new file mode 100644
index 000000000..1b5d91866
--- /dev/null
+++ b/src/locales/es/newtab.json
@@ -0,0 +1,516 @@
+{
+  "home": {
+    "viewAll": "Ver todo",
+    "communities": "Comunidades"
+  },
+  "welcome": {
+    "title": "Bienvenido a Automa! 🎉",
+    "text": "Para empezar, lea la documentación o consulte los flujos de trabajo en Automa Marketplace.",
+    "marketplace": "Marketplace"
+  },
+  "packages": {
+    "name": "Package | Packages",
+    "add": "Añadir paquete",
+    "icon": "Icono del paquete",
+    "open": "Abrir paquetes",
+    "new": "Nuevo paquete",
+    "import": "Importar paquete",
+    "set": "Establecer como un paquete",
+    "settings": {
+      "asBlock": "Establecer paquete como bloque"
+    },
+    "categories": {
+      "my": "Mis Paquetes",
+      "installed": "Instalar Paquetes"
+    }
+  },
+  "scheduledWorkflow": {
+    "title": "Flujos de trabajo programados",
+    "nextRun": "Próxima ejecución",
+    "active": "Activar",
+    "refresh": "Refrescar",
+    "schedule":{
+      "title": "Horario",
+      "types": {
+        "everyDay": "Todos los días",
+        "general": "Cada {time}",
+        "interval": "Cada {time} minutos"
+      }
+    }
+  },
+  "storage": {
+    "title": "Almacenamiento",
+    "table": {
+      "add": "Añadir tabla",
+      "edit": "Editar Tabla",
+      "createdAt": "Creado en",
+      "modifiedAt": "Modificado en",
+      "rowsCount": "Recuento de filas",
+      "delete": "Borrar tabla"
+    }
+  },
+  "credential": {
+    "title": "Credencial | Credenciales",
+    "add": "Añadir credencial",
+    "use": {
+      "title": "Credenciales usadas",
+      "description": "Este flujo de trabajo utiliza estas credenciales"
+    }
+  },
+  "workflowPermissions": {
+    "title": "Permisos de flujo de trabajo",
+    "description": "Este flujo de trabajo requiere estos permisos para ejecutarse correctamente",
+    "contextMenus": {
+      "title": "Menú contextual",
+      "description": "Para ejecutar el flujo de trabajo a través del menú contextual"
+    },
+    "clipboardRead": {
+      "title": "Portapapeles",
+      "description": "Para acceder a los datos del portapapeles"
+    },
+    "notifications": {
+      "title": "Notificación",
+      "description": "Para mostrar una notificación"
+    },
+    "downloads": {
+      "title": "Descargar",
+      "description": "Guardar los activos de la página y cambiar el nombre del archivo descargado"
+    },
+    "cookies": {
+      "title": "Cookies",
+      "description": "Leer, establecer, o quitar cookies"
+    }
+  },
+  "updateMessage": {
+    "text1": "Automa ha sido actualizado a v{version},",
+    "text2": "ver las novedades."
+  },
+  "workflows": {
+    "folder": {
+      "new": "Nueva carpeta",
+      "name": "Nombre de la carpeta",
+      "delete": "Eliminar carpeta",
+      "rename": "Cambiar nombre de carpeta"
+    }
+  },
+  "auth": {
+    "title": "Auth",
+    "signIn": "Iniciar sesión",
+    "username": "Primero tienes que configurar tu nombre de usuario",
+    "clickHere": "Pulse aquí",
+    "text": "Tienes que iniciar sesión antes de poder hacerlo."
+  },
+  "running": {
+    "start": "Comenzó el {date}",
+    "message": "Esto sólo muestra los últimos 5 registros"
+  },
+  "settings": {
+    "theme": "Tema",
+    "shortcuts": {
+      "duplicate": "Acceso directo ya utilizado por \"{name}\""
+    },
+    "editor": {
+      "title": "Titulo",
+      "curvature": {
+        "title": "Curvatura de la línea",
+        "line": "Línea",
+        "reroute": "Redirigir",
+        "rerouteFirstLast": "Redirigir primer y último punto"
+      },
+      "arrow": {
+        "title": "Fecha",
+        "description": "Añadir una flecha al final de la línea"
+      },
+      "snapGrid": {
+        "title": "Ajustar a la cuadrícula",
+        "description": "Ajustarse a la cuadrícula al mover un bloque"
+      },
+      "saveWhenExecute": {
+        "title": "Guardado automático al ejecutar el flujo de trabajo",
+        "description": "Los cambios en el flujo de trabajo se guardarán al ejecutarlo"
+      }
+    },
+    "deleteLog": {
+      "title": "Borrado automático de registros de flujo de trabajo",
+      "after": "Borrar después de",
+      "deleteAfter": {
+        "never": "Nunca",
+        "days": "{day} dias"
+      }
+    },
+    "language": {
+      "label": "Idioma",
+      "helpTranslate": "¿No encuentra su idioma? Puedes ayuda a traducir.",
+      "reloadPage": "Recargar la página para que el cambio surta efecto"
+    },
+    "menu": {
+      "backup": "Flujos de trabajo de copia de seguridad",
+      "editor": "Editor",
+      "general": "General",
+      "shortcuts": "Atajos",
+      "about": "Acerca de"
+    },
+    "backupWorkflows": {
+      "title": "Copia de seguridad local",
+      "invalidPassword": "Contraseña no válida",
+      "workflowsAdded": "{count} se han añadido flujos de trabajo",
+      "name": "Flujos de trabajo de copia de seguridad",
+      "needSignin": "Primero tienes que registrarte",
+      "backup": {
+        "button": "Copia de seguridad",
+        "settings": "Configuración de la copia de seguridad",
+        "encrypt": "Cifrar con contraseña",
+        "schedule": "Programar copia de seguridad local"
+      },
+      "restore": {
+        "title": "Restaurar flujos de trabajo",
+        "button": "Restaurar",
+        "update": "Actualizar si el flujo de trabajo existe"
+      },
+      "cloud": {
+        "buttons": {
+          "local": "Local",
+          "cloud": "Nube"
+        },
+        "location": "Ubicación",
+        "delete": "Eliminar copia de seguridad",
+        "title": "Respaldo en la Nube",
+        "sync": "Sincronizar",
+        "lastSync": "Ultima Sincronización",
+        "lastBackup": "Ultimo Respaldo",
+        "select": "Seleccionar flujos de trabajo",
+        "storedWorkflows": "Flujos de trabajo almacenados en la nube",
+        "selected": "Selección",
+        "selectText": "Seleccione los flujos de trabajo de los que desea hacer una copia de seguridad",
+        "selectAll": "Seleccionar todo",
+        "deselectAll": "Deseleccionar todo",
+        "needSelectWorkflow": "Debe seleccionar los flujos de trabajo de los que desea hacer una copia de seguridad"
+      }
+    }
+  },
+  "workflow": {
+    "events": {
+      "title": "Eventos de flujo de trabajo",
+      "add-action": "Añadir acción",
+      "description": "Realizar acciones cuando se produzca el evento.",
+      "event": "Evento | Eventos",
+      "action": "Acción",
+      "actions": {
+        "js-code": {
+          "title": "Ejecutar código JS"
+        },
+        "http-request": {
+          "title": "Solicitud HTTP"
+        }
+      },
+      "types": {
+        "finish:success": {
+          "name": "Finalizar (éxito)",
+          "description": "La ejecución del flujo de trabajo finaliza con éxito"
+        },
+        "finish:failed": {
+          "name": "Finalizar (fallido)",
+          "description": "La ejecución del flujo de trabajo ha finalizado con error"
+        }
+      }
+    },
+    "previewMode": {
+      "title": "Modo de vista previa",
+      "description": "Estás en el modo de vista previa, los cambios realizados no se guardarán."
+    },
+    "pinWorkflow": {
+      "pin": "Fijar flujo de trabajo",
+      "unpin": "Quitar flujo de trabajo",
+      "pinned": "Flujos de trabajo anclados"
+    },
+    "parameters": {
+      "add": "Añadir parámetro",
+      "preferInTab": "Preferir parámetros de entrada en la pestaña"
+    },
+    "my": "Mis flujos de trabajo",
+    "testing": {
+      "title": "Modo de Prueba",
+      "nextBlock": "Siguiente bloque",
+      "startRun": "Comience a ejecutar en",
+      "disabled": "Guarde primero los cambios"
+    },
+    "import": "Importar flujo de trabajo",
+    "new": "Nuevo Flujo",
+    "delete": "Eliminar Flujo",
+    "browse": "Explorar flujos",
+    "name": "Nombre del flujo",
+    "rename": "Renombrar flujo",
+    "backupCloud": "Copia de seguridad en la nube del flujo",
+    "add": "Añadir flujo de trabajo",
+    "clickToEnable": "Haga clic para activar",
+    "toggleSidebar": "Alternar barra lateral",
+    "cantEdit": "No se puede editar el flujo de trabajo compartido",
+    "undo": "Deshacer",
+    "redo": "Rehacer",
+    "autoAlign": {
+      "title": "Auto-alear"
+    },
+    "blocksFolder": {
+      "title": "Bloque de carpetas",
+      "add": "Añadir bloques a la carpeta",
+      "save": "Guardar en carpeta"
+    },
+    "searchBlocks": {
+      "title": "Buscar bloques en el editor"
+    },
+    "conditionBuilder": {
+      "title": "Condición de constructor",
+      "add": "Añadir condición",
+      "and": "AND",
+      "or": "OR",
+      "topAwait": "Apoyar la espera de alto nivel y \"automaRefData\" función"
+    },
+    "host": {
+      "title": "Flujo de trabajo del host",
+      "set": "Establecer como flujo de trabajo anfitrión",
+      "id": "ID de host",
+      "add": "Añadir flujo de trabajo alojado",
+      "sync": {
+        "title": "Sincronización",
+        "description": "Sincronización con el flujo de trabajo del host"
+      },
+      "messages": {
+        "hostExist": "Ya ha añadido este host",
+        "notFound": "No se puede encontrar un flujo de trabajo alojado con el ID \"{id}\""
+      }
+    },
+    "type": {
+      "local": "Local",
+      "shared": "Compartido",
+      "host": "Host"
+    },
+    "unpublish": {
+      "title": "Flujo de trabajo de despublicación",
+      "button": "Anular la publicación",
+      "body": "¿Está seguro de que desea anular la publicación del flujo de trabajo \"{name}\"?"
+    },
+    "share": {
+      "url": "Compartir URL",
+      "publish": "Publique",
+      "sharedAs": "Compartido como \"{name}\"",
+      "title": "Compartir flujo de trabajo",
+      "download": "Guardar flujo de trabajo en local",
+      "edit": "Editar descripción",
+      "fetchLocal": "Obtener flujo de trabajo local",
+      "update": "Actualización",
+      "unpublish": "Anule la publicación"
+    },
+    "variables": {
+      "title": "Variable | Variables",
+      "name": "Nombre de la variable",
+      "assign": "Asignar a variable"
+    },
+    "protect": {
+      "title": "Proteger el flujo de trabajo",
+      "remove": "Quitar la protección",
+      "button": "Proteja",
+      "note": "Nota: esta contraseña será necesaria más adelante para editar o eliminar el flujo de trabajo."
+    },
+    "locked": {
+      "title": "Este flujo de trabajo está protegido",
+      "body": "Introduce la contraseña para desbloquearlo",
+      "unlock": "Desbloquear",
+      "messages": {
+        "incorrect-password": "Contraseña incorrecta"
+      }
+    },
+    "state": {
+      "executeBy": "Ejecutado por: \"{name}\""
+    },
+    "table": {
+      "title": "Tabla | Tablas",
+      "placeholder": "Buscar o añadir una columna",
+      "select": "Seleccionar columna",
+      "column": {
+        "name": "Nombre de columna",
+        "type": "Tipo de datos"
+      }
+    },
+    "sidebar": {
+      "workflowIcon": "Icono de flujo de trabajo"
+    },
+    "editor": {
+      "zoomIn": "Ampliar",
+      "zoomOut": "Alejar",
+      "resetZoom": "Restablecer zoom",
+      "duplicate": "Duplicar",
+      "copy": "Copiar",
+      "paste": "Pegar",
+      "group": "Agrupar bloques",
+      "ungroup": "Desagrupar bloques"
+    },
+    "settings": {
+      "saveLog": "Guardar registro de flujo de trabajo",
+      "executedBlockOnWeb": "Mostrar el bloque ejecutado en la página web",
+      "notification": {
+        "title": "Notificación de flujo de trabajo",
+        "description": "Mostrar el estado del flujo de trabajo (success or failed) después de ejecutar",
+        "noPermission": "Esta opción requiere \"notifications\" permiso para trabajar"
+      },
+      "publicId": {
+        "title": "ID público del flujo de trabajo",
+        "description": "Establezca un ID público para ejecutar el flujo de trabajo a través de un evento personalizado de JavaScript"
+      },
+      "defaultColumn": {
+        "title": "Insertar en la columna por defecto",
+        "description": "Insertar datos en la columna por defecto si no hay ninguna columna seleccionada en el bloque",
+        "name": "Nombre de columna por defecto"
+      },
+      "autocomplete": {
+        "title": "Autocompletar",
+        "description": "Activar autocompletar en el bloque de entrada (desactivar si hace inestable Automa)"
+      },
+      "clearCache": {
+        "title": "Limpiar cache",
+        "description": "Limpiar cache (state and loop index) del flujo de trabajo",
+        "info": "Se ha borrado correctamente la caché del flujo de trabajo",
+        "btn": "Limpiar"
+      },
+      "reuseLastState": {
+        "title": "Reutilizar el estado del último flujo de trabajo",
+        "description": "Utilizar los datos estatales (tabla, variables y datos globales) del último flujo de trabajo ejecutado"
+      },
+      "debugMode": {
+        "title": "Modo depuración",
+        "description": "Ejecutar el flujo de trabajo mediante el protocolo DevTools de Chrome"
+      },
+      "restartWorkflow": {
+        "for": "Reiniciar",
+        "times": "Veces",
+        "description": "Número máximo de veces que se reiniciará el flujo de trabajo"
+      },
+      "onError": {
+        "title": "Error en el flujo de trabajo",
+        "description": "Establecer la acción a tomar si se produce un error en el flujo de trabajo",
+        "items": {
+          "keepRunning": "Seguir Ejecutando",
+          "stopWorkflow": "Detener el flujo de trabajo",
+          "restartWorkflow": "Reiniciar el flujo de trabajo"
+        }
+      },
+      "timeout": {
+        "title": "Tiempo de espera del flujo de trabajo (milisegundos)"
+      },
+      "blockDelay": {
+        "title": "Retraso en bloque (milisegundos)",
+        "description": "Añadir retardo antes de ejecutar cada uno de los bloques"
+      },
+      "tabLoadTimeout": {
+        "title": "Tiempo de espera de carga de la pestaña",
+        "description": "Tiempo máximo para cargar una pestaña en milisegundos, introduzca 0 para desactivar el tiempo de espera"
+      }
+    }
+  },
+  "collection": {
+    "description": "Ejecute sus flujos de trabajo en secuencia",
+    "new": "Nueva colección",
+    "delete": "Borrar colección",
+    "add": "Añadir colección",
+    "rename": "Renombrar colección",
+    "flow": "Flujo",
+    "dragDropText": "Introduzca aquí un flujo de trabajo o un bloque",
+    "options": {
+      "atOnce": {
+        "title": "Ejecutar todos los flujos de trabajo de la colección a la vez",
+        "description": "Los bloques no se ejecutarán cuando se utilice esta opción"
+      }
+    },
+    "globalData": {
+      "note": "Esto sobrescribirá los datos globales del flujo de trabajo"
+    }
+  },
+  "log": {
+    "flowId": "ID de flujo",
+    "goBack": "Volver a \"{name}\" Registros",
+    "goWorkflow": "Ir al flujo de trabajo",
+    "startedDate": "Fecha de inicio",
+    "duration": "Duración",
+    "selectAll": "Seleccionar todo",
+    "deselectAll": "Deseleccionar todo",
+    "deleteSelected": "Borrar los registros seleccionados",
+    "clearLogs": {
+      "title": "Borrar registros",
+      "description": "¿Estás seguro de que quieres borrar todos los registros?"
+    },
+    "types": {
+      "stop": "El flujo de trabajo se detiene",
+      "finish": "Acabado"
+    },
+    "messages": {
+      "url-empty": "La URL está vacía",
+      "invalid-url": "La URL no es válida",
+      "conditions-empty": "Las condiciones están vacías",
+      "invalid-proxy-host": "Proxy host no válido",
+      "workflow-disabled": "Flujo de trabajo desactivado",
+      "selector-empty": "El selector de elementos está vacío",
+      "invalid-body": "El cuerpo del contenido no es un JSON válido",
+      "invalid-active-tab": "\"{url}\" es una URL no válida",
+      "empty-spreadsheet-id": "El ID de la hoja de cálculo está vacío",
+      "invalid-loop-data": "Datos no válidos para el bucle",
+      "empty-workflow": "Primero debe seleccionar un flujo de trabajo",
+      "active-tab-removed": "Se ha eliminado la pestaña de flujo de trabajo activo",
+      "empty-spreadsheet-range": "El rango de la hoja de cálculo está vacío",
+      "stop-timeout": "El flujo de trabajo se detuvo debido a un tiempo de espera",
+      "no-file-access": "Automa no tiene acceso al fichero",
+      "no-workflow": "No se puede encontrar un flujo de trabajo con el ID \"{workflowId}\"",
+      "no-match-tab": "No se puede encontrar una pestaña que coincida con el patrón \"{pattern}\"",
+      "no-clipboard-acces": "No tiene permiso para acceder al portapapeles",
+      "browser-not-supported": "Esta función no está disponible en {browser} navegador",
+      "element-not-found": "No se puede encontrar un elemento con el selector \"{selector}\"",
+      "no-permission": "No tiene \"{permission}\" permiso para realizar esta acción",
+      "not-iframe": "Elemento con \"{selector}\" el selector no es un elemento iframe",
+      "iframe-not-found": "No se puede encontrar un elemento iframe con el selector \"{selector}\"",
+      "workflow-infinite-loop": "No se puede ejecutar el flujo de trabajo para evitar un bucle infinito",
+      "not-debug-mode": "El flujo de trabajo debe ejecutarse en modo de depuración para que este bloque funcione correctamente",
+      "no-iframe-id": "No se puede encontrar el Frame ID para el elemento iframe con el selector \"{selector}\"",
+      "no-tab": "No se puede conectar a una ficha, utilice \"New tab\" o \"Active tab\" antes de utilizar el bloque \"{name}\" bloque"
+    },
+    "description": {
+      "text": "{status} on {date} in {duration}",
+      "status": {
+        "success": "Con éxito",
+        "error": "Fallido",
+        "stopped": "Detenido"
+      }
+    },
+    "delete": {
+      "title": "Eliminar Registro",
+      "description": "¿Estás seguro de que quieres borrar todos los registros seleccionados?"
+    },
+    "exportData": {
+      "title": "Exportar datos",
+      "types": {
+        "json": "JSON",
+        "csv": "CSV",
+        "plain-text": "Texto sin formato"
+      }
+    },
+    "filter": {
+      "title": "Filtros",
+      "byStatus": "Por estado",
+      "byDate": {
+        "title": "Por fecha",
+        "items": {
+          "lastDay": "Último día",
+          "last7Days": "Últimos siete días",
+          "last30Days": "Últimos treinta días"
+        }
+      }
+    }
+  },
+  "components": {
+    "pagination": {
+      "text1": "Mostrar",
+      "text2": "Elementos de {count}",
+      "nextPage": "Siguiente página",
+      "currentPage": "Página actual",
+      "prevPage": "Página anterior",
+      "of": "de {page}"
+    }
+  }
+}
\ No newline at end of file
diff --git a/src/locales/es/popup.json b/src/locales/es/popup.json
new file mode 100644
index 000000000..e7c59041f
--- /dev/null
+++ b/src/locales/es/popup.json
@@ -0,0 +1,32 @@
+{
+  "recording": {
+    "stop": "Detener la grabación",
+    "title": "Grabación"
+  },
+  "home": {
+    "record": {
+      "title": "Registro del flujo de trabajo",
+      "button": "Registro",
+      "name": "Nombre del flujo de trabajo",
+      "selectBlock": "Seleccione un bloque para empezar",
+      "anotherBlock": "No se puede empezar desde este bloque",
+      "tabs": {
+        "new": "Nuevo flujo de trabajo",
+        "existing": "Flujo de trabajo existente"
+      }
+    },
+    "elementSelector": {
+      "name": "Selector de elementos",
+      "noAccess": "No tiene acceso a este sitio"
+    },
+    "workflow": {
+      "new": "Nuevo flujo de trabajo",
+      "rename": "Renombrar flujo de trabajo",
+      "delete": "Eliminar flujo de trabajo",
+      "type": {
+        "host": "Host",
+        "local": "Local"
+      }
+    }
+  }
+}
diff --git a/src/utils/shared.js b/src/utils/shared.js
index 6761a815d..6d7f9c907 100644
--- a/src/utils/shared.js
+++ b/src/utils/shared.js
@@ -1583,6 +1583,7 @@ export const supportLocales = [
   { id: 'zh', name: '简体中文' },
   { id: 'zh-TW', name: '繁體中文' },
   { id: 'tr', name: 'Türkçe' },
+  { id: 'es', name: 'Spanish' },
 ];
 
 export const communities = [

From 62489659d106ed5874840d9039490751a2fee7a2 Mon Sep 17 00:00:00 2001
From: zthxxx <zthxxx.me@gmail.com>
Date: Fri, 26 Apr 2024 23:47:00 +0800
Subject: [PATCH 8/9] fix: fix get the active tab from extension dashborad
 window

While user want to get active tab from extension dashboard window (such as trigger CSS selector),
the extension dashboard window is always the only focused one, so that original code could not get the active tab correctly.

But via the [`windows.getLastFocused()`](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/windows/getLastFocused) api
with query the "normal" type window will exactly get the correctly active tab.
---
 src/manifest.chrome.json |  1 +
 src/utils/helper.js      | 24 +++++++-----------------
 2 files changed, 8 insertions(+), 17 deletions(-)

diff --git a/src/manifest.chrome.json b/src/manifest.chrome.json
index 53911e610..475e444fe 100644
--- a/src/manifest.chrome.json
+++ b/src/manifest.chrome.json
@@ -55,6 +55,7 @@
   ],
   "permissions": [
     "tabs",
+    "activeTab",
     "proxy",
     "alarms",
     "storage",
diff --git a/src/utils/helper.js b/src/utils/helper.js
index cc6e28d2c..cf1f81661 100644
--- a/src/utils/helper.js
+++ b/src/utils/helper.js
@@ -2,29 +2,19 @@ import browser from 'webextension-polyfill';
 
 export async function getActiveTab() {
   try {
-    let windowId = null;
     const tabsQuery = {
       active: true,
       url: '*://*/*',
     };
-    const extURL = browser.runtime.getURL('');
-    const windows = await browser.windows.getAll({ populate: true });
-    for (const browserWindow of windows) {
-      const [tab] = browserWindow.tabs;
-      const isDashboard =
-        browserWindow.tabs.length === 1 && tab.url?.includes(extURL);
-
-      if (isDashboard) {
-        await browser.windows.update(browserWindow.id, {
-          focused: false,
-        });
-      } else if (browserWindow.focused) {
-        windowId = browserWindow.id;
-      }
-    }
+
+    const window = await browser.windows.getLastFocused({
+      populate: true,
+      windowTypes: ['normal'],
+    });
+    const windowId = window.id;
 
     if (windowId) tabsQuery.windowId = windowId;
-    else if (windows.length > 2) tabsQuery.lastFocusedWindow = true;
+    else tabsQuery.lastFocusedWindow = true;
 
     const [tab] = await browser.tabs.query(tabsQuery);
 

From 835eb57994bb9e1fc38cccda401cfdc137cb9785 Mon Sep 17 00:00:00 2001
From: zZeleZz <lexir@inbox.ru>
Date: Tue, 28 May 2024 11:32:57 +0000
Subject: [PATCH 9/9] feat(locale): add ru locale

---
 src/lib/dayjs.js           |   1 +
 src/locales/ru/block.json  | 806 +++++++++++++++++++++++++++++++++++++
 src/locales/ru/common.json |  77 ++++
 src/locales/ru/newtab.json | 516 ++++++++++++++++++++++++
 src/locales/ru/popup.json  |  32 ++
 src/utils/shared.js        |   1 +
 6 files changed, 1433 insertions(+)
 create mode 100644 src/locales/ru/block.json
 create mode 100644 src/locales/ru/common.json
 create mode 100644 src/locales/ru/newtab.json
 create mode 100644 src/locales/ru/popup.json

diff --git a/src/lib/dayjs.js b/src/lib/dayjs.js
index 0b7e57c41..ce7cf2103 100644
--- a/src/lib/dayjs.js
+++ b/src/lib/dayjs.js
@@ -7,6 +7,7 @@ import 'dayjs/locale/fr';
 import 'dayjs/locale/it';
 import 'dayjs/locale/uk';
 import 'dayjs/locale/tr';
+import 'dayjs/locale/ru';
 
 dayjs.extend(relativeTime);
 
diff --git a/src/locales/ru/block.json b/src/locales/ru/block.json
new file mode 100644
index 000000000..e6b2b1f96
--- /dev/null
+++ b/src/locales/ru/block.json
@@ -0,0 +1,806 @@
+{
+    "collection": {
+      "blocks": {
+        "export-result": {
+          "name": "Экспорт результата",
+          "description": "Экспортировать результат коллекции в формате JSON"
+        }
+      }
+    },
+    "workflow": {
+      "blocks": {
+        "base": {
+          "title": "Блоки",
+          "moveToGroup": "Переместить блок в группу блоков",
+          "selector": "Селектор элемента",
+          "selectorOptions": "Опции селектора",
+          "timeout": "Таймаут (миллисекунды)",
+          "noPermission": "У Automa недостаточно разрешений для выполнения этого действия",
+          "grantPermission": "Предоставить разрешение",
+          "action": "Действие",
+          "element": {
+            "select": "Выбрать элемент",
+            "verify": "Проверить селектор"
+          },
+          "settings": {
+            "title": "Настройки блока",
+            "blockTimeout": {
+              "title": "Таймаут выполнения блока (миллисекунды)",
+              "description": "Максимальное время выполнения блока (0 для отключения)"
+            },
+            "line": {
+              "title": "Линии",
+              "label": "Метка",
+              "animated": "Анимировано",
+              "select": "Выбрать линию",
+              "to": "Линия к блоку {name}",
+              "lineColor": "Цвет"
+            }
+          },
+          "toggle": {
+            "enable": "Включить блок",
+            "disable": "Отключить блок"
+          },
+          "onError": {
+            "info": "Эти правила будут применяться при возникновении ошибки в блоке",
+            "button": "При ошибке",
+            "title": "При возникновении ошибки",
+            "retry": "Повторить действие",
+            "fallbackTitle": "Будет выполнено при возникновении ошибки в блоке",
+            "times": {
+              "name": "Раз",
+              "description": "Количество попыток повторного выполнения действия"
+            },
+            "interval": {
+              "name": "Интервал",
+              "description": "Временной интервал ожидания между каждой попыткой",
+              "second": "секунда"
+            },
+            "toDo": {
+              "error": "Выбросить ошибку",
+              "continue": "Продолжить выполнение",
+              "fallback": "Выполнить резервное действие",
+              "restart": "Перезапустить выполнение"
+            },
+            "insertData": {
+              "name": "Вставить данные"
+            }
+          },
+          "table": {
+            "checkbox": "Вставить в таблицу",
+            "select": "Выбрать колонку",
+            "extraRow": {
+              "checkbox": "Добавить дополнительную строку",
+              "placeholder": "Значение",
+              "title": "Значение дополнительной строки"
+            }
+          },
+          "findElement": {
+            "placeholder": "Найти элемент по",
+            "options": {
+              "cssSelector": "CSS Селектор",
+              "xpath": "XPath"
+            }
+          },
+          "markElement": {
+            "title": "Элемент не будет выбран, если его уже выбрали ранее",
+            "text": "Отметить элемент"
+          },
+          "multiple": {
+            "title": "Выбрать несколько элементов",
+            "text": "Много"
+          },
+          "waitSelector": {
+            "title": "Ожидание селектора",
+            "timeout": "Таймаут селектора (мс)"
+          },
+          "downloads": {
+            "onConflict": {
+              "uniquify": "Уникализировать",
+              "overwrite": "Перезаписать",
+              "prompt": "Запросить"
+            }
+          }
+        },
+        "wait-connections": {
+          "name": "Ожидание соединений",
+          "description": "Ожидание всех соединений перед переходом к следующему блоку",
+          "specificFlow": "Продолжить только конкретный поток",
+          "selectFlow": "Выбрать поток"
+        },
+        "cookie": {
+          "name": "Куки",
+          "description": "Получить, установить или удалить куки",
+          "types": {
+            "get": "Получить куки",
+            "set": "Установить куки",
+            "remove": "Удалить куки",
+            "getAll": "Получить все куки"
+          },
+          "useJson": "Использовать формат JSON"
+        },
+        "note": {
+          "name": "Заметка"
+        },
+        "slice-variable": {
+          "name": "Разделение переменной",
+          "description": "Извлечение раздела значения переменной",
+          "start": "Начальный индекс",
+          "end": "Конечный индекс"
+        },
+        "workflow-state": {
+          "name": "Состояние рабочего процесса",
+          "description": "Управление состояниями рабочих процессов",
+          "actions": {
+            "stop": "Остановить рабочие процессы"
+          }
+        },
+        "regex-variable": {
+          "name": "Переменная RegEx",
+          "description": "Сопоставление значения переменной с регулярным выражением"
+        },
+        "data-mapping": {
+          "source": "Источник",
+          "destination": "Назначение",
+          "name": "Сопоставление данных",
+          "edit": "Редактировать карту данных",
+          "dataSource": "Источник данных",
+          "description": "Сопоставление данных переменной или таблицы",
+          "addSource": "Добавить источник",
+          "addDestination": "Добавить назначение"
+        },
+        "sort-data": {
+          "name": "Сортировка данных",
+          "description": "Сортировка элементов данных",
+          "property": "Сортировать по свойству элемента",
+          "addProperty": "Добавить свойство"
+        },
+        "increase-variable": {
+          "name": "Увеличить переменную",
+          "description": "Увеличение значения переменной на определенную величину",
+          "increase": "Увеличить на"
+        },
+        "notification": {
+          "name": "уведомление",
+          "description": "Отображение уведомления",
+          "title": "Заголовок",
+          "message": "Сообщение",
+          "imageUrl": "URL изображения (необязательно)",
+          "iconUrl": "URL иконки (необязательно)"
+        },
+        "delete-data": {
+          "name": "Удалить данные",
+          "description": "Удалить данные таблицы или переменные",
+          "from": "Данные от",
+          "allColumns": "[Все столбцы]"
+        },
+        "log-data": {
+          "name": "Получить данные лога",
+          "description": "Получить последние данные лога рабочего процесса",
+          "data": "Данные лога"
+        },
+        "tab-url": {
+          "name": "Получить URL вкладки",
+          "description": "Получить URL вкладки",
+          "select": "Выбрать вкладку",
+          "types": {
+            "active-tab": "Активная вкладка",
+            "all": "Все вкладки"
+          },
+          "query": {
+            "title": "Запрос",
+            "matchPatterns": "@:workflow.blocks.switch-tab.matchPattern (необязательно)",
+            "tabTitle": "Название вкладки (необязательно)"
+          }
+        },
+        "reload-tab": {
+          "name": "Перезагрузить вкладку",
+          "description": "Перезагрузить активную вкладку"
+        },
+        "press-key": {
+          "name": "Нажать клавишу",
+          "description": "Нажмите клавишу или комбинацию клавиш",
+          "target": "Целевой элемент (необязательно)",
+          "key": "Клавиша",
+          "detect": "Обнаружить клавишу",
+          "actions": {
+            "press-key": "Нажать клавишу",
+            "multiple-keys": "Нажать несколько клавиш"
+          },
+          "press-time": "Время нажатия (миллисекунды)"
+        },
+        "save-assets": {
+          "name": "Сохранить активы",
+          "description": "Сохранить активы (изображение, видео, аудио или файл) из элемента или URL",
+          "filename": "Имя файла (необязательно)",
+          "saveDownloadIds": "Сохранить ID загрузки элементов",
+          "contentTypes": {
+            "title": "Тип",
+            "element": "Медиа элемент (изображение, аудио или видео)",
+            "url": "URL"
+          }
+        },
+        "handle-dialog": {
+            "name": "Управление диалогом",
+            "description": "Принимает или отклоняет диалог, инициированный JavaScript (alert, confirm, prompt или onbeforeunload)",
+            "accept": "Принять диалог",
+            "promptText": {
+              "label": "Текст для prompt (необязательно)",
+              "description": "Текст, который нужно ввести в диалоговое окно prompt перед принятием"
+            }
+          },
+          "handle-download": {
+            "name": "Управление загрузками",
+            "description": "Управление загруженным файлом",
+            "timeout": "Таймаут (миллисекунды)",
+            "noPermission": "Нет разрешения на доступ к загрузкам",
+            "onConflict": "При конфликте",
+            "waitFile": "Ждать завершения загрузки файла",
+            "downloadId": "ID загрузки файла (необязательно)",
+            "filePath": "Путь к файлу"
+          },
+          "insert-data": {
+            "name": "Вставка данных",
+            "description": "Вставка данных в таблицу или переменную"
+          },
+        "clipboard": {
+            "name": "Буфер обмена",
+            "description": "Получение скопированного текста из буфера обмена",
+            "data": "Данные буфера обмена",
+            "noPermission": "Нет доступа к буферу обмена",
+            "grantPermission": "Предоставить доступ",
+            "copySelection": "Копировать выделенный текст на странице",
+            "types": {
+              "get": "Получить данные буфера обмена",
+              "insert": "Вставить текст в буфер обмена"
+            }
+          },
+          "hover-element": {
+            "name": "Наведение на элемент",
+            "description": "Наведение курсора на элемент"
+          },
+          "create-element": {
+            "name": "Создание элемента",
+            "description": "Создание элемента и вставка его в страницу",
+            "edit": "Редактировать элемент",
+            "wrap": "Обернуть внутри элемента",
+            "insertEl": {
+              "title": "Вставка элемента",
+              "items": {
+                "before": "Вставить первым дочерним элементом",
+                "after": "Вставить последним дочерним элементом",
+                "next-sibling": "Вставить следующим соседним элементом",
+                "prev-sibling": "Вставить предыдущим соседним элементом",
+                "replace": "Заменить целевой элемент"
+              }
+            }
+          },
+        "upload-file": {
+            "name": "Загрузка файла",
+            "description": "Загрузить файл в элемент <input type=\"file\">",
+            "filePath": "URL или путь к файлу",
+            "addFile": "Добавить файл",
+            "onlyURL": "Загрузка файлов по URL поддерживается только в браузере Firefox",
+            "requirement": "Прочитайте требования перед использованием этого блока",
+            "noFileAccess": "У Automa нет доступа к файлам"
+          },
+          "browser-event": {
+            "name": "Событие браузера",
+            "description": "Выполняет следующий блок, когда запускается указанное событие",
+            "events": "События",
+            "timeout": "Таймаут (миллисекунды)",
+            "activeTabLoaded": "Активная вкладка",
+            "setAsActiveTab": "Установить как активную вкладку"
+          },
+          "blocks-group-2": {
+            "name": "Группа блоков 2",
+            "description": "Описание группы блоков"
+          },
+          "blocks-group": {
+            "name": "Группа блоков",
+            "groupName": "Имя группы",
+            "description": "Группирование блоков",
+            "dropText": "Перетащите блок сюда",
+            "cantAdd": "Не удается добавить блок \"{blockName}\" в группу"
+          },
+         "trigger": {
+            "name": "Триггер",
+            "description": "Блок, с которого начинается выполнение рабочего процесса",
+            "addTime": "Добавить время",
+            "selectDay": "Выбрать день",
+            "timeExist": "Вы уже установили триггер на {time} в {day}",
+            "fixedDelay": "Фиксированная задержка",
+            "contextMenus": {
+              "noPermission": "Для работы этого триггера необходимо получить разрешение \"contextMenus\"",
+              "grantPermission": "Предоставить разрешение",
+              "appearIn": "Отобразится в",
+              "contextName": "Имя рабочего процесса в контекстном меню"
+            },
+            "days": [
+              "Воскресенье",
+              "Понедельник",
+              "Вторник",
+              "Среда",
+              "Четверг",
+              "Пятница",
+              "Суббота"
+            ],
+            "useRegex": "Использовать регулярные выражения",
+            "shortcut": {
+              "tooltip": "Запись сочетания клавиш",
+              "stopRecord": "Остановить запись",
+              "checkboxTitle": "Выполнять сочетание клавиш даже в элементе ввода",
+              "checkbox": "Активно в полях ввода",
+              "note": "Примечание: сочетание клавиш работает только когда вы находитесь на веб-странице"
+            },
+          "forms": {
+            "triggerWorkflow": "Запуск рабочего процесса",
+              "interval": "Интервал (минуты)",
+              "delay": "Задержка (минуты)",
+              "date": "Дата",
+              "time": "Время",
+              "url": "URL или Regex",
+              "shortcut": "Сочетание клавиш",
+              "cron-expression": "Cron выражение"
+          },
+          "element-change": {
+            "target": "Целевой элемент для наблюдения",
+            "optionsInfo": "Какое изменение элемента будет запускать рабочий процесс",
+            "targetWebsite": "Соответствие шаблону веб-сайта, где находится целевой элемент (нажмите, чтобы увидеть больше примеров шаблонов)",
+            "baseEl": {
+              "title": "Базовый элемент (необязательно)",
+              "description": "Automa будет перезапускать наблюдение за целевым элементом, когда этот элемент изменится"
+            },
+            "subtree": {
+              "title": "Включая поддерево",
+              "description": "Расширить мониторинг на весь поддерево целевого элемента"
+            },
+            "childList": {
+              "title": "Список дочерних элементов",
+              "description": "Мониторинг добавления новых дочерних элементов или удаления существующих"
+            },
+            "attributes": {
+              "title": "Атрибуты",
+              "description": "Наблюдение за изменениями значений атрибутов целевого элемента"
+            },
+            "attributeFilter": {
+              "title": "Фильтр атрибутов",
+              "separate": "Используйте запятые для разделения имен атрибутов",
+              "description": "Наблюдение только за определенными атрибутами (оставьте пустым для всех)"
+            },
+            "characterData": {
+              "title": "Данные символов",
+              "description": "Наблюдение за изменениями данных символов/текста внутри целевого элемента"
+            }
+          },
+          "items": {
+            "manual": "Вручную",
+                "interval": "Интервал",
+                "cron-job": "Задание Cron",
+                "date": "В определенную дату",
+                "context-menu": "Контекстное меню",
+                "element-change": "При изменении элемента",
+                "specific-day": "В определенный день",
+                "visit-web": "При посещении веб-сайта",
+                "on-startup": "При запуске браузера",
+                "keyboard-shortcut": "Горячая клавиша"
+          }
+        },
+        "execute-workflow": {
+            "name": "Выполнить рабочий процесс",
+            "overwriteNote": "Это перезапишет глобальные данные выбранного рабочего процесса",
+            "select": "Выбрать рабочий процесс",
+            "executeId": "ID выполнения (необязательно)",
+            "description": "",
+            "insertAllVars": "Использовать все переменные текущего рабочего процесса",
+            "insertVars": "Вставить переменные текущего рабочего процесса",
+            "useCommas": "Использовать запятые для разделения имен переменных",
+            "insertAllGlobalData": "Использовать все глобальные данные текущего рабочего процесса"
+        },
+        "google-sheets-drive": {
+            "name": "Google Таблицы (GDrive)",
+            "description": "Подключенные таблицы",
+            "connected": "Соединено",
+            "select": "Выбрать лист",
+            "connect": "Соединить"
+          },
+          "google-drive": {
+            "name": "Google Диск",
+            "description": "Загрузить файлы на Google Диск",
+            "actions": {
+              "upload": "Загрузить файлы"
+          }
+        },
+        "google-sheets": {
+            "name": "Google Таблицы",
+            "description": "Читать или обновлять данные Google Таблиц",
+            "previewData": "Предварительный просмотр данных",
+            "firstRow": "Использовать первую строку как ключи",
+            "keysAsFirstRow": "Использовать ключи как первую строку",
+            "insertData": "Вставить данные",
+            "valueInputOption": "Опция ввода значений",
+            "insertDataOption": "Опция вставки данных",
+            "rangeToSearch": "Диапазон для начала поиска",
+            "dataFrom": {
+              "label": "Данные из",
+              "options": {
+                "data-columns": "Таблица",
+                "custom": "Пользовательские"
+              }
+            },
+            "refKey": {
+              "label": "Справочный ключ (необязательно)",
+              "placeholder": "Имя ключа"
+            },
+            "spreadsheetId": {
+              "label": "ID таблицы",
+              "link": "Смотрите, как получить ID таблицы"
+            },
+            "range": {
+              "label": "Диапазон",
+              "link": "Нажмите, чтобы увидеть больше примеров"
+            },
+            "select": {
+                "get": "Получить значения ячеек таблицы",
+                "getRange": "Получить диапазон таблицы",
+                "update": "Обновить значения ячеек таблицы",
+                "append": "Добавить значения ячеек таблицы",
+                "clear": "Очистить значения ячеек таблицы",
+                "create": "Создать таблицу",
+                "add-sheet": "Добавить лист"
+              }
+            },
+            "active-tab": {
+              "name": "Активная вкладка",
+              "description": "Установить вкладку, на которой вы находитесь, как активную вкладку"
+            },
+            "proxy": {
+              "name": "Прокси",
+              "description": "Установить прокси для браузера",
+              "clear": "Очистить все прокси",
+              "bypass": {
+                "label": "Список исключений",
+                "note": "Используйте запятые для разделения URL"
+              }
+            },
+        "new-window": {
+                "name": "Новое окно",
+                "description": "Создать новое окно",
+                "top": "Верх",
+                "left": "Лево",
+                "height": "Высота",
+                "width": "Ширина",
+                "note": "Примечание: используйте 0 для отключения",
+                "position": "Позиция окна",
+                "size": "Размер окна",
+                "windowState": {
+                  "placeholder": "Состояние окна",
+                  "options": {
+                    "normal": "Обычное",
+                    "minimized": "Свернутое",
+                    "maximized": "Развернутое",
+                    "fullscreen": "Полноэкранное"
+                  }
+                },
+                "incognito": {
+                  "text": "Установить как окно инкогнито",
+                  "note": "Сначала вы должны разрешить 'Разрешить в инкогнито' для этого расширения"
+                }
+              },
+              "go-back": {
+                "name": "Вернуться назад",
+                "description": "Вернуться на предыдущую страницу"
+              },
+              "forward-page": {
+                "name": "Вперед",
+                "description": "Перейти на следующую страницу"
+              },
+        "close-tab": {
+                "name": "Закрыть вкладку/окно",
+                "description": "",
+                "url": "Соответствие шаблонам",
+                "activeTab": "Закрыть активную вкладку",
+                "allWindows": "Закрыть все окна"
+              },
+              "event-click": {
+                "name": "Клик по элементу",
+                "description": ""
+              },
+              "delay": {
+                "name": "Задержка",
+                "description": "Добавить задержку перед выполнением следующего блока",
+                "input": {
+                  "title": "Задержка в миллисекундах",
+                  "placeholder": "Задержка в миллисекундах"
+                }
+              },
+              "parameter-prompt": {
+                "name": "Параметр Prompt"
+              },
+              "get-text": {
+                "name": "Получить текст",
+                "description": "Получить текст из элемента",
+                "checkbox": "Вставить в таблицу",
+                "includeTags": "Включать HTML теги",
+                "prefixText": {
+                  "placeholder": "Префикс текста",
+                  "title": "Добавить префикс к тексту"
+                },
+                "suffixText": {
+                  "placeholder": "Суффикс текста",
+                  "title": "Добавить суффикс к тексту"
+                }
+              },
+        "export-data": {
+                "name": "Экспорт данных",
+                "description": "Экспорт данных рабочего процесса",
+                "exportAs": "Экспортировать как",
+                "refKey": "Справочный ключ",
+                "bomHeader": "Добавить BOM UTF-8",
+                "dataToExport": {
+                  "placeholder": "Данные для экспорта",
+                  "options": {
+                    "data-columns": "Таблица",
+                    "google-sheets": "Google Sheets",
+                    "variable": "Переменная"
+                  }
+                }
+              },
+              "element-scroll": {
+                "name": "Прокрутка элемента",
+                "description": "",
+                "scrollY": "Прокрутка по вертикали",
+                "scrollX": "Прокрутка по горизонтали",
+                "intoView": "Прокрутить к видимой части",
+                "smooth": "Плавная прокрутка",
+                "incScrollX": "Увеличить горизонтальную прокрутку",
+                "incScrollY": "Увеличить вертикальную прокрутку"
+              },
+              "switch-tab": {
+                "name": "Переключение вкладок",
+                "description": "Переключение между вкладками",
+                "matchPattern": "Шаблоны соответствия",
+                "url": "URL новой вкладки",
+                "createIfNoMatch": "Создать, если совпадений нет"
+              },
+        "new-tab": {
+                "name": "Новая вкладка",
+                "description": "",
+                "url": "URL новой вкладки",
+                "tab-zoom": "Масштабирование вкладки",
+                "customUserAgent": "Использовать пользовательское значение User-Agent",
+                "activeTab": "Сделать активной вкладкой",
+                "tabToGroup": "Добавить вкладку в группу",
+                "waitTabLoaded": "Ждать загрузки вкладки",
+                "updatePrevTab": {
+                  "title": "Использовать ранее открытую новую вкладку вместо создания новой",
+                  "text": "Обновить ранее открытую вкладку"
+                }
+              },
+              "link": {
+                "name": "Ссылка",
+                "description": "Открыть элемент ссылки",
+                "openInNewTab": "Открыть в новой вкладке"
+              },
+              "attribute-value": {
+                "name": "Значение атрибута",
+                "description": "Получить значение атрибута элемента",
+                "forms": {
+                  "name": "Имя атрибута",
+                  "checkbox": "Вставить в таблицу",
+                  "column": "Выбрать столбец",
+                  "value": "Значение атрибута",
+                  "action": {
+                    "get": "Получить значение атрибута",
+                    "set": "Задать значение атрибута"
+                  },
+            "extraRow": {
+                    "checkbox": "Добавить дополнительную строку",
+                    "placeholder": "Значение",
+                    "title": "Значение дополнительной строки"
+                  }
+          }
+        },
+        "forms": {
+            "name": "Формы",
+            "description": "",
+            "selected": "Выбрано",
+            "type": "Тип формы",
+            "getValue": "Получить значение формы",
+            "text-field": {
+              "name": "Текстовое поле",
+              "value": "Значение",
+              "clearValue": "Очистить значение формы",
+              "delay": {
+                "placeholder": "Задержка",
+                "label": "Задержка при вводе (миллисекунды)(0 чтобы отключить)"
+              }
+            },
+            "select": {
+              "name": "Выпадающий список"
+            },
+            "radio": {
+              "name": "Переключатель"
+            },
+            "checkbox": {
+              "name": "Флажок"
+            }
+          },
+          "repeat-task": {
+            "name": "Повторение задачи",
+            "description": "",
+            "times": "раз",
+            "repeatFrom": "Повторить с"
+          },
+          "javascript-code": {
+            "name": "Код JavaScript",
+            "description": "Выполнение вашего кода JavaScript на веб-странице",
+            "availabeFuncs": "Доступные функции:",
+            "removeAfterExec": "Удалить после выполнения блока",
+            "everyNewTab": "Выполнить в каждой новой вкладке",
+            "context": {
+              "name": "Контекст выполнения",
+              "items": {
+                "website": "Активная вкладка",
+                "background": "Фоновый режим"
+              }
+            },
+            "modal": {
+              "tabs": {
+                "code": "Код JavaScript",
+                "preloadScript": "Скрипт предзагрузки"
+              }
+            },
+            "timeout": {
+              "placeholder": "Таймаут (миллисекунды)",
+              "title": "Таймаут выполнения кода JavaScript"
+            }
+          },
+          "trigger-event": {
+            "name": "Событие запуска",
+            "description": "",
+            "selectEvent": "Выбрать событие"
+          },
+          "conditions": {
+            "name": "Условия",
+            "add": "Добавить путь",
+            "retryConditions": "Повторить, если условия не выполнены",
+            "description": "Условный блок",
+            "refresh": "Обновить соединения условий",
+            "fallbackTitle": "Выполняется, когда ни одно из сравнений не соответствует требованию",
+            "equals": "Равно",
+            "gt": "Больше чем",
+            "gte": "Больше или равно",
+            "lt": "Меньше чем",
+            "lte": "Меньше или равно",
+            "ne": "Не равно",
+            "contains": "Содержит"
+          },
+          "element-exists": {
+            "name": "Элемент существует",
+            "description": "Проверить существование элемента",
+            "selector": "Селектор элемента",
+            "fallbackTitle": "Выполняется, когда элемент не существует",
+            "throwError": "Генерировать ошибку, если элемент не существует",
+            "tryFor": {
+              "title": "Количество попыток проверки существования элемента",
+              "label": "Попыток"
+            },
+            "timeout": {
+              "label": "Таймаут (миллисекунды)",
+              "title": "Таймаут для каждой попытки"
+            }
+          },
+          "webhook": {
+            "name": "HTTP запрос",
+            "description": "Выполнение HTTP запроса",
+            "contentType": "Тип содержимого",
+            "method": "Метод запроса",
+            "url": "URL запроса",
+            "fallback": "Выполняется, когда HTTP запрос не удался",
+            "buttons": {
+              "header": "Добавить заголовок"
+            },
+            "timeout": {
+              "placeholder": "Таймаут",
+              "title": "Таймаут выполнения HTTP запроса (мс)"
+            },
+            "tabs": {
+              "headers": "Заголовки",
+              "body": "Тело запроса",
+              "response": "Ответ"
+            }
+          },
+          "while-loop": {
+            "name": "Цикл while",
+            "description": "Выполняет блоки, пока условие истинно",
+            "editCondition": "Редактировать условие",
+            "fallback": "Выполняется, когда условие ложно"
+          },
+          "loop-elements": {
+            "name": "Перебор элементов",
+            "description": "Итерация по элементам",
+            "loadMore": "Загрузить больше элементов",
+            "scrollToBottom": "Прокрутить вниз",
+            "scrollToTop": "Прокрутить вверх",
+            "actions": {
+              "none": "Без действий",
+              "click-element": "Клик по элементу",
+              "scroll": "Прокрутить вниз",
+              "click-link": "Клик по ссылке",
+              "scroll-up": "Прокрутить вверх"
+            }
+          },
+          "loop-data": {
+            "name": "Перебор данных",
+            "description": "Итерация по таблице или вашим пользовательским данным",
+            "loopId": "ID цикла",
+            "refKey": "Справочный ключ",
+            "startIndex": "Начать с индекса",
+            "resumeLastWorkflow": "Возобновить последний рабочий процесс",
+            "reverse": "Обратный порядок цикла",
+            "modal": {
+              "fileTooLarge": "Файл слишком велик для редактирования",
+              "maxFile": "Максимальный размер файла — 1 МБ",
+              "options": {
+                "firstRow": "Использовать первую строку как ключи"
+              }
+            },
+            "buttons": {
+              "clear": "Очистить данные",
+              "insert": "Вставить данные",
+              "import": "Импортировать файл"
+            },
+            "maxLoop": {
+                "title": "Максимальное количество данных для цикла",
+                "label": "Максимум данных для цикла (0 для отключения)"
+              },
+              "loopThrough": {
+                "placeholder": "Перебирать через",
+                "fromNumber": "С числа",
+                "toNumber": "По число",
+                "options": {
+                  "numbers": "Числа",
+                  "variable": "Переменная",
+                  "data-columns": "Таблица",
+                  "table": "Таблица",
+                  "custom-data": "Пользовательские данные",
+                  "google-sheets": "Google Таблицы",
+                  "elements": "Элементы"
+                }
+              }
+            },
+            "loop-breakpoint": {
+              "name": "Точка останова цикла",
+              "description": "Указание, где блок 'Перебор данных' должен остановиться"
+            },
+            "take-screenshot": {
+              "name": "Сделать снимок экрана",
+              "fullPage": "Сделать снимок всей страницы",
+              "description": "Сделать снимок текущей активной вкладки",
+              "imageQuality": "Качество изображения",
+              "saveToColumn": "Вставить снимок экрана в таблицу",
+              "saveToComputer": "Сохранить снимок экрана на компьютер",
+              "types": {
+                "title": "Сделать снимок экрана",
+                "page": "Страницы",
+                "fullpage": "Всей страницы",
+                "element": "Элемента"
+              }
+        },
+        "switch-to": {
+            "name": "Переключиться на фрейм",
+            "description": "Переключение между основным окном и фреймом (iframe)",
+            "iframeSelector": "Селектор элемента",
+            "windowTypes": {
+              "main": "Основное окно",
+              "iframe": "Фрейм (iframe)"
+            }
+          },
+          "debugMode": {
+            "title": "Режим отладки",
+            "description": "Выполнение блока с использованием Chrome DevTools Protocol"
+          }
+      }
+    }
+  }
\ No newline at end of file
diff --git a/src/locales/ru/common.json b/src/locales/ru/common.json
new file mode 100644
index 000000000..388b92d91
--- /dev/null
+++ b/src/locales/ru/common.json
@@ -0,0 +1,77 @@
+{
+    "common": {
+      "dashboard": "Панель управления",
+      "workflow": "Рабочий процесс | Рабочие процессы",
+      "collection": "Коллекция | Коллекции",
+      "log": "Лог | Логи",
+      "block": "Блок | Блоки",
+      "schedule": "Расписание",
+      "folder": "Папка | Папки",
+      "new": "Новый",
+      "docs": "Документация",
+      "search": "Поиск",
+      "example": "Пример | Примеры",
+      "import": "Импорт",
+      "export": "Экспорт",
+      "rename": "Переименовать",
+      "execute": "Выполнить",
+      "delete": "Удалить",
+      "cancel": "Отменить",
+      "settings": "Настройки",
+      "options": "Опции",
+      "confirm": "Подтвердить",
+      "name": "Название",
+      "all": "Все",
+      "add": "Добавить",
+      "save": "Сохранить",
+      "data": "данные",
+      "stop": "Стоп",
+      "sheet": "Лист",
+      "pause": "Пауза",
+      "resume": "Возобновить",
+      "action": "Действие | Действия",
+      "packages": "Пакеты",
+      "storage": "Хранилище",
+      "editor": "Редактор",
+      "running": "Выполнение",
+      "globalData": "Глобальные данные",
+      "fileName": "Имя файла",
+      "description": "Описание",
+      "disable": "Отключить",
+      "disabled": "Отключен",
+      "enable": "Включить",
+      "fallback": "Резервный вариант",
+      "update": "Обновить",
+      "feature": "Функция",
+      "duplicate": "Дублировать",
+      "password": "Пароль",
+      "category": "Категория",
+      "optional": "Необязательный",
+      "0disable": "0 для отключения",
+      "millisecond": "миллисекунда | миллисекунды"
+    },
+    "message": {
+      "noBlock": "Нет блока",
+      "noData": "Данные для отображения отсутствуют",
+      "noTriggerBlock": "Не удается найти блок триггера",
+      "useDynamicData": "Узнайте, как добавить динамические данные",
+      "delete": "Вы уверены, что хотите удалить \"{name}\"?",
+      "empty": "Ой... Похоже, у вас нет ни одного элемента",
+      "maxSizeExceeded": "Размер файла превысил максимально допустимый",
+      "notSaved": "Вы действительно хотите уйти? У вас есть несохраненные изменения!",
+      "somethingWrong": "Что-то пошло не так",
+      "limitExceeded": "Вы превысили лимит"
+    },
+    "sort": {
+      "sortBy": "Сортировать по",
+      "name": "Название",
+      "createdAt": "Дата создания",
+      "updatedAt": "Последнее обновление",
+      "mostUsed": "Наиболее используемые"
+    },
+    "logStatus": {
+      "stopped": "остановлено",
+      "error": "ошибка",
+      "success": "успешно"
+    }
+  }
\ No newline at end of file
diff --git a/src/locales/ru/newtab.json b/src/locales/ru/newtab.json
new file mode 100644
index 000000000..2c7b5bbf2
--- /dev/null
+++ b/src/locales/ru/newtab.json
@@ -0,0 +1,516 @@
+{
+    "home": {
+        "viewAll": "Просмотреть все",
+        "communities": "Сообщества"
+    },
+    "welcome": {
+        "title": "Добро пожаловать в Automa! 🎉",
+        "text": "Начните с чтения документации или поиска рабочих процессов в каталоге Automa.",
+        "marketplace": "Каталог"
+    },
+    "packages": {
+        "name": "Пакет | Пакеты",
+        "add": "Добавить пакет",
+        "icon": "Иконка пакета",
+        "open": "Открыть пакеты",
+        "new": "Новый пакет",
+        "import": "Импортировать пакет",
+        "set": "Установить как пакет",
+      "settings": {
+        "asBlock": "Установить пакет как блок"
+      },
+      "categories": {
+        "my": "Мои пакеты",
+        "installed": "Установленные пакеты"
+      }
+    },
+    "scheduledWorkflow": {
+        "title": "Расписания рабочих процессов",
+        "nextRun": "Следующий запуск",
+        "active": "Активно",
+        "refresh": "Обновить",
+        "schedule": {
+          "title": "Расписание",
+        "types": {
+            "everyDay": "Каждый день",
+            "general": "Каждые {time}",
+            "interval": "Каждые {time} минут"
+        }
+      }
+    },
+    "storage": {
+        "title": "Хранилище",
+        "table": {
+          "add": "Добавить таблицу",
+          "edit": "Редактировать таблицу",
+          "createdAt": "Создано в",
+          "modifiedAt": "Изменено в",
+          "rowsCount": "Количество строк",
+          "delete": "Удалить таблицу"
+      }
+    },
+    "credential": {
+        "title": "Учетные данные | Учетные данные",
+        "add": "Добавить учетную запись",
+        "use": {
+          "title": "Используемые учетные данные",
+          "description": "Этот рабочий процесс использует эти учетные данные"
+      }
+    },
+    "workflowPermissions": {
+        "title": "Разрешения рабочего процесса",
+        "description": "Для корректной работы этому рабочему процессу требуются следующие разрешения",
+        "contextMenus": {
+          "title": "Контекстное меню",
+          "description": "Для выполнения рабочего процесса через контекстное меню"
+      },
+      "clipboardRead": {
+        "title": "Буфер обмена",
+        "description": "Для доступа к данным буфера обмена"
+      },
+      "notifications": {
+        "title": "Уведомление",
+        "description": "Для отображения уведомления"
+      },
+      "downloads": {
+        "title": "Загрузка",
+        "description": "Сохранение ресурсов страницы и переименование скачанного файла"
+      },
+      "cookies": {
+        "title": "Куки",
+        "description": "Чтение, установка или удаление куки"
+      }
+    },
+    "updateMessage": {
+        "text1": "Automa обновлен до версии v{version},",
+        "text2": "смотрите что нового."
+      },
+      "workflows": {
+        "folder": {
+          "new": "Новая папка",
+          "name": "Имя папки",
+          "delete": "Удалить папку",
+          "rename": "Переименовать папку"
+        }
+      },
+      "auth": {
+        "title": "Авторизация",
+        "signIn": "Войти",
+        "username": "Сначала установите свое имя пользователя",
+        "clickHere": "Нажмите здесь",
+        "text": "Вы должны войти в систему, прежде чем сможете это сделать"
+    },
+    "running": {
+        "start": "Запущено {date}",
+        "message": "Здесь отображаются только последние 5 записей"
+      },
+      "settings": {
+        "theme": "Тема",
+        "shortcuts": {
+          "duplicate": "Сочетание клавиш уже используется \"{name}\""
+        },
+        "editor": {
+          "title": "Заголовок",
+          "curvature": {
+            "title": "Кривизна линии",
+            "line": "Линия",
+            "reroute": "Перенаправление",
+            "rerouteFirstLast": "Перенаправление первой и последней точки"
+          },
+          "arrow": {
+            "title": "Стрелка линии",
+            "description": "Добавить стрелку в конце линии"
+          },
+          "snapGrid": {
+            "title": "Привязка к сетке",
+            "description": "Привязывать блок к сетке при перемещении"
+        },
+        "saveWhenExecute": {
+            "title": "Авто-сохранение при выполнении рабочего процесса",
+            "description": "Изменения в рабочем процессе будут сохранены при его выполнении"
+          }
+        },
+        "deleteLog": {
+          "title": "Авто-удаление журналов рабочих процессов",
+          "after": "Удалить после",
+          "deleteAfter": {
+            "never": "Никогда",
+            "days": "{day} дней"
+          }
+        },
+        "language": {
+          "label": "Язык",
+          "helpTranslate": "Не можете найти свой язык? Помогите с переводом.",
+          "reloadPage": "Перезагрузите страницу, чтобы изменения вступили в силу"
+        },
+        "menu": {
+          "backup": "Резервное копирование рабочих процессов",
+          "editor": "Редактор",
+          "general": "Общие",
+          "shortcuts": "Ярлыки",
+          "about": "О программе"
+      },
+      "backupWorkflows": {
+        "title": "Локальное резервное копирование",
+        "invalidPassword": "Неверный пароль",
+        "workflowsAdded": "{count} рабочие процессы были добавлены",
+        "name": "Резервные рабочие процессы",
+        "needSignin": "Сначала войдите в систему",
+        "backup": {
+          "button": "Резервное копирование",
+          "settings": "Настройки резервного копирования",
+          "encrypt": "Зашифровать паролем",
+          "schedule": "Запланировать локальное резервное копирование"
+        },
+        "restore": {
+          "title": "Восстановить рабочие процессы",
+          "button": "Восстановить",
+          "update": "Обновить, если рабочий процесс существует"
+        },
+        "cloud": {
+          "buttons": {
+            "local": "Локально",
+            "cloud": "Облако"
+          },
+          "location": "Местоположение",
+          "delete": "Удалить резервную копию",
+          "title": "Облачное резервное копирование",
+          "sync": "Синхронизация",
+          "lastSync": "Последняя синхронизация",
+          "lastBackup": "Последнее резервное копирование",
+          "select": "Выберите рабочие процессы",
+          "storedWorkflows": "Рабочие процессы, хранящиеся в облаке",
+          "selected": "Выбрано",
+          "selectText": "Выберите рабочие процессы, которые хотите резервно скопировать",
+          "selectAll": "Выбрать все",
+          "deselectAll": "Отменить выбор всего",
+          "needSelectWorkflow": "Необходимо выбрать рабочие процессы, которые вы хотите резервно скопировать"
+        }
+      }
+    },
+    "workflow": {
+      "events": {
+        "title": "События рабочего процесса",
+        "add-action": "Добавить действие",
+        "description": "Выполнить действия, когда происходит событие.",
+        "event": "Событие | События",
+        "action": "Действие",
+        "actions": {
+          "js-code": {
+            "title": "Выполнить JS код"
+          },
+          "http-request": {
+            "title": "HTTP запрос"
+          }
+        },
+        "types": {
+          "finish:success": {
+            "name": "Завершить (успех)",
+            "description": "Выполнение рабочего процесса завершено успешно"
+          },
+          "finish:failed": {
+            "name": "Завершить (ошибка)",
+            "description": "Выполнение рабочего процесса завершено с ошибкой"
+          }
+        }
+      },
+      "previewMode": {
+        "title": "Режим предпросмотра",
+        "description": "Вы находитесь в режиме предпросмотра, изменения, которые вы сделали, не будут сохранены"
+      },
+      "pinWorkflow": {
+        "pin": "Закрепить рабочий процесс",
+        "unpin": "Открепить рабочий процесс",
+        "pinned": "Закрепленные рабочие процессы"
+      },
+      "parameters": {
+        "add": "Добавить параметр",
+        "preferInTab": "Предпочитать ввод параметров во вкладке"
+      },
+      "my": "Мои рабочие процессы",
+      "testing": {
+        "title": "Режим тестирования",
+        "nextBlock": "Следующий блок",
+        "startRun": "Начать исполнение с",
+        "disabled": "Сначала сохраните изменения"
+      },
+      "import": "Импортировать рабочий процесс",
+      "new": "Новый рабочий процесс",
+      "delete": "Удалить рабочий процесс",
+      "browse": "Просмотр рабочих процессов",
+      "name": "Название рабочего процесса",
+      "rename": "Переименовать рабочий процесс",
+      "backupCloud": "Резервное копирование рабочего процесса в облако",
+      "add": "Добавить рабочий процесс",
+      "clickToEnable": "Нажмите, чтобы включить",
+      "toggleSidebar": "Переключить боковую панель",
+      "cantEdit": "Невозможно редактировать общий рабочий процесс",
+      "undo": "Отменить",
+      "redo": "Повторить",
+      "autoAlign": {
+        "title": "Авто-выравнивание"
+      },
+      "blocksFolder": {
+        "title": "Папка блоков",
+        "add": "Добавить блоки в папку",
+        "save": "Сохранить в папку"
+      },
+      "searchBlocks": {
+        "title": "Поиск блоков в редакторе"
+      },
+      "conditionBuilder": {
+        "title": "Конструктор условий",
+        "add": "Добавить условие",
+        "and": "И",
+        "or": "ИЛИ",
+        "topAwait": "Поддерживает ожидание на верхнем уровне и функцию \"automaRefData\""
+      },
+      "host": {
+        "title": "Рабочий процесс хоста",
+        "set": "Установить как рабочий процесс хоста",
+        "id": "ID хоста",
+        "add": "Добавить хостовый рабочий процесс",
+        "sync": {
+          "title": "Синхронизация",
+          "description": "Синхронизировать с рабочим процессом хоста"
+        },
+        "messages": {
+          "hostExist": "Вы уже добавили этого хоста",
+          "notFound": "Не могу найти хостовый рабочий процесс с ID \"{id}\""
+        }
+      },
+      "type": {
+        "local": "Локальный",
+        "shared": "Общий",
+        "host": "Хост"
+      },
+      "unpublish": {
+        "title": "Отменить публикацию рабочего процесса",
+        "button": "Отменить публикацию",
+        "body": "Вы уверены, что хотите отменить публикацию рабочего процесса \"{name}\"?"
+      },
+      "share": {
+        "url": "Поделиться URL",
+        "publish": "Опубликовать",
+        "sharedAs": "Опубликовано как \"{name}\"",
+        "title": "Поделиться рабочим процессом",
+        "download": "Сохранить рабочий процесс локально",
+        "edit": "Редактировать описание",
+        "fetchLocal": "Загрузить локальный рабочий процесс",
+        "update": "Обновить",
+        "unpublish": "Отменить публикацию"
+      },
+      "variables": {
+        "title": "Переменная | Переменные",
+        "name": "Имя переменной",
+        "assign": "Назначить переменной"
+      },
+      "protect": {
+        "title": "Защитить рабочий процесс",
+        "remove": "Снять защиту",
+        "button": "Защитить",
+        "note": "Примечание: этот пароль потребуется позже для редактирования или удаления рабочего процесса."
+      },
+      "locked": {
+        "title": "Этот рабочий процесс защищён",
+        "body": "Введите пароль, чтобы разблокировать его",
+        "unlock": "Разблокировать",
+        "messages": {
+          "incorrect-password": "Неверный пароль"
+        }
+      },
+      "state": {
+        "executeBy": "Выполнено: \"{name}\""
+      },
+      "table": {
+        "title": "Таблица | Таблицы",
+        "placeholder": "Поиск или добавление столбца",
+        "select": "Выбрать столбец",
+        "column": {
+          "name": "Название столбца",
+          "type": "Тип данных"
+        }
+      },
+      "sidebar": {
+        "workflowIcon": "Иконка рабочего процесса"
+      },
+      "editor": {
+        "zoomIn": "Увеличить",
+        "zoomOut": "Уменьшить",
+        "resetZoom": "Сброс масштаба",
+        "duplicate": "Дублировать",
+        "copy": "Копировать",
+        "paste": "Вставить",
+        "group": "Группировать блоки",
+        "ungroup": "Разгруппировать блоки"
+      },
+      "settings": {
+        "saveLog": "Сохранить лог рабочего процесса",
+        "executedBlockOnWeb": "Показывать выполненный блок на веб-странице",
+        "notification": {
+          "title": "Уведомление рабочего процесса",
+          "description": "Показывать статус рабочего процесса (успех или неудача) после его выполнения",
+          "noPermission": "Эта опция требует разрешения на \"уведомления\" для работы"
+        },
+        "publicId": {
+          "title": "Общедоступный ID рабочего процесса",
+          "description": "Установить общедоступный ID для выполнения рабочего процесса через пользовательское событие JavaScript"
+        },
+        "defaultColumn": {
+          "title": "Вставить в столбец по умолчанию",
+          "description": "Вставить данные в столбец по умолчанию, если в блоке не выбран другой столбец",
+          "name": "Имя столбца по умолчанию"
+        },
+        "autocomplete": {
+          "title": "Автозаполнение",
+          "description": "Включить автозаполнение в блоке ввода (отключить, если это делает Automa нестабильной)"
+        },
+        "clearCache": {
+            "title": "Очистить кэш",
+            "description": "Очистить кэш (состояние и индекс цикла) рабочего процесса",
+            "info": "Кэш рабочего процесса успешно очищен",
+            "btn": "Очистить"
+          },
+          "reuseLastState": {
+            "title": "Использовать последнее состояние рабочего процесса",
+            "description": "Использовать данные состояния (таблицу, переменные и общие данные) из последнего выполненного рабочего процесса"
+          },
+          "debugMode": {
+            "title": "Режим отладки",
+            "description": "Выполнить рабочий процесс, используя протокол Chrome DevTools"
+          },
+          "restartWorkflow": {
+            "for": "Перезапустить рабочий процесс",
+            "times": "Раз",
+            "description": "Максимальное количество перезапусков рабочего процесса"
+          },
+          "onError": {
+            "title": "При ошибке в рабочем процессе",
+            "description": "Установить действие при возникновении ошибки в рабочем процессе",
+            "items": {
+              "keepRunning": "Продолжать выполнение",
+              "stopWorkflow": "Остановить рабочий процесс",
+              "restartWorkflow": "Перезапустить рабочий процесс"
+            }
+          },
+          "timeout": {
+            "title": "Таймаут рабочего процесса (в миллисекундах)"
+        },
+        "blockDelay": {
+            "title": "Задержка блока (в миллисекундах)",
+            "description": "Добавить задержку перед выполнением каждого блока"
+        },
+        "tabLoadTimeout": {
+            "title": "Таймаут загрузки вкладки",
+            "description": "Максимальное время загрузки вкладки в миллисекундах, введите 0 для отключения таймаута"
+        }
+      }
+    },
+    "collection": {
+        "description": "Выполнить рабочие процессы последовательно",
+        "new": "Новая коллекция",
+        "delete": "Удалить коллекцию",
+        "add": "Добавить коллекцию",
+        "rename": "Переименовать коллекцию",
+        "flow": "Поток",
+        "dragDropText": "Перетащите рабочий процесс или блок сюда",
+        "options": {
+          "atOnce": {
+            "title": "Выполнить все рабочие процессы в коллекции одновременно",
+            "description": "Блоки не будут выполняться, когда эта опция используется"
+        }
+      },
+      "globalData": {
+        "note": "Это перезапишет глобальные данные рабочего процесса"
+      }
+    },
+    "log": {
+        "flowId": "ID потока",
+        "goBack": "Вернуться к логам \"{name}\"",
+        "goWorkflow": "Перейти к рабочему процессу",
+        "startedDate": "Дата запуска",
+        "duration": "Продолжительность",
+        "selectAll": "Выбрать все",
+        "deselectAll": "Отменить выбор всего",
+        "deleteSelected": "Удалить выбранные логи",
+        "clearLogs": {
+          "title": "Очистить логи",
+          "description": "Вы уверены, что хотите очистить все логи?"
+        },
+        "types": {
+          "stop": "Рабочий процесс остановлен",
+          "finish": "Завершить"
+      },
+      "messages": {
+        "url-empty": "URL пуст",
+              "invalid-url": "Недействительный URL",
+              "conditions-empty": "Условия пусты",
+              "invalid-proxy-host": "Недействительный хост прокси",
+              "workflow-disabled": "Рабочий процесс отключен",
+              "selector-empty": "Селектор элемента пуст",
+              "invalid-body": "Тело контента не является допустимым JSON",
+              "invalid-active-tab": "\"{url}\" является недействительным URL",
+              "empty-spreadsheet-id": "ID таблицы пуст",
+              "invalid-loop-data": "Недопустимые данные для цикла",
+              "empty-workflow": "Сначала вы должны выбрать рабочий процесс",
+              "active-tab-removed": "Активная вкладка рабочего процесса удалена",
+              "empty-spreadsheet-range": "Диапазон таблицы пуст",
+              "stop-timeout": "Рабочий процесс остановлен из-за тайм-аута",
+              "no-file-access": "У Automa нет доступа к файлу",
+              "no-workflow": "Не могу найти рабочий процесс с ID \"{workflowId}\"",
+              "no-match-tab": "Не могу найти вкладку, соответствующую шаблону \"{pattern}\"",
+              "no-clipboard-acces": "Нет разрешения на доступ к буферу обмена",
+              "browser-not-supported": "Эта функция не поддерживается в браузере {browser}",
+              "element-not-found": "Не могу найти элемент с селектором \"{selector}\"",
+              "no-permission": "Нет разрешения \"{permission}\" для выполнения этого действия",
+              "not-iframe": "Элемент с селектором \"{selector}\" не является элементом iframe",
+              "iframe-not-found": "Не могу найти элемент iframe с селектором \"{selector}\"",
+              "workflow-infinite-loop": "Не могу выполнить рабочий процесс, чтобы предотвратить бесконечный цикл",
+              "not-debug-mode": "Рабочий процесс должен быть запущен в режиме отладки для работы этого блока",
+              "no-iframe-id": "Не могу найти ID фрейма для элемента iframe с селектором \"{selector}\"",
+              "no-tab": "Не могу подключиться к вкладке, используйте блок \"Новая вкладка\" или \"Активная вкладка\" перед использованием блока \"{name}\""
+      },
+      "description": {
+        "text": "{status} на {date} за {duration}",
+              "status": {
+                "success": "Успешно",
+                "error": "Ошибка",
+                "stopped": "Остановлено"
+        }
+      },
+      "delete": {
+        "title": "Удалить лог",
+        "description": "Вы уверены, что хотите удалить все выбранные логи?"
+      },
+      "exportData": {
+        "title": "Экспорт данных",
+        "types": {
+        "json": "JSON",
+        "csv": "CSV",
+        "plain-text": "Простой текст"
+        }
+      },
+      "filter": {
+        "title": "Фильтр",
+              "byStatus": "По статусу",
+              "byDate": {
+                "title": "По дате",
+                "items": {
+                  "lastDay": "Последний день",
+                  "last7Days": "Последние 7 дней",
+                  "last30Days": "Последние 30 дней"
+          }
+        }
+      }
+    },
+    "components": {
+        "pagination": {
+            "text1": "Показано",
+            "text2": "элементов из {count}",
+            "nextPage": "Следующая страница",
+            "currentPage": "Текущая страница",
+            "prevPage": "Предыдущая страница",
+            "of": "из {page}"
+      }
+    }
+  }
\ No newline at end of file
diff --git a/src/locales/ru/popup.json b/src/locales/ru/popup.json
new file mode 100644
index 000000000..43f295373
--- /dev/null
+++ b/src/locales/ru/popup.json
@@ -0,0 +1,32 @@
+{
+  "recording": {
+    "stop": "Остановить запись",
+    "title": "Запись"
+  },
+  "home": {
+    "record": {
+      "title": "Записать рабочий процесс",
+      "button": "Запись",
+      "name": "Название рабочего процесса",
+      "selectBlock": "Выберите блок для начала",
+      "anotherBlock": "Нельзя начать с этого блока",
+      "tabs": {
+        "new": "Новый рабочий процесс",
+        "existing": "Существующий рабочий процесс"
+      }
+    },
+    "elementSelector": {
+      "name": "Выбор элемента",
+      "noAccess": "Нет доступа к этому сайту"
+    },
+    "workflow": {
+      "new": "Новый рабочий процесс",
+      "rename": "Переименовать рабочий процесс",
+      "delete": "Удалить рабочий процесс",
+      "type": {
+        "host": "Хост",
+        "local": "Локальный"
+      }
+    }
+  }
+}
diff --git a/src/utils/shared.js b/src/utils/shared.js
index 6761a815d..d497ba580 100644
--- a/src/utils/shared.js
+++ b/src/utils/shared.js
@@ -1583,6 +1583,7 @@ export const supportLocales = [
   { id: 'zh', name: '简体中文' },
   { id: 'zh-TW', name: '繁體中文' },
   { id: 'tr', name: 'Türkçe' },
+  { id: 'ru', name: 'Русский' },
 ];
 
 export const communities = [