Meridian Office

Meridian Slides — спецификация приложения

Документ приложения по разделу 8 библии (docs/00-foundation.md). Версия 0.1 · 2026-10-03. Собственный формат: .mpx (шаблон .mpt, плоский XML .mpxf), пространство имён urn:meridian:office:slides:1, MIME application/vnd.meridian.slides. Цвет приложения --app-slides #E25C3D, значок — прямоугольник с треугольником «play». Крейты ядра: kernel/crates/meridian-slides (модель презентации, пакет .mpx), meridian-scene (общая графика сцены: фигуры, геометрия, стили, группы — делится с Draw/Write/Sheets), meridian-anim (таймлайн и планировщик анимаций), meridian-show (сеанс показа, режим докладчика, перо/лазер), meridian-transitions (переходы, шейдеры SkSL), meridian-diagram (диаграммы-схемы), meridian-video (экспорт видео, запись), meridian-chart (диаграммы), meridian-codecs-{pptx,ppt,odp,iwork}; оболочка — shell/src/slides/ (QML/C++); скрипты — meridian-script. Фаза по библии: 3 (12–22 мес от старта). Редакция: Slides входит в Free (Feature::CoreSlides); экспорт видео — Feature::SlidesVideoExport, пульт докладчика — Feature::SlidesPresenterRemote, скрипты — Feature::ScriptsRun/ScriptsEdit, совместная работа — Feature::CloudCollab (фаза 6).

Содержание

  1. Назначение и аналоги
  2. Функции (по группам, P0/P1/P2)
  3. Экраны
  4. Модель данных
  5. Алгоритмы
  6. MeridianScript API для Slides
  7. Форматы
  8. Горячие клавиши
  9. Критерии готовности 1.0
  10. Риски
  11. Вопросы к библии

1. Назначение и аналоги

Meridian Slides — редактор презентаций: слайды с заполнителями, образцами и темами, анимации и переходы, показ с режимом докладчика на втором экране, запись показа с голосом, экспорт в видео и PDF. Точно открывает .pptx вместе с анимациями, переходами и образцами, пишет .pptx без потерь для всего, что умеет сам.

1.1 Аналоги

Продукт Сильные стороны Слабые стороны, которые используем
Microsoft PowerPoint эталон формата, богатые анимации, морфинг, дизайнерские идеи, режим докладчика подписка, Windows/macOS только, тяжёлый, VBA, нет Linux, облако навязывается
LibreOffice Impress бесплатен, кроссплатформенный, ODF неточный импорт pptx (анимации, SmartArt, эффекты), устаревший интерфейс, слабый режим докладчика, нет экспорта видео без обходов
Apple Keynote плавные анимации (Magic Move), красивые темы только Apple, закрытый формат, экспорт в pptx с потерями
Google Slides совместная работа только в браузере, бедные анимации, пересохранение pptx теряет оформление
WPS Presentation хорошая совместимость с pptx закрытый, реклама, китайская юрисдикция данных

1.2 Чем Slides будет лучше — конкретно

Свойство Как достигаем
Открывает pptx вместе с анимациями и переходами, а не «картинками» таймлайн meridian-anim структурно равен p:timing OOXML; 150+ пресетов анимаций и 45+ переходов реализованы 1:1
Показ 60 кадров/с, переходы на GPU meridian-transitions: шейдеры SkSL (Skia runtime effects), 3D-переходы через SkM44; отрисовка показа в отдельном потоке
Режим докладчика на любом числе экранов и на Linux/Wayland два QQuickWindow с одной моделью состояния показа (ShowSession), выбор экрана через QWindow::setScreen
Экспорт видео офлайн виртуальные часы + offscreen-рендер + платформенные кодеры (Media Foundation / VideoToolbox / libvpx+libopus)
Текст в слайдах — тот же движок, что в Write text-model/text-layout ядра: шейпинг, переносы, RTL, вертикальный текст, проверка орфографии Lingo
Диаграммы, таблицы, формулы — общие модули Meridian Chart, grid-model Sheets, Meridian Math встроены, а не «вставлены как объект»
Скрипты вместо VBA MeridianScript (TypeScript) с типизированным API презентации, песочница, события показа
Нет сюрпризов с лицензией Slides полностью бесплатен в редакции Free; экспорт видео и пульт докладчика — Pro

1.3 Границы версии 1.0

В 1.0 (конец фазы 3) входят все P0 ниже. 3D-сцена фигур (a:scene3d, a:sp3d), морфинг, запись с камеры, сравнение презентаций, авто-субтитры и совместная работа появляются в 1.x/2.0 по приоритетам P1/P2 и фазам 6–7.


2. Функции

Приоритеты: P0 — без этого нельзя выпустить 1.0, P1 — в 1.x, P2 — позже. Пометки редакций — [Pro] и т.п. по docs/10-licensing-accounts.md; без пометки — Free.

2.1 Слайды и структура презентации

Функция P Поведение
Создать/дублировать/удалить/переставить слайды (перетаскиванием в миниатюрах и сортировщике, с мультивыбором) P0 дубликат получает новые id фигур, анимации и заметки копируются
Новый слайд с выбором макета (галерея макетов текущего образца); Ctrl+M — макет как у текущего (кроме титульного → «Заголовок и объект») P0 —
Скрыть/показать слайд; скрытые пропускаются при показе и видео, но печатаются по выбору P0 —
Размер слайда: 16:9 (13,333×7,5 дюйма), 4:3, 16:10, A4, Letter, свой; масштабирование содержимого при смене («вписать»/«по максимуму») P0 единицы — EMU внутри, см/дюймы/пункты в интерфейсе
Разделы: создать, переименовать, свернуть/развернуть, переместить вверх/вниз, удалить (с/без слайдов) P0 OOXML p14:sectionLst
Миниатюры слайдов: живые, с кэшем и фоновой генерацией (§5.7) P0 —
Копирование слайдов между презентациями с выбором «тема назначения» / «исходное оформление» P0 при переносе образец копируется, если выбрано исходное оформление
Повторное использование слайдов из другого файла (панель со списком миниатюр) P1 —
Сравнение двух презентаций с принятием/отклонением (§2.21) P1 —
Избранные (закреплённые) слайды и «библиотека слайдов» организации P2 фаза 6/7

2.2 Макеты, образцы, темы

Функция P Поведение
Образец слайдов (slide master): несколько образцов в одной презентации, фон, заполнители, стили текста (заголовок, текст уровней 1–9, прочий), общие фигуры и колонтитулы P0 OOXML p:sldMaster: p:txStyles/titleStyle,bodyStyle,otherStyle, p:clrMap
Макеты (layouts): 11 стандартных типов + свои; переименование, скрытие фоновых фигур образца, свои заполнители с типом/индексом P0 типы ST_SlideLayoutType; стандартные: Титульный, Заголовок и объект, Заголовок раздела, Два объекта, Сравнение, Только заголовок, Пустой, Объект с подписью, Рисунок с подписью, Заголовок и вертикальный текст, Вертикальный заголовок и текст
Тема: цветовая схема (12 цветов: dk1, lt1, dk2, lt2, accent1–6, hlink, folHlink) с картой цветов bg1/tx1/bg2/tx2, шрифтовая пара (major/minor для latin/ea/cs и переопределения по письменностям), эффекты (3 уровня заливок, линий, эффектов, фонов) P0 a:theme DrawingML 1:1; оттенки (lumMod/lumOff) в палитре «Цвета темы» 6×10
Варианты темы (variants) — 4 цветовых/фоновых варианта у каждой встроенной темы P0 p15:themeFamily/варианты хранятся как отдельные темы в .mpt
Встроенные темы: не менее 30, в стиле MDS (спокойные, инженерные), плюс «Office-совместимые» (Carlito/Caladea) P0 галерея на вкладке «Дизайн»
Шаблоны .mpt и .potx; «сохранить тему» (.mthm — тема как пакет MOP с одной темой, импорт .thmx) P0 —
«Дизайнерские идеи»: локальный генератор вариантов раскладки слайда по правилам (сетка, пропорции, замена макета, акцентные блоки), без ИИ P1 ИИ-варианты через Assist — фаза 7 [Pro]
Фон слайда: сплошной, градиент, рисунок/текстура, узор; «скрыть фоновые графические объекты»; применить ко всем P0 —
Колонтитулы: дата/время (фиксированная или авто, 13 форматов), номер слайда, нижний колонтитул; отдельно для заметок и выдач P0 диалог SL-26

2.3 Заполнители

Функция P Поведение
16 типов: заголовок, центрированный заголовок, подзаголовок, текст, объект, рисунок, диаграмма, таблица, диаграмма-схема, медиа, картинка, дата, колонтитул, номер слайда, верхний колонтитул (заметки/выдачи), изображение слайда (заметки) P0 ST_PlaceholderType
Наследование образец → макет → слайд по типу и индексу (§4.5), «сбросить слайд» восстанавливает геометрию и форматирование P0 —
Текст-подсказка пустого заполнителя («Заголовок слайда»), не печатается и не показывается P0 —
Значки быстрой вставки в пустом заполнителе объекта: таблица, диаграмма, диаграмма-схема, рисунок, значок, видео P0 —
Автоподбор текста при переполнении (сжать/расширить фигуру/нет) (§5.2) P0 кнопка-подсказка «Параметры автоподбора» у фигуры
Автонумерация слайда, авто-дата как поля (a:fld) P0 —

2.4 Текст (движок Write)

Функция P Поведение
Текстовое тело в любой фигуре: абзацы, уровни 1–9, выравнивание, отступы, табуляции, интервалы, маркеры (символ, рисунок, автонумерация — 40 схем OOXML ST_TextAutonumberScheme), цвет/размер маркера P0 модель text-model, раскладка text-layout
Символы: шрифт по письменности (latin/ea/cs/sym), размер, Ж/К/Ч/зачёркнутый (одинарный/двойной), капители/прописные, межзнаковый интервал, кернинг, верхний/нижний индекс, цвет/заливка текста, контур, тень, свечение, отражение P0 эффекты текста — a:effectLst на a:rPr; рендер через Skia
Направление текста: горизонтальный, повёрнутый 90°/270°, вертикальный с накоплением, восточноазиатский вертикальный; RTL; колонки (до 16) с интервалом P0 a:bodyPr/@vert, @numCol, @rtlCol
Привязка по вертикали (верх/центр/низ), по горизонтали центра, внутренние поля (по умолчанию 0,25/0,13 см), перенос слов, поворот текста отдельно от фигуры P0 —
Деформация текста (WordArt-преобразования, a:prstTxWarp, 40 видов) P1 раскладка глифов по огибающей (§5.2)
Проверка орфографии (Lingo), автозамена, тезаурус, переносы, язык абзаца/фрагмента P0 —
Поиск и замена (по всей презентации, включая заметки), замена шрифтов во всём документе P0 —
Гиперссылки и действия на тексте (слайд, показ, URL, файл, скрипт) P0 —
Формулы Math в тексте (встроенные объекты) P0 (отображение) / P1 (редактор, фаза 4) —
Специальные символы, дата/время, номер слайда как поля P0 —
Вставка текста из Write/буфера с сохранением стилей или «только текст» P0 —

2.5 Фигуры

Геометрия — общая библиотека meridian-scene, та же, что в Write/Sheets/Draw: 187 предустановленных фигур OOXML (a:prstGeom), вычисляемых по формулам направляющих (§5.1). Группы галереи «Фигуры» (всего 187):

Группа Кол-во Состав (идентификаторы ST_ShapeType)
Линии и соединительные линии 11 line, lineInv, straightConnector1, bentConnector2…5, curvedConnector2…5
Прямоугольники 9 rect, roundRect, round1Rect, round2SameRect, round2DiagRect, snipRoundRect, snip1Rect, snip2SameRect, snip2DiagRect
Основные фигуры 43 triangle, rtTriangle, diamond, parallelogram, trapezoid, nonIsoscelesTrapezoid, pentagon, hexagon, heptagon, octagon, decagon, dodecagon, plaque, ellipse, teardrop, pie, pieWedge, blockArc, donut, noSmoking, cube, can, lightningBolt, heart, sun, moon, smileyFace, foldedCorner, bevel, frame, halfFrame, corner, diagStripe, chord, arc, leftBracket, rightBracket, leftBrace, rightBrace, bracketPair, bracePair, cloud, plus
Фигурные стрелки 31 rightArrow, leftArrow, upArrow, downArrow, leftRightArrow, upDownArrow, quadArrow, leftRightUpArrow, bentArrow, uturnArrow, leftUpArrow, bentUpArrow, curvedRightArrow, curvedLeftArrow, curvedUpArrow, curvedDownArrow, stripedRightArrow, notchedRightArrow, homePlate, chevron, rightArrowCallout, downArrowCallout, leftArrowCallout, upArrowCallout, leftRightArrowCallout, upDownArrowCallout, quadArrowCallout, circularArrow, leftCircularArrow, leftRightCircularArrow, swooshArrow
Фигуры для формул 6 mathPlus, mathMinus, mathMultiply, mathDivide, mathEqual, mathNotEqual
Блок-схема 29 flowChartProcess, flowChartAlternateProcess, flowChartDecision, flowChartInputOutput, flowChartPredefinedProcess, flowChartInternalStorage, flowChartDocument, flowChartMultidocument, flowChartTerminator, flowChartPreparation, flowChartManualInput, flowChartManualOperation, flowChartConnector, flowChartOffpageConnector, flowChartPunchedCard, flowChartPunchedTape, flowChartSummingJunction, flowChartOr, flowChartCollate, flowChartSort, flowChartExtract, flowChartMerge, flowChartOfflineStorage, flowChartOnlineStorage, flowChartMagneticTape, flowChartMagneticDisk, flowChartMagneticDrum, flowChartDisplay, flowChartDelay
Звёзды и ленты 21 irregularSeal1, irregularSeal2, star4, star5, star6, star7, star8, star10, star12, star16, star24, star32, ribbon, ribbon2, ellipseRibbon, ellipseRibbon2, leftRightRibbon, verticalScroll, horizontalScroll, wave, doubleWave
Выноски 16 wedgeRectCallout, wedgeRoundRectCallout, wedgeEllipseCallout, cloudCallout, callout1…3, accentCallout1…3, borderCallout1…3, accentBorderCallout1…3
Управляющие кнопки 12 actionButtonBlank, actionButtonHome, actionButtonHelp, actionButtonInformation, actionButtonForwardNext, actionButtonBackPrevious, actionButtonEnd, actionButtonBeginning, actionButtonReturn, actionButtonDocument, actionButtonSound, actionButtonMovie
Служебные (не в галерее, нужны для импорта) 9 gear6, gear9, funnel, cornerTabs, squareTabs, plaqueTabs, chartX, chartStar, chartPlus
Функция P Поведение
Вставка фигур из галереи, рисование с ограничением пропорций (Shift) и от центра (Ctrl), регуляторы формы (жёлтые маркеры a:avLst) P0 —
Произвольная фигура (кривая Безье, полилиния, карандаш), редактирование узлов — редактор из Draw P0 a:custGeom
Объединение фигур: объединить, объединить с пересечением, фрагментировать, пересечь, вычесть (булевы операции Draw) P1 результат — custGeom
Стили фигур: матрица 6 акцентов × 7 стилей темы (a:lnRef/fillRef/effectRef/fontRef), «другие заливки/контуры/эффекты» P0 —
Заливки: нет, сплошная, градиент (линейный/радиальный/прямоугольный/по контуру, до 10 остановок, прозрачность), рисунок/текстура (растянуть/замостить, смещение, прозрачность), узор (54 предустановленных ST_PresetPatternVal) P0 —
Линии: сплошная/градиент, толщина, 11 штрихов, составные (5), концы (плоский/круглый/квадратный), соединения (скос/срез/круглое), стрелки 6 типов × размеры 3×3 P0 —
Эффекты: тень (внешняя 9 пресетов, внутренняя 9, перспективная 5; цвет, размытие, расстояние, угол, прозрачность), отражение (9), свечение (24 пресета), сглаживание краёв (6) P0 рендер через SkImageFilter (DropShadow, Blur)
Рельеф, поворот объёмной фигуры, освещение, материал (a:sp3d, a:scene3d) P2 в 1.0 — плоское отображение с приближённым рельефом (внутренняя тень + блик)
Выравнивание (6 вариантов + относительно слайда/выделения), распределение, умные направляющие (§5.3), привязка к сетке/направляющим, сетка с шагом P0 —
Группировка/разгруппировка/перегруппировка, порядок (вперёд/назад/на передний/на задний), панель «Выделение» (имена, видимость, порядок) P0 —
Поворот (маркер, 15° с Shift, точный ввод), отражение, размер и положение с точностью 0,01 см, блокировка пропорций, замена фигуры с сохранением текста P0 —
Замещающий текст (alt), название, скрытие, запрет выделения/перемещения (блокировки) P0 —

