94 lines
43 KiB
Go
94 lines
43 KiB
Go
package main
|
||
|
||
import (
|
||
"fmt"
|
||
"path/filepath"
|
||
"strings"
|
||
)
|
||
|
||
// The manual is shared by the standalone artifact and the docs integration.
|
||
// It describes the current controls; tutorials below use that same application.
|
||
type guideChapter struct {
|
||
ID, EN, RU, Lesson string
|
||
English, Russian []string
|
||
}
|
||
|
||
var guidebook = []guideChapter{
|
||
{"getting-started", "Getting started", "Начало работы", "first-sprite",
|
||
[]string{"Asset Studio edits pixels, layers and frame animation. In native Aego choose an Art document in Assets, or use Edit Sprite / Edit Source Art on SpriteRenderer. A PNG opens a confirmation to create its linked editable source; the prepared atlas remains a viewing and diagnostics resource.", "In the web app choose New Sprite, enter 32×32, and select RGBA. Pencil is B, Eraser E, and Fill G. Drag on the canvas, then try Undo and Redo. One completed stroke is one operation. Esc cancels an unfinished gesture.", "Save .aeart to keep layers, indexed pixels, frames, linked images, tags and surface channels. PNG is a flattened image of the selected frame/channel. Download a source copy before closing if browser recovery is unavailable. No account, desktop service or server upload is required."},
|
||
[]string{"Asset Studio редактирует пиксели, слои и покадровую анимацию. В Aego откройте Art Document из Assets либо нажмите Edit Sprite / «Редактировать изображение» в SpriteRenderer. Для PNG редактор предлагает создать связанный исходник; подготовленный атлас остаётся ресурсом просмотра и диагностики.", "В веб-приложении выберите New Sprite, размер 32×32 и RGBA. B — карандаш, E — ластик, G — заливка. Проведите линию, проверьте отмену и повтор. Законченный штрих — одна операция. Esc отменяет незавершённый жест.", "Сохраняйте .aeart: он содержит слои, индексы палитры, кадры, связи изображений, метки и каналы. PNG — сведённое изображение выбранного кадра и канала. Если recovery недоступно, скачайте исходник перед закрытием. Учётная запись, desktop-сервис и загрузка рисунка на сервер не нужны."}},
|
||
{"pixel-art-tools", "Pixel art tools", "Инструменты рисования", "pixel-perfect",
|
||
[]string{"The context toolbar above the canvas holds brush size, square/round shape, Pixel Perfect, fill mode, dithering, symmetry and surface channel. A fast pointer move is interpolated by Go. Shapes preview while dragging and commit on release; Esc discards the preview.", "Line, Rectangle and Ellipse use the brush settings. Polygon accepts clicked vertices and Enter to finish. Curve accepts a start, two control points and an end. Gradient uses foreground/background colors; Dither distributes the two colors on the pixel grid. Shift is not required to obtain crisp edges.", "Use rectangular, elliptical, lasso or magic-wand selection to limit painting. Move drags the selected pixels; Copy/Paste and the Transform dialog, Flip/Rotate and nearest-pixel Scale actions use the active cel. Select a region up to 128×128, choose From selection, then use Custom brush or Pattern. Custom brush follows the pointer; Pattern repeats in canvas coordinates. Capturing a brush does not change document history."},
|
||
[]string{"На панели у холста находятся размер кисти, квадратная/круглая форма, Pixel Perfect, заливка фигуры, дизеринг, симметрия и канал. Быстрые движения указателя интерполирует Go. Фигура видна до отпускания кнопки; Esc убирает предпросмотр.", "Линия, прямоугольник и эллипс используют настройки кисти. Для многоугольника отмечайте вершины и нажмите Enter. Для кривой укажите начало, две управляющие точки и конец. Градиент использует основной и фоновый цвета; дизеринг распределяет их по пиксельной сетке. Края остаются чёткими без специальных модификаторов.", "Прямоугольное, овальное выделение, лассо и волшебная палочка ограничивают рисование. Move перемещает выбранные пиксели; Copy/Paste и диалог «Преобразовать» с отражением, поворотом и масштабированием без сглаживания действуют на активную ячейку. Выделите область до 128×128, нажмите «Из выделения» и выберите свою кисть либо узор. Кисть следует за указателем, узор повторяется в координатах холста. Создание кисти не добавляет запись в Undo."}},
|
||
{"layers-palettes", "Layers and palettes", "Слои и палитры", "layers",
|
||
[]string{"Add a layer with +. Layer Properties chooses Raster, Group or Reference, its name and parent group. Visibility and lock are separate: hiding a layer removes it from composition; locking prevents edits. Opacity and Normal/Multiply/Screen/Add affect composition. Reference layers are excluded from game export. Isolate previews a layer or group without changing visibility or history. Merge down combines adjacent visible Normal-blend raster layers (or two reference layers); other blends are rejected because they depend on the underlying image. Undo restores their links. Indexed merging requires exact representable palette colors.", "RGBA stores color and alpha; Grayscale stores luminance and alpha. Indexed albedo stores actual palette indices. Choose a swatch to paint by index. The foreground alpha control is explicit; right-click a palette entry to select the background color. X swaps foreground and background.", "Palette Import accepts the supported JSON palette and GPL text. From image extracts colors; quantization is a separate explicit choice. Order is a permutation that preserves appearance by rewriting indices. Remap intentionally changes which colors the image uses. The transparent index remains reserved. Surface normal/height/emission channels keep their data semantics when albedo is indexed. Ramp shade shifts selected pixel colors along an explicit palette range."},
|
||
[]string{"Добавьте слой кнопкой +. В свойствах выбираются Raster, Group или Reference, имя и родительская группа. Видимость и блокировка независимы: скрытый слой не участвует в композиции, заблокированный нельзя редактировать. Непрозрачность и Normal/Multiply/Screen/Add меняют композицию. Референсные слои не включаются в игровой экспорт. «Изолировать» показывает слой или группу без изменения видимости и истории. «Объединить вниз» объединяет соседние видимые растровые слои с Normal либо два референсных слоя; другие режимы отклоняются, поскольку зависят от подложки. Undo восстанавливает связи. В Indexed все полученные цвета должны точно присутствовать в палитре.", "RGBA хранит цвет и alpha, Grayscale — яркость и alpha. Indexed albedo хранит настоящие индексы палитры. Рисуйте выбранным образцом; alpha основного цвета задаётся отдельно. Правой кнопкой по образцу выбирается фоновый цвет, X меняет основной и фоновый местами.", "Импорт палитры читает поддерживаемый JSON и GPL. «Из рисунка» извлекает цвета; квантование включается отдельно. «Порядок» переставляет цвета с пересчётом индексов и сохраняет внешний вид. Remap намеренно перекрашивает изображение. Прозрачный индекс зарезервирован. Normal/height/emission сохраняют смысл своих данных и при индексированном albedo. Ramp Shading сдвигает цвета выбранных пикселей по заданному диапазону палитры."}},
|
||
{"timeline", "Animation timeline", "Шкала анимации", "animation",
|
||
[]string{"The asset timeline is a grid of layers and frames. A cel is the image at one intersection, including its offset and channel. Select a frame header to change the displayed frame. + Frame adds a frame; Duplicate copies independently; Link shares the image.", "Duration is measured in milliseconds for each frame. Playback uses the Go document timing, including Forward, Reverse and Ping-pong tags. Tags name frame ranges; editing or deleting a tag does not recreate the pixel frames. Enter starts/stops playback.", "Shift selects a range and Ctrl/Command adds individual cels. Move/copy range asks for layer/frame offsets and explicit overwrite permission. Copy frames/Paste animation transfers animation through the shared document model. Asset animation and scene-property animation are different timelines; native import produces the existing .aeanim resources for the game."},
|
||
[]string{"Шкала ассета — таблица слоёв и кадров. Ячейка (cel) связывает изображение с одним пересечением, смещением и каналом. Заголовок кадра меняет отображаемый кадр. «+ Кадр» добавляет кадр, «Копия» создаёт независимый рисунок, «Связать» использует общее изображение.", "Длительность каждого кадра задаётся в миллисекундах. Воспроизведение использует время Go-документа и направления Forward, Reverse, Ping-pong. Метка именует диапазон; её правка или удаление не пересоздаёт пиксельные кадры. Enter запускает и останавливает просмотр.", "Shift выделяет диапазон, Ctrl/Command добавляет отдельные ячейки. Для переноса/копии задайте смещение по слоям и кадрам; замена существующих ячеек требует явного выбора. Copy frames/Paste animation переносит анимацию через общую модель документа. Анимация рисунка и свойств сцены имеют разные шкалы; native-импорт создаёт существующие игровые .aeanim."}},
|
||
{"linked-cels", "Linked cels", "Связанные ячейки", "linked-cels",
|
||
[]string{"Linked cels share an image identity. Painting that image changes every linked cel, even when the cels have different frame or layer positions. The infinity marker identifies shared images in the timeline.", "Use Link to reuse artwork intentionally. Duplicate normally produces an independent image with copy-on-write storage. Unlink copies the shared image for the selected cel; subsequent painting no longer changes the others. Undo restores both pixels and link structure.", "Save as .aeart to preserve these relationships. A flattened PNG or sheet contains rendered pixels and cannot reconstruct linked identities. Reopening the source in native or web uses the same file format and validation."},
|
||
[]string{"Связанные ячейки имеют общий идентификатор изображения. Рисование меняет все такие ячейки, даже если они находятся в разных кадрах или слоях. Знак бесконечности на шкале обозначает общие изображения.", "Используйте «Связать» для намеренного повторения рисунка. Обычная «Копия» создаёт независимые данные с copy-on-write. «Отвязать» копирует общее изображение для выбранной ячейки; дальнейшие правки не затрагивают остальные. Undo восстанавливает пиксели и структуру связей.", "Сохраняйте .aeart для сохранения этих отношений. Сведённый PNG или спрайт-лист содержит готовые пиксели и не восстанавливает идентичность linked cels. Native и web читают один формат с общей проверкой данных."}},
|
||
{"onion-skin", "Onion skin and alignment", "Калька и выравнивание", "onion-skin",
|
||
[]string{"Enable Onion Skin beside playback, then select a middle frame. Previous and next frames appear as tinted guides around the current drawing. The overlay is not written into the cel and does not appear in PNG export.", "Stop playback to edit a frame. Keep feet or contact points aligned across the sequence. Pivot edits the current frame anchor and shows a crosshair; a frame-specific anchor takes precedence over the document default. Pivot data belongs to the source; the linked PNG workflow preserves existing frame pivots and IDs. Flip in GPU Preview is a presentation choice; the separate Flip action edits pixels.", "In native Aego use the real selected character and scene preview to check Animator, FlipX and the ground contact. Preview must not alter physics or authored collider geometry. Changing alpha may change the rendered shadow contour, not the physics collider."},
|
||
[]string{"Включите «Калька» рядом с воспроизведением и выберите средний кадр. Соседние кадры видны как цветные ориентиры. Этот слой подсказок не записывается в cel и не попадает в PNG.", "Остановите воспроизведение для правки кадра. Выравнивайте ноги или точки контакта по всей последовательности. Кнопка Pivot меняет точку привязки текущего кадра и показывает перекрестие; привязка кадра приоритетнее общей. Pivot принадлежит исходнику; связанный PNG сохраняет прежние pivot и ID кадров. Flip в GPU Preview меняет только просмотр, отдельная команда отражения меняет пиксели.", "В native Aego проверяйте Animator, FlipX и контакт с землёй на выбранном персонаже в настоящей сцене. Preview не должен менять физику или геометрию коллайдера. Изменение alpha может изменить контур нарисованной тени, но не физический коллайдер."}},
|
||
{"import-export", "Import and export", "Импорт и экспорт", "export",
|
||
[]string{"Open accepts .aeart, PNG and the supported .ase/.aseprite subset. A local file is read in the browser; the server does not receive its bytes. Invalid files and exceeded limits report an error before replacing document state. Opening another file creates a separate tab.", "Save/Download .aeart preserves the editable document. PNG exports the selected frame and channel. Sprite sheet export produces a PNG grid and JSON frame metadata with durations and geometry. Keep both downloads together. Native Aego imports .aeart through its registered importer and builds .aeanim and prepared regions with stable references.", "A browser download does not provide a reliable disk-commit acknowledgement, so it may leave the tab marked dirty. File System Access, when available, can acknowledge a successful write. Never treat a PNG export as a backup of layers, tags or palette indices."},
|
||
[]string{"Open принимает .aeart, PNG и поддерживаемую часть .ase/.aseprite. Локальный файл читается в браузере, сервер не получает его байты. Неверный формат и превышение лимитов сообщаются до замены состояния документа. Другой файл открывается отдельной вкладкой.", "Save/Download .aeart сохраняет редактируемый документ. PNG экспортирует выбранные кадр и канал. Спрайт-лист состоит из PNG-сетки и JSON с длительностями и геометрией кадров; храните оба скачанных файла вместе. Native Aego импортирует .aeart обычным импортёром и строит .aeanim и регионы со стабильными ссылками.", "Обычное скачивание в браузере не подтверждает успешную запись на диск, поэтому вкладка может оставаться dirty. File System Access при доступности подтверждает запись. Экспорт PNG не заменяет резервную копию слоёв, меток и индексов палитры."}},
|
||
{"aseprite-import", "Aseprite import", "Импорт Aseprite", "aseprite",
|
||
[]string{"The Go importer reads RGBA, grayscale and indexed raster data, supported layer/group records, raw/compressed and linked cels, frame durations, supported tags and palette records. Genuine upstream fixtures and independently rendered reference PNGs test the supported visible result.", "Tilemaps/tilesets, animated palettes, custom ICC/gamma profiles, unsupported blend modes, nonzero cel z-index and ping-pong-reverse tags are not silently approximated. Unsupported critical records fail the import. Discarded metadata or finite repetition data produces diagnostics. Read those messages before relying on an imported animation.", "The tutorial offers a licensed original Aseprite test sprite. Download it, use Open, inspect its four frames and layers, then save as .aeart. Aego does not export .aseprite and does not promise a lossless round-trip of unsupported Aseprite features."},
|
||
[]string{"Go-импортёр читает растровые RGBA, grayscale и indexed, поддерживаемые слои/группы, обычные, сжатые и связанные cels, длительности, метки и палитры. Настоящие upstream-файлы и независимо отрендеренные PNG проверяют поддерживаемый видимый результат.", "Tilemap/tileset, анимированные палитры, собственные ICC/gamma-профили, неподдерживаемые blend modes, ненулевой cel z-index и ping-pong-reverse не заменяются приблизительной имитацией. Неподдерживаемые критические записи останавливают импорт. Потеря метаданных или конечного числа повторений сопровождается диагностикой; прочитайте её до использования анимации.", "В урок включён оригинальный тестовый спрайт Aseprite с лицензией. Скачайте его, откройте через Open, проверьте четыре кадра и слои и сохраните .aeart. Aego не экспортирует .aseprite и не обещает lossless round-trip неподдерживаемых функций."}},
|
||
{"surface-channels", "Lit, normal and emission", "Свет, normal и emission", "surface-channels",
|
||
[]string{"Choose Albedo, Normal, Height or Emission above the art canvas. Each channel has cels tied to the same frame identities. Normal and height are data channels; emission keeps its color semantics. Paint normal vectors deliberately, with RGB 128/128/255 as a conventional flat normal.", "Choose Lit / Normal in Preview to load Aego's WebGL2 renderer. Move Light and enable Shadows to inspect the alpha contour. Paint emission and raise Emission; enable Bloom to inspect the real PostFX chain. Normal/Height/Emission modes show the channel directly and report missing channel data.", "Flash and Dissolve use the existing Aego materials. These controls affect only the isolated preview world. Height visualization does not imply parallax or 3D displacement. If WebGL2 is unavailable or lost, read the status; the pixel document and export remain CPU-owned."},
|
||
[]string{"Над холстом выбираются Albedo, Normal, Height и Emission. Ячейки каналов привязаны к тем же ID кадров. Normal и height — каналы данных; emission сохраняет свои цветовые правила. Нормали рисуются осознанно: RGB 128/128/255 обычно соответствует плоской нормали.", "Выберите Lit / Normal в предпросмотре для загрузки WebGL2 renderer Aego. Передвигайте свет и включайте тени для проверки alpha-контура. Нарисуйте emission, увеличьте Emission и включите Bloom для настоящей цепочки PostFX. Режимы Normal/Height/Emission показывают канал напрямую и сообщают об отсутствии данных.", "Flash и Dissolve используют существующие материалы Aego. Настройки действуют только на отдельный мир предпросмотра. Просмотр Height не означает parallax или объёмное смещение. При недоступном или потерянном WebGL2 смотрите статус; пиксели и экспорт остаются в CPU-документе."}},
|
||
{"vfx-authoring", "VFX authoring", "Создание эффектов", "explosion",
|
||
[]string{"Choose New Effect on the start page, or New → Template in the editor. The shared catalog contains Dust, Spark, Smoke, Explosion, Fire, Hit Flash, Magic Projectile and Trail. Create opens an independent editable document with eight frames, layers, palette, tag and pivot, then selects the VFX workspace. The existing explosion lesson remains available separately.", "Draw expansion, breakup and fading across frames, keeping the origin consistent. Use independent cels for changing shapes and linked cels for repeated artwork. Save/Download .aeart preserves the template association; reopening the file uses the same template and editable pixels in native and web.", "Choose VFX or ParticleSystem2D in Preview. Template documents use their corresponding real Aego particle preset, including bursts, curves, material and lifecycle. Restart Effect replays one-shot effects such as Hit Flash and Explosion; changing the continuous particles-per-second rate does not remove the preset bursts. Painting and changing frames update the prepared images without resetting the chosen preview settings. Bloom is a preview option. A particle flipbook uses the runtime's uniform FrameFPS derived from the average frame duration; the Art playback itself respects individual durations.", "In native Aego use Assets → Create → Animated Effect (.aeart + .aepreset)… (or New Effect…). Choose the path and one of the same eight templates. Create writes the editable source and its linked particle preset in one Assets History operation and opens VFX. For a game object, open the same .aeart in native Aego and assign the imported frames to ParticleSystem2D through the existing authoring workflow. Use the native emitter Inspector and Curve/Gradient editors for production settings. The standalone browser does not pretend to assign assets to an unopened local game project."},
|
||
[]string{"Нажмите «Новый эффект» на стартовой странице либо «Создать» → «Шаблон» в редакторе. Общий каталог содержит «Пыль», «Искры», «Дым», «Взрыв», «Огонь», «Вспышка удара», «Магический снаряд» и «След». Команда «Создать» открывает независимый документ с восемью кадрами, слоями, палитрой, меткой и точкой привязки, затем включает рабочее пространство VFX. Урок с покадровым взрывом остаётся отдельным примером.", "Нарисуйте расширение, распад и затухание по кадрам, сохраняя общую точку привязки. Для меняющихся форм используйте независимые cels, для повторов — связанные. Сохранение или скачивание .aeart сохраняет связь с шаблоном: повторно открытый файл содержит те же редактируемые пиксели и в native, и в web.", "Выберите VFX или ParticleSystem2D в предпросмотре. Для документа из шаблона используется соответствующий настоящий пресет частиц Aego с его всплесками, кривыми, материалом и временем жизни. Кнопка «Повторить эффект» заново запускает одноразовый взрыв или вспышку. Изменение непрерывной скорости испускания не удаляет всплески пресета. Рисование и переключение кадров обновляют подготовленные изображения, сохраняя выбранные настройки preview. Bloom включается отдельно. Flipbook частиц использует равномерный FrameFPS из средней длительности; просмотр Art-анимации учитывает индивидуальные длительности.", "В native Aego выберите Assets → Создать → Анимированный эффект (.aeart + .aepreset)… либо команду «Новый эффект…». Укажите путь и один из тех же восьми шаблонов. Создание записывает редактируемый исходник и связанный пресет частиц одной операцией общей истории Assets, затем открывает VFX. Для игрового объекта откройте тот же .aeart в native Aego и назначьте импортированные кадры ParticleSystem2D существующим workflow. Полные настройки эмиттера, кривые и градиенты доступны в native Inspector. Браузер не выдаёт экспорт за назначение ассета в неоткрытый локальный игровой проект."}},
|
||
{"using-in-aego", "Using assets in Aego", "Использование в Aego", "character",
|
||
[]string{"Select Player in the platformer example and use SpriteRenderer's Edit Sprite. If the source is PNG, confirm creation of a linked .aeart. The adapter retains the existing texture and frame IDs, slice dimensions, pivots and animation dependencies; it does not promote a GPU atlas to the source.", "Paint the active frame and observe Scene View. A shared source affects its consumers; Find All Uses opens references. Duplicate for This Object creates an independent source and remaps that object's dependent animation/controller references. The confirmation explains that undoing assignment leaves the new files in Assets.", "Save publishes through the ordinary asset pipeline. Undo/Redo uses the editor History and restores source state and live prepared data. Normal/emission and alpha-shadow updates do not change collider geometry. After reopening, the saved source and old AssetRefs remain connected. Native/web game export uses the existing exporter."},
|
||
[]string{"Выберите Player в примере platformer и нажмите Edit Sprite у SpriteRenderer. Если исходник PNG, подтвердите создание связанного .aeart. Адаптер сохраняет существующие ID текстуры и кадров, размеры нарезки, pivot и зависимости анимации; GPU-атлас не становится исходником.", "Измените активный кадр и наблюдайте Scene View. Общий источник влияет на потребителей; Find All Uses открывает ссылки. Duplicate for This Object создаёт независимый исходник и переназначает зависимые анимации и controller выбранного объекта. Диалог поясняет: отмена назначения оставляет новые файлы в Assets.", "Save публикует через обычный pipeline. Undo/Redo использует History редактора и восстанавливает исходное состояние и подготовленные данные. Обновление normal/emission и alpha-тени не меняет коллайдер. После открытия сохранённый исходник остаётся связан со старыми AssetRef. Native/web экспорт игры выполняет существующий exporter."}},
|
||
{"web-standalone", "Web standalone and embedding", "Веб-приложение и документация", "first-sprite",
|
||
[]string{"The standalone and embedded pages load the same content-hashed application and Go core. Drawing loads first; GPU Preview is a separate lazy renderer resource in the same build. The app works with ordinary file input and download without File System Access or a desktop installation.", "In a lesson click Try it to load one real editor. Open Full Editor transfers a bounded, versioned source snapshot directly from the iframe to the new app window. An acknowledgement confirms receipt. Source history remains in the original window; further edits in either copy are independent.", "If popups or transfer are blocked, Download for transfer preserves the snapshot for manual Open. Embedded storage may be partitioned or unavailable; do not assume shared storage between documentation and the app. Resize the window or use the panels toggle on narrow screens; use the full editor when the lesson is too compact.", "Choose Auto, Dark or Light in the editor header. Auto follows the system theme; the browser remembers an explicit choice when local storage is available. This changes the interface, not the artwork or its transparency background."},
|
||
[]string{"Standalone и встроенные страницы загружают одно приложение с хешированными ресурсами и общим Go Core. Рисование доступно первым; GPU Preview — отдельный ленивый ресурс renderer в той же сборке. Обычные выбор файла и скачивание работают без File System Access и установленного движка.", "В уроке нажмите «Попробовать»: загрузится настоящий редактор. Open Full Editor передаёт ограниченный версионированный исходник напрямую из iframe в новую вкладку приложения. Подтверждение означает получение. История остаётся в исходной вкладке; дальнейшие правки двух копий независимы.", "Если новое окно или передача заблокированы, «Скачать для переноса» сохраняет снимок для ручного Open. Встроенное хранилище может быть изолировано или недоступно; общее storage документации и приложения не гарантируется. В узком окне используйте кнопку панелей, а для большой композиции откройте полный редактор.", "Выберите в шапке «Авто», «Тёмная» или «Светлая». «Авто» следует системной теме; браузер запоминает явный выбор, если доступно локальное хранилище. Меняется только интерфейс, а не рисунок или фон прозрачности."}},
|
||
{"recovery", "Saving, recovery and conflicts", "Сохранение, восстановление и конфликты", "export",
|
||
[]string{"Some native source operations journal source and metadata edits. After an interrupted transaction, check `aego source-recovery status` and choose recovery explicitly; restore requires `--confirm`. Unexpected external changes are preserved and reported as conflicts.", "In the browser, recovery snapshots use IndexedDB transactions and distinct document keys. On reload choose the required local draft and Restore. Reset Example affects only that example's tab; it does not delete other drawings. Browser storage is optional and can be evicted by the browser or privacy settings.", "A storage/quota error is visible and does not mark the drawing saved. Download .aeart while the tab is open. Keep permanent file copies of important work. If an external source edit conflicts with a dirty native document, resolve it explicitly; background import must not replace unsaved pixels."},
|
||
[]string{"Некоторые операции с native-исходниками журналируют изменения файлов и метаданных. После прерывания проверьте `aego source-recovery status` и примите решение о восстановлении явно; restore требует `--confirm`. Неожиданные внешние изменения сохраняются и вызывают конфликт.", "В браузере recovery использует транзакции IndexedDB и отдельные ключи документов. После reload выберите нужный черновик и нажмите «Восстановить». Reset Example действует только на вкладку примера и не удаляет другие рисунки. Browser storage необязательно и может быть очищено браузером или настройками приватности.", "Ошибка storage/quota видна и не помечает рисунок сохранённым. Скачайте .aeart, пока вкладка открыта. Храните постоянные копии важной работы. При внешней правке dirty-исходника native требует явного разрешения конфликта; фоновый импорт не должен заменять несохранённые пиксели."}},
|
||
{"keyboard-shortcuts", "Keyboard and pointer controls", "Клавиатура и указатель", "first-sprite",
|
||
[]string{"B Pencil; E Eraser; G Fill; I Eyedropper; L Line; R Rectangle; O Ellipse; D Gradient; M rectangular selection; Q Lasso; W Magic Wand; V Move; P Polygon; C Curve. Toolbar buttons expose the same operations.", "Ctrl/Command+Z Undo; Shift+Ctrl/Command+Z or Ctrl+Y Redo; Ctrl/Command+S Save; Ctrl/Command+O Open; Ctrl/Command+C/V Copy/Paste; Ctrl/Command+A Select all; Ctrl/Command+D Clear selection. Enter confirms a polygon or toggles playback; Esc cancels construction/gesture and clears selection.", "Wheel zoom follows the pointer. Pan and pinch adjust only the view, not pixels. Mouse, touch and pen use the same pointer transport into Go; physical pressure-sensitive hardware requires its own device check. Shortcuts should not intercept typing in text inputs. Document tabs retain their own view and selection state."},
|
||
[]string{"B — карандаш; E — ластик; G — заливка; I — пипетка; L — линия; R — прямоугольник; O — эллипс; D — градиент; M — прямоугольное выделение; Q — лассо; W — волшебная палочка; V — перемещение; P — многоугольник; C — кривая. Кнопки панели вызывают те же операции.", "Ctrl/Command+Z — отмена; Shift+Ctrl/Command+Z или Ctrl+Y — повтор; Ctrl/Command+S — сохранить; Ctrl/Command+O — открыть; Ctrl/Command+C/V — копировать/вставить; Ctrl/Command+A — выделить всё; Ctrl/Command+D — убрать выделение. Enter завершает многоугольник либо переключает воспроизведение. Esc отменяет построение/жест и убирает выделение.", "Колесо меняет масштаб относительно указателя. Pan и pinch меняют только вид. Мышь, touch и pen передаются в Go одним pointer-контрактом; физическое перо и давление требуют проверки устройства. Горячие клавиши не должны перехватывать ввод текста в полях. Вкладки сохраняют свои настройки вида и выбора."}},
|
||
{"troubleshooting", "Troubleshooting", "Решение проблем", "first-sprite",
|
||
[]string{"WASM failed to load: inspect the status and retry on a stable connection. Hosting must return application/wasm and compatible CSP, never HTML for a missing binary. A mismatched build/version must be updated as one verified artifact. The GPU module is requested only when a GPU mode is selected.", "Missing channel or GPU failure: select the appropriate frame/channel, paint data, then retry the preview mode. Context loss is reported while Aego restores GPU resources from CPU data. A failed preview is not evidence that the source disappeared. Export the source if recovery/storage is also unavailable.", "Import rejected: keep the original file and read the specific format/limit diagnostic. Aseprite unsupported chunks are not a promise of lossless import. Scene did not update: confirm the source link, frame, shared/individual assignment and importer diagnostics. External file conflict: keep both versions and resolve explicitly. An older app must not open a newer unsupported document version silently."},
|
||
[]string{"WASM не загрузился: прочитайте статус и повторите при стабильном соединении. Сервер должен отдавать application/wasm и подходящую CSP, а не HTML вместо отсутствующего бинарника. Несовпадающие версии обновляются одним проверенным артефактом. GPU-модуль запрашивается только при выборе GPU-режима.", "Нет канала или ошибка GPU: выберите нужные кадр и канал, нарисуйте данные и повторите выбор preview. Потеря контекста отображается, пока Aego восстанавливает GPU-ресурсы из CPU-данных. Сбой предпросмотра не означает потерю исходника. Экспортируйте исходник, если recovery тоже недоступно.", "Импорт отклонён: сохраните оригинал и прочитайте конкретную ошибку формата/лимита. Неподдерживаемые chunks Aseprite не дают обещания lossless-импорта. Сцена не обновилась: проверьте связь источника, кадр, общее/индивидуальное назначение и диагностику импортёра. При внешнем конфликте сохраняйте обе версии и разрешайте его явно. Старое приложение не должно молча открывать неподдерживаемую новую версию документа."}},
|
||
}
|
||
|
||
func writeGuidebook(out string, names map[string]string, o buildOptions) error {
|
||
for _, lang := range []string{"en", "ru"} {
|
||
for _, g := range guidebook {
|
||
title, paragraphs, learn := g.EN, g.English, "Interactive lesson"
|
||
if lang == "ru" {
|
||
title, paragraphs, learn = g.RU, g.Russian, "Интерактивный урок"
|
||
}
|
||
var body, nav strings.Builder
|
||
for _, p := range paragraphs {
|
||
fmt.Fprintf(&body, "<p>%s</p>", esc(p))
|
||
}
|
||
for _, chapter := range guidebook {
|
||
label := chapter.EN
|
||
if lang == "ru" {
|
||
label = chapter.RU
|
||
}
|
||
fmt.Fprintf(&nav, `<a href="../%s/">%s</a>`, esc(chapter.ID), esc(label))
|
||
}
|
||
other := "ru"
|
||
if lang == "ru" {
|
||
other = "en"
|
||
}
|
||
h := `<!doctype html><html lang="` + lang + `"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>` + esc(title) + ` — Asset Studio</title><link rel="stylesheet" href="../../../../` + names["docs.css"] + `"></head><body><header><a href="` + esc(o.Origin+"/r/"+o.ID+"/") + `">AEGO · Asset Studio</a><a href="../../../` + other + `/guide/` + g.ID + `/">` + strings.ToUpper(other) + `</a></header><main><nav>` + nav.String() + `</nav><article><h1>` + esc(title) + `</h1>` + body.String() + `<p><a href="../../` + g.Lesson + `/">` + esc(learn) + ` →</a></p></article></main></body></html>`
|
||
if err := writeNew(filepath.Join(out, "docs", lang, "guide", g.ID, "index.html"), []byte(h)); err != nil {
|
||
return err
|
||
}
|
||
}
|
||
}
|
||
return nil
|
||
}
|