From 52da9a39234b10e24cab09fe6f5c002ba3589c1c Mon Sep 17 00:00:00 2001 From: Repinoid Date: Wed, 16 Sep 2026 07:42:31 +0300 Subject: [PATCH] Update upload interface and ignore temporary E2E artifacts --- .github/CODERULES.md | 2 +- .gitignore | 2 + site/templates/index.html | 1397 +++++++++++++++++++++++-------------- 3 files changed, 860 insertions(+), 541 deletions(-) diff --git a/.github/CODERULES.md b/.github/CODERULES.md index 9ed4540..a68c3c0 100644 --- a/.github/CODERULES.md +++ b/.github/CODERULES.md @@ -3,7 +3,7 @@ - НЕЛЬЗЯ менять ЧТО-ЛИБО при вопросе (?, почему, как, где, что) — только ответ словами - НЕЛЬЗЯ спешить — обдумать, проверить, потом отвечать - НЕЛЬЗЯ лезть в /home/naeel/nubes/contracts/ (кроме loadtest) -- НЕЛЬЗЯ предполагать — сомневаешься = спроси +- НИКОГДА не руководствоваться догадками. Если что-либо неизвестно точно или недоступно — немедленно остановиться и сообщить об этом; не продолжать действие и не выдавать предположение за факт. - НЕЛЬЗЯ грузить внешние CDN/библиотеки на фронтенд — всё в коде # ✅ ПОРЯДОК ПРАВКИ diff --git a/.gitignore b/.gitignore index 69e83b4..b36f1f7 100644 --- a/.gitignore +++ b/.gitignore @@ -26,6 +26,8 @@ dist/ # about1500.md *.har chrome-net-export-log.json +History/tests/2026-09-15-*.md +tests/e2e_mass_processing.py TSTFILES/ files/ upload-platform/ diff --git a/site/templates/index.html b/site/templates/index.html index a43c5e9..56f018c 100644 --- a/site/templates/index.html +++ b/site/templates/index.html @@ -1,5 +1,6 @@ + @@ -20,622 +21,938 @@ --red: #ef4444; --green: #22c55e; } - * { box-sizing: border-box; margin: 0; padding: 0; } - body { font: 14px system-ui, sans-serif; color: var(--text); background: var(--bg); min-height: 100vh; } + + * { + box-sizing: border-box; + margin: 0; + padding: 0; + } + + body { + font: 14px system-ui, sans-serif; + color: var(--text); + background: var(--bg); + min-height: 100vh; + } + .topbar { - background: var(--card); border-bottom: 1px solid var(--brand-gray); - padding: 0 16px; height: 48px; display: flex; align-items: center; gap: 10px; + background: var(--card); + border-bottom: 1px solid var(--brand-gray); + padding: 0 16px; + height: 48px; + display: flex; + align-items: center; + gap: 10px; } - .topbar img { height: 18px; } - .topbar .title { font-weight: 600; font-size: 14px; } - .topbar .ver { font-weight: 400; color: var(--muted); font-size: 12px; } + + .topbar img { + height: 18px; + } + + .topbar .title { + font-weight: 600; + font-size: 14px; + } + + .topbar .ver { + font-weight: 400; + color: var(--muted); + font-size: 12px; + } + .topbar .help { - margin-left: auto; cursor: pointer; text-decoration: none; user-select: none; - display: inline-flex; align-items: center; justify-content: center; - padding: 5px 14px; border-radius: 6px; - background: #1d4ed8; color: #fff; font-size: 13px; font-weight: 700; line-height: 1; + margin-left: auto; + cursor: pointer; + text-decoration: none; + user-select: none; + display: inline-flex; + align-items: center; + justify-content: center; + padding: 5px 14px; + border-radius: 6px; + background: #1d4ed8; + color: #fff; + font-size: 13px; + font-weight: 700; + line-height: 1; letter-spacing: .06em; - box-shadow: 0 1px 3px rgba(0,0,0,.25); + box-shadow: 0 1px 3px rgba(0, 0, 0, .25); } - .topbar .help:hover { background: #1e40af; color: #fff; } - .content { max-width: 820px; margin: 20px auto; padding: 0 12px; } + + .topbar .help:hover { + background: #1e40af; + color: #fff; + } + + .content { + max-width: 820px; + margin: 20px auto; + padding: 0 12px; + } + .card { - background: var(--card); border-radius: 12px; - border: 1px solid var(--brand-gray); box-shadow: 0 1px 2px rgba(0,0,0,.04); + background: var(--card); + border-radius: 12px; + border: 1px solid var(--brand-gray); + box-shadow: 0 1px 2px rgba(0, 0, 0, .04); } + .card-header { - background: var(--brand-grey-light); padding: 10px 12px; - font-weight: 600; font-size: 14px; border-bottom: 1px solid var(--brand-gray); + background: var(--brand-grey-light); + padding: 10px 12px; + font-weight: 600; + font-size: 14px; + border-bottom: 1px solid var(--brand-gray); + } + + .card-body { + padding: 12px; + } + + .sub { + font-size: 12px; + color: var(--muted); + margin-bottom: 10px; + line-height: 1.5; } - .card-body { padding: 12px; } - .sub { font-size: 12px; color: var(--muted); margin-bottom: 10px; line-height: 1.5; } /* FilePicker styling */ - .file-picker { font-family: inherit; color: var(--text); } - .file-picker .fp-toolbar { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 10px; } + .file-picker { + font-family: inherit; + color: var(--text); + } + + .file-picker .fp-toolbar { + display: flex; + flex-wrap: wrap; + gap: 8px; + margin-bottom: 10px; + } + .file-picker .fp-toolbar button { - height: 32px; border-radius: 6px; padding: 0 12px; font-size: 13px; - font-family: inherit; cursor: pointer; border: 1px solid var(--brand-gray); - background: var(--card); color: var(--text); - display: inline-flex; align-items: center; gap: 5px; font-weight: 500; + height: 32px; + border-radius: 6px; + padding: 0 12px; + font-size: 13px; + font-family: inherit; + cursor: pointer; + border: 1px solid var(--brand-gray); + background: var(--card); + color: var(--text); + display: inline-flex; + align-items: center; + gap: 5px; + font-weight: 500; } - .file-picker .fp-toolbar button#fp-files-btn { background: #eff6ff; border-color: var(--brand-primary); color: var(--brand-primary); } - .file-picker .fp-toolbar button#fp-folder-btn { background: var(--card); } - .file-picker .fp-toolbar button#fp-clear-btn { color: var(--muted); border-color: transparent; } - .file-picker .fp-toolbar button#fp-clear-btn:hover { color: var(--red); } - .file-picker .fp-table-wrap { border: 1px solid var(--brand-gray); border-radius: 8px; overflow: hidden; margin-bottom: 6px; } - .file-picker .fp-table { width: 100%; border-collapse: collapse; font-size: 13px; } + + .file-picker .fp-toolbar button#fp-files-btn { + background: #eff6ff; + border-color: var(--brand-primary); + color: var(--brand-primary); + } + + .file-picker .fp-toolbar button#fp-folder-btn { + background: var(--card); + } + + .file-picker .fp-toolbar button#fp-clear-btn { + color: var(--muted); + border-color: transparent; + } + + .file-picker .fp-toolbar button#fp-clear-btn:hover { + color: var(--red); + } + + .file-picker .fp-table-wrap { + border: 1px solid var(--brand-gray); + border-radius: 8px; + overflow: hidden; + margin-bottom: 6px; + } + + .file-picker .fp-table { + width: 100%; + border-collapse: collapse; + font-size: 13px; + } + .file-picker .fp-table th { - background: var(--brand-grey-light); text-transform: uppercase; padding: 6px 8px; - border-right: 1px solid var(--brand-gray); border-bottom: 1px solid var(--brand-gray); - text-align: left; font-weight: 600; font-size: 10px; color: var(--muted); + background: var(--brand-grey-light); + text-transform: uppercase; + padding: 6px 8px; + border-right: 1px solid var(--brand-gray); + border-bottom: 1px solid var(--brand-gray); + text-align: left; + font-weight: 600; + font-size: 10px; + color: var(--muted); } + .file-picker .fp-table td { - padding: 5px 8px; border-right: 1px solid var(--brand-gray); border-bottom: 1px solid var(--brand-gray); + padding: 5px 8px; + border-right: 1px solid var(--brand-gray); + border-bottom: 1px solid var(--brand-gray); } - .file-picker .tree-row:hover td { background: rgba(37,99,235,.03); } - .file-picker .tree-row.row-current td { background: rgba(37,99,235,.12) !important; color: #1d4ed8; font-weight: 600; } + + .file-picker .tree-row:hover td { + background: rgba(37, 99, 235, .03); + } + + .file-picker .tree-row.row-current td { + background: rgba(37, 99, 235, .12) !important; + color: #1d4ed8; + font-weight: 600; + } + .file-picker .tree-name { - display: inline-flex; align-items: center; gap: 6px; border: 0; background: transparent; - color: inherit; font: inherit; text-align: left; cursor: pointer; + display: inline-flex; + align-items: center; + gap: 6px; + border: 0; + background: transparent; + color: inherit; + font: inherit; + text-align: left; + cursor: pointer; } - .file-picker .tree-chevron { display: inline-block; width: 12px; color: var(--muted); font-size: 9px; } - .file-picker .fp-status { font-size: 12px; color: var(--muted); margin: 4px 0; } - .file-picker .fp-count { display: none; } + + .file-picker .tree-chevron { + display: inline-block; + width: 12px; + color: var(--muted); + font-size: 9px; + } + + .file-picker .fp-status { + font-size: 12px; + color: var(--muted); + margin: 4px 0; + } + + .file-picker .fp-count { + display: none; + } + .file-picker .remove-btn { - cursor: pointer; color: #f87171; background: none; border: none; - padding: 2px 4px; font-size: 14px; line-height: 1; + cursor: pointer; + color: #f87171; + background: none; + border: none; + padding: 2px 4px; + font-size: 14px; + line-height: 1; + } + + .file-picker .remove-btn:hover { + color: var(--red); + } + + body.busy .file-picker button { + pointer-events: none; + opacity: 0.5; + } + + body.busy .file-picker .remove-btn { + display: none; } - .file-picker .remove-btn:hover { color: var(--red); } - body.busy .file-picker button { pointer-events: none; opacity: 0.5; } - body.busy .file-picker .remove-btn { display: none; } .footer-bar { - margin-top: 10px; display: flex; justify-content: space-between; align-items: center; - font-size: 12px; color: var(--muted); + margin-top: 10px; + display: flex; + justify-content: space-between; + align-items: center; + font-size: 12px; + color: var(--muted); } + .btn { - height: 32px; border-radius: 6px; padding: 0 12px; font-size: 13px; - font-family: inherit; cursor: pointer; border: 1px solid var(--brand-gray); - background: var(--card); color: var(--text); - display: inline-flex; align-items: center; gap: 5px; + height: 32px; + border-radius: 6px; + padding: 0 12px; + font-size: 13px; + font-family: inherit; + cursor: pointer; + border: 1px solid var(--brand-gray); + background: var(--card); + color: var(--text); + display: inline-flex; + align-items: center; + gap: 5px; } - .btn-primary { background: var(--brand-primary); border-color: var(--brand-primary); color: #fff; } - .btn-primary:hover { opacity: .9; } - .btn:disabled { opacity: .4; cursor: not-allowed; } - .status { margin-top: 10px; padding: 8px 12px; border-radius: 8px; font-size: 13px; display: none; } - .status.progress { background: #eff6ff; border: 1px solid var(--brand-primary); color: var(--brand-primary); display: block; } - .status.done { background: #f0fdf4; border: 1px solid var(--green); color: #16a34a; display: block; } - .status.error { background: #fef2f2; border: 1px solid var(--red); color: #991b1b; display: block; } - .dl-btns { display: none; gap: 8px; margin-top: 8px; } - .dl-btns.show { display: flex; } + + .btn-primary { + background: var(--brand-primary); + border-color: var(--brand-primary); + color: #fff; + } + + .btn-primary:hover { + opacity: .9; + } + + .btn:disabled { + opacity: .4; + cursor: not-allowed; + } + + .status { + margin-top: 10px; + padding: 8px 12px; + border-radius: 8px; + font-size: 13px; + display: none; + } + + .status.progress { + background: #eff6ff; + border: 1px solid var(--brand-primary); + color: var(--brand-primary); + display: block; + } + + .status.done { + background: #f0fdf4; + border: 1px solid var(--green); + color: #16a34a; + display: block; + } + + .status.error { + background: #fef2f2; + border: 1px solid var(--red); + color: #991b1b; + display: block; + } + + .dl-btns { + display: none; + gap: 8px; + margin-top: 8px; + } + + .dl-btns.show { + display: flex; + } + .stats-block { - display: none; margin-top: 12px; padding: 16px; + display: none; + margin-top: 12px; + padding: 16px; background: linear-gradient(135deg, #f0fdf4, #ecfdf5); - border: 2px solid var(--green); border-radius: 12px; + border: 2px solid var(--green); + border-radius: 12px; } - .stats-block.show { display: block; } - .stats-title { font-size: 16px; font-weight: 700; color: #14532d; margin-bottom: 10px; } - .stats-row { display: flex; flex-wrap: wrap; gap: 10px; } + + .stats-block.show { + display: block; + } + + .stats-title { + font-size: 16px; + font-weight: 700; + color: #14532d; + margin-bottom: 10px; + } + + .stats-row { + display: flex; + flex-wrap: wrap; + gap: 10px; + } + .stat-item { - flex: 1; min-width: 130px; background: #fff; border: 1px solid #bbf7d0; - border-radius: 10px; padding: 10px 12px; text-align: center; + flex: 1; + min-width: 130px; + background: #fff; + border: 1px solid #bbf7d0; + border-radius: 10px; + padding: 10px 12px; + text-align: center; } - .stat-label { font-size: 12px; text-transform: uppercase; letter-spacing: .04em; color: var(--muted); margin-bottom: 4px; } - .stat-value { font-size: 24px; font-weight: 800; color: #166534; } + + .stat-label { + font-size: 12px; + text-transform: uppercase; + letter-spacing: .04em; + color: var(--muted); + margin-bottom: 4px; + } + + .stat-value { + font-size: 24px; + font-weight: 800; + color: #166534; + } + .live-block { - display: none; margin-top: 12px; padding: 16px; + display: none; + margin-top: 12px; + padding: 16px; background: linear-gradient(135deg, #eff6ff, #dbeafe); - border: 2px solid var(--brand-primary); border-radius: 12px; + border: 2px solid var(--brand-primary); + border-radius: 12px; } - .live-block.show { display: block; } - .live-title { font-size: 18px; font-weight: 800; color: #1e40af; margin-bottom: 6px; } - .live-file { font-size: 15px; color: #1e3a8a; margin-bottom: 10px; word-break: break-word; } - .live-timer { font-size: 40px; font-weight: 800; color: #1d4ed8; line-height: 1.1; } + + .live-block.show { + display: block; + } + + .live-title { + font-size: 18px; + font-weight: 800; + color: #1e40af; + margin-bottom: 6px; + } + + .live-file { + font-size: 15px; + color: #1e3a8a; + margin-bottom: 10px; + word-break: break-word; + } + + .live-timer { + font-size: 40px; + font-weight: 800; + color: #1d4ed8; + line-height: 1.1; + } + .live-llm { - display: none; margin-top: 8px; padding: 8px 12px; border-radius: 8px; - background: #fef3c7; border: 1px solid #f59e0b; color: #92400e; - font-size: 18px; font-weight: 700; width: fit-content; + display: none; + margin-top: 8px; + padding: 8px 12px; + border-radius: 8px; + background: #fef3c7; + border: 1px solid #f59e0b; + color: #92400e; + font-size: 18px; + font-weight: 700; + width: fit-content; + } + + .live-llm.show { + display: inline-block; + } + + .live-eta { + margin-top: 8px; + font-size: 14px; + color: #1d4ed8; + font-weight: 600; } - .live-llm.show { display: inline-block; } - .live-eta { margin-top: 8px; font-size: 14px; color: #1d4ed8; font-weight: 600; } + -
- Nubes - DrHider - v{{ version }} - HELP -
-
-
-
Обфускация документов
-
-