2.6 Рисунки

Функция P Поведение
Вставка: файл (png, jpg, gif, webp, bmp, tiff, heic, avif, svg, emf, wmf), буфер обмена, снимок экрана/области (через Paint-модуль захвата), перетаскивание P0 хранение в media/; EMF/WMF — векторно через импорт Draw, резерв — растр
Обрезка: прямоугольная, по фигуре (любая из 187), по пропорции (1:1, 4:3, 16:9, …), «заливка» и «вписать», обрезка не разрушает исходник P0 a:srcRect + a:prstGeom
Стили рисунков: 28 предустановленных (рамки, тени, скосы, отражения, мягкие края, повороты) P0 —
Коррекция: резкость/размытие, яркость, контраст; цвет: насыщенность, оттенок, перекраска (12 вариантов по теме), прозрачный цвет, прозрачность (ползунок) P0 параметры хранятся как a:lum, a:alphaModFix, a:duotone, a:clrChange; рендер через SkColorFilter/SkImageFilter
Удаление фона: автоматическая маска (локальная модель сегментации из Paint) + кисти «отметить/исключить» P1 результат — альфа-маска в media/, исходник сохраняется
Художественные эффекты (карандаш, акварель, мозаика, …) P2 —
Сжатие рисунков (целевое разрешение 96/150/220/330 dpi, удаление обрезанных областей), замена рисунка с сохранением формата, сброс P0 —
Альбом (фотоальбом из папки: раскладки 1/2/4 на слайд, подписи) P2 —
Alt-текст, «декоративный», подпись P0 Assist предлагает alt-текст [Pro]

2.7 Значки и SVG

Функция P Поведение
Библиотека значков: Meridian Glyphs + открытые наборы (Lucide, Fluent — MIT), ≥ 2 000 значков по категориям, поиск по русским и английским названиям P0 хранятся как SVG в ресурсах, вставляются как svgBlip
Вставка SVG с сохранением вектора; перекраска по цветам темы (замена fill/stroke), контур, тень P0 рендер через resvg/собственный SVG-парсер кодеков → meridian-scene
«Преобразовать в фигуру»: SVG → группа фигур с custGeom (редактируемые узлы) P0 —
Экспорт в pptx: asvg:svgBlip + PNG-резерв (как PowerPoint 2016+) P0 —

2.8 Таблицы

Функция P Поведение
Вставка n×m (сетка-выбор до 10×8, диалог до 75×75), рисование таблицы, из Sheets с сохранением форматов, из Write P0 модель — grid-model Sheets (без формул), текст ячеек — text-model
Стили таблиц: 74 предустановленных (как ppt/tableStyles.xml, GUID-идентификаторы), параметры: строка заголовка, строка итогов, чередование строк/столбцов, первый/последний столбец P0 —
Ячейки: объединить/разделить, выравнивание, поля, направление текста, заливка (сплошная/градиент/рисунок), границы (пресеты и по сторонам), размеры, распределение, автоподбор P0 —
Эффекты таблицы (тень, отражение, рельеф), стили WordArt в ячейках P1 —
Связь с диапазоном Sheets (обновление по команде) P1 ссылка objects/table1.msx + диапазон

2.9 Диаграммы (Meridian Chart)

Функция P Поведение
Все типы Meridian Chart (docs/algorithms/chart-engine.md): классические P0, современные (каскадная, воронка, treemap, солнечные лучи, гистограмма, Парето, ящик с усами) P1 P0/P1 один движок с Sheets/Write
Данные: встроенная мини-таблица (objects/chartN.msx, grid-model Sheets) редактируется в боковой панели; связь с внешним .msx/.xlsx с обновлением по команде P0 / P1 как c:externalData в pptx
Макеты, стили (16), цвета по теме, элементы (заголовок, оси, легенда, подписи данных, тренды, планки погрешностей) P0 —
Анимация диаграммы: как один объект, по сериям, по категориям, по элементам серий/категорий P0 p:bldOleChart/p:bldChart
Шаблоны диаграмм .mcht P1 общие с Sheets

2.10 Диаграммы-схемы (аналог SmartArt)

Модуль meridian-diagram: дерево узлов с текстом → автоматическая раскладка по выбранному макету → фигуры, стилизованные темой. Доступен в Slides, Write, Sheets (один код). Категории и макеты:

Категория Макеты P0 Макеты P1 P2
Список простой блочный список, вертикальный маркированный, горизонтальный маркированный, список с рисунками-акцентами, вертикальный блочный, табличный список, список с заголовками в блоках список с округлёнными блоками, вертикальный список со стрелками, список-«лесенка», список с картинками в круге —
Процесс простой процесс, пошаговый (step down), процесс со стрелками-шевронами, повторяющийся изогнутый (змейка), процесс с акцентами, временная шкала вертикальный процесс, чередующийся поток, круговой изогнутый, воронка-процесс, уравнение, процесс со сходящимися стрелками процесс с рисунками
Цикл простой цикл, радиальный цикл, цикл с текстом, сегментированный цикл многонаправленный цикл, шестерёнки, непрерывный цикл, расходящийся радиальный —
Иерархия организационная диаграмма (с помощниками и вертикальными ветвями), иерархия, иерархия с подписями, горизонтальная иерархия табличная иерархия, иерархия с рисунками, круговая иерархия, полукруглая организационная —
Связь баланс, воронка, сходящиеся/расходящиеся стрелки, диаграмма Венна (простая/линейная/вложенная), целевая (концентрическая) противовес, уравнение, кластеры, радиальная, группированный список, «сравнение» (две колонки) —
Матрица простая матрица 2×2, матрица с заголовком, сетка 2×2 циклическая матрица —
Пирамида простая пирамида, перевёрнутая, сегментированная пирамида со списком —
Рисунок список с рисунками, подписанные рисунки полоса рисунков с текстом, круг с рисунками —
Функция P Поведение
Текстовая панель-структура: ввод по уровням, Tab/Shift+Tab — понизить/повысить, Enter — новый узел, перенос узлов перетаскиванием P0 —
Добавить фигуру (после/перед/выше/ниже/помощник), изменить направление (слева направо ↔︎ справа налево), макет организационной ветви (стандартный, обе стороны, слева, справа) P0 —
Сменить макет внутри категории и между категориями с сохранением текста; цвета (по теме: цветной, акцент 1–6, прозрачный/монохромный варианты), стили (7 плоских + 7 объёмных — объёмные P2) P0 —
Преобразовать в фигуры / в текст (список); восстановить макет; размер шрифта общий (§5.6) P0 —
Импорт pptx: известные макеты (по uniqueId dgm:layoutDef) → наш макет; неизвестные → редактируемая группа фигур из кэша drawingN.xml P0 интерпретатор dgm:layoutDef (алгоритмы lin, hierChild, cycle, snake, pyra, composite, conn) — P2

2.11 Видео и аудио

Функция P Поведение
Вставка видео (mp4/H.264, mp4/H.265 при поддержке ОС, webm/VP8/VP9/AV1, mov, m4v, avi, mkv — контейнеры через платформенный декодер) и аудио (mp3, wav, m4a/AAC, ogg/Vorbis, opus, flac) — встроить или связать с файлом P0 воспроизведение: Qt Multimedia (FFmpeg-бэкенд Qt 6.5+ / платформенные AVFoundation, Media Foundation, GStreamer)
Воспроизведение: автоматически / по щелчку / по последовательности щелчков; во весь экран; скрыть, пока не воспроизводится; непрерывно; перемотать после воспроизведения; громкость; без звука P0 p:nvPr/a:videoFile, p14:media, атрибуты trim/fade/bmkLst
Обрезка (trim) начала/конца с предпросмотром и точным вводом времени; без перекодирования (метки), при экспорте видео — физически P0 p14:trim st/end
Появление/исчезание звука (fade in/out), закладки на временной шкале → триггеры анимаций «по закладке» P0 p14:fade, p14:bmk
Кадр-заставка (poster frame): из видео (текущий кадр) или из файла; стили видео (рамка, форма, тень), обрезка кадра P0 —
Фоновая музыка через слайды («воспроизводить для всех слайдов», скрыть значок), остановка на N-м слайде P0 —
Сжатие медиа (целевое качество: Full HD / HD / стандартное) через meridian-video P1 —
Запись экрана (область, звук системы/микрофона) → вставка на слайд P2 —
Субтитры (WebVTT) к видео, отображение при показе P2 —
Онлайн-видео (ссылка на YouTube/VK) P1 постер + ссылка; при показе — открытие во встроенном браузере не делаем, открываем системный

2.12 Переходы

Каталог переходов (имя, категория по PowerPoint, OOXML-элемент, параметры «Параметры эффекта», способ отрисовки):

# Переход Категория OOXML Параметры Рендер
1 Нет — — — —
2 Прорезание Простые p:cut через чёрный CPU
3 Выцветание Простые p:fade плавно / через чёрный шейдер
4 Сдвиг Простые p:push снизу/слева/справа/сверху шейдер
5 Появление Простые p:wipe 4 направления шейдер
6 Панорама Простые p:split по вертикали/горизонтали, внутрь/наружу шейдер
7 Проявление Простые p14:reveal плавно слева/справа, через чёрный шейдер
8 Случайные полосы Простые p:randomBar по вертикали/горизонтали шейдер (хэш полос)
9 Фигура Простые p:circle / p:diamond / p:plus / p:wedge / p:zoom круг, ромб, плюс, клин, внутрь/наружу шейдер (SDF)
10 Открытие Простые p:pull 8 направлений шейдер
11 Наплыв Простые p:cover 8 направлений шейдер
12 Вспышка Простые p14:flash — шейдер
13 Жалюзи Простые p:blinds по вертикали/горизонтали шейдер
14 Шашки Простые p:checker по вертикали/горизонтали шейдер
15 Часы Простые p:wheel 1/2/3/4/8 спиц, обратно (p14:wheelReverse) шейдер
16 Растворение Простые p:dissolve — шейдер (шум)
17 Гребёнка Простые p:comb по вертикали/горизонтали шейдер
18 Полосы Простые p:strips 4 диагонали шейдер
19 Новости Простые p:newsflash — 2D-трансформ
20 Падение Эффектные p15:prstTrans fallOver влево/вправо 3D (SkM44)
21 Драпировка Эффектные p15:prstTrans drape влево/вправо сетка вершин (drawVertices)
22 Занавес Эффектные p15:prstTrans curtains — сетка вершин
23 Ветер Эффектные p15:prstTrans wind влево/вправо частицы (полосы)
24 Престиж Эффектные p15:prstTrans prestige — 3D
25 Разрушение Эффектные p15:prstTrans fracture — осколки Вороного (предрасчёт)
26 Сжатие Эффектные p15:prstTrans crush — сетка вершин
27 Отслаивание Эффектные p15:prstTrans peelOff влево/вправо сетка вершин
28 Скручивание страницы Эффектные p15:prstTrans pageCurlDouble/Single влево/вправо сетка вершин
29 Самолёт Эффектные p15:prstTrans airplane влево/вправо 3D
30 Оригами Эффектные p15:prstTrans origami влево/вправо 3D
31 Растворение (пиксели) Эффектные p14:glitter ромбы/шестиугольники, 4 направления шейдер
32 Вихрь Эффектные p14:vortex 4 направления частицы (тайлы)
33 Измельчение Эффектные p14:shred полосы/прямоугольники, внутрь/наружу тайлы
34 Переключение Эффектные p14:switch влево/вправо 3D
35 Переворот Эффектные p14:flip влево/вправо 3D
36 Галерея Эффектные p14:gallery влево/вправо 3D
37 Куб Эффектные p14:prism (isContent=0) 4 направления 3D
38 Двери Эффектные p14:doors по вертикали/горизонтали 3D
39 Прямоугольник (Box) Эффектные p14:prism (isContent=1) 4 направления 3D
40 Гребень/соты Эффектные p14:honeycomb — тайлы
41 Рябь Эффектные p14:ripple центр/углы шейдер
42 Колесо обозрения Динамические p14:ferris влево/вправо 3D
43 Конвейер Динамические p14:conveyor влево/вправо 3D
44 Поворот Динамические p14:prism (isInverted) 4 направления 3D
45 Окно Динамические p14:window по вертикали/горизонтали 3D
46 Орбита Динамические p14:prism (вариант) 4 направления 3D
47 Пролёт Динамические p14:flythrough внутрь/наружу, с отскоком 3D
48 Панорамирование Динамические p14:pan 4 направления 2D
49 Деформация Эффектные p14:warp внутрь/наружу шейдер
50 Случайный — p:random — выбор из 2–19
51 Морфинг — p159:morph по объектам / словам / символам интерполяция сцены (§5.10) — P1
Функция P Поведение
Переходы 1–19 и 50 P0 —
Переходы 20–49 P0 для 31–41 (шейдеры/тайлы), P1 для 20–30, 42–49 (3D и сетки вершин) при отсутствии GPU — замена на «Выцветание»
Длительность (0,01–59 с), звук перехода (встроенные 19 + файл, «непрерывно»), смена слайда по щелчку и/или через время, применить ко всем P0 p:transition/@spd, p14:dur, @advClick, @advTm, p:sndAc
Предпросмотр на холсте, автопредпросмотр при выборе P0 —
Морфинг P1 сопоставление фигур по имени !!имя и по id, интерполяция положения/размера/поворота/цвета/геометрии с равным числом узлов; текст — по словам/символам

2.13 Анимации

