diff --git a/.dockerignore b/.dockerignore index 357063f..8d89a4d 100644 --- a/.dockerignore +++ b/.dockerignore @@ -6,6 +6,7 @@ __mocks__ .env* .eslint* .log +.yarn Makefile Procfile app.json diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index a4cc22c..c164efb 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -37,7 +37,7 @@ jobs: - arm64 steps: - name: Checkout Repository - uses: actions/checkout@v5 + uses: actions/checkout@v6 with: submodules: recursive @@ -111,7 +111,7 @@ jobs: version: ${{ needs.build.outputs.version }} steps: - name: Download Digests - uses: actions/download-artifact@v6 + uses: actions/download-artifact@v7 with: path: ${{ runner.temp }}/digests pattern: digests-* diff --git a/Dockerfile b/Dockerfile index 3839ee5..769e8e2 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,35 +1,25 @@ -FROM node:22.21.0 AS base +FROM node:22.21.0 ARG APP_PATH ARG SRC_PATH +ARG CDN_URL WORKDIR $APP_PATH - -FROM base AS deps -COPY ${SRC_PATH}/package.json ${SRC_PATH}/yarn.lock ./ -RUN yarn install --production=true --frozen-lockfile --network-timeout 1000000 && \ - yarn cache clean - -FROM base AS build -RUN apt-get update && \ - apt-get install -y patch cmake && \ - rm -rf /var/lib/apt/lists/* +COPY ${SRC_PATH}/package.json ${SRC_PATH}/yarn.lock ${SRC_PATH}/.yarnrc.yml ./ COPY ${SRC_PATH}/patches ./patches -COPY ${SRC_PATH}/package.json ${SRC_PATH}/yarn.lock ./ -ENV NODE_OPTIONS="--max-old-space-size=24000" -RUN yarn install --no-optional --frozen-lockfile --network-timeout 1000000 && \ +ENV NODE_OPTIONS='--max-old-space-size=24000' +RUN corepack enable && \ + yarn install --immutable --network-timeout 1000000 && \ yarn cache clean COPY ${SRC_PATH} . -COPY --from=deps $APP_PATH/node_modules ./node_modules COPY ./patches/* . RUN for patch in $(ls *.patch); do patch -p1 < $patch; done -RUN cat < /entrypoint.sh +RUN cat << EOF > /entrypoint.sh npx yarn concurrently -n "dev,i18n" \ "yarn dev:watch" \ "yarn nodemon \ --watch './shared/i18n/locales/ru_RU' \ --exec 'yarn build:i18n'" EOF -ARG CDN_URL -ARG DATA_PATH=/var/lib/outline/data +ENV DATA_PATH=/var/lib/outline/data VOLUME ${DATA_PATH} STOPSIGNAL SIGKILL ENTRYPOINT ["bash", "/entrypoint.sh"] diff --git a/Dockerfile.prod b/Dockerfile.prod index 9de2296..2233e5d 100644 --- a/Dockerfile.prod +++ b/Dockerfile.prod @@ -1,51 +1,43 @@ -FROM node:22.21.0 AS base +FROM node:22.21.0 AS build ARG APP_PATH ARG SRC_PATH +ARG CDN_URL WORKDIR $APP_PATH - -FROM base AS deps -COPY ${SRC_PATH}/package.json ${SRC_PATH}/yarn.lock ./ -RUN yarn install --production=true --frozen-lockfile --network-timeout 1000000 && \ - yarn cache clean - -FROM base AS build -RUN apt-get update && \ - apt-get install -y patch cmake && \ - rm -rf /var/lib/apt/lists/* +COPY ${SRC_PATH}/package.json ${SRC_PATH}/yarn.lock ${SRC_PATH}/.yarnrc.yml ./ COPY ${SRC_PATH}/patches ./patches -COPY ${SRC_PATH}/package.json ${SRC_PATH}/yarn.lock ./ -ENV NODE_OPTIONS="--max-old-space-size=24000" -RUN yarn install --no-optional --frozen-lockfile --network-timeout 1000000 && \ +ENV NODE_OPTIONS='--max-old-space-size=24000' +RUN corepack enable && \ + yarn install --immutable --network-timeout 1000000 && \ yarn cache clean COPY ${SRC_PATH} . COPY ./patches/lang.patch . RUN patch -p1 < lang.patch COPY ./translation/ru.json ./shared/i18n/locales/ru_RU/translation.json -ARG CDN_URL -RUN yarn build && rm -rf node_modules +RUN yarn build && \ + yarn workspaces focus --production FROM node:22.21.0-slim AS release RUN apt-get update && \ apt-get install -y curl && \ rm -rf /var/lib/apt/lists/* -ARG DATA_PATH=/var/lib/outline/data -ARG USER=nodejs -ARG APP_PATH -WORKDIR $APP_PATH +ENV DATA_PATH=/var/lib/outline/data +ENV USER=nodejs RUN addgroup --gid 1001 ${USER} && \ adduser --uid 1001 --ingroup ${USER} ${USER} && \ mkdir -p ${DATA_PATH} && \ chown -R ${USER}:${USER} ${DATA_PATH}/.. -COPY --chown=${USER} --from=deps $APP_PATH/node_modules ./node_modules -COPY --chown=${USER} --from=build $APP_PATH/build ./build -COPY --chown=${USER} --from=build $APP_PATH/server ./server -COPY --chown=${USER} --from=build $APP_PATH/public ./public -COPY --chown=${USER} --from=build $APP_PATH/.sequelizerc . -COPY --chown=${USER} --from=build $APP_PATH/package.json . +ARG APP_PATH +WORKDIR $APP_PATH +COPY --chown=${USER}:${USER} --from=build $APP_PATH/node_modules ./node_modules +COPY --chown=${USER}:${USER} --from=build $APP_PATH/build ./build +COPY --chown=${USER}:${USER} --from=build $APP_PATH/server ./server +COPY --chown=${USER}:${USER} --from=build $APP_PATH/public ./public +COPY --chown=${USER}:${USER} --from=build $APP_PATH/.sequelizerc . +COPY --chown=${USER}:${USER} --from=build $APP_PATH/package.json . ENV NODE_ENV=production ENV PORT=3000 USER ${USER} EXPOSE ${PORT} VOLUME ${DATA_PATH} HEALTHCHECK --interval=1m CMD curl -fs localhost:${PORT}/_health | grep -q OK || exit 1 -CMD ["yarn", "start"] +CMD ["node", "build/server/index.js"] \ No newline at end of file diff --git a/README.md b/README.md index 05dba9d..097e27b 100644 --- a/README.md +++ b/README.md @@ -20,8 +20,8 @@ ```yaml services: outline: - image: flameshikari/outline-ru:1.1.0 - # image: ghcr.io/flameshikari/outline-ru:1.1.0 + image: flameshikari/outline-ru:1.2.0 + # image: ghcr.io/flameshikari/outline-ru:1.2.0 env_file: ./docker.env expose: - 3000 @@ -93,7 +93,7 @@ services: 2. Пулл изменений в подмодуле и переключение на последний доступный тег: ```sh - git submodule foreach 'git pull --rebase --tags && git checkout v1.1.0' + git submodule foreach 'git pull --rebase --tags && git checkout v1.2.0' ``` 3. Запуск контейнеров: diff --git a/outline b/outline index 6cfc7da..4aa5cac 160000 --- a/outline +++ b/outline @@ -1 +1 @@ -Subproject commit 6cfc7da40b773c5e52c30df3749bfbe924dade10 +Subproject commit 4aa5cacc57857b63b1c1de112cd7ea40afad5c2a diff --git a/translation/ru.json b/translation/ru.json index e8ee87c..520a6dd 100644 --- a/translation/ru.json +++ b/translation/ru.json @@ -113,6 +113,7 @@ "You have left the shared document": "Вы покинули общий документ", "Could not leave document": "Не удалось покинуть документ", "Apply template": "Применить шаблон", + "Disconnect": "Отключить", "Disconnect analytics": "Отключить аналитику", "Home": "Домашняя", "Drafts": "Черновики", @@ -171,6 +172,7 @@ "Navigation": "Навигация", "Notification": "Уведомление", "Groups": "Группы", + "Emoji": "Эмодзи", "People": "Люди", "Share": "Поделиться", "Workspace": "Рабочее пространство", @@ -213,10 +215,6 @@ "Collections could not be loaded, please reload the app": "Не удалось загрузить коллекции, пожалуйста, перезагрузите приложение", "Start view": "Начать просмотр", "Install now": "Установить сейчас", - "Disconnect": "Отключить", - "Disconnecting": "Отключение", - "Are you sure you want to disconnect the {{ service }} integration?": "Вы уверены, что хотите отключить интеграцию {{ service }}?", - "This will stop sending analytics events to the configured instance.": "Это прекратит отправку аналитических событий в настроенный инстанс.", "Deleted Collection": "Удаленная коллекция", "Untitled": "Без названия", "Unpin": "Открепить", @@ -259,6 +257,8 @@ "Currently editing": "Сейчас редактируется", "Currently viewing": "Сейчас просматривается", "Viewed {{ timeAgo }}": "Просмотрено {{ timeAgo }}", + "Uploading": "Идёт загрузка", + "Upload an image": "Загрузить изображение", "Module failed to load": "Произошла ошибка во время загрузки модуля", "Loading Failed": "Ошибка загрузки", "Sorry, part of the application failed to load. This may be because it was updated since you opened the tab or because of a failed network request. Please try reloading.": "К сожалению, части приложения не удалось загрузиться. Это могло произойти из-за того, что страница обновилась с тех пор, как была открыта или из-за проблем в отправке сетевого запроса. Пожалуйста, попробуйте перезагрузить страницу.", @@ -278,9 +278,9 @@ "{{userName}} published": "Опубликовано {{userName}}", "{{userName}} unpublished": "Снято с публикации {{userName}}", "{{userName}} moved": "Перемещено {{userName}}", - "Export started": "Экспорт начат", "Your file will be available in {{ location }} soon": "Ваш файл будет доступен в {{ location }} скоро", "View": "Просмотр", + "Export started": "Экспорт начат", "A ZIP file containing the images, and documents in the Markdown format.": "ZIP-архив, содержащий изображения и документы в формате Markdown.", "A ZIP file containing the images, and documents as HTML files.": "ZIP-архив, содержащий изображения и документы в формате HTML.", "Structured data that can be used to transfer data to another compatible {{ appName }} instance.": "Структурированные данные, которые можно использовать для передачи данных в другой совместимый инстанс {{ appName }}.", @@ -295,6 +295,9 @@ "Filter options": "Параметры фильтра", "Filter": "Фильтр", "No results": "Ничего не найденo", + "{{ count }} members_0": "{{ count }} участник", + "{{ count }} members_1": "{{ count }} участника", + "{{ count }} members_2": "{{ count }} участников", "{{authorName}} created <3>": "{{authorName}} создал <3>", "{{authorName}} opened <3>": "{{authorName}} открыл <3>", "Search emoji": "Поиск эмодзи", @@ -316,8 +319,7 @@ "Objects": "Объекты", "Symbols": "Символы", "Flags": "Флаги", - "Select a color": "Выберите цвет", - "Loading": "Загрузка", + "Custom": "Пользовательский", "View only": "Только просмотр", "Can edit": "Может редактировать", "No access": "Нет доступа", @@ -357,10 +359,13 @@ "Reaction picker": "Выбор реакции", "Could not load reactions": "Не удалось загрузить реакции", "Reaction": "Реакция", + "{{ hours }}h {{ minutes }}m read": "{{ hours }}ч {{ minutes }}м чтения", + "{{ hours }}h read": "{{ hours }}ч чтения", "{{ minutes }}m read": "{{ minutes }}м чтения", "Revision deleted": "Ревизия удалена", "Current version": "Текущая версия", "{{userName}} edited": "{{userName}} отредактировал", + "Revision options": "Настройка ревизии", "Results": "Результаты", "No results for {{query}}": "По запросу «{{ query }}» ничего не найдено", "Manage": "Управлять", @@ -452,11 +457,12 @@ "Change permissions?": "Изменить права доступа?", "{{ documentName }} cannot be moved within {{ parentDocumentName }}": "{{ documentName }} не может быть перемещён внутри {{ parentDocumentName }}", "You can't reorder documents in an alphabetically sorted collection": "Вы не можете изменить порядок документов в коллекции, отсортированной по алфавиту", - "The {{ documentName }} cannot be moved here": "{{ documentName }} не может быть перемещён сюда", "Return to App": "На главную", "Installation": "Установка", "Unstar document": "Убрать документ из избранного", "Star document": "Добавить документ в избранное", + "Select a color": "Выберите цвет", + "Loading": "Загрузка", "Template created, go ahead and customize it": "Шаблон создан, теперь вы можете перейти к нему и продолжить настройку", "Creating a template from {{titleWithDefault}} is a non-destructive action – we'll make a copy of the document and turn it into a template that can be used as a starting point for new documents.": "Создание шаблона из {{titleWithDefault}} не уничтожит ваш документ — мы сделаем копию и превратим ее в шаблон, который можно будет использовать в качестве отправной точки для новых документов.", "Enable other members to use the template immediately": "Разрешить другим участникам немедленно использовать шаблон", @@ -584,7 +590,6 @@ "Video": "Видео", "None": "Никто", "Delete embed": "Удалить вставку", - "Upload an image": "Загрузить изображение", "Could not import file": "Не удалось импортировать файл", "Unsubscribed from document": "Отписаться от документа", "Unsubscribed from collection": "Отменена подписка на коллекцию", @@ -620,7 +625,6 @@ "Revoking": "Отзыв", "Are you sure you want to revoke access?": "Вы уверены, что хотите отозвать доступ?", "Delete app": "Удалить приложение", - "Revision options": "Настройка ревизии", "Share options": "Настройка доступа", "Headings you add to the document will appear here": "Здесь появятся заголовки, которые вы добавляете в документ", "Contents": "Содержимое", @@ -656,9 +660,9 @@ "30 days": "30 дней", "60 days": "60 дней", "90 days": "90 дней", - "Custom": "Пользовательский", "No expiration": "Нет срока истечения", "The document archive is empty at the moment.": "Архив документов на данный момент пуст.", + "Done editing": "Правки внесены", "Drop documents to import": "Перетащите документы для импорта", "{{ collectionName }} doesn’t contain any\n documents yet.": "{{ collectionName }} пока не содержит\n документов.", "{{ usersCount }} users and {{ groupsCount }} groups with access_0": "{{ usersCount }} пользователь и {{ groupsCount }} групп(ы) с доступом", @@ -673,14 +677,14 @@ "{{ groupsCount }} groups with access_0": "{{ groupsCount }} группа с доступом", "{{ groupsCount }} groups with access_1": "{{ groupsCount }} группы с доступом", "{{ groupsCount }} groups with access_2": "{{ groupsCount }} групп с доступом", - "Archived by {{userName}}": "Архивировано {{userName}}", - "Sorry, an error occurred saving the collection": "Произошла ошибка при сохранении коллекции", - "Add a description": "Добавить описание", "Overview": "Обзор", "Recently updated": "Недавно обновлено", "Recently published": "Недавно опубликовано", "Least recently updated": "Последние обновления", "A–Z": "А–Я", + "Archived by {{userName}}": "Архивировано {{userName}}", + "Sorry, an error occurred saving the collection": "Произошла ошибка при сохранении коллекции", + "Add a description": "Добавить описание", "Signing in": "Вход", "You can safely close this window once the Outline desktop app has opened": "Вы можете безопасно закрыть это окно после открытия настольного приложения Outline", "Error creating comment": "При создании комментария произошла ошибка", @@ -731,7 +735,6 @@ "Edit {{noun}}": "Редактировать {{noun}}", "Archived": "Архивировано", "Save draft": "Сохранить черновик", - "Done editing": "Правки внесены", "Restore version": "Восстановить версию", "No history yet": "Истории пока нет", "Source": "Источник", @@ -802,7 +805,6 @@ "Something went wrong": "Что-то пошло не так", "Sorry, an unknown error occurred loading the page. Please try again or contact support if the issue persists.": "Извините, при загрузке страницы произошла неизвестная ошибка. Попробуйте ещё раз или обратитесь в службу поддержки, если проблема не исчезнет.", "Created by me": "Созданные мной", - "Weird, this shouldn’t ever be empty": "Думаю, это не должно быть пустым", "You haven’t created any documents yet": "Вы еще не создали ни одного документа", "Documents you’ve recently viewed will be here for easy access": "Документы, которые вы недавно просматривали, будут здесь для быстрого доступа", "{{ count }} invites sent_0": "{{ count }} приглашение отправлено", @@ -868,7 +870,6 @@ "Inline LaTeX": "Встроенный LaTeX", "Triggers": "Триггеры", "Mention users and more": "Упоминания пользователей и другое", - "Emoji": "Эмодзи", "Insert block": "Вставить блок", "Sign In": "Вход", "Continue with Email": "Продолжить с почтой", @@ -988,7 +989,15 @@ "Authorization URL": "URL авторизации", "Where users are redirected to authorize this app": "Куда перенаправляются пользователи для авторизации этого приложения", "Applications allow you to build internal or public integrations with Outline and provide secure access via OAuth. For more details see the developer documentation.": "Приложения позволяют создавать внутренние или публичные интеграции с Outline и обеспечивать безопасный доступ через OAuth. Подробности см. в документации для разработчиков.", + "Settings saved": "Настройки сохранены", + "Allow members to sign-in with {{ authProvider }}": "Разрешить пользователям входить с помощью {{ authProvider }}.", + "Connected": "Подключено", + "Disabled": "Отключено", + "Connect": "Подключить", + "Allow members to sign-in using their email address": "Разрешить пользователям входить в систему с помощью их адреса почты", + "The server must have SMTP configured to enable this setting": "Параметр будет доступен после настройки SMTP на сервере.", "by {{ name }}": "{{ name }}", + "Expired": "Срок действия истёк", "Last used": "Последний раз использован", "No expiry": "Нет срока истечения", "Restricted scope": "Ограниченная область видимости", @@ -996,7 +1005,9 @@ "Copied": "Скопировано", "Are you sure you want to revoke the {{ tokenName }} token?": "Вы уверены, что хотите отозвать токен {{ tokenName }}?", "Disconnect integration": "Отключить интеграцию", - "Connected": "Подключено", + "Disconnecting": "Отключение", + "Are you sure you want to disconnect the {{ service }} integration?": "Вы уверены, что хотите отключить интеграцию {{ service }}?", + "This will stop sending analytics events to the configured instance.": "Это прекратит отправку аналитических событий в настроенный инстанс.", "Allowed domains": "Разрешенные домены", "The domains which should be allowed to create new accounts using SSO. Changing this setting does not affect existing user accounts.": "Домены, которым должно быть разрешено создавать новые аккаунты с помощью SSO. Изменение этой настройки не повлияет на существующие аккаунты пользователей.", "Remove domain": "Удалить домен", @@ -1006,10 +1017,8 @@ "Your import is being processed, you can safely leave this page": "Ваш импорт обрабатывается, можете смело покинуть эту страницу", "File not supported – please upload a valid ZIP file": "Файл не поддерживается. Загрузите допустимый ZIP-архив", "Set the default permission level for collections created from the import": "Установите уровень разрешений по умолчанию для коллекций, созданных в результате импорта", - "Uploading": "Идёт загрузка", "Start import": "Начать импортирование", "Processing": "Обработка", - "Expired": "Срок действия истёк", "Completed": "Завершено", "Failed": "Неудачно", "All collections": "Все коллекции", @@ -1047,7 +1056,6 @@ "Date created": "Дата создания", "Crop Image": "Обрезать изображение", "Crop image": "Обрезать изображение", - "How does this work?": "Как это работает?", "You can import a zip file that was previously exported from the JSON option in another instance. In {{ appName }}, open Export in the Settings sidebar and click on Export Data.": "Вы можете импортировать ZIP-архив, который ранее был экспортирован с помощью параметра JSON, в другой инстанс. В {{ appName }} откройте Экспорт на боковой панели настроек и нажмите Экспорт данных.", "Drag and drop the zip file from the JSON export option in {{appName}}, or click to upload": "Перетащите ZIP-архив из параметра экспорта JSON в {{appName}} или нажмите, чтобы загрузить", "Canceled": "Отменено", @@ -1061,7 +1069,6 @@ "You can import a zip file that was previously exported from an Outline installation – collections, documents, and images will be imported. In Outline, open Export in the Settings sidebar and click on Export Data.": "Вы можете импортировать ZIP-архив, который ранее был экспортирован из Outline — коллекции, документы и изображения будут импортированы. В Outline откройте Экспорт на боковой панели настроек и нажмите Экспортировать данные.", "Drag and drop the zip file from the Markdown export option in {{appName}}, or click to upload": "Перетащите ZIP-архив из параметра экспорта Markdown в {{appName}} или нажмите, чтобы загрузить", "Configure": "Настроить", - "Connect": "Подключить", "Last active": "Последняя активность", "Role": "Роль", "Guest": "Гость", @@ -1080,7 +1087,6 @@ "Active": "Активные", "Left": "Слева", "Right": "Справа", - "Settings saved": "Настройки сохранены", "Logo updated": "Логотип обновлен", "Unable to upload new logo": "Не удалось загрузить новый логотип", "Delete workspace": "Удалить рабочее пространство", @@ -1185,11 +1191,6 @@ "Are you sure you want to require invites?": "Вы уверены, что хотите требовать приглашений?", "New users will first need to be invited to create an account. Default role and Allowed domains will no longer apply.": "Новым пользователям нужно будет получать приглашение для создания аккаунта. Роль по умолчанию и Разрешенные домены больше не будут применяться.", "Settings that impact the access, security, and content of your workspace.": "Настройки, влияющие на доступ, безопасность и содержимое вашего рабочего пространства.", - "Allow members to sign-in with {{ authProvider }}": "Разрешить пользователям входить с помощью {{ authProvider }}.", - "Disabled": "Отключено", - "Allow members to sign-in using their email address": "Разрешить пользователям входить в систему с помощью их адреса почты", - "The server must have SMTP configured to enable this setting": "Параметр будет доступен после настройки SMTP на сервере.", - "Access": "Доступ", "Allow users to send invites": "Разрешить пользователям отправлять приглашения", "Allow editors to invite other people to the workspace": "Разрешить редакторам приглашать других людей в рабочее пространство.", "Require invites": "Требуется приглашение", @@ -1390,9 +1391,105 @@ "Caption": "Подпись", "Open": "Открыть", "Error loading data": "Ошибка загрузки данных", - "{{ count }} members_0": "{{ count }} участник", - "{{ count }} members_1": "{{ count }} участника", - "{{ count }} members_2": "{{ count }} участников", - "{{ hours }}h {{ minutes }}m read": "{{ hours }}ч {{ minutes }}м чтения", - "{{ hours }}h read": "{{ hours }}ч чтения" + + "New emoji": "Новое эмодзи", + "Upload emoji": "Загрузить эмодзи", + "Mark as read": "Пометить как прочитанное", + "Mark as unread": "Пометить как непрочитанное", + "Download revision": "Скачать ревизию", + "File type not supported. Please use PNG, JPG, GIF, or WebP.": "Тип файла не поддерживается. Пожалуйста, используйте PNG, JPG, GIF или WebP.", + "File size too large. Maximum size is {{ size }}.": "Размер файла слишком большой. Максимальный размер — {{ size }}.", + "Please enter a name for the emoji": "Пожалуйста, введите имя для эмодзи.", + "Please select an image file": "Пожалуйста, выберите изображение", + "Emoji created successfully": "Эмодзи успешно создано", + "Add emoji": "Добавить эмодзи", + "Square images with transparent backgrounds work best. If your image is too large, we’ll try to resize it for you.": "Квадратные изображения с прозрачным фоном подходят лучше всего. Если изображение слишком большое, мы попробуем уменьшить его размер за вас.", + "Click or drag to replace": "Кликните или перетащите, чтобы заменить", + "Drop the image here": "Перетащите изображение сюда", + "Click, drop, or paste an image here": "Кликните, перетащите или вставьте изображение сюда", + "PNG, JPG, GIF, or WebP up to {{ size }}": "PNG, JPG, GIF или WebP размером до {{ size }}", + "Choose a name": "Выберите имя", + "name can only contain lowercase letters, numbers, and underscores.": "имя может состоять только из строчных латинских букв, цифр и подчеркиваний.", + "This emoji will be available as": "Этот эмодзи будет доступен как", + "A link to your file will be sent through email soon": "Ссылка на ваш файл скоро будет отправлена по почте", + "Edit diagram": "Редактировать диаграмму", + "Notification options": "Параметры уведомлений", + "Mentions": "Упоминания", + "Comments and replies": "Комментарии и ответы", + "Document events": "События документа", + "Collection events": "События коллекции", + "Client type": "Тип клиента", + "Confidential": "Конфиденциально", + "Suitable for server-side applications": "Подходит для серверных приложений", + "Public": "Публично", + "Suitable for client-side or mobile applications": "Подходит для клиентских или мобильных приложений", + "{{count}} people_0": "{{count}} человек", + "{{count}} people_1": "{{count}} человека", + "{{count}} people_2": "{{count}} человек", + "{{ documentName }} cannot be moved here": "{{ documentName }} нельзя переместить сюда", + "Embed PDF": "Встроить PDF", + "Formatting controls": "Инструменты форматирования", + "Distribute columns": "Распределить столбцы", + "Authentication": "Аутентификация", + "Delete Emoji": "Удалить эмодзи", + "Emoji deleted": "Эмодзи удалено", + "Are you sure you want to delete the {{emojiName}} emoji? You will no longer be able to use it in your documents or collections.": "Вы уверены, что хотите удалить эмодзи {{emojiName}}? Вы больше не сможете использовать его в своих документах или коллекциях.", + "Popular": "Популярное", + "{{ current }} of {{ count }} changes_0": "{{ current }} из {{ count }} изменений", + "{{ current }} of {{ count }} changes_1": "{{ current }} из {{ count }} изменений", + "{{ current }} of {{ count }} changes_2": "{{ current }} из {{ count }} изменений", + "{{ count }} changes_0": "{{ count }} изменение", + "{{ count }} changes_1": "{{ count }} изменения", + "{{ count }} changes_2": "{{ count }} изменений", + "Previous change": "Предыдущее изменение", + "Next change": "Следующее изменение", + "Highlight changes": "Выделить изменения", + "Weird, this shouldn't ever be empty": "Здесь будут появляться недавно обновлённые документы", + "Documents with recent activity will appear here": "Здесь будут появляться наиболее популярные документы", + "Continue with Passkey": "Продолжить с ключом доступа", + "Passkeys are not supported in the desktop app": "Ключи доступа не поддерживаются в десктопном приложении", + "Confidential clients can securely store a secret": "Конфиденциальные клиенты могут безопасно хранить секрет", + "Are you sure?": "Вы уверены?", + "Removing": "Удаление", + "Removing this authentication provider will prevent members from signing in with {{ authProvider }}.": "Удаление этого провайдера аутентификации не позволит участникам входить через {{ authProvider }}.", + "Manage how members sign-in to your workspace and which authentication providers are enabled.": "Управляйте тем, как участники входят в рабочее прстранство и какие провайдеры аутентификации включены.", + "Connect {{ authProvider }} to allow members to sign-in": "Подключить {{ authProvider }} для входа участников", + "Passkeys": "Ключи доступа", + "Allow members to sign-in with a WebAuthn passkey": "Разрешить участникам вход с помощью ключа доступа WebAuthn", + "Restrictions": "Ограничения", + "Added by": "Добавлено", + "Date added": "Дата добавления", + "Members exported successfully": "Участники успешно экспортированы", + "Failed to export members": "Не удалось экспортировать участников", + "Download CSV": "Скачать CSV", + "Could not load emojis": "Не удалось загрузить эмодзи", + "Custom emojis can be used throughout your workspace in documents, comments, and reactions.": "Пользовательские эмодзи можно использовать в документах, комментариях и реакциях по всему рабочему пространству.", + "Invites": "Приглашения", + "Allow users to sign in with passkeys for passwordless authentication": "Разрешить вход с помощью ключей доступа для аутентификации без пароля", + "Configure a custom Diagrams.net installation URL to use your own self-hosted instance for embedding diagrams in your documents.": "Настройте URL-адрес вашего инстанса Diagrams.net для использования его при внедрении диаграмм в документы.", + "Installation URL": "URL-адрес инстанса", + "The URL of your Diagrams.net installation. Leave empty to use the cloud hosted app.diagrams.net": "URL-адрес вашего инстанса Diagrams.net. Оставьте пустым, чтобы использовать облачную версию app.diagrams.net", + "Passkey options": "Параметры ключа доступа", + "Registered {{ timeAgo }}": "Зарегистрирован {{ timeAgo }}", + "Passkey updated": "Ключ доступа обновлен", + "Failed to update passkey. Please try again.": "Не удалось обновить ключ доступа. Повторите попытку.", + "Give your passkey a memorable name to easily identify it.": "Дайте ключу доступа запоминающееся имя для легкой идентификации.", + "Enter passkey name": "Введите имя ключа доступа", + "Failed to load passkeys": "Не удалось загрузить ключи доступа", + "Passkey added successfully": "Ключ доступа успешно добавлен", + "Failed to register passkey. Please try again.": "Не удалось зарегистрировать ключ доступа. Пожалуйста, попробуйте снова.", + "Rename passkey": "Переименовать ключ доступа", + "Delete passkey": "Удалить ключ доступа", + "Passkey deleted successfully": "Ключ доступа успешно удален", + "Failed to delete passkey. Please try again.": "Не удалось удалить ключ доступа. Пожалуйста, попробуйте снова.", + "Are you sure you want to delete this passkey? You will no longer be able to use it to sign in.": "Вы уверены, что хотите удалить этот ключ доступа? Вы больше не сможете использовать его для входа.", + "Registering": "Регистрирую", + "Add Passkey": "Добавить ключ доступа", + "Passkeys allow you to sign in safely without a password using your device's biometric authentication (Face ID, Touch ID, Windows Hello) or security key.": "Ключи доступа позволяют безопасно входить без пароля, используя биометрическую аутентификацию устройства (Face ID, Touch ID, Windows Hello) или ключ безопасности.", + "Sign-in with Passkey is currently disabled for this team.": "Вход через ключ доступа временно отключен для этой команды.", + "Enable for all users in Settings -> Authentication.": "Включить для всех пользователей в Настройки -> Аутентификация.", + "Contact a workspace admin to enable it.": "Свяжитесь с администратором рабочего пространства, чтобы включить это.", + "You don't have any passkeys yet.": "У вас пока нет ключей доступа.", + "Empty diagram": "Пустая диаграмма", + "Double click to edit": "Двойной клик для редактирования" }