TreeMap
A free, open-source disk-space visualizer. Squarified treemap, duplicate hunting, disk-full forecasting, and cleanup that only ever moves files to the Trash.
EX-EL — Набор инструментов для работы с документами (frontend-only)
Translation pending
ProductivityTypeScript · CSSGitHub @BorisChubiryaevOnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
No updates detected yet. GitHub releases will appear here.
Owners of public repositories under a personal GitHub account can sign in to verify ownership and manage the introduction themselves. No administrator approval is needed.
Sign in, generate a verification file, and commit it to this repository’s default branch within 30 minutes. Files on other branches or forks do not count. Then check the file below to manage the project without administrator approval. Keep the file to retain your access.
If needed, you will go to sign-in. After signing in, return here and press your chosen verification button again.
Run /nomorevibe verify in your project folder to verify ownership and manage the introduction yourself.
Verify in one minuteAsk about other verification options
Loading the full README. The saved excerpt is shown below.
EX-EL — Набор инструментов для работы с документами Результат — release/mac/Apps4Excel.app. Результат — release/Apps4Excel-1.0.0.dmg. Примечание: DMG собирается через встроенный hdiutil. Скрипт scripts/build-dmg-only.sh создаёт DMG с ярлыком Applications для стандартной установки перетаскиванием. Если нужно собрать только DMG из уже готового .app:Read the full README ↗
Набор офисных инструментов: сравнение, конвертация и правка Excel, Word, PDF, PowerPoint, HTML и изображений, плюс несколько игр. Это одностраничное веб-приложение (React + Vite), которое выкладывается мэшапом в Qlik Sense.
Главный принцип — всё работает в браузере пользователя. Серверной части нет, файлы никуда не отправляются, интернет не нужен. Сервер только раздаёт статические файлы сборки. Тяжёлые движки (распознавание текста, нейросеть удаления фона, Python для PDF → PowerPoint) лежат рядом со сборкой и работают через WebAssembly.
git clone <url-репозитория>
cd app4docs
npm install
npm run dev # http://localhost:5173 (порт можно задать переменной PORT)
| Команда | Что делает |
|---|---|
npm run dev | Сервер разработки Vite |
npm run build | Сборка в dist/ |
npm run preview | Локальный просмотр собранной версии |
npm run lint | ESLint |
npx tsc -b | Проверка типов (в npm run build не входит) |
В корпоративной сети с подменой сертификатов может понадобиться .npmrc в
корне проекта (файл в .gitignore):
strict-ssl=false
npm run build # → dist/ (~146 МБ, из них ~137 МБ — движки)
node dist-utils/index.cjs # → unit-app-light.zip в корне проекта
dist-utils/index.cjs упаковывает сборку в расширение-мэшап:
dist/ описание unit-app-light.qext (type mashup, версия 0.1.0.0);wbfolder.wbl;dist/ в unit-app-light.zip (~72 МБ).⚠️
dist-utils/в.gitignore— в репозитории его нет, утилиту передают отдельно. Без неё мэшап собирается вручную: положить вdist/файлunit-app-light.qextс полями выше и заархивировать содержимоеdist/.
Архив импортируется в QMC: Extensions → Import (при обновлении расширение
заменяется). Приложение открывается по адресу
https://<сервер>/[<префикс прокси>/]extensions/unit-app-light/index.html.
Что важно знать о сервере Qlik. Сборка уже приспособлена к его ограничениям, отдельно настраивать сервер не нужно:
| Ограничение сервера | Как обходит сборка |
|---|---|
| Отдаёт только разрешённые типы файлов (иначе HTTP 415) | В сборке только .html .js .css .json .txt .svg; шрифты встроены в CSS |
| Файрвол режет «опасные» слова и расширения в адресе (403) | Файлы движков названы нейтральными хэшами xxxxxxxx_N.txt |
| Файрвол читает тело ответа (403) | Двоичные файлы движков лежат gzip → HEX-текстом (только 0-9a-f) |
| Файрвол режет большие ответы | Части не больше 6 МБ |
Подробно механизм описан ниже в разделе «PDF → PowerPoint», общий загрузчик —
src/utils/chunkedAssets.ts.
Настройки сборки (vite.config.ts): base: './' — пути относительные,
сборку можно положить в любую папку; маршрутизация через HashRouter
(index.html#/PdfEditor) — переписывать адреса на сервере не нужно; имена
JS/CSS с хэшем содержимого — не кэшировать нужно только index.html.
Content-Security-Policy портала. Если она включена, для всех инструментов
нужны: script-src 'self' 'wasm-unsafe-eval' (WebAssembly), worker-src 'self'
(фоновые потоки), connect-src 'self' (загрузка движков), img-src 'self' data: blob:
(превью). Шахматы и шашки при заблокированном потоке считают ход на самой
странице (src/games/engineRunner.ts), остальные инструменты с потоками без
него не работают.
Проверка после выкладки: главная открывается без ошибок 403/415 в консоли (F12); компьютер в шахматах отвечает на ход; OCR скана в конвертере документов; удаление фона в конвертере изображений; PDF → PowerPoint на небольшом файле; открытие XLSX в Excel-группираторе.
| Что | Версия |
|---|---|
| Node.js (сборка) | ≥ 20.19 или ≥ 22.12 |
| npm | ≥ 10 |
| Браузер | Современный Chromium (Edge, Chrome, Яндекс); IE и режим IE не поддерживаются |
| Протокол | HTTPS — без него не работают Cache Storage и проверка SHA-256 движков |
package-lock.json в .gitignore, а у большинства зависимостей версии с ^,
поэтому сборки на разных машинах могут отличаться. Точно закреплены версии,
от которых зависят файлы в public/: onnxruntime-web, а также CodeMirror и acorn.
app4docs/
├── index.html # точка входа Vite
├── vite.config.ts # base './', шрифты в CSS, имена чанков
├── src/
│ ├── index.tsx # запуск React, HashRouter, тема
│ ├── routes.tsx # все маршруты
│ ├── pages/
│ │ ├── HomePage.tsx # главная: карточки инструментов, опрос, ссылки
│ │ └── <Инструмент>/ # страница + engine/ или core/ (логика без React)
│ ├── components/ # общие: PageShell, модальные окна, тема
│ ├── games/ # движки шахмат и шашек, EngineRunner
│ ├── workers/ # фоновые потоки Excel (разбор, экспорт)
│ ├── utils/ # chunkedAssets (загрузка движков), bgRemoval, pdfWorker
│ ├── styles/ # токены, компоненты, тёмная тема, шрифты
│ └── assets/fonts/ # Inter, Liberation Sans (для PDF)
├── public/ # копируется в dist как есть
│ ├── aibg/ # нейросеть удаления фона (~57 МБ)
│ ├── ocr/ # Tesseract + языки rus/eng (~15 МБ)
│ └── pdf2pptx/ # Pyodide + движок PDF → PowerPoint (~65 МБ)
└── scripts/
├── vendor-*.mjs # переупаковка движков в public/ (нужен интернет)
└── offer-check.ts # стенд проверки движка оферт на настоящих DOCX
Движки в public/ уже лежат в репозитории; скрипты vendor-*.mjs нужны только
при их обновлении.
| Задача | Библиотеки |
|---|---|
| Интерфейс | React 19, react-router 7, TypeScript 5.8, Vite 7 |
| Excel | exceljs |
| PDF: чтение и отрисовка | pdfjs-dist 5 |
| PDF: запись | pdf-lib + @pdf-lib/fontkit, jsPDF |
| Word | docx, docx-preview, mammoth |
| PPTX, DOCX как пакеты | JSZip + собственный разбор XML |
| Изображения | ag-psd, html-to-image, html2canvas |
| Графики | Recharts |
| Распознавание текста (OCR) | tesseract.js 7 (WebAssembly) |
| Нейросеть удаления фона | onnxruntime-web 1.22.0 (WebAssembly) |
| Python в браузере | Pyodide 0.28.3, PyMuPDF, python-pptx |
| Редактор кода, разбор JS | CodeMirror 6, acorn |
| Прочее | file-saver, react-rnd |
Ни одна библиотека не грузится с CDN во время работы — всё входит в сборку.
Каждый инструмент — страница src/pages/<Имя>/ со своим маршрутом в
src/routes.tsx и карточкой на главной (src/pages/HomePage.tsx). Метка
«Тест» на карточке (isTest: true) означает опытную эксплуатацию.
| Инструмент | Маршрут | Что делает |
|---|---|---|
| HTML-редактор (тест) | #/HtmlStudio | Правка HTML-отчётов от ИИ: тексты, блоки, таблицы, данные графиков, цвета |
| Перенос в шаблон | #/PptxRestyle | Перекладывает презентации в корпоративный шаблон: фон, шрифты, цвета |
| PDF → PowerPoint | #/PdfToPptx | Редактируемая презентация из PDF |
| Сравнение Excel/Word/PDF | #/compare | Excel — по ячейкам с выравниванием строк, Word и PDF — по абзацам и таблицам |
| HTML/JSON-таблицы → Excel | #/htmlToExcel | Находит таблицы в HTML или JSON и выгружает в XLSX со стилями |
| Конвертер изображений | #/ImageConverter | SVG, PNG, JPG, WebP, GIF, BMP, PDF, PSD → PNG, JPEG, WebP, BMP, ICO, PDF; удаление фона |
| PDF Studio | #/PdfEditor | Объединение, порядок, повороты, подписи, вымарывание, OCR, формы, сжатие |
| Excel-группиратор | #/ExcelTableBuilder | Объединяет несколько Excel-файлов по ключам с пометкой файла-источника |
| Генератор графиков | #/ChartCraft | Графики из XLSX/CSV или вставки из Excel; экспорт в PNG, SVG, HTML |
| Конвертер документов | #/PdfToWord | PDF ↔ Word, распознавание сканов |
| Объединение изменений в оферту | #/OfferMerge | Собирает правки из нескольких DOCX и обновляет текст оферты |
| Сравнение по рабочим местам | #/WorkplaceCompare | Сверка двух Excel-выгрузок рабочих мест (АС «Друг») с фильтрами |
| Игры | #/Chess, #/Checkers, #/ChessLessons, #/SnakeGame, #/DocMatchGame | Шахматы и шашки против компьютера, уроки шахмат, змейка |
Старые адреса #/Svg2Png и #/JpgToPdfPage открывают конвертер изображений.
Загружаете две Excel-выгрузки по рабочим местам — позиции сопоставляются автоматически, изменения подсвечиваются: 🔴 было, 🟢 стало, 🔵 новая, 🟡 удалена. Фильтры строятся по данным, результат выгружается в Excel.
Сравнивает любые пары: Excel с Excel, Word и PDF в любом сочетании (например, подписанный PDF с исходным .docx). Excel сравнивается по ячейкам; удалённая или вставленная строка не сдвигает сравнение остальных — строки выравниваются. Word и PDF — по абзацам и таблицам. Текст PDF собирается в абзацы, колонтитулы и номера страниц отбрасываются, переносы склеиваются, таблицы с видимыми границами распознаются как таблицы; у каждого различия указана страница. Скан без текстового слоя сравнить нельзя — об этом выводится сообщение.
Вставляете HTML-код страницы (сохранить страницу — Ctrl+S) или JSON — инструмент находит все таблицы и показывает предпросмотр. Можно выбрать таблицы, отфильтровать строки и колонки и выгрузить в Excel с сохранением стилей. Таблицы, которые страница дорисовывает скриптом, в сохранённом HTML могут отсутствовать.
Объединяет несколько Excel-файлов (выгрузки за разные периоды или от разных подразделений) в одну таблицу:
1.1. Высшее, 2.1. Среднее специальное;
ячейки с разделителями (, ; ;) разбиваются и нумеруются.Палитра проверена на различимость при нарушениях цветовосприятия, цвета не повторяются. Пустые ячейки не превращаются в нули, даты сортируются по времени, числа с пробелами, запятой, ₽ и % читаются как числа. Холст: несколько графиков, стрелки, рамки, надписи, мини-карта, отмена любого действия (Ctrl+Z / Ctrl+Y). Горячие клавиши: V — выбор, P — карандаш, A — стрелка, R — рамка, T — надпись, E — ластик, 0 — вписать холст.
Разбирает документы с инструкциями изменений (алгоритмом, без ИИ) и применяет
их к тексту оферты: сноски, пункты, новые редакции, строки таблиц. Правки
выделяются цветом или записываются как исправления Word. Движок —
src/pages/OfferMerge/engine/, стенд для прогона на настоящих документах —
scripts/offer-check.ts.
src/pages/PdfToPptx/)Страница #/PdfToPptx. Каждая страница PDF становится слайдом того же
размера: текст — текстовыми блоками, картинки — картинками, графика —
фигурами PowerPoint. Режим «точная копия» — фон картинкой + текст поверх.
Движок — Python-проект pdf2pptx
(PyMuPDF + python-pptx). В браузере он запускается без изменений через
Pyodide — CPython, собранный в WebAssembly, — в
фоновом потоке (src/pages/PdfToPptx/pdf2pptx.worker.ts). Результат
совпадает с серверной версией байт в байт.
Всё нужное лежит в public/pdf2pptx/ и попадает в dist/ как есть:
runtime/ — Pyodide 0.28.3 и wasm-колёса (PyMuPDF, lxml, Pillow, python-pptx); в hex ~64 МБ;engine/ — Python-код движка;manifest.json — список файлов и коммит движка.Содержимое файлов — hex, под ограничения Qlik. У сервера Qlik Sense несколько проверок, и все срабатывали на файлах движка:
HTTP 415.FilterOther) отвечает HTTP 403,
если в адресе есть «архивное» расширение (.zip, .whl…) или опасное
слово (scr…pt — XSS-шаблон, ловит даже scrpt).Поэтому:
0-9a-f + .txt, напр. e7eec9cb_0.txt): ни
слова, ни расширения..wasm, .whl, .zip, .py) кодируется
в hex (символы 0-9a-f). В таком тексте физически нет ни <, ни кавычек,
ни ../, ни слов script/select/union — нужных символов просто нет,
поэтому ни одно правило WAF не срабатывает. Заодно hex не содержит
zip-структуры (почтовый шлюз не пересобирает) и не является base64 (письмо не
блокируется). Цена — вдвое больший объём (среда ~64 МБ), но это одноразовая
загрузка в кэш.…_0.txt, …_1.txt, … .Соответствие «логическое имя → реальные файлы» задаёт manifest.json (store);
воркер (engineAssets.makeCachedFetch) находит по нему файлы, качает части,
склеивает, сверяет с манифестом (размер и SHA-256) и декодирует hex обратно в
байты, проставляя нужный content-type. pyodide.mjs (ES-модуль, грузится по
своему имени) → pyodide.loader.js; pyodide.asm.js и pyodide-lock.json
отдаются как есть. Все имена и части создаёт scripts/vendor-pdf2pptx.mjs.
Интернет не нужен: файлы движка входят в сборку и грузятся с того же сервера, что и приложение (внешних запросов нет — проверено с полностью закрытым интернетом).
Файлы кладутся в Cache Storage браузера под ключом версии
(src/pages/PdfToPptx/engineAssets.ts), поэтому скачиваются один раз — даже
если хостинг запрещает HTTP-кэширование (Cache-Control: no-store). Главная
страница тихо подкачивает их в фоне через несколько секунд простоя, так что к
открытию инструмента скачивать уже нечего; при обновлении движка старая версия
из кэша удаляется. Cache Storage работает только по https (или localhost) —
по http движок просто грузится без постоянного кэша.
# код движка из соседнего клона ../pdf2pptx (или --engine-dir <путь>)
node scripts/vendor-pdf2pptx.mjs
# пересобрать среду Pyodide и колёса (нужен интернет: npm, PyPI, cdn.jsdelivr.net)
node scripts/vendor-pdf2pptx.mjs --runtime --force
Версии колёс жёстко связаны с Pyodide (ABI pyodide_2025_0, Python 3.13) —
обновлять их нужно вместе, в одном месте: начало скрипта.
.txt, .js, .json), отдельная настройка списка расширений в QMC
не нужна (см. «Содержимое файлов — hex, под ограничения Qlik» выше)..wasm не как application/wasm, фоновый поток сам
исправляет тип — отдельно настраивать Qlik не нужно.script-src 'wasm-unsafe-eval'. Движок распознаёт этот случай и пишет об
этом прямо в ошибке..woff2, поэтому шрифт Inter (латиница и кириллица)
встраивается прямо в CSS (src/styles/fonts.css, assetsInlineLimit в
vite.config.ts) — отдельных файлов шрифтов в сборке нет.manifest.json записаны размер и SHA-256 каждого файла движка. Если файл
изменился по дороге (почтовый шлюз, антивирус, архиватор), ошибка назовёт
его и покажет, сколько байт пришло и сколько ожидалось. Испорченная копия
в кэше браузера удаляется и скачивается заново.src/pages/PdfToWord/)Маршрут #/PdfToWord. Всё работает в браузере, без сервера и интернета.
src/pages/PdfToWord/engine/)PDF хранит не абзацы, а фрагменты текста с координатами, поэтому документ восстанавливается по геометрии страницы:
extract.ts — текст с настоящими шрифтами (pdf.js отдаёт внутренние имена
вида g_d0_f1, настоящее имя TimesNewRomanPS-BoldMT берётся из объекта
шрифта → гарнитура, жирный, курсив), фрагменты режутся на слова; цвет слова —
по отрисованной странице; линии (залитые тонкие прямоугольники и обводки),
заливки, фигуры и картинки — из списка операций до отрисовки (после неё
pdf.js заменяет контуры объектами Path2D).tables.ts — таблицы по линиям сетки: объединённые ячейки (там, где между
ячейками нет линии), заливка ячеек, цвет и толщина рамки.layout.ts — колонтитулы, подчёркивание/зачёркивание, нарисованные маркеры
списков, плашки под текстом, векторные графики (картинкой вместе с
подписями), колонки (вертикальные «коридоры» без текста), абзацы
(межстрочный шаг, красная строка, правило «следующее слово поместилось бы —
значит, конец абзаца»), выравнивание, отступы, интервалы, заголовки,
таблицы без рамок по выровненным столбцам.index.ts — два прохода (сначала колонтитулы по всем страницам), склейка
абзацев и таблиц через границу страниц, разрывы страниц, поля документа.docx.ts — сборка .docx: размер и поля страниц, разделы с колонками,
колонтитулы с полями номера страницы, стили «Заголовок 1–3».Сканы (engine/ocr.ts) распознаются Tesseract (tesseract.js, Apache-2.0;
модели русского и английского LSTM 4.0.0_best_int). Страница выравнивается
по наклону, линии таблиц и подчёркивания находятся на растре и стираются
перед повторным распознаванием (иначе сетка превращается в «мусор»), таблица
строится тем же движком по найденным линиям; жирный — по толщине штриха;
печати, подписи и фото вне текста — картинками.
Файлы распознавания лежат в public/ocr/ (~15 МБ) и доставляются как движок
PDF → PowerPoint: JS-файлы под нейтральными именами xxxxxxxx.js, модели —
HEX-текстом частями xxxxxxxx_N.txt, всё сверяется с manifest.json
(размер, SHA-256) и кэшируется в браузере (src/utils/chunkedAssets.ts).
Без blob-потоков. Пересобрать: node scripts/vendor-ocr.mjs (берёт файлы
из node_modules; заодно правит одну ошибку tesseract.js 7 с языками,
переданными байтами). При выкладке в QlikSense папку ocr кладут рядом с
index.html, как pdf2pptx.
src/pages/PdfToWord/word2pdf/)PAGE/NUMPAGES заменяются метками и заполняются на
каждой странице; колонтитулы наследуются от предыдущего раздела, как в Word.foreignObject, запасной вариант —
html2canvas) и кладётся в PDF; поверх — невидимый текстовый слой (шрифт
Liberation Sans, SIL OFL 1.1), поэтому в PDF работают поиск и копирование.src/utils/pdfWorker.ts — общий поток pdf.js для всех PDF-инструментов. В его
код дописаны полифиллы Math.sumPrecise и Map.getOrInsert(Computed):
pdfjs-dist 5 вызывает их внутри потока при разборе встроенных шрифтов, а без
них шрифты PDF не загружаются (текст рисуется запасным шрифтом).
Партия с компьютером прямо в браузере, без сервера и без внешних библиотек —
работает и в закрытой сети. Все игры открываются одной кнопкой «🎮 Игры» внизу
главной страницы (маршруты #/Chess, #/ChessLessons, #/Checkers).
Уроки шахмат (#/ChessLessons) — 12 уроков для тех, кто никогда не играл:
доска и названия полей, как ходит каждая фигура, взятие, шах и защита от
него, мат, рокировка, взятие на проходе, пат и мат ферзём/ладьёй против
компьютера. В каждом — короткое объяснение и задание на доске: найти поле,
собрать звёзды фигурой за минимум ходов, съесть фигуры, найти верный ход
(с объяснением, почему другой ход не подходит). Есть подсказки, пропуск
задания и прогресс, который сохраняется в браузере. Все задания проверяются
скриптом: решения верные, минимум ходов совпадает с заявленным.
Общее для обеих игр
src/games/engineRunner.ts), а в
консоли появляется строка [engine] … с причиной.Шахматы — все правила: рокировка, взятие на проходе, превращение пешки (с выбором фигуры), мат, пат, ничья по 50 ходам, троекратному повторению и недостатку материала. Ходы — перетаскиванием или кликами, нотация с русскими буквами фигур (Кр, Ф, Л, С, К). На уровнях 4–6 показывается оценка позиции.
Русские шашки — бить обязательно (простые бьют и назад), взятие до конца, турецкий удар, дамка ходит и бьёт на любое расстояние, простая, дошедшая до края во время взятия, продолжает бить дамкой. Ничья — 15 ходов только дамками без взятий или троекратное повторение. Шашки, которые обязаны бить, подсвечиваются; многоходовое взятие отмечается по полям.
Как устроено
src/games/chess/engine.ts — доска 0x88, генератор ходов проверен
perft-тестами (6 эталонных позиций, до 4,8 млн узлов), поиск альфа-бета с
итеративным углублением, таблицей перестановок, нулевым ходом, LMR и
форсированным поиском взятий; оценка — материал, позиционные таблицы,
пешечная структура, добивание в эндшпиле.src/games/checkers/engine.ts — генератор ходов по правилам русских шашек
и альфа-бета с продлением, пока есть обязательные взятия.levels.ts рядом с движками, уроки — в
src/games/chess/lessons.ts (каждый шаг — позиция FEN и тип задания).src/pages/PdfEditor/)Объединение, порядок, повороты, правки страниц, подписи, распознавание и сжатие — целиком в браузере.
core/build.ts: копии исходных страниц (формы заполнены
и «сплющены» шрифтом с кириллицей), поворот, затем распознанный текст и
аннотации, обрезка полей / вписывание в A4, номера страниц и водяной знак.core/geometry.ts: всё рисуется в системе отображаемой
страницы (X вправо, Y вверх) и переводится матрицей с учётом /Rotate и
CropBox. Аннотации — в повороте самой страницы (как в редакторе), номера и
водяной знак — в итоговой ориентации.src/assets/fonts/ — урезан до латиницы и кириллицы (~47 КБ), встраивается
через @pdf-lib/fontkit. Тот же шрифт в редакторе, поэтому переносы строк
совпадают.core/ocr.ts, движок конвертера документов
(PdfToWord/engine/ocr.ts) без выравнивания наклона, чтобы слова легли на
свои места; слой — текст с режимом отрисовки 3 (невидимый).getFieldObjects), значения кладутся в
его annotationStorage для миниатюр и заполняются pdf-lib при сборке.components/PageView.tsx).components/SignatureLibrary.tsx: рисование, загрузка с
удалением белого фона, библиотека в localStorage.Кнопка ✂️ на карточке изображения и «Убрать фон у всех». Окно —
src/pages/ImageConverter/components/BackgroundRemover.tsx, общий код —
src/utils/bgRemoval/:
aiWorker.ts). Вход
320×320; грубая маска доводится guided filter по исходнику, поэтому волосы
и мягкие края получают полупрозрачность.Файлы нейросети лежат в public/aibg/ (~57 МБ) и попадают в dist/aibg/ —
их нужно выкладывать вместе с приложением. Доставка как у pdf2pptx: gzip →
HEX-текст → части до 6 МБ с нейтральными именами xxxxxxxx_N.txt, проверка
SHA-256 по manifest.json, кэш в Cache Storage. Служебный JS-модуль движка
подключается обычным файлом (aibg/xxxxxxxx.js), а не blob-ссылкой, поэтому
работает и при строгой политике безопасности (CSP) портала.
Пересобрать файлы (например, после обновления onnxruntime-web):
node scripts/vendor-aibg.mjs # скачать модель и упаковать
node scripts/vendor-aibg.mjs --model silueta.onnx # взять модель с диска
Версия onnxruntime-web в package.json закреплена точно (1.22.0): служебный
модуль в public/aibg/ собран из неё.
src/pages/PptxRestyle/)Перекладывает презентации в новый корпоративный шаблон: фон, шрифты, цвета и место заголовков берутся из шаблона, содержимое — из исходников. Несколько файлов собираются в одну презентацию (каждый — разделом). Всё в браузере.
Движок — engine/ (JSZip + DOM, без сторонних библиотек PowerPoint):
template.ts — анализ шаблона. Шаблон может быть «настоящим» (оформление
в макетах) или набором слайдов-примеров (фон-картинка и шрифты прямо на
слайдах, как у фирменных шаблонов). Находятся фоны и их роли (титульный,
основной, раздел, финальный), шрифт, кегль, цвет и место заголовка, шрифт и
цвет текста, фирменная палитра и цвет «карточек», светлое/тёмное оформление.styles.ts — «закрепление» унаследованного оформления: положение
плейсхолдеров, маркеры и отступы, размер и цвет текста берутся из макета и
мастера исходника и записываются на слайд — иначе при смене макета они
потерялись бы.restyle.ts — перекраска: шрифты шаблона; цвет текста с проверкой
контраста к реальному фону под ним (фон слайда или заливка фигуры);
насыщенные цвета — в ближайший по тону цвет палитры (красный «внимание»
без близкого цвета в палитре остаётся красным); светлые плашки на тёмном
шаблоне — в «карточки»; таблицы — сетка и шапка в стиле шаблона;
заголовок — на место шаблона с подбором кегля, чтобы не наехать на
содержимое.build.ts — сборка: пакет шаблона без слайдов-примеров, перенос слайдов
со всеми картинками, диаграммами (перекрашиваются ряды и подписи),
заметками; 4:3 вписывается в 16:9; разделы по файлам; удаление
неиспользуемых частей шаблона.Проверка: pptx-результат открывается PowerPoint/LibreOffice, все связи и
типы частей на месте, порядок элементов XML соответствует схеме.
src/pages/HtmlStudio/)Правка HTML-файлов (например, отчётов, которые сгенерировал ИИ) без знания кода. Всё в браузере, файл никуда не отправляется.
iframe без allow-scripts): клик
выделяет блок, двойной клик — правка текста на месте, плавающая панель
форматирования, хлебные крошки, вставка блоков, перемещение
(Alt+↑/↓), дублирование (Ctrl+D), удаление (Delete), отмена (Ctrl+Z/Y).
Панель «Блок»: текст, ссылки, замена картинок, цвета, размеры, отступы,
атрибуты (обработчики on* запрещены), операции с таблицами.core/data.ts, разбор
через acorn): массивы, записи, словари, наборы Chart.js/ECharts/ApexCharts.
Правка в сетке, вставка из Excel, импорт XLSX/CSV, выгрузка в Excel.
Запись обратно меняет только литералы — форматирование кода сохраняется.style#he-custom-css).Ограничения: содержимое, которое рисуют скрипты, видно только в «Просмотре» (в визуальном режиме такие контейнеры заштрихованы); библиотеки с CDN без интернета не загрузятся; если CSP портала блокирует скрипты предпросмотра — используйте «В браузере». Черновик автоматически сохраняется в localStorage.
Например, чтобы передать файлы через почтовый шлюз, который режет
непривычные расширения: добавить .pdf ко всем файлам в папке и вернуть обратно.
macOS / Linux (Terminal):
find . -type f -exec mv {} {}.pdf \;
find . -type f -name "*.pdf" -exec sh -c 'mv "$1" "${1%.pdf}"' _ {} \;
Windows (PowerShell):
Get-ChildItem -Recurse -File | Rename-Item -NewName { $_.Name + ".pdf" }
Get-ChildItem -Recurse -File -Filter "*.pdf" | Rename-Item -NewName { $_.Name -replace '\.pdf$', '' }