Функция P Поведение
Эффекты входа (presetClass="entr"): появление, выцветание, вылет, плавное приближение, панорама, появление (wipe), фигура, часы, случайные полосы, увеличение с поворотом, масштабирование, вращение, отскок; эффектные: бумеранг, падение, кнут, плавное появление (float), центрифуга, вылет вверх по спирали, разворот, растягивание, подпрыгивание, увеличение с поворотом, прыжки, спираль, вспышка, пропеллер, появление с вращением — всего 52 пресета P0 presetID/presetSubtype по таблице PowerPoint (каталог meridian-anim/presets/*.xml, 150+ записей)
Эффекты выделения (emph): пульсация, цветовая пульсация, качание, вращение, увеличение/уменьшение, обесцвечивание, затемнение, осветление, прозрачность, цвет объекта, дополнительный цвет, цвет линии, цвет заливки, цвет кисти, цвет шрифта, подчёркивание, мигание полужирным, проявление полужирным, волна — 30 пресетов P0 —
Эффекты выхода (exit): зеркальные входу — 52 пресета P0 —
Пути перемещения (path): линии (6), дуги (4), повороты (4), фигуры (круг, ромб, шестиугольник, сердце, пятиугольник, квадрат, треугольник, …), циклы (кривая, волна, пружина, …), пользовательский путь (рисование, редактирование узлов), «заблокированный/разблокированный» путь, обратное направление P0 p:animMotion/@path (VML-подобный синтаксис M L C Z E)
Параметры эффекта: направление, вариант, количество (для масштаба/вращения), плавное начало/конец (accel/decel), отскок в конце, звук, затемнение после анимации (скрыть/скрыть по щелчку/цвет), анимация текста (всё сразу / по абзацам N уровня / по словам / по буквам с задержкой %) P0 —
Время: начало (по щелчку / с предыдущим / после предыдущего), задержка, длительность (пресеты 0,5/1/2/3/5 с и ввод), повторение (N раз / до следующего щелчка / до конца слайда), перемотка по завершении, автообращение P0 —
Триггеры: по щелчку на фигуре; по закладке видео/аудио P0 p:cond/@evt="onClick", p:tgtEl/p:spTgt; интерактивные последовательности nodeType="interactive"
Анимация диаграмм (по сериям/категориям), диаграмм-схем (по ветвям/уровням), таблиц — как объект P0 p:bldLst
Панель «Анимация» с таймлайном: список эффектов с номерами, перетаскивание порядка, временная шкала с полосками (сдвиг/растяжение мышью), масштаб шкалы, щелчки как вертикальные маркеры, звуки, предпросмотр P0 SL-11
Копирование анимации («кисть анимации») на другие фигуры P0 —
Нумерованные метки у фигур на холсте, порядок перетаскиванием меток P0 —
Воспроизведение: 60 кадров/с, ease-функции, пропуск кадров без накопления задержки (§5.4) P0 —
Анимация 3D-моделей, cameo P2 —

2.14 Показ слайдов

Функция P Поведение
С начала (F5), с текущего (Shift+F5), в окне, в режиме докладчика (Alt+F5), произвольный показ P0 —
Типы показа: докладчик (полный экран), просмотр в окне (с полосой прокрутки), автоматический (киоск: цикл, только ESC) P0 p:showPr
Навигация: щелчок/колесо/клавиши, «Перейти к слайду» (меню и ввод номера+Enter), сетка всех слайдов (G), по разделам, назад к последнему просмотренному, скрытые слайды по H P0 —
Чёрный (B) и белый (W) экран, пауза автоматического показа (S), скрыть указатель (Ctrl+H), показать (Ctrl+A) P0 —
Лазерная указка (Ctrl+L или Ctrl+ЛКМ), перо (Ctrl+P), маркер (Ctrl+I), ластик (Ctrl+E), очистить (E), цвет пера; штрихи сглаживаются (как в Notes) P0 по выходу — «Сохранить рукописный ввод?» → штрихи становятся фигурами слайда (p14:ink/custGeom)
Масштабирование фрагмента слайда (лупа, +/-, перетаскивание области) P0 —
Режим докладчика (SL-09): текущий слайд, следующий слайд/шаг анимации, заметки с масштабом, таймер и часы, панель миниатюр, инструменты пера, чёрный экран, завершение, обмен экранов, настройки P0 два окна, общая ShowSession (§5.9)
Выбор экрана для показа, автоопределение (показ — на внешнем, докладчик — на основном), «использовать режим докладчика» при одном экране (окно поверх) P0 —
Произвольные показы (подмножество слайдов с именем), запуск из гиперссылок/кнопок, «показать и вернуться» P0 p:custShowLst
Разрешение показа (авто/выбор), «использовать аппаратное ускорение» (отключение GPU-переходов) P0 —
Пульт докладчика: управление с телефона через локальную сеть (QR-код, веб-страница в WASM-свободном варианте: простой HTML+WebSocket) [Pro] P1 Feature::SlidesPresenterRemote
Живые субтитры (локальное распознавание речи — Assist) [Pro] P2 фаза 7
Трансляция показа через Meridian Cloud (зрители в браузере) P2 фаза 6+
Запуск показа из проводника/Finder: пункт «Показать» в контекстном меню .mpx/.pptx (аргумент командной строки --show); отдельное расширение «только показ» не вводится, .ppsx открывается сразу в показе P0 —

2.15 Репетиция и хронометраж

Функция P Поведение
Репетиция: показ с панелью «Запись» (время слайда, общее время, пауза, повтор слайда, далее) P0 —
Сохранение времён на слайды (p:transition/@advTm) и в сортировщике под миниатюрами; «использовать время» при показе P0 —
Очистка времён (на слайде / во всех), ручной ввод времени P0 —
Отчёт о репетиции: таблица слайд → время, план vs факт (цель «уложиться в N минут»), экспорт в Sheets P1 —

2.16 Запись показа

Функция P Поведение
Запись голоса (микрофон, выбор устройства, уровень), хронометраж, лазер/перо/маркер как анимации с таймкодами; с текущего слайда или с начала P0 аудио — Opus (в .mpx), AAC/WAV при экспорте в pptx (a:audioFile + p:cmd playFrom)
Экран записи (SL-23): предпросмотр, заметки, кнопки запись/пауза/стоп, очистить запись на слайде/во всех, переснять слайд P0 —
Видео с камеры (cameo-кружок/прямоугольник в углу), микшер камеры и экрана P1 хранится как видео-объект слайда
Экспорт записи в видео (§2.17), публикация (фаза 6) P0 / P2 —

2.17 Экспорт видео [Pro: Feature::SlidesVideoExport]

Функция P Поведение
Контейнеры/кодеки: MP4 (H.264 + AAC), WebM (VP9 + Opus); разрешение 480p/720p/1080p/4K (с сохранением пропорций слайда), 30/60 к/с, качество (битрейт по пресетам) P0 §5.8
Источник времени: записанные хронометраж и закадровый голос / фиксированное время на слайд (по умолчанию 5 с) P0 —
Включаются переходы, анимации, медиа слайдов (с обрезкой и затуханием), рукописный ввод записи, лазер P0 —
Прогресс, предварительная оценка длительности и размера, отмена, экспорт в фоне с уведомлением P0 —
Аппаратное ускорение кодирования (NVENC/QuickSync/AMF через Media Foundation, VideoToolbox) P1 —
GIF (анимированный, с ограничением 256 цветов и дизерингом), HEVC P2 —

2.18 Раздаточные материалы, печать, PDF

Функция P Поведение
Печать: слайды, страницы заметок, структура, выдачи (1, 2, 3 с линиями для заметок, 4, 6, 9 на лист; порядок горизонтальный/вертикальный), рамка слайдов, вписать по размеру, цвет/оттенки серого/ч/б, диапазоны и разделы, скрытые слайды P0 Meridian Print; диалог SL-27
Образец выдач (SL-07): положение колонтитулов, число слайдов на странице, фон P0 —
PDF: слайды, заметки, выдачи; закладки по разделам/слайдам, гиперссылки, PDF/A, PDF/UA с тегами и порядком чтения; комментарии как аннотации P0 (P1 — комментарии) —
Экспорт слайдов в PNG/JPG/SVG (все/текущий/диапазон, разрешение) P0 —
Экспорт в HTML (статичные страницы с SVG слайдов, навигация клавишами, без анимаций) P2 —

2.19 Заметки докладчика

Функция P Поведение
Панель заметок под холстом (SL-13), форматирование Write (абзацы, списки, Ж/К/Ч), вставка рисунков в страницу заметок P0 p:notes, заполнитель body страницы заметок
Страница заметок (SL-04) с образцом заметок (SL-06): изображение слайда, тело заметок, колонтитулы P0 —
В режиме докладчика: масштаб шрифта заметок, прокрутка P0 —
Печать и PDF с заметками; экспорт заметок в Write P0 / P1 —

2.20 Разделы

См. §2.1. В сортировщике разделы — заголовки с кнопками сворачивания; перетаскивание раздела переносит его слайды; печать и экспорт «только раздел»; «Масштаб раздела» (section zoom) — P2.

2.21 Сравнение и рецензирование

Функция P Поведение
Комментарии: к слайду и к фигуре (якорь с координатами), цепочки ответов, «решено», упоминания (фаза 6), панель SL-14, навигация, печать комментариев P0 импорт/экспорт ppt/comments/ (старые) и современных modernComment (p188)
Сравнение двух презентаций: сопоставление слайдов по id/содержимому, фигур по id/имени, текста по словам; панель изменений с принятием/отклонением по одному/всем P1 Feature::WriteCompare не используем — отдельный флаг не нужен (Free)
Правописание, тезаурус, статистика, язык; перевод фрагмента/презентации (Assist [Pro]) P0 / P2 —
Проверка доступности: отсутствие alt-текста, порядок чтения, контраст текста, дубли заголовков слайдов, таблицы без заголовков, субтитры у видео P0 —
Рукописные пометки (ink) при рецензировании P1 —
Защита: пароль на открытие (AES-256, совместимо с Office agile encryption), только чтение, «пометить как окончательный», цифровая подпись [Pro: DocSign] P0 / P1 Feature::DocEncrypt — Pro; Free открывает и снимает защиту при знании пароля

2.22 Совместная работа (фаза 6) [Pro: CloudCollab]

CRDT (Yrs) на уровне дерева слайдов и фигур и текста в фигурах; присутствие (цветные рамки выделений других авторов, аватары на миниатюрах), «следовать за автором», история версий из history/, общий доступ по ссылке, комментарии с упоминаниями и уведомлениями. Показ по сети («зрители следуют за докладчиком») — P2.

2.23 Доступность

Функция P Поведение
Дерево доступности слайда (Qt Accessibility → UIA/NSAccessibility/AT-SPI): фигуры в порядке чтения, текст, таблицы, alt-текст P0 порядок чтения = порядок в панели «Выделение» снизу вверх, редактируется
Полное управление с клавиатуры (обход фигур Tab, ручки размером/поворотом стрелками, меню действий Shift+F10) P0 —
Высокая контрастность интерфейса, масштаб интерфейса 100–300 %, «уменьшить движение» (переходы → выцветание, анимации сокращаются) P0 —
Проверка доступности (§2.21), экспорт PDF/UA P0 —
Субтитры видео, живые субтитры, озвучивание заметок P2 —

2.24 Прочее

Функция P Поведение
Гиперссылки и действия: по щелчку/при наведении — переход (следующий/предыдущий/первый/последний/последний просмотренный/завершить/слайд/произвольный показ/URL/файл), запуск скрипта, звук, выделение P0 a:hlinkClick, a:hlinkHover, ppaction://
Управляющие кнопки с действиями по умолчанию P0 —
Встраивание шрифтов в .mpx/.pptx (подмножество; только шрифты с разрешением на встраивание по OS/2 fsType) P1 ppt/fonts/*.fntdata
Автосохранение (журнал операций каждые 2 с), восстановление после сбоя, версии P0 —
Свойства документа, статистика (слайды, слова, медиа, размер), «проверка документа» (личные данные, скрытые слайды, заметки, комментарии) P0 —
Шаблоны и Hub: галерея шаблонов (≥ 40 своих), недавние, закреплённые P0 —
Скрипты: вкладка «Скрипты», редактор, события презентации и показа, кнопки [Home+] P0 §6
Assist: конспект → слайды, переписать заметки, предложить дизайн, alt-текст [Pro] P2 фаза 7

3. Экраны

Идентификаторы: SL-01…SL-09 — виды и окна; SL-10…SL-19 — боковые и нижние панели; SL-20…SL-59 — диалоги; SL-60…SL-69 — контекстные меню; SL-70+ — всплывающие элементы. Макет — mockups/slides.html, по одному <section class="screen"> на идентификатор.

3.1 SL-01 Обычный вид (Normal)

Каркас — по §5.3 библии. Слева — панель миниатюр (SL-10) шириной 160–320 px с разделами; в центре — холст слайда с полями 24 px, линейками (опц.) и направляющими; под холстом — панель заметок (SL-13, сворачиваемая); справа — боковая панель с вкладками (SL-11, SL-12, SL-14…). Строка состояния: «Слайд 3 из 24 · Раздел „Введение" · Тема „Меридиан" · Русский · [Заметки] [Комментарии] · режимы · масштаб · [Вписать]».

┌──────────────────────────────────────────────────────────────────────────────────────┐
│ [▶] Отчёт Q3.mpx — Meridian Slides                 [⌘K Поиск команд]  [☁ Сохранено] [👤] │
├──────────────────────────────────────────────────────────────────────────────────────┤
│ Файл  Главная  Вставка  Дизайн  Переходы  Анимации  Показ  Рецензирование  Вид  Скрипты │ Формат фигуры │
│ [Слайды][Буфер][Шрифт][Абзац][Рисование][Редактирование]                       [⌄]   │
├────────────┬──────────────────────────────────────────────────────┬──────────────────┤
│ ▾ Введение │  ┌────────────────────────────────────────────────┐  │ Формат фигуры    │
│ ┌────────┐ │  │                                                │  │ ◇ Заливка        │
│ │ 1  ▣   │ │  │     Итоги квартала                             │  │   ● Сплошная     │
│ └────────┘ │  │     ─────────────────────                      │  │   ○ Градиент     │
│ ┌────────┐ │  │     • Выручка +12 %                            │  │ ◇ Линия          │
│ │ 2  ▣ ★ │ │  │     • Новые регионы: 3                         │  │ ◇ Эффекты        │
│ └────────┘ │  │                                   [диаграмма]  │  │ ◇ Размер и полож.│
│ ▾ Финансы  │  │                                                │  │ ◇ Текст          │
│ ┌────────┐ │  └────────────────────────────────────────────────┘  │                  │
│ │ 3  ▣   │ │  Заметки: Напомнить про сроки аудита…        [▲]     │                  │
├────────────┴──────────────────────────────────────────────────────┴──────────────────┤
│ Слайд 2 из 24 · Финансы · Русский     [Заметки] [Комментарии]   ▦ ▤ ▥ ▶   ─●─ 85 % ⤢ │
└──────────────────────────────────────────────────────────────────────────────────────┘

Элементы холста: рамка выделения с 8 маркерами размера, маркером поворота (сверху), жёлтыми регуляторами формы, нумерованные метки анимаций слева от фигур (при открытой панели «Анимация»), умные направляющие (цвет --m-sun), направляющие слайда (перетаскиваемые, с подписью координаты), сетка, рамки заполнителей пунктиром, значок «автоподбор» у переполненной фигуры, мини-панель форматирования при выделении текста, значки комментариев в углах фигур.

3.2 Остальные виды и окна

ID Экран Описание
SL-02 Сортировщик слайдов сетка миниатюр (размер по масштабу 15–100 %), заголовки разделов с кнопками сворачивания, под миниатюрой — номер, значок перехода (★), время (advTm), значок «скрыт»; перетаскивание со вставочной чертой; мультивыбор; клавиши как в проводнике; двойной клик → SL-01
SL-03 Структура слева вместо миниатюр — дерево заголовков и текста заполнителей (уровни), правка текста прямо в структуре, повышение/понижение, развернуть/свернуть; фигуры без заполнителей не показываются
SL-04 Страницы заметок страница (A4/Letter по образцу заметок): изображение слайда сверху, тело заметок снизу, колонтитулы; масштаб, правка текста заметок и свободных объектов
SL-05 Образец слайдов панель миниатюр: образцы (крупные) и их макеты (отступом); холст образца/макета; контекстная вкладка «Образец слайдов» (вставить образец/макет, удалить, переименовать, сохранить, макет образца: показать/скрыть заполнители, вставить заполнитель▾, заголовок/колонтитулы, темы, фон, размер слайда, закрыть); макеты с индикатором «используется N слайдами»
SL-06 Образец заметок заполнители: изображение слайда, тело, верхний/нижний колонтитул, дата, номер; ориентация, фон
SL-07 Образец выдач число слайдов на странице (1/2/3/4/6/9/структура), ориентация страницы/слайдов, колонтитулы, фон
SL-08 Режим чтения (показ в окне) слайды в окне с панелью навигации внизу (назад/вперёд/меню/завершить), без ribbon; реагирует на размер окна
SL-09 Показ и режим докладчика Окно показа: полноэкранное на выбранном экране, чёрные поля при несовпадении пропорций, скрытая панель инструментов в левом нижнем углу (появляется при движении мыши: назад, перо▾, лупа, сетка слайдов, субтитры, меню, вперёд). Окно докладчика: вверху — таймер (старт/пауза/сброс), часы, индикатор «Экран N»; слева большой текущий слайд (с рукописными инструментами), справа сверху — следующий слайд/шаг («Далее: анимация 3 из 5»), справа снизу — заметки с кнопками A+/A−; внизу — лента миниатюр с номерами и разделами, кнопки «Чёрный экран», «Обмен экранов», «Показать панель задач», «Завершить». Клавиши — §8

3.3 Ribbon — вкладки и группы

Вкладка Группы (команды)
Файл (backstage) Создать (шаблоны и темы Hub), Открыть, Сведения (защита, проверка, свойства, версии, встроенные шрифты, медиа: сжать/оптимизировать), Сохранить, Сохранить как, Экспорт (PDF, видео, изображения, выдачи в Write, HTML), Печать (SL-27), Поделиться (фаза 6), Параметры (SL-40), Аккаунт/Лицензия
Главная Слайды (создать слайд▾, макет▾, сбросить, раздел▾) · Буфер обмена (вставить▾, вырезать, копировать, формат по образцу) · Шрифт (гарнитура, размер, увеличить/уменьшить, очистить формат, Ж/К/Ч/S, тень, межзнаковый▾, регистр▾, цвет▾) · Абзац (маркеры▾, нумерация▾, уровень −/+, интервал▾, направление▾, выравнивание ×4, колонки▾, выровнять текст▾, преобразовать в диаграмму-схему▾) · Рисование (галерея фигур, упорядочить▾, экспресс-стили▾, заливка▾, контур▾, эффекты▾) · Редактирование (найти, заменить▾, выделить▾) · Assist [Pro]
Вставка Слайды (создать слайд▾, повторное использование) · Таблицы (таблица▾) · Изображения (рисунки▾, снимок▾, фотоальбом P2) · Иллюстрации (фигуры▾, значки, диаграмма-схема, диаграмма) · Ссылки (гиперссылка, действие, масштаб слайдов P2) · Примечания (комментарий) · Текст (надпись, колонтитулы, WordArt▾, дата и время, номер слайда, объект Math) · Символы (формула▾, символ) · Мультимедиа (видео▾, звук▾, запись экрана P2) · Скрипты (кнопка)
Дизайн Темы (галерея, цвета▾, шрифты▾, эффекты▾, фон▾) · Варианты (4 варианта) · Настроить (размер слайда▾, формат фона → SL-12, дизайнерские идеи P1)
Переходы Просмотр (просмотр) · Переход к этому слайду (галерея из §2.12, параметры эффекта▾) · Время показа (звук▾, длительность, применить ко всем; смена слайда: по щелчку, через N с)
Анимации Просмотр (просмотр▾) · Анимация (галерея: вход/выделение/выход/пути; параметры эффекта▾) · Расширенная анимация (добавить анимацию▾, область анимации → SL-11, триггер▾, по образцу) · Время показа (начало▾, длительность, задержка, порядок: раньше/позже)
Показ Начать показ (с начала, с текущего, в режиме докладчика, произвольный показ▾, по сети P2) · Настройка (настройка показа → SL-21, скрыть слайд, репетиция, записать▾ → SL-23, воспроизвести закадровый текст, использовать время, показывать элементы управления) · Мониторы (экран показа▾, режим докладчика ☑) · Субтитры (P2)
Рецензирование Правописание (орфография, тезаурус, статистика) · Доступность (проверка, alt-текст) · Язык (перевести P2, язык▾) · Примечания (создать, удалить▾, предыдущее, следующее, показать панель) · Сравнить (сравнить P1, принять▾, отклонить▾, далее/назад, панель, завершить) · Рукописный ввод (начать, скрыть P1) · Защита (пароль, только чтение, окончательный, подпись)
Вид Режимы просмотра (обычный, структура, сортировщик, страницы заметок, чтение) · Режимы образцов (образец слайдов, заметок, выдач) · Показать (линейка, сетка, направляющие, заметки, параметры сетки → SL-29) · Масштаб (масштаб, вписать) · Цвет/оттенки серого (цвет, серый, ч/б — предпросмотр печати) · Окно (новое окно, упорядочить, каскад, переключить) · Фокус
Скрипты [Home+] Код (редактор скриптов, записать действия, остановить, выполнить▾, отладчик) · Презентация (скрипты документа, события: открытие/показ/смена слайда/клик, расписания) · Кнопки (кнопка на слайде, в ленте, назначить действие) · Безопасность (разрешения, подписи, политики)
Формат фигуры (контекст) Вставка фигур (галерея, изменить фигуру▾, объединить▾ P1, надпись) · Стили фигур (галерея, заливка▾, контур▾, эффекты▾) · Стили WordArt (галерея, заливка▾, контур▾, эффекты▾) · Специальные возможности (alt-текст) · Упорядочение (вперёд▾, назад▾, область выделения, выровнять▾, группировать▾, повернуть▾) · Размер (высота, ширина, дополнительно → SL-12)
Формат рисунка (контекст) Изменение (удалить фон P1, коррекция▾, цвет▾, художественные эффекты P2, прозрачность▾, сжать, заменить▾, сброс▾) · Стили рисунков (галерея, граница▾, эффекты▾, макет рисунка — в диаграмму-схему▾) · Специальные возможности · Упорядочение · Размер (обрезка▾, высота, ширина)
Конструктор таблиц / Макет таблицы (контекст) Параметры стиля · Стили таблиц · Стили WordArt · Нарисовать границы ‖ Таблица (выделить▾, сетка) · Строки и столбцы (удалить▾, вставить ×4) · Объединение · Размер ячейки · Выравнивание · Размер таблицы · Упорядочение
Конструктор диаграмм / Формат (контекст) как в Sheets (docs/apps/sheets.md §3.2): макеты, стили, данные (изменить данные → панель, выбрать данные, строка/столбец, обновить связь), тип ‖ Формат
Конструктор диаграммы-схемы / Формат (контекст) Создание рисунка (добавить фигуру▾, маркер, справа налево, макет▾, повысить/понизить, вверх/вниз, область текста) · Макеты (галерея) · Стили (цвета▾, галерея стилей) · Сброс (восстановить, преобразовать▾) ‖ Фигуры (в 2D-режиме, изменить фигуру▾, крупнее/мельче) · Стили фигур · Стили WordArt · Упорядочение · Размер
Формат видео / Воспроизведение (контекст) Просмотр · Коррекция (яркость, цвет, заставка▾, сброс▾) · Стили видео (галерея, форма▾, граница▾, эффекты▾) · Упорядочение · Размер (обрезка) ‖ Закладки (добавить, удалить) · Редактирование (монтаж → SL-32, появление/исчезание) · Параметры (громкость▾, начало▾, во весь экран, скрыть пока не воспроизводится, непрерывно, перемотать) · Субтитры P2
Формат звука / Воспроизведение (контекст) Стили рисунка (значок) ‖ Закладки · Монтаж · Появление/исчезание · Параметры (громкость, начало, для всех слайдов, непрерывно, скрыть при показе, перемотать) · Стили звука (в фоне, нет стиля)
Образец слайдов / Образец заметок / Образец выдач (контекст) см. SL-05…SL-07
Запись (контекст, при открытой SL-23) Запись (с текущего слайда, с начала) · Содержимое (снимок экрана P2, запись экрана P2) · Автовоспроизведение (воспроизвести, очистить▾) · Сохранить (экспорт в видео, опубликовать P2)

Компактный режим и командная палитра — по §5.3 библии. Палитра в Slides дополнительно ищет слайды по заголовку («перейти к слайду „Бюджет"»), фигуры по имени и анимации.

3.4 Панели

ID Панель Описание
SL-10 Миниатюры слайдов (слева) вертикальный список с номерами, значками «скрыт»/«переход»/«анимация»/«комментарии»/«скрипт», заголовки разделов (свернуть/развернуть, контекстное меню раздела), перетаскивание, мультивыбор (Ctrl/Shift), масштаб миниатюр (Ctrl+колесо), кнопка «Структура» переключает в SL-03; при совместной работе — аватары редакторов на миниатюрах
SL-11 Анимация (справа) верх: список эффектов (номер, значок типа, имя фигуры, триггер-группы «Триггер: Фигура 5»), перетаскивание порядка, ▶ «Воспроизвести с/все», кнопки раньше/позже; низ: таймлайн — шкала секунд (масштаб ×0,5…×8), полоски эффектов (цвет по типу: вход зелёный, выделение жёлтый --m-sun, выход красный, путь синий), перетаскивание начала/длины, маркеры щелчков, звуки; двойной клик по эффекту → SL-24 «Параметры эффекта»
SL-12 Формат фигуры / рисунка / фона / текста (справа) аккордеон: Заливка, Линия, Эффекты (тень/отражение/свечение/мягкие края/рельеф P2/поворот 3D P2), Размер и свойства (размер, положение, надпись: привязка, поля, автоподбор, колонки; alt-текст), Рисунок (коррекция, цвет, обрезка); для фона — «Формат фона» с «применить ко всем» и «сбросить»; для текста — заливка/контур/эффекты текста
SL-13 Заметки (внизу) многострочный редактор Write, высота перетаскиванием (запоминается), кнопка разворота, счётчик слов
SL-14 Комментарии (справа) карточки по слайду: автор, время, текст, ответы, «решено», якорь (клик — подсветка фигуры), «Создать», фильтр (все/открытые/мои), навигация по слайдам с комментариями
SL-15 Макеты / Дизайнерские идеи (справа) вкладка «Макеты»: галерея макетов текущего образца (клик — применить); вкладка «Идеи» P1: 6–12 вариантов раскладки текущего слайда (миниатюры), «Ещё», применение с отменой
SL-16 Выделение (справа) дерево фигур слайда (группы раскрываются) в z-порядке, видимость (глаз), переименование, перетаскивание порядка, блокировка; порядок чтения для доступности = обратный z-порядок с ручной правкой
SL-17 Данные диаграммы (справа) мини-таблица Sheets (grid-model) для встроенных данных: правка ячеек, добавить/удалить ряды, «переключить строки/столбцы», «открыть в Sheets», связь с файлом
SL-18 Повторное использование слайдов (справа) P1 выбор файла, миниатюры, «сохранить исходное форматирование», клик — вставить после текущего
SL-19 Текст диаграммы-схемы (плавающая у объекта) структура узлов с уровнями, маркеры, подсказки клавиш
SL-70 Мини-панель форматирования при выделении текста/фигуры: шрифт, размер, Ж/К/Ч, цвет, выравнивание, маркеры, заливка/контур, «ещё…»
SL-71 Кнопка «Параметры автоподбора» у переполненного заполнителя: сжать текст / остановить / разделить на два слайда / продолжить на новом / изменить на два столбца
SL-72 Панель репетиции поверх показа: ▶/⏸, время слайда, ↻ повторить, общее время, «Далее»
SL-73 Панель инструментов показа полупрозрачная в левом нижнем углу окна показа

3.5 Диалоги

ID Диалог Содержимое
SL-20 Параметры слайда (размер) список пресетов (16:9, 4:3, 16:10, A4, A3, Letter, Ledger, B4, B5, 35 мм, баннер, свой), ширина/высота (см/дюйм/px), ориентация слайдов и заметок, нумерация с, при уменьшении: «вписать» / «по максимуму» с предпросмотром
SL-21 Настройка показа тип (докладчик / окно / киоск), параметры (непрерывный цикл до Esc, без закадрового текста, без анимации, отключить GPU-переходы), цвет пера/лазера, слайды (все / с N по M / произвольный показ), смена слайдов (вручную / по времени), мониторы (экран показа, режим докладчика), разрешение
SL-22 Произвольный показ список показов; создать/изменить: имя, два списка (слайды презентации → слайды показа) с добавлением/удалением/порядком; «Показать»
SL-23 Запись показа (окно) полноэкранное окно: предпросмотр слайда, заметки, устройства (микрофон, камера P1, уровень), кнопки Запись/Пауза/Стоп/Повтор, таймер, перо/лазер, навигация, «Очистить» ▾ (запись на слайде / все), по закрытии — сохранение хронометража
SL-24 Параметры эффекта вкладки: Эффект (направление/вариант, количество, плавное начало/конец, отскок, звук, после анимации, анимация текста), Время (начало, задержка, длительность, повтор, перемотка, триггеры), Анимация текста/диаграммы/схемы (группировка: как один объект / по абзацам уровня N / по сериям / по ветвям; порядок, обратный порядок, задержка между элементами, анимировать прикреплённую фигуру)
SL-25 Экспорт видео [Pro] формат (MP4 H.264 / WebM VP9), качество (4K / Full HD / HD / SD — таблица битрейтов), к/с (30/60), источник времени (записанные / N с на слайд), использовать закадровый текст и лазер, диапазон (все / раздел / с-по), папка/имя, оценка размера и длительности, «Экспортировать» с прогрессом в фоне
SL-26 Колонтитулы вкладки Слайд / Заметки и выдачи: дата и время (автообновление: формат из 13, язык, календарь; фиксированная), номер слайда, нижний колонтитул (текст), верхний колонтитул (заметки), «не показывать на титульном», предпросмотр положения; «Применить» / «Применить ко всем»
SL-27 Печать выдач принтер и свойства (Meridian Print), что печатать (слайды / страницы заметок / структура / выдачи 1–9 с порядком), диапазон (все / текущий / выделенные / с-по / разделы), копии, разобрать, цвет, рамка, вписать, скрытые слайды, комментарии и рукописный ввод, предпросмотр справа
SL-28 Гиперссылка / Действие гиперссылка: файл/веб-страница, место в документе (список слайдов с миниатюрами, произвольные показы), адрес эл. почты, текст, подсказка; действие по щелчку/наведению: нет, переход▾, запуск программы (запрещено политикой по умолчанию), запуск скрипта▾, звук▾, выделить
SL-29 Сетка и направляющие привязка к сетке, к фигурам (умные направляющие), шаг сетки (0,1–5 см, пресеты 1/8…1/2 дюйма), показывать сетку, направляющие (вертикальные/горизонтальные, добавить/удалить, цвет), применить к образцу
SL-30 Вставка таблицы столбцы/строки (1–75)
SL-31 Вставка видео / звука из файла, из буфера, по ссылке (онлайн P1), «связать с файлом», сжать при вставке
SL-32 Монтаж видео/звука временная шкала с миниатюрами кадров/формой волны, маркеры начала/конца с полями времени, предпросмотр, кнопки покадровой навигации
SL-33 Параметры переходов звук (список 19 встроенных + «другой…», «непрерывно»), длительность, смена слайда
SL-34 Диаграмма-схема — выбор макета слева категории, в центре галерея, справа крупный пример с описанием
SL-35 Вставка диаграммы типы Meridian Chart с подтипами и предпросмотром на данных-образце
SL-36 Сравнение презентаций P1 выбор файла, отчёт: список изменений (слайд, тип, описание), принять/отклонить
SL-37 Сжатие медиа целевое качество, оценка экономии, прогресс
SL-38 Встраивание шрифтов P1 список использованных шрифтов, лицензия на встраивание (разрешено/только предпросмотр/запрещено), подмножество/все символы
SL-39 Замена шрифтов «заменить» → «на» по всей презентации
SL-40 Параметры Slides общие (единицы, язык), правка (автоподбор по умолчанию, умные направляющие, вставка), сохранение (формат по умолчанию, автосохранение, встраивать шрифты), показ (экраны, подсказки, конец показа чёрным), дополнительно (GPU, кэш миниатюр, качество рисунков), скрипты
SL-41 Параметры автоподбора текста для фигуры: не автоподбирать / сжимать при переполнении / подгонять размер фигуры
SL-42 Произвольный путь — редактирование редактор узлов пути перемещения (общий редактор Draw) с привязкой к центру фигуры, «замкнуть», «обратить»
SL-43 Экспорт изображений формат (PNG/JPG/SVG/WebP), слайды (все/текущий/диапазон), размер (ширина px или dpi), прозрачный фон (PNG), папка, шаблон имени
SL-44 Защита: пароль / только чтение / подпись как в Write
SL-45 Фотоальбом P2 источник, раскладка, подписи, порядок
SL-46 Пульт докладчика [Pro] P1 QR-код и адрес, подключённые устройства, отключить
SL-60 Контекстное меню слайда (миниатюра) создать, дублировать, удалить, скрыть, макет▾, сбросить, добавить раздел, переименовать раздел, формат фона, новый комментарий, вставить▾
SL-61 Контекстное меню фигуры вырезать/копировать/вставить▾, группировать▾, на передний/задний план▾, гиперссылка, сохранить как рисунок, изменить замещающий текст, размер и положение, формат фигуры, заблокировать, добавить анимацию▾
SL-62 Контекстное меню показа далее, назад, последний просмотренный, показать все слайды, лупа, произвольный показ▾, показать режим докладчика, экран▾ (чёрный/белый/панель задач), указатель▾ (лазер/стрелка/перо/маркер/ластик/цвет), субтитры P2, справка, пауза/продолжить, завершить

4. Модель данных

4.1 Пакет .mpx

mimetype                       application/vnd.meridian.slides (без сжатия, первым)
manifest.xml                   список частей, версия формата, роль (document|template), наличие скриптов/подписей
meta.xml                       Dublin Core + статистика (слайды, слова, медиа), приложение-создатель
presentation.xml               корень: размер слайда, порядок слайдов, разделы, произвольные показы, настройки показа,
                               стиль текста по умолчанию, ссылки на образцы и темы
masters/master-<ulid>.xml      образец слайдов (фон, заполнители, стили текста, карта цветов, список макетов)
layouts/layout-<ulid>.xml      макет (ссылка на образец, тип, заполнители)
slides/slide-<ulid>.xml        слайд (ссылка на макет, дерево фигур, фон, переход, таймлайн анимаций, заметки, комментарии)
themes/theme-<ulid>.xml        тема DrawingML-подобной структуры (цвета, шрифты, эффекты)
notes-master.xml, handout-master.xml
styles.xml                     стили таблиц, стили фигур по умолчанию, именованные стили текста
settings.xml                   вид, масштаб, последний слайд, параметры сетки, кэш репетиции
media/<sha256>.<ext>           изображения, видео, аудио (большие — stored, без deflate)
objects/chart-<ulid>.msx       данные диаграмм, objects/table-<ulid>.msx — связанные таблицы, objects/*.meq — формулы
diagrams/diagram-<ulid>.xml    модель диаграммы-схемы (узлы + макет + стиль)
thumbnails/slide-<ulid>.png    кэш миниатюр (опционально), thumbnail.png — первый слайд 256 px
history/                       журнал CRDT-операций (опционально)
scripts/, signatures/, fonts/  скрипты, подписи, встроенные подмножества шрифтов (WOFF2)

Идентификаторы — ULID (сортируемые, уникальные между документами) для слайдов/образцов/макетов и u32 для фигур внутри слайда (как p:cNvPr/@id, сохраняются при round-trip pptx). Пример слайда:

<slide xmlns="urn:meridian:office:slides:1" id="01J9QZ3M7P6V8R2TQX4W5Y6Z7A" layout="01J9QZ…" hidden="false">
  <background><solidFill color="scheme:bg1"/></background>
  <shapes>
    <sp id="2" name="Заголовок 1" ph="title">
      <xfrm x="838200" y="365125" w="10515600" h="1325563"/>
      <txBody><bodyPr anchor="b" autofit="shrink"/><p><r rPr.sz="4400">Итоги квартала</r></p></txBody>
    </sp>
    <sp id="3" name="Текст 2" ph="body" phIdx="1">
      <xfrm x="838200" y="1825625" w="10515600" h="4351338"/>
      <txBody><p lvl="0"><r>Выручка +12 %</r></p><p lvl="0"><r>Новые регионы: 3</r></p></txBody>
    </sp>
    <graphicFrame id="4" name="Диаграмма 3"><xfrm …/><chart ref="objects/chart-01J9…msx" model="charts/chart-01J9….xml"/></graphicFrame>
  </shapes>
  <transition kind="push" dir="l" dur="700" advClick="true" advTm="5000"/>
  <timing>…(§4.6)…</timing>
  <notes><p><r>Напомнить про сроки аудита</r></p></notes>
</slide>

4.2 Структуры ядра (Rust, meridian-slides)

// kernel/crates/meridian-slides/src/model.rs
use meridian_scene::{Shape, ShapeId, ShapeTree, Fill, Theme, ColorMap, TextStyleLevels};

/// Презентация — корень документа / Presentation document root.
pub struct Presentation {
    pub id: Ulid,
    pub size: SlideSize,                       // ширина/высота в EMU, тип пресета / width/height in EMU
    pub masters: IndexMap<Ulid, SlideMaster>,
    pub layouts: IndexMap<Ulid, SlideLayout>,
    pub slides: Vec<Ulid>,                     // порядок слайдов / slide order
    pub slide_store: IndexMap<Ulid, Slide>,
    pub sections: Vec<Section>,                // раздел = имя + диапазон слайдов / name + slide range
    pub custom_shows: Vec<CustomShow>,
    pub notes_master: NotesMaster,
    pub handout_master: HandoutMaster,
    pub themes: IndexMap<Ulid, Theme>,
    pub default_text_style: TextStyleLevels,
    pub show_settings: ShowSettings,           // тип показа, цикл, экраны / show type, loop, screens
    pub media: MediaStore,                     // sha256 → MediaEntry (путь, mime, размер, длительность)
    pub comments: CommentStore,                // комментарии по слайдам / per-slide comments
    pub meta: DocMeta,
}

pub struct SlideMaster {
    pub id: Ulid,
    pub theme: Ulid,
    pub color_map: ColorMap,                   // bg1→lt1, tx1→dk1, … / scheme-to-theme mapping
    pub background: Background,
    pub shapes: ShapeTree,                     // общие фигуры + заполнители с полным форматированием
    pub text_styles: MasterTextStyles,         // title, body (9 уровней), other
    pub layouts: Vec<Ulid>,
    pub transition: Option<Transition>,
    pub timing: Option<AnimTimeline>,
    pub header_footer: HeaderFooter,
}

pub struct SlideLayout {
    pub id: Ulid,
    pub master: Ulid,
    pub kind: LayoutKind,                      // 36 типов ST_SlideLayoutType + Custom
    pub name: String,
    pub shapes: ShapeTree,                     // заполнители макета (ph type/idx) и фоновые фигуры
    pub show_master_shapes: bool,
    pub background: Option<Background>,
    pub preserve: bool,                        // не удалять при неиспользовании / keep when unused
}

pub struct Slide {
    pub id: Ulid,
    pub layout: Ulid,
    pub shapes: ShapeTree,                     // дерево фигур в z-порядке / shape tree in z-order
    pub background: Option<Background>,
    pub show_master_shapes: bool,
    pub transition: Option<Transition>,
    pub timing: Option<AnimTimeline>,          // §4.6
    pub notes: Option<NotesSlide>,
    pub hidden: bool,
    pub advance_ms: Option<u32>,               // хронометраж репетиции / rehearsed advance time
    pub narration: Option<MediaRef>,           // закадровый голос / recorded narration
    pub revision: u64,                         // для инвалидации миниатюр / thumbnail invalidation
}

/// Дерево фигур: плоское хранилище + порядок детей; группы — узлы с детьми.
pub struct ShapeTree {
    pub nodes: SlotMap<ShapeId, ShapeNode>,
    pub roots: Vec<ShapeId>,                   // z-порядок: первый — самый нижний / first = bottom-most
}
pub struct ShapeNode { pub shape: Shape, pub parent: Option<ShapeId>, pub children: Vec<ShapeId> }

pub enum ShapeKind {
    Sp { geom: Geometry, text: Option<TextBody> },             // фигура с текстом / shape with text
    Pic { media: MediaRef, crop: SrcRect, effects: PicEffects },
    GraphicFrame(GraphicContent),                               // Table | Chart | Diagram | Ole | Math
    Cxn { geom: Geometry, start: Option<CxnEnd>, end: Option<CxnEnd> },
    Grp { child_xfrm: ChildTransform },                         // группа: своя система координат
    Media { media: MediaRef, poster: Option<MediaRef>, playback: Playback },
}

pub struct Shape {
    pub id: ShapeId,                           // = p:cNvPr/@id при round-trip
    pub name: String,
    pub kind: ShapeKind,
    pub xfrm: Transform2D,                     // off, ext, rot (1/60000°), flipH, flipV
    pub placeholder: Option<Placeholder>,      // type, idx, orient, size
    pub style: ShapeStyleRefs,                 // lnRef/fillRef/effectRef/fontRef (idx + цвет)
    pub props: ShapeProps,                     // fill, line, effects, scene3d/sp3d (P2)
    pub hyperlink: Option<Action>,
    pub hover: Option<Action>,
    pub locks: Locks,                          // noGrp, noMove, noResize, noSelect, noTextEdit, …
    pub alt_text: AltText,
    pub hidden: bool,
    pub ext: Vec<ExtensionBlob>,               // неизвестные расширения — round-trip / unknown extensions
}

pub struct Placeholder { pub kind: PlaceholderType, pub idx: Option<u32>, pub orient: Orient, pub size: PhSize, pub has_custom_prompt: bool }

4.3 Текстовое тело

TextBody — тот же тип, что в Write (text-model): BodyProps (вставки, привязка, перенос, направление, колонки, автоподбор, деформация), ListStyle (9 уровней ParaProps), Vec<Paragraph>; Paragraph { props, runs }, Run { text, props: RunProps } | Field { kind: SlideNum | DateTime(fmt), props } | LineBreak | MathInline(ref). Единицы: размер шрифта в 1/100 pt, отступы и интервалы в EMU или процентах — как в DrawingML, чтобы round-trip был без округлений.

4.4 Геометрия и стили (из meridian-scene)

pub enum Geometry {
    Preset { kind: PresetShape /* 187 вариантов */, adj: SmallVec<[(AdjName, i64); 8]> },
    Custom { paths: Vec<GeomPath>, guides: Vec<Guide>, adj: Vec<(AdjName, i64)>, cxn: Vec<CxnSite>, text_rect: Option<GuideRect> },
}
pub enum Fill { None, Solid(Color), Gradient(Gradient), Blip(BlipFill), Pattern { preset: PatternPreset, fg: Color, bg: Color }, Group /* наследовать от группы */ }
pub enum Color { Srgb(u32), Scheme { name: SchemeColor, mods: Vec<ColorMod> }, Preset(PresetColor), Hsl(..), System(..) }
pub struct Line { pub width_emu: i64, pub fill: Fill, pub dash: DashPreset | Custom(Vec<(u32,u32)>), pub cap: Cap, pub join: Join, pub compound: Compound, pub head: Arrow, pub tail: Arrow }
pub struct Effects { pub shadow: Option<Shadow>, pub reflection: Option<Reflection>, pub glow: Option<Glow>, pub soft_edge: Option<i64>, pub blur: Option<Blur> }

