diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 43b0137c4..ed34b9fad 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -27,6 +27,8 @@ jobs: with: node-version: '12' - run: node ./node-red/.github/scripts/update-node-red-docker.js + env: + ACTIONS_ALLOW_UNSECURE_COMMANDS: true - name: Create Docker Pull Request uses: peter-evans/create-pull-request@v2 with: diff --git a/.travis.yml b/.travis.yml index 315eb07a8..4cd0dffe1 100644 --- a/.travis.yml +++ b/.travis.yml @@ -11,5 +11,11 @@ matrix: before_script: - npm install -g coveralls - node_js: "12" + script: + - ./node_modules/.bin/grunt no-coverage - node_js: "10" + script: + - ./node_modules/.bin/grunt no-coverage - node_js: "8" + script: + - ./node_modules/.bin/grunt no-coverage diff --git a/CHANGELOG.md b/CHANGELOG.md index 7f4f4a43f..fdbb4ada9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,10 +1,87 @@ +### 1.2.7: Maintenance Release + +Editor + + - Ensure subflow-scoped config nodes do not get moved on import Fixes #2789 + - Allow TypedInput to be disabled (#2752) @bartbutenaers + - Allow userMenu to be explicitly enabled (#2805) @tfmf + - Improvements to DE translation (#2192) @ketzu + + +Runtime + + - Handle `undefined` error passed to node.error (#2781) @johnwang71 + - Disable nyc coverage reporting on older node versions + - Improve Editor API unit test coverage (#2777) @aaronmyatt + + +Nodes + + - Trigger: ensure timestamp option sends .now() at point of sending + + +### 1.2.6: Maintenance Release + + +Editor + + - Update Japanese translations for 1.2.5 (#2764) @kazuhitoyokoi + - Library: properly handle symlinked folders (#2768) @natcl + +Runtime + + - Support Windows paths when installing tarball by path name Fixes #2769 + - Fix unsecure command usage in GH Action + +Nodes + + - Update MQTT to latest to fix Node 8 URL breakage + + + + +### 1.2.5: Maintenance Release + +Editor + + - Fix import of config nodes with unknown z property + +Runtime + + - Set ACTIONS_ALLOW_UNSECURE_COMMANDS in GH Action + +### 1.2.4: Maintenance Release + +Editor + + - Support bigint types in Debug sidebar + - Clear retained status of deleted nodes + - Prevent needless retention of node status messages + - Update projects dialogs to use TypedInput-cred input + - Restore cursor position in TypedInput cred-mode + - Ensure config nodes with invalid z are imported somewhere + - Ensure user keyboard shortcuts override defaults Fixes #2753 + +Runtime + + - Disable projects when flowFile passed into grunt dev + - Add Russian Locale (#2761) (#2531) (@alexk111) + - Add Japanese translation for http-in node (#2758) (@kazuhitoyokoi) + +Nodes + + - CSV: Fix CSV node repeating array output + ### 1.2.3: Maintenance Release Editor + - Disable 'use strict' checking in Function node Fixes #2743 + - Add gray/grey alternate options for status - Handle import errors on initial load and report to user - Only apply recovery tab on initial load Fixes #2731 - Reinstate coveralls reporting to travis build + - Update Japanese message catalogue for 1.2.3 release #2747 (@HiroyasuNishiyama) Runtime @@ -12,6 +89,7 @@ Runtime - Add mutex lock to saveSettings storage call Fixes #2736 (#2737) - Migrate to nyc instead of istanbul for code coverage - Move mosca to ui-test-dependencies + - Remove " from npm install prefix option ### 1.2.2: Maintenance Release diff --git a/Gruntfile.js b/Gruntfile.js index 49d2f154e..b01763ab0 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -24,6 +24,7 @@ module.exports = function(grunt) { var flowFile = grunt.option('flowFile'); if (flowFile) { nodemonArgs.push(flowFile); + process.env.NODE_RED_ENABLE_PROJECTS=false; } var userDir = grunt.option('userDir'); if (userDir) { @@ -622,6 +623,11 @@ module.exports = function(grunt) { 'Builds editor content then runs code style checks and unit tests on all components', ['build','verifyPackageDependencies','jshint:editor','nyc:all']); + grunt.registerTask('no-coverage', + 'Builds editor content then runs code style checks and unit tests on all components without code coverage', + ['build','verifyPackageDependencies','jshint:editor','simplemocha:all']); + + grunt.registerTask('test-core', 'Runs code style check and unit tests on core runtime code', ['build','nyc:core']); diff --git a/package.json b/package.json index 70b3b0d0a..1050b4bff 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "node-red", - "version": "1.2.3", + "version": "1.2.7", "description": "Low-code programming for event-driven applications", "homepage": "http://nodered.org", "license": "Apache-2.0", @@ -27,7 +27,7 @@ ], "dependencies": { "ajv": "6.12.6", - "async-mutex": "0.2.4", + "async-mutex": "0.2.6", "basic-auth": "2.0.1", "bcryptjs": "2.4.3", "body-parser": "1.19.0", @@ -38,7 +38,7 @@ "cookie-parser": "1.4.5", "cors": "2.8.5", "cron": "1.7.2", - "denque": "1.4.1", + "denque": "1.5.0", "express": "4.17.1", "express-session": "1.17.1", "fs-extra": "8.1.0", @@ -54,11 +54,11 @@ "lodash.clonedeep": "^4.5.0", "media-typer": "1.1.0", "memorystore": "1.6.4", - "mime": "2.4.6", - "moment-timezone": "^0.5.31", - "mqtt": "4.2.4", + "mime": "2.4.7", + "moment-timezone": "0.5.32", + "mqtt": "4.2.6", "multer": "1.4.2", - "mustache": "4.0.1", + "mustache": "4.1.0", "node-red-admin": "^0.2.6", "node-red-node-rbe": "^0.2.9", "node-red-node-sentiment": "^0.1.6", @@ -73,7 +73,7 @@ "request": "2.88.0", "semver": "6.3.0", "tar": "6.0.5", - "uglify-js": "3.11.4", + "uglify-js": "3.12.4", "when": "3.7.8", "ws": "6.2.1", "xml2js": "0.4.23" @@ -82,7 +82,7 @@ "bcrypt": "3.0.8" }, "devDependencies": { - "dompurify": "2.2.2", + "dompurify": "2.2.6", "grunt": "1.3.0", "grunt-chmod": "~1.1.1", "grunt-cli": "~1.3.2", @@ -104,7 +104,7 @@ "grunt-simple-nyc": "^3.0.1", "http-proxy": "1.18.1", "jsdoc-nr-template": "github:node-red/jsdoc-nr-template", - "marked": "1.2.2", + "marked": "1.2.7", "minami": "1.2.3", "mocha": "^5.2.0", "node-red-node-test-helper": "^0.2.5", diff --git a/packages/node_modules/@node-red/editor-api/lib/editor/comms.js b/packages/node_modules/@node-red/editor-api/lib/editor/comms.js index 386b5f8a8..9c96bbf5b 100644 --- a/packages/node_modules/@node-red/editor-api/lib/editor/comms.js +++ b/packages/node_modules/@node-red/editor-api/lib/editor/comms.js @@ -33,8 +33,6 @@ var activeConnections = []; var anonymousUser; -var retained = {}; - var heartbeatTimer; var lastSentTime; diff --git a/packages/node_modules/@node-red/editor-api/package.json b/packages/node_modules/@node-red/editor-api/package.json index 470a6dc9e..89838e602 100644 --- a/packages/node_modules/@node-red/editor-api/package.json +++ b/packages/node_modules/@node-red/editor-api/package.json @@ -1,6 +1,6 @@ { "name": "@node-red/editor-api", - "version": "1.2.3", + "version": "1.2.7", "license": "Apache-2.0", "main": "./lib/index.js", "repository": { @@ -16,8 +16,8 @@ } ], "dependencies": { - "@node-red/util": "1.2.3", - "@node-red/editor-client": "1.2.3", + "@node-red/util": "1.2.7", + "@node-red/editor-client": "1.2.7", "bcryptjs": "2.4.3", "body-parser": "1.19.0", "clone": "2.1.2", @@ -25,9 +25,9 @@ "express-session": "1.17.1", "express": "4.17.1", "memorystore": "1.6.4", - "mime": "2.4.6", + "mime": "2.4.7", "multer": "1.4.2", - "mustache": "4.0.1", + "mustache": "4.1.0", "oauth2orize": "1.11.0", "passport-http-bearer": "1.0.1", "passport-oauth2-client-password": "0.1.2", diff --git a/packages/node_modules/@node-red/editor-client/locales/de/editor.json b/packages/node_modules/@node-red/editor-client/locales/de/editor.json index 0c8dd42eb..7c408d742 100755 --- a/packages/node_modules/@node-red/editor-client/locales/de/editor.json +++ b/packages/node_modules/@node-red/editor-client/locales/de/editor.json @@ -32,7 +32,7 @@ "label" : { "view" : { "view" : "Ansicht", - "grid" : "Gitter", + "grid" : "Raster", "showGrid" : "Raster anzeigen", "snapGrid" : "Am Raster ausrichten", "gridSize" : "Rastergröße", diff --git a/packages/node_modules/@node-red/editor-client/locales/en-US/editor.json b/packages/node_modules/@node-red/editor-client/locales/en-US/editor.json index a26717b2f..0b92fc18c 100755 --- a/packages/node_modules/@node-red/editor-client/locales/en-US/editor.json +++ b/packages/node_modules/@node-red/editor-client/locales/en-US/editor.json @@ -1089,6 +1089,7 @@ "en-US": "English", "ja": "Japanese", "ko": "Korean", + "ru": "Russian", "zh-CN": "Chinese(Simplified)", "zh-TW": "Chinese(Traditional)" } diff --git a/packages/node_modules/@node-red/editor-client/locales/ja/editor.json b/packages/node_modules/@node-red/editor-client/locales/ja/editor.json index feaa627e5..f5774d57d 100644 --- a/packages/node_modules/@node-red/editor-client/locales/ja/editor.json +++ b/packages/node_modules/@node-red/editor-client/locales/ja/editor.json @@ -42,7 +42,8 @@ "loadNodeCatalogs": "ノードカタログを読み込み中", "loadNodes": "ノードを読み込み中 __count__", "loadFlows": "フローを読み込み中", - "importFlows": "ワークスペースにフローを追加中" + "importFlows": "ワークスペースにフローを追加中", + "importError": "
フロー追加エラー
__message__
" }, "workspace": { "defaultName": "フロー __number__", @@ -207,6 +208,8 @@ "download": "ダウンロード", "importUnrecognised": "認識できない型が読み込まれました:", "importUnrecognised_plural": "認識できない型が読み込まれました:", + "importDuplicate": "重複したノードを読み込みました:", + "importDuplicate_plural": "重複したノードを読み込みました:", "nodesExported": "クリップボードへフローを書き出しました", "nodesImported": "読み込みました:", "nodeCopied": "__count__ 個のノードをコピーしました", @@ -545,7 +548,7 @@ "sortRecent": "日付順", "more": "+ さらに __count__ 個", "upload": "モジュールのtgzファイルをアップロード", - "refresh": "モジュールリスト更新", + "refresh": "モジュールリスト更新", "errors": { "catalogLoadFailed": "ノードのカタログの読み込みに失敗しました。
詳細はブラウザのコンソールを確認してください。
", "installFailed": "追加処理が失敗しました: __module__
__message__
詳細はログを確認してください。
", @@ -1086,6 +1089,7 @@ "en-US": "英語", "ja": "日本語", "ko": "韓国語", + "ru": "ロシア語", "zh-CN": "中国語(簡体)", "zh-TW": "中国語(繁体)" } diff --git a/packages/node_modules/@node-red/editor-client/locales/ru/editor.json b/packages/node_modules/@node-red/editor-client/locales/ru/editor.json new file mode 100755 index 000000000..1f91d4b0b --- /dev/null +++ b/packages/node_modules/@node-red/editor-client/locales/ru/editor.json @@ -0,0 +1,1139 @@ +{ + "common": { + "label": { + "name": "Имя", + "ok": "Ок", + "done":"Готово", + "cancel": "Отмена", + "delete": "Удалить", + "close": "Закрыть", + "load": "Загрузить", + "save": "Сохранить", + "import": "Импорт", + "export": "Экспорт", + "back": "Назад", + "next": "Далее", + "clone": "Клонировать проект", + "cont": "Продолжить", + "style": "Стиль", + "line": "Контур", + "fill": "Заливка", + "label": "Метка", + "color": "Цвет", + "position": "Положение", + "enable": "Включить", + "disable": "Отключить", + "upload": "Загрузить" + }, + "type": { + "string": "строка", + "number": "число", + "boolean": "логический тип", + "array": "массив", + "buffer": "буфер", + "object": "объект", + "jsonString": "JSON строка", + "undefined": "undefined", + "null": "null" + } + }, + "event": { + "loadPalette": "Загрузка палитры", + "loadNodeCatalogs": "Загрузка каталогов узлов", + "loadNodes": "Загрузка узлов __count__", + "loadFlows": "Загрузка потоков", + "importFlows": "Добавление потоков в рабочую область", + "importError": "Ошибка добавления потоков
__message__
" + }, + "workspace": { + "defaultName": "Поток __number__", + "editFlow": "Изменить поток: __name__", + "confirmDelete": "Подтвердить удаление", + "delete": "Вы уверены, что хотите удалить '__label__'?", + "dropFlowHere": "Перетащите поток сюда", + "addFlow": "Добавить поток", + "listFlows": "Список потоков", + "status": "Статус", + "enabled": "Включено", + "disabled":"Отключено", + "info": "Описание", + "selectNodes": "Кликните по узлам, чтобы выбрать их" + }, + "menu": { + "label": { + "view": { + "view": "Вид", + "grid": "Сетка", + "showGrid": "Показывать сетку", + "snapGrid": "Привязывать к сетке", + "gridSize": "Размер сетки", + "textDir": "Направление текста", + "defaultDir": "По умолчанию", + "ltr": "Слева направо", + "rtl": "Справа налево", + "auto": "Контекстуальный", + "language": "Язык", + "browserDefault": "По умолчанию в браузере" + }, + "sidebar": { + "show": "Показывать боковую панель" + }, + "palette": { + "show": "Показывать палитру" + }, + "settings": "Параметры", + "userSettings": "Параметры пользователя", + "nodes": "Узлы", + "displayStatus": "Показывать статус узла", + "displayConfig": "Конфигурационные узлы", + "import": "Импорт", + "export": "Экспорт", + "search": "Поиск в потоках", + "searchInput": "поиск в Ваших потоках", + "subflows": "Подпотоки", + "createSubflow": "Создать подпоток", + "selectionToSubflow": "Выделение в подпоток", + "flows": "Потоки", + "add": "Добавить", + "rename": "Переименовать", + "delete": "Удалить", + "keyboardShortcuts": "Сочетания клавиш", + "login": "Войти", + "logout": "Выйти", + "editPalette":"Управление палитрой", + "other": "Другое", + "showTips": "Показывать советы", + "help": "Вебсайт Node-RED", + "projects": "Проекты", + "projects-new": "Новый", + "projects-open": "Открыть", + "projects-settings": "Настройки проекта", + "showNodeLabelDefault": "Показывать метки у недавно добавленных узлов", + "groups": "Группы", + "groupSelection": "Сгруппировать выделение", + "ungroupSelection": "Разгруппировать выделение", + "groupMergeSelection": "Объединить выделение", + "groupRemoveSelection": "Удалить из группы" + } + }, + "actions": { + "toggle-navigator": "Показать/скрыть навигатор", + "zoom-out": "Уменьшить", + "zoom-reset": "Сбросить масштаб", + "zoom-in": "Увеличить" + }, + "user": { + "loggedInAs": "Вы вошли как __name__", + "username": "Имя пользователя", + "password": "Пароль", + "login": "Войти", + "loginFailed": "Ошибка входа", + "notAuthorized": "Вы не авторизованы", + "errors": { + "settings": "Вы должны войти, чтобы получить доступ к настройкам", + "deploy": "Вы должны войти, чтобы развернуть изменения", + "notAuthorized": "Вы должны войти, чтобы выполнить это действие" + } + }, + "notification": { + "warning": "Предупреждение: __message__", + "warnings": { + "undeployedChanges": "узел имеет неразвернутые изменения", + "nodeActionDisabled": "действия узла отключены", + "nodeActionDisabledSubflow": "действия узла отключены внутри подпотока", + "missing-types": "Потоки остановлены из-за отсутствующих типов узлов.
", + "safe-mode":"Потоки остановлены в безопасном режиме.
Вы можете изменить свои потоки и развернуть изменения для перезапуска.
", + "restartRequired": "Node-RED должен быть перезапущен, чтобы включить обновленные модули", + "credentials_load_failed": "Потоки остановлены, поскольку учетные данные не могут быть расшифрованы.
Файл учетных данных потока зашифрован, но ключ шифрования проекта отсутствует или недействителен.
", + "credentials_load_failed_reset":"Учетные данные не могут быть расшифрованы
Файл учетных данных потока зашифрован, но ключ шифрования проекта отсутствует или недействителен.
Файл учетных данных потока будет сброшен при следующем развертывании. Любые существующие учетные данные потока будут удалены.
", + "missing_flow_file": "Файл потока проекта не найден.
Проект не настроен с файлом потока.
", + "missing_package_file": "Файл пакета проекта не найден.
В проекте отсутствует файл package.json.
", + "project_empty": "Проект пуст.
Вы хотите создать набор файлов проекта по умолчанию?
В противном случае вам придется вручную добавлять файлы в проект за пределами редактора.
Проект '__project__' не найден.
", + "git_merge_conflict": "Автоматическое слияние изменений не удалось.
Исправьте неразрешенные конфликты, и закоммитьте результаты.
" + }, + "error": "Ошибка: __message__", + "errors": { + "lostConnection": "Потеряно соединение с сервером, переподключение...", + "lostConnectionReconnect": "Потеряно соединение с сервером, переподключение через __time__сек.", + "lostConnectionTry": "Попробовать сейчас", + "cannotAddSubflowToItself": "Невозможно добавить подпоток в самого себя", + "cannotAddCircularReference": "Невозможно добавить подпоток - обнаружена циклическая ссылка", + "unsupportedVersion": "Используется неподдерживаемая версия Node.js
Вы должны обновить Node.js до последней версии LTS релиза
", + "failedToAppendNode": "Не удалось загрузить '__module__'
__error__
" + }, + "project": { + "change-branch": "Переключиться в локальную ветку '__project__'", + "merge-abort": "Git-слияние прервано", + "loaded": "Проект '__project__' загружен", + "updated": "Проект '__project__' обновлен", + "pull": "Проект '__project__' перезагружен", + "revert": "Изменения в проекте '__project__' отменены", + "merge-complete": "Git-слияние завершено", + "setupCredentials": "Настройка учетных данных", + "setupProjectFiles": "Настройка файлов проекта", + "no": "Нет, спасибо", + "createDefault": "Создать файлы проекта по умолчанию", + "mergeConflict": "Показать конфликты слияния" + }, + "label": { + "manage-project-dep": "Управление зависимостями проекта", + "setup-cred": "Настройка учетных данных", + "setup-project": "Настройка файлов проекта", + "create-default-package": "Создать файл пакета по умолчанию", + "no-thanks": "Нет, спасибо", + "create-default-project": "Создать файлы проекта по умолчанию", + "show-merge-conflicts": "Показать конфликты слияния" + } + }, + "clipboard": { + "clipboard": "Буфер обмена", + "nodes": "Узлы", + "node": "__count__ узел", + "node_plural_2": "__count__ узла", + "node_plural_5": "__count__ узлов", + "configNode": "__count__ конфигурационный узел", + "configNode_plural_2": "__count__ конфигурационных узла", + "configNode_plural_5": "__count__ конфигурационных узлов", + "group": "__count__ группа", + "group_plural_2": "__count__ группы", + "group_plural_5": "__count__ групп", + "flow": "__count__ поток", + "flow_plural_2": "__count__ потока", + "flow_plural_5": "__count__ потоков", + "subflow": "__count__ подпотока", + "subflow_plural_2": "__count__ подпотока", + "subflow_plural_5": "__count__ подпотоков", + "replacedNodes": "__count__ узел заменен", + "replacedNodes_plural_2": "__count__ узла заменено", + "replacedNodes_plural_5": "__count__ узлов заменено", + "pasteNodes": "Вставьте json потока или", + "selectFile": "выберите файл для импорта", + "importNodes": "Импортировать узлы", + "exportNodes": "Экспортировать узлы", + "download": "Скачать", + "importUnrecognised": "Импортирован неопознанный тип:", + "importUnrecognised_plural_2": "Импортированы неопознанные типы:", + "importUnrecognised_plural_5": "Импортированы неопознанные типы:", + "importDuplicate": "Импортирован дубликат узла:", + "importDuplicate_plural_2": "Импортированы дубликаты узлов:", + "importDuplicate_plural_5": "Импортированы дубликаты узлов:", + "nodesExported": "Узлы экспортированы в буфер обмена", + "nodesImported": "Импортированы:", + "nodeCopied": "__count__ узел скопирован", + "nodeCopied_plural_2": "__count__ узла скопировано", + "nodeCopied_plural_5": "__count__ узлов скопировано", + "groupCopied": "__count__ группа скопирована", + "groupCopied_plural_2": "__count__ группы скопированы", + "groupCopied_plural_5": "__count__ групп скопировано", + "groupStyleCopied": "Стиль группы скопирован", + "invalidFlow": "Неверный поток: __message__", + "recoveredNodes": "Восстановленные узлы", + "recoveredNodesInfo": "У узлов в этом потоке отсутствовал действительный id потока при импортировании. Они были добавлены в этот поток, чтобы Вы могли либо вернуть, либо удалить их.", + "recoveredNodesNotification": "Импортированы узлы без действительного id потока
Они были добавлены в новый поток под названием '__flowName__'.
", + "export": { + "selected":"выбранные узлы", + "current":"текущий поток", + "all":"все потоки", + "compact":"компактно", + "formatted":"форматированно", + "copy": "Скопировать в буфер обмена", + "export": "Экспорт в библиотеку", + "exportAs": "Экспорт как", + "overwrite": "Заменить", + "exists": "\"__file__\" уже существует.
Вы хотите его заменить?
" + }, + "import": { + "import": "Импортировать в", + "importSelected": "Импортировать выбранные", + "importCopy": "Импортировать копию", + "viewNodes": "Посмотреть узлы...", + "newFlow": "новый поток", + "replace": "заменить", + "errors": { + "notArray": "Не массив JSON", + "itemNotObject": "Недопустимый поток - элемент __index__ не является узлом объекта", + "missingId": "Недопустимый поток - у элемента __index__ отсутствует свойство 'id'", + "missingType": "Недопустимый поток - у элемента __index__ отсутствует свойство 'type'" + }, + "conflictNotification1": "Некоторые импортируемые Вами узлы уже существуют в рабочей области.", + "conflictNotification2": "Выберите, какие узлы импортировать и следует ли заменить существующие узлы или импортировать их копию." + }, + "copyMessagePath": "Путь скопирован", + "copyMessageValue": "Значение скопировано", + "copyMessageValue_truncated": "Усеченное значение скопировано" + }, + "deploy": { + "deploy": "Развернуть", + "full": "Полностью", + "fullDesc": "Развертывает все в рабочей области", + "modifiedFlows": "Измененные потоки", + "modifiedFlowsDesc": "Развертывает только потоки, которые содержат измененные узлы", + "modifiedNodes": "Измененные узлы", + "modifiedNodesDesc": "Развертывает только узлы, которые были изменены", + "restartFlows": "Перезапустить потоки", + "restartFlowsDesc": "Перезапускает текущие развернутые потоки", + "successfulDeploy": "Успешно развернуто", + "successfulRestart": "Потоки успешно перезапущены", + "deployFailed": "Развертывание не удалось: __message__", + "unusedConfigNodes":"У вас есть неиспользуемых узлы конфигурации.", + "unusedConfigNodesLink":"Нажмите здесь, чтобы их увидеть", + "errors": { + "noResponse": "нет ответа от сервера" + }, + "confirm": { + "button": { + "ignore": "Игнорировать", + "confirm": "Подтвердить развертывание", + "review": "Обзор изменений", + "cancel": "Отмена", + "merge": "Слияние", + "overwrite": "Игнорировать и развернуть" + }, + "undeployedChanges": "У Вас есть неразвернутые изменение.\n\nПокидая эту страницу, вы потеряете эти изменения.", + "improperlyConfigured": "Рабочая область содержит узлы, которые не настроены должным образом:", + "unknown": "Рабочая область содержит неизвестные типы узлов:", + "confirm": "Вы уверены, что хотите развернуть??", + "doNotWarn": "больше не предупреждать об этом", + "conflict": "На сервере запущен более свежий набор потоков.", + "backgroundUpdate": "Потоки на сервере обновлены.", + "conflictChecking": "Проверка возможности автоматического слияния изменений", + "conflictAutoMerge": "Изменения не содержат конфликтов и могут быть объединены автоматически.", + "conflictManualMerge": "Изменения включают конфликты, которые должны быть разрешены перед их развертыванием.", + "plusNMore": "+ еще __count__" + } + }, + "eventLog": { + "title": "Журнал событий", + "view": "Посмотреть журнал" + }, + "diff": { + "unresolvedCount": "__count__ неразрешенный конфликт", + "unresolvedCount_plural_2": "__count__ неразрешенных конфликта", + "unresolvedCount_plural_5": "__count__ неразрешенных конфликтов", + "globalNodes": "Глобальные узлы", + "flowProperties": "Свойства потока", + "type": { + "added": "добавлен", + "changed": "изменен", + "unchanged": "без изменений", + "deleted": "удален", + "flowDeleted": "поток удален", + "flowAdded": "поток добавлен", + "movedTo": "перемещен в __id__", + "movedFrom": "перемещен из __id__" + }, + "nodeCount": "__count__ узел", + "nodeCount_plural_2": "__count__ узла", + "nodeCount_plural_5": "__count__ узлов", + "local":"Локальные изменения", + "remote":"Удаленные изменения", + "reviewChanges": "Обзор изменений", + "noBinaryFileShowed": "Невозможно отобразить содержимое двоичного файла", + "viewCommitDiff": "Просмотр изменений коммита", + "compareChanges": "Сравнить изменения", + "saveConflict": "Сохранить разрешение конфликта", + "conflictHeader": "__resolved__ из __unresolved__ кофликта(ов) разрешено", + "commonVersionError": "Общая версия содержит недействительный JSON:", + "oldVersionError": "Старая версия содержит недействительный JSON:", + "newVersionError": "Новая версия содержит недействительный JSON:" + }, + "subflow": { + "editSubflowInstance": "Изменить экземпляр подпотока: __name__", + "editSubflow": "Изменить шаблон подпотока: __name__", + "edit": "Изменить шаблон подпотока", + "subflowInstances": "Есть __count__ экземпляр этого шаблона подпотока", + "subflowInstances_plural_2": "Есть __count__ экземпляра этого шаблона подпотока", + "subflowInstances_plural_5": "Есть __count__ экземпляров этого шаблона подпотока", + "editSubflowProperties": "редактировать свойства", + "input": "входы:", + "output": "выходы:", + "status": "узел статуса", + "deleteSubflow": "удалить подпоток", + "info": "Описание", + "category": "Категория", + "env": { + "restore": "Восстановить в подпоток по умолчанию", + "remove": "Удалить переменную среды" + }, + "errors": { + "noNodesSelected": "Невозможно создать подпоток: узлы не выбраны", + "multipleInputsToSelection": "Невозможно создать подпоток: множество входов на выбранное" + } + }, + "group": { + "editGroup": "Изменить группу: __name__", + "errors": { + "cannotCreateDiffGroups": "Невозможно создать группу, используя узлы из разных групп", + "cannotAddSubflowPorts": "Невозможно добавить порты подпотока в группу" + } + }, + "editor": { + "configEdit": "Правка", + "configAdd": "Добавить", + "configUpdate": "Обновить", + "configDelete": "Удалить", + "nodesUse": "__count__ узел использует эту конфигурацию", + "nodesUse_plural_2": "__count__ узла используют эту конфигурацию", + "nodesUse_plural_5": "__count__ узлов используют эту конфигурацию", + "addNewConfig": "Добавить новый конфигурационный узел __type__", + "editNode": "Изменить узел __type__", + "editConfig": "Изменить конфигурационный узел __type__", + "addNewType": "Добавить новый __type__...", + "nodeProperties": "свойства узла", + "label": "Метка", + "color": "Цвет", + "portLabels": "Метки портов", + "labelInputs": "Входы", + "labelOutputs": "Выходы", + "settingIcon": "Значок", + "default": "по умолчанию", + "noDefaultLabel": "нет", + "defaultLabel": "использовать метку по умолчанию", + "searchIcons": "Поиск значков", + "useDefault": "использовать по умолчанию", + "description": "Описание", + "show": "Показать", + "hide": "Спрятать", + "locale": "Выберите язык интерфейса", + "icon": "Знак", + "inputType": "Тип входа", + "selectType": "выберите типы...", + "inputs" : { + "input": "ввод", + "select": "выбор", + "checkbox": "флажок", + "spinner": "счетчик", + "none": "нет", + "hidden": "спрятать свойство" + }, + "types": { + "str": "строка", + "num": "число", + "bool": "логический тип", + "json": "JSON", + "bin": "буфер", + "env": "переменная среды", + "cred": "учетные данные" + }, + "menu": { + "input": "ввод", + "select": "выбор", + "checkbox": "флажок", + "spinner": "счетчик", + "hidden": "только метка" + }, + "select": { + "label": "Метка", + "value": "Значение" + }, + "spinner": { + "min": "Минимум", + "max": "Максимум" + }, + "errors": { + "scopeChange": "Изменение области действия сделает ее недоступной для узлов в других потоках, которые ее используют", + "invalidProperties": "Неверные свойства:" + } + }, + "keyboard": { + "title": "Горячие клавиши", + "keyboard": "Клавиши", + "filterActions": "фильтр действий", + "shortcut": "сочетание", + "scope": "область", + "unassigned": "Не назначено", + "global": "глобально", + "workspace": "рабочая область", + "selectAll": "Выбрать все узлы", + "selectAllConnected": "Выбрать все соединенные узлы", + "addRemoveNode": "Добавить/убрать узел из выбора", + "editSelected": "Изменить выбранный узел", + "deleteSelected": "Удалить выбранные узлы или связь", + "importNode": "Импорт узлов", + "exportNode": "Экспорт узлов", + "nudgeNode": "Переместить выбранные узлы (1пикс)", + "moveNode": "Переместить выбранные узлы (20пикс)", + "toggleSidebar": "Показать/скрыть боковую панель", + "togglePalette": "Показать/скрыть палитру", + "copyNode": "Скопировать выбранные узлы", + "cutNode": "Вырезать выбранные узлы", + "pasteNode": "Вставить узлы", + "undoChange": "Отменить последнее выполненное изменение", + "searchBox": "Открыть окно поиска", + "managePalette": "Управление палитрой", + "actionList":"Список действий" + }, + "library": { + "library": "Библиотека", + "openLibrary": "Открыть библиотеку...", + "saveToLibrary": "Сохранить в библиотеку...", + "typeLibrary": "Библиотека __type__", + "unnamedType": "Безымянный __type__", + "exportedToLibrary": "Узлы экспортированы в библиотеку", + "dialogSaveOverwrite": "__libraryType__ под названием __libraryName__ уже существует. Заменить?", + "invalidFilename": "Неверное имя файла", + "savedNodes": "Сохраненные узлы", + "savedType": "Сохраненные __type__", + "saveFailed": "Не удалось сохранить: __message__", + "newFolder": "Новая папка", + "types": { + "local": "Локальные", + "examples": "Примеры" + } + }, + "palette": { + "noInfo": "сведения отсутствуют", + "filter": "фильтр узлов", + "search": "поиск по модулям", + "addCategory": "Добавить новую...", + "label": { + "subflows": "подпотоки", + "network": "сеть", + "common": "общие", + "input": "ввод", + "output": "вывод", + "function": "функция", + "sequence": "последоват-ть", + "parser": "анализатор", + "social": "социальные", + "storage": "хранилище", + "analysis": "анализ", + "advanced": "продвинутые" + }, + "actions": { + "collapse-all": "Свернуть все категории", + "expand-all": "Развернуть все категории" + }, + "event": { + "nodeAdded": "Узел добавлен в палитру:", + "nodeAdded_plural_2": "Узлы добавлены в палитру:", + "nodeAdded_plural_5": "Узлы добавлены в палитру:", + "nodeRemoved": "Узел удален из палитры:", + "nodeRemoved_plural_2": "Узлы удалены из палитры:", + "nodeRemoved_plural_5": "Узлы удалены из палитры:", + "nodeEnabled": "Узел включен:", + "nodeEnabled_plural_2": "Узлы включены:", + "nodeEnabled_plural_5": "Узлы включены:", + "nodeDisabled": "Узел отключен:", + "nodeDisabled_plural_2": "Узлы отключены:", + "nodeDisabled_plural_5": "Узлы отключены:", + "nodeUpgraded": "Узловой модуль __module__ обновлен до версии __version__" + }, + "editor": { + "title": "Управление палитрой", + "palette": "Палитра", + "times": { + "seconds": "сек назад", + "minutes": "мин назад", + "minutesV": "__count__ минуту назад", + "minutesV_plural_2": "__count__ минуты назад", + "minutesV_plural_5": "__count__ минут назад", + "hoursV": "__count__ час назад", + "hoursV_plural_2": "__count__ часа назад", + "hoursV_plural_5": "__count__ часов назад", + "daysV": "__count__ день назад", + "daysV_plural_2": "__count__ дня назад", + "daysV_plural_5": "__count__ дней назад", + "weeksV": "__count__ неделю назад", + "weeksV_plural_2": "__count__ недели назад", + "weeksV_plural_5": "__count__ недель назад", + "monthsV": "__count__ месяц назад", + "monthsV_plural_2": "__count__ месяца назад", + "monthsV_plural_5": "__count__ месяцев назад", + "yearsV": "__count__ год назад", + "yearsV_plural_2": "__count__ года назад", + "yearsV_plural_5": "__count__ лет назад", + "yearMonthsV": "__y__ год, __count__ месяц назад", + "yearMonthsV_plural_2": "__y__ год, __count__ месяца назад", + "yearMonthsV_plural_5": "__y__ год, __count__ месяцев назад", + "yearsMonthsV": "__y__ года, __count__ месяц назад", + "yearsMonthsV_plural_2": "__y__ года, __count__ месяца назад", + "yearsMonthsV_plural_5": "__y__ года, __count__ месяцев назад" + }, + "nodeCount": "__label__ узел", + "nodeCount_plural_2": "__label__ узла", + "nodeCount_plural_5": "__label__ узлов", + "moduleCount": "__count__ модуль доступен", + "moduleCount_plural_2": "__count__ модуля доступно", + "moduleCount_plural_5": "__count__ модулей доступно", + "inuse": "в использовании", + "enableall": "включить все", + "disableall": "отключить все", + "enable": "включить", + "disable": "отключить", + "remove": "удалить", + "update": "обновить до __version__", + "updated": "обновлено", + "install": "установить", + "installed": "установлено", + "conflict": "конфликт", + "conflictTip": "Этот модуль не может быть установлен, поскольку он
включает тип узла, который уже был установлен
Конфликты с __module__
Не удалось загрузить каталог узлов.
Проверьте консоль браузера для получения дополнительной информации
", + "installFailed": "Не удалось установить: __module__
__message__
Проверьте журнал для получения дополнительной информации
", + "removeFailed": "Не удалось удалить: __module__
__message__
Проверьте журнал для получения дополнительной информации
", + "updateFailed": "Не удалось обновить: __module__
__message__
Проверьте журнал для получения дополнительной информации
", + "enableFailed": "Не удалось включить: __module__
__message__
Проверьте журнал для получения дополнительной информации
", + "disableFailed": "Не удалось отключить: __module__
__message__
Проверьте журнал для получения дополнительной информации
" + }, + "confirm": { + "install": { + "body":"Установка '__module__'
Перед установкой ознакомьтесь с документацией по узлу. Некоторые узлы имеют зависимости, которые не могут быть автоматически разрешены и могут потребовать перезапуска Node-RED.
", + "title": "Установить узлы" + }, + "remove": { + "body":"Удаление '__module__'
После удаления узла из Node-RED он может продолжать использовать ресурсы, пока Node-RED не будет перезапущен.
", + "title": "Удалить узлы" + }, + "update": { + "body":"Обновление '__module__'
Обновление узла потребует перезапуска Node-RED для завершения обновления. Это должно быть сделано вручную.
", + "title": "Обновить узлы" + }, + "cannotUpdate": { + "body":"Доступно обновление для этого узла, но оно не установлено в месте, которое менеджер палитры может обновить.Не удалось получить удаленные изменения; Ваши непроиндексированные локальные изменения будут перезаписаны.
Закоммитьте Ваши изменения и попробуйте еще раз.
", + "showUnstagedChanges": "Показать непроиндексированные изменения", + "connectionFailed": "Не удалось подключиться к удаленному репозиторию: ", + "pullUnrelatedHistory": "Удаленный репозиторий содержит историю коммитов, не имеющих отношения к локальному.
Вы уверены, что хотите получить изменения в Ваш локальный репозиторий?
", + "pullChanges": "Получить изменения", + "history": "история", + "projectHistory": "История проекта", + "daysAgo": "__count__ день назад", + "daysAgo_plural_2": "__count__ дня назад", + "daysAgo_plural_5": "__count__ дней назад", + "hoursAgo": "__count__ час назад", + "hoursAgo_plural_2": "__count__ часа назад", + "hoursAgo_plural_5": "__count__ часов назад", + "minsAgo": "__count__ минуту назад", + "minsAgo_plural_2": "__count__ минуты назад", + "minsAgo_plural_5": "__count__ минут назад", + "secondsAgo": "Секунд назад", + "notTracking": "Ваша локальная ветвь в настоящее время не отслеживает удаленную ветвь.", + "statusUnmergedChanged": "В вашем репозитории есть неслитые изменения. Вам нужно исправить конфликты и закоммитить результат.", + "repositoryUpToDate": "Ваш репозиторий в актуальном состоянии.", + "commitsAhead": "Ваш репозиторий на __count__ коммит опережает удаленный. Вы можете отправить этот коммит сейчас.", + "commitsAhead_plural_2": "Ваш репозиторий на __count__ коммита опережает удаленный. Вы можете отправить эти коммиты сейчас.", + "commitsAhead_plural_5": "Ваш репозиторий на __count__ коммитов опережает удаленный. Вы можете отправить эти коммиты сейчас.", + "commitsBehind": "Ваш репозиторий на __count__ коммит позади удаленного. Вы можете получить этот коммит сейчас.", + "commitsBehind_plural_2": "Ваш репозиторий на __count__ коммита позади удаленного. Вы можете получить этот коммит сейчас.", + "commitsBehind_plural_5": "Ваш репозиторий на __count__ коммитов позади удаленного. Вы можете получить этот коммит сейчас.", + "commitsAheadAndBehind1": "Ваш репозиторий на __count__ коомит позади и ", + "commitsAheadAndBehind1_plural_2": "Ваш репозиторий на __count__ коммита позади и ", + "commitsAheadAndBehind1_plural_5": "Ваш репозиторий на __count__ коммитов позади и ", + "commitsAheadAndBehind2": "__count__ коммит впереди удаленного. ", + "commitsAheadAndBehind2_plural_2": "__count__ коммита впереди удаленного. ", + "commitsAheadAndBehind2_plural_5": "__count__ коммитов впереди удаленного. ", + "commitsAheadAndBehind3": "Вы должны получить удаленный коммит перед отправкой.", + "commitsAheadAndBehind3_plural_2": "Вы должны получить удаленные коммиты перед отправкой.", + "commitsAheadAndBehind3_plural_5": "Вы должны получить удаленные коммиты перед отправкой.", + "refreshCommitHistory": "Обновить историю коммитов", + "refreshChanges": "Обновить изменения" + } + } + }, + "typedInput": { + "type": { + "str": "строка", + "num": "число", + "re": "регул. выражение", + "bool": "логический тип", + "json": "JSON", + "bin": "буфер", + "date": "отметка времени", + "jsonata": "выражение", + "env": "переменная среды", + "cred": "учетные данные" + } + }, + "editableList": { + "add": "добавить" + }, + "search": { + "empty": "Ничего не найдено", + "addNode": "добавить узел..." + }, + "expressionEditor": { + "functions": "Функции", + "functionReference": "Справка о функции", + "insert": "Вставить", + "title": "Редактор JSONata выражений", + "test": "Тестировать", + "data": "Пример сообщения", + "result": "Результат", + "format": "форматировать выражение", + "compatMode": "Режим совместимости включен", + "compatModeDesc": " Похоже, что текущее выражение все еще ссылается на msg
, поэтому будет выполняться в режиме совместимости. Обновите выражение, чтобы не использовать msg
, так как этот режим будет удален в будущем.
Когда поддержка JSONata была впервые добавлена в Node-RED, требовалось, чтобы выражение ссылалось на объект msg
. Например, msg.payload
будет использоваться для доступа к свойству payload.
В этом больше нет необходимости, поскольку выражение будет исполняться непосредственно для сообщения. Чтобы получить доступ к payload, выражение должно быть просто payload
.
Тип Буфер хранится в виде массива байтовых значений в формате JSON. Редактор попытается проанализировать введенное значение как массив JSON. Если это недопустимый JSON, он будет считаться строкой UTF-8 и преобразовываться в массив кодов отдельных символов.
Например, значение Hello World
будет преобразовано в массив JSON:
[72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100]" + }, + "projects": { + "config-git": "Настроить Git-клиент", + "welcome": { + "hello": "Здравствуйте! Мы ввели в использование 'Проекты' в Node-RED.", + "desc0": "Это новый способ управления файлами потоков, включающий контроль версий ваших потоков.", + "desc1": "Для начала вы можете создать свой первый проект или клонировать существующий проект из git репозитория.", + "desc2": "Если вы не уверены, вы можете пропустить это сейчас. Вы по-прежнему сможете создать свой первый проект из меню 'Проекты' в любое время.", + "create": "Создать проект", + "clone": "Клонировать репозиторий", + "openExistingProject": "Открыть существующий проект", + "not-right-now": "Не сейчас" + }, + "git-config": { + "setup": "Настройте Ваш клиент контроля версий", + "desc0": "Node-RED использует инструмент с открытым исходным кодом Git для контроля версий. Он отслеживает изменения в файлах Вашего проекта и позволяет отправлять их в удаленные репозитории.", + "desc1": "Когда вы делаете коммит набора изменений, Git записывает внесенные изменения с именем пользователя и адресом электронной почты. Имя пользователя может быть любым, каким вы хотите - оно не обязательно должно быть вашим настоящим именем.", + "desc2": "Ваш Git-клиент уже настроен с деталями ниже.", + "desc3": "Вы можете изменить эти настройки позже во вкладке 'Настройки Git' диалога настроек.", + "username": "Имя пользователя", + "email": "Email" + }, + "project-details": { + "create": "Создайте Ваш проект", + "desc0": "Проект поддерживается как Git-репозиторий. Это позволяет намного легче делиться своими потоками с другими и работать над ними вместе.", + "desc1": "Вы можете создать несколько проектов и быстро переключаться между ними из редактора.", + "desc2": "Для начала Вашему проекту нужно название и описание (необязательно).", + "already-exists": "Проект уже существует", + "must-contain": "Должно содержать только A-Z 0-9 _ -", + "project-name": "Название проекта", + "desc": "Описание", + "opt": "Необязательно" + }, + "clone-project": { + "clone": "Клонировать проект", + "desc0": "Если у вас уже есть git-репозиторий, содержащий проект, Вы можете клонировать его, чтобы начать.", + "already-exists": "Проект уже существует", + "must-contain": "Должно содержать только A-Z 0-9 _ -", + "project-name": "Название проекта", + "no-info-in-url": "Не включайте имя пользователя / пароль в URL-адрес", + "git-url": "URL Git-репозитория", + "protocols": "https://, ssh:// или file://", + "auth-failed": "Ошибка аутентификации", + "username": "Имя пользователя", + "passwd": "Пароль", + "ssh-key": "SSH ключ", + "passphrase": "Пароль", + "ssh-key-desc": "Прежде чем вы сможете клонировать репозиторий через ssh, вы должны добавить SSH-ключ для доступа к нему.", + "ssh-key-add": "Добавить ssh ключ", + "credential-key": "Ключ шифрования учетных данных", + "cant-get-ssh-key": "Ошибка! Не удается получить выбранный путь ключа SSH.", + "already-exists2": "уже существует", + "git-error": "ошибка git", + "connection-failed": "Ошибка подключения", + "not-git-repo": "Не git-репозиторий", + "repo-not-found": "Репозиторий не найден" + }, + "default-files": { + "create": "Создайте файлы Вашего проекта", + "desc0": "Проект содержит ваши потоковые файлы, файл README и файл package.json.", + "desc1": "Он может содержать любые другие файлы, которые вы хотите хранить в git-репозитории.", + "desc2": "Ваши существующие файлы потока и учетные данные будут скопированы в проект.", + "flow-file": "Файл потока", + "credentials-file": "Файл учетных данных" + }, + "encryption-config": { + "setup": "Настройте шифрование Вашего файла учетных данных", + "desc0": "Ваш файл учетных данных потока может быть зашифрован, чтобы сохранить его содержимое в безопасности.", + "desc1": "Если Вы хотите хранить эти учетные данные в публичном Git-репозитории, Вы должны зашифровать их, предоставив секретную ключевую фразу.", + "desc2": "Ваш файл учетных данных потока в настоящее время не зашифрован.", + "desc3": "Это означает, что его содержимое, такое как пароли и токены доступа, могут быть прочитаны любым пользователем, имеющим доступ к файлу.", + "desc4": "Если вы хотите хранить эти учетные данные в публичном Git-репозитории, Вы должны зашифровать их, предоставив секретную ключевую фразу.", + "desc5": "Ваш файл учетных данных потока в настоящее время зашифрован с использованием свойства credentialSecret файла настроек в качестве ключа.", + "desc6": "Ваш файл учетных данных потока в настоящее время зашифрован с использованием сгенерированного системой ключа. Вы должны предоставить новый секретный ключ для этого проекта.", + "desc7": "Ключ будет храниться отдельно от файлов Вашего проекта. Вам нужно будет предоставить ключ для использования этого проекта в другом экземпляре Node-RED.", + "credentials": "Учетные данные", + "enable": "Включить шифрование", + "disable": "Отключить шифрование", + "disabled": "отключено", + "copy": "Скопировать существующий ключ", + "use-custom": "Использовать пользовательский ключ", + "desc8": "Файл учетных данных не будет зашифрован, и его содержимое легко прочитать", + "create-project-files": "Создать файлы проекта", + "create-project": "Создать проект", + "already-exists": "уже существует", + "git-error": "ошибка git", + "git-auth-error": "ошибка аутентификации git" + }, + "create-success": { + "success": "Вы успешно создали свой первый проект!", + "desc0": "Теперь Вы можете продолжать использовать Node-RED как обычно.", + "desc1": "Вкладка 'Информация' на боковой панели показывает, какой у Вас текущий активный проект. Кнопка рядом с названием может быть использована для доступа к просмотру настроек проекта.", + "desc2": "Вкладка 'История' на боковой панели может использоваться для просмотра файлов, которые были изменены в Вашем проекте, и для их коммита. Она показывает Вам полную историю ваших коммитов и позволяет отправить Ваши изменения в удаленный репозиторий." + }, + "create": { + "projects": "Проекты", + "already-exists": "Проект уже существует", + "must-contain": "Должен содержать только A-Z 0-9 _ -", + "no-info-in-url": "Не включайте имя пользователя / пароль в URL-адрес", + "open": "Открыть проект", + "create": "Создать проект", + "clone": "Клонировать репозиторий", + "project-name": "Название проекта", + "desc": "Описание", + "opt": "Необязательно", + "flow-file": "Файл потока", + "credentials": "Учетные данные", + "enable-encryption": "Включить шифрование", + "disable-encryption": "Отключить шифрование", + "encryption-key": "Ключ шифрования", + "desc0": "Фраза, которой защитить Ваши учетные данные", + "desc1": "Файл учетных данных не будет зашифрован, и его содержимое легко прочитать", + "git-url": "URL git-репозитория", + "protocols": "https://, ssh:// или file://", + "auth-failed": "Ошибка аутентификации", + "username": "Имя пользователя", + "password": "Пароль", + "ssh-key": "SSH ключ", + "passphrase": "Пароль", + "desc2": "Прежде чем Вы сможете клонировать репозиторий через ssh, Вы должны добавить SSH-ключ для доступа к нему.", + "add-ssh-key": "Добавить ssh ключ", + "credentials-encryption-key": "Ключ шифрования учетных данных", + "already-exists-2": "уже существует", + "git-error": "ошибка git", + "con-failed": "Ошибка подключения", + "not-git": "Не git репозиторий", + "no-resource": "Репозиторий не найден", + "cant-get-ssh-key-path": "Ошибка! Не удается получить путь выбранного ключа SSH.", + "unexpected_error": "непредвиденная_ошибка" + }, + "delete": { + "confirm": "Вы уверены, что хотите удалить этот проект?" + }, + "create-project-list": { + "search": "искать по Вашим проектам", + "current": "текущий" + }, + "require-clean": { + "confirm": "
У вас есть неразвернутые изменения, которые будут потеряны.
Вы хотите продолжить?
" + }, + "send-req": { + "auth-req": "Требуется аутентификация для хранилища", + "username": "Имя пользователя", + "password": "Пароль", + "passphrase": "Пароль", + "retry": "Повторить", + "update-failed": "Не удалось обновить аутентификацию", + "unhandled": "Необработанный ответ об ошибке", + "host-key-verify-failed": "Проверка ключа хоста не удалась.
Ключ хоста хранилища не может быть проверен. Пожалуйста, обновите файл ').text(RED._("projects.welcome.desc2")).appendTo(body);
var row = $(' When converting to CSV, the column template is used to identify which properties to extract from the object and in what order. If the template is blank then the node can use a simple comma separated list of properties supplied in If the input is an array then the columns template is only used to optionally generate a row of column titles. If 'parse numerical values' option is checked, string numerical values will be returned as numbers, ie. middle value '1,"1.5",2'. If 'include empty strings' option is checked, empty strings will be returned in result, ie. middle value '"1","",3'. Тип этого узла неизвестен Вашей установке Node-RED. Если Вы развернете узел в этом состоянии, его конфигурация будет сохранена, но поток не будет запущен, пока отсутствующий тип не будет установлен. Дополнительную справку смотрите в информационной вкладке на боковой панелиknown_hosts
и попробуйте снова."
+ },
+ "create-branch-list": {
+ "invalid": "Неверная ветвь",
+ "create": "Создать ветвь",
+ "current": "текущая"
+ },
+ "create-default-file-set": {
+ "no-active": "Невозможно создать набор файлов по умолчанию без активного проекта",
+ "no-empty": "Невозможно создать набор файлов по умолчанию для непустого проекта",
+ "git-error": "ошибка git"
+ },
+ "errors" : {
+ "no-username-email": "Ваш Git-клиент не настроен с именем пользователя / электронной почтой.",
+ "unexpected": "Произошла непредвиденная ошибка",
+ "code": "код"
+ }
+ },
+ "editor-tab": {
+ "properties": "Свойства",
+ "envProperties": "Переменные среды",
+ "description": "Описание",
+ "appearance": "Внешний вид",
+ "preview": "Предпросмотр редактора",
+ "defaultValue": "Значение по умолчанию"
+ },
+ "languages" : {
+ "de": "Немецкий",
+ "en-US": "Английский",
+ "ja": "Японский",
+ "ko": "Корейский",
+ "ru": "Русский",
+ "zh-CN": "Китайский (упрощенный)",
+ "zh-TW": "Китайский (традиционный)"
+ }
+}
diff --git a/packages/node_modules/@node-red/editor-client/locales/ru/infotips.json b/packages/node_modules/@node-red/editor-client/locales/ru/infotips.json
new file mode 100755
index 000000000..d65d88545
--- /dev/null
+++ b/packages/node_modules/@node-red/editor-client/locales/ru/infotips.json
@@ -0,0 +1,23 @@
+{
+ "info": {
+ "tip0" : "Вы можете удалить выбранные узлы или провода с {{core:delete-selection}}",
+ "tip1" : "Ищите узлы с {{core:search}}",
+ "tip2" : "{{core:toggle-sidebar}} показывает/скрывает эту боковою панель",
+ "tip3" : "Вы можете управлять палитрой узлов с помощью {{core:manage-palette}}",
+ "tip4" : "Узлы конфигурации потока перечисляются на боковой панели. Доступ к списку можно получить из меню или с помощью {{core:show-config-tab}}",
+ "tip5" : "Эти советы можно включить/выключить через настройки",
+ "tip6" : "Перемещайте выбранные узлы клавишами [влево] [вверх] [вниз] и [вправо]. Удерживайте [Shift], чтобы увеличить шаг",
+ "tip7" : "Перетаскивание узла на провод соединит его с обеих сторон",
+ "tip8" : "Экспортируйте выбранные узлы или текущую вкладку с {{core:show-export-dialog}}",
+ "tip9" : "Импортируйте поток, перетаскивая его JSON в редактор или с помощью {{core:show-import-dialog}}",
+ "tip10" : "Нажмите [Shift], [кликните] по порту узла и перетаскивайте подключенные провода на другой узел",
+ "tip11" : "Открывайте вкладку Информация с {{core:show-info-tab}} или вкладку Отладка с {{core:show-debug-tab}}",
+ "tip12" : "Нажмите [ctrl] и [кликните] в рабочей области, чтобы открыть диалог быстрого добавления",
+ "tip13" : "Нажмите [ctrl] и [кликните] по порту узла, чтобы начать быстрое подключение",
+ "tip14" : "Нажмите [Shift] и [кликните] по узлу, чтобы выбрать все соединенные узлы",
+ "tip15" : "Нажмите [ctrl] и [кликните] по узлу, чтобы добавить или убрать его из текущего выбора",
+ "tip16" : "Переключайте вкладки потока с помощью {{core:show-previous-tab}} и {{core:show-next-tab}}",
+ "tip17" : "Вы можете подтвердить изменения в редакторе узла с {{core:confirm-edit-tray}} или отменить их с {{core:cancel-edit-tray}}",
+ "tip18" : "Нажатие {{core:edit-selected-node}} откроет редактор первого узла в текущем выборе"
+ }
+}
diff --git a/packages/node_modules/@node-red/editor-client/locales/ru/jsonata.json b/packages/node_modules/@node-red/editor-client/locales/ru/jsonata.json
new file mode 100755
index 000000000..fd0ecf24c
--- /dev/null
+++ b/packages/node_modules/@node-red/editor-client/locales/ru/jsonata.json
@@ -0,0 +1,274 @@
+{
+ "$string": {
+ "args": "arg[, prettify]",
+ "desc": "Преобразует параметр `arg` в строку, используя следующие правила приведения:\n\n - Строки возвращаются как есть\n - Функции преобразуются в пустую строку\n - Числовая бесконечность и NaN выдают ошибку, поскольку они не могут быть представлены числом в JSON\n - Все остальные значения преобразуются в строку JSON с помощью функции `JSON.stringify`. Если значение `prettify` равно true, тогда будет сгенерирован \"отформатированный\" JSON. То есть каждое поле будет в отдельной строке, а строки будут иметь отступ в зависимости от глубины поля."
+ },
+ "$length": {
+ "args": "str",
+ "desc": "Возвращает количество символов в строке `str`. Выдается ошибка, если `str` не является строкой."
+ },
+ "$substring": {
+ "args": "str, start[, length]",
+ "desc": "Возвращает строку, содержащую символы из первого параметра `str`, начиная с позиции `start` (отсчет с нуля). Если указан `length`, то подстрока будет содержать максимум `length` символов. Если `start` отрицателен, то это означает количество символов с конца `str`."
+ },
+ "$substringBefore": {
+ "args": "str, chars",
+ "desc": "Возвращает подстроку перед первым вхождением последовательности символов `chars` в строке `str`. Если `str` не содержит `chars`, то он возвращает `str`."
+ },
+ "$substringAfter": {
+ "args": "str, chars",
+ "desc": "Возвращает подстроку после первого вхождения последовательности символов `chars` в строке `str`. Если `str` не содержит `chars`, то он возвращает `str`."
+ },
+ "$uppercase": {
+ "args": "str",
+ "desc": "Возвращает строку со всеми символами `str`, преобразованными в верхний регистр."
+ },
+ "$lowercase": {
+ "args": "str",
+ "desc": "Возвращает строку со всеми символами `str`, преобразованными в нижний регистр."
+ },
+ "$trim": {
+ "args": "str",
+ "desc": "Нормализует и обрезает все пробельные символы в строке `str`, выполняя следующие шаги:\n\n - Все символы табуляции, возврата каретки и перевода строки заменяются пробелами.\n- Последовательности пробелов сокращаются до одного пробела.\n- Пробелы в начале и конце `str` удаляются.\n\n Если `str` не указан (то есть эта функция вызывается без аргументов), тогда значение контекста используется в качестве значения `str`. Выдается ошибка, если `str` не является строкой."
+ },
+ "$contains": {
+ "args": "str, pattern",
+ "desc": "Возвращает `true`, если строка `str` соответствует шаблону `pattern`, в противном случае возвращает `false`. Если `str` не указан (то есть эта функция вызывается с одним аргументом), то значение контекста используется как значение `str`. Параметр `pattern` может быть либо строкой, либо регулярным выражением."
+ },
+ "$split": {
+ "args": "str[, separator][, limit]",
+ "desc": "Разбивает строку `str` на массив подстрок. Выдает ошибку, если `str` не является строкой. Необязательный параметр `separator` (строка или регулярное выражение) указывает символы внутри строки `str`, относительно которых она должна быть разделена. Если `separator` не указан, то предполагается пустая строка, и `str` будет разбит на массив из отдельных символов. Выдает ошибку, если `separator` не является строкой. Необязательный параметр `limit` - это число, указывающее максимальное количество подстрок для включения в результирующий массив. Любые дополнительные подстроки отбрасываются. Если `limit` не указан, то весь `str` разделяется без ограничения размера результирующего массива. Выдает ошибку, если `limit` не является положительным числом."
+ },
+ "$join": {
+ "args": "array[, separator]",
+ "desc": "Объединяет массив подстрок в одну объединенную строку, в которой каждая подстрока отделена необязательным параметром `separator`. Выдает ошибку, если входной массив содержит элемент, который не является строкой. Если `separator` не указан, то предполагается, что это пустая строка, то есть нет `separator` между подстроками. Выдает ошибку, если `separator` не является строкой."
+ },
+ "$match": {
+ "args": "str, pattern [, limit]",
+ "desc": "Применяет строку `str` к регулярному выражению `pattern` и возвращает массив объектов, каждый из которых содержит информацию о каждом совпадении внутри `str`."
+ },
+ "$replace": {
+ "args": "str, pattern, replacement [, limit]",
+ "desc": "Находит вхождения шаблона `pattern` в строке `str` и заменяет их на строку `replacement`.\n\nНеобязательный параметр `limit` - это максимальное количество замен."
+ },
+ "$now": {
+ "args":"",
+ "desc":"Создает отметку времени в формате, совместимом с ISO 8601, и возвращает ее как строку."
+ },
+ "$base64encode": {
+ "args":"string",
+ "desc":"Преобразует ASCII-строку в base-64 кодировку. Каждый символ в строке обрабатывается как байт двоичных данных. Для этого необходимо, чтобы все символы в строке находились в диапазоне от 0x00 до 0xFF, который включает все символы строк в URI-кодировке. Символы Юникода за пределами этого диапазона не поддерживаются."
+ },
+ "$base64decode": {
+ "args":"string",
+ "desc":"Преобразует байты в кодировке base-64 в строку, используя кодовую страницу Юникод UTF-8."
+ },
+ "$number": {
+ "args": "arg",
+ "desc": "Преобразует параметр `arg` в число с использованием следующих правил приведения:\n\n - Числа возвращаются как есть\n - Строки, которые содержат последовательность символов, представляющих допустимое в JSON число, преобразуются в это число\n - Все остальные значения вызывают ошибку."
+ },
+ "$abs": {
+ "args":"number",
+ "desc":"Возвращает абсолютное значение числа `number`."
+ },
+ "$floor": {
+ "args":"number",
+ "desc":"Возвращает значение числа `number`, округленное до ближайшего целого числа, которое меньше или равно `number`."
+ },
+ "$ceil": {
+ "args":"number",
+ "desc":"Возвращает значение числа `number`, округленное до ближайшего целого числа, которое больше или равно `number`."
+ },
+ "$round": {
+ "args":"number [, precision]",
+ "desc":"Возвращает значение числа `number`, округленное до количества десятичных знаков, указанных необязательным параметром `precision`."
+ },
+ "$power": {
+ "args":"base, exponent",
+ "desc":"Возвращает значение числа `base`, возведенное в степень `exponent`."
+ },
+ "$sqrt": {
+ "args":"number",
+ "desc":"Возвращает квадратный корень из значения числа `number`."
+ },
+ "$random": {
+ "args":"",
+ "desc":"Возвращает псевдослучайное число, которе больше или равно нулю и меньше единицы."
+ },
+ "$millis": {
+ "args":"",
+ "desc":"Возвращает число миллисекунд с начала Unix-эпохи (1 января 1970 года по Гринвичу) в виде числа. Все вызовы `$millis()` в пределах выполнения выражения будут возвращать одно и то же значение."
+ },
+ "$sum": {
+ "args": "array",
+ "desc": "Возвращает арифметическую сумму массива чисел `array`. Вызывает ошибку, если входной массив `array` содержит элемент, который не является числом."
+ },
+ "$max": {
+ "args": "array",
+ "desc": "Возвращает максимальное число в массиве чисел `array`. Вызывает ошибку, если входной массив `array` содержит элемент, который не является числом."
+ },
+ "$min": {
+ "args": "array",
+ "desc": "Возвращает минимальное число в массиве чисел `array`. Вызывает ошибку, если входной массив `array` содержит элемент, который не является числом."
+ },
+ "$average": {
+ "args": "array",
+ "desc": "Возвращает среднее значение массива чисел `array`. Вызывает ошибку, если входной массив `array` содержит элемент, который не является числом."
+ },
+ "$boolean": {
+ "args": "arg",
+ "desc": "Приводит аргумент к логическому значению, используя следующие правила: \n\n - Логические значения возвращаются как есть\n - пустая строка: `false`\n - непустая строка: `true`\n - число равное `0`: `false`\n - ненулевое число: `true`\n - `null` : `false`\n - пустой массив: `false`\n - массив, который содержит хотя бы один элемент, приводимый к `true`: `true`\n - массив, все элементы которого приводятся к `false`: `false`\n - пустой объект: `false`\n - непустой объект: `true`\n - функция: `false`"
+ },
+ "$not": {
+ "args": "arg",
+ "desc": "Возвращает логическое НЕ для аргумента. `arg` сначала приводится к логическому значению"
+ },
+ "$exists": {
+ "args": "arg",
+ "desc": "Возвращает логическое `true`, если выполнение выражения `arg` возвращает значение, или `false`, если выражение ничему не соответствует (например, путь к несуществующему полю)."
+ },
+ "$count": {
+ "args": "array",
+ "desc": "Возвращает количество элементов в массиве"
+ },
+ "$append": {
+ "args": "array, array",
+ "desc": "Присоединяет один массив к другому"
+ },
+ "$sort": {
+ "args":"array [, function]",
+ "desc":"Возвращает массив, содержащий все значения параметра `array`, но отсортированные по порядку.\n\nЕсли указан компаратор `function`, то это должна быть функция, которая принимает два параметра:\n\n`function(val1, val2)`\n\nЭту функцию вызывает алгоритм сортировки для сравнения двух значений: val1 и val2. Если значение val1 следует поместить после значения val2 в желаемом порядке сортировки, то функция должна возвращать логическое значение `true`, чтобы обозначить замену. В противном случае она должна вернуть `false`."
+ },
+ "$reverse": {
+ "args":"array",
+ "desc":"Возвращает массив, содержащий все значения из параметра `array`, но в обратном порядке."
+ },
+ "$shuffle": {
+ "args":"array",
+ "desc":"Возвращает массив, содержащий все значения из параметра `array`, но перемешанный в случайном порядке."
+ },
+ "$zip": {
+ "args":"array, ...",
+ "desc":"Возвращает свернутый (сжатый) массив, содержащий сгруппированные массивы значений из аргументов `array1` … `arrayN` по индексам 0, 1, 2...."
+ },
+ "$keys": {
+ "args": "object",
+ "desc": "Возвращает массив, содержащий ключи объекта. Если аргумент является массивом объектов, то возвращаемый массив содержит недублированный список всех ключей из всех объектов."
+ },
+ "$lookup": {
+ "args": "object, key",
+ "desc": "Возвращает значение, связанное с ключом в объекте. Если первый аргумент является массивом объектов, то просходит поиск по всем объектам в массиве, и возвращаются значения, связанные со всеми вхождениями ключа."
+ },
+ "$spread": {
+ "args": "object",
+ "desc": "Разбивает объект, содержащий пары ключ / значение, на массив объектов, каждый из которых имеет одну пару ключ / значение из входного объекта. Если параметр является массивом объектов, то результирующий массив содержит объект для каждой пары ключ / значение из каждого объекта предоставленного массива."
+ },
+ "$merge": {
+ "args": "array<object>",
+ "desc": "Объединяет массив объектов в один объект, содержащий все пары ключ / значение каждого из объектов входного массива. Если какой-либо из входных объектов содержит один и тот же ключ, возвращаемый объект будет содержать значение последнего в массиве. Вызывает ошибку, если входной массив содержит элемент, который не является объектом."
+ },
+ "$sift": {
+ "args":"object, function",
+ "desc":"Возвращает объект, который содержит только пары ключ / значение из параметра `object`, которые удовлетворяют предикату `function`, переданному в качестве второго параметра.\n\n`function`, которая передается в качестве второго параметра, должна иметь следующую сигнатуру:\n\n`function(value [, key [, object]])`"
+ },
+ "$each": {
+ "args":"object, function",
+ "desc":"Возвращает массив, который содержит значения, возвращаемые функцией `function` при применении к каждой паре ключ/значение из объекта `object`."
+ },
+ "$map": {
+ "args":"array, function",
+ "desc":"Возвращает массив, содержащий результаты применения функции `function` к каждому значению массива `array`.\n\nФункция `function`, указанная в качестве второго параметра, должна иметь следующую сигнатуру:\n\n`function(value [, index [, array]])`"
+ },
+ "$filter": {
+ "args":"array, function",
+ "desc":"Возвращает массив, содержащий только те значения из массива `array`, которые удовлетворяют предикату `function`.\n\nФункция `function`, указанная в качестве второго параметра, должна иметь следующую сигнатуру:\n\n`function(value [, index [, array]])`"
+ },
+ "$reduce": {
+ "args":"array, function [, init]",
+ "desc":"Возвращает агрегированное значение, полученное в результате последовательного применения функции `function` к каждому значению в массиве в сочетании с результатом от предыдущего применения функции.\n\nФункция должна принимать два аргумента и вести себя как инфиксный оператор между каждым значением в массиве `array`. Сигнатура `function` должна иметь форму: `myfunc($accumulator, $value[, $index[, $array]])`\n\nНеобязательный параметр `init` используется в качестве начального значения в агрегации."
+ },
+ "$flowContext": {
+ "args": "string[, string]",
+ "desc": "Извлекает свойство контекста потока.\n\nЭто функция от Node-RED."
+ },
+ "$globalContext": {
+ "args": "string[, string]",
+ "desc": "Извлекает свойство глобального контекста.\n\nЭто функция от Node-RED."
+ },
+ "$pad": {
+ "args": "string, width [, char]",
+ "desc": "Возвращает копию строки `string` с дополнительным заполнением, если необходимо, чтобы общее количество символов как минимум соответствовало абсолютному значению параметра `width`.\n\nЕсли `width` является положительным числом, то строка дополняется справа; если отрицательным, то дополняется слева.\n\nНеобязательный аргумент `char` указывает символ(ы) для заполнения. Если не указано, по умолчанию используется пробел."
+ },
+ "$fromMillis": {
+ "args": "number",
+ "desc": "Преобразует число, представляющее миллисекунды с начала Unix-эпохи (1 января 1970 года по Гринвичу), в строку отметки времени в формате ISO 8601."
+ },
+ "$formatNumber": {
+ "args": "number, picture [, options]",
+ "desc": "Преобразует число `number` в строку и форматирует ее в десятичное представление, как указано в строке `picture`.\n\nПоведение этой функции соответствует XPath/XQuery-функции fn:format-number, как определено в спецификация XPath F&O 3.1. Строка `picture` определяет, как форматируется число и имеет тот же синтаксис, что и fn:format-number.\n\nНеобязательный третий аргумент `options` используется для переопределения символов форматирования, специфичных для локали по умолчанию, таких как десятичный разделитель. Если аргумент указан, то это должен быть объект, содержащий пары имя/значение, указанные в разделе десятичного формата спецификации XPath F&O 3.1."
+ },
+ "$formatBase": {
+ "args": "number [, radix]",
+ "desc": "Преобразует число `number` в строку и форматирует ее в целое число, представленное в системе счисления, указанной аргументом `radix`. Если `radix` не указан, то по умолчанию используется десятичная. Значение 'radix` может быть от 2 до 36, в противном случае выдается ошибка."
+ },
+ "$toMillis": {
+ "args": "timestamp",
+ "desc": "Преобразует строку `timestamp` в формате ISO 8601 в число миллисекунд с начала Unix-эпохи (1 января 1970 года по Гринвичу). Вызывает ошибку, если строка в неправильном формате."
+ },
+ "$env": {
+ "args": "arg",
+ "desc": "Возвращает значение переменной среды.\n\nЭто функция от Node-RED."
+ },
+ "$eval": {
+ "args": "expr [, context]",
+ "desc": "Анализирует и исполняет строку `expr`, которая содержит JSON или выражение JSONata, используя текущий контекст в качестве контекста для исполнения."
+ },
+ "$formatInteger": {
+ "args": "number, picture",
+ "desc": "Преобразует число `number` в строку и форматирует ее в целочисленное представление, как указано в строке `picture`. Строка `picture` определяет, как форматируется число и имеет тот же синтаксис, что и `fn:format-integer` из спецификации XPath F&O 3.1."
+ },
+ "$parseInteger": {
+ "args": "string, picture",
+ "desc": "Разбирает содержимое строки `string` в целое число (как число JSON), используя формат, указанный в строке `picture`. Строковый параметр `picture` имеет тот же формат, что и `$formatInteger`."
+ },
+ "$error": {
+ "args": "[str]",
+ "desc": "Вызывает ошибку с сообщением. Необязательная строка `str` заменяет сообщение по умолчанию $error() function evaluated`"
+ },
+ "$assert": {
+ "args": "arg, str",
+ "desc": "Если значение `arg` равно true, функция возвращает значение undefined. Если значение `arg` равно false, генерируется исключение с `str` в качестве сообщения об исключении."
+ },
+ "$single": {
+ "args": "array, function",
+ "desc": "Возвращает одно-единственное значение из массива `array`, которое удовлетворяет предикату `function` (то есть когда `function` возвращает логическое `true` при передаче значения). Выдает исключение, если число подходящих значений не одно.\n\nФункция должна соответствовать следующей сигнатуре: `function(value [, index [, array]])` где value - элемент массива, index - позиция этого значения, а весь массив передается в качестве третьего аргумента"
+ },
+ "$encodeUrl": {
+ "args": "str",
+ "desc": "Кодирует компонент Uniform Resource Locator (URL), заменяя каждый экземпляр определенных символов одной, двумя, тремя или четырьмя escape-последовательностями, представляющими кодировку UTF-8 символа.\n\nПример: `$encodeUrlComponent(\"?x=test\")` => `\"%3Fx%3Dtest\"`"
+ },
+ "$encodeUrlComponent": {
+ "args": "str",
+ "desc": "Кодирует Uniform Resource Locator (URL), заменяя каждый экземпляр определенных символов одной, двумя, тремя или четырьмя escape-последовательностями, представляющими кодировку UTF-8 символа.\n\nПример: `$encodeUrl(\"https://mozilla.org/?x=шеллы\")` => `\"https://mozilla.org/?x=%D1%88%D0%B5%D0%BB%D0%BB%D1%8B\"`"
+ },
+ "$decodeUrl": {
+ "args": "str",
+ "desc": "Декодирует компонент Uniform Resource Locator (URL), ранее созданный с помощью encodeUrlComponent.\n\nПример: `$decodeUrlComponent(\"%3Fx%3Dtest\")` => `\"?x=test\"`"
+ },
+ "$decodeUrlComponent": {
+ "args": "str",
+ "desc": "Декодирует компонент Uniform Resource Locator (URL), ранее созданный с помощью encodeUrl. \n\nПример: `$decodeUrl(\"https://mozilla.org/?x=%D1%88%D0%B5%D0%BB%D0%BB%D1%8B\")` => `\"https://mozilla.org/?x=шеллы\"`"
+ },
+ "$distinct": {
+ "args": "array",
+ "desc": "Возвращает массив содержащий все элементы из массива `array`, с удаленными дупликатами"
+ },
+ "$type": {
+ "args": "value",
+ "desc": "Возвращает тип значения `value` в виде строки. Если `value` не определено, то будет возвращено `undefined`"
+ },
+ "$moment": {
+ "args": "[str]",
+ "desc": "Получает date объект, используя библиотеку Moment."
+ }
+}
diff --git a/packages/node_modules/@node-red/editor-client/package.json b/packages/node_modules/@node-red/editor-client/package.json
index bd5b7b657..5adb7deed 100644
--- a/packages/node_modules/@node-red/editor-client/package.json
+++ b/packages/node_modules/@node-red/editor-client/package.json
@@ -1,6 +1,6 @@
{
"name": "@node-red/editor-client",
- "version": "1.2.3",
+ "version": "1.2.7",
"license": "Apache-2.0",
"repository": {
"type": "git",
diff --git a/packages/node_modules/@node-red/editor-client/src/ace/bin/worker-nrjavascript.js b/packages/node_modules/@node-red/editor-client/src/ace/bin/worker-nrjavascript.js
index 0a767c5a0..f1a778f24 100644
--- a/packages/node_modules/@node-red/editor-client/src/ace/bin/worker-nrjavascript.js
+++ b/packages/node_modules/@node-red/editor-client/src/ace/bin/worker-nrjavascript.js
@@ -1 +1 @@
-"no use strict";!function(e){function t(e,t){var n=e,r="";while(n){var i=t[n];if(typeof i=="string")return i+r;if(i)return i.location.replace(/\/*$/,"/")+(r||i.main||i.name);if(i===!1)return"";var s=n.lastIndexOf("/");if(s===-1)break;r=n.substr(s)+r,n=n.slice(0,s)}return e}if(typeof e.window!="undefined"&&e.document)return;if(e.require&&e.define)return;e.console||(e.console=function(){var e=Array.prototype.slice.call(arguments,0);postMessage({type:"log",data:e})},e.console.error=e.console.warn=e.console.log=e.console.trace=e.console),e.window=e,e.ace=e,e.onerror=function(e,t,n,r,i){postMessage({type:"error",data:{message:e,data:i.data,file:t,line:n,col:r,stack:i.stack}})},e.normalizeModule=function(t,n){if(n.indexOf("!")!==-1){var r=n.split("!");return e.normalizeModule(t,r[0])+"!"+e.normalizeModule(t,r[1])}if(n.charAt(0)=="."){var i=t.split("/").slice(0,-1).join("/");n=(i?i+"/":"")+n;while(n.indexOf(".")!==-1&&s!=n){var s=n;n=n.replace(/^\.\//,"").replace(/\/\.\//,"/").replace(/[^\/]+\/\.\.\//,"")}}return n},e.require=function(r,i){i||(i=r,r=null);if(!i.charAt)throw new Error("worker.js require() accepts only (parentId, id) as arguments");i=e.normalizeModule(r,i);var s=e.require.modules[i];if(s)return s.initialized||(s.initialized=!0,s.exports=s.factory().exports),s.exports;if(!e.require.tlns)return console.log("unable to load "+i);var o=t(i,e.require.tlns);return o.slice(-3)!=".js"&&(o+=".js"),e.require.id=i,e.require.modules[i]={},importScripts(o),e.require(r,i)},e.require.modules={},e.require.tlns={},e.define=function(t,n,r){arguments.length==2?(r=n,typeof t!="string"&&(n=t,t=e.require.id)):arguments.length==1&&(r=t,n=[],t=e.require.id);if(typeof r!="function"){e.require.modules[t]={exports:r,initialized:!0};return}n.length||(n=["require","exports","module"]);var i=function(n){return e.require(t,n)};e.require.modules[t]={exports:{},factory:function(){var e=this,t=r.apply(this,n.slice(0,r.length).map(function(t){switch(t){case"require":return i;case"exports":return e.exports;case"module":return e;default:return i(t)}}));return t&&(e.exports=t),e}}},e.define.amd={},require.tlns={},e.initBaseUrls=function(t){for(var n in t)require.tlns[n]=t[n]},e.initSender=function(){var n=e.require("ace/lib/event_emitter").EventEmitter,r=e.require("ace/lib/oop"),i=function(){};return function(){r.implement(this,n),this.callback=function(e,t){postMessage({type:"call",id:t,data:e})},this.emit=function(e,t){postMessage({type:"event",name:e,data:t})}}.call(i.prototype),new i};var n=e.main=null,r=e.sender=null;e.onmessage=function(t){var i=t.data;if(i.event&&r)r._signal(i.event,i.data);else if(i.command)if(n[i.command])n[i.command].apply(n,i.args);else{if(!e[i.command])throw new Error("Unknown command:"+i.command);e[i.command].apply(e,i.args)}else if(i.init){e.initBaseUrls(i.tlns),r=e.sender=e.initSender();var s=require(i.module)[i.classname];n=e.main=new s(r)}}}(this),ace.define("ace/lib/oop",[],function(e,t,n){"use strict";t.inherits=function(e,t){e.super_=t,e.prototype=Object.create(t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}})},t.mixin=function(e,t){for(var n in t)e[n]=t[n];return e},t.implement=function(e,n){t.mixin(e,n)}}),ace.define("ace/range",[],function(e,t,n){"use strict";var r=function(e,t){return e.row-t.row||e.column-t.column},i=function(e,t,n,r){this.start={row:e,column:t},this.end={row:n,column:r}};(function(){this.isEqual=function(e){return this.start.row===e.start.row&&this.end.row===e.end.row&&this.start.column===e.start.column&&this.end.column===e.end.column},this.toString=function(){return"Range: ["+this.start.row+"/"+this.start.column+"] -> ["+this.end.row+"/"+this.end.column+"]"},this.contains=function(e,t){return this.compare(e,t)==0},this.compareRange=function(e){var t,n=e.end,r=e.start;return t=this.compare(n.row,n.column),t==1?(t=this.compare(r.row,r.column),t==1?2:t==0?1:0):t==-1?-2:(t=this.compare(r.row,r.column),t==-1?-1:t==1?42:0)},this.comparePoint=function(e){return this.compare(e.row,e.column)},this.containsRange=function(e){return this.comparePoint(e.start)==0&&this.comparePoint(e.end)==0},this.intersects=function(e){var t=this.compareRange(e);return t==-1||t==0||t==1},this.isEnd=function(e,t){return this.end.row==e&&this.end.column==t},this.isStart=function(e,t){return this.start.row==e&&this.start.column==t},this.setStart=function(e,t){typeof e=="object"?(this.start.column=e.column,this.start.row=e.row):(this.start.row=e,this.start.column=t)},this.setEnd=function(e,t){typeof e=="object"?(this.end.column=e.column,this.end.row=e.row):(this.end.row=e,this.end.column=t)},this.inside=function(e,t){return this.compare(e,t)==0?this.isEnd(e,t)||this.isStart(e,t)?!1:!0:!1},this.insideStart=function(e,t){return this.compare(e,t)==0?this.isEnd(e,t)?!1:!0:!1},this.insideEnd=function(e,t){return this.compare(e,t)==0?this.isStart(e,t)?!1:!0:!1},this.compare=function(e,t){return!this.isMultiLine()&&e===this.start.row?t1&&(r=t[1])):(t=O(at(t,!1,!1),String),n=function(e,n){return!I(t,n)}),rn(e,n,r)}),on=Yt(Vt,!0),gn=f||mn("Array"),bn=mn("Arguments"),wn=mn("Function"),En=mn("String"),Sn=mn("Number"),xn=mn("Date"),Tn=mn("RegExp"),Nn=mn("Error"),Cn=mn("Symbol"),kn=mn("Map"),Ln=mn("WeakMap"),An=mn("Set"),On=mn("WeakSet");(function(){bn(arguments)||(bn=function(e){return T(e,"callee")})})();var Mn=t.document&&t.document.childNodes;typeof /./!="function"&&typeof Int8Array!="object"&&typeof Mn!="function"&&(wn=function(e){return typeof e=="function"||!1});var Vn=Date.now||function(){return(new Date).getTime()},$n={"&":"&","<":"<",">":">",'"':""","'":"'","`":"`"},Jn=Qt($n),Qn=Kn($n),Gn=Kn(Jn),Zn=0,tr=v.templateSettings={evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g,escape:/<%-([\s\S]+?)%>/g},nr=/(.)^/,rr={"'":"'","\\":"\\","\r":"r","\n":"n","\u2028":"u2028","\u2029":"u2029"},ir=/\\|'|\r|\n|\u2028|\u2029/g,sr=function(e){return"\\"+rr[e]};A(["pop","push","reverse","shift","sort","splice","unshift"],function(e){var t=n[e];v.prototype[e]=function(){var n=this._wrapped;return t.apply(n,arguments),(e==="shift"||e==="splice")&&n.length===0&&delete n[0],ar(this,n)}}),A(["concat","join","slice"],function(e){var t=n[e];v.prototype[e]=function(){return ar(this,t.apply(this._wrapped,arguments))}}),v.prototype.value=function(){return this._wrapped},v.prototype.valueOf=v.prototype.toJSON=v.prototype.value,v.prototype.toString=function(){return String(this._wrapped)};var lr={"default":v,VERSION:m,iteratee:b,restArguments:E,each:A,forEach:A,map:O,collect:O,reduce:_,foldl:_,inject:_,reduceRight:D,foldr:D,find:P,detect:P,filter:H,select:H,reject:B,every:j,all:j,some:F,any:F,contains:I,includes:I,include:I,invoke:q,pluck:R,where:U,findWhere:z,max:W,min:X,shuffle:V,sample:$,sortBy:J,groupBy:Q,indexBy:G,countBy:Y,toArray:et,size:tt,partition:nt,first:rt,head:rt,take:rt,initial:it,last:st,rest:ot,tail:ot,drop:ot,compact:ut,flatten:ft,without:lt,uniq:ct,unique:ct,union:ht,intersection:pt,difference:dt,unzip:vt,zip:mt,object:gt,findIndex:bt,findLastIndex:wt,sortedIndex:Et,indexOf:xt,lastIndexOf:Tt,range:Nt,chunk:Ct,bind:Lt,partial:At,bindAll:Ot,memoize:Mt,delay:_t,defer:Dt,throttle:Pt,debounce:Ht,wrap:Bt,negate:jt,compose:Ft,after:It,before:qt,once:Rt,keys:Xt,allKeys:Vt,values:$t,mapObject:Jt,pairs:Kt,invert:Qt,functions:Gt,methods:Gt,extend:Zt,extendOwn:en,assign:en,findKey:tn,pick:rn,omit:sn,defaults:on,create:un,clone:an,tap:fn,isMatch:ln,isEqual:pn,isEmpty:dn,isElement:vn,isArray:gn,isObject:yn,isArguments:bn,isFunction:wn,isString:En,isNumber:Sn,isDate:xn,isRegExp:Tn,isError:Nn,isSymbol:Cn,isMap:kn,isWeakMap:Ln,isSet:An,isWeakSet:On,isFinite:_n,isNaN:Dn,isBoolean:Pn,isNull:Hn,isUndefined:Bn,has:jn,identity:Fn,constant:In,noop:qn,property:Rn,propertyOf:Un,matcher:zn,matches:zn,times:Wn,random:Xn,now:Vn,escape:Qn,unescape:Gn,result:Yn,uniqueId:er,templateSettings:tr,template:or,chain:ur,mixin:fr},cr=fr(lr);return cr._=cr,cr})}).call(this,typeof global!="undefined"?global:typeof self!="undefined"?self:typeof window!="undefined"?window:{})},{}],"/../../jshint/src/jshint.js":[function(e,t,n){var r=e("underscore");r.clone=e("lodash.clone");var i=e("events"),s=e("./vars.js"),o=e("./messages.js"),u=e("./lex.js").Lexer,a=e("./reg.js"),f=e("./state.js").state,l=e("./style.js"),c=e("./options.js"),h=e("./scope-manager.js"),p=e("./prod-params.js"),d=e("console-browserify"),v=function(){"use strict";function N(e,t,n){var i,s;return t?(i="",s=c.validNames):(i="unstable ",s=c.unstableNames),e=e.trim(),/^[+-]W\d{3}$/g.test(e)?!0:s.indexOf(e)===-1&&n.type!=="jslint"&&!r.has(c.removed,e)?(F("E001",n,i,e),!1):!0}function C(e){return Object.prototype.toString.call(e)==="[object String]"}function k(e,t){return e?!e.identifier||e.value!==t?!1:!0:!1}function L(e,t){if(!t.reserved)return!1;var n=t.meta;if(n&&n.isFutureReservedWord){if(f.inES5()){if(!n.es5)return!1;if(t.isProperty)return!1}}else if(n&&n.es5&&!f.inES5())return!1;return n&&n.strictOnly&&f.inES5()&&!f.option.strict&&!f.isStrict()?!1:t.id==="await"&&!(e&p.async)&&!f.option.module?!1:t.id==="yield"&&!(e&p.yield)?f.isStrict():!0}function A(e,t){return e.replace(/\{([^{}]*)\}/g,function(e,n){var r=t[n];return typeof r=="string"||typeof r=="number"?r:e})}function O(e,t){Object.keys(t).forEach(function(n){if(r.has(v.blacklist,n))return;e[n]=t[n]})}function M(){if(f.option.enforceall){for(var e in c.bool.enforcing)f.option[e]===undefined&&!c.noenforceall[e]&&(f.option[e]=!0);for(var t in c.bool.relaxing)f.option[t]===undefined&&(f.option[t]=!1)}}function D(){var e=null;M(),e=f.inferEsVersion(),e&&P("E059",f.tokens.next,"esversion",e),f.inES5()&&O(S,s.ecmaIdentifiers[5]),f.inES6()&&O(S,s.ecmaIdentifiers[6]),f.inES8()&&O(S,s.ecmaIdentifiers[8]),f.option.strict==="global"&&"globalstrict"in f.option&&P("E059",f.tokens.next,"strict","globalstrict"),f.option.module&&(f.inES6()||B("W134",f.tokens.next,"module",6)),f.option.regexpu&&(f.inES6()||B("W134",f.tokens.next,"regexpu",6)),f.option.couch&&O(S,s.couch),f.option.qunit&&O(S,s.qunit),f.option.rhino&&O(S,s.rhino),f.option.shelljs&&(O(S,s.shelljs),O(S,s.node)),f.option.typed&&O(S,s.typed),f.option.phantom&&O(S,s.phantom),f.option.prototypejs&&O(S,s.prototypejs),f.option.node&&(O(S,s.node),O(S,s.typed)),f.option.devel&&O(S,s.devel),f.option.dojo&&O(S,s.dojo),f.option.browser&&(O(S,s.browser),O(S,s.typed)),f.option.browserify&&(O(S,s.browser),O(S,s.typed),O(S,s.browserify)),f.option.nonstandard&&O(S,s.nonstandard),f.option.jasmine&&O(S,s.jasmine),f.option.jquery&&O(S,s.jquery),f.option.mootools&&O(S,s.mootools),f.option.worker&&O(S,s.worker),f.option.wsh&&O(S,s.wsh),f.option.yui&&O(S,s.yui),f.option.mocha&&O(S,s.mocha)}function P(e,t,n,r){var i=Math.floor(t.line/f.lines.length*100),s=o.errors[e].desc,u={name:"JSHintError",line:t.line,character:t.from,message:s+" ("+i+"% scanned).",raw:s,code:e,a:n,b:r};throw u.reason=A(s,u)+" ("+i+"% scanned).",u}function H(){var e=f.ignoredLines;if(r.isEmpty(e))return;v.errors=r.reject(v.errors,function(t){return e[t.line]})}function B(e,t,n,r,i,s){var u,a,l,c;if(/^W\d{3}$/.test(e)){if(f.ignored[e])return;c=o.warnings[e]}else/E\d{3}/.test(e)?c=o.errors[e]:/I\d{3}/.test(e)&&(c=o.info[e]);return t=t||f.tokens.next||{},t.id==="(end)"&&(t=f.tokens.curr),a=t.line,u=t.from,l={id:"(error)",raw:c.desc,code:c.code,evidence:f.lines[a-1]||"",line:a,character:u,scope:v.scope,a:n,b:r,c:i,d:s},l.reason=A(c.desc,l),v.errors.push(l),H(),v.errors.length>=f.option.maxerr&&P("E043",t),l}function j(e,t,n,r,i,s,o){return B(e,{line:t,from:n},r,i,s,o)}function F(e,t,n,r,i,s){B(e,t,n,r,i,s)}function I(e,t,n,r,i,s,o){return F(e,{line:t,from:n},r,i,s,o)}function q(e,t){v.internals.push({id:"(internal)",elem:e,token:t,code:t.value.replace(/([^\\])(\\*)\2\\n/g,"$1\n")})}function R(e,t){var i=e.body.split(",").map(function(e){return e.trim()}),s={};if(e.type==="falls through"){t.caseFallsThrough=!0;return}if(e.type==="globals"){i.forEach(function(t,n){var r=t.split(":"),o=r[0].trim();if(o==="-"||!o.length){if(n>0&&n===i.length-1)return;F("E002",e);return}o.charAt(0)==="-"?(o=o.slice(1),v.blacklist[o]=o,delete S[o]):s[o]=r.length>1&&r[1].trim()==="true"}),O(S,s);for(var o in s)r.has(s,o)&&(n[o]=e)}e.type==="exported"&&i.forEach(function(t,n){if(!t.length){if(n>0&&n===i.length-1)return;F("E002",e);return}f.funct["(scope)"].addExported(t)}),e.type==="members"&&(E=E||{},i.forEach(function(e){var t=e.charAt(0),n=e.charAt(e.length-1);t===n&&(t==='"'||t==="'")&&(e=e.substr(1,e.length-2).replace('\\"','"')),E[e]=!1}));var u=["maxstatements","maxparams","maxdepth","maxcomplexity","maxerr","maxlen","indent"];if(e.type==="jshint"||e.type==="jslint"||e.type==="jshint.unstable")i.forEach(function(t){var n=t.split(":"),r=n[0].trim(),i=n.length>1?n[1].trim():"",s;if(!N(r,e.type!=="jshint.unstable",e))return;if(u.indexOf(r)>=0){if(i!=="false"){s=+i;if(typeof s!="number"||!isFinite(s)||s<=0||Math.floor(s)!==s){F("E032",e,i);return}f.option[r]=s}else f.option[r]=r==="indent"?4:!1;return}if(r==="validthis"){if(f.funct["(global)"])return void F("E009");if(i!=="true"&&i!=="false")return void F("E002",e);f.option.validthis=i==="true";return}if(r==="quotmark"){switch(i){case"true":case"false":f.option.quotmark=i==="true";break;case"double":case"single":f.option.quotmark=i;break;default:F("E002",e)}return}if(r==="shadow"){switch(i){case"true":f.option.shadow=!0;break;case"outer":f.option.shadow="outer";break;case"false":case"inner":f.option.shadow="inner";break;default:F("E002",e)}return}if(r==="unused"){switch(i){case"true":f.option.unused=!0;break;case"false":f.option.unused=!1;break;case"vars":case"strict":f.option.unused=i;break;default:F("E002",e)}return}if(r==="latedef"){switch(i){case"true":f.option.latedef=!0;break;case"false":f.option.latedef=!1;break;case"nofunc":f.option.latedef="nofunc";break;default:F("E002",e)}return}if(r==="ignore"){switch(i){case"line":f.ignoredLines[e.line]=!0,H();break;default:F("E002",e)}return}if(r==="strict"){switch(i){case"true":f.option.strict=!0;break;case"false":f.option.strict=!1;break;case"global":case"implied":f.option.strict=i;break;default:F("E002",e)}return}r==="module"&&(qt(f.funct)||F("E055",e,"module"));if(r==="esversion"){switch(i){case"3":case"5":case"6":case"7":case"8":case"9":case"10":f.option.moz=!1,f.option.esversion=+i;break;case"2015":case"2016":case"2017":case"2018":case"2019":f.option.moz=!1,f.option.esversion=+i-2009;break;default:F("E002",e)}qt(f.funct)||F("E055",e,"esversion");return}var o=/^([+-])(W\d{3})$/g.exec(r);if(o){f.ignored[o[2]]=o[1]==="-";return}var a;if(i==="true"||i==="false"){e.type==="jslint"?(a=c.renamed[r]||r,f.option[a]=i==="true",c.inverted[a]!==undefined&&(f.option[a]=!f.option[a])):e.type==="jshint.unstable"?f.option.unstable[r]=i==="true":f.option[r]=i==="true";return}F("E002",e)}),D()}function U(e){var t=e||0,n=y.length,r;if(t=0;c--)if(u[c]!==f[c])return!1;for(c=u.length-1;c>=0;c--){l=u[c];if(!w(e[l],t[l],n,r))return!1}return!0}function x(e,t,n){w(e,t,!0)&&y(e,t,n,"notDeepStrictEqual",x)}function T(e,t){if(!e||!t)return!1;if(Object.prototype.toString.call(t)=="[object RegExp]")return t.test(e);try{if(e instanceof t)return!0}catch(n){}return Error.isPrototypeOf(t)?!1:t.call({},e)===!0}function N(e){var t;try{e()}catch(n){t=n}return t}function C(e,t,n,r){var i;if(typeof t!="function")throw new TypeError('"block" argument must be a function');typeof n=="string"&&(r=n,n=null),i=N(t),r=(n&&n.name?" ("+n.name+").":".")+(r?" "+r:"."),e&&!i&&y(i,n,"Missing expected exception"+r);var s=typeof r=="string",u=!e&&o.isError(i),a=!e&&i&&!n;(u&&s&&T(i,n)||a)&&y(i,n,"Got unwanted exception"+r);if(e&&i&&n&&!T(i,n)||!e&&i)throw i}function k(e,t){e||y(e,!0,t,"==",k)}var r=e("object-assign"),o=e("util/"),u=Object.prototype.hasOwnProperty,a=Array.prototype.slice,f=function(){return function(){}.name==="foo"}(),h=t.exports=b,p=/\s*function\s+([^\(\s]*)\s*/;h.AssertionError=function(t){this.name="AssertionError",this.actual=t.actual,this.expected=t.expected,this.operator=t.operator,t.message?(this.message=t.message,this.generatedMessage=!1):(this.message=g(this),this.generatedMessage=!0);var n=t.stackStartFunction||y;if(Error.captureStackTrace)Error.captureStackTrace(this,n);else{var r=new Error;if(r.stack){var i=r.stack,s=d(n),o=i.indexOf("\n"+s);if(o>=0){var u=i.indexOf("\n",o+1);i=i.substring(u+1)}this.stack=i}}},o.inherits(h.AssertionError,Error),h.fail=y,h.ok=b,h.equal=function(t,n,r){t!=n&&y(t,n,r,"==",h.equal)},h.notEqual=function(t,n,r){t==n&&y(t,n,r,"!=",h.notEqual)},h.deepEqual=function(t,n,r){w(t,n,!1)||y(t,n,r,"deepEqual",h.deepEqual)},h.deepStrictEqual=function(t,n,r){w(t,n,!0)||y(t,n,r,"deepStrictEqual",h.deepStrictEqual)},h.notDeepEqual=function(t,n,r){w(t,n,!1)&&y(t,n,r,"notDeepEqual",h.notDeepEqual)},h.notDeepStrictEqual=x,h.strictEqual=function(t,n,r){t!==n&&y(t,n,r,"===",h.strictEqual)},h.notStrictEqual=function(t,n,r){t===n&&y(t,n,r,"!==",h.notStrictEqual)},h.throws=function(e,t,n){C(!0,e,t,n)},h.doesNotThrow=function(e,t,n){C(!1,e,t,n)},h.ifError=function(e){if(e)throw e},h.strict=r(k,h,{equal:h.strictEqual,deepEqual:h.deepStrictEqual,notEqual:h.notStrictEqual,notDeepEqual:h.notDeepStrictEqual}),h.strict.strict=h.strict;var L=Object.keys||function(e){var t=[];for(var n in e)u.call(e,n)&&t.push(n);return t}}).call(this,typeof global!="undefined"?global:typeof self!="undefined"?self:typeof window!="undefined"?window:{})},{"object-assign":"/../node_modules/object-assign/index.js","util/":"/../node_modules/assert/node_modules/util/util.js"}],"/../node_modules/assert/node_modules/inherits/inherits_browser.js":[function(e,t,n){typeof Object.create=="function"?t.exports=function(t,n){t.super_=n,t.prototype=Object.create(n.prototype,{constructor:{value:t,enumerable:!1,writable:!0,configurable:!0}})}:t.exports=function(t,n){t.super_=n;var r=function(){};r.prototype=n.prototype,t.prototype=new r,t.prototype.constructor=t}},{}],"/../node_modules/assert/node_modules/util/support/isBufferBrowser.js":[function(e,t,n){t.exports=function(t){return t&&typeof t=="object"&&typeof t.copy=="function"&&typeof t.fill=="function"&&typeof t.readUInt8=="function"}},{}],"/../node_modules/assert/node_modules/util/util.js":[function(e,t,n){(function(t,r){function u(e,t){var r={seen:[],stylize:f};return arguments.length>=3&&(r.depth=arguments[2]),arguments.length>=4&&(r.colors=arguments[3]),y(t)?r.showHidden=t:t&&n._extend(r,t),T(r.showHidden)&&(r.showHidden=!1),T(r.depth)&&(r.depth=2),T(r.colors)&&(r.colors=!1),T(r.customInspect)&&(r.customInspect=!0),r.colors&&(r.stylize=a),c(r,e,r.depth)}function a(e,t){var n=u.styles[t];return n?"["+u.colors[n][0]+"m"+e+"["+u.colors[n][1]+"m":e}function f(e,t){return e}function l(e){var t={};return e.forEach(function(e,n){t[e]=!0}),t}function c(e,t,r){if(e.customInspect&&t&&A(t.inspect)&&t.inspect!==n.inspect&&(!t.constructor||t.constructor.prototype!==t)){var i=t.inspect(r,e);return S(i)||(i=c(e,i,r)),i}var s=h(e,t);if(s)return s;var o=Object.keys(t),u=l(o);e.showHidden&&(o=Object.getOwnPropertyNames(t));if(L(t)&&(o.indexOf("message")>=0||o.indexOf("description")>=0))return p(t);if(o.length===0){if(A(t)){var a=t.name?": "+t.name:"";return e.stylize("[Function"+a+"]","special")}if(N(t))return e.stylize(RegExp.prototype.toString.call(t),"regexp");if(k(t))return e.stylize(Date.prototype.toString.call(t),"date");if(L(t))return p(t)}var f="",y=!1,b=["{","}"];g(t)&&(y=!0,b=["[","]"]);if(A(t)){var w=t.name?": "+t.name:"";f=" [Function"+w+"]"}N(t)&&(f=" "+RegExp.prototype.toString.call(t)),k(t)&&(f=" "+Date.prototype.toUTCString.call(t)),L(t)&&(f=" "+p(t));if(o.length!==0||!!y&&t.length!=0){if(r<0)return N(t)?e.stylize(RegExp.prototype.toString.call(t),"regexp"):e.stylize("[Object]","special");e.seen.push(t);var E;return y?E=d(e,t,r,u,o):E=o.map(function(n){return v(e,t,r,u,n,y)}),e.seen.pop(),m(E,f,b)}return b[0]+f+b[1]}function h(e,t){if(T(t))return e.stylize("undefined","undefined");if(S(t)){var n="'"+JSON.stringify(t).replace(/^"|"$/g,"").replace(/'/g,"\\'").replace(/\\"/g,'"')+"'";return e.stylize(n,"string")}if(E(t))return e.stylize(""+t,"number");if(y(t))return e.stylize(""+t,"boolean");if(b(t))return e.stylize("null","null")}function p(e){return"["+Error.prototype.toString.call(e)+"]"}function d(e,t,n,r,i){var s=[];for(var o=0,u=t.length;o-1&&(s?u=u.split("\n").map(function(e){return" "+e}).join("\n").substr(2):u="\n"+u.split("\n").map(function(e){return" "+e}).join("\n"))):u=e.stylize("[Circular]","special"));if(T(o)){if(s&&i.match(/^\d+$/))return u;o=JSON.stringify(""+i),o.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)?(o=o.substr(1,o.length-2),o=e.stylize(o,"name")):(o=o.replace(/'/g,"\\'").replace(/\\"/g,'"').replace(/(^"|"$)/g,"'"),o=e.stylize(o,"string"))}return o+": "+u}function m(e,t,n){var r=0,i=e.reduce(function(e,t){return r++,t.indexOf("\n")>=0&&r++,e+t.replace(/\u001b\[\d\d?m/g,"").length+1},0);return i>60?n[0]+(t===""?"":t+"\n ")+" "+e.join(",\n ")+" "+n[1]:n[0]+t+" "+e.join(", ")+" "+n[1]}function g(e){return Array.isArray(e)}function y(e){return typeof e=="boolean"}function b(e){return e===null}function w(e){return e==null}function E(e){return typeof e=="number"}function S(e){return typeof e=="string"}function x(e){return typeof e=="symbol"}function T(e){return e===void 0}function N(e){return C(e)&&M(e)==="[object RegExp]"}function C(e){return typeof e=="object"&&e!==null}function k(e){return C(e)&&M(e)==="[object Date]"}function L(e){return C(e)&&(M(e)==="[object Error]"||e instanceof Error)}function A(e){return typeof e=="function"}function O(e){return e===null||typeof e=="boolean"||typeof e=="number"||typeof e=="string"||typeof e=="symbol"||typeof e=="undefined"}function M(e){return Object.prototype.toString.call(e)}function _(e){return e<10?"0"+e.toString(10):e.toString(10)}function P(){var e=new Date,t=[_(e.getHours()),_(e.getMinutes()),_(e.getSeconds())].join(":");return[e.getDate(),D[e.getMonth()],t].join(" ")}function H(e,t){return Object.prototype.hasOwnProperty.call(e,t)}var i=/%[sdj%]/g;n.format=function(e){if(!S(e)){var t=[];for(var n=0;n0&&u.length>s){u.warned=!0;var a=new Error("Possible EventEmitter memory leak detected. "+u.length+' "'+String(t)+'" listeners '+"added. Use emitter.setMaxListeners() to "+"increase limit.");a.name="MaxListenersExceededWarning",a.emitter=e,a.type=t,a.count=u.length,typeof console=="object"&&console.warn&&console.warn("%s: %s",a.name,a.message)}}}return e}function y(){if(!this.fired){this.target.removeListener(this.type,this.wrapFn),this.fired=!0;switch(arguments.length){case 0:return this.listener.call(this.target);case 1:return this.listener.call(this.target,arguments[0]);case 2:return this.listener.call(this.target,arguments[0],arguments[1]);case 3:return this.listener.call(this.target,arguments[0],arguments[1],arguments[2]);default:var e=new Array(arguments.length);for(var t=0;t1&&(r=t[1])):(t=O(at(t,!1,!1),String),n=function(e,n){return!I(t,n)}),rn(e,n,r)}),on=Yt(Vt,!0),gn=f||mn("Array"),bn=mn("Arguments"),wn=mn("Function"),En=mn("String"),Sn=mn("Number"),xn=mn("Date"),Tn=mn("RegExp"),Nn=mn("Error"),Cn=mn("Symbol"),kn=mn("Map"),Ln=mn("WeakMap"),An=mn("Set"),On=mn("WeakSet");(function(){bn(arguments)||(bn=function(e){return T(e,"callee")})})();var Mn=t.document&&t.document.childNodes;typeof /./!="function"&&typeof Int8Array!="object"&&typeof Mn!="function"&&(wn=function(e){return typeof e=="function"||!1});var Vn=Date.now||function(){return(new Date).getTime()},$n={"&":"&","<":"<",">":">",'"':""","'":"'","`":"`"},Jn=Qt($n),Qn=Kn($n),Gn=Kn(Jn),Zn=0,tr=v.templateSettings={evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g,escape:/<%-([\s\S]+?)%>/g},nr=/(.)^/,rr={"'":"'","\\":"\\","\r":"r","\n":"n","\u2028":"u2028","\u2029":"u2029"},ir=/\\|'|\r|\n|\u2028|\u2029/g,sr=function(e){return"\\"+rr[e]};A(["pop","push","reverse","shift","sort","splice","unshift"],function(e){var t=n[e];v.prototype[e]=function(){var n=this._wrapped;return t.apply(n,arguments),(e==="shift"||e==="splice")&&n.length===0&&delete n[0],ar(this,n)}}),A(["concat","join","slice"],function(e){var t=n[e];v.prototype[e]=function(){return ar(this,t.apply(this._wrapped,arguments))}}),v.prototype.value=function(){return this._wrapped},v.prototype.valueOf=v.prototype.toJSON=v.prototype.value,v.prototype.toString=function(){return String(this._wrapped)};var lr={"default":v,VERSION:m,iteratee:b,restArguments:E,each:A,forEach:A,map:O,collect:O,reduce:_,foldl:_,inject:_,reduceRight:D,foldr:D,find:P,detect:P,filter:H,select:H,reject:B,every:j,all:j,some:F,any:F,contains:I,includes:I,include:I,invoke:q,pluck:R,where:U,findWhere:z,max:W,min:X,shuffle:V,sample:$,sortBy:J,groupBy:Q,indexBy:G,countBy:Y,toArray:et,size:tt,partition:nt,first:rt,head:rt,take:rt,initial:it,last:st,rest:ot,tail:ot,drop:ot,compact:ut,flatten:ft,without:lt,uniq:ct,unique:ct,union:ht,intersection:pt,difference:dt,unzip:vt,zip:mt,object:gt,findIndex:bt,findLastIndex:wt,sortedIndex:Et,indexOf:xt,lastIndexOf:Tt,range:Nt,chunk:Ct,bind:Lt,partial:At,bindAll:Ot,memoize:Mt,delay:_t,defer:Dt,throttle:Pt,debounce:Ht,wrap:Bt,negate:jt,compose:Ft,after:It,before:qt,once:Rt,keys:Xt,allKeys:Vt,values:$t,mapObject:Jt,pairs:Kt,invert:Qt,functions:Gt,methods:Gt,extend:Zt,extendOwn:en,assign:en,findKey:tn,pick:rn,omit:sn,defaults:on,create:un,clone:an,tap:fn,isMatch:ln,isEqual:pn,isEmpty:dn,isElement:vn,isArray:gn,isObject:yn,isArguments:bn,isFunction:wn,isString:En,isNumber:Sn,isDate:xn,isRegExp:Tn,isError:Nn,isSymbol:Cn,isMap:kn,isWeakMap:Ln,isSet:An,isWeakSet:On,isFinite:_n,isNaN:Dn,isBoolean:Pn,isNull:Hn,isUndefined:Bn,has:jn,identity:Fn,constant:In,noop:qn,property:Rn,propertyOf:Un,matcher:zn,matches:zn,times:Wn,random:Xn,now:Vn,escape:Qn,unescape:Gn,result:Yn,uniqueId:er,templateSettings:tr,template:or,chain:ur,mixin:fr},cr=fr(lr);return cr._=cr,cr})}).call(this,typeof global!="undefined"?global:typeof self!="undefined"?self:typeof window!="undefined"?window:{})},{}],"/../../jshint/src/jshint.js":[function(e,t,n){var r=e("underscore");r.clone=e("lodash.clone");var i=e("events"),s=e("./vars.js"),o=e("./messages.js"),u=e("./lex.js").Lexer,a=e("./reg.js"),f=e("./state.js").state,l=e("./style.js"),c=e("./options.js"),h=e("./scope-manager.js"),p=e("./prod-params.js"),d=e("console-browserify"),v=function(){"use strict";function C(e,t,n){var i,s;return t?(i="",s=c.validNames):(i="unstable ",s=c.unstableNames),e=e.trim(),/^[+-]W\d{3}$/g.test(e)?!0:s.indexOf(e)===-1&&n.type!=="jslint"&&!r.has(c.removed,e)?(I("E001",n,i,e),!1):!0}function k(e){return Object.prototype.toString.call(e)==="[object String]"}function L(e,t){return e?!e.identifier||e.value!==t?!1:!0:!1}function A(e,t){if(!t.reserved)return!1;var n=t.meta;if(n&&n.isFutureReservedWord){if(f.inES5()){if(!n.es5)return!1;if(t.isProperty)return!1}}else if(n&&n.es5&&!f.inES5())return!1;return n&&n.strictOnly&&f.inES5()&&!f.option.strict&&!f.isStrict()?!1:t.id==="await"&&!(e&p.async)&&!f.option.module?!1:t.id==="yield"&&!(e&p.yield)?f.isStrict():!0}function O(e,t){return e.replace(/\{([^{}]*)\}/g,function(e,n){var r=t[n];return typeof r=="string"||typeof r=="number"?r:e})}function M(e,t){Object.keys(t).forEach(function(n){if(r.has(v.blacklist,n))return;e[n]=t[n]})}function D(){if(f.option.enforceall){for(var e in c.bool.enforcing)f.option[e]===undefined&&!c.noenforceall[e]&&(f.option[e]=!0);for(var t in c.bool.relaxing)f.option[t]===undefined&&(f.option[t]=!1)}}function P(){var e=null;D(),e=f.inferEsVersion(),e&&H("E059",f.tokens.next,"esversion",e),f.inES5()&&M(x,s.ecmaIdentifiers[5]),f.inES6()&&M(x,s.ecmaIdentifiers[6]),f.inES8()&&M(x,s.ecmaIdentifiers[8]),f.option.strict==="global"&&"globalstrict"in f.option&&H("E059",f.tokens.next,"strict","globalstrict"),f.option.module&&(f.inES6()||j("W134",f.tokens.next,"module",6)),f.option.regexpu&&(f.inES6()||j("W134",f.tokens.next,"regexpu",6)),f.option.couch&&M(x,s.couch),f.option.qunit&&M(x,s.qunit),f.option.rhino&&M(x,s.rhino),f.option.shelljs&&(M(x,s.shelljs),M(x,s.node)),f.option.typed&&M(x,s.typed),f.option.phantom&&M(x,s.phantom),f.option.prototypejs&&M(x,s.prototypejs),f.option.node&&(M(x,s.node),M(x,s.typed)),f.option.devel&&M(x,s.devel),f.option.dojo&&M(x,s.dojo),f.option.browser&&(M(x,s.browser),M(x,s.typed)),f.option.browserify&&(M(x,s.browser),M(x,s.typed),M(x,s.browserify)),f.option.nonstandard&&M(x,s.nonstandard),f.option.jasmine&&M(x,s.jasmine),f.option.jquery&&M(x,s.jquery),f.option.mootools&&M(x,s.mootools),f.option.worker&&M(x,s.worker),f.option.wsh&&M(x,s.wsh),f.option.yui&&M(x,s.yui),f.option.mocha&&M(x,s.mocha)}function H(e,t,n,r){var i=Math.floor(t.line/f.lines.length*100),s=o.errors[e].desc,u={name:"JSHintError",line:t.line,character:t.from,message:s+" ("+i+"% scanned).",raw:s,code:e,a:n,b:r};throw u.reason=O(s,u)+" ("+i+"% scanned).",u}function B(){var e=f.ignoredLines;if(r.isEmpty(e))return;v.errors=r.reject(v.errors,function(t){return e[t.line]})}function j(e,t,n,r,i,s){var u,a,l,c;if(/^W\d{3}$/.test(e)){if(f.ignored[e])return;c=o.warnings[e]}else/E\d{3}/.test(e)?c=o.errors[e]:/I\d{3}/.test(e)&&(c=o.info[e]);return t=t||f.tokens.next||{},t.id==="(end)"&&(t=f.tokens.curr),a=t.line,u=t.from,l={id:"(error)",raw:c.desc,code:c.code,evidence:f.lines[a-1]||"",line:a,character:u,scope:v.scope,a:n,b:r,c:i,d:s},l.reason=O(c.desc,l),v.errors.push(l),B(),v.errors.length>=f.option.maxerr&&(d.log(v.errors),H("E043",t)),l}function F(e,t,n,r,i,s,o){return j(e,{line:t,from:n},r,i,s,o)}function I(e,t,n,r,i,s){j(e,t,n,r,i,s)}function q(e,t,n,r,i,s,o){return I(e,{line:t,from:n},r,i,s,o)}function R(e,t){v.internals.push({id:"(internal)",elem:e,token:t,code:t.value.replace(/([^\\])(\\*)\2\\n/g,"$1\n")})}function U(e,t){var i=e.body.split(",").map(function(e){return e.trim()}),s={};if(e.type==="falls through"){t.caseFallsThrough=!0;return}if(e.type==="globals"){i.forEach(function(t,n){var r=t.split(":"),o=r[0].trim();if(o==="-"||!o.length){if(n>0&&n===i.length-1)return;I("E002",e);return}o.charAt(0)==="-"?(o=o.slice(1),v.blacklist[o]=o,delete x[o]):s[o]=r.length>1&&r[1].trim()==="true"}),M(x,s);for(var o in s)r.has(s,o)&&(n[o]=e)}e.type==="exported"&&i.forEach(function(t,n){if(!t.length){if(n>0&&n===i.length-1)return;I("E002",e);return}f.funct["(scope)"].addExported(t)}),e.type==="members"&&(S=S||{},i.forEach(function(e){var t=e.charAt(0),n=e.charAt(e.length-1);t===n&&(t==='"'||t==="'")&&(e=e.substr(1,e.length-2).replace('\\"','"')),S[e]=!1}));var u=["maxstatements","maxparams","maxdepth","maxcomplexity","maxerr","maxlen","indent"];if(e.type==="jshint"||e.type==="jslint"||e.type==="jshint.unstable")i.forEach(function(t){var n=t.split(":"),r=n[0].trim(),i=n.length>1?n[1].trim():"",s;if(!C(r,e.type!=="jshint.unstable",e))return;if(u.indexOf(r)>=0){if(i!=="false"){s=+i;if(typeof s!="number"||!isFinite(s)||s<=0||Math.floor(s)!==s){I("E032",e,i);return}f.option[r]=s}else f.option[r]=r==="indent"?4:!1;return}if(r==="validthis"){if(f.funct["(global)"])return void I("E009");if(i!=="true"&&i!=="false")return void I("E002",e);f.option.validthis=i==="true";return}if(r==="quotmark"){switch(i){case"true":case"false":f.option.quotmark=i==="true";break;case"double":case"single":f.option.quotmark=i;break;default:I("E002",e)}return}if(r==="shadow"){switch(i){case"true":f.option.shadow=!0;break;case"outer":f.option.shadow="outer";break;case"false":case"inner":f.option.shadow="inner";break;default:I("E002",e)}return}if(r==="unused"){switch(i){case"true":f.option.unused=!0;break;case"false":f.option.unused=!1;break;case"vars":case"strict":f.option.unused=i;break;default:I("E002",e)}return}if(r==="latedef"){switch(i){case"true":f.option.latedef=!0;break;case"false":f.option.latedef=!1;break;case"nofunc":f.option.latedef="nofunc";break;default:I("E002",e)}return}if(r==="ignore"){switch(i){case"line":f.ignoredLines[e.line]=!0,B();break;default:I("E002",e)}return}if(r==="strict"){switch(i){case"true":f.option.strict=!0;break;case"false":f.option.strict=!1;break;case"global":case"implied":f.option.strict=i;break;default:I("E002",e)}return}r==="module"&&(Rt(f.funct)||I("E055",e,"module"));if(r==="esversion"){switch(i){case"3":case"5":case"6":case"7":case"8":case"9":case"10":f.option.moz=!1,f.option.esversion=+i;break;case"2015":case"2016":case"2017":case"2018":case"2019":f.option.moz=!1,f.option.esversion=+i-2009;break;default:I("E002",e)}Rt(f.funct)||I("E055",e,"esversion");return}var o=/^([+-])(W\d{3})$/g.exec(r);if(o){f.ignored[o[2]]=o[1]==="-";return}var a;if(i==="true"||i==="false"){e.type==="jslint"?(a=c.renamed[r]||r,f.option[a]=i==="true",c.inverted[a]!==undefined&&(f.option[a]=!f.option[a])):e.type==="jshint.unstable"?f.option.unstable[r]=i==="true":f.option[r]=i==="true";return}I("E002",e)}),P()}function z(e){var t=e||0,n=b.length,r;if(t=0;c--)if(u[c]!==f[c])return!1;for(c=u.length-1;c>=0;c--){l=u[c];if(!w(e[l],t[l],n,r))return!1}return!0}function x(e,t,n){w(e,t,!0)&&y(e,t,n,"notDeepStrictEqual",x)}function T(e,t){if(!e||!t)return!1;if(Object.prototype.toString.call(t)=="[object RegExp]")return t.test(e);try{if(e instanceof t)return!0}catch(n){}return Error.isPrototypeOf(t)?!1:t.call({},e)===!0}function N(e){var t;try{e()}catch(n){t=n}return t}function C(e,t,n,r){var i;if(typeof t!="function")throw new TypeError('"block" argument must be a function');typeof n=="string"&&(r=n,n=null),i=N(t),r=(n&&n.name?" ("+n.name+").":".")+(r?" "+r:"."),e&&!i&&y(i,n,"Missing expected exception"+r);var s=typeof r=="string",u=!e&&o.isError(i),a=!e&&i&&!n;(u&&s&&T(i,n)||a)&&y(i,n,"Got unwanted exception"+r);if(e&&i&&n&&!T(i,n)||!e&&i)throw i}function k(e,t){e||y(e,!0,t,"==",k)}var r=e("object-assign"),o=e("util/"),u=Object.prototype.hasOwnProperty,a=Array.prototype.slice,f=function(){return function(){}.name==="foo"}(),h=t.exports=b,p=/\s*function\s+([^\(\s]*)\s*/;h.AssertionError=function(t){this.name="AssertionError",this.actual=t.actual,this.expected=t.expected,this.operator=t.operator,t.message?(this.message=t.message,this.generatedMessage=!1):(this.message=g(this),this.generatedMessage=!0);var n=t.stackStartFunction||y;if(Error.captureStackTrace)Error.captureStackTrace(this,n);else{var r=new Error;if(r.stack){var i=r.stack,s=d(n),o=i.indexOf("\n"+s);if(o>=0){var u=i.indexOf("\n",o+1);i=i.substring(u+1)}this.stack=i}}},o.inherits(h.AssertionError,Error),h.fail=y,h.ok=b,h.equal=function(t,n,r){t!=n&&y(t,n,r,"==",h.equal)},h.notEqual=function(t,n,r){t==n&&y(t,n,r,"!=",h.notEqual)},h.deepEqual=function(t,n,r){w(t,n,!1)||y(t,n,r,"deepEqual",h.deepEqual)},h.deepStrictEqual=function(t,n,r){w(t,n,!0)||y(t,n,r,"deepStrictEqual",h.deepStrictEqual)},h.notDeepEqual=function(t,n,r){w(t,n,!1)&&y(t,n,r,"notDeepEqual",h.notDeepEqual)},h.notDeepStrictEqual=x,h.strictEqual=function(t,n,r){t!==n&&y(t,n,r,"===",h.strictEqual)},h.notStrictEqual=function(t,n,r){t===n&&y(t,n,r,"!==",h.notStrictEqual)},h.throws=function(e,t,n){C(!0,e,t,n)},h.doesNotThrow=function(e,t,n){C(!1,e,t,n)},h.ifError=function(e){if(e)throw e},h.strict=r(k,h,{equal:h.strictEqual,deepEqual:h.deepStrictEqual,notEqual:h.notStrictEqual,notDeepEqual:h.notDeepStrictEqual}),h.strict.strict=h.strict;var L=Object.keys||function(e){var t=[];for(var n in e)u.call(e,n)&&t.push(n);return t}}).call(this,typeof global!="undefined"?global:typeof self!="undefined"?self:typeof window!="undefined"?window:{})},{"object-assign":"/../node_modules/object-assign/index.js","util/":"/../node_modules/assert/node_modules/util/util.js"}],"/../node_modules/assert/node_modules/inherits/inherits_browser.js":[function(e,t,n){typeof Object.create=="function"?t.exports=function(t,n){t.super_=n,t.prototype=Object.create(n.prototype,{constructor:{value:t,enumerable:!1,writable:!0,configurable:!0}})}:t.exports=function(t,n){t.super_=n;var r=function(){};r.prototype=n.prototype,t.prototype=new r,t.prototype.constructor=t}},{}],"/../node_modules/assert/node_modules/util/support/isBufferBrowser.js":[function(e,t,n){t.exports=function(t){return t&&typeof t=="object"&&typeof t.copy=="function"&&typeof t.fill=="function"&&typeof t.readUInt8=="function"}},{}],"/../node_modules/assert/node_modules/util/util.js":[function(e,t,n){(function(t,r){function u(e,t){var r={seen:[],stylize:f};return arguments.length>=3&&(r.depth=arguments[2]),arguments.length>=4&&(r.colors=arguments[3]),y(t)?r.showHidden=t:t&&n._extend(r,t),T(r.showHidden)&&(r.showHidden=!1),T(r.depth)&&(r.depth=2),T(r.colors)&&(r.colors=!1),T(r.customInspect)&&(r.customInspect=!0),r.colors&&(r.stylize=a),c(r,e,r.depth)}function a(e,t){var n=u.styles[t];return n?"["+u.colors[n][0]+"m"+e+"["+u.colors[n][1]+"m":e}function f(e,t){return e}function l(e){var t={};return e.forEach(function(e,n){t[e]=!0}),t}function c(e,t,r){if(e.customInspect&&t&&A(t.inspect)&&t.inspect!==n.inspect&&(!t.constructor||t.constructor.prototype!==t)){var i=t.inspect(r,e);return S(i)||(i=c(e,i,r)),i}var s=h(e,t);if(s)return s;var o=Object.keys(t),u=l(o);e.showHidden&&(o=Object.getOwnPropertyNames(t));if(L(t)&&(o.indexOf("message")>=0||o.indexOf("description")>=0))return p(t);if(o.length===0){if(A(t)){var a=t.name?": "+t.name:"";return e.stylize("[Function"+a+"]","special")}if(N(t))return e.stylize(RegExp.prototype.toString.call(t),"regexp");if(k(t))return e.stylize(Date.prototype.toString.call(t),"date");if(L(t))return p(t)}var f="",y=!1,b=["{","}"];g(t)&&(y=!0,b=["[","]"]);if(A(t)){var w=t.name?": "+t.name:"";f=" [Function"+w+"]"}N(t)&&(f=" "+RegExp.prototype.toString.call(t)),k(t)&&(f=" "+Date.prototype.toUTCString.call(t)),L(t)&&(f=" "+p(t));if(o.length!==0||!!y&&t.length!=0){if(r<0)return N(t)?e.stylize(RegExp.prototype.toString.call(t),"regexp"):e.stylize("[Object]","special");e.seen.push(t);var E;return y?E=d(e,t,r,u,o):E=o.map(function(n){return v(e,t,r,u,n,y)}),e.seen.pop(),m(E,f,b)}return b[0]+f+b[1]}function h(e,t){if(T(t))return e.stylize("undefined","undefined");if(S(t)){var n="'"+JSON.stringify(t).replace(/^"|"$/g,"").replace(/'/g,"\\'").replace(/\\"/g,'"')+"'";return e.stylize(n,"string")}if(E(t))return e.stylize(""+t,"number");if(y(t))return e.stylize(""+t,"boolean");if(b(t))return e.stylize("null","null")}function p(e){return"["+Error.prototype.toString.call(e)+"]"}function d(e,t,n,r,i){var s=[];for(var o=0,u=t.length;o-1&&(s?u=u.split("\n").map(function(e){return" "+e}).join("\n").substr(2):u="\n"+u.split("\n").map(function(e){return" "+e}).join("\n"))):u=e.stylize("[Circular]","special"));if(T(o)){if(s&&i.match(/^\d+$/))return u;o=JSON.stringify(""+i),o.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)?(o=o.substr(1,o.length-2),o=e.stylize(o,"name")):(o=o.replace(/'/g,"\\'").replace(/\\"/g,'"').replace(/(^"|"$)/g,"'"),o=e.stylize(o,"string"))}return o+": "+u}function m(e,t,n){var r=0,i=e.reduce(function(e,t){return r++,t.indexOf("\n")>=0&&r++,e+t.replace(/\u001b\[\d\d?m/g,"").length+1},0);return i>60?n[0]+(t===""?"":t+"\n ")+" "+e.join(",\n ")+" "+n[1]:n[0]+t+" "+e.join(", ")+" "+n[1]}function g(e){return Array.isArray(e)}function y(e){return typeof e=="boolean"}function b(e){return e===null}function w(e){return e==null}function E(e){return typeof e=="number"}function S(e){return typeof e=="string"}function x(e){return typeof e=="symbol"}function T(e){return e===void 0}function N(e){return C(e)&&M(e)==="[object RegExp]"}function C(e){return typeof e=="object"&&e!==null}function k(e){return C(e)&&M(e)==="[object Date]"}function L(e){return C(e)&&(M(e)==="[object Error]"||e instanceof Error)}function A(e){return typeof e=="function"}function O(e){return e===null||typeof e=="boolean"||typeof e=="number"||typeof e=="string"||typeof e=="symbol"||typeof e=="undefined"}function M(e){return Object.prototype.toString.call(e)}function _(e){return e<10?"0"+e.toString(10):e.toString(10)}function P(){var e=new Date,t=[_(e.getHours()),_(e.getMinutes()),_(e.getSeconds())].join(":");return[e.getDate(),D[e.getMonth()],t].join(" ")}function H(e,t){return Object.prototype.hasOwnProperty.call(e,t)}var i=/%[sdj%]/g;n.format=function(e){if(!S(e)){var t=[];for(var n=0;n0&&u.length>s){u.warned=!0;var a=new Error("Possible EventEmitter memory leak detected. "+u.length+' "'+String(t)+'" listeners '+"added. Use emitter.setMaxListeners() to "+"increase limit.");a.name="MaxListenersExceededWarning",a.emitter=e,a.type=t,a.count=u.length,typeof console=="object"&&console.warn&&console.warn("%s: %s",a.name,a.message)}}}return e}function y(){if(!this.fired){this.target.removeListener(this.type,this.wrapFn),this.fired=!0;switch(arguments.length){case 0:return this.listener.call(this.target);case 1:return this.listener.call(this.target,arguments[0]);case 2:return this.listener.call(this.target,arguments[0],arguments[1]);case 3:return this.listener.call(this.target,arguments[0],arguments[1],arguments[2]);default:var e=new Array(arguments.length);for(var t=0;tmsg.columns
to
- determine what to extract. If that is not present then all the object properties are ouput in the order in which they are found.payload
будет содержать данные, которые будут отправлены или получены из websocket. Слушатель может быть настроен на отправку или получение всего объекта сообщения в виде строки в формате JSON.",
+ "path2": "Путь будет относительно __path__
.",
+ "url1": "URL должен использовать схему ws:// или wss:// и указывать на существующего слушателя websocket.",
+ "url2": "По умолчанию payload
будет содержать данные, которые будут отправлены или получены из websocket. Клиент может быть настроен на отправку или получение всего объекта сообщения в виде строки в формате JSON."
+ },
+ "status": {
+ "connected": "подключен __count__",
+ "connected_plural_2": "подключено __count__",
+ "connected_plural_5": "подключено __count__"
+ },
+ "errors": {
+ "connect-error": "Произошла ошибка в соединении ws: ",
+ "send-error": "Произошла ошибка при отправке: ",
+ "missing-conf": "Отсутствует конфигурация сервера",
+ "duplicate-path": "Не может быть двух слушателей WebSocket по одному пути: __path__"
+ }
+ },
+ "watch": {
+ "watch": "наблюдение",
+ "label": {
+ "files": "Файл(ы)",
+ "recursive": "Наблюдать за подкаталогами рекурсивно"
+ },
+ "placeholder": {
+ "files": "Разделенный запятыми список файлов и/или каталогов"
+ },
+ "tip": "В Windows Вы должны использовать двойную обратную косую черту \\\\ в любых именах каталогов."
+ },
+ "tcpin": {
+ "label": {
+ "type": "Тип",
+ "output": "Вывод",
+ "port": "порт",
+ "host": "к хосту",
+ "payload": "данные",
+ "delimited": "разделены с",
+ "close-connection": "Закрывать соединение после отправки каждого сообщения?",
+ "decode-base64": "Расшифровать сообщение Base64?",
+ "server": "Сервер",
+ "return": "Возврат",
+ "ms": "мсек",
+ "chars": "симв."
+ },
+ "type": {
+ "listen": "Слушать",
+ "connect": "Подключиться",
+ "reply": "Ответить на TCP"
+ },
+ "output": {
+ "stream": "поток",
+ "single": "одиночный",
+ "buffer": "буфер",
+ "string": "строка",
+ "base64": "строка Base64"
+ },
+ "return": {
+ "timeout": "по истечении времени ожидания",
+ "character": "когда получен символ",
+ "number": "по получении N символов",
+ "never": "никогда - держать соединение открытым",
+ "immed": "немедленно - не ждать ответа"
+ },
+ "status": {
+ "connecting": "подключение к __host__:__port__",
+ "connected": "подключен к __host__:__port__",
+ "listening-port": "прослушивание порта __port__",
+ "stopped-listening": "прослушивание порта остановлено",
+ "connection-from": "соединение от __host__:__port__",
+ "connection-closed": "закрыто соединение от __host__:__port__",
+ "connections": "__count__ соединение",
+ "connections_plural_2": "__count__ соединения",
+ "connections_plural_5": "__count__ соединений"
+ },
+ "errors": {
+ "connection-lost": "потеряно соединение с __host__:__port__",
+ "timeout": "сокет на порту __port__ закрыт из-за превышения времени ожидания",
+ "cannot-listen": "невозможно прослушивать порт __port__, ошибка: __error__",
+ "error": "ошибка: __error__",
+
+ "socket-error": "ошибка сокета от __host__:__port__",
+ "no-host": "Хост и/или порт не установлены",
+ "connect-timeout": "превышено время ожидания подключения",
+ "connect-fail": "подключение не удалось"
+ }
+ },
+ "udp": {
+ "label": {
+ "listen": "Слушать",
+ "onport": "на порте",
+ "using": "используя",
+ "output": "Выход",
+ "group": "Группа",
+ "interface": "Локал. IF",
+ "send": "Отправлять",
+ "toport": "на порт",
+ "address": "Адрес",
+ "decode-base64": "Декодировать данные кодированные в Base64?"
+ },
+ "placeholder": {
+ "interface": "(необяз) локальный интерфейс или адрес для привязки",
+ "interfaceprompt": "(необяз) локальный интерфейс или адрес для привязки",
+ "address": "IP-адрес назначения"
+ },
+ "udpmsgs": "UDP сообщения",
+ "mcmsgs": "многоадресные сообщения",
+ "udpmsg": "UDP сообщение",
+ "bcmsg": "широковещательное сообщение",
+ "mcmsg": "многоадресное сообщение",
+ "output": {
+ "buffer": "буфер",
+ "string": "строка",
+ "base64": "строка Base64"
+ },
+ "bind": {
+ "random": "привязать к случайному локальному порту",
+ "local": "привязать к локальному порту",
+ "target": "привязать к целевому порту"
+ },
+ "tip": {
+ "in": "Совет: убедитесь, что Ваш брандмауэр разрешит вхождение данных.",
+ "out": "Совет: оставьте адрес и порт пустыми, если вы хотите установить их, используя msg.ip
и msg.port
.",
+ "port": "Уже используемые порты: "
+ },
+ "status": {
+ "listener-at": "слушатель udp на __host__:__port__",
+ "mc-group": "группа многоадресной рассылки udp __group__",
+ "listener-stopped": "слушатель udp остановлен",
+ "output-stopped": "выход udp остановлен",
+ "mc-ready": "многоадресная рассылка udp готова: __iface__:__outport__ -> __host__:__port__",
+ "bc-ready": "широковещательная рассылка udp готова: __outport__ -> __host__:__port__",
+ "ready": "udp готов: __outport__ -> __host__:__port__",
+ "ready-nolocal": "udp готов: __host__:__port__",
+ "re-use": "сокет повторного использования udp: __outport__ -> __host__:__port__"
+ },
+ "errors": {
+ "access-error": "Ошибка доступа UDP, Вам может потребоваться доступ с правами root для портов ниже 1024",
+ "error": "ошибка: __error__",
+ "bad-mcaddress": "Неверный адрес многоадресной рассылки",
+ "interface": "Должен быть IP-адрес требуемого интерфейса",
+ "ip-notset": "UDP: IP-адрес не установлен",
+ "port-notset": "UDP: порт не установлен",
+ "port-invalid": "UDP: номер порта недействителен",
+ "alreadyused": "UDP: порт __port__ уже используется",
+ "ifnotfound": "UDP: интерфейс __iface__ не найден"
+ }
+ },
+ "switch": {
+ "switch": "направить",
+ "label": {
+ "property": "Свойство",
+ "rule": "правило",
+ "repair": "воссоздать последовательность сообщений"
+ },
+ "previous": "предыдущее значение",
+ "and": "и",
+ "checkall": "проверка всех правил",
+ "stopfirst": "остановка после первого совпадения",
+ "ignorecase": "игнорировать регистр",
+ "rules": {
+ "btwn": "между",
+ "cont": "содержит",
+ "regex": "подходит под регул. выраж.",
+ "true": "равно true",
+ "false": "равно false",
+ "null": "равно null",
+ "nnull": "не равно null",
+ "istype": "является типом",
+ "empty": "пустое",
+ "nempty": "не пустое",
+ "head": "первые N",
+ "tail": "последние N",
+ "index": "индекс между",
+ "exp": "выраж. JSONata",
+ "else": "иначе",
+ "hask": "имеет ключ"
+ },
+ "errors": {
+ "invalid-expr": "Неверное выражение JSONata: __error__",
+ "too-many": "слишком много ожидающих сообщений в узле switch"
+ }
+ },
+ "change": {
+ "label": {
+ "rules": "Правила",
+ "rule": "правило",
+ "set": "установить __property__",
+ "change": "изменить __property__",
+ "delete": "удалить __property__",
+ "move": "переместить __property__",
+ "changeCount": "изменить: __count__ правило",
+ "changeCount_plural_2": "изменить: __count__ правила",
+ "changeCount_plural_5": "изменить: __count__ правил",
+ "regex": "Использовать регул. выражение"
+ },
+ "action": {
+ "set": "Установить",
+ "change": "Изменить",
+ "delete": "Удалить",
+ "move": "Переместить",
+ "to": "в",
+ "search": "Искать",
+ "replace": "Заменить на"
+ },
+ "errors": {
+ "invalid-from": "Неверное свойство 'from': __error__",
+ "invalid-json": "Неверное свойство JSON 'to'",
+ "invalid-expr": "Неверное выражение JSONata: __error__",
+ "no-override": "Невозможно установить свойство необъектного типа: __property__"
+ }
+ },
+ "range": {
+ "range": "Диапазон",
+ "label": {
+ "action": "Действие",
+ "inputrange": "Сопоставить входной диапазон",
+ "resultrange": "с целевым диапазоном",
+ "from": "от",
+ "to": "до",
+ "roundresult": "Округлять результат до ближайшего целого числа?"
+ },
+ "placeholder": {
+ "min": "напр. 0",
+ "maxin": "напр. 99",
+ "maxout": "напр. 255"
+ },
+ "scale": {
+ "payload": "Масштабировать msg-свойство",
+ "limit": "Масштабировать и ограничить целевым диапазоном",
+ "wrap": "Масштабировать и обернуть в целевой диапазон"
+ },
+ "tip": "Совет: этот узел работает ТОЛЬКО с числами.",
+ "errors": {
+ "notnumber": "Не число"
+ }
+ },
+ "csv": {
+ "label": {
+ "columns": "Столбцы",
+ "separator": "Разделитель",
+ "c2o": "Опции CSV -> Объект",
+ "o2c": "Опции Объект -> CSV",
+ "input": "Вход",
+ "skip-s": "Пропускать первые",
+ "skip-e": "строк(и)",
+ "firstrow": "первый ряд содержит имена столбцов",
+ "output": "Выход",
+ "includerow": "включать ряд с именами столбцов",
+ "newline": "Новая строка",
+ "usestrings": "разбирать числовые значения",
+ "include_empty_strings": "включать пустые строковые значения",
+ "include_null_values": "включать null-значения"
+ },
+ "placeholder": {
+ "columns": "имена столбцов через запятую"
+ },
+ "separator": {
+ "comma": "запятая",
+ "tab": "табуляция",
+ "space": "пробел",
+ "semicolon": "точка с запятой",
+ "colon": "двоеточие",
+ "hashtag": "хэштег",
+ "other": "другой..."
+ },
+ "output": {
+ "row": "сообщение для каждой строки",
+ "array": "одно сообщение [массив]"
+ },
+ "newline": {
+ "linux": "Linux (\\n)",
+ "mac": "Mac (\\r)",
+ "windows": "Windows (\\r\\n)"
+ },
+ "hdrout": {
+ "none": "никогда не отправлять заголовки столбцов",
+ "all": "всегда отправлять заголовки столбцов",
+ "once": "отправлять заголовки один раз, до msg.reset"
+ },
+ "errors": {
+ "csv_js": "Этот узел обрабатывает только CSV-строки или объекты js.",
+ "obj_csv": "Не указан шаблон столбцов для Объект -> CSV.",
+ "bad_csv": "Неверно сформированный CSV-файл - возможно, выход поврежден."
+ }
+ },
+ "html": {
+ "label": {
+ "select": "Селектор",
+ "output": "Выход",
+ "in": "в"
+ },
+ "output": {
+ "html": "html-контент элементов",
+ "text": "только текстовый контент элементов",
+ "attr": "объект любых атрибутов элементов"
+ },
+ "format": {
+ "single": "одним сообщением [массив]",
+ "multi": "по сообщению для каждого элемента"
+ }
+ },
+ "json": {
+ "errors": {
+ "dropped-object": "Данные не-объектного типа проигнорированы",
+ "dropped": "Данные неподдерживаемого типа проигнорированы",
+ "dropped-error": "Не удалось преобразовать данные",
+ "schema-error": "Ошибка схемы JSON",
+ "schema-error-compile": "Ошибка схемы JSON: не удалось скомпилировать схему"
+ },
+ "label": {
+ "o2j": "Опции Объект -> JSON",
+ "pretty": "Форматировать строку JSON",
+ "action": "Действие",
+ "property": "Свойство",
+ "actions": {
+ "toggle": "Преобразовывать в любую сторону",
+ "str":"Всегда преобразовывать в строку JSON",
+ "obj":"Всегда преобразовывать в объект JavaScript"
+ }
+ }
+ },
+ "yaml": {
+ "errors": {
+ "dropped-object": "Данные не-объектного типа проигнорированы",
+ "dropped": "Данные неподдерживаемого типа проигнорированы",
+ "dropped-error": "Не удалось преобразовать данные"
+ }
+ },
+ "xml": {
+ "label": {
+ "represent": "Имя свойства для атрибутов XML-тега",
+ "prefix": "Имя свойства для текстового содержимого тега",
+ "advanced": "Расширенные опции",
+ "x2o": "Опции XML -> Объект"
+ },
+ "errors": {
+ "xml_js": "Этот узел обрабатывает только строки XML или объекты JS."
+ }
+ },
+ "file": {
+ "label": {
+ "filename": "Имя файла",
+ "action": "Действие",
+ "addnewline": "Добавлять новую строку (\\n) к данным?",
+ "createdir": "Создать каталог, если он не существует?",
+ "outputas": "Выход",
+ "breakchunks": "Разбить файл на части",
+ "breaklines": "Разбить на строки",
+ "filelabel": "файл",
+ "sendError": "Отправлять сообщение при ошибке (устаревший режим)",
+ "encoding": "Кодировка",
+ "deletelabel": "удалить __file__",
+ "utf8String": "строка UTF8",
+ "binaryBuffer": "двоичный буфер"
+ },
+ "action": {
+ "append": "добавить в файл",
+ "overwrite": "перезаписать файл",
+ "delete": "удалить файл"
+ },
+ "output": {
+ "utf8": "одна ut8-строка",
+ "buffer": "один объект буфера",
+ "lines": "сообщение для каждой строчки",
+ "stream": "поток буферов"
+ },
+ "status": {
+ "wrotefile": "записано в файл: __file__",
+ "deletedfile": "удален файл: __file__",
+ "appendedfile": "добавлено в файл: __file__"
+ },
+ "encoding": {
+ "none": "по умолчанию",
+ "native": "Нативная",
+ "unicode": "Юникод",
+ "japanese": "Японская",
+ "chinese": "Китайская",
+ "korean": "Корейская",
+ "taiwan": "Тайвань/Гонконг",
+ "windows": "Кодовые страницы Windows",
+ "iso": "Кодовые страницы ISO",
+ "ibm": "Кодовые страницы IBM",
+ "mac": "Кодовые страницы Mac",
+ "koi8": "Кодовые страницы KOI8",
+ "misc": "Разные"
+ },
+ "errors": {
+ "nofilename": "Не указано имя файла",
+ "invaliddelete": "Предупреждение: неверное удаление. Пожалуйста, используйте конкретную опцию удаления в диалоге конфигурации.",
+ "deletefail": "не удалось удалить файл: __error__",
+ "writefail": "не удалось записать в файл: __error__",
+ "appendfail": "не удалось добавить в файл: __error__",
+ "createfail": "не удалось создать файл: __error__"
+ },
+ "tip": "Подсказка: имя файла должно быть абсолютным путем, иначе он будет относительно рабочего каталога процесса Node-RED."
+ },
+ "split": {
+ "split": "разделить",
+ "intro":"Разделить msg.payload
в зависимости от типа:",
+ "object":"Объект",
+ "objectSend":"Отправлять сообщение для каждой пары ключ/значение",
+ "strBuff":"Строка / Буфер",
+ "array":"Массив",
+ "splitUsing":"С помощью",
+ "splitLength":"Фикс. длина",
+ "stream":"Обрабатывать как поток сообщений",
+ "addname":" Копировать ключ в "
+ },
+ "join": {
+ "join": "соединить",
+ "mode": {
+ "mode": "Режим",
+ "auto": "автоматический",
+ "merge": "объединение последовательности",
+ "reduce": "агрегация последовательности",
+ "custom": "ручной"
+ },
+ "combine": "Объединить каждый",
+ "completeMessage": "полное сообщение",
+ "create": "чтобы создать",
+ "type": {
+ "string": "строку",
+ "array": "массив",
+ "buffer": "буфер",
+ "object": "объект ключей/значений",
+ "merged": "объединенный объект"
+ },
+ "using": "используя значение",
+ "key": "как ключ",
+ "joinedUsing": "соединяя с помощью",
+ "send": "Отправить сообщение:",
+ "afterCount": "после ряда частей сообщения",
+ "count": "кол-во",
+ "subsequent": "и каждое последующее сообщение.",
+ "afterTimeout": "по истечении времени с 1го сообщения",
+ "seconds": "сек",
+ "complete": "после сообщения с установленным свойством msg.complete
",
+ "tip": "В этом режиме предполагается, что этот узел либо связан с узлом split, либо полученные сообщения будут иметь правильно настроенное свойство msg.parts
.",
+ "too-many": "слишком много ожидающих сообщений в узле join",
+ "merge": {
+ "topics-label": "Объединенные темы",
+ "topics": "темы",
+ "topic": "тема",
+ "on-change": "Отправлять объединенное сообщение по прибытии новой темы"
+ },
+ "reduce": {
+ "exp": "Агрегирующее выражение",
+ "exp-value": "выражение",
+ "init": "Начальное значение",
+ "right": "Выполнять в обратном порядке (от последнего к первому)",
+ "fixup": "Исправляющее выражение"
+ },
+ "errors": {
+ "invalid-expr": "Неверное выражение JSONata: __error__",
+ "invalid-type": "Невозможно присоединить __error__ к буферу"
+ }
+ },
+ "sort" : {
+ "sort": "сортировать",
+ "target" : "Сортировать",
+ "seq" : "последовательность сообщений",
+ "key" : "Ключ",
+ "elem" : "значение элемента",
+ "order" : "Порядок",
+ "ascending" : "восходящий",
+ "descending" : "нисходящий",
+ "as-number" : "как число",
+ "invalid-exp" : "Неверное выражение JSONata в узле sort: __message__",
+ "too-many" : "Слишком много ожидающих сообщений в узле sort",
+ "clear" : "очистить ожидающее сообщение в узле sort"
+ },
+ "batch" : {
+ "batch": "группировать",
+ "mode": {
+ "label" : "Режим",
+ "num-msgs" : "Группировать по количеству сообщений",
+ "interval" : "Группировать по интервалу времени",
+ "concat" : "Объединять последовательности"
+ },
+ "count": {
+ "label" : "Количество сообщений",
+ "overlap" : "Совпадения",
+ "count" : "кол-во",
+ "invalid" : "Неверные количество и совпадения"
+ },
+ "interval": {
+ "label" : "Интервал",
+ "seconds" : "сек",
+ "empty" : "отправить пустое сообщение, когда сообщение не приходит"
+ },
+ "concat": {
+ "topics-label": "Темы",
+ "topic" : "тема"
+ },
+ "too-many" : "Слишком много ожидающих сообщений в узле batch",
+ "unexpected" : "неожиданный режим",
+ "no-parts" : "в сообщении нет свойства parts"
+ }
+}
diff --git a/packages/node_modules/@node-red/nodes/locales/ru/network/05-tls.html b/packages/node_modules/@node-red/nodes/locales/ru/network/05-tls.html
new file mode 100644
index 000000000..33c790ed0
--- /dev/null
+++ b/packages/node_modules/@node-red/nodes/locales/ru/network/05-tls.html
@@ -0,0 +1,19 @@
+
+
+
diff --git a/packages/node_modules/@node-red/nodes/locales/ru/network/06-httpproxy.html b/packages/node_modules/@node-red/nodes/locales/ru/network/06-httpproxy.html
new file mode 100644
index 000000000..85fe4eb81
--- /dev/null
+++ b/packages/node_modules/@node-red/nodes/locales/ru/network/06-httpproxy.html
@@ -0,0 +1,26 @@
+
+
+
diff --git a/packages/node_modules/@node-red/nodes/locales/ru/network/10-mqtt.html b/packages/node_modules/@node-red/nodes/locales/ru/network/10-mqtt.html
new file mode 100644
index 000000000..ce10a9515
--- /dev/null
+++ b/packages/node_modules/@node-red/nodes/locales/ru/network/10-mqtt.html
@@ -0,0 +1,113 @@
+
+
+
+
+
+
+
diff --git a/packages/node_modules/@node-red/nodes/locales/ru/network/21-httpin.html b/packages/node_modules/@node-red/nodes/locales/ru/network/21-httpin.html
new file mode 100644
index 000000000..2527c1599
--- /dev/null
+++ b/packages/node_modules/@node-red/nodes/locales/ru/network/21-httpin.html
@@ -0,0 +1,107 @@
+
+
+
+
+
diff --git a/packages/node_modules/@node-red/nodes/locales/ru/network/21-httprequest.html b/packages/node_modules/@node-red/nodes/locales/ru/network/21-httprequest.html
new file mode 100644
index 000000000..12662aacf
--- /dev/null
+++ b/packages/node_modules/@node-red/nodes/locales/ru/network/21-httprequest.html
@@ -0,0 +1,106 @@
+
+
+
diff --git a/packages/node_modules/@node-red/nodes/locales/ru/network/22-websocket.html b/packages/node_modules/@node-red/nodes/locales/ru/network/22-websocket.html
new file mode 100644
index 000000000..243f71107
--- /dev/null
+++ b/packages/node_modules/@node-red/nodes/locales/ru/network/22-websocket.html
@@ -0,0 +1,52 @@
+
+
+
+
+
+
+
+
+
diff --git a/packages/node_modules/@node-red/nodes/locales/ru/network/31-tcpin.html b/packages/node_modules/@node-red/nodes/locales/ru/network/31-tcpin.html
new file mode 100644
index 000000000..f23bd974a
--- /dev/null
+++ b/packages/node_modules/@node-red/nodes/locales/ru/network/31-tcpin.html
@@ -0,0 +1,57 @@
+
+
+
+
+
+
+
diff --git a/packages/node_modules/@node-red/nodes/locales/ru/network/32-udp.html b/packages/node_modules/@node-red/nodes/locales/ru/network/32-udp.html
new file mode 100644
index 000000000..2a1026e8b
--- /dev/null
+++ b/packages/node_modules/@node-red/nodes/locales/ru/network/32-udp.html
@@ -0,0 +1,42 @@
+
+
+
+
+
diff --git a/packages/node_modules/@node-red/nodes/locales/ru/parsers/70-CSV.html b/packages/node_modules/@node-red/nodes/locales/ru/parsers/70-CSV.html
new file mode 100644
index 000000000..de94a1fd8
--- /dev/null
+++ b/packages/node_modules/@node-red/nodes/locales/ru/parsers/70-CSV.html
@@ -0,0 +1,72 @@
+
+
+
diff --git a/packages/node_modules/@node-red/nodes/locales/ru/parsers/70-HTML.html b/packages/node_modules/@node-red/nodes/locales/ru/parsers/70-HTML.html
new file mode 100644
index 000000000..30a5a2366
--- /dev/null
+++ b/packages/node_modules/@node-red/nodes/locales/ru/parsers/70-HTML.html
@@ -0,0 +1,40 @@
+
+
+
diff --git a/packages/node_modules/@node-red/nodes/locales/ru/parsers/70-JSON.html b/packages/node_modules/@node-red/nodes/locales/ru/parsers/70-JSON.html
new file mode 100644
index 000000000..0b663ed05
--- /dev/null
+++ b/packages/node_modules/@node-red/nodes/locales/ru/parsers/70-JSON.html
@@ -0,0 +1,56 @@
+
+
+
diff --git a/packages/node_modules/@node-red/nodes/locales/ru/parsers/70-XML.html b/packages/node_modules/@node-red/nodes/locales/ru/parsers/70-XML.html
new file mode 100644
index 000000000..ed6fe6c44
--- /dev/null
+++ b/packages/node_modules/@node-red/nodes/locales/ru/parsers/70-XML.html
@@ -0,0 +1,60 @@
+
+
+
diff --git a/packages/node_modules/@node-red/nodes/locales/ru/parsers/70-YAML.html b/packages/node_modules/@node-red/nodes/locales/ru/parsers/70-YAML.html
new file mode 100644
index 000000000..b0049330b
--- /dev/null
+++ b/packages/node_modules/@node-red/nodes/locales/ru/parsers/70-YAML.html
@@ -0,0 +1,38 @@
+
+
+
diff --git a/packages/node_modules/@node-red/nodes/locales/ru/sequence/17-split.html b/packages/node_modules/@node-red/nodes/locales/ru/sequence/17-split.html
new file mode 100644
index 000000000..cf7397157
--- /dev/null
+++ b/packages/node_modules/@node-red/nodes/locales/ru/sequence/17-split.html
@@ -0,0 +1,175 @@
+
+
+
+
+
diff --git a/packages/node_modules/@node-red/nodes/locales/ru/sequence/18-sort.html b/packages/node_modules/@node-red/nodes/locales/ru/sequence/18-sort.html
new file mode 100644
index 000000000..efd183854
--- /dev/null
+++ b/packages/node_modules/@node-red/nodes/locales/ru/sequence/18-sort.html
@@ -0,0 +1,56 @@
+
+
+
diff --git a/packages/node_modules/@node-red/nodes/locales/ru/sequence/19-batch.html b/packages/node_modules/@node-red/nodes/locales/ru/sequence/19-batch.html
new file mode 100644
index 000000000..ecda13154
--- /dev/null
+++ b/packages/node_modules/@node-red/nodes/locales/ru/sequence/19-batch.html
@@ -0,0 +1,45 @@
+
+
+
diff --git a/packages/node_modules/@node-red/nodes/locales/ru/storage/10-file.html b/packages/node_modules/@node-red/nodes/locales/ru/storage/10-file.html
new file mode 100644
index 000000000..e1c8bf456
--- /dev/null
+++ b/packages/node_modules/@node-red/nodes/locales/ru/storage/10-file.html
@@ -0,0 +1,86 @@
+
+
+
+
+
diff --git a/packages/node_modules/@node-red/nodes/locales/ru/storage/23-watch.html b/packages/node_modules/@node-red/nodes/locales/ru/storage/23-watch.html
new file mode 100644
index 000000000..7960f3113
--- /dev/null
+++ b/packages/node_modules/@node-red/nodes/locales/ru/storage/23-watch.html
@@ -0,0 +1,39 @@
+
+
+
diff --git a/packages/node_modules/@node-red/nodes/package.json b/packages/node_modules/@node-red/nodes/package.json
index 1e0c2ab5d..25b277921 100644
--- a/packages/node_modules/@node-red/nodes/package.json
+++ b/packages/node_modules/@node-red/nodes/package.json
@@ -1,6 +1,6 @@
{
"name": "@node-red/nodes",
- "version": "1.2.3",
+ "version": "1.2.7",
"license": "Apache-2.0",
"repository": {
"type": "git",
@@ -23,7 +23,7 @@
"cookie": "0.4.1",
"cors": "2.8.5",
"cron": "1.7.2",
- "denque": "1.4.1",
+ "denque": "1.5.0",
"fs-extra": "8.1.0",
"fs.notify": "0.0.4",
"hash-sum": "2.0.0",
@@ -31,9 +31,9 @@
"is-utf8": "0.2.1",
"js-yaml": "3.14.0",
"media-typer": "1.1.0",
- "mqtt": "4.2.4",
+ "mqtt": "4.2.6",
"multer": "1.4.2",
- "mustache": "4.0.1",
+ "mustache": "4.1.0",
"on-headers": "1.0.2",
"raw-body": "2.4.1",
"request": "2.88.0",
diff --git a/packages/node_modules/@node-red/registry/lib/installer.js b/packages/node_modules/@node-red/registry/lib/installer.js
index 7e15e5a94..03f9eb11c 100644
--- a/packages/node_modules/@node-red/registry/lib/installer.js
+++ b/packages/node_modules/@node-red/registry/lib/installer.js
@@ -35,7 +35,7 @@ var settings;
const moduleRe = /^(@[^/@]+?[/])?[^/@]+?$/;
const slashRe = process.platform === "win32" ? /\\|[/]/ : /[/]/;
const pkgurlRe = /^(https?|git(|\+https?|\+ssh|\+file)):\/\//;
-const localtgzRe = /^\/.+tgz$/;
+const localtgzRe = /^([a-zA-Z]:|\/).+tgz$/;
function init(runtime) {
events = runtime.events;
@@ -136,7 +136,7 @@ function installModule(module,version,url) {
}
var installDir = settings.userDir || process.env.NODE_RED_HOME || ".";
- var args = ['install','--no-audit','--no-update-notifier','--no-fund','--save','--save-prefix="~"','--production',installName];
+ var args = ['install','--no-audit','--no-update-notifier','--no-fund','--save','--save-prefix=~','--production',installName];
log.trace(npmCommand + JSON.stringify(args));
exec.run(npmCommand,args,{
cwd: installDir
diff --git a/packages/node_modules/@node-red/registry/package.json b/packages/node_modules/@node-red/registry/package.json
index d31f41319..74816922e 100644
--- a/packages/node_modules/@node-red/registry/package.json
+++ b/packages/node_modules/@node-red/registry/package.json
@@ -1,6 +1,6 @@
{
"name": "@node-red/registry",
- "version": "1.2.3",
+ "version": "1.2.7",
"license": "Apache-2.0",
"main": "./lib/index.js",
"repository": {
@@ -16,10 +16,10 @@
}
],
"dependencies": {
- "@node-red/util": "1.2.3",
+ "@node-red/util": "1.2.7",
"semver": "6.3.0",
"tar": "6.0.5",
- "uglify-js": "3.11.4",
+ "uglify-js": "3.12.4",
"when": "3.7.8"
}
}
diff --git a/packages/node_modules/@node-red/runtime/lib/api/comms.js b/packages/node_modules/@node-red/runtime/lib/api/comms.js
index 0652a651b..55789b806 100644
--- a/packages/node_modules/@node-red/runtime/lib/api/comms.js
+++ b/packages/node_modules/@node-red/runtime/lib/api/comms.js
@@ -38,12 +38,20 @@ function handleCommsEvent(event) {
publish(event.topic,event.data,event.retain);
}
function handleStatusEvent(event) {
- var status = {
- text: event.status.text,
- fill: event.status.fill,
- shape: event.status.shape
- };
- publish("status/"+event.id,status,true);
+ if (!event.status) {
+ delete retained["status/"+event.id]
+ } else if (!event.status.text && !event.status.fill && !event.status.shape) {
+ if (retained["status/"+event.id]) {
+ publish("status/"+event.id,{},false);
+ }
+ } else {
+ var status = {
+ text: event.status.text,
+ fill: event.status.fill,
+ shape: event.status.shape
+ };
+ publish("status/"+event.id,status,true);
+ }
}
function handleRuntimeEvent(event) {
runtime.log.trace("runtime event: "+JSON.stringify(event));
diff --git a/packages/node_modules/@node-red/runtime/lib/flows/Flow.js b/packages/node_modules/@node-red/runtime/lib/flows/Flow.js
index 20a4f6c3d..325639f64 100644
--- a/packages/node_modules/@node-red/runtime/lib/flows/Flow.js
+++ b/packages/node_modules/@node-red/runtime/lib/flows/Flow.js
@@ -319,6 +319,11 @@ class Flow {
node.error(err);
}
}
+ if (removedMap[stopList[i]]) {
+ events.emit("node-status",{
+ id: node.id
+ });
+ }
}
}
return Promise.all(promises);
@@ -465,8 +470,8 @@ class Flow {
}
// console.log("HE",logMessage);
var count = 1;
- if (msg && msg.hasOwnProperty("error") && msg.error !== null) {
- if (msg.error.hasOwnProperty("source") && msg.error.source !== null) {
+ if (msg && msg.hasOwnProperty("error") && msg.error) {
+ if (msg.error.hasOwnProperty("source") && msg.error.source) {
if (msg.error.source.id === node.id) {
count = msg.error.source.count+1;
if (count === 10) {
diff --git a/packages/node_modules/@node-red/runtime/lib/flows/Subflow.js b/packages/node_modules/@node-red/runtime/lib/flows/Subflow.js
index 8b78cad17..d8514dac4 100644
--- a/packages/node_modules/@node-red/runtime/lib/flows/Subflow.js
+++ b/packages/node_modules/@node-red/runtime/lib/flows/Subflow.js
@@ -18,6 +18,7 @@ const clone = require("clone");
const Flow = require('./Flow').Flow;
const context = require('../nodes/context');
const util = require("util");
+const events = require("../events");
const redUtil = require("@node-red/util").util;
const flowUtil = require("./util");
@@ -116,8 +117,8 @@ class Subflow extends Flow {
this.node_map = node_map;
this.path = parent.path+"/"+(subflowInstance._alias||subflowInstance.id);
- this.templateCredentials = credentials.get(subflowDef.id);
- this.instanceCredentials = credentials.get(this.id);
+ this.templateCredentials = credentials.get(subflowDef.id) || {};
+ this.instanceCredentials = credentials.get(this.id) || {};
var env = [];
if (this.subflowDef.env) {
@@ -308,7 +309,26 @@ class Subflow extends Flow {
super.start(diff);
}
+ /**
+ * Stop this subflow.
+ * The `stopList` argument helps define what needs to be stopped in the case
+ * of a modified-nodes/flows type deploy.
+ * @param {[type]} stopList [description]
+ * @param {[type]} removedList [description]
+ * @return {[type]} [description]
+ */
+ stop(stopList, removedList) {
+ const nodes = Object.keys(this.activeNodes);
+ return super.stop(stopList, removedList).then(res => {
+ nodes.forEach(id => {
+ events.emit("node-status",{
+ id: id
+ });
+ })
+ return res;
+ })
+ }
/**
* Get environment variable of subflow
* @param {String} name name of env var
diff --git a/packages/node_modules/@node-red/runtime/lib/storage/localfilesystem/library.js b/packages/node_modules/@node-red/runtime/lib/storage/localfilesystem/library.js
index 04701321f..22f01c978 100644
--- a/packages/node_modules/@node-red/runtime/lib/storage/localfilesystem/library.js
+++ b/packages/node_modules/@node-red/runtime/lib/storage/localfilesystem/library.js
@@ -102,7 +102,8 @@ function getLibraryEntry(type,path) {
var files = [];
fns.sort().filter(function(fn) {
var fullPath = fspath.join(path,fn);
- var absoluteFullPath = fspath.join(root,fullPath);
+ // we use fs.realpathSync to also resolve Symbolic Link
+ var absoluteFullPath = fs.realpathSync(fspath.join(root,fullPath));
if (fn[0] != ".") {
var stats = fs.lstatSync(absoluteFullPath);
if (stats.isDirectory()) {
diff --git a/packages/node_modules/@node-red/runtime/locales/ja/runtime.json b/packages/node_modules/@node-red/runtime/locales/ja/runtime.json
index ff871e3c2..6f3d07c6d 100644
--- a/packages/node_modules/@node-red/runtime/locales/ja/runtime.json
+++ b/packages/node_modules/@node-red/runtime/locales/ja/runtime.json
@@ -169,6 +169,7 @@
"error-invalid-default-module": "デフォルトコンテキストストアが不明: '__storage__'",
"unknown-store": "不明なコンテキストストア '__name__' が指定されました。デフォルトストアを使用します。",
"localfilesystem": {
+ "invalid-json": "コンテキストファイル '__file__' のJSONが不正",
"error-circular": "コンテキスト __scope__ は永続化できない循環参照を含んでいます",
"error-write": "コンテキスト書込みエラー: __message__"
}
diff --git a/packages/node_modules/@node-red/runtime/locales/ru/runtime.json b/packages/node_modules/@node-red/runtime/locales/ru/runtime.json
new file mode 100644
index 000000000..75a62b89e
--- /dev/null
+++ b/packages/node_modules/@node-red/runtime/locales/ru/runtime.json
@@ -0,0 +1,186 @@
+{
+ "runtime": {
+ "welcome": "Добро пожаловать в Node-RED",
+ "version": "Версия __component__: __version__",
+ "unsupported_version": "Неподдерживаемая версия __component__. Требуется: __requires__ Найдено: __version__",
+ "paths": {
+ "settings": "Файл настроек : __path__",
+ "httpStatic": "HTTP статика : __path__"
+ }
+ },
+
+ "server": {
+ "loading": "Загрузка узлов палитры",
+ "palette-editor": {
+ "disabled": "Редактор палитры отключен : пользовательские настройки",
+ "npm-not-found": "Редактор палитры отключен : команда npm не найдена",
+ "npm-too-old": "Редактор палитры отключен : устаревшая версия npm. Требуется npm >= 3.x"
+ },
+ "errors": "Не удалось зарегистрировать __count__ тип узла",
+ "errors_plural_2": "Не удалось зарегистрировать __count__ типа узла",
+ "errors_plural_5": "Не удалось зарегистрировать __count__ типов узла",
+ "errors-help": "Запустите с -v для деталей",
+ "missing-modules": "Недостающие модули узлов:",
+ "node-version-mismatch": "Модуль узла не может быть загружен в этой версии. Требуется: __version__ ",
+ "type-already-registered": "'__type__' уже зарегистрирован модулем __module__",
+ "removing-modules": "Удаление модулей из конфига",
+ "added-types": "Добавлены типы узлов:",
+ "removed-types": "Удалены типы узлов:",
+ "install": {
+ "invalid": "Неверное имя модуля",
+ "installing": "Установка модуля: __name__, версия: __version__",
+ "installed": "Установлен модуль: __name__",
+ "install-failed": "Установка не удалась",
+ "install-failed-long": "Установка модуля __name__ не удалась:",
+ "install-failed-not-found": "Модуль $t(server.install.install-failed-long) не найден",
+ "install-failed-name": "$t(server.install.install-failed-long) неверное имя модуля: __name__",
+ "install-failed-url": "$t(server.install.install-failed-long) неверный url: __url__",
+ "upgrading": "Обновление модуля: __name__ до версии: __version__",
+ "upgraded": "Обновлен модуль: __name__. Перезапустите Node-RED, чтобы использовать новую версию",
+ "upgrade-failed-not-found": "Версия $t(server.install.install-failed-long) не найдена",
+ "uninstalling": "Удаление модуля: __name__",
+ "uninstall-failed": "Удаление не удалось",
+ "uninstall-failed-long": "Удаление модуля __name__ не удалось:",
+ "uninstalled": "Удален модуль: __name__"
+ },
+ "unable-to-listen": "Невозможно прослушивать __listenpath__",
+ "port-in-use": "Ошибка: порт используется",
+ "uncaught-exception": "Непойманное исключение:",
+ "admin-ui-disabled": "Пользовательский интерфейс администратора отключен",
+ "now-running": "Сервер теперь работает на __listenpath__",
+ "failed-to-start": "Не удалось запустить сервер:",
+ "headless-mode": "Работает в безголовом (headless) режиме",
+ "httpadminauth-deprecated": "использование httpAdminAuth устарело. Используйте adminAuth вместо этого",
+ "https": {
+ "refresh-interval": "Обновление настроек https каждые __interval__ часов",
+ "settings-refreshed": "Настройки сервера https обновлены",
+ "refresh-failed": "Не удалось обновить настройки https: __message__",
+ "nodejs-version": "httpsRefreshInterval требует Node.js 11 или выше",
+ "function-required": "httpsRefreshInterval требует, чтобы свойство https было функцией"
+ }
+ },
+
+ "api": {
+ "flows": {
+ "error-save": "Ошибка сохранения потоков: __message__",
+ "error-reload": "Ошибка перезагрузки потоков: __message__"
+ },
+ "library": {
+ "error-load-entry": "Ошибка загрузки записи библиотеки '__path__': __message__",
+ "error-save-entry": "Ошибка сохранения записи библиотеки '__path__': __message__",
+ "error-load-flow": "Ошибка загрузки потока '__path__': __message__",
+ "error-save-flow": "Ошибка сохранения потока '__path__': __message__"
+ },
+ "nodes": {
+ "enabled": "Включены типы узлов:",
+ "disabled": "Отлючены типы узлов:",
+ "error-enable": "Не удалось включить узел:"
+ }
+ },
+
+ "comms": {
+ "error": "Ошибка канала связи: __message__",
+ "error-server": "Ошибка сервера связи: __message__",
+ "error-send": "Ошибка связи при отправке: __message__"
+ },
+
+ "settings": {
+ "user-not-available": "Не удается сохранить настройки пользователя: __message__",
+ "not-available": "Настройки недоступны",
+ "property-read-only": "Свойство '__prop__' доступно только для чтения"
+ },
+
+ "nodes": {
+ "credentials": {
+ "error":"Ошибка при загрузке учетных данных: __message__",
+ "error-saving":"Ошибка при сохранении учетных данных: __message__",
+ "not-registered": "Тип учетных данных '__type__' не зарегистрирован",
+ "system-key-warning": "\n\n---------------------------------------------------------------------\nВаш файл учетных данных потока зашифрован с использованием\nсгенерированного системой ключа.\n\nЕсли сгенерированный системой ключ по какой-либо причине утерян, файл\nс Вашими учетными данными не подлежит восстановлению. Вам придется\nудалить его и повторно ввести свои учетные данные.\n\nВы должны установить свой собственный ключ, используя опцию\n'credentialSecret' в Вашем файле настроек. После этого Node-RED\nповторно зашифрует Ваш файл учетных данных, используя выбранный Вами\nключ, при следующем развертывании изменений.\n---------------------------------------------------------------------\n"
+ },
+ "flows": {
+ "safe-mode": "Потоки остановлены в безопасном режиме. Разверните, чтобы запустить.",
+ "registered-missing": "Отсутствует зарегистрированный тип: __type__",
+ "error": "Ошибка загрузки потоков: __message__",
+ "starting-modified-nodes": "Запуск измененных узлов",
+ "starting-modified-flows": "Запуск измененных потоков",
+ "starting-flows": "Запуск потоков",
+ "started-modified-nodes": "Запущены измененные узлы",
+ "started-modified-flows": "Запущены измененные потоки",
+ "started-flows": "Запущены потоки",
+ "stopping-modified-nodes": "Остановка измененных узлов",
+ "stopping-modified-flows": "Остановка измененных потоков",
+ "stopping-flows": "Остановка потоков",
+ "stopped-modified-nodes": "Остановлены измененные узлы",
+ "stopped-modified-flows": "Остановлены измененные потоки",
+ "stopped-flows": "Остановлены потоки",
+ "stopped": "Остановлен",
+ "stopping-error": "Ошибка остановки узла: __message__",
+ "added-flow": "Добавление потока: __label__",
+ "updated-flow": "Обновлен поток: __label__",
+ "removed-flow": "Удален поток: __label__",
+ "missing-types": "Ожидание регистрации отсутствующих типов:",
+ "missing-type-provided": " - __type__ (предоставлен npm-модулем __module__)",
+ "missing-type-install-1": "Чтобы установить любой из этих отсутствующих модулей, запустите:",
+ "missing-type-install-2": "в каталоге:"
+ },
+ "flow": {
+ "unknown-type": "Неизвестный тип: __type__",
+ "missing-types": "недостающие типы",
+ "error-loop": "Сообщение превысило максимальное количество уловов"
+ },
+ "index": {
+ "unrecognised-id": "Нераспознанный идентификатор: __id__",
+ "type-in-use": "Тип используется: __msg__",
+ "unrecognised-module": "Нераспознанный модуль: __module__"
+ },
+ "registry": {
+ "localfilesystem": {
+ "module-not-found": "Не удается найти модуль '__module__'"
+ }
+ }
+ },
+
+ "storage": {
+ "index": {
+ "forbidden-flow-name": "запрещенное имя потока"
+ },
+ "localfilesystem": {
+ "user-dir": "Каталог пользователя : __path__",
+ "flows-file": "Файл потоков : __path__",
+ "create": "Создание нового файла __type__",
+ "empty": "Существующий файл __type__ пуст",
+ "invalid": "Существующий файл __type__ не является допустимым json",
+ "restore": "Восстановление резервной копии файла __type__ : __path__",
+ "restore-fail": "Восстановление резервной копии файла __type__ не удалось : __message__",
+ "fsync-fail": "Запись данных файла __path__ на диск не удалась : __message__",
+ "projects": {
+ "changing-project": "Установка активного проекта : __project__",
+ "active-project": "Активный проект : __project__",
+ "project-not-found": "Проект не найден : __project__",
+ "no-active-project": "Нет активного проекта : используется файл потоков по умолчанию",
+ "disabled": "Проекты отключены : editorTheme.projects.enabled=false",
+ "disabledNoFlag": "Проекты отключены : установите editorTheme.projects.enabled=true , чтобы включить",
+ "git-not-found": "Проекты отключены : команда git не найдена",
+ "git-version-old": "Проекты отключены : git __version__ не поддерживается. Требуется 2.x",
+ "summary": "Node-RED проект",
+ "readme": "### О проекте\n\nЭто README.md файл Вашего проекта. Он помогает пользователям понять, что\nделает Ваш проект, как его использовать и все остальное, что им может\nпонадобиться знать."
+ }
+ }
+ },
+
+ "context": {
+ "log-store-init": "Хранилище контекста : '__name__' [__info__]",
+ "error-loading-module": "Ошибка загрузки хранилища контекста: __message__",
+ "error-loading-module2": "Ошибка загрузки хранилища контекста '__module__': __message__",
+ "error-module-not-defined": "У хранилища контекста '__storage__' отсутствует опция 'module'",
+ "error-invalid-module-name": "Неверное имя хранилища контекста: '__name__'",
+ "error-invalid-default-module": "Хранилище контекста по умолчанию неизвестно: '__storage__'",
+ "unknown-store": "Задано неизвестное хранилище контекста '__name__'. Используется хранилище по умолчанию.",
+ "localfilesystem": {
+ "invalid-json": "Неверный JSON в файле контекста '__file__'",
+ "error-circular": "Контекст __scope__ содержит циклическую ссылку, которая не может быть сохранена",
+ "error-write": "Ошибка записи контекста: __message__"
+ }
+ }
+
+}
diff --git a/packages/node_modules/@node-red/runtime/package.json b/packages/node_modules/@node-red/runtime/package.json
index c8bd96aa8..10adaa423 100644
--- a/packages/node_modules/@node-red/runtime/package.json
+++ b/packages/node_modules/@node-red/runtime/package.json
@@ -1,6 +1,6 @@
{
"name": "@node-red/runtime",
- "version": "1.2.3",
+ "version": "1.2.7",
"license": "Apache-2.0",
"main": "./lib/index.js",
"repository": {
@@ -16,9 +16,9 @@
}
],
"dependencies": {
- "@node-red/registry": "1.2.3",
- "@node-red/util": "1.2.3",
- "async-mutex": "0.2.4",
+ "@node-red/registry": "1.2.7",
+ "@node-red/util": "1.2.7",
+ "async-mutex": "0.2.6",
"clone": "2.1.2",
"express": "4.17.1",
"fs-extra": "8.1.0",
diff --git a/packages/node_modules/@node-red/util/lib/util.js b/packages/node_modules/@node-red/util/lib/util.js
index 261dc3867..07f506007 100644
--- a/packages/node_modules/@node-red/util/lib/util.js
+++ b/packages/node_modules/@node-red/util/lib/util.js
@@ -774,6 +774,12 @@ function encodeObject(msg,opts) {
data: value.toString()
}
}
+ } else if (typeof value === 'bigint') {
+ value = {
+ __enc__: true,
+ type: 'bigint',
+ data: value.toString()
+ }
} else if (value && value.constructor) {
if (value.type === "Buffer") {
value.__enc__ = true;
@@ -808,6 +814,13 @@ function encodeObject(msg,opts) {
} else if (msgType === "number") {
msg.format = "number";
msg.msg = msg.msg.toString();
+ } else if (msgType === "bigint") {
+ msg.format = "bigint";
+ msg.msg = {
+ __enc__: true,
+ type: 'bigint',
+ data: msg.msg.toString()
+ };
} else if (msg.msg === null || msgType === "undefined") {
msg.format = (msg.msg === null)?"null":"undefined";
msg.msg = "(undefined)";
diff --git a/packages/node_modules/@node-red/util/package.json b/packages/node_modules/@node-red/util/package.json
index bb3325d91..fafa7f6ec 100644
--- a/packages/node_modules/@node-red/util/package.json
+++ b/packages/node_modules/@node-red/util/package.json
@@ -1,6 +1,6 @@
{
"name": "@node-red/util",
- "version": "1.2.3",
+ "version": "1.2.7",
"license": "Apache-2.0",
"repository": {
"type": "git",
@@ -20,7 +20,7 @@
"json-stringify-safe": "5.0.1",
"jsonata": "1.8.4",
"lodash.clonedeep": "^4.5.0",
- "moment-timezone": "^0.5.31",
+ "moment-timezone": "0.5.32",
"when": "3.7.8"
}
}
diff --git a/packages/node_modules/node-red/package.json b/packages/node_modules/node-red/package.json
index f6a98d688..3f18a811e 100644
--- a/packages/node_modules/node-red/package.json
+++ b/packages/node_modules/node-red/package.json
@@ -1,6 +1,6 @@
{
"name": "node-red",
- "version": "1.2.3",
+ "version": "1.2.7",
"description": "Low-code programming for event-driven applications",
"homepage": "http://nodered.org",
"license": "Apache-2.0",
@@ -31,10 +31,10 @@
"flow"
],
"dependencies": {
- "@node-red/editor-api": "1.2.3",
- "@node-red/runtime": "1.2.3",
- "@node-red/util": "1.2.3",
- "@node-red/nodes": "1.2.3",
+ "@node-red/editor-api": "1.2.7",
+ "@node-red/runtime": "1.2.7",
+ "@node-red/util": "1.2.7",
+ "@node-red/nodes": "1.2.7",
"basic-auth": "2.0.1",
"bcryptjs": "2.4.3",
"express": "4.17.1",
diff --git a/test/nodes/core/parsers/70-CSV_spec.js b/test/nodes/core/parsers/70-CSV_spec.js
index 10e167b6d..17cbb9dc1 100644
--- a/test/nodes/core/parsers/70-CSV_spec.js
+++ b/test/nodes/core/parsers/70-CSV_spec.js
@@ -261,15 +261,15 @@ describe('CSV node', function() {
var n2 = helper.getNode("n2");
var c = 0;
n2.on("input", function(msg) {
- if (c == 0) {
+ if (c == 0) {
c = 1;
msg.should.have.property('payload', { a: "with,an", b: "odd,number", c: "ofquotes\n" });
check_parts(msg, 0, 1);
}
- else {
+ else {
msg.should.have.property('payload', { a: "this is", b: "a normal", c: "line" });
check_parts(msg, 0, 1);
- done();
+ done();
}
});
var testString = '"with,a"n,odd","num"ber","of"qu"ot"es"'+String.fromCharCode(10);
@@ -287,15 +287,15 @@ describe('CSV node', function() {
var c = 0;
n2.on("input", function(msg) {
//console.log(msg)
- if (c == 0) {
+ if (c == 0) {
c = 1;
msg.should.have.property('payload', { a: "with,an", b: "odd,number", c: "ofquotes\nthis is,a normal,line" });
check_parts(msg, 0, 1);
}
- else {
+ else {
msg.should.have.property('payload', { a: "this is", b: "another", c: "line" });
check_parts(msg, 0, 1);
- done();
+ done();
}
});
var testString = '"with,a"n,odd","num"ber","of"qu"ot"es"'+String.fromCharCode(10)+'"this is","a normal","line"'+String.fromCharCode(10);
@@ -555,14 +555,68 @@ describe('CSV node', function() {
});
it('should convert an array of objects to a multi-line csv', function(done) {
- var flow = [ { id:"n1", type:"csv", temp:"a,b,c,d", wires:[["n2"]] },
+ var flow = [ { id:"n1", type:"csv", temp:"a,d,c,b", wires:[["n2"]] },
{id:"n2", type:"helper"} ];
helper.load(csvNode, flow, function() {
var n1 = helper.getNode("n1");
var n2 = helper.getNode("n2");
n2.on("input", function(msg) {
try {
- msg.should.have.property('payload', '4,3,2,1\n1,2,3,4\n');
+ msg.should.have.property('payload', '4,1,2,3\n1,4,3,2\n');
+ done();
+ }
+ catch(e) { done(e); }
+ });
+ var testJson = [{ d: 1, b: 3, c: 2, a: 4 },{d:4,a:1,c:3,b:2}];
+ n1.emit("input", {payload:testJson});
+ });
+ });
+
+ it('should convert an array of objects to a multi-line csv and add a header', function(done) {
+ var flow = [ { id:"n1", type:"csv", temp:"a,b,c,d", hdrout:"all", wires:[["n2"]] },
+ {id:"n2", type:"helper"} ];
+ helper.load(csvNode, flow, function() {
+ var n1 = helper.getNode("n1");
+ var n2 = helper.getNode("n2");
+ n2.on("input", function(msg) {
+ try {
+ msg.should.have.property('payload', 'a,b,c,d\n4,3,2,1\n1,2,3,4\n');
+ done();
+ }
+ catch(e) { done(e); }
+ });
+ var testJson = [{ d: 1, b: 3, c: 2, a: 4 },{d:4,a:1,c:3,b:2}];
+ n1.emit("input", {payload:testJson});
+ });
+ });
+
+ it('should convert an array of objects to a multi-line csv without a template', function(done) {
+ var flow = [ { id:"n1", type:"csv", temp:"", wires:[["n2"]] },
+ {id:"n2", type:"helper"} ];
+ helper.load(csvNode, flow, function() {
+ var n1 = helper.getNode("n1");
+ var n2 = helper.getNode("n2");
+ n2.on("input", function(msg) {
+ try {
+ msg.should.have.property('payload', '1,3,2,4\n4,2,3,1\n');
+ done();
+ }
+ catch(e) { done(e); }
+ });
+ var testJson = [{ d: 1, b: 3, c: 2, a: 4 },{d:4,a:1,c:3,b:2}];
+ n1.emit("input", {payload:testJson});
+ });
+ });
+
+ it('should convert an array of objects to a multi-line csv without a template and with a header', function(done) {
+ var flow = [ { id:"n1", type:"csv", temp:"", hdrout:"all", wires:[["n2"]] },
+ {id:"n2", type:"helper"} ];
+ helper.load(csvNode, flow, function() {
+ var n1 = helper.getNode("n1");
+ var n2 = helper.getNode("n2");
+ n2.on("input", function(msg) {
+ try {
+ msg.should.have.property('payload', 'd,b,c,a\n1,3,2,4\n4,2,3,1\n');
done();
}
catch(e) { done(e); }
diff --git a/test/unit/@node-red/editor-api/lib/editor/theme_spec.js b/test/unit/@node-red/editor-api/lib/editor/theme_spec.js
index 67e305f71..e7db72dd6 100644
--- a/test/unit/@node-red/editor-api/lib/editor/theme_spec.js
+++ b/test/unit/@node-red/editor-api/lib/editor/theme_spec.js
@@ -143,4 +143,19 @@ describe("api/editor/theme", function () {
settings.projects.should.have.a.property("enabled", false);
});
+ it("test explicit userMenu set to true in theme setting", function () {
+ theme.init({
+ editorTheme: {
+ userMenu: true,
+ }
+ });
+
+ theme.app();
+
+ var settings = theme.settings();
+ settings.should.have.a.property("userMenu");
+ settings.userMenu.should.be.eql(true);
+
+ });
+
});
diff --git a/test/unit/@node-red/editor-api/lib/index_spec.js b/test/unit/@node-red/editor-api/lib/index_spec.js
index 1d5e9380b..28928181b 100644
--- a/test/unit/@node-red/editor-api/lib/index_spec.js
+++ b/test/unit/@node-red/editor-api/lib/index_spec.js
@@ -18,11 +18,9 @@ var should = require("should");
var sinon = require("sinon");
var request = require("supertest");
var express = require("express");
-var when = require("when");
-var fs = require("fs");
-var path = require("path");
var NR_TEST_UTILS = require("nr-test-utils");
+const auth = require("basic-auth");
var api = NR_TEST_UTILS.require("@node-red/editor-api");
@@ -96,4 +94,89 @@ describe("api/index", function() {
request(api.httpAdmin).get("/auth/login").expect(200).end(done)
})
});
+
+ describe('initialises api with admin middleware', function(done) {
+ it('ignores non-function values',function(done) {
+ api.init({ httpAdminRoot: true, httpAdminMiddleware: undefined },{},{},{});
+ const middlewareFound = api.httpAdmin._router.stack.filter((layer) => layer.name === 'testMiddleware')
+ should(middlewareFound).be.empty();
+ done();
+ });
+
+ it('only accepts functions as middleware',function(done) {
+ const testMiddleware = function(req, res, next){ next(); };
+ api.init({ httpAdminRoot: true, httpAdminMiddleware: testMiddleware },{},{},{});
+ const middlewareFound = api.httpAdmin._router.stack.filter((layer) => layer.name === 'testMiddleware')
+ should(middlewareFound).be.length(1);
+ done();
+ });
+ });
+
+ describe('initialises api with authentication enabled', function(done) {
+
+ it('enables an oauth/openID based authentication mechanism',function(done) {
+ const stub = sinon.stub(apiAuth, 'genericStrategy', function(){});
+ const adminAuth = { type: 'strategy', strategy: {} }
+ api.init({ httpAdminRoot: true, adminAuth },{},{},{});
+ should(stub.called).be.ok();
+ stub.restore();
+ done();
+ });
+
+ it('enables password protection',function(done) {
+ const adminAuth = { type: 'credentials' }
+ api.init({ httpAdminRoot: true, adminAuth },{},{},{});
+
+ // is the name ("initialize") of the passport middleware present
+ const middlewareFound = api.httpAdmin._router.stack.filter((layer) => layer.name === 'initialize')
+ should(middlewareFound).be.length(1);
+ done();
+ });
+
+ });
+
+ describe('initialises api with custom cors config', function (done) {
+ const httpAdminCors = {
+ origin: "*",
+ methods: "GET,PUT,POST,DELETE"
+ };
+
+ it('uses default cors middleware when user settings absent', function(done){
+ api.init({ httpAdminRoot: true }, {}, {}, {});
+ const middlewareFound = api.httpAdmin._router.stack.filter((layer) => layer.name === 'corsMiddleware')
+ should(middlewareFound).be.length(1);
+ done();
+ })
+
+ it('enables custom cors middleware when settings present', function(done){
+ api.init({ httpAdminRoot: true, httpAdminCors }, {}, {}, {});
+ const middlewareFound = api.httpAdmin._router.stack.filter((layer) => layer.name === 'corsMiddleware')
+ should(middlewareFound).be.length(2);
+ done();
+ })
+ });
+
+ describe('editor start', function (done) {
+
+ it('cannot be started when editor is disabled', function (done) {
+ const stub = sinon.stub(apiEditor, 'start', function () {
+ return Promise.resolve(true);
+ });
+ api.init({ httpAdminRoot: true, disableEditor: true }, {}, {}, {});
+ should(api.start()).resolvedWith(true);
+ stub.restore();
+ done();
+ });
+
+ it('can be started when editor enabled', function (done) {
+ const stub = sinon.stub(apiEditor, 'start');
+ api.init({ httpAdminRoot: true, disableEditor: false }, {}, {}, {});
+ api.start();
+ should(stub.called).be.true();
+ stub.restore();
+ done();
+ });
+
+ });
+
});
diff --git a/test/unit/@node-red/runtime/lib/api/comms_spec.js b/test/unit/@node-red/runtime/lib/api/comms_spec.js
index df423b7dd..e1359cb7d 100644
--- a/test/unit/@node-red/runtime/lib/api/comms_spec.js
+++ b/test/unit/@node-red/runtime/lib/api/comms_spec.js
@@ -211,6 +211,82 @@ describe("runtime-api/comms", function() {
});
}).catch(done);
})
+ it('retains non-blank status message',function(done){
+ eventHandlers['node-status']({
+ id: "node1234",
+ status: {text:"hello"}
+ })
+ messages.should.have.length(0);
+ comms.addConnection({client: clientConnection}).then(function() {
+ return comms.subscribe({client: clientConnection, topic: "status/#"}).then(function() {
+ messages.should.have.length(1);
+ messages[0].should.have.property("topic","status/node1234");
+ messages[0].should.have.property("data",{text:"hello", fill: undefined, shape: undefined});
+ done();
+ });
+ }).catch(done);
+ })
+ it('does not retain blank status message',function(done){
+ eventHandlers['node-status']({
+ id: "node1234",
+ status: {}
+ })
+ messages.should.have.length(0);
+ comms.addConnection({client: clientConnection}).then(function() {
+ return comms.subscribe({client: clientConnection, topic: "status/#"}).then(function() {
+ messages.should.have.length(0);
+ done();
+ });
+ }).catch(done);
+ })
+ it('does not send blank status if first status',function(done){
+ messages.should.have.length(0);
+ comms.addConnection({client: clientConnection}).then(function() {
+ return comms.subscribe({client: clientConnection, topic: "status/#"}).then(function() {
+ eventHandlers['node-status']({
+ id: "node5678",
+ status: {}
+ })
+ messages.should.have.length(0);
+ done()
+ })
+ }).catch(done);
+ });
+ it('sends blank status if replacing retained',function(done){
+ eventHandlers['node-status']({
+ id: "node5678",
+ status: {text:"hello"}
+ })
+ messages.should.have.length(0);
+ comms.addConnection({client: clientConnection}).then(function() {
+ return comms.subscribe({client: clientConnection, topic: "status/#"}).then(function() {
+ messages.should.have.length(1);
+ eventHandlers['node-status']({
+ id: "node5678",
+ status: {}
+ })
+ messages.should.have.length(2);
+ done()
+ })
+ }).catch(done);
+ });
+
+ it('does not retain initial status blank message',function(done){
+ eventHandlers['node-status']({
+ id: "my-event",
+ status: {}
+ })
+ messages.should.have.length(0);
+ comms.addConnection({client: clientConnection}).then(function() {
+ return comms.subscribe({client: clientConnection, topic: "my-event"}).then(function() {
+ messages.should.have.length(1);
+ messages[0].should.have.property("topic","my-event");
+ messages[0].should.have.property("data","my-payload");
+ done();
+ });
+ }).catch(done);
+ })
+
it('retained messages get cleared',function(done) {
eventHandlers['comms']({
topic: "my-event",
');
@@ -352,7 +352,7 @@ RED.utils = (function() {
$('