- Загрузите документы (.docx, .doc, .pdf, .txt, .md, .zip) — получите ZIP с обезличенными копиями.
- CSV с таблицей замен скачивается отдельно.
- Ограничения: один файл не более 50 МБ, суммарно не более 500 МБ. Файлы сверх лимитов помечаются статусом «пропущен» и не участвуют в обфускации. Пустые, повреждённые файлы и сканы без текстового слоя получают статус «не извлечён» — они тоже не попадают в результат.
- ⏱ Время обработки каждого файла — ориентировочное (обновляется по факту). -

+
+ Nubes + DrHider + v{{ version }} + HELP +
+
+
+
Обфускация документов
+
+

+ Загрузите документы (.docx, .doc, .pdf, .txt, .md, .zip) — получите ZIP с обезличенными копиями.
+ CSV с таблицей замен скачивается отдельно.
+ Ограничения: один файл не более 50 МБ, суммарно не более 500 МБ. Файлы сверх + лимитов помечаются статусом «пропущен» и не участвуют в обфускации. Пустые, повреждённые файлы и сканы без + текстового слоя получают статус «не извлечён» — они тоже не попадают в результат.
+ ⏱ Время обработки каждого файла — ориентировочное (обновляется по факту). +

-
+
- -
-
- - -
-
-
⏱ Обработка…
-
-
0.0 с
-
🤖 ИИ обрабатывает… 0.0 с
-
-
-
-
📊 Итоги обработки
-
-
-
Общее время
-
-
-
-
Из них ИИ
-
-
-
-
Токены ИИ
-
+ +
+
+ + +
+
+
⏱ Обработка…
+
+
0.0 с
+
🤖 ИИ обрабатывает… 0.0 с
+
+
+
+
📊 Итоги обработки
+
+
+
Общее время
+
+
+
+
Из них ИИ
+
+
+
+
Токены ИИ
+
+
-
- - + - -