Цвета разрешаются в sRGB только при рендере: Color::resolve(theme, color_map); модификаторы (lumMod, lumOff, tint, shade, alpha, satMod, hueOff …) применяются в порядке записи, как в DrawingML.

4.5 Наследование свойств заполнителей (master → layout → slide)

Поиск «родителя» заполнителя:

  1. Фигура слайда с placeholder{kind, idx} ищет в макете заполнитель с тем же idx; если idx нет — с тем же kind (для kind ∈ {title, ctrTitle} ищется title/ctrTitle; для body/obj/tbl/chart/dgm/media/pic/clipArt — body).
  2. Заполнитель макета ищет в образце по kind (все «телесные» типы → body; dt, ftr, sldNum — по своему типу).
  3. Для текста к цепочке добавляются стили образца (titleStyle / bodyStyle / otherStyle по уровню абзаца), затем default_text_style презентации, затем тема (шрифты +mj-lt/+mn-lt, цвета схемы), затем встроенные значения (размер 18 pt, выравнивание влево, чёрный tx1).
/// Разрешение свойств абзаца/символов по цепочке наследования /
/// Resolve paragraph/run properties along the inheritance chain.
pub fn resolve_run_props(ctx: &ResolveCtx, slide: &Slide, shape: &Shape, para: &Paragraph, run: &Run) -> ResolvedRunProps {
    let lvl = para.props.level.unwrap_or(0) as usize;
    // Цепочка от самого конкретного к общему / chain from most specific to most generic
    let mut chain: SmallVec<[&RunProps; 8]> = smallvec![&run.props];
    if let Some(pr) = para.props.default_run.as_ref() { chain.push(pr); }          // a:pPr/a:defRPr
    if let Some(list) = shape.text_list_style() { chain.extend(list.level(lvl).map(|l| &l.run)); }
    for owner in ctx.placeholder_chain(slide, shape) {                               // layout ph → master ph
        if let Some(list) = owner.text_list_style() { chain.extend(list.level(lvl).map(|l| &l.run)); }
    }
    chain.extend(ctx.master_text_style(slide, shape).level(lvl).map(|l| &l.run));   // titleStyle/bodyStyle/otherStyle
    chain.extend(ctx.presentation.default_text_style.level(lvl).map(|l| &l.run));
    let mut out = ResolvedRunProps::builtin();                                       // 18 pt, tx1, +mn-lt
    for props in chain.iter().rev() { out.apply(props); }                            // общие → конкретные / generic → specific
    out.resolve_colors(ctx.theme(slide), ctx.color_map(slide));
    out
}

