541 lines
32 KiB
HTML
Executable file
541 lines
32 KiB
HTML
Executable file
<!DOCTYPE html>
|
||
<html lang="ru">
|
||
<head>
|
||
<meta charset="UTF-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||
<title>YOLO Train Studio</title>
|
||
<!-- Google Fonts -->
|
||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||
<link rel="icon" type="image/svg+xml" href="/static/favicon.svg">
|
||
<link rel="stylesheet" href="/static/style.css?v=6">
|
||
</head>
|
||
<body>
|
||
<header class="app-header">
|
||
<div class="header-logo">
|
||
<svg class="logo-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
||
<path d="M21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16z"></path>
|
||
<polyline points="3.27 6.96 12 12.01 20.73 6.96"></polyline>
|
||
<line x1="12" y1="22.08" x2="12" y2="12"></line>
|
||
</svg>
|
||
<div class="logo-text" style="margin-right: 2rem;">
|
||
<h1>YOLO Train Studio</h1>
|
||
<span>Интерфейс обучения модели</span>
|
||
</div>
|
||
<div class="view-tabs" style="display: flex; gap: 10px;">
|
||
<button class="view-btn active" data-view="train-view">Обучение</button>
|
||
<button class="view-btn" data-view="export-view">Экспорт</button>
|
||
</div>
|
||
</div>
|
||
<div class="header-actions">
|
||
<a href="http://localhost:5000" target="_blank" rel="noopener noreferrer" class="mlflow-link" id="mlflow-header-link">
|
||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" class="link-icon">
|
||
<path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"></path>
|
||
<polyline points="15 3 21 3 21 9"></polyline>
|
||
<line x1="10" y1="14" x2="21" y2="3"></line>
|
||
</svg>
|
||
Открыть MLflow UI
|
||
</a>
|
||
</div>
|
||
</header>
|
||
|
||
<main class="app-workspace">
|
||
<div id="train-view" class="workspace-view active">
|
||
<!-- Configuration Card -->
|
||
<section class="pane" id="config-pane">
|
||
<!-- Session Controls -->
|
||
<div class="session-controls">
|
||
<div class="session-header">
|
||
<svg class="session-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
||
<path d="M19 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11l5 5v11a2 2 0 0 1-2 2z"></path>
|
||
<polyline points="17 21 17 13 7 13 7 21"></polyline>
|
||
<polyline points="7 3 7 8 15 8"></polyline>
|
||
</svg>
|
||
<h3>Профили конфигурации</h3>
|
||
</div>
|
||
<div class="session-body">
|
||
<div class="session-row">
|
||
<div class="session-field">
|
||
<label for="session-select">Активный профиль</label>
|
||
<select id="session-select">
|
||
<option value="">По умолчанию (Последний запуск)</option>
|
||
</select>
|
||
</div>
|
||
<button type="button" id="session-delete-btn" class="btn-action btn-delete" disabled title="Удалить выбранный профиль">
|
||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" class="btn-icon-small"><polyline points="3 6 5 6 21 6"></polyline><path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"></path></svg>
|
||
</button>
|
||
</div>
|
||
<div class="session-row">
|
||
<div class="session-field">
|
||
<label for="session-name">Сохранить текущие настройки как профиль</label>
|
||
<input type="text" id="session-name" pattern="[A-Za-z0-9_-]+" autocomplete="off" placeholder="Введите имя профиля...">
|
||
</div>
|
||
<button type="button" id="session-save-btn" class="btn-action btn-save" title="Сохранить настройки">
|
||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" class="btn-icon-small"><path d="M19 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11l5 5v11a2 2 0 0 1-2 2z"></path><polyline points="17 21 17 13 7 13 7 21"></polyline></svg>
|
||
</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="tabs">
|
||
<button class="tab-btn active" data-tab="general">Основное</button>
|
||
<button class="tab-btn" data-tab="training">Обучение</button>
|
||
<button class="tab-btn" data-tab="augmentation">Аугментация</button>
|
||
<button class="tab-btn" data-tab="mlflow">MLflow</button>
|
||
</div>
|
||
|
||
<form id="config-form" class="form-container">
|
||
<!-- GENERAL TAB -->
|
||
<div class="tab-content active" id="tab-general">
|
||
<div class="form-section-title">Модель и Данные</div>
|
||
<div class="field">
|
||
<label for="task">Тип задачи</label>
|
||
<select id="task" name="task">
|
||
<option value="detect">Detect (Детекция)</option>
|
||
<option value="segment">Segment (Сегментация)</option>
|
||
<option value="classify">Classify (Классификация)</option>
|
||
<option value="pose">Pose (Позы)</option>
|
||
<option value="obb">OBB (Ориентированные боксы)</option>
|
||
</select>
|
||
</div>
|
||
<div class="field">
|
||
<label for="model-select">Выбор модели</label>
|
||
<select id="model-select">
|
||
<!-- Populated dynamically via JS based on task -->
|
||
</select>
|
||
</div>
|
||
<div class="field" id="model-custom-wrapper" style="display: none;">
|
||
<label for="model">Имя весов или путь к модели вручную</label>
|
||
<input type="text" id="model" name="model" placeholder="например, yolo11n.pt или /workspace/runs/.../best.pt">
|
||
</div>
|
||
<div class="field">
|
||
<label for="dataset-select">Выбор датасета</label>
|
||
<select id="dataset-select">
|
||
<option value="">Поиск локальных датасетов...</option>
|
||
</select>
|
||
</div>
|
||
<div class="field" id="dataset-custom-wrapper" style="display: none;">
|
||
<label for="dataset">Путь к датасету вручную</label>
|
||
<input type="text" id="dataset" name="dataset" placeholder="например, coco8.yaml или /workspace/datasets/custom">
|
||
</div>
|
||
|
||
<div class="form-section-title">Разделение данных (Train/Val)</div>
|
||
<div class="toggle-row">
|
||
<div class="toggle-label">
|
||
<h3>Автоматическое разделение</h3>
|
||
<p>Разделить датасет на train/val перед запуском</p>
|
||
</div>
|
||
<label class="switch-container">
|
||
<input type="checkbox" id="split-enabled">
|
||
<span class="switch-slider"></span>
|
||
</label>
|
||
</div>
|
||
<div class="row split-fields">
|
||
<div class="field">
|
||
<label for="split-ratio">Доля train (0.1…0.95)</label>
|
||
<input type="number" id="split-ratio" name="split-ratio" step="0.05" min="0.1" max="0.95" value="0.8">
|
||
</div>
|
||
<div class="field">
|
||
<label for="split-classes">Файл классов (classes.txt / YAML)</label>
|
||
<input type="text" id="split-classes" name="split-classes" placeholder="Автопоиск">
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- TRAINING TAB -->
|
||
<div class="tab-content" id="tab-training">
|
||
<div class="form-section-title">Гиперпараметры</div>
|
||
<div class="row">
|
||
<div class="field">
|
||
<label for="epochs">Количество эпох</label>
|
||
<input type="number" id="epochs" name="epochs" min="1" value="100">
|
||
</div>
|
||
<div class="field">
|
||
<label for="image-size">Размер изображения</label>
|
||
<input type="number" id="image-size" name="image-size" min="32" value="640">
|
||
</div>
|
||
<div class="field">
|
||
<label for="batch-size">Размер батча (Batch)</label>
|
||
<input type="number" id="batch-size" name="batch-size" min="-1" value="16">
|
||
</div>
|
||
</div>
|
||
<div class="row">
|
||
<div class="field">
|
||
<label for="device">Устройство (Device)</label>
|
||
<input type="text" id="device" name="device" placeholder="cpu, 0, 0,1">
|
||
</div>
|
||
<div class="field">
|
||
<label for="workers">Потоки загрузки (Workers)</label>
|
||
<input type="number" id="workers" name="workers" min="0" value="8">
|
||
</div>
|
||
<div class="field">
|
||
<label for="patience">Ожидание (Patience)</label>
|
||
<input type="number" id="patience" name="patience" min="0" value="100">
|
||
</div>
|
||
</div>
|
||
<div class="row">
|
||
<div class="field">
|
||
<label for="project">Каталог результатов</label>
|
||
<input type="text" id="project" name="project" value="runs/train">
|
||
</div>
|
||
<div class="field">
|
||
<label for="run-name">Имя запуска</label>
|
||
<input type="text" id="run-name" name="run-name" placeholder="experiment-01">
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- AUGMENTATION TAB -->
|
||
<div class="tab-content" id="tab-augmentation">
|
||
<div class="toggle-row">
|
||
<div class="toggle-label">
|
||
<h3>Пользовательские аугментации</h3>
|
||
<p>Передавать параметры аугментации в Ultralytics</p>
|
||
</div>
|
||
<label class="switch-container">
|
||
<input type="checkbox" id="augmentation-enabled" checked>
|
||
<span class="switch-slider"></span>
|
||
</label>
|
||
</div>
|
||
|
||
<div class="augmentation-fields">
|
||
<div class="form-section-title">Цветовые (HSV)</div>
|
||
<div class="row">
|
||
<div class="field">
|
||
<label for="hsv-h">HSV Hue (0…1)</label>
|
||
<input type="number" id="hsv-h" name="hsv-h" step="0.005" min="0" max="1" value="0.015">
|
||
</div>
|
||
<div class="field">
|
||
<label for="hsv-s">HSV Saturation (0…1)</label>
|
||
<input type="number" id="hsv-s" name="hsv-s" step="0.05" min="0" max="1" value="0.7">
|
||
</div>
|
||
<div class="field">
|
||
<label for="hsv-v">HSV Value/Brightness (0…1)</label>
|
||
<input type="number" id="hsv-v" name="hsv-v" step="0.05" min="0" max="1" value="0.4">
|
||
</div>
|
||
</div>
|
||
|
||
<div class="form-section-title">Геометрические</div>
|
||
<div class="row">
|
||
<div class="field">
|
||
<label for="degrees">Поворот (град.)</label>
|
||
<input type="number" id="degrees" name="degrees" step="0.5" min="0" value="0.0">
|
||
</div>
|
||
<div class="field">
|
||
<label for="translate">Смещение (0…1)</label>
|
||
<input type="number" id="translate" name="translate" step="0.05" min="0" max="1" value="0.1">
|
||
</div>
|
||
<div class="field">
|
||
<label for="scale">Масштаб (0…1)</label>
|
||
<input type="number" id="scale" name="scale" step="0.05" min="0" max="1" value="0.5">
|
||
</div>
|
||
</div>
|
||
<div class="row">
|
||
<div class="field">
|
||
<label for="shear">Сдвиг (град.)</label>
|
||
<input type="number" id="shear" name="shear" step="0.5" min="0" value="0.0">
|
||
</div>
|
||
<div class="field">
|
||
<label for="perspective">Перспектива (0…1)</label>
|
||
<input type="number" id="perspective" name="perspective" step="0.001" min="0" max="1" value="0.0">
|
||
</div>
|
||
<div class="field">
|
||
<label for="close-mosaic">Закрыть mosaic (эпох)</label>
|
||
<input type="number" id="close-mosaic" name="close-mosaic" min="0" value="10">
|
||
</div>
|
||
</div>
|
||
<div class="row">
|
||
<div class="field">
|
||
<label for="flipud">Flip вверх/вниз</label>
|
||
<input type="number" id="flipud" name="flipud" step="0.1" min="0" max="1" value="0.0">
|
||
</div>
|
||
<div class="field">
|
||
<label for="fliplr">Flip влево/вправо</label>
|
||
<input type="number" id="fliplr" name="fliplr" step="0.1" min="0" max="1" value="0.5">
|
||
</div>
|
||
<div class="field">
|
||
<label for="bgr">RGB ↔ BGR (0…1)</label>
|
||
<input type="number" id="bgr" name="bgr" step="0.1" min="0" max="1" value="0.0">
|
||
</div>
|
||
</div>
|
||
|
||
<div class="form-section-title">Составные</div>
|
||
<div class="row">
|
||
<div class="field">
|
||
<label for="mosaic">Mosaic (0…1)</label>
|
||
<input type="number" id="mosaic" name="mosaic" step="0.1" min="0" max="1" value="1.0">
|
||
</div>
|
||
<div class="field">
|
||
<label for="mixup">MixUp (0…1)</label>
|
||
<input type="number" id="mixup" name="mixup" step="0.1" min="0" max="1" value="0.0">
|
||
</div>
|
||
<div class="field">
|
||
<label for="cutmix">CutMix (0…1)</label>
|
||
<input type="number" id="cutmix" name="cutmix" step="0.1" min="0" max="1" value="0.0">
|
||
</div>
|
||
</div>
|
||
<div class="row">
|
||
<div class="field">
|
||
<label for="copy-paste">Copy-paste (0…1)</label>
|
||
<input type="number" id="copy-paste" name="copy-paste" step="0.1" min="0" max="1" value="0.0">
|
||
</div>
|
||
<div class="field">
|
||
<label for="erasing">Erasing (0…1)</label>
|
||
<input type="number" id="erasing" name="erasing" step="0.05" min="0" max="1" value="0.4">
|
||
</div>
|
||
<div class="field">
|
||
<label for="copy-paste-mode">Режим Copy-paste</label>
|
||
<select id="copy-paste-mode" name="copy-paste-mode">
|
||
<option value="flip">Flip</option>
|
||
<option value="mixup">Mixup</option>
|
||
</select>
|
||
</div>
|
||
</div>
|
||
<div class="field">
|
||
<label for="auto-augment">AutoAugment политика (classify)</label>
|
||
<select id="auto-augment" name="auto-augment">
|
||
<option value="none">Отключено</option>
|
||
<option value="randaugment">RandAugment</option>
|
||
<option value="autoaugment">AutoAugment</option>
|
||
<option value="augmix">AugMix</option>
|
||
</select>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- MLFLOW TAB -->
|
||
<div class="tab-content" id="tab-mlflow">
|
||
<div class="toggle-row">
|
||
<div class="toggle-label">
|
||
<h3>Интеграция MLflow</h3>
|
||
<p>Записывать параметры, метрики и checkpoints</p>
|
||
</div>
|
||
<label class="switch-container">
|
||
<input type="checkbox" id="mlflow-enabled" checked>
|
||
<span class="switch-slider"></span>
|
||
</label>
|
||
</div>
|
||
|
||
<div class="mlflow-fields">
|
||
<div class="field">
|
||
<label for="tracking-uri">Tracking URI</label>
|
||
<input type="text" id="tracking-uri" name="tracking-uri" value="sqlite:///mlflow.db" placeholder="http://127.0.0.1:5000">
|
||
</div>
|
||
<div class="row">
|
||
<div class="field">
|
||
<label for="experiment-name">Название эксперимента</label>
|
||
<input type="text" id="experiment-name" name="experiment-name" value="yolo-webui">
|
||
</div>
|
||
<div class="field">
|
||
<label for="mlflow-run-name">Имя запуска (Run Name)</label>
|
||
<input type="text" id="mlflow-run-name" name="mlflow-run-name" placeholder="Автоматически">
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</form>
|
||
</section>
|
||
|
||
<!-- Monitoring Card -->
|
||
<section class="pane" id="run-pane">
|
||
<!-- Status Card -->
|
||
<div id="status-card" class="status-idle">
|
||
<div class="status-header">
|
||
<div class="status-indicator">
|
||
<span class="status-dot"></span>
|
||
<h2 id="status-title">ГОТОВО К ЗАПУСКУ</h2>
|
||
</div>
|
||
<div class="status-timer" id="status-timer">00:00:00</div>
|
||
</div>
|
||
<p id="status-text">Проверьте параметры и начните обучение.</p>
|
||
<div class="progress-container">
|
||
<div class="progress-bar-wrapper">
|
||
<div class="progress-bar-fill" id="progress-bar-fill" style="width: 0%"></div>
|
||
</div>
|
||
<div class="progress-meta">
|
||
<span id="progress-text">Эпохи: 0 / 100</span>
|
||
<span id="progress-eta">ETA: --:--:--</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Action Buttons -->
|
||
<div class="action-buttons">
|
||
<button type="button" id="start-btn" class="btn btn-primary">
|
||
<svg viewBox="0 0 24 24" fill="currentColor" class="btn-icon">
|
||
<path d="M8 5v14l11-7z"></path>
|
||
</svg>
|
||
Начать обучение
|
||
</button>
|
||
<button type="button" id="stop-btn" class="btn btn-danger" disabled>
|
||
<svg viewBox="0 0 24 24" fill="currentColor" class="btn-icon">
|
||
<path d="M6 19h4V5H6v14zm8-14v14h4V5h-4z"></path>
|
||
</svg>
|
||
Остановить
|
||
</button>
|
||
</div>
|
||
|
||
<!-- Logs Box -->
|
||
<div class="log-card">
|
||
<div class="log-header">
|
||
<h3>Журнал</h3>
|
||
<div class="log-actions">
|
||
<label class="checkbox-inline">
|
||
<input type="checkbox" id="autoscroll" checked>
|
||
Автопрокрутка
|
||
</label>
|
||
<button type="button" id="clear-log-btn" class="btn-text">Очистить</button>
|
||
</div>
|
||
</div>
|
||
<div class="log-body" id="log-container">
|
||
<div class="log-line log-level-info">Интерфейс готов. Ожидание запуска...</div>
|
||
</div>
|
||
</div>
|
||
|
||
</section>
|
||
</div> <!-- End train-view -->
|
||
|
||
<div id="export-view" class="workspace-view">
|
||
<!-- Export Configuration Card -->
|
||
<section class="pane" id="export-config-pane">
|
||
<div class="tabs">
|
||
<button type="button" class="export-tab-btn active" style="flex: 1; background: var(--accent-gradient); border: none; border-radius: 6px; color: #fff; font-family: var(--font-sans); font-size: 0.9rem; font-weight: 600; padding: 0.6rem; cursor: default; box-shadow: 0 4px 10px rgba(0, 0, 0, 0.25);">Настройки экспорта</button>
|
||
</div>
|
||
<form id="export-form" class="form-container">
|
||
<div style="display: block;">
|
||
<div class="form-section-title">Параметры модели</div>
|
||
<div class="field">
|
||
<label for="export-model-select">Модель для экспорта</label>
|
||
<select id="export-model-select">
|
||
<option value="">Поиск моделей...</option>
|
||
</select>
|
||
</div>
|
||
<div class="field" id="export-model-custom-wrapper" style="display: none;">
|
||
<label for="export-model">Имя весов или путь к модели вручную</label>
|
||
<input type="text" id="export-model" name="export-model" placeholder="например, /workspace/runs/.../best.pt">
|
||
</div>
|
||
<div class="field">
|
||
<label for="export-format">Формат экспорта</label>
|
||
<select id="export-format" name="export-format">
|
||
<option value="onnx">ONNX (.onnx)</option>
|
||
<option value="engine">TensorRT (.engine)</option>
|
||
<option value="openvino">OpenVINO (_openvino_model/)</option>
|
||
<option value="torchscript">TorchScript (.torchscript)</option>
|
||
<option value="coreml">CoreML (.mlpackage)</option>
|
||
<option value="tflite">TFLite (.tflite)</option>
|
||
<option value="saved_model">TensorFlow SavedModel (_saved_model/)</option>
|
||
<option value="pb">TensorFlow GraphDef (.pb)</option>
|
||
</select>
|
||
</div>
|
||
|
||
<div class="form-section-title">Опции</div>
|
||
<div class="row">
|
||
<div class="field">
|
||
<label for="export-imgsz">Размер изображения (imgsz)</label>
|
||
<input type="number" id="export-imgsz" name="export-imgsz" value="640" min="32" max="8192" step="1" required>
|
||
</div>
|
||
<div class="field">
|
||
<label for="export-batch" title="Максимальный размер батча. Важен при Dynamic=True для TensorRT.">Макс. батч (batch)</label>
|
||
<input type="number" id="export-batch" name="export-batch" value="1" min="1" max="1024" step="1" required>
|
||
</div>
|
||
<div class="field">
|
||
<label for="export-workspace" title="Размер памяти для сборки TensorRT (ГБ).">Workspace (ГБ)</label>
|
||
<input type="number" id="export-workspace" name="export-workspace" value="4" min="1" max="64" step="0.5" required>
|
||
</div>
|
||
</div>
|
||
<div class="row">
|
||
<div class="toggle-row" style="padding: 10px 0;">
|
||
<div class="toggle-label">
|
||
<h3>FP16 (Half)</h3>
|
||
<p>Использовать полуточность</p>
|
||
</div>
|
||
<label class="switch-container">
|
||
<input type="checkbox" id="export-half">
|
||
<span class="switch-slider"></span>
|
||
</label>
|
||
</div>
|
||
<div class="toggle-row" style="padding: 10px 0;">
|
||
<div class="toggle-label">
|
||
<h3>INT8</h3>
|
||
<p>Квантование до INT8</p>
|
||
</div>
|
||
<label class="switch-container">
|
||
<input type="checkbox" id="export-int8">
|
||
<span class="switch-slider"></span>
|
||
</label>
|
||
</div>
|
||
<div class="toggle-row" style="padding: 10px 0;">
|
||
<div class="toggle-label">
|
||
<h3>Dynamic</h3>
|
||
<p>Динамические оси</p>
|
||
</div>
|
||
<label class="switch-container">
|
||
<input type="checkbox" id="export-dynamic">
|
||
<span class="switch-slider"></span>
|
||
</label>
|
||
</div>
|
||
<div class="toggle-row" style="padding: 10px 0;">
|
||
<div class="toggle-label" title="Только для ONNX. Оптимизирует и упрощает граф модели.">
|
||
<h3>Simplify</h3>
|
||
<p>Упростить граф (ONNX)</p>
|
||
</div>
|
||
<label class="switch-container">
|
||
<input type="checkbox" id="export-simplify">
|
||
<span class="switch-slider"></span>
|
||
</label>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</form>
|
||
</section>
|
||
|
||
<!-- Export Monitoring Card -->
|
||
<section class="pane" id="export-run-pane">
|
||
<div id="export-status-card" class="status-idle">
|
||
<div class="status-header">
|
||
<div class="status-indicator">
|
||
<span class="status-dot"></span>
|
||
<h2 id="export-status-title">ГОТОВО К ЭКСПОРТУ</h2>
|
||
</div>
|
||
</div>
|
||
<p id="export-status-text">Выберите модель и формат для начала.</p>
|
||
</div>
|
||
|
||
<!-- Action Buttons -->
|
||
<div class="action-buttons">
|
||
<button type="button" id="export-start-btn" class="btn btn-primary">
|
||
<svg viewBox="0 0 24 24" fill="currentColor" class="btn-icon">
|
||
<path d="M8 5v14l11-7z"></path>
|
||
</svg>
|
||
Начать экспорт
|
||
</button>
|
||
<button type="button" id="export-stop-btn" class="btn btn-danger" disabled>
|
||
<svg viewBox="0 0 24 24" fill="currentColor" class="btn-icon">
|
||
<path d="M6 19h4V5H6v14zm8-14v14h4V5h-4z"></path>
|
||
</svg>
|
||
Остановить
|
||
</button>
|
||
</div>
|
||
|
||
<!-- Logs Box -->
|
||
<div class="log-card" style="flex: 1;">
|
||
<div class="log-header">
|
||
<h3>Журнал экспорта</h3>
|
||
<div class="log-actions">
|
||
<label class="checkbox-inline">
|
||
<input type="checkbox" id="export-autoscroll" checked>
|
||
Автопрокрутка
|
||
</label>
|
||
<button type="button" id="export-clear-log-btn" class="btn-text">Очистить</button>
|
||
</div>
|
||
</div>
|
||
<div class="log-body" id="export-log-container">
|
||
<div class="log-line log-level-info">Ожидание запуска экспорта...</div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
</div> <!-- End export-view -->
|
||
</main>
|
||
<script src="/static/app.js?v=6"></script>
|
||
</body>
|
||
</html>
|