{{ tr('Suggestions') }}
{{ suggestActiveCount }} {{ suggestCollapsed ? '▸' : '▾' }}{{ tr('Update available') }}: {{ updateInfo.latest }}
{{ updateInfo.notes }}
{{ lang==='ru' ? 'Пока нет сообщений и дел' : 'No messages or tasks yet' }}
{{ j.printer_name }}{{ j.file_name }}
{{ sendStateLabel(j.state) }} · {{ Math.round(j.progress) }}%
{{ sendErrLabel(j) }}
{{ (lang==='ru'?'Отправка на ':'Sending to ') + printSendingNow.printer_name }}
{{ row.gcode_file }}
{{ row.match_printer_name }}{{ queueReasonText(row.match_reason) }}
{{ ui3PpP.name }}
{{ ui3PpP.model || (lang==='ru'?'модель не указана':'model not set') }} · {{ ui3PpP.ip }}
{{ lang==='ru' ? 'Сообщения принтера' : 'Printer messages' }} · {{ hmsCount(ui3Printer) }}
{{ hmsText(h) }}
{{ lang==='ru' ? 'Уведомление принтера' : 'Printer notification' }}
{{ hmsModuleText(h.module) }} · {{ hmsSevText(h.severity) }} · {{ h.code }}
{{ lang==='ru' ? 'Незнакомые коды программа не расшифровывает: полный текст — на экране принтера или по QR-коду на нём' : 'Unknown codes are not translated: the full text is on the printer screen, or behind its QR code' }}
{{ lang==='ru'?'Печать':'Print' }}
{{ lang==='ru'?'Управлять печатью может только оператор.':'Only an operator can control printing.' }}
{{ lang==='ru'?'Температуры':'Temperatures' }}
{{ lang==='ru'?'Пресеты прогрева':'Preheat presets' }}{{ lang==='ru'?'одни на всю ферму':'shared by the whole farm' }}
{{ lang==='ru'?'Имя':'Name' }}{{ lang==='ru'?'Сопло':'Nozzle' }}{{ lang==='ru'?'Стол':'Bed' }}{{ lang==='ru'?'Камера':'Chamber' }}
{{ ui3PresetError }}
{{ lang==='ru'?'Материал':'Material' }}{{ ui3PpNowLabel }}
{{ ui3PpP.type === 'bambu' ? 'AMS' : 'CFS' }}{{ t.short }}
{{ r.label }}{{ r.text }}{{ r.rem }}
{{ lang==='ru' ? 'Катушка со склада не привязана' : 'No stock spool bound' }}
{{ lang==='ru'?'Служебное':'Service' }}
{{ lang==='ru'?'Для этого принтера служебных действий сейчас нет.':'No service actions for this printer right now.' }}
{{ lang==='ru'?'Камера':'Camera' }}
{{ partDisplayName(pt.name) }} ×{{ pt.qty }}
{{ ui3PpPct }} %{{ ui3PpRemainText }}{{ ui3PpFinishText }}
{{ ui3FilTotals.printers }}{{ lang==='ru'?' принтеров':' printers' }}
{{ ui3FilTotals.slots }}{{ lang==='ru'?' слотов':' slots' }}
{{ ui3FilTotals.grams }}{{ lang==='ru'?' г на ферме':' g on the farm' }}
{{ ui3FilTotals.low }}{{ lang==='ru'?' скоро кончится':' running low' }}
{{ ui3FilTotals.empty }}{{ lang==='ru'?' пустых':' empty' }}
{{ lang==='ru'?'Пока нечего показать: программа не получила от принтеров ни одного слота. Проверьте, что принтеры на связи, а модуль «Складской учёт» установлен — тогда здесь появятся и граммы.':'Nothing to show yet: no slots reported by the printers. Check that the printers are online and the Inventory module is installed — then grams appear here too.' }}
x.id === pr.pid))" :title="lang==='ru'?'Открыть пульт принтера':'Open the printer panel'">
{{ pr.name }}
{{ pr.model }}
{{ s.label }}
{{ s.material || (lang==='ru'?'пусто':'empty') }}
{{ s.colorName }} · {{ s.vendor }}
{{ s.rem }}{{ lang==='ru'?' г':' g' }} · {{ s.pct }} %
—
{{ lang==='ru'?'остаток неизвестен':'amount unknown' }}
{{ lang==='ru'?'Граммы приходят от модуля «Складской учёт» и есть только у привязанных катушек. Слот, к которому катушка не привязана, показывает материал от самого принтера, а остаток у него неизвестен.':'Grams come from the Inventory module and exist only for bound spools. A slot without a bound spool shows the material reported by the printer, and its remaining amount is unknown.' }}
{{ lang==='ru'?'Программа сама подбирает принтер: свободный, с нужным материалом и с вашим разрешением запускать из очереди. Печать начинается по вашему подтверждению — так вы видите, куда она уйдёт.':'The program picks a printer itself: free, with the right material and allowed by you to start from the queue. Printing starts on your confirmation.' }}
{{ lang==='ru'?'Очередь пуста. Нажмите правой кнопкой на файле в «Задачах» и выберите «Добавить в очередь».':'The queue is empty. Right-click a file in Tasks and choose “Add to queue”.' }}
{{ row.gcode_file }}{{ row.material || (lang==='ru'?'материал не указан':'material unknown') }}{{ row.match_printer_name }}{{ queueReasonText(row.match_reason) }}
{{ lang==='ru'?'Кому разрешён запуск из очереди':'Allowed to start from the queue' }}
{{ queueAllowed.length }}{{ lang==='ru'?'из':'of' }} {{ printers.length }}
{{ lang==='ru'?'Отмечать можно и в списке принтеров — кнопкой рядом с «Добавить».':'You can also mark them in the printers list, next to “Add”.' }}{{ tr('Projects') }}{{ projSort === 'name' ? '▲' : '▼' }}
{{ p2NameMsg(project2NameErr) }}
{{ tr('Nothing found') }}
{{ tr('No projects yet. Use the + New Project button to create your first one.') }}
{{ pr.name }}
{{ p2NameMsg(project2RenameErr[pr.id]) }}
{{ pr.done_count }}/{{ pr.parts_count }} {{ lang==='ru' ? 'типов дет.' : 'part types' }}
{{ lang==='ru' ? 'Проверочный режим: доступен только один контролируемый запуск' : 'Verification mode: only one controlled start is available' }}
{{ wpxStatus(pr.id).t }}
{{ projectWholePlan.plan_quality==='exact' ? (lang==='ru'?'Точный план':'Exact plan') : (lang==='ru'?'Приближённый план':'Approximate plan') }}
{{ lang==='ru' ? 'Нужно' : 'Need' }}: {{ wpxSummary(pr.id).need }}
{{ lang==='ru' ? 'Готово' : 'Done' }}: {{ wpxSummary(pr.id).done }}
{{ lang==='ru' ? 'Осталось' : 'Left' }}: {{ wpxSummary(pr.id).left }}
{{ lang==='ru' ? 'Текущий запуск' : 'Current run' }}: {{ wpxSummary(pr.id).cur }} {{ lang==='ru' ? 'из' : 'of' }} {{ wpxSummary(pr.id).runsTotal }}
{{ lang==='ru' ? 'Принтер' : 'Printer' }}: {{ wpxSeriesPrinter(wpxRunFor(pr.id)) }}
{{ lang==='ru' ? 'Проблемы' : 'Issues' }}: {{ wpxSummary(pr.id).issues }}
{{ lang==='ru' ? 'Не удалось рассчитать план:' : 'Plan calculation failed:' }} {{ projectWholeError }}
{{ lang==='ru' ? 'Приближённый план — достигнут лимит полного перебора. Он рабочий, но не обязательно самый экономный.' : 'Approximate plan — exhaustive search limit reached.' }}
{{ lang==='ru' ? 'Проект уже напечатан полностью — планировать нечего.' : 'Project is already fully printed.' }}
{{ lang==='ru' ? 'Осталось напечатать' : 'Remaining' }}
{{ lang==='ru'?'Деталь':'Part' }}{{ lang==='ru'?'Нужно':'Required' }}{{ lang==='ru'?'Напечатано':'Printed' }}{{ lang==='ru'?'Переделка':'Rework' }}{{ lang==='ru'?'Осталось':'Remaining' }}
{{ p.part_name }}{{ p.required_qty }}{{ p.printed_qty }}
{{ p.rework_qty ? (p.rework_done + '/' + p.rework_qty) : '—' }}{{ p.remaining }}
{{ lang==='ru' ? 'Что будет напечатано' : 'Planned runs' }}
{{ it.filename }}{{ lang==='ru' ? 'запуск' : 'run' }} #{{ it.seq }}
{{ projectWholePartName(pid) }} × {{ q }}
{{ lang==='ru'?'лишних':'extra' }} {{ projectWholePartName(pid) }} × {{ q }}
{{ lang==='ru' ? 'Неизбежное перепроизводство' : 'Unavoidable overproduction' }}
{{ lang==='ru'?'Деталь':'Part' }}{{ lang==='ru'?'Нужно':'Needed' }}{{ lang==='ru'?'Будет напечатано':'Will print' }}{{ lang==='ru'?'Лишнее':'Extra' }}
{{ r.name }}{{ r.need }}{{ r.total }}+{{ r.extra }}
{{ lang==='ru' ? 'Проблемы' : 'Problems' }}
{{ b.part_name || projectWholePartName(b.part_id) }}
{{ lang==='ru'?'не покрыто':'uncovered' }}: {{ b.qty }}
{{ b.reason }}
{{ lang==='ru' ? 'Принтеры' : 'Printers' }}
{{ projectWholePreflight.idle_is_not_proof }}
{{ pp.name }}
{{ pp.status }}
{{ pp.telemetry_fresh ? (lang==='ru'?'связь свежая':'fresh') : (lang==='ru'?'нет свежих данных':'stale/offline') }} · {{ readinessReasonsText(pp.unavailable_reasons) }}
{{ lang==='ru' ? 'Не удалось сохранить план:' : 'Save failed:' }} {{ projectWholeSaveError }}
{{ lang==='ru' ? 'Проект изменился после расчёта. Обновите план.' : 'Project changed after the calculation. Refresh the plan.' }}
{{ lang==='ru' ? 'Для проекта уже существует сохранённый план — он показан ниже.' : 'A saved plan already exists — it is shown below.' }}
{{ lang==='ru' ? 'План сохранён. Автоматическая печать в этой версии отключена.' : 'Plan saved. Automatic printing is disabled in this version.' }}
{{ lang==='ru' ? 'Считаем план…' : 'Calculating…' }}
{{ lang==='ru' ? 'Запуск печати из приложения выключен' : 'Printing from the app is off' }}
{{ lang==='ru' ? 'После включения приложение сможет отправлять реальную печать. Каждый запуск всё равно нужно подтвердить, а принтер должен быть в безопасном простое.' : 'Once enabled, the app can send real prints. Each start still needs confirmation and a safely idle printer.' }}
{{ lang==='ru' ? 'Материал' : 'Material' }}: {{ wpxSeriesMaterial(wpxRunFor(pr.id)) }}
{{ lang==='ru' ? 'Сейчас: запуск' : 'Now: run' }} {{ wpxCurrentIndex(wpxRunFor(pr.id)) + 1 }} {{ lang==='ru' ? 'из' : 'of' }} {{ wpxSummary(pr.id).runsTotal }}
{{ wpxPartsText(wpxRunFor(pr.id), it) }}
{{ wpxFileLabel(it) }}
{{ wpxPrinterName(wpxRunFor(pr.id), it) }}
{{ wpxItemState(wpxRunFor(pr.id), it) }}
{{ lang==='ru' ? 'Материал' : 'Material' }}: {{ wpxMaterialLine(it) }}
{{ feedItemNotice(wpxRunFor(pr.id).run_id, it.item_id) }}
{{ feedItemError(wpxRunFor(pr.id).run_id, it.item_id) }}
✓ {{ lang==='ru' ? 'Стол подтверждён пустым' : 'Plate confirmed empty' }}
{{ wpxClrState(wpxRunFor(pr.id), it).kind==='need-initial' ? (lang==='ru' ? 'Перед первой печатью физически проверьте, что стол пуст. Только человек может это подтвердить.' : 'Before the first print, physically verify the plate is empty. Only a human can confirm this.') : (lang==='ru' ? 'Снимите готовую деталь и подтвердите очистку стола.' : 'Remove the printed part and confirm the plate is clear.') }}
{{ clearanceStateText(wpxClrState(wpxRunFor(pr.id), it).t) }}
{{ clearanceBlockReason(wpxClrState(wpxRunFor(pr.id), it).t) }}
{{ lang==='ru' ? 'Вооружён контрольный запуск' : 'Controlled start is armed' }}
{{ lang==='ru' ? 'Не удалось получить версию плана. Обновите данные; запуск заблокирован.' : 'Could not read the plan version. Refresh the data; the start is blocked.' }}
{{ startItemNotice(wpxRunFor(pr.id).run_id, it.item_id) }}
{{ startItemNotice(wpxRunFor(pr.id).run_id, it.item_id) }}
{{ lang==='ru' ? 'Доказать, началась ли печать, нечем. Автоматический повтор запрещён.' : 'There is no proof whether the print started. Automatic retry is forbidden.' }} ({{ it.last_error }})
{{ lang==='ru' ? 'Запуск' : 'Run' }} {{ wpxCurrentIndex(wpxRunFor(pr.id)) + 2 + qi }}
{{ wpxPartsText(wpxRunFor(pr.id), q) }}
{{ lang==='ru' ? 'после завершения запуска' : 'after run' }} {{ wpxCurrentIndex(wpxRunFor(pr.id)) + 1 + qi }}
{{ lang==='ru' ? 'В очереди' : 'Queued' }}
{{ projectRunErrors[wpxRunFor(pr.id).run_id] }}
run: {{ wpxRunFor(pr.id).run_id }} · state: {{ wpxRunFor(pr.id).state }} · plan: {{ wpxRunFor(pr.id).plan_quality }} · updated_at: {{ wpxRunFor(pr.id).updated_at }}
{{ it.item_id }} · {{ it.file_id }} · {{ it.state }} · {{ it.block_reason }} · {{ it.last_error }} · fp: {{ it.feed_plan.fingerprint }}
{{ tr('No files in this project yet. Open editing (pencil) and add a .gcode or .3mf file.') }}
{{ tr('Part name') }}{{ sortDir===1 ? '▲' : '▼' }}
{{ tr('Prnt') }}{{ sortDir===1 ? '▲' : '▼' }}{{ lang==='ru' ? 'из' : 'of' }}{{ tr('Req') }}{{ sortDir===1 ? '▲' : '▼' }}
{{ tr('Req') }}{{ sortDir===1 ? '▲' : '▼' }}
{{ tr('Prnt') }}{{ sortDir===1 ? '▲' : '▼' }}
{{ lang==='ru'?'Брак':'Defect' }}
{{ tr('Status') }}{{ sortDir===1 ? '▲' : '▼' }}
{{ tr('Printing') }}
{{ tr('No parts yet. Add a file and parts will be detected automatically.') }}
{{ partDisplayName(pp.part_name) }}
{{ pvVariantCount(pp) > 1 ? ('▣ ' + pvVariantCount(pp)) : '1' }}
{{ pp.notes || (can('project') ? (lang==='ru' ? 'Заметка…' : 'Note…') : '') }}
{{ lang==='ru' ? 'из' : 'of' }}
{{ pp.required_qty }}
{{ pp.printed_qty }}
{{ pp.rework_done }}/{{ pp.rework_qty }}
{{ livePartPrintingQty(pp) || '—' }}
×{{ pl.on_plate_qty }}
{{ tr('Part name') }}
{{ tr('Prnt') }}{{ lang==='ru' ? 'из' : 'of' }}{{ tr('Req') }}
{{ tr('Req') }}
{{ tr('Prnt') }}
{{ lang==='ru'?'Брак':'Defect' }}
{{ tr('Status') }}
{{ tr('Printing') }}
{{ partDisplayName(pp.part_name) }}
{{ lang==='ru' ? 'из' : 'of' }}
{{ pp.rework_done || 0 }}/{{ pp.rework_qty }}
{{ tr('STL/3MF files') }}
{{ tr('G-code files') }}
{{ tr('Parts on plate') }}
×
{{ tr('Tasks') }}
{{ stagingFiles.length }} {{ tr('files') }} {{ tr('Req') }} {{ stagingTotals.req }} · {{ tr('Prnt') }} {{ stagingTotals.prnt }} · {{ stagingTotals.pct }}%
{{ tr('Group') }}
{{ tr('Nothing found') }}
{{ tr('File name') }}{{ stSortDir===1 ? '▲' : '▼' }}
{{ tr('Prnt') }}{{ stSortDir===1 ? '▲' : '▼' }}{{ lang==='ru' ? 'из' : 'of' }}{{ tr('Req') }}{{ stSortDir===1 ? '▲' : '▼' }}
{{ tr('Req') }}{{ stSortDir===1 ? '▲' : '▼' }}
{{ tr('Prnt') }}{{ stSortDir===1 ? '▲' : '▼' }}
{{ tr('Status') }}{{ stSortDir===1 ? '▲' : '▼' }}
{{ tr('Printing') }}
{{ tr('No files yet. Drag a .gcode / .3mf file here or click Open.') }}
{{ f.filename }}
{{ f.notes || (can('project') ? (lang==='ru' ? 'Заметка…' : 'Note…') : '') }}
{{ stagingProgressText(f) }}
{{ lang==='ru' ? 'из' : 'of' }}
{{ liveStagingPrintingQty(f) || '—' }}
{{ tr('Parts on plate') }}
{{ partDisplayName(pt.name) }}
×{{ pt.count }}
{{ tr('Total') }}
{{ f.part_total || 0 }}
{{ f.filename }}
{{ stagingStatusLabel(f) }}
{{ partDisplayName(pt.name) }}
×{{ pt.count }}
{{ tr('Total') }}
{{ f.part_total || 0 }}
{{ tr('Req') }}: {{ f.required_qty }}
{{ tr('Prnt') }}: {{ f.printed_qty }}
.{{ f.filename.split('.').pop().toLowerCase() }}
{{ tr('No files yet. Drag a .gcode / .3mf file here or click Open.') }}
{{ lang==='ru'?'Общие':'General' }}
{{ tourEnabled ? (lang==='ru'?'Внешний вид, обучение и отображение сроков.':'Appearance, tours and how dates are shown.') : (lang==='ru'?'Внешний вид, справка и отображение сроков.':'Appearance, help and how dates are shown.') }}
{{ lang==='ru'?'Программа':'Program' }}
{{ lang==='ru'?'Набор возможностей и сведения о версии.':'Feature set and version information.' }}
{{ lang==='ru'?'Версия программы':'Edition' }}{{ lang==='ru'?'Определяет, какие разделы доступны.':'Controls which sections are available.' }}
{{ tourEnabled ? (lang==='ru'?'Подсказки в интерфейсе и обучающие туры.':'Interface hints and guided tours.') : (lang==='ru'?'Пояснения к кнопкам и полям при наведении курсора.':'Explanations for buttons and fields when you hover them.') }}
{{ tr('Appearance') }}
{{ lang==='ru'?'Тема, шрифт и вспомогательные панели.':'Theme, font and helper panels.' }}
{{ tr('Theme') }}{{ lang==='ru'?'Выбор из двух режимов — это не «включено/выключено».':'A choice between two modes, not on/off.' }}
{{ lang==='ru'?'Шрифт':'Font' }}
{{ lang==='ru'?'Сроки':'Dates' }}
{{ lang==='ru'?'Как показываются даты и близость срока.':'How dates and approaching deadlines are shown.' }}
{{ lang==='ru'?'Предупреждать о близком сроке':'Warn about an approaching deadline' }}{{ lang==='ru'?'Жёлтая отметка, когда до срока осталось не больше указанного.':'A yellow mark when the deadline is within this many days.' }}
{{ lang==='ru'?'дней':'days' }}
{{ lang==='ru'?'Печать':'Printing' }}
{{ lang==='ru'?'Слайсер, порядок запуска и приём файлов из слайсера.':'Slicer, start order and accepting files from the slicer.' }}
{{ tr('Slicer') }}
{{ lang==='ru'?'Какая программа открывает модели для нарезки.':'Which program opens models for slicing.' }}
{{ lang==='ru'?'Программа нарезки':'Slicing program' }}{{ lang==='ru'?'«Авто» — первый найденный в системе.':'Auto picks the first one found.' }}
{{ lang==='ru'?'Поэтапный запуск печати':'Staggered print start' }}
{{ lang==='ru'?'Чтобы принтеры не стартовали одновременно.':'So the printers do not all start at once.' }}
{{ lang==='ru'?'Интервал между запусками':'Interval between starts' }}
{{ lang==='ru'?'сек':'sec' }}
i{{ lang==='ru'?'Принтеры стартуют по очереди с этим интервалом — так не перегружается электросеть. Очередь работает и при закрытой вкладке.':'Printers start one by one with this interval, so the power grid is not overloaded. The queue keeps running even with the tab closed.' }}
{{ lang==='ru'?'Пока ключ не создан, файлы из слайсера не принимаются.':'Until a key is created, uploads from the slicer are rejected.' }}{{ lang==='ru'?'Слайсер отправляет файлы напрямую в Farm Manager.':'The slicer sends files straight to Farm Manager.' }} ({{ sliCb.created_at }})
{{ lang==='ru'?'Ключ доступа':'Access key' }}{{ lang==='ru'?'В слайсере: тип хоста OctoPrint или Klipper/Moonraker, поле API Key.':'In the slicer: host type OctoPrint or Klipper/Moonraker, API Key field.' }}
!{{ lang==='ru'?'Сохраните ключ сейчас — показать его повторно нельзя.':'Save the key now — it cannot be shown again.' }}{{ sliCbToken }}{{ lang==='ru'?'После замены ключа настройку в слайсере нужно обновить.':'After replacing the key, update the slicer settings.' }}
{{ lang==='ru'?'Система':'System' }}
{{ lang==='ru'?'Инструменты, файлы принтеров, сеть, хранение данных, копии и модули.':'Tools, printer files, network, data storage, backups and modules.' }}
{{ lang==='ru'?'Быстрые инструменты':'Quick tools' }}
{{ lang==='ru'?'Отдельные экраны для проверки фермы и файлов на принтерах.':'Separate screens for checking the farm and printer files.' }}
{{ lang==='ru'?'Доступ Farm Manager к файлам, которые хранятся на принтерах.':'Farm Manager access to files stored on the printers.' }}
!{{ lang==='ru'?'Удаление необратимо и зависит от возможностей принтера. Файл активной печати и служебные файлы защищены всегда.':'Deletion is irreversible and depends on the printer. The active print file and system files are always protected.' }}
i · {{ a.name }}: {{ a.text }}
{{ lang==='ru'?'Сеть и доступ':'Network & access' }}{{ lang==='ru'?'Этот компьютер':'This computer' }}
{{ lang==='ru'?'Кто может открыть Farm Manager и на каком порту он слушает.':'Who can open Farm Manager and which port it listens on.' }}
i{{ lanBlockedText }}
!{{ lanError }}
i{{ lang==='ru'?'Связь с принтерами, камеры и печать от этой настройки не зависят.':'Printer connections, cameras and printing do not depend on this setting.' }}
{{ lanHint }}
{{ lang==='ru'?'Адрес для других компьютеров:':'Address for other computers:' }} {{ lanUrl }}
{{ lang==='ru'?'Если из сети не открывается — разрешите входящий порт в брандмауэре Windows вручную: программа этого не гарантирует.':'If it does not open from the network, allow the incoming port in Windows Firewall manually: the program does not guarantee this.' }}
{{ lanHint }}
{{ lang==='ru'?'Адрес для других компьютеров:':'Address for other computers:' }} {{ lanUrl }}
{{ lang==='ru'?'Если из сети не открывается — разрешите входящий порт в брандмауэре Windows вручную: программа этого не гарантирует.':'If it does not open from the network, allow the incoming port in Windows Firewall manually: the program does not guarantee this.' }}
!{{ lang==='ru'?'Требуется перезапуск':'Restart required' }} {{ lang==='ru'?'Изменение вступит в силу после перезапуска программы.':'The change takes effect after you restart the program.' }}
{{ lang==='ru'?'Порт сервера':'Server port' }}{{ lang==='ru'?'Требуется перезапуск':'Restart required' }}{{ lang==='ru'?'Через него подключаются браузер, окно программы и клиенты.':'The browser, the app window and clients connect through it.' }}{{ netPort || '—' }} · {{ lang==='ru'?'после перезапуска':'after restart' }}: {{ netPendingPort }}
{{ lang==='ru'?'Только чтение':'Read only' }}
i{{ lang==='ru'?'Порт меняется только на компьютере-сервере.':'The port can only be changed on the server computer.' }}
{{ lang==='ru'?'Хранение данных':'Data storage' }}{{ lang==='ru'?'Этот компьютер':'This computer' }}
{{ lang==='ru'?'Где программа держит базу, файлы и архивы на этой машине.':'Where the app keeps its database, files and archives on this machine.' }}
{{ lang==='ru'?'Папка данных':'Data folder' }}{{ storageInfo.data_dir }}
i{{ (lang==='ru'?'После перезапуска: ':'After restart: ') + dataDirPending }}
{{ lang==='ru'?'Смена папки данных применяется при следующем запуске программы.':'The new data folder takes effect on the next app start.' }}
{{ lang==='ru'?'Смена папки данных применяется при следующем запуске программы.':'The new data folder takes effect on the next app start.' }}
{{ lang==='ru'?'Папка архивов':'Archive folder' }}{{ storageInfo.archive_dir }}
{{ lang==='ru'?'Доступ и аудит':'Access & audit' }}{{ authEnabled ? (lang==='ru'?'Включён':'Enabled') : (lang==='ru'?'Выключен':'Disabled') }}
{{ lang==='ru'?'Пароли, роли и журнал действий на этом сервере.':'Passwords, roles and the action log on this server.' }}
{{ lang==='ru'?'Вход выполнен':'Signed in' }}
{{ authUser ? authUser.username : '' }} · {{ authUser ? roleLabel(authUser.role) : '' }}
{{ lang==='ru'?'Что входит в копию, создание, защита паролем и восстановление.':'What the backup covers, creating it, password protection and restoring.' }}
{{ lang==='ru'?'Резервная копия сохраняет настройки Farm Manager, принтеры, данные подключения и всю пользовательскую информацию установленных модулей. Проекты и задачи в копию не входят и при восстановлении не изменяются.':'The backup saves Farm Manager settings, printers, connection data and all user information of the installed modules. Projects and tasks are not included and are never changed by a restore.' }}
• {{ lang==='ru'?'Настройки Farm Manager':'Farm Manager settings' }}
• {{ lang==='ru'?'Принтеры и данные подключения':'Printers and connection data' }}
• {{ lang==='ru'?'Складской учёт':'Inventory' }}
• {{ lang==='ru'?'Расчёт заказа — сохранённые заказы в копию пока не входят':'Order calculation — saved orders are not in the backup yet' }}
• {{ lang==='ru'?'Аналитика качества — в модуле нет пользовательских данных для сохранения':'Quality analytics — the module has no user data to save' }}
• {{ lang==='ru'?'Оформление и темы — темы хранятся в браузере этого компьютера и в копию не входят':'Appearance and themes — themes live in this browser and are not in the backup' }}
{{ lang==='ru'?'Резервная копия будет создана без пароля и содержит настройки подключения принтеров. Храните файл в защищённом месте.':'The backup will be created without a password and contains printer connection settings. Keep the file in a safe place.' }}
{{ lang==='ru'?'Потерянный пароль восстановить невозможно — копию без него не открыть.':'A lost password cannot be recovered — the backup cannot be opened without it.' }}
{{ lang==='ru'?'Папка данных, папка архивов и порт сервера относятся к этому компьютеру. При восстановлении они останутся без изменений.':'The data folder, archive folder and server port belong to this computer. They remain unchanged during a restore.' }}
{{ lang==='ru'?'Восстановление из резервной копии':'Restore from backup' }}
{{ cbPhase==='checking' ? (lang==='ru'?'Проверка резервной копии…':'Checking the backup…') : (lang==='ru'?'Подготовка плана…':'Preparing the plan…') }}
{{ lang==='ru'?'Требуется пароль':'Password required' }}
{{ lang==='ru'?'План восстановления':'Restore plan' }}
{{ (lang==='ru'?'Принтеров добавить: ':'Printers to add: ') + (cbPlan.counts ? cbPlan.counts.printers_added : 0) + (lang==='ru'?', обновить: ':', update: ') + (cbPlan.counts ? cbPlan.counts.printers_updated : 0) }}
{{ (lang==='ru'?'Настроек изменится: ':'Settings changed: ') + (cbPlan.counts ? cbPlan.counts.core_changed : 0) }}
{{ lang==='ru'?'Настройки этого компьютера':'This computer settings' }}
{{ cbMbLabel(mb.key) + ' — ' + (mb.applied ? (lang==='ru'?'требует отдельного подтверждения':'requires separate confirmation') : (lang==='ru'?'не будет изменено':'will not be changed')) }}
{{ lang==='ru'?'Данные модулей':'Module data' }}
{{ lang==='ru'?'Данные модулей отсутствуют в этой версии резервной копии и не будут изменены':'Module data is absent in this backup version and will not be changed' }}
{{ cbModLabel(m.module_id) + ' — ' + (m.data_class==='no_persistent_user_data' ? (lang==='ru'?'нет пользовательских данных':'no user data') : ((lang==='ru'?'добавить: ':'add: ') + (m.counts ? m.counts.added : 0) + (lang==='ru'?', обновить: ':', update: ') + (m.counts ? m.counts.updated : 0) + (lang==='ru'?', останется своих: ':', kept current: ') + (m.counts ? m.counts.current_only : 0))) }}
{{ w.text }}
{{ lang==='ru'?'Потребуется перезапуск программы.':'A restart will be required.' }}
{{ lang==='ru'?'Конфигурация восстановлена':'Configuration restored' }}
!{{ lang==='ru'?'Чтобы применить все восстановленные настройки, перезапустите Farm Manager.':'To apply all restored settings, restart Farm Manager.' }}
{{ lang==='ru'?'Не удалось перезапустить. Завершите Farm Manager через значок в трее и запустите снова.':'Restart failed. Close Farm Manager via the tray icon and start it again.' }}
!
{{ cbMsg.text }}
{{ lang==='ru'?'Модули':'Modules' }}
{{ lang==='ru'?'Расширения программы: что установлено, что включено и откуда ставить новое.':'Program extensions: what is installed, what is enabled and where to install from.' }}
{{ lang==='ru'?'Нажмите на модуль, чтобы открыть его. У модуля без своего окна настройки стоят ячейкой ниже.':'Click a module to open it. A module without its own window has its settings as a cell below.' }}
{{ lang==='ru'?'Установленные модули отсутствуют.':'No modules installed.' }}
{{ lang==='ru'?'Недостаточно прав для управления модулями.':'Not enough permissions to manage modules.' }}
{{ lang==='ru'?'Не удалось получить состояние модулей.':'Could not load module state.' }}
{{ lang==='ru'?'Загрузка списка модулей…':'Loading modules…' }}
{{ lang==='ru'?'Модули с пометкой ниже не загрузились. Поставьте актуальный файл — секция «Установка и обновление».':'The modules marked below did not load. Install the current file — see “Install and update”.' }}
{{ lang==='ru'?'Выберите, какие модули показывать кнопками справа на панели «Проекты · Задачи · Очередь · Филамент». Выбор общий для всех компьютеров фермы.':'Choose which modules appear as buttons on the right of the “Projects · Tasks · Queue · Filament” bar. The choice is shared across the farm.' }}
{{ lang==='ru'?'Выбор сохранён только на этом компьютере: сервер программы его не принял. Чаще всего помогает перезапуск Farm Manager — после него выбор станет общим для фермы.':'Saved on this computer only: the program server did not accept it. Restarting Farm Manager usually helps — after that the choice is shared across the farm.' }}
{{ lang==='ru'?'Модулей с собственным окном пока нет — показывать на панели нечего.':'No modules with their own window yet — nothing to show on the bar.' }}
{{ moduleInstallMsg.text }}
i{{ lang==='ru'?'Новый модуль появится после перезапуска программы.':'The new module appears after the program restarts.' }}
{{ restartMessage }}
{{ pfSummary.count }} {{ lang==='ru'?'файлов':'files' }} · {{ pfFmtSize(pfSummary.size) }}
· {{ lang==='ru'?'выбрано':'selected' }} {{ pfSummary.sel }} ({{ pfFmtSize(pfSummary.selSize) }})
· {{ lang==='ru'?'свободно':'free' }} {{ pfFmtSize(pfStorage.free_bytes) }} {{ lang==='ru'?'из':'of' }} {{ pfFmtSize(pfStorage.total_bytes) }}
· {{ lang==='ru'?'Удаление выключено (Настройки → Система → Файлы принтеров)':'Deletion is off (Settings → System → Printer files)' }}
· {{ lang==='ru'?'Печать доступна':'Printing available' }}
· {{ lang==='ru'?'Удаление не поддерживается принтером':'Deletion is not supported by the printer' }}
{{ lang==='ru'?'Загрузка списка файлов…':'Loading file list…' }}
{{ lang==='ru'?'Выберите принтер':'Select a printer' }}
{{ pfReasonText('read_disabled') }}
{{ lang==='ru'?'Не поддерживается':'Not supported' }}{{ pfReasonText(pfReason) }}
{{ lang==='ru'?'Принтер недоступен':'Printer is unreachable' }}
{{ lang==='ru'?'Накопитель не найден или извлечён':'Storage not found or removed' }}
{{ lang==='ru'?'Ошибка чтения: ':'Read error: ' }}{{ pfReasonText(pfReason) }}
{{ lang==='ru'?'На накопителе нет файлов':'No files on this storage' }}
| {{ lang==='ru'?'Имя':'Name' }}{{ pfSortDir===1?'▲':'▼' }} | {{ lang==='ru'?'Категория':'Category' }} | {{ lang==='ru'?'Размер':'Size' }}{{ pfSortDir===1?'▲':'▼' }} | {{ lang==='ru'?'Дата':'Date' }}{{ pfSortDir===1?'▲':'▼' }} | {{ lang==='ru'?'Состояние':'State' }} | ||
|---|---|---|---|---|---|---|
|
|
{{ pfCatText(e) }}{{ lang==='ru'?'Таймлапс':'Timelapse' }} | {{ pfFmtSize(e.size_bytes) }} | {{ e.is_directory ? '—' : pfFmtDate(e.modified_at) }} | {{ lang==='ru'?'Активная печать':'Active print' }} {{ pfStatusText(e) }} {{ pfReasonText(e.protected_reason) }} — |
{{ pfPreview.entry.name }}
{{ lang==='ru'?'Загрузка картинки…':'Loading preview…' }}
{{ pfPreview.reason ? pfReasonText(pfPreview.reason) : (lang==='ru'?'Картинку получить не удалось':'Could not load the preview') }}
{{ lang==='ru'?'Считаем…':'Counting…' }}
{{ lang==='ru'?'Отчёты считаются по журналу печатей, а его ведёт модуль «Качество печати». Модуль не установлен — считать не из чего. Поставить: Настройки → Модули.':'Reports are built from the print log kept by the Print quality module. The module is not installed, so there is nothing to count. Install it in Settings → Modules.' }}
{{ lang==='ru'?'Модуль «Качество печати» установлен, но не работает: он выключен или не запустился. Пока он не работает, журнал печатей не ведётся и считать нечего. Включить: Настройки → Система → Модули.':'The Print quality module is installed but not running: it is switched off or failed to start. While it is not running the print log is not kept and there is nothing to count. Enable it in Settings → System → Modules.' }}
{{ lang==='ru'?'Не удалось получить список модулей, поэтому неизвестно, ведётся ли журнал печатей. Это не значит, что данных нет — проверьте связь с сервером и обновите.':'The module list could not be fetched, so it is unknown whether the print log is being kept. It does not mean there is no data — check the server connection and refresh.' }}
{{ lang==='ru'?'Не удалось прочитать журнал печатей. Проверьте, что сервер запущен, и обновите.':'The print log could not be read. Check that the server is running and refresh.' }}
{{ lang==='ru'?'За выбранный срок печатей не было.':'No prints in the selected period.' }}
{{ repStats.total }}{{ lang==='ru'?'запусков печати':'print runs' }}
{{ repStats.finished }}{{ lang==='ru'?'завершено':'finished' }}
{{ repStats.failed }}{{ lang==='ru'?'сбой':'failed' }}
{{ repStats.cancelled }}{{ lang==='ru'?'отменено':'cancelled' }}
{{ repStats.unknown }}{{ lang==='ru'?'исход не ясен':'outcome unclear' }}
{{ repStats.judged ? (repStats.rate + '%') : '—' }}{{ lang==='ru'?'доля успеха':'success rate' }}
{{ repDuration(repStats.seconds) }}{{ lang==='ru'?'печатали всего':'total printing time' }}
{{ lang==='ru'?'Записей без отметки о завершении':'Runs with no completion mark' }}: {{ repStats.running }}. {{ lang==='ru'?'Это либо печать, идущая прямо сейчас, либо печать, закончившаяся при выключенной программе — её исход никто не увидел. В долю успеха такие записи не входят.':'These are either prints running right now or prints that ended while the program was closed, so nobody saw the outcome. Such runs are excluded from the success rate.' }}
{{ lang==='ru'?'Показаны последние 2000 запусков за срок — более ранние в подсчёт не вошли.':'Only the latest 2000 runs of the period are counted; earlier ones are not included.' }}
{{ lang==='ru'?'По дням':'By day' }}
{{ d.total }}
{{ repDayLabel(d.day) }}
{{ lang==='ru'?'По принтерам':'By printer' }}
{{ lang==='ru'?'Принтер':'Printer' }}
{{ lang==='ru'?'всего':'total' }}
{{ lang==='ru'?'завершено':'finished' }}
{{ lang==='ru'?'сбой':'failed' }}
{{ lang==='ru'?'отменено':'cancelled' }}
{{ lang==='ru'?'не ясен':'unclear' }}
{{ lang==='ru'?'успех':'success' }}
{{ lang==='ru'?'время печати':'printing time' }}
{{ p.name }}
{{ p.total }}
{{ p.finished }}
{{ p.failed }}
{{ p.cancelled }}
{{ p.unknown }}
{{ p.judged ? (p.rate + '%') : '—' }}
{{ repDuration(p.seconds) }}
{{ lang==='ru'?'Что печаталось чаще':'Most printed files' }}
{{ lang==='ru'?'Файл':'File' }}
{{ lang==='ru'?'запусков':'runs' }}
{{ lang==='ru'?'завершено':'finished' }}
{{ lang==='ru'?'сбой':'failed' }}
{{ f.name }}
{{ f.total }}
{{ f.finished }}
{{ f.failed }}
{{ lang==='ru'?'Как это считается, честно:':'How this is counted, honestly:' }}
· {{ lang==='ru'?'«Отменено» — это и остановка вами, и уход принтера в покой без доказанного завершения.':'“Cancelled” covers both a stop by you and the printer going idle without a proven finish.' }}
· {{ lang==='ru'?'«Исход не ясен» — прежнюю печать сменил новый файл, и чем она кончилась, никто не знает. В долю успеха такие не входят вовсе.':'“Outcome unclear” means a new file replaced the previous print and nobody knows how it ended. Such runs are excluded from the success rate.' }}
· {{ lang==='ru'?'Доля успеха = завершено ÷ (завершено + сбой + отменено).':'Success rate = finished ÷ (finished + failed + cancelled).' }}
· {{ lang==='ru'?'Время печати суммируется только по завершённым печатям. Если завершённых не было, стоит прочерк, а не ноль.':'Printing time is summed over finished prints only. With no finished prints a dash is shown, not a zero.' }}
· {{ lang==='ru'?'Записи без отметки о завершении в разбивку по принтерам не попадают отдельным столбцом, но входят в общее число запусков — поэтому столбцы могут не сходиться с ним.':'Runs with no completion mark have no column of their own in the per-printer table, yet they count towards the total number of runs — so the columns may not add up to it.' }}
· {{ lang==='ru'?'Глубина отчёта ограничена днём установки модуля «Качество печати»: раньше него история не велась.':'The report goes back only to the day the Print quality module was installed; nothing was recorded before that.' }}
✕
{{ tr('No records yet') }}
{{ tr('Checking connection…') }}
{{ tr('No printers') }}
| {{ tr('Printer') }} | {{ tr('Status') }} | {{ tr('Network') }} | {{ tr('Issues') }} | |
|---|---|---|---|---|
| {{ d.name }}{{ d.model }} | {{ tr(d.state) }} | {{ cdiagNet(d) }} | {{ cdiagIssues(d) }} | |
|
{{ tr('Latency trend') }}
{{ sparkRange((connDetail[d.pid]||d).spark) }}
{{ tr('Speed test unavailable for FlashForge') }}
{{ speedTest[d.pid].result.ok ? speedTest[d.pid].result.text : tr('Test failed') }}
{{ speedTest[d.pid].result.advice }}
|
||||
{{ lang==='ru'?'Сохранённая очередь запуска печати':'Durable print launch queue' }}
{{ dpqActionErr }}
{{ lang==='ru'?'Не удалось загрузить очередь':'Failed to load the queue' }}
{{ lang==='ru'?'Загрузка…':'Loading…' }}
{{ lang==='ru'?'Очередь пуста':'The queue is empty' }}
| {{ lang==='ru'?'Статус':'Status' }} | {{ lang==='ru'?'Принтер':'Printer' }} | {{ lang==='ru'?'Задание':'Job' }} | {{ lang==='ru'?'Старт':'Due' }} | {{ lang==='ru'?'Попыток':'Attempts' }} | {{ lang==='ru'?'Ошибка':'Error' }} | {{ lang==='ru'?'Действие':'Action' }} | |
|---|---|---|---|---|---|---|---|
| {{ dpqStatusLabel(q.status) }} | {{ q.printer_name || q.printer_id }}{{ q.flow }} | {{ q.job_ref || '—' }} | {{ dpqTime(q.due_ts) }} | {{ q.attempts || 0 }} | {{ q.last_error || '—' }} | — |
{{ lang==='ru'?'Перехват команды Bambu Studio':'Bambu Studio command capture' }}
{{ lang==='ru'?'Временный диагностический инструмент. Открывает ОТДЕЛЬНОЕ read-only подключение к принтеру (только подписка на команды, без отправки чего-либо) и показывает, что именно шлёт Bambu Studio при нажатии Send. Порядок: выберите Bambu-принтер → «Начать перехват» → в Bambu Studio запустите печать на ЭТОТ принтер. Останавливается сам через 120 секунд или по кнопке. Коды доступа/пароли не показываются. На печать, очередь и восстановление не влияет.':'Temporary diagnostic tool. Opens a SEPARATE read-only connection to the printer (subscribe only, never sends anything) and shows exactly what Bambu Studio sends on Send. Steps: pick a Bambu printer → Start capture → in Bambu Studio start a print to THIS printer. Auto-stops after 120 seconds or via the button. Access codes/passwords are never shown. Does not affect printing, queue or recovery.' }}
{{ sniffStatusLabel }}
{{ (lang==='ru'?'осталось ':'time left ') + sniffState.remaining_s + (lang==='ru'?' c':'s') }}
{{ (lang==='ru'?'перехвачено: ':'captured: ') + (sniffState.received||0) + ' · ' + (lang==='ru'?'показано ':'shown ') + (sniffState.stored||0) + '/' + (sniffState.max||20) }}
{{ lang==='ru'?'В ферме нет зарегистрированных Bambu-принтеров.':'No registered Bambu printers in the farm.' }}
{{ sniffState.active ? (lang==='ru'?'Слушаем команды. Теперь нажмите Send в Bambu Studio для выбранного принтера…':'Listening. Now press Send in Bambu Studio for the selected printer…') : (lang==='ru'?'Нажмите «Начать перехват», затем отправьте печать из Bambu Studio.':'Click Start capture, then send a print from Bambu Studio.') }}
{{ m.topic }}
project_file
{{ m.command }}
{{ sniffTime(m.ts) }}
{{ sniffFmt(m) }}
{{ (lang==='ru'?'Сообщение не в формате JSON (длина ':'Non-JSON message (length ') + (m.raw_len||0) + (lang==='ru'?' байт), содержимое не показано.':' bytes), content not shown.') }}
{{ namePop.text }}
{{ tr('Select AMS slot:') }}
AMS {{ grp.n }}
{{ getPrinterName(cameraPrinterId) }} — {{ tr('Live') }}
{{ lang==='ru' ? 'Нет связи с камерой' : 'No connection to the camera' }}
✕
{{ tr('Quick access') }}
{{ tr('This PC') }}
{{ tr('File name') }} {{ exSortDir>0?'▲':'▼' }}{{ tr('Modified') }} {{ exSortDir>0?'▲':'▼' }}{{ tr('Type') }} {{ exSortDir>0?'▲':'▼' }}{{ tr('Size') }} {{ exSortDir>0?'▲':'▼' }}
{{ tr('Loading…') }}
{{ tr(exError) }}
{{ tr('This folder is empty') }}
{{ it.is_dir ? '📁' : exIcon(it) }}{{ it.name }}
{{ exIcon(exSelItem) }}
{{ exSelItem.name }}
{{ tr('Select a file to preview') }}
{{ exSelected.length > 1 ? (exSelected.length + ' ' + tr('selected')) : (exSelItem ? exSelItem.name : (exItems.length + ' ' + tr('items'))) }}
{{ tr('Select AMS slot:') }}
AMS {{ grp.n }}
{{ lang==='ru' ? 'Материал закончился' : 'Filament has run out' }}
{{ lang==='ru'
? 'Остальные принтеры уже поставлены в очередь. По этим нужно ваше решение — на складе такой катушки нет.'
: 'The other printers are already queued. These need your decision — there is no such spool in stock.' }}
{{ r.printer_name }}
{{ ((r.material || '') + ' ' + (r.color_name || '')).trim() || tr('the spool') }}
{{ lang==='ru' ? 'нужно' : 'needed' }} {{ r.needed }} {{ lang==='ru' ? 'г' : 'g' }} · {{ lang==='ru' ? 'по учёту' : 'in stock' }} {{ r.available }} {{ lang==='ru' ? 'г' : 'g' }}
{{ r.state==='queued' ? (lang==='ru' ? 'В очереди' : 'Queued') : (r.state==='skipped' ? (lang==='ru' ? 'Пропущен' : 'Skipped') : (lang==='ru' ? 'Не удалось' : 'Failed')) }}
{{ lang==='ru'
? '«Поставил новую катушку» оприходует её и поставит в слот. «Печатать всё равно» запустит печать и спишет остаток в ноль — с записью в журнале склада.'
: '“I mounted a new spool” receives it into stock and binds it to the slot. “Print anyway” starts the print and writes the leftover down to zero, with a stock-ledger entry.' }}
{{ tr('Select model') }}
{{ g.brand === 'Generic' ? tr('Generic') : g.brand }}
{{ tr('No model covers found — put the cover PNGs into a printer_covers folder next to server.py.') }}