Геометрия заполнителя (xfrm) наследуется так же: если у фигуры слайда нет xfrm, берётся из макета, затем из образца. «Сбросить слайд» удаляет на слайде всё, что совпадает с унаследованным, сохраняя текст.

4.6 Таймлайн анимаций (meridian-anim)

Структура повторяет дерево p:timing, чтобы импорт/экспорт pptx был изоморфным; «плоские» списки для панели SL-11 вычисляются из дерева.

// kernel/crates/meridian-anim/src/timeline.rs
pub struct AnimTimeline { pub root: TimeNode /* nodeType=tmRoot, par */, pub builds: Vec<Build> /* bldP, bldChart, bldDgm */ }

pub struct TimeNode {
    pub id: u32,
    pub kind: NodeKind,                      // Par | Seq { concurrent, next_action, prev_action } | Behavior(Behavior)
    pub node_type: NodeType,                 // TmRoot | MainSeq | ClickEffect | WithEffect | AfterEffect | ClickPar | WithGroup | AfterGroup | Interactive
    pub start: Vec<Condition>,               // stCondLst: Delay(ms) | Indefinite | OnClick(ShapeId) | OnBegin(NodeId) | OnEnd(NodeId) | OnNext | OnPrev | Bookmark(media, name)
    pub end: Vec<Condition>,
    pub duration: Duration,                  // Ms(u32) | Indefinite | Media
    pub repeat: Repeat,                      // Count(f32) | Indefinite | UntilNextClick | UntilEndOfSlide
    pub autoreverse: bool,
    pub fill: FillMode,                      // Hold | Freeze | Remove | Transition
    pub accel: u16, pub decel: u16,          // 0..100000 (доли длительности) / fractions of duration
    pub restart: Restart,                    // Always | WhenNotActive | Never
    pub preset: Option<Preset>,              // { class: Entr|Emph|Exit|Path|Verb|MediaCall, id: u16, subtype: u16 }
    pub group_id: Option<u32>,               // grpId — связь с bldP / link to text build
    pub target: Option<Target>,              // фигура / абзац / фон / звук / видео
    pub children: Vec<TimeNode>,
    pub next_cond: Vec<Condition>, pub prev_cond: Vec<Condition>,   // для Seq
}

pub enum Behavior {
    Set   { attr: AnimAttr, value: AnimValue },                                        // p:set
    Anim  { attr: AnimAttr, calc: CalcMode /* Discrete|Lin|Fmla */, keys: Vec<KeyFrame /* tm 0..100000, val|formula */>, by: Option<AnimValue>, from: Option<AnimValue>, to: Option<AnimValue> },
    Effect { transition: InOut, filter: String /* "fade", "wipe(left)", "wheel(4)" … */, progress: Option<Vec<KeyFrame>> }, // p:animEffect
    Motion { path: MotionPath /* M L C Z E в долях слайда */, origin: Origin, rotate_along: bool, path_edit_mode: EditMode, by_x: f32, by_y: f32 },
    Rotate { by: Option<i32>, from: Option<i32>, to: Option<i32> },                   // 1/60000°
    Scale  { by: Option<(f32,f32)>, from: Option<(f32,f32)>, to: Option<(f32,f32)>, zoom_contents: bool },
    Color  { space: ColorSpace /* rgb|hsl */, dir: HueDir, by: Option<ColorDelta>, from: Option<Color>, to: Option<Color> },
    Command { kind: CmdKind /* Call|Evt|Verb */, cmd: String /* playFrom(0.0), togglePause, stop */ },
    Audio  { media: MediaRef, is_narration: bool },
    Video  { media: MediaRef, full_screen: bool },
}

pub enum AnimAttr { PptX, PptY, PptW, PptH, PptR, Visibility, FillColor, FillOn, LineColor, LineOn, Opacity, TextFontSize, TextBold, TextItalic, TextUnderline, TextColor, Custom(SmolStr) }

Соответствие с панелью SL-11: один «эффект» = поддерево ClickEffect|WithEffect|AfterEffect с preset; его «щелчок» = индекс ClickPar-предка в MainSeq; «начало» вычисляется из node_type; задержка/длительность — из start/duration.

4.7 Переходы, показ, запись

pub struct Transition { pub kind: TransitionKind /* 51 вариант §2.12 */, pub params: TransitionParams /* dir, orient, spokes, thru_black, pattern, … */, pub duration_ms: u32, pub sound: Option<TransitionSound>, pub advance_on_click: bool, pub advance_after_ms: Option<u32> }
pub struct ShowSettings { pub kind: ShowKind /* Presenter | Window | Kiosk */, pub loop_: bool, pub show_narration: bool, pub show_animation: bool, pub use_timings: bool, pub range: ShowRange /* All | Range(a,b) | Custom(Ulid) */, pub pen_color: Color, pub laser_color: Color, pub gpu_transitions: bool, pub screen_policy: ScreenPolicy }
pub struct Narration { pub audio: MediaRef, pub ink: Vec<TimedStroke>, pub laser: Vec<TimedPoint>, pub clicks: Vec<(u32 /*ms*/, ClickKind)> }

5. Алгоритмы

5.1 Вычисление геометрии prstGeom по формулам направляющих

Источник — presetShapeDefinitions.xml (ECMA-376, часть 1, приложение). При сборке build.rs крейта meridian-scene разбирает его в статические таблицы (PRESETS: [PresetGeom; 187]), поэтому в рантайме XML не читается.

// kernel/crates/meridian-scene/src/preset_geom.rs
pub struct PresetGeom {
    pub name: &'static str,
    pub adj_defaults: &'static [(&'static str, i64)],  // avLst
    pub guides: &'static [Guide],                       // gdLst — уже в порядке вычисления / in evaluation order
    pub adj_handles: &'static [AdjHandle],              // ahLst: XY | Polar, диапазоны min/max
    pub cxn_sites: &'static [CxnSite],                  // cxnLst: угол + точка (ссылки на направляющие)
    pub text_rect: Option<GuideRect>,                   // rect: l, t, r, b
    pub paths: &'static [PresetPath],                   // pathLst
}
pub struct Guide { pub name: &'static str, pub op: Op, pub a: Operand, pub b: Operand, pub c: Operand }
pub enum Op { MulDiv, AddSub, AddDiv, IfElse, Abs, At2, Cat2, Cos, Max, Min, Mod, Pin, Sat2, Sin, Sqrt, Tan, Val }
pub enum Operand { Lit(i64), Ref(u16) /* индекс в таблице значений */ }
pub struct PresetPath { pub w: Option<i64>, pub h: Option<i64>, pub fill: PathFill /* Norm|None|Lighten|LightenLess|Darken|DarkenLess */, pub stroke: bool, pub extrusion_ok: bool, pub cmds: &'static [PathCmd] }
pub enum PathCmd { MoveTo(Operand, Operand), LineTo(Operand, Operand), ArcTo { w_r: Operand, h_r: Operand, st_ang: Operand, sw_ang: Operand }, QuadTo([Operand; 4]), CubicTo([Operand; 6]), Close }

Порядок вычисления значений (все — i64 в EMU; углы — в 1/60000 градуса, cd4 = 5400000):

  1. Встроенные: w, h, l=0, t=0, r=w, b=h, hc=w/2, vc=h/2, ss=min(w,h), ls=max(w,h), доли wd2 … wd32, hd2 … hd32, ssd2 … ssd32, углы cd2=10800000, cd4, cd8, 3cd4, 3cd8, 5cd8, 7cd8.
  2. Регуляторы adj из фигуры, иначе adj_defaults.
  3. Направляющие gdLst последовательно (формулы ссылаются только на ранее определённые — спецификация это гарантирует).
fn eval(op: Op, a: i64, b: i64, c: i64) -> i64 {
    use Op::*;
    match op {
        MulDiv => mul_div(a, b, c),                  // a*b/c с i128 без переполнения / overflow-safe
        AddSub => a + b - c,
        AddDiv => (a + b) / c.max(1),
        IfElse => if a > 0 { b } else { c },
        Abs => a.abs(), Max => a.max(b), Min => a.min(b), Mod => (a*a + b*b + c*c).isqrt(),
        Pin => b.clamp(a, c),
        Sqrt => (a.max(0) as f64).sqrt() as i64,
        Val => a,
        Sin => (a as f64 * deg(b).sin()).round() as i64,   // a·sin(b)
        Cos => (a as f64 * deg(b).cos()).round() as i64,
        Tan => (a as f64 * deg(b).tan()).round() as i64,
        At2 => to_ang((b as f64).atan2(a as f64)),           // atan2(b, a) в 1/60000°
        Cat2 => (a as f64 * (c as f64).atan2(b as f64).cos()).round() as i64,  // a·cos(atan2(c,b))
        Sat2 => (a as f64 * (c as f64).atan2(b as f64).sin()).round() as i64,  // a·sin(atan2(c,b))
    }
}

/// Построение контура в системе координат фигуры (EMU) / Build outline in shape coordinates.
pub fn build_paths(geom: &PresetGeom, w: i64, h: i64, adj: &[(AdjName, i64)]) -> Vec<(kurbo::BezPath, PathStyle)> {
    let vals = eval_guides(geom, w, h, adj);
    geom.paths.iter().map(|p| {
        // Масштаб из пространства пути в размер фигуры / scale path space to shape size
        let sx = p.w.map_or(1.0, |pw| w as f64 / pw as f64);
        let sy = p.h.map_or(1.0, |ph| h as f64 / ph as f64);
        let mut out = kurbo::BezPath::new();
        let mut cur = kurbo::Point::ZERO;
        for cmd in p.cmds {
            match *cmd {
                PathCmd::MoveTo(x, y) => { cur = pt(&vals, x, y, sx, sy); out.move_to(cur); }
                PathCmd::LineTo(x, y) => { cur = pt(&vals, x, y, sx, sy); out.line_to(cur); }
                PathCmd::ArcTo { w_r, h_r, st_ang, sw_ang } => {
                    // Дуга эллипса от текущей точки: центр вычисляется так, чтобы текущая точка лежала на эллипсе
                    // под углом st_ang. Углы DrawingML — геометрические («по транспортиру»), переводим в параметрические:
                    // t = atan2(wR·sin θ, hR·cos θ). / DrawingML angles are geometric, convert to parametric.
                    let (rx, ry) = (vals.get(w_r) as f64 * sx, vals.get(h_r) as f64 * sy);
                    let (st, sw) = (deg(vals.get(st_ang)), deg(vals.get(sw_ang)));
                    let t0 = param_angle(st, rx, ry);
                    let center = kurbo::Point::new(cur.x - rx * t0.cos(), cur.y - ry * t0.sin());
                    let t1 = param_angle(st + sw, rx, ry) + if sw < 0.0 && param_angle(st+sw,rx,ry) > t0 { -std::f64::consts::TAU } else { 0.0 };
                    let arc = kurbo::Arc { center, radii: kurbo::Vec2::new(rx, ry), start_angle: t0, sweep_angle: t1 - t0, x_rotation: 0.0 };
                    arc.append_iter(0.1).for_each(|el| out.push(el));   // кубики Безье по четвертям / cubic segments
                    cur = arc.end();   // конечная точка дуги / arc end point
                }
                PathCmd::QuadTo([x1,y1,x,y]) => { let p1 = pt(&vals,x1,y1,sx,sy); cur = pt(&vals,x,y,sx,sy); out.quad_to(p1, cur); }
                PathCmd::CubicTo([x1,y1,x2,y2,x,y]) => { let p1 = pt(&vals,x1,y1,sx,sy); let p2 = pt(&vals,x2,y2,sx,sy); cur = pt(&vals,x,y,sx,sy); out.curve_to(p1,p2,cur); }
                PathCmd::Close => out.close_path(),
            }
        }
        (out, PathStyle { fill: p.fill, stroke: p.stroke })
    }).collect()
}

Регуляторы (ahLst) дают маркеры на холсте: позиция маркера вычисляется по направляющим, перетаскивание решает обратную задачу (линейная для XY, через atan2/расстояние для Polar) с ограничением min/max. Точки соединения cxnLst используются коннекторами (Draw/Slides) — тот же код. Текстовый прямоугольник rect ограничивает раскладку текста. Результат build_paths кэшируется по ключу (preset, w, h, adj) (LRU 4 096 записей на документ). Проверка: снимочные тесты всех 187 фигур при трёх размерах против эталонов PowerPoint (SSIM ≥ 0,99).

5.2 Автоподбор текста (shrink-on-overflow)

Режимы bodyPr/autofit: none, spAutoFit (фигура растёт/сжимается по тексту — высота = высота раскладки + вставки), normAutofit { font_scale: %, ln_spc_reduction: % }. Для normAutofit масштаб ищется по «лестнице» PowerPoint, чтобы значения совпадали с теми, что пишет PowerPoint (иначе при round-trip текст «прыгает»):

const LADDER: &[(u16 /*fontScale %*/, u16 /*lnSpcReduction %*/)] = &[
    (100,0), (100,10), (100,20), (92,20), (85,20), (77,20), (70,20), (62,20), (55,20), (47,20), (40,20), (32,20), (25,20),
];
/// Подбор масштаба: первый шаг лестницы, при котором текст помещается / first ladder step that fits.
pub fn autofit(body: &TextBody, rect: Rect, ctx: &LayoutCtx) -> (u16, u16) {
    for &(fs, lr) in LADDER {
        let layout = ctx.layout(body, rect.width(), FontScale(fs), LineSpacingReduction(lr));
        if layout.height() <= rect.height() { return (fs, lr); }
    }
    *LADDER.last().unwrap()   // не помещается даже при 25 % — остаётся переполнение / overflow remains
}

Оптимизация: раскладка с масштабом 100 % — обычная; затем бинарный поиск по индексу лестницы (монотонность высоты по масштабу выполняется), т.е. ≤ 4 раскладки вместо 13. Пересчёт — при изменении текста/размера/шрифта, с задержкой 50 мс при наборе. spAutoFit при вертикальном тексте меняет ширину. Деформации (prstTxWarp) P1: текст раскладывается в прямоугольник, затем глифы отображаются через огибающую (верхняя/нижняя кривые Безье из пресета) — та же техника, что у WordArt в Write.

5.3 Умные направляющие, привязки, равномерное распределение

Кандидаты привязки собираются при начале перетаскивания (и кэшируются до его конца):

pub struct SnapIndex { xs: Vec<(f64 /*x слайда*/, SnapSrc)>, ys: Vec<(f64, SnapSrc)>, gaps_x: Vec<Gap>, gaps_y: Vec<Gap> }
// xs/ys отсортированы; SnapSrc = Edge(ShapeId, Left|CenterX|Right) | SlideEdge | SlideCenter | Guide(id) | Grid
// Gap — расстояние между соседними (по проекции) фигурами: (a, b, size) для «равных интервалов»

При движении: для перетаскиваемого прямоугольника берём 3 вертикальные линии (левая/центр/правая) и 3 горизонтальные; для каждой — бинарный поиск ближайшего кандидата; выбираем минимальную дельту |Δ| ≤ tol, где tol = 6 px / zoom; применяем смещение, рисуем направляющую через обе фигуры (цвет --m-sun, 1 px, с размерными засечками). Равные интервалы: для пары соседей A, B на той же оси проверяем, образует ли перетаскиваемая фигура интервал, равный gap(A,B) слева или справа — при совпадении рисуем две скобки с подписью. Приоритет: центр слайда > край слайда > направляющие > фигуры > равные интервалы > сетка. При зажатом Alt привязка отключается. При изменении размера — те же кандидаты для перемещаемого края. Поворот привязывается к 0/15/…° при Shift. Распределение (команда «Распределить по горизонтали»): сортировка по x, gap = (span − Σw) / (n − 1), при n = 2 — относительно слайда. Выравнивание относительно слайда или выделения — по bounding box с учётом поворота (ось-ориентированный прямоугольник повёрнутой фигуры).

5.4 Планировщик анимаций (60 кадров/с)

Дерево AnimTimeline при входе на слайд компилируется в план: список треков с абсолютным временем относительно «шага» (щелчка).

pub struct Track { pub target: Target, pub attr: AnimAttr, pub start_ms: f64, pub dur_ms: f64, pub repeat: Repeat, pub autoreverse: bool,
                   pub fill: FillMode, pub ease: Ease /* accel/decel → кусочно-квадратичная */, pub keys: Vec<KeyFrame>, pub calc: CalcMode }
pub struct Step { pub index: u32, pub tracks: Vec<Track>, pub total_ms: f64, pub media_cmds: Vec<(f64, MediaCmd)>, pub interactive: Option<ShapeId> }
pub struct Plan { pub steps: Vec<Step>, pub initial_state: SceneState /* фигуры с эффектом входа скрыты */ }

/// Компиляция: обход дерева, накопление задержек / compile tree into steps with absolute times.
fn compile(node: &TimeNode, t0: f64, step: &mut Step, plan: &mut Plan) {
    let start = t0 + node.start.iter().filter_map(Condition::delay_ms).sum::<f64>();
    match &node.kind {
        NodeKind::Par => { for c in &node.children { compile(c, start, step, plan); } }
        NodeKind::Seq { .. } => {
            let mut t = start;
            for c in &node.children {
                if c.node_type == NodeType::ClickPar || c.start.iter().any(Condition::is_indefinite) {
                    plan.push_step(std::mem::take(step));           // новый щелчок / new click step
                    t = 0.0;
                }
                compile(c, t, step, plan);
                t += c.total_duration();                            // «после предыдущего» / "after previous"
            }
        }
        NodeKind::Behavior(b) => step.tracks.push(Track::from_behavior(node, b, start)),
    }
    if let Some(sh) = node.interactive_trigger() { step.interactive = Some(sh); }
}

Воспроизведение: ShowClock — монотонное время с момента начала шага; кадр по vsync QQuickWindow::beforeRendering:

pub fn sample(plan: &Plan, step: usize, t_ms: f64, base: &SceneState) -> SceneState {
    let mut st = base.clone_shallow();                       // COW: меняем только анимируемые атрибуты
    for tr in &plan.steps[step].tracks {
        let Some(local) = tr.local_time(t_ms) else { continue };   // учитывает repeat/autoreverse/fill
        let u = tr.ease.apply(local / tr.dur_ms);                  // 0..1 с accel/decel
        let v = match tr.calc { CalcMode::Discrete => tr.keys.step(u), CalcMode::Lin => tr.keys.lerp(u), CalcMode::Fmla => tr.keys.eval_formula(u, &st) };
        st.apply(tr.target, tr.attr, v);                           // ppt_x/ppt_y — доли ширины/высоты слайда
    }
    st
}

Ease: accel/decel в долях длительности — кусочная функция (квадратичный разгон, линейная середина, квадратичное торможение, площадь нормирована на 1); для «отскока» и пружины — пресеты Bounce, Elastic, для плавных путей — EaseInOutCubic. Пропуск кадров: состояние — функция времени, поэтому задержки не накапливаются. Завершение шага — когда t ≥ total_ms и нет бесконечных повторов; «после предыдущего» между щелчками реализовано компиляцией. Тексты «по абзацам/словам/буквам» разворачиваются при компиляции в N треков с задержкой (bldP/@advAuto или % от длительности). Пути движения: MotionPath → kurbo::BezPath в долях слайда, точка по t — через параметризацию по длине дуги (ParamCurveArclen), rotate_along — касательная. Предпросмотр в редакторе — тот же планировщик с виртуальными часами.

5.5 Переходы на GPU (Skia)

Каждый переход — Transition трейт: prepare(from: &SkImage, to: &SkImage, params) -> Box<dyn TransitionFrame>, draw(canvas, progress 0..1). Три семейства реализации:

  1. Шейдерные (p:fade, wipe, push, split, blinds, checker, wheel, dissolve, randomBar, фигуры, glitter, ripple, warp, reveal, flash) — SkRuntimeEffect на SkSL с униформами progress, size, dir, двумя дочерними шейдерами from/to (текстуры слайдов):
// meridian-transitions/shaders/wipe.sksl — появление / wipe
uniform shader from; uniform shader to; uniform float progress; uniform float2 size; uniform int dir; // 0 l,1 r,2 u,3 d
half4 main(float2 p) {
    float u = dir == 0 ? p.x / size.x : dir == 1 ? 1.0 - p.x / size.x : dir == 2 ? p.y / size.y : 1.0 - p.y / size.y;
    float edge = smoothstep(progress - 0.01, progress + 0.01, u);   // мягкая кромка 1 % / 1 % soft edge
    return mix(to.eval(p), from.eval(p), edge);
}

Растворение: hash(floor(p / cell)) сравнивается с progress; шашки/жалюзи — по fract координат ячеек с чередованием; часы — по углу atan2; фигуры — знаковые функции расстояния (круг, ромб, плюс). 2. 3D (cube/prism, flip, doors, switch, gallery, ferris, conveyor, window, fallOver, airplane, origami, flythrough, prestige) — две (или больше) плоскости с текстурами, рисуются через canvas.concat(SkM44::perspective(...) * rotate * translate); Skia поддерживает перспективные матрицы для drawImageRect; порядок отрисовки — по глубине центра плоскости (painter's algorithm, достаточно для 2–6 плоскостей); освещение — множитель яркости по косинусу угла. 3. Сетки вершин (drape, curtains, crush, peelOff, pageCurl*) — canvas.draw_vertices с сеткой 64×36, UV в текстуру слайда, вершины смещаются аналитически (скручивание — цилиндр радиуса r(t), занавес — синусоида с затуханием). fracture/shred/vortex/honeycomb — предрассчитанные тайлы/осколки (Вороной из 60–120 точек), каждый рисуется с собственной трансформацией.

Производительность: текстуры from/to рендерятся заранее (при входе в слайд — следующий слайд уже отрисован), переход занимает ≤ 2 draw-вызовов на кадр для шейдеров и ≤ 150 для тайлов; целевое 60 к/с при 4K на интегрированной графике (Iris Xe/Apple M1). Без GPU (Skia CPU): шейдерные переходы работают (медленнее, при 1080p ~ 25–40 к/с), 3D и сетки заменяются на fade. Политика выбора: ShowSettings.gpu_transitions && backend.is_gpu().

5.6 Раскладка диаграмм-схем

Модель: Diagram { kind: DiagramKind, root: DNode, style: DiagramStyle, dir: Ltr|Rtl, font_scale: u16 }, DNode { id, text: TextBody, children: Vec<DNode>, role: Normal|Assistant, image: Option<MediaRef> }. Раскладчик — функция layout(kind, &root, bounds) -> Vec<DShape> (фигуры + коннекторы + текстовые прямоугольники):

fn layout_process(nodes: &[DNode], b: Rect, o: &ProcessOpts) -> Vec<DShape> {
    // Горизонтальный процесс: n блоков + (n−1) стрелок; ширина блока : стрелка = 1 : 0.35
    let n = nodes.len() as f64; let gap = 0.35;
    let unit = b.width() / (n + (n - 1.0) * gap);
    let h = (b.height() * 0.6).min(unit * 0.8);
    let y = b.center().y - h / 2.0;
    let mut out = vec![];
    for (i, node) in nodes.iter().enumerate() {
        let x = b.x0 + i as f64 * unit * (1.0 + gap);
        out.push(DShape::block(node.id, Rect::new(x, y, x + unit, y + h), PresetShape::RoundRect, &node.text));
        if i + 1 < nodes.len() { out.push(DShape::arrow(Rect::new(x + unit, y + h*0.3, x + unit*(1.0+gap), y + h*0.7), PresetShape::RightArrow)); }
    }
    out
}

fn layout_hierarchy(root: &DNode, b: Rect) -> Vec<DShape> {
    // Reingold–Tilford / Walker: ширины поддеревьев, затем центрирование родителя над детьми; помощники — в отдельной колонке
    let mut widths = HashMap::new();
    fn measure(n: &DNode, w: &mut HashMap<NodeId, f64>) -> f64 {
        let kids: f64 = n.children.iter().filter(|c| c.role != Role::Assistant).map(|c| measure(c, w)).sum::<f64>();
        let me = kids.max(1.0) + n.children.iter().filter(|c| c.role != Role::Assistant).count().saturating_sub(1) as f64 * 0.25;
        w.insert(n.id, me); me
    }
    let total = measure(root, &mut widths);
    let depth = root.depth();
    let cell_w = b.width() / total; let cell_h = b.height() / (depth as f64 * 1.6 - 0.6);
    let mut out = vec![];
    fn place(n: &DNode, x0: f64, level: usize, w: &HashMap<NodeId, f64>, cw: f64, ch: f64, b: Rect, out: &mut Vec<DShape>) {
        let cx = x0 + w[&n.id] * cw / 2.0;
        let r = Rect::from_center_size((cx, b.y0 + level as f64 * ch * 1.6 + ch / 2.0), (cw.min(2.5*ch) * 0.9, ch));
        out.push(DShape::block(n.id, r, PresetShape::Rect, &n.text));
        let mut x = x0;
        for c in n.children.iter().filter(|c| c.role != Role::Assistant) {
            place(c, x, level + 1, w, cw, ch, b, out);
            out.push(DShape::elbow_connector(n.id, c.id));             // ортогональный коннектор «локтем»
            x += (w[&c.id] + 0.25) * cw;
        }
    }
    place(root, b.x0, 0, &widths, cell_w, cell_h, b, &mut out);
    out
}

Цикл: n узлов по окружности радиуса min(w,h)/2 − r_node, угол 2π/n, стрелки — дуги между соседями (blockArc с adj углов). Пирамида: n трапеций равной высоты, ширина линейно от 100 % к 30 %. Венн: окружности с перекрытием 40 % радиуса, прозрачность заливки 50 %. Матрица: 2×2 с общим центром. Воронка: сегменты с уменьшением ширины по кубической кривой. Общий масштаб шрифта: для каждого узла — максимальный fontScale из лестницы §5.2, по диаграмме — минимум из них (как dgm:… autofit), чтобы все узлы имели один размер. Направление RTL — зеркалирование x. Результат — обычные фигуры слайда в группе с меткой diagram (редактирование фигур вручную помечает диаграмму «ручная», автораскладка выключается до «Восстановить»).

5.7 Генерация миниатюр

ThumbnailService (поток пула rayon, приоритетная очередь): задание (slide_id, revision, width_px); рендер слайда в offscreen SkSurface (GPU, если доступен, иначе CPU) в масштабе width_px / slide_w, финальное состояние анимаций (все объекты видимы), без переходов; результат — SkImage в LRU-кэше (лимит 256 МБ), ключ (slide_id, revision, width). Приоритет: видимые миниатюры > соседние (±5) > остальные; при прокрутке — перезапрос с отменой устаревших. Инвалидация — по Slide.revision (инкремент при любой операции undo-журнала, затрагивающей слайд, макет, образец или тему — изменение образца инвалидирует все слайды его макетов). Размеры: 96, 160, 240, 320 px для панели, 15–100 % для сортировщика (рендер по требованию с кэшем уровня). thumbnail.png пакета — первый слайд 256×144 при сохранении. Диаграммы, таблицы и видео (постер) рисуются тем же списком отображения, что и холст.

5.8 Экспорт видео

Конвейер meridian-video:

ShowSession (виртуальные часы, детерминированные шаги) → ShowRenderer (offscreen Skia GPU, N×M) → кадр (SkImage, BGRA/NV12)
    → VideoEncoder (платформенный) ─┐
Аудиомикшер (закадровый голос + медиа слайдов + звуки переходов, 48 кГц стерео) → AudioEncoder ─┤→ Muxer (mp4 / webm) → файл
pub trait VideoEncoder: Send { fn new(cfg: &VideoCfg) -> Result<Self> where Self: Sized; fn encode(&mut self, frame: &Frame, pts_ns: i64) -> Result<Vec<Packet>>; fn finish(&mut self) -> Result<Vec<Packet>>; }
pub trait AudioEncoder: Send { fn encode(&mut self, pcm: &[f32], pts_ns: i64) -> Result<Vec<Packet>>; fn finish(&mut self) -> Result<Vec<Packet>>; }
pub trait Muxer { fn add_video(&mut self, codec: CodecParams) -> TrackId; fn add_audio(&mut self, codec: CodecParams) -> TrackId; fn write(&mut self, track: TrackId, pkt: Packet) -> Result<()>; fn finish(self) -> Result<()>; }
Платформа H.264 / AAC (mp4) VP9 / Opus (webm)
Windows Media Foundation (IMFSinkWriter/IMFTransform, аппаратные NVENC/QSV/AMF автоматически) libvpx + libopus (статически, BSD)
macOS VideoToolbox + AudioToolbox (VTCompressionSession, AAC через AudioConverter) libvpx + libopus
Linux VA-API через libva при наличии; иначе OpenH264 (BSD; бинарник Cisco с патентным покрытием загружается по согласию пользователя). Свободного кодера AAC с подходящей лицензией нет, поэтому аудио в MP4 — Opus (поддерживается современными плеерами) с предупреждением и рекомендацией WebM libvpx + libopus — всегда доступно, формат по умолчанию на Linux

Мультиплексоры — собственные писатели в Rust: MP4 (ISO BMFF: ftyp/moov/mdat, avc1+avcC, mp4a/Opus, таблицы stts/stsc/stsz/stco, moov в конце с последующим «faststart»-переносом) и WebM (EBML/Matroska: Segment/Info/Tracks/Cluster/SimpleBlock, Cues). Кадры: время кадра t = i / fps, ShowSession.seek_virtual(t) выбирает слайд/шаг/переход по хронометражу; рендер — те же sample() и Transition::draw, что при показе, поэтому видео совпадает с показом по кадрам. Чтение кадра с GPU — SkSurface::readPixels в NV12 (конверсия на GPU шейдером) либо нулевая копия (D3D11-текстура → MF, CVPixelBuffer → VideoToolbox) — P1. Медиа слайдов декодируются платформенным декодером в тот же виртуальный таймлайн (видео — кадр по t − t_start, аудио — в микшер). Производительность: 1080p30 быстрее реального времени ≥ 2× на ноутбуке 2020 года. Прогресс по кадрам, отмена — мгновенная (частичный файл удаляется).

5.9 Режим докладчика: два окна и синхронизация

┌──────────────┐   команды (Next/Prev/GoTo/Pen/Laser/Black/…)   ┌──────────────────────┐
│ ShowWindow   │ ───────────────────────────────────────────────▶│ ShowSession (Rust)   │
│ (экран 2)    │◀──── watch::Receiver<ShowState> (снимок) ────── │  state: ShowState    │
└──────────────┘                                                  │  plan: Plan          │
┌──────────────┐ ───────────────────────────────────────────────▶│  clock: ShowClock    │
│ Presenter    │◀──── watch::Receiver<ShowState> ─────────────── │  ink/laser буферы    │
│ Window (1)   │                                                  └──────────────────────┘
└──────────────┘

5.10 Морфинг (P1)

Сопоставление фигур между слайдами A и B: явное по имени !!ключ, затем по ShapeId (дубликат слайда сохраняет id), затем эвристика (одинаковый тип + близкие размеры/текст). Для пар: интерполяция xfrm (положение, размер, поворот по кратчайшей дуге), цветов (в OKLab), прозрачности; геометрии — если обе Preset одного типа → интерполяция adj, иначе — контуры приводятся к одинаковому числу сегментов (ресэмплинг по длине дуги) и интерполируются поточечно; текст — по словам/символам (позиции глифов из раскладки). Непарные фигуры — выцветание. Ease — EaseInOutCubic, длительность по умолчанию 2 с.

5.11 Текст по абзацам при импорте и «уровни» pptx

Для bldP build="p" каждый абзац получает собственный поднабор треков с grpId; при advAuto задержка между абзацами берётся из атрибута, иначе — из структуры дерева (отдельные par на абзац с p:txEl/p:pRg). Экспорт — обратное преобразование.


6. MeridianScript API для Slides

Пространство имён meridian.slides (TypeScript-типы поставляются с редактором скриптов; выполнение — QuickJS-ng в песочнице). Все изменения через API идут через undo-журнал (одна скриптовая транзакция = один шаг отмены).

Объект Основные члены
slides.activePresentation: Presentation slides: SlideCollection, masters, layouts, sections, customShows, theme, slideSize, notesMaster, properties, save(), saveAs(path, format?), exportPdf(opts), exportVideo(opts) [Pro], exportImages(opts), print(opts), comments, media
SlideCollection count, item(i), byId(id), add(layout, index?), insertFromFile(path, indices?), move(from, to), forEach, [Symbol.iterator]
Slide index, id, name, layout, shapes: ShapeCollection, background, transition: Transition, timeline: Timeline, notes: TextFrame, hidden, section, comments, duplicate(), delete(), moveTo(i), reset(), thumbnail(width): ImageData, select()
ShapeCollection count, item(i), byName(n), addShape(preset, rect), addTextBox(rect, text), addPicture(src, rect), addTable(rows, cols, rect), addChart(type, data, rect), addDiagram(kind, nodes, rect), addVideo(src, rect), addAudio(src), addConnector(kind, from, to), group(ids), placeholders
Shape id, name, type, left/top/width/height, rotation, flipH/flipV, zOrder, fill: Fill, line: Line, effects, textFrame: TextFrame, placeholder?, altText, hyperlink, action, locked, visible, animations: Animation[], addAnimation(effect, opts), bringToFront(), sendToBack(), delete(), duplicate(), toImage(opts), table?, chart?, diagram?, media?
TextFrame text, paragraphs: Paragraph[], autofit, anchor, margins, wrap, columns, font: Font (на всё), replace(find, repl, opts), insert(text, at?)
Transition kind, params, duration, sound, advanceOnClick, advanceAfter, applyToAll()
Timeline effects: Animation[], add(shape, preset, { start, delay, duration, direction }), remove(a), move(a, index), play(), clear()
Animation shape, kind (entrance | emphasis | exit | path), preset, start (click | with | after), delay, duration, repeat, trigger, params, textBuild
slides.show: SlideShow start(opts), startPresenter(), end(), next(), previous(), goTo(i), current, isRunning, black(), white(), pointer, on('slideChange' | 'click' | 'start' | 'end', cb)
slides.events on('open' | 'beforeSave' | 'slideAdded' | 'selectionChanged' | 'showStart' | 'showEnd' | 'slideShown', cb)
slides.ui selection: Shape[] | Slide[], currentSlide, view (normal | sorter | outline | notes | master), showPanel(id), dialog(...), toast(msg)

Примеры:

// Слайды из таблицы Sheets: по строке на слайд / One slide per row of a Sheets range
import { sheets, slides } from "meridian";
const wb = await sheets.open("Проекты.msx");
const rows = wb.sheet("Проекты").range("A2:C20").values as [string, string, number][];
const pres = slides.activePresentation;
const layout = pres.layouts.byName("Заголовок и объект");
for (const [name, owner, budget] of rows) {
  const s = pres.slides.add(layout);
  s.shapes.placeholders.title.textFrame.text = name;
  s.shapes.placeholders.body.textFrame.text = `Ответственный: ${owner}\nБюджет: ${budget.toLocaleString("ru-RU")} ₽`;
  s.transition.kind = "push"; s.transition.params = { dir: "left" }; s.transition.duration = 0.5;
}
// Единые переходы и анимация заголовков во всей презентации / Uniform transitions and title animation
const pres = slides.activePresentation;
for (const s of pres.slides) {
  s.transition.kind = "fade"; s.transition.duration = 0.7;
  const title = s.shapes.placeholders.title;
  if (title) s.timeline.add(title, "entrance.fade", { start: "with", duration: 0.5 });
}
// Замена текста везде, включая заметки, с отчётом / Replace text everywhere incl. notes
let n = 0;
for (const s of slides.activePresentation.slides) {
  for (const sh of s.shapes) if (sh.textFrame) n += sh.textFrame.replace("ООО «Старое»", "ООО «Новое»", { wholeWord: true });
  n += s.notes.replace("ООО «Старое»", "ООО «Новое»");
}
slides.ui.toast(`Заменено: ${n}`);
// Таймер показа и событие смены слайда: пишем в лог продолжительность каждого слайда / Log time per slide during show
const t: Record<number, number> = {}; let last = Date.now(), cur = 0;
slides.show.on("slideChange", (e) => { t[cur] = (t[cur] ?? 0) + (Date.now() - last); last = Date.now(); cur = e.index; });
slides.show.on("end", () => console.table(t));
// Экспорт: PDF с заметками и видео 1080p / Export PDF with notes and 1080p video
await slides.activePresentation.exportPdf({ path: "отчёт.pdf", notes: true, bookmarks: "sections" });
await slides.activePresentation.exportVideo({ path: "отчёт.mp4", format: "mp4", height: 1080, fps: 30, useTimings: true });

7. Форматы

7.1 Сводка

Формат Чтение Запись Приоритет Кодек
.mpx / .mpt / .mpxf полное полное P0 meridian-slides
.pptx / .pptm / .potx / .ppsx полное (см. потери) полное для всего, что умеет Slides; неизвестные части — round-trip P0 meridian-codecs-pptx
.ppt / .pps / .pot (97–2003) текст, фигуры, рисунки, образцы, переходы, базовые анимации, заметки упрощённая: без анимаций PowerPoint 2002+ (только базовые эффекты), без SmartArt P0 чтение / P1 запись meridian-codecs-ppt
.odp / .otp полное полное P0 meridian-codecs-odf
.key (Keynote '13+ IWA, Keynote '09 XML) слайды, мастера, текст, фигуры, рисунки, таблицы, диаграммы (частично), переходы/анимации по таблице соответствий — (Keynote сам открывает pptx) P1 meridian-codecs-iwork
.sxi через ODF-кодек с таблицей замены пространств имён — P2 meridian-codecs-odf
.pdf — (импорт PDF как слайдов-изображений — P2 через Meridian PDF) слайды/заметки/выдачи, PDF/A, PDF/UA P0 Meridian Print
.mp4 / .webm — видео показа [Pro] P0 meridian-video
.png / .jpg / .svg / .webp — слайды P0 Meridian Render
.html — статичные страницы P2 —

7.2 PPTX — особенности

Структура: ppt/presentation.xml (sldMasterIdLst, sldIdLst, sldSz, notesSz, defaultTextStyle, custShowLst, extLst/p14:sectionLst), ppt/slides/slideN.xml (+ _rels: макет, медиа, диаграммы, схемы, заметки, комментарии), ppt/slideLayouts/, ppt/slideMasters/, ppt/theme/, ppt/notesSlides/, ppt/notesMasters/, ppt/handoutMasters/, ppt/comments/ (+ modernComment_*.xml, authors.xml), ppt/presProps.xml (showPr), ppt/viewProps.xml, ppt/tableStyles.xml, ppt/media/, ppt/embeddings/, ppt/charts/, ppt/diagrams/, ppt/fonts/, ppt/vbaProject.bin.

Область Чтение Запись Примечание
Образцы/макеты/темы, карта цветов, варианты полное полное несколько образцов, preserve
Текст: bodyPr, lstStyle, уровни, поля, автонумерация, prstTxWarp полное (деформации — P1 отображение) полное единицы без округления
Фигуры prstGeom/custGeom, стили, заливки, линии, эффекты полное полное scene3d/sp3d — хранится и возвращается, отображение приближённое (P2 полное)
Рисунки: blip, srcRect, duotone, lum, alphaModFix, clrChange, SVG asvg:svgBlip полное полное художественные эффекты a14:imgProps — round-trip без отображения
Таблицы a:tbl, стили tableStyleId полное полное —
Диаграммы c:chart, cx:chart, встроенная книга через Meridian Chart полное см. docs/algorithms/chart-engine.md
Диаграммы-схемы dgm:* известные макеты → редактируемые; иначе кэш drawingN.xml модель + кэш drawing + data/layout/colors/quickStyle для известных макетов; для «ручных» — группа фигур —
Медиа p14:media, trim, fade, bmkLst, постеры, videoFile/audioFile, онлайн-видео полное полное кодеки — платформенные
Переходы p:transition + p14: + p15:prstTrans + p159:morph все 51 все неизвестные — round-trip в mc:AlternateContent
Анимации p:timing, p:bldLst, триггеры, интерактивные последовательности, p:cmd, p:audio/video изоморфно изоморфно неизвестные presetID воспроизводятся по дереву поведений (не по пресету)
Комментарии старые и современные (p188), ответы, статус полное современные + старые для совместимости —
Разделы, произвольные показы, showPr, хронометраж, закадровый текст (p:cmd playFrom + аудио) полное полное —
Защита: agile encryption (AES-256/SHA-512), modifyVerifier, «окончательный» полное полное [Pro: DocEncrypt] на запись Free — чтение и снятие
VBA (.pptm) хранится как есть, не выполняется; транслятор простых макросов [Pro] возвращается без изменений —
ActiveX, OLE-объекты кэш-изображение + round-trip как есть —
Ink p14:ink/inkml отображение P1 запись P1 —
3D-модели am3d, Zoom (p:…zoom), cameo постер/изображение + round-trip как есть P2
Встроенные шрифты .fntdata (обфусцированные) P1 чтение P1 запись только fsType ∈ {installable, editable}
Расширения extLst, неизвестные части round-trip round-trip политика библии §3.1

Известные трудности: авто-вычисление геометрии групп (chOff/chExt масштабирование детей), p:ph без idx, пустые spPr, порядок rels, кодировка идентификаторов комментариев, mc:AlternateContent с несколькими вариантами (берём Requires из известных нам пространств имён, иначе Fallback).

7.3 PPT (бинарный)

OLE2-контейнер: потоки PowerPoint Document, Pictures, Current User, Summary Information, VBA. Записи (RecordHeader: recVer/recInstance/recType/recLen) → контейнеры DocumentContainer, MainMasterContainer, SlideContainer, NotesContainer; графика — OfficeArt (Escher): OfficeArtDgContainer → OfficeArtSpContainer → OfficeArtFSP (тип msospt* → таблица соответствия 202 типов с prstGeom) + OfficeArtFOPT (свойства: геометрия pVertices/pSegmentInfo для произвольных форм, заливки, линии, текст). Текст: TextHeaderAtom, TextCharsAtom (UTF-16) / TextBytesAtom (ANSI, кодовая страница по языку — для русских файлов cp1251), StyleTextPropAtom, TextRulerAtom; «внешние» вставки TextSpecialInfoAtom. Анимации 2002+: PP10SlideBinaryTagExtension с TimeNodeContainer — отображаются в наше дерево; старые AnimationInfoAtom — простые эффекты. Переходы — SlideShowSlideInfoAtom. Шифрование RC4 CryptoAPI — чтение P1. Запись P1: текст, фигуры, рисунки, образцы, переходы, заметки; анимации — только появление/выцветание/вылет; остальное — предупреждение «не сохраняется в этом формате».

7.4 ODP

ODF 1.3: office:presentation → draw:page (presentation:class у рамок: title, outline, subtitle, notes, graphic, object, chart, table, page-number, date-time, footer, header), draw:custom-shape + draw:enhanced-geometry (draw:type="ooxml-…", формулы draw:formula эквивалентны направляющим — один вычислитель с таблицей функций), style:master-page + presentation:page-layout + draw:layer-set, presentation:settings, presentation:show, presentation:header-decl/footer-decl/date-time-decl. Анимации — SMIL (anim:par/seq/iterate/animate/ set/animateMotion/animateColor/animateTransform/transitionFilter/audio/command) с presentation:node-type и presentation:preset-class/preset-id/preset-sub-type — те же пресеты, что в PowerPoint, поэтому дерево переносится почти без потерь. Переходы — smil:type/subtype в style:drawing-page-properties (barWipe, fade, pushWipe, …) + presentation:transition-speed, presentation:duration.

Потери при записи в ODP: темы (ODF без тем — LibreOffice 7.6+ понимает loext:theme, пишем её и явные стили), стили таблиц (пишем явные стили ячеек), эффекты свечения/отражения (loext:glow, loext:softedge для LibreOffice, иначе отбрасываются), современные переходы без SMIL-аналога (fracture, morph → fade), триггеры по закладкам медиа, комментарии с ответами (officeooo:annotation — плоские), встроенные шрифты (P2), диаграммы-схемы — группа фигур (так же делает LibreOffice).

7.5 Keynote

.key — пакет (zip или папка): Index/*.iwa (snappy-сжатые блоки Protobuf, типы сообщений TSP/TSK/TSWP/TSD/TST/TSCH/KN — схема восстановлена сообществом; свои .proto поддерживаем в meridian-codecs-iwork), Data/ (медиа), Metadata/, preview.jpg. Читаем: слайды, мастера, фон, текст со стилями, фигуры (пути Безье → custGeom; стандартные Keynote-формы → prstGeom), рисунки с масками, таблицы (TST), диаграммы (TSCH, основные типы), переходы и построения (таблица соответствий: Magic Move → морфинг P1, Dissolve → fade, Push/Wipe/Cube/Flip/Doorway → наши, прочие (Anvil, Sparkle…) → ближайший + предупреждение), заметки докладчика. Шрифты Apple заменяются метрически близкими. Keynote '09 (index.apxl XML) — отдельный разбор, тот же результат. Запись .key не планируется.


8. Горячие клавиши

Схема по умолчанию — Microsoft Office (Windows/Linux: Ctrl, macOS: ⌘). Схема LibreOffice и своя — в настройках.

8.1 Редактор

Действие Клавиши
Новый слайд / дублировать слайд Ctrl+M / Ctrl+Shift+D
Дублировать фигуру Ctrl+D
Показ с начала / с текущего / режим докладчика F5 / Shift+F5 / Alt+F5
Командная палитра Ctrl+K (см. §11)
Гиперссылка Ctrl+Shift+K (см. §11)
Найти / заменить Ctrl+F / Ctrl+H
Отменить / повторить Ctrl+Z / Ctrl+Y
Полужирный / курсив / подчёркнутый Ctrl+B / Ctrl+I / Ctrl+U
Увеличить / уменьшить шрифт Ctrl+Shift+> / Ctrl+Shift+< (также Ctrl+] / Ctrl+[)
Выравнивание влево / центр / вправо / по ширине Ctrl+L / Ctrl+E / Ctrl+R / Ctrl+J
Повысить / понизить уровень абзаца Alt+Shift+← / Alt+Shift+→ (также Shift+Tab / Tab в начале абзаца)
Переместить абзац вверх / вниз Alt+Shift+↑ / Alt+Shift+↓
Верхний / нижний индекс Ctrl+Shift++ / Ctrl+=
Сбросить форматирование символов Ctrl+Space
Диалог шрифта Ctrl+Shift+F
Копировать / вставить формат Ctrl+Shift+C / Ctrl+Shift+V
Группировать / разгруппировать Ctrl+G / Ctrl+Shift+G
На передний / на задний план Ctrl+Shift+] / Ctrl+Shift+[
Переместить вперёд / назад на один уровень Ctrl+Alt+] / Ctrl+Alt+[
Сдвиг фигуры на 1 px / на шаг сетки ←↑→↓ / Ctrl+←↑→↓
Изменить размер на 1 px Shift+←↑→↓
Повернуть на 15° Alt+← / Alt+→
Следующая / предыдущая фигура Tab / Shift+Tab
Редактировать текст выделенной фигуры / выйти F2 или Enter / Esc
Переход к следующему заполнителю, после последнего — новый слайд Ctrl+Enter
Панель выделения Alt+F10
Сетка / направляющие Shift+F9 / Alt+F9
Временно отключить привязку удерживать Alt при перетаскивании
Орфография / тезаурус F7 / Shift+F7
Сохранить / сохранить как / открыть / печать Ctrl+S / F12 / Ctrl+O / Ctrl+P
Обычный вид / сортировщик / структура / страницы заметок Alt+V, N / Alt+V, D / Alt+V, O / Alt+V, P (клавиатурные подсказки ленты); Shift+щелчок по кнопке вида — образец
Масштаб: вписать / 100 % / увеличить / уменьшить Ctrl+0 / Ctrl+1 / Ctrl++ / Ctrl+−; Ctrl+колесо
Следующий / предыдущий слайд (в миниатюрах/холсте) Page Down / Page Up; первый/последний — Ctrl+Home / Ctrl+End
Скрыть слайд Ctrl+Shift+H
Добавить раздел Ctrl+,
Заметки: фокус в панель Alt+Shift+N
Анимация: панель Alt+Shift+A
Контекстное меню Shift+F10 или Menu
Клавиатурные подсказки ленты Alt (как в Office: Alt+H Главная, Alt+N Вставка, Alt+G Дизайн, Alt+K Переходы, Alt+A Анимации, Alt+S Показ, Alt+R Рецензирование, Alt+W Вид)
Полноэкранный «Фокус» F11

8.2 Показ слайдов

Действие Клавиши
Следующий слайд/шаг N, Enter, Space, →, ↓, Page Down, щелчок
Предыдущий P, Backspace, ←, ↑, Page Up
Перейти к слайду N N + Enter (ввод числа)
Первый / последний Home / End
Сетка всех слайдов / выход из неё G (также −), Esc
Чёрный / белый экран B или . / W или ,
Пауза / продолжить автоматический показ S или +
Показать скрытый слайд H
Лазерная указка Ctrl+L (переключатель) или Ctrl+ЛКМ
Перо / маркер / ластик / стрелка Ctrl+P / Ctrl+I / Ctrl+E / Ctrl+A
Очистить рукописный ввод E
Скрыть / показать указатель Ctrl+H / Ctrl+A (или Ctrl+U — показать автоматически)
Лупа (увеличить/уменьшить) + / − (при открытой лупе), Ctrl+колесо
Произвольный показ / меню Shift+F10 или ПКМ
Режим докладчика вкл/выкл во время показа Alt+F5
Обменять экраны докладчика и показа Alt+Shift+S
Панель задач Ctrl+T
Остановить/запустить медиа / громкость / перемотка Alt+P / Alt+↑ / Alt+↓ / Alt+Shift+Page Down / Alt+Shift+Page Up; без звука Alt+U
Субтитры (P2) J
Завершить показ Esc, Ctrl+Break, пункт меню «Завершить показ»

9. Критерии готовности 1.0

№ Критерий Метрика
1 Открытие корпуса pptx (≥ 3 000 реальных презентаций: шаблоны Office, корпоративные, образовательные, с анимациями и медиа) 100 % без сбоев (фаззинг парсера cargo-fuzz 72 ч без падений); SSIM рендера слайда ≥ 0,98 против PowerPoint для 95 % слайдов, ≥ 0,95 для 99 %
2 Round-trip pptx → mpx → pptx без потерь для всех свойств P0; PowerPoint открывает результат без «восстановления»; повторный round-trip даёт байт-в-байт равный XML (нормализованный)
3 Анимации все 150+ пресетов PowerPoint воспроизводятся и соответствуют эталонным видео покадрово (допуск 1 кадр при 60 к/с); неизвестные пресеты — по дереву поведений
4 Переходы 51 переход; 60 к/с при 1080p на Intel Iris Xe / Apple M1 / AMD Vega 8; при 4K — ≥ 45 к/с
5 Показ задержка реакции на щелчок ≤ 16 мс; смена слайда с предрендером ≤ 1 кадр; режим докладчика на 2–3 экранах на Windows/macOS/Linux X11/Wayland
6 Производительность открытие 100 слайдов с медиа ≤ 2 с (SSD), 1 000 слайдов ≤ 8 с; холст 60 к/с при перетаскивании на слайде с 200 фигурами; память ≤ 600 МБ на 100-слайдовой презентации с 50 рисунками
7 Экспорт видео 1080p30 ≥ 2× реального времени; совпадение кадров с показом; воспроизводится в VLC, Windows Media Player, QuickTime, Chrome
8 ODP корпус 1 000 файлов LibreOffice: открытие 100 %, SSIM ≥ 0,97; Impress открывает наш odp без предупреждений
9 PPT корпус 1 000 файлов 97–2003: открытие 100 %, текст и рисунки без потерь
10 Keynote корпус 200 файлов: 100 % открытие, визуальное совпадение ≥ 0,9 SSIM
11 Текст все возможности Write в фигурах: RTL, вертикальный, переносы, орфография на 40 языках
12 Доступность скринридеры NVDA/VoiceOver/Orca читают слайды в порядке чтения; все команды с клавиатуры; проверка доступности выявляет 100 % тестовых дефектов
13 Стабильность автосохранение и восстановление без потери данных (тест kill −9 каждые 5 с на протяжении часа правок); парсеры в песочном процессе
14 Печать/PDF выдачи 1–9, заметки, PDF/A-2b и PDF/UA проходят veraPDF
15 Скрипты API §6 покрыт тестами; 20 примеров скриптов в галерее; события показа
16 Локализация интерфейс ru/en, пресеты с русскими названиями, 30 тем, 40 шаблонов
17 Установка MSIX/MSI, DMG (universal), Flatpak/AppImage; ассоциации .mpx/.pptx/.odp/.key

10. Риски

Риск Вероятность Влияние Снижение
Сложность p:timing: недокументированные комбинации поведений в реальных файлах высокая средняя изоморфное дерево + воспроизведение по поведениям, а не по пресетам; корпус из 3 000 файлов; покадровые эталоны
Патенты на H.264/AAC и лицензии кодеров на Linux средняя средняя платформенные кодеры на Windows/macOS; на Linux — WebM по умолчанию, OpenH264 по согласию пользователя; абстракция VideoEncoder
3D-эффекты фигур (sp3d, scene3d) и объёмные переходы — свой растеризатор средняя средняя P2; в 1.0 — приближённый плоский рендер, round-trip без потерь
Диаграммы-схемы: ~190 макетов OOXML с собственным языком раскладки высокая средняя кэш drawing для точного отображения, 40 своих макетов, интерпретатор layoutDef — P2
Wayland: позиционирование окон и полноэкранный режим на нужном выводе, захват курсора средняя средняя setScreen + xdg_toplevel.set_fullscreen(output); тесты на GNOME/KDE/Sway; резерв — X11/XWayland
Шрифты: документы с Calibri/Segoe без встраивания; встраивание с нарушением лицензий высокая низкая метрические аналоги (Carlito, Liberation); встраивание только по fsType
Keynote — закрытый формат, схема Protobuf меняется средняя низкая P1, корпус из версий Keynote 9–14, graceful degradation (постер слайда из preview.jpg)
Производительность миниатюр и холста на слабых GPU / без GPU средняя средняя CPU-резерв Skia, кэш и приоритизация миниатюр, лимиты памяти
Морфинг: несовпадение с PowerPoint в краевых случаях средняя низкая P1; тестовые пары слайдов; документированные отличия
Медиа: кодеки, недоступные в системе (HEVC на Windows без расширения, AV1 на старых macOS) средняя средняя диагностика при вставке с предложением перекодировать через meridian-video; FFmpeg-бэкенд Qt как резерв
Разрастание объёма 1.0 высокая высокая строгие P0; 3D, морфинг, сравнение, cameo, субтитры — в 1.x

11. Вопросы к библии

  1. Ctrl+K. Библия назначает Ctrl/⌘+K командной палитре, но в Microsoft Office это «Гиперссылка» — привычка, которую принцип «не ломать привычки» велит сохранить. Предложение: палитра — Ctrl+Shift+P (как в VS Code) с дублем F1, гиперссылка — Ctrl+K; либо оставить палитру на Ctrl+K, а гиперссылку перенести на Ctrl+Shift+K (так принято в этом документе до решения).
  2. Общий модуль «диаграммы-схемы». SmartArt есть в Word/Excel/PowerPoint; предлагается добавить в §2.2 библии модуль ядра Meridian Diagram (meridian-diagram), как Meridian Chart.
  3. Общая сцена фигур. Write (§2.8) и Slides опираются на один крейт геометрии/стилей фигур; предлагается явно назвать его в §2.2 (Meridian Scene, meridian-scene) и завести docs/algorithms/scene.md (prstGeom, стили, рендер).
  4. Видеокодеки. Нужна политика по лицензиям кодеров (платформенные API vs. бандл OpenH264/libvpx) в разделе стека; здесь принято: Windows/macOS — системные кодеры, Linux — WebM по умолчанию.
  5. Редакция для экспорта видео. docs/10-licensing-accounts.md относит slides_video_export к Pro; библия §9.1 для Free говорит «все форматы чтения/записи». Нужно решить, считается ли видео «форматом записи» (тогда Free) или функцией Pro.
  6. Путь спецификации Chart. docs/apps/sheets.md ссылается на docs/kernel/chart.md, а документ движка написан как docs/algorithms/chart-engine.md — выбрать одно расположение и исправить ссылку.