Skip to content

Latest commit

 

History

History
350 lines (255 loc) · 188 KB

editor.ja.md

File metadata and controls

350 lines (255 loc) · 188 KB

編集アプリ(インストール不要)

English | 日本語

作業フォルダを直接開き、開発サーバーと同じこと(プレビュー、スライドの上での原稿・台本の編集、コメント)をするウェブページ。Egatari ファイル(.ega.html)(原稿も中に持つ 1 つの HTML。Egatari の形式に従う)も、フォルダなしで開き、メモリの上で直して保存し直せる。インストールもターミナルも要らない。最初の画面は Egatari ファイルを先に置く(「ファイルを開く(.ega.html)…」「新規作成…」。作業フォルダは「フォルダで作業する…」)。

形 中身 ここで
作業フォルダ deck.html・narration.md・audio/ … の入ったフォルダ。コマンド・AI のコーディングツール(Claude Code・Codex・Gemini CLI など)・ほかのエディタが読み書きする 「フォルダで作業する…」(Chrome / Edge)で直す
Egatari ファイル(.ega.html) 原稿と音声を中に持つ 1 つの HTML(--portable)。ブラウザで開けば再生 「開く…」で直す(どのブラウザでも)
再生専用(--play-only) 原稿を持たない Egatari ファイル 直せない(元の Egatari ファイルか作業フォルダを開く)
組み立てた HTML(out/deck.html) コマンド(node kit/build.mjs)の発表用の出力(編集アプリからはエクスポートしない) 直せない(作業フォルダを開く)
  • ブラウザ: パソコンの Google Chrome か Microsoft Edge(Windows・macOS・Linux・ChromeOS)。フォルダは File System Access API(showDirectoryPicker)を使うので、Safari と Firefox では開けない(最初の画面にそう出て、そこで新しく作る道として「新規作成… → チャットの AI に書いてもらう」を示す)。Egatari ファイルは今のどのブラウザでも開いて直せる(ファイルを選ぶ画面がなければ、保存はダウンロードになり、保存のたびにダウンロードに新しいファイルができる。最初の画面と保存の知らせにそう出る:次はいちばん新しいものを開く)
  • 通信: アプリ自身の読み込みのほかは無い。作業フォルダやファイルはブラウザの中で読み書きし、どこにも送らない。「AI 音声をこの PC で作る」(音声の板)を使うときだけ、編集アプリのサイトの別の TTS の窓がモデルを取る(編集アプリのページそのものは、そのときもどこにも繋がらない)

アプリの入手

形 開き方 備考
配信 https://studio.egatari.org/ main から .github/workflows/pages.yml で公開する。字は教材が使う分だけ読む。前の場所 …/editor/ からはここへ移る
オフライン版のエディタ(editor.html) npm run build:app のあと dist/editor.html をダブルクリック 約 10 MB(字を全部入れてある)。Chrome・Edge なら file:// で動く。このファイルを人に渡してもよい
自分のサーバー npm run build:app のあと dist/ を静的に配る どこでもよい(https か http://localhost)。サイトの根でも、下のパスでもよい

npm run build:app(node tools/build-app.mjs [--out dist] [--no-single])は先に npm ci が要る(バージョンを固定した開発用の依存 esbuild を使う)。

使い方

  1. 教材を開く。 Egatari ファイルは最初の画面の「ファイルを開く(.ega.html)…」か ファイル ▾ →「開く…」(下)。作業フォルダ(deck.html の入ったフォルダ。deck.html がなければフォルダの最上位の最初の .html)は画面にドラッグ&ドロップするか、「フォルダで作業する…」(最初の画面か ファイル ▾)を押す。そのフォルダを編集してよいか、ブラウザが 1 回たずねる

    • 最初の画面は上から:新規作成…(主のボタン。チャットの AI に教材を書いてもらう。下)、ファイルを開く(.ega.html)… とドラッグ&ドロップの場所、最近のファイル、サンプル、小さく パーツの一覧(パーツのページの /parts/ を新しいタブで開く。サイトではサイトの根からの相対で、凍結した写し /vX.Y.Z/ からは ../parts/。手元から開いたオフライン版のエディタでは、ヘルプのパーツのリンクと同じく公開のサイトの https://studio.egatari.org/parts/。app/parts-gallery.js の partsIndexHref)、小さく Claude Code・Cowork で作る(上級)(行き先は app/main.js の WITH_CLAUDE_URL の 1 か所。説明のページは未定)、フォルダで作業する…。4 つのファイルの種類の表は使い方(?)にある。新しい作業フォルダはコマンドの npm run new で作る
    • 続きを開く:いちばん最近のものが作業フォルダなら、最初の画面の上に 続きを開く:〈フォルダの名前〉。押すとブラウザが許可を求め、許せばそのフォルダを開く(断れば最初の画面のまま)。ページを読み込み直したとき(Cmd+R・F5 や、時間を置いて戻ったとき)、そのフォルダの許可がまだあれば(Chrome の「常に許可」など)、押さなくても開き直す。許可がなければ、押すまで許可を求めない。Egatari ファイルは読み込み直すと閉じる(保存していない変更はブラウザに残り、最初の画面の「保存していない変更」から戻せる)
    • 最近のファイル:作業フォルダと Egatari ファイルが最初の画面に並ぶ(ブラウザがハンドルを IndexedDB に残す。中身は残さない)。開き直すとき、ブラウザがもう一度許可を求める(Egatari ファイルは読む許可だけ。書く許可は「保存」のときに求める)。Egatari ファイルが並ぶのは、ブラウザがファイルのハンドルをくれたとき(Chrome / Edge の「ファイルを開く(.ega.html)…」かドラッグ&ドロップ)だけで、Safari・Firefox では並ばない
    • サンプル(配信版だけ):このリポジトリのサンプル(examples/。音声なし)を Egatari ファイルにしたものが最初の画面に並ぶ。いちばん上の列「まず見る」に Egatari の紹介(画面の言語のものが先、もう一方には言語のラベル)とパーツ図鑑(再生だけ。パーツの一覧 へも)、その下にサンプルの種類のカード 教育・ビジネス・生活(添え書きと件数)。カードを押すと、そのサンプルが 1 本ずつの札で並ぶ(戻る で最初の画面へ)。サンプルが 7 本以上の種類は小見出しで分ける(教育:授業・大学の講義・学会発表・校内研修。授業は教科の順)。札は、サムネイル(その教材が何をするかがわかるステップ)・題名・場面(教科のある授業は「授業・理科」)・ラベル(本・声・ライブ・縦書き・画面と違う言語)・タグ(使っているパーツ。3 つまで、残りは「ほか n つ」)・再生。タグを押すと、そのパーツを使ったサンプルだけが並び(見出しに「流れ図を使ったサンプル(9 件)」、横に 絞り込みを外す)、?samples-part=<タグ> でも同じ絞り込みが開く(パーツの一覧から)。並び・種類・小見出し・教科は examples/index.json(egatari.org の src/gallery/lessons.json と同じ。tools/examples-sync.mjs --check --lessons が照らす)。再生 は同じサイトからファイル(examples/<名前>.ega.html)を読み、一覧の sha256(組み立てのときの値)と合うことを確かめてから、大きな窓の中でファイルそのもの(自分のプレーヤー)を sandbox の枠で再生する(プレビューと同じ決まり。このサイトが配ったサンプルだけなので、独自のコードがあってもたずねない)。下に AI への頼み方(そのサンプルを作るときに頼んだ文)とライセンス。ボタンは 3 つで、その下に 1 行「構成・テーマ・パーツを引き継ぎます。中身はあなたの題材で新しく作ります」(主のボタンの説明も兼ねる)。このサンプルを参考に作る(主のボタン。backlog #130)は新規作成…を、サンプルの使う場面(①)・テーマ(③)・パーツ(④ で印)を入れた形で開く。テーマは、新規作成で選べる同梱のテーマのときだけ引き継ぎ、ほかの名前なら default にする(kit/core/new-deck-pack.mjs の sampleTheme)。紹介のためのサンプルは Egatari のロゴを入れた教材の中だけのテーマを使うことがあり、それを利用者の教材に渡してはならないから。① と ③ は答えた 1 行に サンプルから の札(変えると消える)、④ のサンプルのパーツにも同じ札(推し直しで外さず、目安に収めるときも外す候補にしない)。サンプルのパーツは軽量の指示でも詳しく書く(中核の 4 つのほかの標準のパーツも)。目安を越えたら、まずサンプルが使わない中核の 4 つを短くし、次にサンプルが使わない専門のパーツを外す候補に出し(軽量の指示では、続けてサンプルが使わない標準のパーツも束が 1 つのときの決まった順に。中核の 4 つは外さない)、ほかに減らすものがないときだけサンプルのパーツを短くする(kit/core/llm-pack-assemble.mjs の fitSample。kit/core/new-deck-pack.mjs の samplePackFit から。メーターの下の 1 行が短くしたパーツを言う)。② だけが空で開き、タイトルの欄で字を待つ。上に「サンプル「…」から始めます。…② に、作る教材のことを書いてください。」。④ には サンプル「…」の構成(N 枚の見出しと要点)を指示に添える(既定で印。外すと指示が小さくなる):写す指示の「頼みたいこと」の後ろに、スライドごとの見出しと要点を、その構成と見せ方に倣うように添える(kit/core/sample-info.mjs の sampleStructureRequest。サンプルの全文は入れない。構成案ではないので、枚数は ② の長さ(なければ短く)に合わせて縮めさせる。2 回に分けて頼むかは ② の長さだけで決まる)。作成すると egatari.json の studio.newDeck に fromSample(サンプルの名前)。コマンドの node kit/llm-pack.mjs --from-sample <名前> [--request <文|ファイル>] [--plan free|paid] [--lang ja|en] は、② にタイトル(--request の 1 行目。残りは内容)を書いて ④ で写す指示とバイトまで同じものを出す(目安に収めた後=[候補を外す]を押した後。組み立ては kit/core/new-deck-pack.mjs を編集アプリと共有し、tools/test-app-from-sample.mjs が 4 つのサンプル × 軽量・詳細 × 言語で比べる)。コピーを開いて編集(小さく)は、選んだファイルとまったく同じように開く(取り込みの確かめも同じ。tmlr2026-calibration は独自のパーツがあるので動かす前に確かめ、最初の編集の前に編集の確認を出す)。閉じる。egatari.org のサンプルのページの「Studio でこのサンプルを参考に作る」は ?from-sample=<名前>(examples.json の名前。例:kokugo-kanbun)で同じ新規作成を開く(?lang= と一緒に使える。読んだら URL から引数を消す)。サンプルの一覧はそのバージョンのアプリに組み込んであり、何も読みに行かないので、サイトの根でも凍結した写し(/vX.Y.Z/)の中でもそのバージョンのサンプルで開き、オフライン版のエディタ(editor.html)でも開く。一覧にない名前は、ふつうの新規作成を開き、上に 1 行「サンプル「…」が見つかりません。新規作成を開きました」を出す。サンプルごとの examples/<名前>/sample.json(頼み方の文・使う場面・テーマ(引き継ぐのは新規作成で選べる同梱のものだけ)・パーツ・構成・本の有無・言語・権利)は、組み立てが確かめて一覧に入れる(tools/examples-portable.mjs。正しくなければ組まない)。オフライン版のエディタ(file:// の editor.html)には出ない
  2. 直す。 キーは開発サーバーと同じ(ツールの列にもボタンがある。右の板の見出しになるまでは、仮の群 編集 (e)・台本 (n)・コメント (c)・音声)

    キー すること
    e 編集モード。枠の出た要素をダブルクリックすると原稿(HTML と \( … \) の式)が開く。⌘/Ctrl+Enter で保存
    l 先のステップを薄く見せる(入/切。字幕と同じ選び):全部のステップを見せ、まだ来ていないステップを薄くする(--preview-opacity、既定 0.45)。今のステップに印は付けない。data-preview="none" を付けた答えは隠したまま。?mode=talk&preview=1 と同じ
    n 表示中のステップの台本の引き出し(話者、発言の追加・削除・並べ替え。語の読み方は下の 読み方…)
    Alt+クリック(Mac は ⌥ option+クリック) その要素について コメントを残す(comments.json)。押した点もピンとして残る
    m(編集モードの帯の「マーカー(m)」のボタン、編集中は「マーカー」(キーは m)になるスライドのツールバーのペンのボタンでも。d でも開く) マーカー(編集モードの間だけ):スライドに丸や矢印を描く。描き終えるとその印についてコメントの欄が横の板に開く。欄が開いている間は続けて描け(矢印と丸、いくつもの印。20 本まで)、どの線も同じコメントの印になる。「残す」で全部の印をコメントと一緒に残し(strokes)、「キャンセル」で全部捨てる
    c 未対応のコメントの一覧(番号付き)。開いている間、画面のステップのピンがスライドの上に出る。クリックでそのスライドとステップへ(ピンが光る)、「解決」で対応済み

    編集モードの帯・原稿の欄・台本の引き出し・コメントの欄と一覧は、どれも右の 1 つの板(プレビューはその横に縮む)にあり、板の上には橙の帯 編集中 — アプリ が付く。どれも教材ではなく編集アプリのページの一部。スライドの場所に見えるものは教材が描けるもの。信じてよいのはエディタ自身の板のツールだけ。 原稿の欄・コメントの欄を開いている間、プレビューはクリックを受けない。プレビューはダブルクリックや Alt+クリックの場所を知らせるだけで、原稿を読み・見せ・「保存」(か ⌘/Ctrl+Enter)を押したときに書くのは編集アプリ。キーはプレビューの上でも編集アプリの上でも効く

    読み方…(backlog #101)は、台本の引き出しの語や記号の読み方を付ける。語を選んで(カーソルを語の中に置くだけでもよい。そのときはカーソルの所の語。Word の「ルビ」と同じ)発言の下の 読み方… を押す。発言の下に小さな欄が開く:「θ」の読み方、読み方(その語の読み、なければ同じ台本のほかの所の読み、なければ辞書の読みが入り、どこから入れたかを 1 行で添える)、読み上げで聞く・AI 音声で聞く(読みだけを、この端末の読み上げか、この PC の AI 音声で。AI 音声は動く所でだけ出す。何も保存しない)、この台本のすべてに(ほかに n か所)、辞書に登録、付ける・キャンセル(Enter・Esc)。読みの付いた語なら 読み方を外す も。

    • 保存するのはいつも narration.md の読みの書き方 {θ|シータ}(format spec §8.3)。音声はどこで作っても台本だけで決まる。引き出しは {} を見せない:読みの付いた語は、その上に小さく読みを出し(ルビ)、押すと読み方の欄が開いて直せる・外せる。カーソルはその語を 1 字のように飛び越え、Backspace・Delete は語ごと消す。元に戻す・やり直し(⌘/Ctrl+Z、⌘/Ctrl+Shift+Z、Ctrl+Y)は欄が自分で持つ:打った字はまとめ、読み方を付ける・外すのはそれぞれ 1 つ。コピー・切り取りは原稿の文字({θ|シータ})をクリップボードに入れ、貼り付けは文字だけを入れて(発言は 1 行なので改行は詰める)読みをルビで見せる。手で {x|y} と打った所は、引き出しを開き直すまで打った形のまま。発言の中の Enter は何もしない(発言は 1 行。新しい発言は「+ 発言を足す」)。
    • 選べるのは 1 つの語か記号だけ(R-reading):空白・句読点・式(1-η・θとη)を含む、読みや {cue} などの印にかかる、25 字以上、2 つの発言にまたがる選び方は、何を選べばよいかを 1 行で添えて断る。Q*・x′・θ̂・N₀・L殻・t-SNE は 1 つの語。
    • この台本のすべてに は、その語の読みの付いていない所すべてに付ける:このステップの中はその場で(元に戻せる)、ほかのステップはこのステップを保存したときに(足もとに「保存すると、ほかのステップの 4 か所にも読み方を付けます」と出る。narration.md の控えは .cache/edits/)。語は丸ごと当てる:MySQL の中の SQL は変えず、漢字で終わる語は長い漢字の語の中では変えない(tts/yomi.py と同じ)。変えるのは発言の文だけで、見出し・@x- の行・注は触らない。
    • 辞書に登録 は、語と読みの組をこのブラウザ(localStorage。台本の言語ごと、1000 語まで)に覚える。日本語入力のユーザー辞書と同じ。あとで同じ語を選ぶと(どの教材でも)その読みが入る。付けるのは人なので、台本にはいつも読みが書かれる。辞書にある語はチェックが入った状態で開き、外して「付ける」と辞書から消える。データを残さないブラウザ(プライベートウィンドウ・サイトのデータを止めた設定・保存に失敗する場合)では、このチェックを押せなくし、わけを 1 行で出す(「このブラウザでは辞書を使えません…読み方はこのまま付けられます」)。ほかはそのまま使える。AI 音声の読み辞書(tts/yomi.yaml)とは別のもの:読み辞書は合成の直前に日本語だけに当て、誤読を測った語だけを載せる。ブラウザごとの語を合成のときに当てると、台本が同じでも PC ごとに音声が変わってしまう。
    • 開発サーバーの引き出しにも同じ欄がある(聞く 2 つのボタンはない)。

    編集モードと発表のツールは同時に使わない。 編集モードに入ると、レーザーポインター・ペン・消えるペンを切り(書いた線は見えたまま残り、その上には描けない)、自動再生と音声を止め、スライド一覧・黒い画面・キーの一覧(?)・全画面・打ちかけのページ番号を閉じる。授業と字幕はそのまま。編集している間は、ツールバーのボタン(自動再生・レーザーポインター・消えるペン・色・消す・一覧・全画面)を隠し、そのキー(x v Shift+d Backspace o a b f)は効かない。ペンのボタンだけは同じ絵のまま マーカー という名前で残り、そのボタンとペンのキー d は、ペンの代わりにマーカーを入り切りする(上の表)。発表者ビューでツールを選んでも切れる。編集モードを出ても、どれも元には戻さない。入力欄(原稿の欄や教材の中の入力欄)で打ったキーは、いつも字として入り、ツールやスライドの操作にはならない。今のモードは下の帯の右端に出し(編集中・発表のツール:ペン・表示)、読み上げソフトにも知らせる。スライドには重ねない

    開発サーバーと同じく、プレビューを組んだ後にファイルが変わっていれば(原稿の hash・台本のバージョンが合わなければ)保存しない。読み込み直してからもう一度

    Esc で、開いている窓を上のものから 1 つずつ閉じる:書いている途中の原稿の欄・コメントの欄、次に音声の板・録音モード・台本の引き出し・コメントの一覧・横の板(品質チェック・ファイルの情報・使い方)のうち後に開いたもの。Shift+Esc で全部を閉じる。台本の引き出しに保存していない入力があれば先に聞く。確かめの窓と一覧は、これまでどおり Esc で閉じる

    保存の場所。 下の帯の左端に、今どこに保存されているかをいつも出す(札の説明に詳しく)。作業フォルダは「作業フォルダ「…」に保存済み」:各欄の「保存」と録音・取り込み・TTS がその場でフォルダに書くので、ファイル ▾ →「保存」 は押してもわけを言うだけ。Egatari ファイルにするには ファイル ▾ →「名前を付けて保存…」(編集可・.ega.html)。Egatari ファイルは「「…」に保存済み」(「保存」で上書き)、ブラウザが上書きできないときは「「…」を開いています(保存はダウンロードに)」(「保存」のたびに新しいファイルがダウンロードされる)、メモリの上にだけ変更があるときは 保存していない変更があります(タブを閉じると録音も含めて消える)、メモリの上にだけある教材(チャットの AI の出力を貼り付けた・スライドのファイルだけを開いた)は まだファイルに保存していません

  3. AI のコーディングツールと一緒に。 AI のコーディングツール(やほかのエディタ)がフォルダを変える間も開いたままでよい。約 1.5 秒ごとにファイルを見て、変わったら組み直し、同じスライド・ステップのままプレビューを読み込み直す。原稿の欄や台本の引き出しで入力中のものは、プレビューを読み込み直しても残る(編集アプリのページにある)。その間に同じ要素やステップが変わっていれば、保存は断る。組み立てに失敗したら、直るまでプレビューの上にエラーを出す

  4. ツールの列。 ファイル ▾・スライド ▾・品質チェック・プレビュー ▾ の 4 つ(と仮の板の群、使い方の ?)。幅 1280 px 以上なら 1 行に収まり、それより狭いと折り返す。一覧は ARIA のメニューボタンの形:ボタンの Enter・Space・↓ で開いて最初の項目へ、↑ で最後の項目へ。一覧の中は ↑↓ で移り(端で回る)、Home・End で端へ、字でその字で始まる項目へ、→ か Enter で エクスポート ▸ を開き、← か Esc で閉じる。Esc で一覧を閉じてボタンに戻り、Tab や外を押しても閉じる。一覧や確かめの窓が開いている間は、キーをプレビューに送らない(e・n・c の切り替えにもならない)

    一覧 項目
    ファイル ▾ 新規作成…・開く…・保存(Egatari ファイル。作業フォルダでは、編集するたびに保存されることを言う)・名前を付けて保存…(Egatari ファイル:別のファイルに。新しい教材としても保存できる。作業フォルダ:Egatari ファイル(編集可)に)・エクスポート ▸(参加者用(再生専用)…・動画(MP4)にする…・LMS 用(SCORM)…・スライドを印刷・本を印刷(本のない教材は 台本を印刷)、Egatari ファイルでは 作業フォルダにエクスポート… も)・ファイルの情報…・フォルダで作業する…
    スライド ▾ スライドの挿入…(テンプレートから・チャットの AI に書いてもらう)・複製・削除(スライド一覧で選んだスライド。一覧を閉じていればプレビューに出ているスライド)・修正…・テーマを変更…
    品質チェック ブラウザ版の品質チェック。組み立てとプレビューの読み込みのたびに約 1 秒後に自分でかかり(組み立ての途中はかけない)、札にそのエラーと警告の数を出す(エラーがあればエラーの色)。組み立てと保存の警告は板の先頭に一覧で出る
    プレビュー ▾ 表示のモードを 1 つ選ぶ:スライドショーで確かめる (f)(全画面にもする)・動画で確かめる(プレビューをそのモードで読み込み直す)・先のステップを薄く見せる (l)(スライドショーの入/切)・発表者ビューで確かめる (p)・「発表するときは、保存した .ega.html をブラウザで開きます」の添え書き

    ファイル ▾ の後ろの ● は、Egatari ファイルに保存していない変更があること

    • 使い方(?) にも AI のスキルをダウンロード がある。新規作成… と同じ言語・バージョンを渡し、同じ添え書きを付ける
    • 品質チェック:ブラウザ版の品質チェック。npm run check の検査を、プレビューの中と原稿の上で、同じコードと言葉で行う:体裁(はみ出しと縦組みの限り・箱で切れる字やスライドの外に出る字・図の中の字の大きさ・タイトルと結論の字数。同じ kit/core/layout-scan.mjs)、残った $…$ など組まれていない数式、です・ます と句読点、台本の抜け、式を読む台本、スライドへのリンク、強調の目印、モーフ、画像と図の名前、スライドの id と鍵、1.0 の語彙にない書き方、パレットのコントラスト。結果をクリックでそのスライドへ。画面を撮る検査(パーツの再現性・本文の釣り合い)・手元のファイルを見る検査・情報の一覧はコマンド版だけ(リファレンス:編集アプリでは)。画面の大きさが違うので、数値がコマンド版の品質チェックとわずかに違うことがある
    • 組み立てた HTML(out/deck.html)は、編集アプリからはエクスポートしない。コマンドの node kit/build.mjs で組む
    • ファイル ▾ →「名前を付けて保存…」(作業フォルダ):原稿と音声を中に持つ Egatari ファイル(編集可・.ega.html)にして、人に渡せる形で保存する。作業フォルダはそのまま
    • ファイル ▾ → エクスポート ▸ →「参加者用(再生専用)…」:原稿を持たない Egatari ファイル(形式の §3.7。--play-only と同じ)。どのブラウザでも再生でき、編集はできない。Egatari ファイルを開いているときは保存したものから作る(保存していない変更があれば、先に「保存」)。作業フォルダはそのフォルダから。窓に ライブ(質問・投票)を付ける のチェックがある。ファイルの名前は教材の題名に .play.ega.html
    • ファイル ▾ → エクスポート ▸ →「動画(MP4)にする…」:動画はエディタの中では作らず、Google Colab(CPU で動く動画のノート)で作る。窓は「この教材のファイル(<名前>.ega.html)を Colab に上げてください」と案内し、Colab を開く で新しいタブに開く。保存していない変更があればボタンは 保存して Colab を開く、作業フォルダでまだエクスポートしていなければ Egatari ファイルに保存して Colab を開く(どちらも保存・エクスポートの後に開く)。音声の更新が必要なステップがあれば、その数を 1 行で知らせる(動画もその音声のまま)。Egatari ファイルのまま配れば、動画にしなくても再生できる。ノートの使い方は 動画にする
    • ファイル ▾ → エクスポート ▸ →「LMS 用(SCORM)…」:SCORM 1.2 のパッケージ(.scorm.zip。--scorm と同じ)。再生専用の写しを index.html として、imsmanifest.xml と一緒に入れたもので、Moodle などの LMS に SCORM パッケージとして追加する。窓に、LMS に記録されるものと、いつ「完了」になるか(metadata.completion を平たい言葉で)が出る。ダウンロード で zip を保存する。Egatari ファイルに保存していない変更があれば、再生専用と同じく先に「保存」。LMS で進み具合を取る(SCORM)
    • 同じ窓の ライブ(質問・投票)を付ける:印を付けると同じ窓にライブの設定が出て、エクスポート… でライブ(授業中の質問と投票。形式の拡張 live、下書き)を付けた Egatari ファイル(再生専用)。ライブ ID と参加コードを窓で作って、ホストがホストのページに 1 回だけ貼る 1 本の文字列をコピーし(ホストのページでコピーした設定を貼る前からの方法も、たたんで残す)、参加者からの質問を受け付けるかとステップごとの投票を決め(投票は「4 枚目『XML の壁』・ステップ 1」のような表示名で出し、スライドの id とステップは吹き出しに)、ホストのページに渡す投票の設定(表示名入り)をコピーしてエクスポートする。まだ足りないものは エクスポートの前に直すこと に画面の言葉で出て、直すまで エクスポート… は窓を閉じずに最初の 1 つを知らせる。ファイルの名前には、題名の側にライブの始まる日の印を付ける(例:題名(ライブ 10-30).play.ega.html。英語の画面では Title (live 10-30).play.ega.html)。拡張子は変えない。授業の後の結果の取り込みは ファイル ▾ →「ファイルの情報…」 の添付で。編集アプリ自身はどこにもつながらない。教材に残すのは参加コードのない設定だけ。ライブを参照
    • ファイル ▾ → エクスポート ▸ →「スライドを印刷」:スライドをブラウザの印刷にかける(tools/pdf.mjs と同じく、各スライドの最終状態を 1 ページずつ。「PDF に保存」を選ぶ。章の扉を含め、スライドの背景は「背景のグラフィック」を入れなくても画面と同じ色で刷られる)。「本を印刷」「台本を印刷」は本を見る
    • プレビュー ▾ →「発表者ビューで確かめる」(教材の p でも):今の画面(先のステップを薄く見せる。発表者にだけ)・次のスライド(すべてのステップを出した姿)・台本(カンペ)・経過時間・描くツールの窓。編集アプリの窓のプレビューを操作する。音声を鳴らすのもそのプレビューで、発表者ビューで自動再生を始めても(a かそのボタン)、台本の音声は編集アプリの窓で 1 回だけ鳴る。プレビューでもう一度 p を押すと閉じる。発表者ビューでは、Esc(描くツールを使っていないとき)・p・発表者ビューを閉じる(p) で窓を閉じ、編集アプリの窓にフォーカスを返す。発表者の窓が全画面のときは、全画面をやめるだけ。窓にフォーカスがない間は、大きな「ここを押すと操作できます」の覆いが最初のクリックを受ける。プロジェクターで使う順番は、先に発表者ビューを開き、それから聴き手の窓(編集アプリの スライドショーで確かめる)をプロジェクターの画面で全画面にする
    • 発表者ビューから抜けられないとき:画面を覆ったままキーが効かないときは、Mac は cmd+Tab で編集アプリの窓に戻って p(Windows は Alt+Tab。Windows ではまだ確かめていない)。キーの一覧(?)にも同じことを書いてある
    • プレビュー ▾ →「スライドショーで確かめる」(f でも):プレビューを画面いっぱいにして、投影の見え方を確かめる。「動画で確かめる」で、もう 1 つの表示のモード(動画)の見え方を確かめる。「先のステップを薄く見せる」(l でも)は、スライドショーで先のステップを薄く見せる入/切(字幕と同じ選び)。ここはプレビューで、発表するときは保存した .ega.html をブラウザで開く
    • キー:ツールの列・見出し・状態の行を押した後も、矢印・PageUp/PageDown・Home/End・b(黒い画面:プレビュー全体を真っ黒にする。隅に薄く「黒い画面中 — b か Esc で戻ります」が 2 秒出て、マウスを動かすとまた出る。もう一度 b・Esc・クリック・矢印・Space・PageUp/PageDown・Home/End で戻り、スライドは動かない)・a・f はスライドに届く(編集モードの間は b・a・f は効かない)。未保存の台本でプレビューが止まっている間にプレビューを押すかキーを押すと、そのわけを保存・元に戻すのボタンと一緒に出す
    • 発表者ビューの黒い画面:本体が黒い画面している間、発表者ビューには「黒い画面中」と出て、そこで b を押しても本体を黒い画面・解除できる。黒い画面の間に発表者ビューで矢印・Space・PageUp/PageDown を押すと、黒い画面を終えるだけでスライドは動かない

発表者ビューでの参加者の入力

発表者ビューの「今の画面」で、m-predict の数を入力したり、タイマーの +1 分/−1 分 ボタンで時間を変えたりできます。本体と「今の画面」には同じ数と延長時間が表示され、本体での変更も発表者ビューに映ります。「次」の画面は作者の値を表示します。入力欄や操作の中のキーはそのパーツが使うので、数を入力してもスライドは進みません。タイマーのボタンをマウスで押した後は、Space でいつもどおり進められます。

数と延長時間は、同じスライド内のステップを進めても戻しても残ります。別のスライドから入ったときや、スライドへ跳んだとき(今いるスライドへのジャンプも含む)に作者の値へ戻ります。動画モードでは参加者の入力を受け付けず、台本・作者の指定した時間・タイムライン・動画・印刷の出力は変わりません。

スライド一覧(足す・複製・削除・並べ替え)

プレビューの左の端の スライド一覧 のつまみで、そこに一覧を開きます(✕ で閉じます)。スライドを順に、そのスライドの最後のステップのサムネイルと見出しで並べます。サムネイルは教材自身が、一覧の後ろの sandbox の枠に描きます(プレビューと同じ決まり。クリックを受けず、読み上げソフトにも出しません)。一覧・ボタン・確かめの窓は編集アプリのページのものです。開いていたかどうかはこのブラウザが覚えます。

  • 選ぶ:スライドを押すか、一覧で ↑ ↓ Home End。プレビューもそのスライドへ動きます。プレビューを動かすと、選択も付いてきます
  • スライドの挿入 ▾:選んだスライドの後ろに、テンプレートからか、チャットの AI に書いてもらって(チャットの AI に書いてもらう…。下の「スライドの挿入…」)新しいスライドを入れます。テンプレートは見出しと本文・2 列・図(点線の枠と図の説明)・章の扉(sec)・引用(box と cite の行)。id(s-xxxxxx。文書の中で使っていないもの)はエディタが付け、台本に ## 見出し {#id} の節を、前のスライドの節の後ろに、ステップごとの仮の 1 行と一緒に足します。仮の行は印 ✎ で始まり、テンプレートの字も決まっている(どちらも kit/core/template-text.mjs に 1 か所で書く)ので、直し忘れが見つかります。品質チェック(ここと npm run check)は警告にし(narrPlaceholder・templateText)、TTS の前(音声の板・Colab の tts-job.json・tts/synth.py)と Egatari ファイルをエクスポートする前(編集可・再生専用・ライブ。--portable・--play-only)に、エディタかコマンドが先に一覧を出します。続けることもできます(このまま作る・このままエクスポート)。直さないと、TTS が仮の文を読み上げ、字幕と読める層にも入ります
  • 複製:選んだスライドの写しを、新しい id ですぐ後ろに入れます。台本は写し、音声は写しません。写しのステップは、録るか作るまで一覧に 音声が要るステップ N と出ます
  • 削除(一覧で Delete キーでも):先に確かめます。窓はスライドの名前と、一緒に消えるもの(台本の節、audio/manifest.json の音声の記録とそのファイル(ほかのステップが使っているファイルは残す)、録ってまだ使っていない音声)を出します。音声の更新が必要なときの決まり(形式 §5.4)と同じく、黙って作り直したり消したりはしません
  • 並べ替え:一覧の中でドラッグするか、↑ / ↓ を押すか、一覧で Alt+↑ / Alt+↓。id は変わらず、台本の節も同じ順に並べ替え、音声は鍵で付いたままです
  • 元に戻す(一覧の上):直前のスライドの操作を取り消します。原稿・台本・音声の記録と消した音声のファイルを、エディタが覚えている前の中身で書き戻し、使っていない録音も音声の板に戻します。次のスライドの操作まで、Egatari ファイルを保存するまで、別の教材を開くまで使えます。その間に 3 つのファイルのどれかが変わっていれば(編集・外のツール)戻しません。どの操作でも、書き換える前のファイルは .cache/edits/ に控えます

操作のたびに、deck.html・narration.md・audio/manifest.json(変わったものだけ)を書き、組み直し、そのスライドを見せて品質チェックを出します。読み上げソフトには何をしたかを知らせます(live region)。Egatari ファイルでは変更はメモリの上にあり、次の 保存 でファイルを組み直します(段 B)。組み直さない保存ではスライドの並びを変えられないためです(形式 §7.2。エディタの段 A の保存は source-changed で断り、組み直してよいかを聞きます)。台本だけを直せる Egatari ファイル(実行系かパーツライブラリのバージョンが違う)と読むだけの Egatari ファイルでは使えません。スライドの id が重なっている教材は、先に直す必要があります(理由を出します)。id のないスライドは見出しから決めた名前のままで、足したスライドと写したスライドには必ず id を付けます

台本の音声(音声の板)

ツールの列の 音声 は、同じ信頼する横の板に欄を開く。フォルダでも、開いた Egatari ファイルでも同じに使える。上から 3 つの区画(設計はプロジェクトの覚え書きの handoff/audio-flow-2026-10-25.md。backlog #82・#83・#85・#89):

  • A. この教材の音声(いつも上):状態の 1 行と、ボタンは多くて 1 つ。1 行は、音声のあるステップの数(「まだ音声がありません(8 ステップ)」「8 ステップのうち 5 ステップに音声があります」「8 ステップすべてに音声があります」)、台本が変わって更新が必要なステップの数、声を変えた後も前の声のままの AI 音声のステップの数(inputHash は声を含まないので、AI 音声の記録の recipe.voice と今の声(Egatari ファイルの選択、なければ voice.json、なければ既定)を比べる。recipe.voice のない記録と dry-run の音声は数えない)。Egatari ファイルでは「保存するまでファイルには入っていません」を足す。ボタンは、音声のないステップがあれば 残りの音声を作る(n ステップ)、古いステップか前の声のステップだけなら 音声を更新(n ステップ)、Egatari ファイルで作るものがなければ 保存、音声が 1 つもなければ出さない(B を開いておく)。ボタンは、いちばん新しい音声のやり方で続ける:録音(その最初のステップで録音モードを開く)・クラウド(そのステップの台本を書き出す。手順 1)・この PC(そのステップを作る)。いちばん新しい音声は、この画面で最後に書いたステップの記録、なければ(manifest に時刻はないので)台本の順で最後の、やり方の分かる記録。やり方は記録から決める:kind: "recorded" は録音、kind: "tts" で recipe.processing に +colab があればクラウド、ほかの AI 音声はこの PC。取り込んだ音声はやり方に数えない。やり方はどこにも覚えない(前の egatari.json の studio.audioMethod は読まず、書かない)。やり方が分からない・この端末で使えなければ、ボタンは B を開く。
  • B. 音声をどう付けますか(初めは開き、全部のステップに音声がそろうとたたむ):答えはこの順:自分の声で録音する(録音モードを開く (r)。音声のない最初のステップから)、AI 音声をクラウドで作る(Google Colab)、AI 音声をこの PC で作る(このブラウザで作れるとき、つまり配信版か配った編集アプリで WebGPU があるときだけ出す。初めてのときにモデルを取得すると添え、この PC で作る(n ステップ) を出す。スマートフォン・タブレット・メモリの少ない端末では、出すが選べず、「この端末では AI 音声を作れません。クラウド(Google Colab)で作ってください」と 1 行添える)。開いたときの答えは、いちばん新しい音声のやり方(録音 → 録音、Colab の AI 音声 → クラウド、この PC の AI 音声 → この PC。この端末で作れなければクラウド)。音声がなければ録音。この画面で選んだ答えは、作業場所を替えるまで覚える。AI 音声のやり方を選ぶと、その中の 1 行目に 声 と ▶ 試聴(1 つ、掛け合いなら 説明する人の声・質問する人の声。新規作成の ② と同じ言葉)を出す:クラウドは手順 1 の上、この PC はボタンの上。録音を選んでいる間は出さない。
  • C. このステップ(画面に出ているステップ。スライドに付いていき、音声を作って書いている間はそのステップのままで、スライドが動いたらそう知らせる):見出し「スライド 3「…」・ステップ 2」、今の音声(「AI 音声 · 5.2 秒」「録音 · 4.8 秒 · 更新が必要」「まだ音声がありません」)、ボタン ▶ 聞く・読み上げで聞く・● 録音 (r)・ファイルから取り込む…・↶ 前に戻す・(この PC で作れるときだけ)この PC で作り直す、そのステップの台本(読むだけ。直すのは「台本」の板)。{cue}・{mark} があれば「動きに合わせる所が n 個あります(録音では C で置けます)」。

細かいこと:

  • 今の音声。 audio/manifest.json にあるステップの音声を再生する(フォルダやファイルから編集アプリのページで読む。プレビューからは受け取らない)。▶ 聞く で鳴らし、種類(録音・AI 音声・取り込み)、長さ、出どころ(TTS ならエンジン・モデル・声・シード)も出す。更新が必要 の印は、音声を作った後に台本が変わったか、どの台本から作ったか分からないこと(format spec §5.4:inputHash が null か今の台本と違う。inputHash のない前の tts/synth.py の manifest では、TTS の控え audio/seg_<digest>.json で比べる)。古いステップは、品質チェック(組み立ての警告)と npm run check にも出る。読み上げるためのステップの台本も出す:欄は台本の長さに合わせて伸び(板の半分ほどまで)、右下の角で大きさを変えられる。掛け合いの教材では各ターンに Expert か Novice の印を付ける(台本の書き方。声の欄は説明する人・質問する人)。↶ 前に戻す で、最後に作った音声の前にそのステップが持っていた音声に戻す(下を参照)。
  • 録音。 ● 録音 (r)(と B の 録音モードを開く (r)。音声のない最初のステップで)は、板のステップで録音モードを開く(録り方は 1 つ)。1 段だけなら Space で録り、話して、もう一度 Space、そして Esc:板に戻り、そのステップの新しい音声を見せる(板は録音モードの裏で開いたまま)。録音モードは台本を大きく出してその横にメーターを置き、録った音声はすぐにそのステップの音声にする。ここの ↶ 前に戻す でそのステップの前の音声へ順に戻れる(音声のファイルは消さない)。
  • ファイルから取り込む… は WAV・MP3・M4A・Ogg・WebM・FLAC を読む(64 MiB まで。大きさは読む前に確かめる)。録音と同じく、すぐに使う。
  • 声。 話す役ごとに 1 つ(1 人の語りなら 1 つ、掛け合いなら Expert と Novice)の欄で選ぶ:日本語の教材は bob と alice、英語の教材は Kokoro の声(米・英の 8 つ。残りは ほかの声 に畳む)。▶ 見本 で事前に作った短い見本を鳴らす(lab/voices/samples/。モデルは読み込まない)。作業フォルダでは選んだ声を voice.json に書く。Egatari ファイルではこの画面を開いている間だけ覚え(voice.json を変えると保存が組み直しになるため)、作った音声の記録には使った声の名前が残る。voice.json の声が、この PC で作る AI 音声にないときは、日本語も英語も同じに扱う:板がそう知らせ、TTS はその役の既定の声(bob・alice、または am_michael・af_heart)で作る。TTS の窓は知らない名前を断る(黙って別の声にしない)。
  • AI 音声をこの PC で作る(B。音声の要るステップをまとめて)と この PC で作り直す(C。そのステップ)は、ブラウザの中で AI 音声を作る:日本語の教材は Irodori-TTS 500M-v3(読み辞書 tts/yomi.yaml を tts/yomi.py と同じ規則で通す。声は voice.json のもの、既定は bob と alice。シード 0、ステップ 40。手元の mlx のサーバーもシード 0 だが、ブラウザは別の乱数の作り方で雑音を作るので、手元で作った音と波形は同じにならない)、ほかの言語は Kokoro-82M v1.0(bob → am_michael、alice → af_heart。voice.json に Kokoro の声の名前を書いてもよい)。{cue}・{mark} で分けた部分ごとに合成して後処理し、tts/synth.py と同じくつなぐ(ターンの間は 350 ms)ので、タイミングの時刻を持つ(sync: "auto")。初めてのときは何を取得するかを見せて確かめ(Irodori の fp16 で約 1.26 GB、fp16 のシェーダーのない GPU では 2.44 GB、Kokoro で約 330 MB。2 回目からはブラウザのキャッシュから読む)、編集アプリのサイトの小さな窓(lab/tts-helper.html)を開く。その窓がモデルを読み込み、この PC の GPU で合成する。窓に渡すのは読む文(読み辞書の後)と声の名前だけで、返ってくるのは音だけ。WebGPU が要り(パソコンの新しい Chrome か Edge)、オフライン版のエディタ(file://)では使えない。使えないときは「この PC」の答えもボタンも出さない(WebGPU の有無を前に出した言い方はしない)。作れる端末は、3 つがそろうとき:WebGPU がある、メモリが 8 GB 以上(navigator.deviceMemory。分かるブラウザだけ)、粗いポインタだけの小さな画面(画面の短い辺が 1024 px 以下。スマートフォン・タブレット)でない(app/tts-client.js の deviceLimit)。WebGPU があってもそろわない端末では、「この PC」の答えと この PC で作り直す を出すが押せず、わけを 1 行(ボタンは title)に書く。ほかの参照音声は tts/synth.py で。エンジンはスライドではなく台本の言語で決める:voice.json の "lang"、次に台本の文(日本語の教材でも発言がほとんど英語なら英語)、最後に <html lang>。出す声と読み辞書も同じ言語に従う。
  • 後処理 は tts/core.py と同じことをブラウザでする(kit/core/audio-core.mjs):モノラル、44.1 kHz、前後の無音を削る(20 ms の窓で −45 dB、50 ms 残す)、音量を −20 LUFS に(EBU R128 の積分ラウドネス、一律のゲイン。トゥルーピークが −1.5 dBTP を超えるので ffmpeg の loudnorm なら動的な処理に切り替えるところでは、ゲインを −1.5 dBTP で止める)。この違いがあるので、後処理の名前は別の trim-45-loud-20-cap-v1 にする。tools/test-audio-core.mjs が同じ入力で tts/core.py と長さと音量を比べる。
  • 文の前処理(kit/core/tts-normalize.mjs、規則 join-num-counter@1)は、各部分をエンジンに渡す直前に、ブラウザでも Colab のノートブック(colab/egatari_tts.py。同じ規則で、共有の例で突き合わせる)でもかける:算用数字(0-9・全角の0-9。1.5 のような小数も)と、その直後の日本語の文字(ひらがな・カタカナ・漢字)の間の空白(ASCII・全角)を取る。「1 歩」は「1歩」になり、「いちぽ」と読まれない。「3 分」「10 本」「2 つ」も詰める一方、「x 2 y」「Chapter 3 is」や数字の前の空白(「第 3 章」)はそのまま。助数詞の読みの表は持たない。これは「何を言うか」ではなく「どう合成するか」なので、ttsParts と inputHash は変えず、取り直しの recipe に "textNormalize": "join-num-counter@1" を書く(format spec §5.4)。この項目のない音声(これまでに作ったすべて)は古くならず、そのまま鳴り、音声の板も一覧にしない:読みがおかしいと聞こえたステップは この PC で作り直す かクラウドで作り直す。
  • 音声を書く(録音・取り込み・TTS の直後)ときは、取り直しを MP3(LAME、64 kbps の CBR、モノラル、44.1 kHz)にして、audio/<rec|tts|imp>_<hash>.mp3 と audio/manifest.json のステップの記録を書く。MP3 のエンコーダは編集アプリのコードに入れない:編集アプリのサイトの vendor/lame-wasm/ にある手を加えない lame-wasm のファイルで(LAME は LGPL。NOTICE を参照)、取り直しを MP3 にするときだけ読み込む。オフライン版のエディタは MP3 のエンコーダを持たず、WAV(16 bit。ファイルは大きい)で保存する。配信版でもエンコーダを読み込めなければ WAV。MP3 は 1105 標本(符号化の遅れ 576 と復号の遅れ 529、0.025057 秒)遅れて始まるので、それを startOffset に書き、実行系はその時刻から鳴らす(dur とタイミングの時刻がずれない)(前の manifest は .cache/edits/ に控え、前の音声のファイルは残す。tts/synth.py が古い wav を残すのと同じ)。記録には出どころを書く:kind(recorded・tts・imported)、inputHash(その取り直しを作ったときの台本)、TTS なら recipe(engine・model・voice・seed・dictionary = 読み辞書の SHA-256)、どの種類にも processing(trim-45-loud-20-cap-v1)、MP3 なら startOffset。機器の名前・元のファイル名など録った状況の記録は書かない。録音と取り込みにはタイミングの時刻がない(sync: "none"、cues は空)ので、タイミングに合わせた動きと強調は時間で進む。ステップの長さは新しい音声に合わせて決まる(manifest の dur。実行系がそこからタイムラインを計算する)。timeline.json の dur の上書きがあればそちらが勝ち、板がそれを知らせる。書けなかった取り直し(読むだけのファイル・編集の確認を断った)は まだ使っていない音声 に「この音声を使う」と一緒に残り、使うか別の教材を開くまでメモリの上にある。「前に戻す」のための前の記録もメモリの上だけに置く(ステップごとに 20 まで。別の教材を開くまで)。tts/synth.py は録音と取り込みを残す(--replace-recorded で替える)。
  • 読み上げで聞く(音声ファイルにはなりません)。 今のステップの台本を、この端末の読み上げの声で読む(format spec §5.6 のプレビュー)。読みの {x|y} は y を読み、{cue}・{mark:…} と @x- の行は読まない。日本語には AI 音声と同じ読み辞書(tts/yomi.yaml)と文の前処理(join-num-counter@1)を当てる(kit/core/read-aloud.mjs、プレーヤーと同じ)。選んだ語を読み上げで聞く は、台本の欄で選んだ語や文だけを読む(このステップの {x|y} の読みも当てる。読み方… の「読み上げで聞く」も同じ口 readAloud(text, lang)(app/read-aloud.js)を使う)。読んでいる間は「読み上げ中」と出て、「■ 止める」・別のステップへの移動・板を閉じると止まる。端末の中で動く声(localService)だけを使い、ネットワークの声は使わない。その言語の声が端末にないときは、そう知らせ、音声が要るなら AI 音声(クラウドの Google Colab か、この PC)で作るよう案内する。何も書かない:作業フォルダにも Egatari ファイルにも音声の記録にも残らず、音声ファイルにはならない。
  • Egatari ファイル: 新しい音声でメモリの上のフォルダが変わり、保存 で組み直さずに書く(段 A:そのステップの音声の記録・実行系の音声の項目・中の音声だけが変わる)。
  • AI 合成音声。 どこかのステップの音声を TTS で作った(kind: "tts")ときは、プレーヤーのツールバーに小さな札「AI 音声」(説明は「音声は AI で合成したものです」)、キーの一覧(?)に同じ文、そのステップの発表者ビューに 1 行が出る。スライドの上や字幕には出さない。取り込んだ音声(kind: "imported")は、キーの一覧と発表者ビューに「音声の作り方は記録されていません」と出し、録音には印を付けない。Egatari ファイル・再生専用の派生を含むどの出力も、種類を deck-audio の kind に入れる(format spec §5.2・§7.3)。

クラウドで作る(Google Colab)

**確認済み:2026-10-23、CPU(講習で、Irodori)。2026-10-24、T4 で固定したバージョン(cuda13 の組):Irodori 23 ステップを 42 秒、Kokoro 59 ステップを 30 秒。2026-10-25、持ち主の手での計測(10 ステップ・話者 1 人。日本語 209 字・英語 518 字):T4 の日本語(Irodori)は読み込み 34 秒・合成 19 秒、T4 の英語(Kokoro)は読み込み 4 秒・合成 4 秒、CPU の英語は読み込み 7 秒・合成 33 秒(1 ステップ約 3 秒で十分使える)、CPU の日本語は読み込み 1 分・1 ステップ約 60 秒(steps=40)。1 ステップだけの手での計測は steps=40 で 90 秒、steps=16 で 52.5 秒(このバージョンより前の、fp16 の重みで参照音声を毎回符号化していたとき)**

B の AI 音声をクラウドで作る(Google Colab) は、WebGPU のない PC(学校や職場の PC の多く)やスマートフォンでも使える。Google Colab(自分の Google アカウント)で同じ声の音声を作り、動きに合わせる所(cue)の時刻つきで取り込む。板には番号の付いた 3 つの手順を出す(新規作成の段と同じ見た目:左の線、番号の札「手順 1」と見出し、ボタン 1 つ)。どの手順もいつでも押せ、この画面で済んだ手順には ✓ が付く(台本を書き出した → 手順 1、ZIP ファイルを取り込んだ → 手順 2 と 3。Colab を開いただけでは付けない)。

  1. 手順 1 台本を書き出す(台本を書き出す。「音声の要る N ステップの台本を 1 つのファイルにします」)。音声の要るステップ(音声がない・古い・前の声で作った)を書き出す。このブラウザで初めてのときだけ確かめる(「台本を Google Colab に渡します」:台本の文は Google の環境で処理されるので、共有してよい文だけにする。スライドやほかのファイルは渡さない。書き出す/キャンセル。このブラウザの localStorage に覚える)。モデルは Hugging Face から取る。ダウンロードする tts-job.json には、読み上げる文(読み辞書を通した後で、{cue} / {mark} で区切ったもの)・声の名前・各ステップの inputHash・docId・目標の recipe だけが入る。

  2. 手順 2 Colab で実行する(Colab を開く)で公式のノートブック colab/egatari-tts.ipynb を新しいタブで開く(リンクはバージョンのタグに固定)。その下に、Colab での手順を a〜d の別の並びで書く(全体の手順と紛れないように。文はノートブックの冒頭と同じ kit/core/colab-core.mjs の COLAB_STEPS で、c だけ板の手順の番号に合わせる):a. 右上の「接続」を押す(ノートブックは T4 GPU に設定済み)。つながらないと知らせが出たら「ランタイム」→「ランタイムのタイプを変更」で「CPU」を選んでから、もう一度「接続」(CPU でも作れるが時間がかかる)b. 「ランタイム」→「すべてのセルを実行」c. ファイルを選ぶ画面で、手順 1 のファイルを選ぶ d. 終わると音声の ZIP ファイルがダウンロードされる。時間の目安は T4 のものだけ(「T4 で 10 ステップ 20 秒ほど」)。CPU の目安は実測してから足す。日本語は Irodori-TTS 500M-v3(ONNX、バージョンを固定)、ほかの言語は Kokoro-82M。セル 1 が見つけた CUDA のライブラリで、固定したバージョンの組を 2 つから選ぶ。libcublasLt.so.13 があれば cuda13(onnxruntime-node 1.30.0・@huggingface/transformers 4.3.1・onnxruntime-gpu 1.31.0)、libcublasLt.so.12 だけなら cuda12(onnxruntime-node 1.24.3・@huggingface/transformers 4.2.0・onnxruntime-gpu 1.26.0)、GPU がなければ cuda13 で、選んだ組を env: CUDA libraries … → pin set … の行に出す。2 つの組の音はほぼ同じだがビット単位では一致しないので、別の Colab のイメージで作り直すと、ステップの音が少し変わることがある。それでも GPU を使えないときは、CPU に切り替えたことと理由を 1 行出して、遅くなるが続ける。セル 1 の最初の env: の行(Python・Node・GPU と CUDA・見つかった CUDA のライブラリ・選んだ組とバージョン)とセル 3 の providers in use の行で、どちらで動いたかがわかる。不具合を知らせるときはこれらの行も添える(バージョンは tools/make-colab-notebook.mjs の COLAB_PINS)。Node の常駐ワーカー(colab/irodori_node.mjs)を 1 度だけ起動し、6 つの ONNX セッションとトークナイザは 1 度だけ読み込んで、部分ごとに合成する(部分ごとに seed と steps が同じなので、各部分の音は決まる)。モデルは local_dir で実ファイルとして落とし(Hugging Face のキャッシュの symlink は onnxruntime-node が断る)、clone・インストール・Node が失敗したときは、その出力の最後の 30 行を出して止まる。エディタと同じ後処理(trim-45-loud-20-cap-v1)を部分ごとにかけ、ターンの間に 0.35 秒の無音を入れ、cue の時刻は実際の音から測る。GPU がないとき(または CPU に切り替えたとき)、日本語は CPU 用の設定で合成する:diffusion の steps を減らし(colab/egatari_tts.py の IRODORI_CPU_STEPS。16、GPU は 40)、重みは fp32(onnx/。CPU では fp16 より速い)。セル 1 の env: の行がそう書く(… · CPU(Irodori の steps=16))。ワーカーは参照音声を声ごとに 1 度だけ符号化して使い回す(音は同じで、部分ごとの時間が減る)。セル 4 は自分の時計(合成そのものを囲む単調な時計)で時間を出す:進み具合の行ごとにそのステップの時間と始めからの時間(3/10 s-intro:2 (+41.2 s, total 2:15))、最後に全体の時間。長い実行では Colab のセルの時間表示が合わないことがあるので、こちらを見る。セル 3 の PROFILE にチェックを入れると、部分ごとに段の時間(文・参照音声・diffusion の steps・復号・後処理)を出す。核は colab/egatari_tts.py で、モデルなしでローカルの dry-run ができる(uv run --no-project --with numpy --with scipy python colab/egatari_tts.py tts-job.json out.zip --dry-run)。ノートブックは tools/make-colab-notebook.mjs が作る(npm run gen)。 自分の参照音声(省略可・日本語の Irodori のみ)。 ノートブックの省略可のセルで UPLOAD にチェックを入れて 3〜30 秒の WAV か MP3(話す人は 1 人)を選ぶか、DRIVE_PATH に Drive のパスを書く。ノートブックは、読めること・3〜30 秒であること・無音でないことを確かめ、同梱の参照音声と同じ 48 kHz のモノラルに直して、ジョブのすべての話者の Irodori の参照音声にする。だめなファイルは理由つきのメッセージで止まる。セルに触れなければ、これまでの声をこれまでどおり使う。出力の形式と inputHash は変わらず、Kokoro は使わない。使ってよい声(自分の声、または本人の許可のある声)だけにすること。ファイルは自分の Colab のランタイムの中にあり、ほかへは送られない(ランタイムが片づけられると消える)。

  3. 手順 3 できた音声を取り込む(できた音声を取り込む…。「手順 2 でダウンロードした ZIP ファイルを選びます」)で、ダウンロードした ZIP ファイル(records.json と audio/*.wav)を、ふつうのファイルの選択で選んで読む(フォルダを選ぶ仕組みは使わないので、File System Access API のない Safari などでも使える)。エディタは各ステップの inputHash を今の台本から計算し直して照合する(ノートブックの値は信用しない)。合うステップは、ほかの音声と同じように書く(MP3・kind: "tts"・sync: "auto" と測った cues・recipe・inputHash・startOffset。仕様 §5.3 の引き取りの規則)。作業フォルダはその場で、Egatari ファイルはメモリの上に書いて「保存」(段 A)。書き出した後に台本が変わったステップは使わない:板は「6 ステップに AI 音声を付けました。2 ステップは、書き出した後に台本が変わっているので使っていません」と出し、音声を更新(2 ステップ) でそのステップをクラウドで続ける(更新が必要なステップを別に並べる一覧はもうない)。今の台本にないステップ・記録が不備なもの(パス・cue の数が合わない)・音声がないものは、理由を出してスキップする。別の教材のための ZIP ファイル(docId が違う)は拒否する(「この ZIP ファイルには、この教材の音声が入っていません…」。台本に題があれば元の教材の題を添える)。読み辞書や後処理のバージョンが違うときは知らせるだけ。各記録の recipe には runtime も入る。バージョンの組と、CPU への切り替えのあとで実際に使った実行プロバイダ(cuda12/cuda・cuda13/cpu。組がわからなければ none/…、プロバイダを確かめられなければ cuda?)で、2 つの組や GPU と CPU で音が少し違うために記録する。取り込みは音声の manifest の recipe にそのまま残し、形の合わない値は落とす。inputHash には入らないので、これでステップが古くなることはない。日本語でノートブックが書く diffusionSteps(Irodori の diffusion の steps)と precision(fp16 か fp32)も同じ扱い。

ZIP ファイルはダウンロード物なので信頼しない。バイトとして読み、割り当てる前に上限を課す(ZIP ファイル 512 MiB・音声 1 つ 64 MiB・records.json 4 MiB・ステップは 400 まで。zip64・暗号化・知らない圧縮は断り、CRC-32 を確かめる)。読むのは records.json と audio/<名前>.wav だけ(名前を確かめる)。音声は本物の WAV として復号でき、長さが記録と合うこと。ZIP ファイルの中身を HTML やコードとして扱うことはない(仕様 §11)。

tts-job.json と records.json(egatari: "tts-job" / "tts-records"、v: 1)はエディタとノートブックの間のこの製品の取り決めで、形式の仕様の物ではない。tts-job.json の任意の項目 title(教材の題。120 字まで)は records.json に写され、取り込みを断るときに、元の教材の名前を言うためだけに使う。records.json の各ステップの記録は仕様 §5.2 の音声の記録の形(file・dur・cues・kind・sync・inputHash・recipe)。試験は tools/test-colab.mjs(ZIP ファイルの読み取り・job・取り込みの計画・敵対の ZIP ファイル・ノートブック、uv があれば Python の核の dry-run)と tools/test-colab-app.mjs(tools/colab-fixture.mjs で作った ZIP ファイルでの編集アプリの往復。フォルダと Egatari ファイル)。

録音モード(キーボードだけで録る)

音を宣言する、または events(k) を持つパーツを含む教材では、スライドのツールバーに 効果音を消す が出ます。Tab で選び、Enter または Space で切り替えます。押された状態ではパーツの音がすべて消えます。端末に保存できる場合は、ブラウザがこの選択を覚えます。スライドショーでステップを前へ進めると(手で送っても再生でも)、参加者の操作の後から音が鳴ります。画面の内容はそのまま見られます。録音モードでは開いている間だけパーツの音を止め、閉じると保存した選択に戻します。

r(編集アプリのページでも教材の上でも)か、音声の板の「● 録音 (r)」で、台本を全部キーボードだけで録るための広い画面を開きます。ステップの台本を大きく出し(掛け合いは Expert / Novice の札。長い台本は中でスクロール)、プレビューは横の細い舞台のサムネイルになって録音の位置に付いてくるので、図を見ながら読めます。音声の板と同じく信頼する編集の画面の中にあり、マイク・録音・後処理・書き込みはプレビューでは一切行いません(教材からの知らせで開けるのはこの画面だけで、録音は始まりません)。開いている間、プレビューは inert です。画面に出ているステップ(音声の板からなら板のステップ)から始まり、台本のあるステップを順に録ります。録り方はこれだけです:音声の板の「● 録音 (r)」はこの画面を開き、板は裏で開いたままなので、Esc で新しい音声の出た板に戻ります。

続けて録るは初めはオンで、この端末に覚えます。ステップを替えてもテイクや効果音は鳴りません。

キー 動作
Space 録音の開始/停止。止めると後処理(音声の板と同じ:前後の無音を削る・−20 LUFS・モノラル 44.1 kHz)をして、すぐそのステップの音声にします(kind recorded。これまでどおり「前に戻す」で戻せます)。ステップは替わりません。開いた直後(とステップを移った直後)は、そのステップを読み終えるまで Space のボタンが 準備中… になります。その間に押した Space は覚えておき、準備ができしだい録り始めます(2 回押しても 1 回)
Enter 録音中なら止めて採用し、次のステップへ。録った後(または音声のあるステップ)なら次のステップへ。続けて録るがオンなら、前のテイクを整えて保存した後、次のステップに音声がない・音声の更新が必要なときだけ録音を始めます。今の台本に合う音声があれば待機します。オフなら次のステップは毎回待機します。最後のステップでは、Enter でテイクを採用して止まります。音声のないステップでは、進まずにそう知らせます
Backspace 取り直し。録音中は今のテイクを捨てます(何も書きません)。録った後は、そのテイクを「前に戻す」で外して前の音声に戻し、次の Space を待ちます。戻せるのは、このモードで録った音声だけです
← / → 前・次のステップ(録音中なら先に止めて採用)
C 録音中に、台本の {cue}・{mark} のタイミングごとに押します(タイミングは ①②… のチップで出て、次のタイミングは太い枠、押したものは ✓)。押した時刻が cue になります(sync: "manual"。時刻は押した生の時刻から、前の無音を削った分を引いたもの)。押した数がタイミングの数と違えば cue は書かず(sync: "none"。警告を出し、図は時間で進みます)、間違った同期は作りません
Esc 閉じる(録音中は今のテイクを捨てます。Shift+Esc は開いている窓を全部)。フォーカスは元の場所に戻ります

1 段は Space → 話す → Enter です。取り直したテイクは前のテイクの cue を使いません(仕様 §5.3):sync: "none"・cue なしから始まり、C で埋めます。台本を直して音声が古くなったステップには「古い」の知らせ、タイミングがあって cue が未設定のステップには「図は時間で進みます」の知らせが出ます。掛け合いはステップごとに 1 本のテイクです(1 人が両方の役を読むか、2 人が交互に)。入力の大きさのメーターと経過時間(1 つのテイクは 600 秒で止まり、そこまでを使う)、テイクの長さと音量の調整、音が割れていそうなときの警告が出ます。機器から遅れて届く標本を受け取るため、停止後も 0.15 秒間受け取ります。無音を削る前に、停止キーの押下の 30 ms 前から後を除き、開始はキーの解放(押下から最低 120 ms 後)のさらに 30 ms 後までを除きます。Enter も、前のテイクの末尾と次のテイクの先頭に同じ処理をします。マイクは画面を閉じるまで開いたままで(許可は 1 回、録り始めの遅れなし)、閉じると手放します。書き込みが断られたとき(読むだけのファイル・編集の確認を断った)は、そのテイクは音声の板の「まだ使っていない音声」に残ります。

読み上げソフトには、この画面は modal の dialog です。live region がステップ(n / N・題・音声の有無・タイミングの数)・「録音中」・続けて録るときの「続けて録音中:ステップ 3/7」・押したタイミング・テイクの結果を知らせ、alert の領域が問題を知らせます。どのキーにもボタン(キーの aria-keyshortcuts つき)があり、prefers-reduced-motion ではメーターを 1 秒に数回だけ更新します。この画面の間、e・n・r は何もせず、ツールバーは inert です。

添付(下書き・試行)

下書き・試行(形式の §3.8 の案):役割ごとに入れてよい形式と中身の確かめは参照のとおり。

ファイル ▾ →「ファイルの情報…」 は、egatari.json の metadata の題名・ライセンス・作成者・著作権・クレジットの表示を出し(ここでは読むだけ。作業フォルダなら egatari.json を直す)、形式(「形式:Egatari 1.0(WD …)」。ファイルの version と、vendor/egatari-spec/SOURCE.json に仕様の写しのバージョンがあればそのバージョン)と作った Studio(「作った Studio:0.4.6」。generator.version から。作業フォルダは「この Studio:…」)、「再生は、ファイルに入ったプレーヤーで動きます。編集はいつも最新の Studio で行ってください」の添え書きを出し、その下に添付(見出しは「添付(下書き・試行)」)を出す。添付は、作業フォルダか開いた Egatari ファイルの attachments/ の下のファイルを並べる(形式の §3.8:読み手のための元の原稿・PDF・コード・データ・補足。参照)。ファイルを足す… で写し入れる(役割は形式から推す:.pdf → pdf、.tex・.bib・.docx・.md → source、.py・.ipynb・環境の定義 → code、.csv・.tsv・.json・.xlsx → data、画像と .txt → supplement)、ファイルごとに題を尋ねる(要る。1 行で 120 字まで。ファイル名から埋めてあり、直せる)。形式が許さないファイルは、理由と規則(§3.8)を言って断る:名前から分かるもの(実行できるファイル・.js・.bat・.ps1 など OS がスクリプトとして開く拡張子・HTML・SVG・ZIP・マクロを入れられる Office のファイルと、.doc・.xls・.ppt の古い Office のファイル・音声と動画・どの役割も受けない形式)は題を尋ねる前に、中身から分かるもの(JavaScript のある PDF・文書の中へ移るほかの開いたときの動作や GoTo・URI のほかの動作のある PDF・パスワードの要る暗号化した PDF・マクロや外への参照のある Office・名前を替えた実行ファイル・2 つの形式を重ねたファイル・音声と動画)は読んだ後・書く前に。表計算のソフトが数式として読みうる値は知らせて足す。行ごとに役割(なし:入れるが読み手の一覧に出ない。ファイルの形式を受けない役割は断る)・題(要る:ないものは入れるが一覧に出ない。消せない)・説明(任意。1〜2 文で 300 字まで。ダウンロードの一覧の題の下に出る)・名前を替える…(新しい名前も足すときと同じく確かめる)・消す。役割・題・説明は egatari.json(attachments。ほかの項目は残し、.cache/edits/ に控え)に書く。attachments/ の外・..・予約名・重なる名前は断り、上限(1 つ 10 MiB・合わせて 20 MiB・100 個)を超えるファイルは読む前に断る。フォルダから消すときは .cache/edits/ に控えを残す。エディタは添付を開かず、プレビューにも渡さない。Egatari ファイルでは 保存 まではメモリの上で、保存は段 A:変わるのは索引の添付の項目・その塊・原稿の hash だけ。Egatari ファイルの最初の変更の前には、ほかの編集と同じく編集の確認が出る。ライブの結果を取り込む… は、ライブからダウンロードした結果を役割 data の添付にし、要約を出す(ライブの「授業の後」)。

本(下書き)

下書き(形式の §9C、article-v1)。本のある教材(article.md か article/<名前>.md。本を書く)も、ほかの教材と同じように開けます。本を書くのは Claude Code やコマンドで、編集アプリでは本を読む・直す・印刷します。本のツール(Egatari Text の読み手。圧縮して約 350 KB)と citeproc-js(文献を引く本だけ)は、本のある教材を初めて開いたときに読み込みます。本のない教材では読み込みません。

  • プレビュー ▾ →「表示」:スライド・スライドと本・本 で、プレビューのプレーヤーの並べ方を、参加者・学習者が見るのと同じ形にします(プレーヤーの本の窓:同期・スライドで見る・本で読む。Viewer と同じ)。プレーヤーの中で並べ方を替えると、この選びも替わります。
  • ツールの列の 本 で「本」の板を開きます。スライドと本が合っていないかもしれません は、つないだ後に字が変わったスライドと節(と、まだ確かめていない組)を挙げます。読み比べて、合っていれば 確認済みにする(すべて確認済みにする)を押します。今の状態を egatari.json の articleLinks に記録します(形式の §9C.7)。どちらの字も自動では直しません。
  • 「本」の板には、本のエラーと警告(npm run check と同じ)と、本のファイルごとのふつうの文字の欄(上でファイルを選ぶ)もあります。保存(⌘/Ctrl+Enter)は、UTF-8・改行 LF・Unicode の NFC で書きます(形式の §9C.2)。作業フォルダではそのファイルに書き(前の中身は .cache/edits/ に控えます)、Egatari ファイルではメモリの上の教材を変え、ファイル ▾ → 保存 のときに本だけを組み直します(スライドはバイトのまま。形式の §9C.1)。エラーのある本は保存しません。知らせに直す所を挙げます。
  • ファイル ▾ → エクスポート ▸ → 本を印刷 は、本を A4 縦で印刷します。スライドへのリンクは、教材の言葉で「→ スライド 5・ステップ 3」(ステップ 0 へのリンクは「→ スライド 5」)と刷ります。本のない教材では、この項目は 台本を印刷 で、スライドを 1 枚ずつ小さく(最後の状態で)、その台本と並べて刷ります。スライドを印刷 は、これまでどおりスライドを 1 枚ずつ刷ります。
  • citeproc で引用を組んだときは、本の下と「本」の板に「Citations formatted by citeproc-js — (c) Frank Bennett — citeproc-js implements the Citation Style Language — https://citationstyles.org/」の 1 行を出します(CPAL-1.0 の Exhibit B。NOTICE)。
  • まだできないこと:本の貼り付けと取り込み(Markdown・TeX・Word)、スライドと節のつなぎを手で直すこと、引用の書式を選ぶこと、B5 と 2 枚を 1 枚に印刷すること。本の表示は、使っている端末の字体で出ます。

Egatari ファイル(フォルダなし)

Egatari ファイルは、npm run build -- <deck.html> --portable(または編集アプリの ファイル ▾ →「名前を付けて保存…」)が書くもの(作業フォルダの最上位に、題名から作った名前で書き、パスを表示する)。組んだ教材と同じように再生でき、スライド・台本・音声を中に持つので、元のフォルダがなくても編集アプリで直せる。人への配り方(Google ドライブ・メール・LMS)は distributing.ja.md。

  • 開く。 最初の画面の「ファイルを開く(.ega.html)…」か ファイル ▾ →「開く…」 を押すか、ファイルを最初の画面にドラッグ&ドロップする。編集アプリはファイルをバイト列として読み、スクリプトを動かさない HTML の解析器で、Web Worker の中で取り出す。ファイルそのものをページとして読み込むことはないので、取り出しの間に中のものは何も動かない。形式のハッシュ・大きさの上限・パスの規則を先にすべて確かめる(npm run portable -- unpack と同じ)。HTML は上限(要素・属性・入れ子の深さ)を解析の途中で数えながら解析し、中の原稿のファイルに書かれたタグも 500000 までにするので、小さな要素を何百万も並べたファイルは、全部の木を作る前に断る。読むのに 30 秒より長くかかれば Worker を止めて断る。開いた教材(フォルダ・Egatari ファイル)の組み立てとコードの確かめも Worker の中で、組み立ての上限(reference)の内で行い、60 秒より長くかかればその Worker を止めて失敗にする(build-timeout)。その間もページは固まらない。フォルダから読むのは組み立てが参照したファイルだけ(同時に 8 つまで、1 つは一覧の大きさまで。一覧の後で大きくなったファイルは断る)で、止めた Worker からの答えは捨てる。どのファイルも、読む前に File.size で、読んだ後に読んだバイトで大きさを確かめ(app/bounded-read.js)、deck.html・narration.md・comments.json には決まった上限(32 MiB・16 MiB・4 MiB)があり、超えるものは読まずに断る。原稿はメモリの上(メモリの上のフォルダ)に置き、プレビュー・編集のツール・品質チェックはフォルダのときと同じように動く。フォルダがないので、外での変更は見張らない

  • 保存。 「保存」は、ブラウザが書き込めるハンドルをくれたとき(Chrome / Edge の「ファイルを開く(.ega.html)…」かドラッグ&ドロップ。初めは許可をたずねることがある)は同じファイルに書き直す。そうでなければ保存先をたずね、保存の画面がなければ(Safari・Firefox)ダウンロードする。文書の識別子(docId)は変えず、derivedFrom を付けることも変えることもない。ファイル ▾ →「名前を付けて保存…」 は、新しいファイルとして保存する(元のファイルとは別のものになります) かを聞く

    • 印を付けたとき:保存先をたずね、新しい docId の教材として書く。元の教材を derivedFrom(元の docId と原稿の hash)に記録し、著作権・クレジット・作成者はそのまま残す。開いている文書は新しい教材になる(この後の保存も新しい識別子のまま)
    • 付けないとき:保存先をたずね、同じ教材(同じ docId)を別のファイルに書く

    ファイル名の前の ● は保存していない変更の印。ページを離れるときや別のファイルを開くときは先にたずねる。どの保存でも、ライセンス・著作権・クレジット・作成者、編集アプリの知らない索引の項目(どの深さでも:metadata・音声の記録・塊・パーツとテーマ・拡張の中)と拡張のデータは残し、触れていない音声はバイトのまま写す。設定のファイル(原稿の根にある教材の識別子と metadata)がないファイルには、編集アプリが足すことがある。それで原稿の hash は変わるが、保存はもともとそれを書き直す

  • 組み直さずに保存する。 台本(発言の文・強調・タイミング)、音声、timeline.json の秒数の上書きだけが変わったときは、「保存」はスライドを組み直さない。形式がそういう編集に挙げる所(§7.2 の段 A)だけを書き換える:実行系の台本・強調・秒数・音声のデータのうち変わったステップの項目、スクリプトなしで読める文字の層のうち変わったステップ、原稿の hash と索引とその hash、中に入れたファイル(新しい中身を足し、どこからも参照されなくなった中身を除く)、そして新しい文に、埋め込んだ字にない字があるときだけ、字の補い(その字を含む字の分割ファイルだけを、編集アプリが持つ字から入れた新しい style 要素。前からある字のデータには触れない)。ファイルのほかのバイトは、ほかのツールや別のバージョンが書いた実行系も含めて、1 バイトも変えない。状態の欄に「組み直さずに」と出る。ステップの台本をすべて消すと、そのステップの音声も消える。保存の知らせに警告があることが出て、品質チェックの板にそのステップが出る。秒数の上書きは項目ごとに写し、各ステップの長さは実行系がそれまでと同じ式で計算する

  • 組み直して保存する。 スライドを直したとき(または上の所の外が変わった、ファイルの組んだ教材と原稿が食い違うとき)は、直した原稿から編集アプリに同梱の kit・パーツ・テーマでファイル全体を組み直すので、プレビューとまったく同じに再生する。保存の前に 「スライドはこのエディタの今のバージョンで組み直されます。編集していないスライドも、見え方が変わることがあります。」 と知らせ、組み直さずに保存できない理由も見せ、「組み直して保存」を押してから保存する(キャンセルなら変更は保存しないまま)。まだ一度も保存していない教材(AI の出力から作った・deck.html だけを開いた)は、聞かずに組み直す(このエディタが組んだものなので、ほかは変わらない)。テーマを変えただけ(テーマを変更…)のときは、そのことだけを言う:「テーマを替えたので、スライドを新しいテーマで組み直して保存します。…」。ファイルがほかのプレーヤーを持っていたとき(索引のプレーヤーが Egatari Player でない)は、続けて 「プレーヤーが変わります」 の窓で、ファイルのプレーヤーと保存したファイルに入るプレーヤーを名前とバージョンで見せる(「このファイルは Other Player 2.0.0 で再生します。保存すると、Egatari Player 1.0.0 で再生するファイルになります。…」)。「保存」で保存し、「キャンセル」なら変更は保存せず、ファイルもそのまま(形式の仕様 §4.1)。同じプレーヤーの新しいバージョンになるだけなら聞かない。まだできないこと:組み直しの前と後のスライドを比べること。保存した後にプレビューで確かめる

  • 更新が必要な音声。 ステップの台本を直しても、その音声には触れない(バイトも種類もそのまま)。そのステップは警告に「音声の更新が必要」と出て、保存したファイルでも音声の記録は作ったときの台本の hash のままなので、どの読み手にも古いと分かる。音声の板で録り直すか、作り直す

  • ファイル ▾ → エクスポート ▸ →「作業フォルダにエクスポート…」 は、選んだ空のフォルダに原稿・音声・audio/manifest.json を書く(npm run portable -- unpack と同じファイル)。空でないフォルダは断る。エクスポートしたフォルダは、ふつうの作業フォルダとして開け、組め、まとめられる

  • ファイル ▾ →「名前を付けて保存…」(フォルダを開いているとき)は、フォルダを Egatari ファイル(編集可・.ega.html)にする。最初に出すファイルの名前は教材の題名(設定のファイルの metadata.title、なければ教材の <title>)で、どの OS でも使える形にする(\ / : * ? " < > | と制御文字を除き、頭の点と終わりの点・空白を除き、CON などの予約の名前を避け、80 字・255 バイトまで)。題名がなければスライドのファイルの名前。初回は教材の識別子をフォルダの設定のファイルに書き、次からのエクスポートでも同じものを使う

  • 作業フォルダから書き出したファイル(exportedFrom、形式の §3.1)。作業フォルダの「名前を付けて保存…」(コマンドの --portable も)は、そのファイルに作業フォルダから書き出したという印を、エクスポートしたときのフォルダの原稿の hash と一緒に付ける(時刻・パス・名前は入れない)。そういうファイルを開くと「このファイルは、作業フォルダ(スライドと台本のファイルを入れたフォルダ)から書き出したものです。ここで直しても、作業フォルダのファイルは変わりません。作業フォルダを持っていなければ、気にせずこのまま直して保存できます。」と知らせ(警告ではなく、ふつうの案内の行)、作業フォルダにエクスポート… のボタン(ファイル ▾ → エクスポート ▸ →「作業フォルダにエクスポート…」と同じ)を出す。編集は断らない。「保存」と「名前を付けて保存…」は印を変えないので、ファイルの原稿の hash が印と違ってくると「書き出したあと、このファイルで直した所があります。」を足す。「新しいファイルとして保存する」に印を付けた保存は印を外す(新しい docId の教材は書き出したファイルではないので、開き直しても知らせは出ない)。フォルダなしで編集アプリから始めた教材(貼り付けたもの・deck.html だけから開いたもの)には印が付かない。展開したフォルダは印を持たず、原本になる。次のエクスポートが新しい印を書く。書き出したファイルと作業フォルダの両方が手元にあれば、npm run portable -- compare <ファイル> <フォルダ> がエクスポートの後にどちらを直したかを言う(参照)。

  • ファイルに入らないもの: コメントと .cache/edits/ の控えはメモリの上にだけ残る(コメントは見直しの覚え書きなので、形式が外す)

このブラウザに残す、保存していない変更

Egatari ファイルを直している間、保存していない変更をこのブラウザの中(IndexedDB)に残す。タブを閉じても落ちても消えない。変更から約 2 秒後(直し続けても 10 秒に 1 回、タブが隠れたときはすぐ)に、開いたときのファイルと、それから変わったファイルだけ(スライド・台本・egatari.json・timeline.json・添付・本・音声のファイルと audio/manifest.json。「保存」が書くものと同じ)を残す。録音は教材に書いた時点で残る。コメント・開いた欄に打ちかけの文字・録音中のテイクは残さない。

  • 復元。 同じファイル(名前と中身が同じ)をもう一度開くと 「保存していない変更があります」(「「…」に、保存していない変更があります(…、このブラウザに残したもの)。復元しますか?」)と聞き、変更を捨てる と 復元 を出す。Esc ならあとで決める。はじめの画面の 保存していない変更 にも並ぶ(行ごとに 復元 と 変更を捨てる)。そこでの復元は、残したファイルの写しを開くので、ファイルを選び直さなくてよい。復元は変更をファイルの上に書き戻して組み直す。ファイルにするには「保存」を押す。元のファイルが変更を残した後に書き換わっていれば、上書きせずに保存の場所を聞く。
  • 2 つのタブ。 タブごとに自分の変更を残し、開いている間はそれを持つ(Web Locks)。ほかのタブで開いている変更は、聞きも並べもしない。同じファイルを 2 つのタブで直しても、残した変更を互いに上書きしない。
  • 消えるとき。 ファイルに保存すると消す。変更を捨てる(ここでも、別のファイルを開くときの問いでも)でも消す。最後に変えてから 30 日たったもの、10 件を超えた古いものは消す。? →「このブラウザに残した、保存していない変更」 に件数と大きさ、すべて捨てる がある。ブラウザが消すこともある(ディスクの空きが足りないとき、Safari は約 7 日開かないとき)。初めて残すときに、消さないようブラウザに求める(永続の保存)。
  • 限り。 残すものが 256 MiB を超える教材は残さない(1 回だけ知らせる)。ブラウザの保存領域が足りないときは「このブラウザに変更を残せませんでした(保存領域が足りません)。」と 1 回だけ知らせ、次の変更でまた試す(編集は続けられる)。下の帯の札の説明が「復元できます」と言うのは、実際に残せているときだけ。
  • プライバシー。 変更はこの端末のこのブラウザの中にだけあり、アップロードしない。
  • 作業フォルダ はその場でフォルダに書くので、何も残さない。

編集の確認(このファイルを編集しますか)

ファイルを編集のために開くたびに、最初の変更の前に(編集モードや台本の引き出しで最初に保存するとき、または「編集」「台本」を押したとき)、ファイルに書かれた題名・作成者・著作権・ライセンス・クレジットの表示を見せる(どれも申告で、確かめたものではない)。改変を認めないライセンス(Creative Commons の -ND、All rights reserved)か、ライセンスがなく著作権の表示だけのときは、改変や改変したものの配布が権利者の著作権を侵すおそれがあると知らせ、確認のチェックを入れるまで編集を始めない。キャンセルならファイルは変わらない。保存で著作権・クレジット・作成者を消すことはない。

スライドのファイル(deck.html)・組んだ発表の HTML を開いたとき

  • スライドのファイル(作業フォルダの deck.html。GitHub から落としたものなど。<section class="slide"> があり、組み立ての実行系や形式のブロックがない)は断らない。台本・音声・その教材だけのパーツは同じフォルダに別のファイルとしてあることを説明し、「作業フォルダを開く…」(フォルダを選ぶ画面。選んだフォルダをふつうに開く)・「このファイルだけを開く」・「キャンセル」を出す。「このファイルだけ」は deck.html だけのメモリの上の教材を新しく作る:台本と音声はない。パーツライブラリのパーツとテーマは使え、参照しているのにないファイル(その教材だけのパーツ・{{JSON:…}} のデータ・取り込み・図)は組み立ての知らせ(1 つにつき 1 回)になり、中身なしで組む(メモリの上の教材はすべてこうする。フォルダは今までどおり、ないファイルがあれば組み立てが失敗する)。ほかの開いたファイルと同じに扱う:教材にコードがあれば先に確かめ、新しい docId で、編集の確認は出さず(権利が書かれていない)、deck.html だけを開いていてまだ保存していないことを知らせる。「保存」は保存先をたずねる:「Egatari ファイル(.ega.html)に保存…」か「作業フォルダにエクスポート…」(空のフォルダ)
  • 組んだ発表の HTML(out/deck.html など。組み立ての実行系と deck-meta はあるが原稿がない)は専用の言葉で断る:発表用に組んだもので、作業フォルダ(「作業フォルダを開く…」を出す)か Egatari ファイルを開くように言う
  • Egatari ファイルの再生専用版(.play.ega.html)はそう名指しして断る:そのままブラウザで再生でき、編集するには元の Egatari ファイルか作業フォルダを開く。ほかの HTML は「Egatari ファイルではない」と言う

断るファイル・読むだけで開くファイル

  • 理由を見せて断る: Egatari ファイルでないもの・再生専用のもの(上を参照)、ハッシュが合わないもの・一部が欠けたもの、許されないパス(../ など)、索引の同じ名前の項目、設定のファイルと食い違う文書の識別子、新しい原稿の書き方のバージョン
  • 新しい major のバージョン、編集アプリが実装していない必須の機能: 編集のためには開かず、エクスポート(作り直し)もしない。索引と中のデータが、編集アプリの知っているバージョンの規則で確かめられれば、原稿を取り出す「作業フォルダにエクスポート…」を申し出る。確かめられなければ取り出しも断る(そういうファイルもブラウザで再生はできる)
  • 台本・音声・秒数だけ: パーツライブラリ・テーマ庫のパーツの hash が編集アプリのものと違う(または編集アプリにない)もの、パーツが必要とする特定のバージョンのパーツがない既存のファイル。編集アプリではそのとおりに組み直せないので、台本・音声・秒数だけを編集できると上に知らせる。「編集」(スライドの文字)は断り、台本の引き出しは使え、「保存」は組み直さずにその所だけを書き換える。スライドの編集・テーマの変更・置き換えはできない。必要なパーツがないときは、どのパーツが何を必要とするかを知らせ、組み直すにはパーツを更新するよう案内する。プレビューはそのファイル自身のプレーヤーで、残るパーツを再生する
  • 読むだけ: それ以外の理由で編集アプリで組み立てられないもの、ひとつ前の種類で、しかも組んだ教材と原稿が食い違うもの。教材は表示し、保存は断り、「作業フォルダにエクスポート…」はできる
  • 独自のコード: 教材が自前のコードを持つかは、組んだ文書から決める(取り込み・前処理の後の原稿全体。組み立てがテキストとして読むファイルは拡張子によらずすべて含み(/*INCLUDE:…*/ で取り込んだ画像のファイルも)、そのあとプレビューに出すのと同じバイト)。src がなく中身が空か空白だけの <script> はコードに数えない(コメントだけのものは数える)。調べるためにフォルダをもう一度読むことはしない。そういう教材(と「extended」のファイル)は、その中のものが動く前に知らせてたずね、「プレビューを始める」を押してからプレビューを始める(キャンセルならファイルは開かない)。たずねる前にプレビューを空にするので、前の教材も新しい教材も、たずねる窓の後ろに出ることも動くこともない。開いている間は上に知らせを出す:コードはプレビューの中だけで、外へ繋がらずに動き、ファイルを書き換えられない。パーツ(components/…、どれかの .js)や deck.html のスクリプトを持つフォルダも、開くたびに 1 回同じことをたずねる(あとからそういうコードが現れたときも)

チャットの AI で下書きする(貼り付けと修正依頼)

初めの下書きは、コーディングツールなしで、チャットの AI(claude.ai・Gemini・ChatGPT など)にも書かせられる。AI への指示の全体(詳細の指示)は authoring-with-llms.ja.md(English。規格・出力の形と標準パーツ)と、材料の種類ごとの束の指示 llm-parts/:stats・data・math・maps・kokugo・english・music・business・tools・science。パーツの段(標準・専門・特殊)と束はパーツライブラリ 2.0 の manifest から決まり、標準パーツはいつも、専門のパーツはその束があるときだけ指示に入り、特殊のパーツは入らない(backlog #125)。④ で軽量の指示を選ぶと、編集アプリは軽い指示をコピーする(下の ④):中核の 4 つのほかの標準パーツは、パーツの一覧の 1 行だけにする。node tools/make-llm-guide.mjs が約束事・パーツの README・tools/llm-guide/ から作り、古くなるか大きさの上限(kit/core/llm-pack-assemble.mjs の PACK_CAP_KB:軽量の指示は標準パーツすべてで 45 KB、詳細の指示は標準パーツとどの 2 つの束の組でも 150 KB)を超えると npm test が失敗する。npm run gen は軽量の指示の束ごとの大きさ(新規作成と同じに収めたもの。kit/core/llm-pack-assemble.mjs の fitPack:45 KB を越えたら中核の 4 つも短くし、それでも越えれば専門のパーツを外す)と、詳細の指示のいちばん大きい組の大きさを出す。詳細の指示ですべての束を一度に選んだ指示も 150 KB の上限に収まる(収まらないときだけ知らせるだけ)。上限を超えたときは、どの指示か(軽量・詳細、言語、束)、何バイト超えたか、大きい節 3 つを出す。node kit/llm-pack.mjs --sets stats,math --lang ja はエディタが軽量の指示でその束を選んだときと同じに収めた文章を出す(中核の 4 つを短くした・専門のパーツを外したときは stderr に出す。--no-fit で組み立てたままの指示)。--plan paid でどのパーツも詳しく、--sets all --plan paid で全体。--list で束と、軽量の指示の収めた大きさと収める前の大きさ(KB は UTF-8 のバイト数 / 1024)。--help で使い方。

新規作成… の 指示をコピー の横に AI のスキルをダウンロード を出す。添え書きは「Claude などのチャットの AI に入れると、指示書を貼らずに作れます。Studio が新しくなったら入れ直してください(スキルの指示と品質チェックはバージョンごとに変わります)」。画面の言語(ja または en)の make の ZIP をチャットの AI に入れ、その出力を Studio に貼り付ける。

  • チャットの AI は、ふつうの 3 つのコマンドの中の 1 つのやり方。 出力の取り込み方(新しい教材・スライドの挿入・今の教材の置き換え)はコマンドが決め、そこに選ぶ欄はない。言葉は「出力」「コードブロック」(はじめに「灰色の枠」と言い添える)「指示」で、ボタンは押すと起きることの名前(作成・挿入・置き換える)

    • 新規作成…(最初の画面か、ファイル ▾ → 新規作成…):チャットの AI の道だけで、下のページがすぐに開く。スライドのテンプレートは スライドの挿入… に、新しい作業フォルダはコマンドの npm run new に
    • スライドの挿入…(スライド ▾ →「スライドの挿入…」 か、スライド一覧の スライドの挿入 ▾):テンプレートから(スライド一覧のテンプレート)と チャットの AI に書いてもらう。新しいスライドは、選んだスライドの後ろに入る(スライド一覧を閉じてツールの列から選んだときは、プレビューに出ているスライドの後ろ)
    • 修正…(スライド ▾ →「修正…」 と、品質チェックの板の先頭):今の教材をチャットの AI に直してもらう
    • テーマを変更…(スライド ▾ →「テーマを変更…」):開いた教材のテーマを後から替える。窓には新規作成の ③ と同じ一覧(見せる名前と色見本、同梱のテーマには小さく向き。今のテーマに印。自分のテーマは「自分のテーマ」の見出しの下。新しくは選べない business の教材では、今のテーマとして「新しくは選べない」と添えて出す)と「テーマを読み込む…」(テーマを読み込む窓(下)を開く。読み込むと一覧に加わる)が出る。替えるのは原稿の <html> の data-theme だけで(ほかの属性はそのまま。スライドには触らない)、egatari.json の themes は新しいテーマとそれが土台にする(extends)テーマを、前のバージョンに固定されていても今のバージョンで固定し(選んだテーマの今の見た目になる)、使わなくなったテーマの固定を外す(updateConfig を通るので、ほかの項目はバイトのまま)。テーマと土台は組み立てと同じ順で探す(原稿のフォルダ → その themes/ → 自分のテーマ(テーマのフォルダとこのブラウザに保存したテーマ。同じ名前なら新しいほう)→ 同梱)。バージョンは、同梱のテーマは themes.lock.json の今のバージョン、それ以外は theme.json の version、なければ "local"。プレビューを組み直し、スライド一覧の操作と同じく、保存していない変更(●)になり、スライド一覧の 元に戻す で原稿と egatari.json がバイトまで戻る。自分のテーマ(テーマのフォルダ・ZIP ファイル)のテーマは、次の保存で今までどおり themes/<名前>/ として入る。見つからないテーマは今までどおり theme not found と警告して default で組む。台本・音声・秒数だけを編集できるファイルと読むだけのファイルでは、項目は押せない形で、わけを出す
  • 新規作成。 画面いっぱいのページ(Google スライドや Canva の新規作成の画面のように)。左上の ← 戻る・キャンセル・Esc で閉じる。はじめに「4 つの問いに答えると、チャットの AI(ChatGPT・Gemini・Claude など)に送る指示ができます。AI の出力をここに貼り付けると、スライドができます。」。問いは答えると考えが 1 つ進むものだけで、考える順(何に使う → 中身 → 見た目 → 送る → 受け取る)に、1 つの問いに 1 つの見出しで並ぶ。開いているのはいまの問いだけ(買い物の手続きのような 1 つだけ開く流れ)。① 〜 ⑤ の見出しはいつも順に見え、見出しは押せるボタン(aria-expanded、いまの問いは aria-current="step")。まだの問いは見出しだけ(薄く、本体なし)。次へ で答えた問いは 1 行にたたみ(「使う場面:授業・研修/授業(小・中・高)変更」)、次の問いが開いて見えるところへ動き、最初の操作に印が移る。③ まで答えると ④ が開く。指示をコピー すると ④ は「指示:軽量・国語・コピーしました 変更」にたたみ、⑤ が開く(チャットのタブから戻ると貼る欄がある)。⑤ は ④ を開いたら見出しからも開ける(もう出力を持っているとき)。変更 はその問いだけを開き直し、前の問いは 1 行のまま、後ろの問いは今の状態のまま。スライドの挿入… と 修正… の 3 つの段も同じ流れ(① の 次へ・② のコピーで次の段。どの見出しからも開ける。構成案の続きは ② から)。答えはページを開いている間は残る。コピーの結果と誤りは読み上げられる(live region)

    1. どんな場面で使いますか(答える問い。既定の印はなく、答えるまで 次へ は押せない。backlog #99)。「場面に合った組み立て(授業なら導入・展開・まとめ)を AI に伝えます。あてはまるものがなければ「その他」を選びます」。使う場面は 授業・研修・研究発表・ビジネス・手引き・その他。その他のほかは もう少し詳しく言うと(これも答える問いで、最後は この中にない。印は付けておかない):授業・研修は 授業(小・中・高)・大学の講義・研修・使い方の説明、研究発表は 学会の口頭発表・ゼミ・進捗報告・招待講演・一般向け、ビジネスは 報告・提案・意思決定・ピッチ・紹介・広報、手引きは マニュアル(目的 → 手順を 1 つずつ → つまずきやすいところ)・決まりの説明(規程・法令)(何についての決まりか → だれに・いつ当てはまるか → しなければならないこと → 原典の文とその日付)・案内(ごみの出し方・図書館・避難・履修登録など)(どんな場面か → 品目や場面から引ける一覧 → わからないときの問い合わせ先)。詳しい場面を選ぶと、その組み立てと見せ方を下に出し、頼みたいことに入れる(- 場面:…・- 構成の型:…・- 見せ方:…)。その他 は何も書かず、この中にない は場面の行だけ(組み立ての行は書かない)。どちらも studio.newDeck では subcategory: null
    2. 何について、だれに向けて作りますか(「書いたことは、AI への指示の最後に入ります」)。タイトル(表紙に出ます) は必須で、書くまで 次へ は押せない。だれ向け(AI に任せる(① の使う場面から考えます)/書く)・長さ(AI に任せる(5〜8 枚くらいにします)/指定する:数と 枚 か 分)・内容(AI に任せる(タイトルだけで考えます)/ここに書く・貼る(授業のメモや教科書の文をそのまま貼れます。大きな欄が開く)/チャットの AI に渡してある(PDF などの資料を添付した、または内容を話し合った。下に「指示は、その資料を渡したチャットに貼り付けてください」))。どれも既定は「AI に任せる」で、選んだときだけ欄が開く。折りたたみ 詳しく(見出しに今の答え:「詳しく:日本語・1 人で説明」、希望を書けば「・そのほかの希望あり」)の中に 言語(日本語/English/その他(書く欄が出る)。既定は画面の言語)・話す人(1 人で説明する(既定)/2 人(説明する人と、質問する人))・そのほかの希望(なくてもよい)(下に小さく「話す人は 2 人まで」)。例の文は ① の答えに合わせる(授業・研修なら「てこのはたらき」「小学 6 年生」…)。「入れたい例や図」の欄はない(内容の欄に入れる)
      • 頼みたいこと(kit/core/llm-request.mjs。指示の最後の記入欄から項目の名前を取る)は、AI に任せた項目を書かない。A は タイトル(表紙にそのまま使う)・対象・長さ(「6 枚」「20 分」)・言語・話者(「1 人」か「2 人(Expert と Novice の掛け合い)」)・そのほかの希望。内容を書いたときは、その後ろの「## 内容」の下に入る。「チャットの AI に渡してある」は B(B. 渡した資料と話し合いの内容で作る:「このチャットで渡した資料と、ここまでの話し合いの内容で、教材を作ってください。」)で、詳しくの欄も出し、A と同じ形で タイトル・対象・長さ・言語・話者・そのほかの希望 を書く
      • 長さは 2 回に分けて頼むかの判断にも使う(分は 1 分 ≒ 1 枚。kit/core/llm-outline.mjs の slideCountOf)
    3. どんな見た目にしますか。 テーマ(「スライドの色と書体です。あとで「テーマを変更…」で変えられます」)。一覧は見せる名前(同梱の 7 つのテーマを和色の名前で:藍・墨・国語・常盤・江戸紫・焦茶・浅葱。選んだテーマの向きを一覧の下に小さく出す(例:「研究・講義向け」)。それと、「自分のテーマ」の見出しの下に自分のテーマのフォルダのテーマと ZIP ファイルから読み込んだテーマを、theme.json の title か name、なければフォルダの名前で)で、テーマを変更… の一覧と同じ。最後の「テーマを読み込む…」で、テーマを読み込む窓(下)を開く。テーマは頼みたいことの 1 行(- テーマ:<名前>(<html data-theme="<名前>">))として入り、出力の教材にテーマがなければ、このテーマを付ける
    4. チャットの AI に指示を送ります。 はじめに問い AI に渡す指示を選んでください:軽量(どの AI でも)(「迷ったらこちら」の札。既定)と 詳細(有料の AI 向け)。それぞれの下に説明。軽量は「約 3 万字までの短い指示です。無料の ChatGPT や Gemini にも、そのまま貼り付けられます。選んだ分野によっては、パーツの説明を短くしたり、一部を省いたりします。」、詳細は「パーツの説明を省かない、長い指示です。ChatGPT・Gemini・Claude の有料プランのように、長い文章を読める AI に向いています。Gemini は、コピーして貼り付けると約 3 万字で切れることがあります。ファイルに保存して添付してください。使う分野だけを選ぶと、指示が短くなり、AI が使う量(トークン)も減り、パーツも選びやすくなります。」。その下に「選んだ指示で、大きさの目安が変わります(軽量は 45 KB、詳細は 150 KB まで)。長すぎる指示は、チャットの AI が最後まで読めないことがあります」。v0.6.6 までは AI のプラン(無料・有料)を聞いていたが、聞くのは渡す指示に変えた(2026-11-07 の作者の決定)。内部の名前は plan の free(軽量)・paid(詳細)のままで、指示の中身も変わらない。軽量・詳細が変えるのはこの目安(kit/core/new-deck.mjs の capKb。PACK_CAP_KB から)と指示の詳しさ(軽量の指示では、中核の 4 つ(棒グラフ・流れ図・目次・予想と答え)のほかの標準パーツを、指示のパーツの一覧の 1 行だけにする。backlog #125)で、選べるパーツやその数は変えない。次の問い AI にどのパーツを使わせますか(backlog #124、handoff/parts-tiers-2026-10-27.md §2):指示が説明できるパーツライブラリのパーツを、チェックボックスで、伝えたいことごとにまとめて並べる(partsList):比べる(量・特徴)・変化・内訳・数字を見せる・手順・年表・予定・原因と結果・循環・階層・分類・位置づけ・重なり・2 つの量の関係・ばらつき・目次・パラメータを動かす・予想して確かめる・時間を区切る。1 つのパーツは 1 か所だけ(manifest の最初の伝えたいこと。順位は「比べる」に入る)で、最後に 教科の形(地図・国語・英語・音楽:日本地図・世界地図・漢文・古文・現代文の読解・書き順・英文の構造・鍵盤・楽譜)。授業(小・中・高)(① が 授業・研修/授業(小・中・高))では、このまとまりが一番上。まとまりは見出しの付いたグループ(role="group")、パーツは label の中のチェックボックスと見本の絵・名前・1 行の説明(aria-describedby。名前はパーツライブラリ 2.0 の manifest の display を npm run gen が kit/core/llm-pack-data.mjs に写したもので、それがないパーツの名前と説明は kit/core/part-labels.mjs。npm run gen:check の node tools/part-labels-check.mjs が両者を比べる)。見本の絵は、パーツの見本(demo.html)の 1 枚目を最後のステップまで進めたもので、npm run thumbs(tools/part-thumbs.mjs → app/part-thumbs.js。192×120 の WebP、全部でおよそ 185 KB)が明るい画面と暗い画面の 2 枚を作る(<picture> と prefers-color-scheme)。alt はパーツの名前と、日本語の画面では見本の見出し(「棒グラフのサンプル:年ごとの売上(架空)」。英語の画面は “Example: Bar chart”)。見本のないパーツは線画。パーツの段と束はパーツライブラリ 2.0 の manifest(components2.lock.json の既定のカタログの vendor/components-2/manifest-<版>.json)から、npm run gen が kit/core/llm-pack-data.mjs(TIERS)に写す。特殊の段のパーツ(ハフマン木・回答のまとめ)は出さない。初めの印:標準のパーツは全部。専門の束は、① の使う場面か ② の言葉(タイトル・内容・そのほかの希望)に当たったときだけ、その束のパーツ(recommend・initialParts):大学の講義・学会の口頭発表・ゼミ・進捗報告 → 統計の図、研修・使い方の説明 → タイマー、報告・提案・意思決定・ピッチ → ビジネス、案内 → 地図。言葉は 分布・統計・データ(統計の図)、筆算・分数・関数(算数・数学)、地図・都道府県・人口(地図)、漢文・漢詩・古文(国語)、英文・文型・関係詞(英語)、音階・和音・楽譜(音楽)、市場・KPI・売上(ビジネス)、タイマー・ワークショップ・グループワーク(タイマー)など。英語の画面は英語の言葉の表(WORDS)。こうして印を付けたパーツには おすすめ の札を付け、束ごとに 1 行でわけを言う(「① の使う場面が「ゼミ・進捗報告」なので、ヒートマップ・ヒストグラム・箱ひげ図・分布の更新も選びました」「② に「漢詩」とあるので、…も選びました」)。自分で付けた・外した印は、推し直しで変えない。新規作成はいつもこの初めの印から(開いている教材の studio.newDeck は読まない)。添え書きは「伝えたいことごとに並べています。標準パーツは全部選んであります。外したパーツは AI が使わず、要るときは近い形を HTML で描きます。表・画像・数式・図形は、選ばなくてもいつも使えます」、一覧の下に「選んだパーツ:N 種類(全 M 種類)」。写す指示は、印の付いたパーツをちょうど載せる(kit/core/llm-pack.mjs の partsPackOpts:標準のパーツと、印の付いた専門のパーツの束を入れ、ほかのパーツはすべて除くので、名前もどこにも出ない。特殊のパーツはいつも入らない)。標準パーツを全部選んだ軽量の指示は、目安に収まる。軽量の指示の目安は 45 KB と、貼り付けの長さ(UTF-16 の単位の数+改行の数。CRLF で貼られることがあるため改行は 2 つに数える。Gemini は貼り付けを約 32,000 で切る)の 31,000 の、先に届くほう(kit/core/llm-pack-assemble.mjs の fitSize・FREE_PASTE_UNITS。node kit/llm-pack.mjs と同じ収め方)。一覧の下に 指示の大きさ:N KB(目安は 45 KB まで) と、軽量・詳細の目安と比べる棒(role="meter")。軽量の指示では、棒と目安を越えたときの行は、2 つの目安のうち近いほうに従う。軽量の指示で目安を越えると、まず中核の 4 つ(棒グラフ・流れ図・目次・予想と答え)の説明もパーツの一覧の 1 行だけにし、メーターの下に「軽量の指示に収めるため、棒グラフ・流れ図・目次・予想と答えの説明を短くしました」と出す(fitPlan。印は外さない)。それでも越えると棒が縞になり、「目安より N KB 大きいので、チャットの AI が最後まで読めないことがあります。外す候補:…」と 候補を外す:候補は、束が 1 つなら、中核の 4 つのほかの標準のパーツを決まった順に(特性要因図・マトリックス・循環・ベン図・階層の木・年表・比べる表・円グラフ・散布図・折れ線グラフ。図表を最後にするのは教科の束が図表に頼るから。kit/core/llm-pack-assemble.mjs の SINGLE_SET_DROP_ORDER)、収まったところまで。その束のパーツと中核の 4 つは候補にしない。束が 2 つ以上なら、印の付いた専門のパーツだけ(標準のパーツは外さない)で、外すと指示がいちばん小さくなるものから、越えた分に届くまで(trimCandidates)。長い教材なら大きさの上に「20 枚なので、2 回に分けて頼みます…」。指示をコピー は、指示と、最後に(空の記入欄の代わりに)①〜③ の答えをコピーする。軽量の指示では押すと「コピーしました(N KB)。チャットの AI のタブに貼り付けて送ってください。長いので、貼るとファイルの添付の形になることがありますが、そのまま送ってかまいません。AI が書き終えたら ⑤ へ」。詳細の指示は貼り付けで切れやすいので(Gemini は貼り付けで約 3 万字で切れる。owner の確認、2026-11-05)、指示をファイルに保存 が主のボタン、指示をコピー が従のボタンになり、下に「長い指示は、ファイルにしてチャットに添付してください。Gemini は、コピーして貼り付けると約 3 万字で切れることがあります。ChatGPT は貼り付けると自動で添付に変わります。」と出る。指示をファイルに保存 は、egatari-instructions-ja.txt か egatari-instructions-en.txt(指示の言語のほう)を、指示をコピー がクリップボードに置くのと同じバイト(UTF-8・BOM なし)でダウンロードし、「保存しました(N KB)。ダウンロードしたファイルをチャットの AI に添付して送ってください。AI が書き終えたら ⑤ へ」と出す(詳細の指示のコピーの知らせからは、下の行と重なる「ファイルの添付の形になることがあります」の文を外す)。① か ② の答えが欠けていれば、その問いを開いて言う。答えた 1 行は「指示:軽量・パーツ 16 種類・コピーしました」
    5. AI の出力を貼り付けます。 「AI の出力には、灰色の枠(コードブロック)が 2 つあります…」。欄は 2 つ:スライド(deck.html) と 台本(narration.md)。それぞれの下に状態(「まだ貼っていません」「✓ スライド 6 枚」「✓ 台本 6 節」、読めなければそのわけ)。出力の全体をどちらの欄に貼っても 2 つに分けて入れ(「出力の全体だったので、スライドと台本に分けました」)、違う欄に貼ったもの(台本の欄にスライドなど)は正しい欄へ移して知らせる。コードブロックの外の文や枠の行ごと貼ったときは、取り出したコードブロックだけを欄に残し、「出力からスライドのコードブロックを取り出しました」と知らせる(分けた・移したときも、欄には取り出したものが残る)。隠れた「待ち」の状態はなく、欄を消せば最初から。作成 はスライドの欄が埋まれば押せ、台本の欄が空ならボタンのすぐ左に「台本なしで作成します(台本はあとで書けます)」と出す。作成・挿入・置き換える はいつも同じ場所にあり、押せない間はすぐ左に、欠けているもののうち最初の 1 つを出す(「① に答えてください」→「② のタイトルを書いてください」→「⑤ にスライドを貼り付けてください」。構成案を待つ間は「⑤ に構成案を貼り付けてください」、欄が読めなければ「⑤ の欄の下の知らせを見てください」。挿入は「③ にスライドを貼り付けてください」、修正は「③ にスライドか台本を貼り付けてください」)
  • もう出力を持っているとき(AI の出力を貼り付ける)。 新規作成のページのはじめの説明の下に AI の出力を貼り付ける があり、その下に「スキルで作った出力や、前に作った出力を、そのまま入れます」(チャットの AI に入れた make のスキルは、出力を「新規作成…」→「AI の出力を貼り付ける」に貼るよう案内する)。押すと ① 〜 ④ を隠し、⑤ と同じ 2 つの欄だけの AI の出力を貼り付けます になる(欄に貼った字は ⑤ と共有で、行き来しても残る)。① 〜 ④ に答えなくても 作成 を押せ、押せない間の言葉には番号を付けない(「スライドを貼り付けてください」)。取り込み方は ⑤ とまったく同じ(コードブロックの取り出し・id・組み立て・品質チェック。エラーがあれば品質チェックの板の AI への修正依頼をコピー)。使う場面・タイトル・テーマは貼った教材のまま:名前は <title>、なければ最初の <h1> から(どちらもなければ ai-draft)、テーマは <html data-theme> のまま(③ のテーマは足さない)。問いに答えていないので studio.newDeck と構成案は書かない。問いに答えて作る でふつうの流れ(そのときの状態のまま)に戻る

  • サンプルを参考に作る(このサンプルを参考に作る)。 新規作成のページのはじめの説明の下、AI の出力を貼り付ける の隣に このサンプルを参考に作る があり、その下に「構成・テーマ・パーツを引き継ぎます。中身はあなたの題材で新しく作ります」。押すと ① 〜 ⑤ と 作成 を隠し、参考にするサンプルを選んでください と、はじめの画面のサンプルと同じ一覧(sample.json のあるもの。題名・枚数・本の印)を、それぞれの 選ぶ(読み上げの名前は「選ぶ: 題名」)と一緒に出す。選ぶと、サンプルの窓の このサンプルを参考に作る を押したとき(と ?from-sample=)と同じ、サンプルから始めた新規作成を開き直す(上の「サンプル」)。問いに答えて作る で戻る。一覧はアプリに組み込んであるので、オフライン版のエディタでも出る。サンプルから始めた新規作成と、サンプルのない組み立て(--no-examples)には出ない

  • ファイルから読む。 ⑤(と貼り付けだけの画面、挿入と修正の ③)の 2 つの欄の下の ファイルから読む(「出力のファイル(.txt・.md)を選ぶか、欄にドラッグ&ドロップします」)で、ChatGPT や Claude がファイルで渡した出力を読める。選んだファイルはスライドの欄に、落としたファイルは落とした欄に入れ、貼り付けた字と同じに分ける・移す(信頼しないのも同じ)。読むのは上限つきの読み取り(app/bounded-read.js)だけで、上限は貼り付けた原稿と同じ(32 MB。READ_LIMITS.source)。超えるファイルは読まずに「このファイルは大きすぎます(32 MB まで)。AI の出力のファイルを選び直してください」、.txt・.md でないファイルは「テキストのファイル(.txt・.md)を選んでください」と断り、欄はそのまま

  • 作っている間。 作成 を押してから教材が見えるまで(出力から組み、開き、最初に組み立てるまで。ふつう 1〜2 秒)、ファイルを開くときと同じロゴを「教材を作っています…」と一緒に出し、その間にはじめの画面には戻らない(サンプルから作るときも同じ。Egatari ファイルの 置き換える は「置き換えています…」)。組み立てられなければ窓に戻ってわけを出し、貼った字は残る。

  • 長い教材は 2 回に分けて。 長さが 9 枚から(分は 1 分 ≒ 1 枚)は、写す文の最後に「まず構成案だけを返してください」(R-outline)が付き、AI は ```outline のコードブロック 1 つ(全スライドの見出しと 1 行の要点の表)で返す。⑤ は ⑤ AI の構成案を貼り付けます になり(構成案の欄と 次へ。その間 作成 は押せない)、受け取ると「構成案:24 枚 変更」にたたみ、「6 枚ずつ作ります」と一覧と 1〜6 枚目を頼む指示をコピー(その範囲の deck.html の全体を、構成案と一緒に頼む)と 2 つの欄を出す。作成すると、構成案を egatari.json の studio.outline({v: 1, next, rows})に残す(updateConfig を通すので、ほかの項目はバイトのまま)。知らせに 構成案:残り N 枚(全 M 枚) と 次の 6 枚を頼む が出て、スライドの挿入のページで次の範囲(「構成案の 7〜12 枚目」。構成案と前のスライド付き)を頼み、入れた後に next を進める。壊れた構成案(コードブロックがない・閉じていない・表の行がない・見出しのない行・2 枚より少ない・60 枚より多い)は、わけを言って断る

    エディタは 2 つのコードブロック deck.html と narration.md を取り出す(```html・```markdown・```html title="deck.html" のような名前や、コードブロックの前の行のファイル名も分かる。Windows の改行、前・間・後の文章、余分なコードブロックはかまわない。同じファイルが 2 つなら最後のものを使う)。コードブロックの右上のコピーで写したものには の行がないので、中身から決める(`<section class="slide"` があればスライド、`## 見出し` と `[0]` などの行があれば台本)。 の行がなく両方が入ったものは分けられないので、写し方を添えて断る。どちらでもないものも断る。閉じていないコードブロックは出力が途中で切れたということなので、その欄にそう書き、送り直しの指示をコピー を出す(足りない台本だけ、または教材の全体を短くして送り直してもらう)。切れたのが台本だけなら、スライドは受け取り、送り直してもらった台本を台本の欄に貼る。コードブロックの印なしで画面からコピーした出力の全体は、<!DOCTYPE html> から </html> までをスライド、その後ろを台本として取り出し、そのことを知らせる

  • id。 AI にはスライドの id を書かないように頼んでいる。エディタは、id のないスライドに新しい id を付け、台本の見出しを ## 見出し {#id} に書き換える(npm run ids と同じ本体の kit/core/slide-ids.mjs)。見出しが同じスライドが 2 枚以上あれば、台本のその見出しの節を順に対応させる

  • 開いたファイルと同じに扱う。 原稿は組み立ての Worker で Egatari ファイルにし、開いたファイルとまったく同じに開く:コードの確かめは中身から決めるので、<script>(ほか動くもの)の入った出力は先に プレビューを始める を聞き、キャンセルなら何も開かない。新しい教材は新しい docId で、まだ保存していない(●)。保存 で保存先を聞く。開くときに、最後に指示を写したときの選び方を egatari.json の studio.newDeck({v: 1, plan, category, subcategory, parts}。parts は印の付いたパーツ。前の記録の subjects・tools・purposesOff は読むだけで書かない。plan は free か paid、plan のない前の記録は free。updateConfig を通す)に残す。シード値は書かない(format spec §8.4:パーツの見せ方は variant="<名前>" だけで選び、書かなければそのパーツの既定の見せ方。原稿にある variant はそのまま残す。前の原稿の data-egatari-seed は誰も読まない属性で、消さずにそのまま残る)。自分の下書きなので編集の確認は出さない。開いたら品質チェックをかける

  • スライドの挿入… → チャットの AI に書いてもらう(backlog #93)。3 つの問い:① どんなスライドを足しますか(挿入する場所を出し、足す枚数(1〜10)と足したいこと)→ ② チャットの AI に指示を送ります(専用の短い指示。kit/core/llm-insert.mjs:「スライド X の後ろに、続きのスライドを n 枚」、スライドの見出しの一覧、挿入する場所の前のスライドとその台本だけ。教材を作ったのとは別のチャットに送るときは この教材を作ったのとは別のチャットに送る(指示の全体も付けます) に印を付けると、前に指示が入る——印を付けると、合わせた文章が詳細の指示と同じくらい長くなりうるので、新規作成の ④ と同じ 指示をファイルに保存/指示をコピー の主従の入れ替えと添付の案内の行が出る)→ ③ AI の出力を貼り付けます(新規作成の ⑤ と同じ 2 つの欄。台本の欄が空なら「台本なしで挿入します」)→ 挿入。出力のスライドを順にその場所へ入れ、スライド一覧と同じやり方(newIdFor)で新しい id を付け、台本の節(## 見出し {#id})を同じ順で入れ(台本のないスライドには仮の行)、スライド一覧と同じ道で書き(.cache/edits/ の控え・元に戻す・組み直し)、品質チェックをかける

  • 修正… ① どこを直してほしいですか(直してほしいこと。なくてもよい)→ ② チャットの AI に修正依頼を送ります(品質チェックの指摘(かけ直す)、① に書いたこと、開いているコメント(comments.json。解決したものは入れない。ピンやマーカーの画像は backlog #90)、今のスライドと台本。直すことがなければそう言う)→ ③ AI の出力を貼り付けます(同じ 2 つの欄。「直したスライドだけが出力されたときは、そのスライドだけを置き換えます」)→ 置き換える。片方の欄だけでも押せる(横に「台本は今のままにします」か「スライドは今のままにします」)

  • AI への修正依頼をコピー。 品質チェックの板にある。修正依頼の文章をクリップボードにコピーして見せる:指摘(エラーと警告)、それが破った規格(規格には R-title のような名前があり、文章は同じ指示から取る)、教材が使っているパーツの説明(指示と同じ文章)、はみ出しと小さい字の量(「本文を 97 px(46 px の行でおよそ 3 行)減らす」「字を 23.2px から 24px 以上に上げる」)、台本についての組み立ての知らせ、今の deck.html と narration.md。教材が長い(合わせて 40000 字を超える)ときは、指摘のあるスライドとその台本だけを載せ、そのスライドだけを返すよう頼む。文章の横の 修正依頼をコピー で、何度でもコピーし直せる(ほかのものをコピーした後など)。同じチャットに貼り付け、AI の出力を貼り付ける… を押すと、修正… の ③ が開く

  • 置き換え(修正… の ③)。 出力を今の教材に入れる(Egatari ファイル(再生専用)では使えない)。文書はそのまま:Egatari ファイルなら docId・設定・音声・パーツを残して原稿だけを入れ替える(保存するまでは未保存)。フォルダなら deck.html と narration.md を、.cache/edits/ に控えを残して書き、コードが現れたらコードの確かめをもう一度聞く。id 付きの <section> の一部だけの出力は、そのスライドと台本の節だけを置き換える。台本の欄だけなら台本だけを(節がどれも id 付きなら、その節だけを)置き換える

  • 品質チェックに足したもの: スライドにないステップの台本(エラー)、表紙など static のスライドの台本、式やいくつもの記号を入れた読みの指定 {x|y}(警告。読みは 1 つの記号か用語に 1 つ)。コマンド版の品質チェックも同じ 3 つを見る

書き換えるファイル

開発サーバーとまったく同じ(dev-server.ja.md の「書き換えるファイル」)。どれも選んだフォルダの中

  • deck.html:編集した要素の中身だけ
  • narration.md:編集したステップの行だけ(注釈やほかの行はそのまま)
  • comments.json:コメント [{id, created, key, range, pin, quote, comment, status}](pin は押した点 {x, y} のスライドの座標、1280×720。マーカーは描いた印 strokes を足す(前のコメントは 1 本の stroke のこともある):約束事 §13。開発サーバーを参照。コメントが何を指しているかを見るには、フォルダに npm run comment-shots -- <作業フォルダ> を動かす:未対応のコメントごとに、そのステップをピン付きで .cache/comment-shots/ に描く)
  • audio/<rec|tts|imp>_<hash>.mp3 と audio/manifest.json:音声の板の この音声を使う で(変わるのはそのステップの記録だけ。前の manifest は控える)
  • スライド一覧で:deck.html(スライドをまるごと入れる・写す・消す・動かす)、narration.md(節をまるごと)、audio/manifest.json と、スライドを消したときはその音声の audio/ のファイル(先に控える。元に戻すで書き戻す)
  • 「本」の板で:保存した本のファイル(article.md か article/<名前>.md。ファイルをまるごと)と、確認済みにする では egatari.json の articleLinks(ほかの項目はバイトのまま)
  • .cache/edits/:書き換える前の deck.html・narration.md・audio/manifest.json(と本のファイル・egatari.json)(新しい 30 個。掃除で消すのは控えの名前の形(<時刻>-<名前>)のファイルだけで、フォルダのほかのものは残す)
  • 作業フォルダの「名前を付けて保存…」・「参加者用(再生専用)…」・「LMS 用(SCORM)…」では選んだファイル(と、初回はフォルダの設定のファイルの教材の識別子。SCORM の zip はダウンロードするだけ)
  • Egatari ファイルを開いたとき:保存するまで何も書かない(直したものはメモリの上)。保存では選んだファイルだけ(組み直さない保存では、上に挙げた所だけを書き換える)、「作業フォルダにエクスポート…」では選んだ空のフォルダのファイルだけ

できないこと

  • Chrome・Edge だけ。 スマートフォンのブラウザもフォルダを開けない
  • この PC で AI 音声を作るモデル。 モデルは編集アプリのサイトのブラウザのキャッシュに置かれる(Irodori-TTS は約 1.26 GB、Kokoro は約 330 MB)。「使い方」に、このサイトが使っている保存領域(navigator.storage.estimate)と入っているモデルが出て、「モデルを消す」で消せる(作った音声は消えない。次に使うときに取得し直す)。TTS の窓はモデルを読み込むとき、古いバージョンのモデルのキャッシュを消し、ブラウザに保存領域を残すよう求める(navigator.storage.persist)。求めが通らなければ、ディスクの空きが足りないときにブラウザがモデルを消すことがあり、Safari は 1 週間ほど開かないと消す
  • コマンドで行うもの: 自分の参照音声やサーバーのエンジンでの TTS(tts/synth.py)・動画(tts/ render/)、品質チェックのコマンド版(npm run check)、tools/pdf.mjs。プレビューは audio/manifest.json の音声(フォルダでも Egatari ファイルでも)を自動再生(a)で鳴らす:編集アプリが音声のファイルを読んでそのバイトをプレビューに渡し、プレビューは自分の文書の blob: の URL で鳴らす(砂場のプレビューはフォルダも編集アプリの blob: の URL も読めない)
  • 音声の板は編集アプリだけ。 開発サーバーには音声の板がない(フォルダを編集アプリで開くか、tts/synth.py を使う)。AI 音声をこの PC で作るには、WebGPU と、配信版か配った編集アプリが要る
  • 字はコマンドと同じく切り出す。 Egatari ファイルに保存・エクスポートするとき、埋め込む字体を教材が使う字だけに切り出す。コマンドと同じ harfbuzz(WebAssembly)なので、字はコマンドで組んだものとバイトまで同じ(tools/test-app.mjs と tools/test-font-subset.mjs が確かめる)。切り出しのツール(font-subset.js、約 2 MB)は初めてエクスポートするときに読み込み、読み込めなければ分割ファイルをそのまま入れる(大きくなるだけで、見た目は同じ)。プレビューは切り出さない。後で字を足す編集(台本や本の段 A の保存)は、埋め込んだどの字体にも、その字だけの小さな補いを足す。字体のファイルを持たない編集アプリ(オフライン版のエディタ editor.html は明朝を持たない)でも保存はでき、開く端末の字体で出る字を名指して知らせる
  • オフライン版のエディタに明朝はない。 配信版の編集アプリは BIZ UDP明朝を持つ(明朝を使う教材、たとえばテーマ kokugo のときだけ読む)が、オフライン版のエディタ dist/editor.html は小さく保つために持たない。そこでは明朝の教材は知らせを出して組まれ、開く端末の明朝で表示されます
  • 同梱のもの。 パーツライブラリのパーツ(vendor/components/ のすべてのバージョンと components.lock.json)・テーマ(themes/)・実行系(kit/)は、アプリを組んだときのもの。教材は、記録したハッシュに合うバージョンのパーツがアプリにあれば、そのバージョンで組み直す。テーマも同じく記録したバージョンで組み直す(前のバージョンは vendor/themes/ と themes.lock.json)。そのバージョンが今のバージョンでなければ、プレビューは記録した色のままで、上の知らせがそう言い、今のバージョンで変わる色(前 → 今、色見本つき)を挙げて「テーマを更新」を出す。今のバージョンで組み直すのはそのボタンを押したときだけ(egatari.json の themes と教材の記録を替える。保存すると新しい色で書く)。黙って色を変えない(リファレンス「テーマのバージョン」)。作業フォルダの中のパーツとテーマ(components/<名前>/index.js、themes/<名前>/)は、いつもどおりフォルダから読む。どちらにもないテーマ(自分のテーマのフォルダにある機関のテーマなど。コマンドは EGATARI_THEMES・~/.egatari/themes で見つける)は theme not found: "<名前>" と警告して default で組み、プレビューの上の知らせに「テーマを読み込む…」を出す(警告の一覧にも)
  • テーマを読み込む。 「テーマを読み込む…」(テーマの知らせ、新規作成の ③ のテーマの一覧の最後、はじめの画面の「自分のテーマ…」)で、小さな窓「テーマを読み込む」を開く:「テーマを ZIP ファイルか、テーマのフォルダから読み込みます。」と、「ZIP ファイルを選ぶ…」「フォルダを選ぶ…」(フォルダを選べるブラウザ(Chrome・Edge)だけ)「キャンセル」。ファイルやフォルダを選ぶ画面はそのボタンから開くので、iPad でも開ける。
  • 自分のテーマのフォルダ。 「フォルダを選ぶ…」で、自分のテーマのフォルダ(たとえば ~/.egatari/themes。macOS の選ぶ画面では ⌘⇧. で隠しフォルダが見える)を 1 回だけ選ぶ。その後はコマンドと同じ順と同じ根の決まりでテーマを探す:作業フォルダ → その themes/ → このフォルダ → 同梱のテーマ。テーマのファイル・ロゴ・extends の親は、そのテーマの根(か同梱のテーマ)の外に出ない。フォルダは読むだけで開き、書き込まない。中身は教材のファイルと同じく信頼しない(テーマの CSS は同じ消毒を通り、ロゴは data URI になる)。読むのは、組み立てが使うテーマのファイルだけ。ブラウザはフォルダのハンドルを IndexedDB に残し(中身は残さない)、次に要るときに読む許可をもう一度求める:知らせに「テーマのフォルダ「<名前>」を使う」を出す。「自分のテーマ…」で今のフォルダとそのテーマを見て、「このフォルダを忘れる」で忘れる。Egatari ファイルにエクスポート・保存すると、使った自分のテーマは原稿の themes/<名前>/ として入るので、ほかの所でも同じテーマで組み直せる(npm run build -- --portable で作った Egatari ファイルは、もうそこに入れている)
  • ZIP ファイルのテーマ(自分のテーマ)。 フォルダを選べない Safari・Firefox・iPad も含め、どのブラウザでも「ZIP ファイルを選ぶ…」で .zip からテーマを読み込める。ZIP ファイルの中の深さ 5 までの、tokens.css のあるフォルダがそれぞれ 1 つのテーマで、名前はそのフォルダの名前(ZIP ファイルの最上位に tokens.css があればファイルの名前)。すべて読み込むので、同じ ZIP ファイルの中のテーマどうしの extends も解決する。読むのは tokens.css・theme.json・その logos に書いたテーマのフォルダの中のロゴ・最上位の LICENSE* だけ。ZIP ファイルは信頼しない:32 MB・3000 項目・テーマのファイルは合わせて 16 MB まで(tokens.css 4 MB、theme.json 64 KB、ロゴは 1 つ 4 MB)。..・絶対パス・シンボリックリンクの項目や、1 つの小文字の識別子(^[a-z][a-z0-9-]{0,63}$)でないテーマの名前があれば、ファイルごと読み込まず、その項目の名前と次にすることを知らせる。読み込んだテーマは中身ごとこのブラウザに保存し(IndexedDB。テーマの名前ごと)、テーマの一覧の「自分のテーマ」の見出しの下に出す。同じ名前のテーマがもうあれば置き換え、「同じ名前のテーマ「<名前>」があったので、今読み込んだものに置き換えました。」と知らせる。はじめの画面の「自分のテーマ…」は、保存したテーマを見せる名前ごとに並べ、それぞれに「削除」を付ける(確かめてから消す:「「<名前>」をこのブラウザから削除します。読み込んだ ZIP ファイルは残ります。」)。削除したテーマを使う教材は default で組み、知らせに「このブラウザに保存したテーマにありません(削除したか、まだ読み込んでいません)。「テーマを読み込む…」で ZIP ファイルかテーマのフォルダから読み込んでください」と出す。組み立ては保存したテーマをテーマのフォルダと同じ場所・同じ順・同じ決まりで読み、テーマのフォルダにも同じ名前のテーマがあれば、あとから選んだ・読み込んだほうを使う(そのようなフォルダを選ぶと「同じ名前のテーマ「<名前>」が、このブラウザにも保存してあります。フォルダのものを使います。」と知らせる)。テーマの ZIP ファイルの作り方:テーマのフォルダを圧縮する(Mac は Finder で右クリック →「圧縮」、Windows は右クリック →「送る」→「圧縮 (zip 形式) フォルダー」)か、GitHub のテーマのリポジトリで「Code」→「Download ZIP」
  • 読まないもの: . で始まる名前と、out/ audio/ video/ bundle/ node_modules/ のフォルダ(3000 ファイル・10 階層まで)。audio/ は Egatari ファイルに保存するときだけ読む
  • 組み直しはまだ比べない。 スライドを直した後の保存は、同梱の kit でファイル全体を組み直す(なので、古い・新しい build で作ったファイルは直した所の外も変わり、字は分割ファイルごと埋め込む)。直したスライドのほかにどのスライドが変わったかは、まだ見せない
  • 字の補いは多めになることがある。 絞り込んだ字に unicode-range のないファイル(以前のバージョンがコマンドで作ったもの)では、元の台本の字があることしか分からないので、絞り込んだ字がもう持っている字の分割ファイルも足すことがある(ファイルが少し大きくなる。字が欠けることはない)
  • 教材の中からの通信は止まる。 外部の画像やスクリプト(https://…)はプレビューに出ない(build はもともと警告する)

仕組みと安全

  • 組み立ては 1 つ。 kit/core/build-core.mjs が組み立ての本体(注記・取り込み・KaTeX・パーツ・台本・強調・秒数・テーマ・ファイルの埋め込み・字)で、Node に依存せず、渡された口を通してだけファイルを読む。kit/build.mjs は Node のファイル(と字の切り出し・ffmpeg)を、編集アプリは選んだフォルダと同梱の kit・パーツ・テーマ・KaTeX・字と同じ字の切り出しを渡す。字の切り出しを切れば、両方が 1 バイトも違わない HTML を出し、エクスポートの切り出した字もバイトまで同じ(tools/test-app.mjs が examples/minimal と examples/tmlr2026-calibration で確かめる)。台本の解析と書き換え(kit/core/narration-core.mjs)と新規作成のテンプレート(kit/templates/new-deck.mjs)も同じく共有する
  • 編集の画面も 1 つで、教材の外にある。 server/editor-ui.js(原稿の欄・台本の引き出し・コメントの欄と一覧)は、ここでは編集アプリのページで、開発サーバーでは外枠のページで動く。どちらも同じ問い合わせ(/__dev/source /__dev/edit /__dev/narration /__dev/comment …)を送り、開発サーバーは HTTP で、編集アプリはページの中で開いたフォルダについて答える(app/devapi.js)。教材の中にあるのは知らせを送る server/hints.js だけ(下)
  • 教材は砂場の中で動き、書き込めない。 プレビューは allow-same-origin を付けない <iframe sandbox="allow-scripts allow-modals"> なので、教材は origin を持たない。編集アプリの画面・保存領域・フォルダのハンドルに届かない。allow-modals は印刷のため。ページの Content-Security-Policy(アプリ自身の読み込みだけを許し、iframe の移動は許さない:frame-src 'none')に重ねて、プレビューの文書には別の決まりを、教材のどのバイトを解析するよりも前に効かせる。編集アプリはプレビューの文書を「信頼する先頭部分(doctype・<html><head>・<meta charset>・CSP の <meta>・小さな信頼する仲立ち)+組んだ教材そのまま」として組み、教材の文書の中を探して決まりを入れることはしない。決まりは connect-src 'none'、画像・字・スタイル・音声は data: / blob: だけ(組み立てが埋め込む)、Worker・iframe・フォーム・<base> は使えない('unsafe-eval' は、取り下げたパーツのバージョンのためだけにプレビューの決まりに残す。次の項目)。発表者ビューは編集アプリが開く窓で、その中の教材もまた同じ決まりの砂場の iframe。やり取りは編集アプリが中継する
  • 編集アプリのページは eval を許さない。許していたのは取り下げたパーツのバージョンのため。 ページ自身の Content-Security-Policy に 'unsafe-eval' はない(あるのは 'wasm-unsafe-eval' だけで、MP3 エンコーダの WebAssembly のため。eval も new Function も許さない。配信版も オフライン版のエディタ editor.html も。試験がページの CSP 違反を見張る)。パーツライブラリ v1.0.0・1.0.1 の m-sweep・m-curves は式を new Function で動かすので、パーツライブラリはそのバージョンを取り下げ(yank)、置き換えを v1.0.2 とした(SECURITY.md)。取り下げたバージョンを記録した教材を開くと、編集アプリは知らせと 「1.0.2 で組み直す」 ボタンを出し、バージョンを勝手に替えることはしない(仕様 §6。組み直すとパーツの同一性の hash や見え方が変わることがあり、組み直した後の知らせに、どの hash が変わったかを書く)。そのときまでは教材は今のまま再生できるが、プレビューの枠(allow-same-origin のない sandbox。編集アプリのページ・保存領域・フォルダのハンドルに届かない origin)の中だけ。枠はこのページの決まりを受け継ぐので、編集アプリの中では取り下げたバージョンの m-sweep・m-curves は式を計算できず、図の代わりの表示(DECK.componentErrors)になり、教材のほかの部分は動く。プレビューの決まり(PREVIEW_CSP)と開発サーバーの教材の文書(編集アプリのページを周りに持たない、最上位の sandbox の文書)は 'unsafe-eval' を残すので、そちらでは取り下げたバージョンも動く
  • 頼みではなく知らせ。 プレビューには書き込みを頼む口がない。送れるのは知らせだけ:「この data-src の範囲と hash の要素を直したい」(編集モードでダブルクリック)、「この要素にコメントしたい」(Alt+クリック。スライドの id とステップ、要素の短い引用、点の近くの字、点のスライドの座標)、鍵の e・n・c・r・Esc(r は録音モードの画面を開くだけ)、今の位置(deck-pos)。知らせは書き込む本文を持たない。編集アプリは送り元の窓と知らせの形を確かめ、編集モードでないときの edit の知らせは無視し、今の原稿を自分で読み、範囲が今の組み立ての直せる要素で hash が合うことを確かめて、自分の欄を見せる。書くのは、その欄や引き出しで「保存」か ⌘/Ctrl+Enter を押したときだけ。編集の確認と読むだけのファイルは、これまでどおりこの書き込みにかかる。編集アプリからプレビューに送るのは、見せるのに要るものだけ(編集モードの入り切り・印を付ける要素・「そのステップへ」・印刷・品質チェック)。コメントの点は開発サーバーと同じく確かめる(数だけ、1280×720 のスライドの外は端に寄せ、ほかの項目は捨てる。app/devapi.js も kit/core/comment-core.mjs でもう一度確かめる)。偽の点で変わるのは印の位置だけで、プレビューの上の印は、編集アプリのページがプレビューの大きさから描く
  • 触るのは選んだフォルダかファイルだけで、ブラウザの許可を得てから
  • 保存は始めたときの教材に結び付く。 待つたび(組み直し・確かめの窓・編集の確認・保存先を選ぶ画面・ファイルを作る・書く)の後に、同じ教材が開いたままかを確かめ、その確かめを書き込みの中まで運ぶ:その間に別の教材を開いたら、ファイルを入れ替えず(書き込みを取り消す)、ほかにも何も書かない。新しい教材の識別子を教材の設定に書くのと「保存した」にするのは、ファイルを書いた後だけ。保存している間にした編集は、保存したファイルに入っていないので、未保存の印のまま
  • 信頼する欄で編集している間(原稿の欄・コメントの欄を開いている、台本の引き出しで入力している・未保存の変更がある)は、プレビューを inert にする。その間は教材からの知らせで板の欄を開け閉め・切り替えせず、編集している台本のステップも替えない
  • フォルダとリンク。 メモリの上・OPFS のフォルダはシンボリックリンクを持てない。選んだフォルダの中のリンクは、Chromium では編集アプリにまったく見えない(一覧に出ず、名前でも開けず、書けない。tools/test-security.mjs が確かめる)ので、組み立てがリンク越しにフォルダの外のファイルを読むことはない。File System Access API には編集アプリ自身がリンクを見分ける手段がないので、これはブラウザに頼っている
  • マイクと TTS は編集アプリのページだけで。 録音(getUserMedia・MediaRecorder)・取り込み・後処理・MP3 にするのは編集アプリのページで、プレビューからは始められず、プレビューから音声を受け取ることもない。録音は録音モードだけで行い、開いている間プレビューは inert。音声の板が音声を作って書いている間は、教材からの知らせで板のステップを替えない。ページの決まりはそのままで通信を許さない:この PC で作る AI 音声は、同じサイトの別の窓(lab/tts-helper.html。試験ページと同じく、バージョンを固定したライブラリを jsDelivr から、モデルを Hugging Face から取る)で動かし、窓に送るのは読む文と声の名前だけ。編集アプリはその窓からの音だけを受け、標本化周波数と長さを確かめ、録音と同じく後処理する。フォルダから読む音声には上限がある(manifest は 16 MiB、音声のファイルは 1 つ 64 MiB)
  • Egatari ファイルを開いても、その中のものは何も動かない。 ファイルはバイト列として読み、スクリプトを動かすブラウザと同じ解析の規則で(何も実行しない)Web Worker(編集アプリに同梱。ページの決まりは blob: の Worker だけを許す)の中で解析する。そのファイルへ移動したり、ページに入れたりはしない。動くのは原稿から組み直した教材だけで、フォルダのときと同じ砂場のプレビューの中

GitHub Pages で配る

.github/workflows/pages.yml が node tools/build-app.mjs --out _site --parts で組み、GitHub Pages に置く(編集アプリは根 /、オフライン版のエディタは /editor.html、試験ページは /lab/irodori.html。前に編集アプリがあった /editor/ は、問い合わせと # を残して / へ移すページ)。パスはどれも相対なので、同じファイルが独自ドメイン https://studio.egatari.org/(Settings → Pages → Custom domain で設定し、サイト全体に効く)でも https://egatari.github.io/egatari-studio/(独自ドメインへ移る)でも動く。置く(deploy)のはリリースのタグだけ:タグ vX.Y.Z(数 3 つ。v0.5.0-rc.1 などの rc のタグは置かない)を push したときと、そのタグで workflow を走らせたとき(そのバージョンを置き直す)。main への push と pull request は組むだけで(リリースの前に組み立ての壊れに気づくため)、ブランチで走らせると組むだけの試し。リリースの手順は RELEASING.ja.md。Pages を設定するまでは何も置かない

  1. Settings → Pages → Build and deployment → Source を GitHub Actions にする
  2. Settings → Secrets and variables → Actions → Variables に EDITOR_PAGES = true を足す(なければ組むだけで、何も置かない)
  3. Settings → Environments → github-pages → Deployment branches and tags にタグの決まり v*.*.* を足す(この environment はふだん main だけを許すので、足さないとタグからの deploy は断られる)
  4. リリースのタグを push するか、タグを選んで workflow を走らせる(Actions → pages → Run workflow)

組み立てはサンプルも Egatari ファイルにして examples/<名前>.ega.html に置き(tools/examples-portable.mjs。合わせて約 37 MB。--no-examples で入れない)、横にサムネイル(<名前>.cover.webp)を置いて、編集アプリの最初の画面に並べる。examples/index.json で path のあるサンプル(本のある heikin-chuouchi・rashomon と、egatari.org のギャラリーの 17 本)は egatari/examples をそのまま写したもの。node tools/examples-sync.mjs <clone> --commit <sha> <名前>… が写し、SOURCE.json にコミットと各ファイルの sha256 を書く。--check(npm run gen:check)は写しが直されていないかを確かめるので、直すときは元のリポジトリで直して写し直す。サムネイルは examples/_covers/:egatari.org のギャラリーにあるものはサイトの絵をそのまま(node tools/example-covers.mjs --site <site>/src/gallery)、Studio だけのものは選んだ絵(--picked <フォルダ>)か 1 枚目のスライドから作った絵(npm run covers)。組むのはサンプルのフォルダの一時的な写しから(examples/ には何も書かない)。egatari.json のないサンプル(テンプレートとして写してよい minimal など)には名前から決めた docId を与えるので、組むたびに同じ文書になる

組み立ては make の生成元から egatari-make-<version>-ja.zip と egatari-make-<version>-en.zip を dist/ に書く。ダウンロードはこのサイト内のファイルを使い、単体の editor.html はオフラインでも使えるよう両言語の ZIP を埋め込む。凍結した /vX.Y.Z/ と編集アプリのサイトのアーカイブも、dist/ のほかのファイルと一緒に ZIP を持つ。

すべてのパーツのサンプル(/parts/)

--parts を付けると、組み立てはすべてのパーツのサンプルのページも作る(tools/parts-gallery.mjs。約 40 秒・10 MB):components2.lock.json の既定(default)のパーツライブラリのバージョンのすべてのパーツを、説明の 1 枚と動くサンプルのスライドで、「新規作成…」の ④ と同じく伝えたいことごとに並べ、前のバージョンと比べて新しい・変わった・サンプルが変わったの印を付ける。置く場所は /parts/v<パーツライブラリの版>/(たとえば https://studio.egatari.org/parts/v2.1.1/)で、/parts/index.html がバージョンを並べ(いまのバージョンが先)、/parts/versions.json も書く。編集アプリの使い方と「新規作成…」の ④ は絶対の URL で張るので、オフライン版のエディタ・file://・Colab からも開ける。ページは取り込んだリリースの写しだけから、git もネットワークも使わずに組む:そのバージョンのファイルを vendor/components/sha256/(そのリリースが配ったときの写し。components2.lock.json の catalogues.<版>.content にパーツごとに記録)から tarball と同じ形に並べ(vendor/components-2/manifest-<版>.json とファイルごとに照らす)、パーツライブラリ自身の gallery.mjs --pack でまとめ、kit/build.mjs で組む。そのツールは egatari/components の決まったコミットの写しを vendor/components-gallery/ に持つ(SOURCE.json がリポジトリ・コミット・各ファイルの sha256 を記録。node tools/parts-gallery.mjs --verify が確かめ、--sync <checkout> が取り直す)ので、タグから組むリリースのアーカイブも同じページを作る。編集アプリと同じく、公開したバージョンは凍結する:組み立ては前の各リリースのアーカイブの parts/ を /parts/ に移し(/vX.Y.Z/ の下には置かない)、同じパーツライブラリのバージョンは最初に公開したリリースのページを残す。いま組んだものは、前に公開していないバージョンにだけ使う

リリースに添えるファイル

npm run release:assets(tools/release-assets.mjs)が同じサンプルのファイルを out/release/ に組み、examples.json(名前・題名・言語・枚数・大きさ・sha256、本があるかの book)を添える。make の生成元から egatari-make-<version>-ja.zip と egatari-make-<version>-en.zip も書く。どこにも上げない。GitHub のリリースには人の手で添える(たとえば gh release create v<版> out/release/*)

バージョンごとの URL(凍結した写し)

サイトは置くバージョンの下限(v0.6.0。下の 置くバージョンの下限)からのすべてのリリースを残す。根は最新のリリース、/vX.Y.Z/(たとえば https://studio.egatari.org/v0.4.2/)はそのリリースを凍結した写しで、中の形は同じ(/vX.Y.Z/editor.html・/vX.Y.Z/lab/…・/vX.Y.Z/examples/…)。Pages は 1 回に 1 つの artifact を置くので、リリースの deploy が組み立てる(node tools/site-versions.mjs assemble):いま組んだものを根と /v<その版>/ に、公開済みの前の各リリースのうち下限からのものは添えたファイル editor-site-vX.Y.Z.tar.gz を取り、リリースの説明の行 editor-site-vX.Y.Z.tar.gz sha256: <16 進>(と GitHub が記録するそのファイルの digest)と合うか確かめて /vX.Y.Z/ に広げる。そのファイルのないリリース(v0.4.0 まで)は飛ばし、sha256 の行がない・合わないときは組み立てを失敗にする。このファイルは組んだ dist/ を、何度作っても同じバイトになるようにまとめたもの(node tools/site-versions.mjs asset vX.Y.Z が、タグの git worktree で npm ci してから組む)で、リリースのときに添える(RELEASING.ja.md)。根の versions.json がバージョンを並べる。main への push と pull request でも、同じ組み立てを試しとして走らせる。1 つのバージョンが約 50 MB なので、GitHub Pages の上限 1 GB には約 18 バージョンが入る。800 MB を超えると知らせ、1 GB を超えると失敗にする。どちらの知らせも、置いている最も古いバージョンを、次に下限を上げるときの候補として挙げる

  • 前のリリースは 1 つだけ。 サイトに置くのは今のバージョン(根と /vX.Y.Z/)と、その 1 つ前のリリースだけ(tools/site-versions.mjs の KEEP_PREVIOUS = 1。2026-11-11 の作者の決定)。リリースのたびに入れ替わる:v0.6.9 を置くと v0.6.8 を置き、v0.6.7 から前は下の「もう置いていない」のページになる。候補(rc)では、その前の最新のリリースを置く。前のリリースだけが公開したパーツライブラリのバージョンのサンプルのページも、一緒に置かなくなる。各リリースの一式は GitHub のリリースから取れる

  • 置くバージョンの下限。 tools/site-versions.mjs の HOSTED_FROM(いまは 0.6.0。v0.6.5 のサイトが 1030 MB になり GitHub Pages に断られたあとの、2026-11-06 の作者の決定)が、サイトに置く最も古いバージョン。それより前のリリースで、添えたファイルが editor-site-vX.Y.Z.tar.gz か editor-site-vX.Y.Z.archived.tar.gz のどちらかの名前であるものは、組み立てが取りも広げもせず、/vX.Y.Z/index.html だけを書く。日本語と英語の短いページで、そのバージョンはもう置いていないこと、GitHub のリリース(一式はそこから取れる)と最新版へのリンクを出す。組み立ての記録にはバージョンごとに 1 行が出る。これらのバージョンは versions.json に入れないので、バージョンの一覧に出ない。その下のほかのパス(/vX.Y.Z/editor.html)は 404 になる。下限を上げるには、HOSTED_FROM を残す最も古いバージョンにして(知らせが候補を挙げる)もう一度置く。リリースに添えたファイルはそのままでよい。ファイルの名前を editor-site-vX.Y.Z.tar.gz に戻しても、下限より前のバージョンはまた置かれない。また置くのは HOSTED_FROM を下げたときだけ(サイトは 1 GB に収まる必要がある)。v0.4.1〜v0.4.8 のファイルは、下限を入れる前に editor-site-vX.Y.Z.archived.tar.gz に名前を変えて残してある。node tools/site-versions.mjs verify が確かめるのは editor-site-vX.Y.Z.tar.gz の名前のファイルだけ

  • 知らせと一覧。 写しは上に 1 行を出す:「Egatari Studio v0.4.2(そのリリースのまま凍結した写し)を使っています」・最新版(根。?lang は残す)へのリンク・ほかのバージョンの一覧。✕ で隠せる。根は最初の画面の下にバージョンの一覧を出す。この知らせより前に組んだ写し(v0.4.1・v0.4.2)には、組み立てが index.html と editor.html に根の version-notice.js を読み込ませる(決まりの <meta> の後に <script> を 1 つ。写しのほかの所は変えない)

  • ブラウザのデータは共有。 どのバージョンも同じサイト(同じ origin)なので、ブラウザのデータを共有する:最近開いたもの(IndexedDB の motion-slides-editor。ファイルのハンドルと名前だけを持ち、どのバージョンも同じ形で読むので、あるバージョンで開いたファイルはどのバージョンにも並ぶ)・画面の言葉(localStorage)・利用者のテーマのフォルダ・この PC で AI 音声を作るモデル(Cache Storage。モデルのバージョンごとの名前なので、同じモデルのバージョンどうしは 1.26 GB の取得を共有する)。ほかのモデルのバージョンのキャッシュを消すのは根だけで、写しは消さない(lab/model-cache.mjs の inFrozenCopy)。ただし写しの v0.4.1・v0.4.2 はこの決まりより前のものなので、後のリリースがモデルを替えると、その新しいモデルを消す。最近開いたものの保存の形を将来変えるときは、DB の名前を替えること(古い写しも開き続けるため)。service worker はない。ウェブアプリの manifest の scope は各写しのフォルダ

確かめ方

node tools/test-app.mjs [作業用のフォルダ] [--shots 画像のフォルダ](npm test に入っている)は、作業用のフォルダに編集アプリを組んで 127.0.0.1 で配り(サイトの形も、根と下のパスの両方で確かめる:編集アプリがコンソールのエラーなしに開く、/editor/?lang=en#x が /?lang=en#x へ移る、/editor.html と /lab/irodori.html が開く)、ブラウザの OPFS(origin-private file system)に作業フォルダを作って window.__APP_TEST_OPEN(handle) で開く。同じ HTML になること・原稿の編集(その間にファイルが変わったときの 409 も)・台本の引き出し(発言を足す・CRLF のまま・409)・コメント・外での変更・組み立ての失敗・品質チェック・エクスポート・発表者ビュー・英語の画面・file:// の オフライン版のエディタと、コンソールのエラーが無いことを確かめる。書き込みを試みる作業フォルダ(tools/hostile-deck.mjs:古い書き込みの知らせと偽の本文の知らせを送り、合言葉を探し、編集アプリのページに触り、書き込みの口に fetch・XHR・beacon するパーツとインラインのスクリプト)は、動く前にたずね、フォルダの中を何も変えず、編集アプリで「保存」を押したときだけ書かれることを確かめる。Egatari ファイルは、examples/minimal(dry-run の音声つき)と tools/portable-fixtures.mjs の試験用の文書から作り、開く・編集の確認(改変を認めないライセンスの確認も)・文字と台本の編集・OPFS のファイルのハンドルへの保存・開き直し(同じ docId、変えていない音声の hash が同じ、展開したフォルダがメモリの上のものと同じ)・「作業フォルダにエクスポート…」と「Egatari ファイルにエクスポート」(同じバイト)・独自のコードの知らせ・印のスクリプトが編集アプリのページでも読み取りの Worker でも動かないこと・断るファイル(パスの抜け出し・新しい major のバージョン・索引の重複・知らない必須の機能)・読むだけのファイル・ダウンロードでの保存、組み直さない保存(形式の所だけが変わることを、場所を見分ける差分で。新しい漢字の字の補い)、組み直しの知らせとキャンセル、新しいファイルとしての保存(docId・derivedFrom)、知らない索引の項目がどちらの保存でも残ること、テーマ庫の hash が違うファイル(台本だけ)、知らない必須の機能のファイルの取り出し、独自のコードをたずねる後ろのプレビューが空であること、ツールの列が両方の言葉で 1280 px と 1440 px で 1 行に収まることを確かめる。tools/test-app-slides.mjs(tools/test-app.mjs が動かす)は、作業フォルダと Egatari ファイルでスライド一覧を確かめる:listbox とキー、テンプレートごとの追加(新しい整った重ならない id・台本の節・品質チェック)、複製(台本は写し、音声は写さない)、確かめの窓のある削除と元に戻す(スライド・台本・音声の記録とファイルがバイトまで戻る)、Alt+↓・ボタン・ドラッグの並べ替え(id・台本の順・音声の鍵)、フォルダを開き直せること、保存した Egatari ファイル(段 B)が読み戻せて開き直せること。node tools/test-slide-ops.mjs(npm test に入っている)は kit/core/slide-ops.mjs の文字列の操作を確かめる。node tools/test-pronounce.mjs は 読み方… を確かめる:語の規則と台本全体の書き換え(kit/core/readings.mjs・narration-core.mjs)、編集アプリ(日本語と英語の画面、読み上げと AI 音声は差し替え)で、選んで読み方を付けた語が原稿では {x|y}・欄ではルビになること、カーソル・元に戻す・やり直し・コピー・Backspace、断る選び方、カーソルの所の語、この台本のすべてに(ほかのステップは保存のときに、控えつき)、辞書、聞く 2 つのボタン、localStorage が例外を投げるときに辞書のチェックが押せずわけの 1 行が出て、読み方は付けられ保存できること。node tools/test-audio.mjs [作業用のフォルダ] [--shots 画像のフォルダ](npm test に入っている)は、Chromium の偽のマイク(作った声らしい信号を入力のファイルに)と差し替えの TTS(モデルを取りに行かない)で音声の板を確かめる:入力の大きさの表示と inert のプレビューでの録音、取り直しの一覧、この音声を使う(MP3・manifest の記録・控え)、台本を直した後の古いの印と警告、品質チェック、作り直し(読み辞書・タイミングの時刻・recipe)、Egatari ファイルを段 A で保存してそのステップの音声だけが変わること(場所を見分ける差分)、lab/tts-helper.html?stub=1 での TTS の窓とのやり取り、WebGPU が使えなければクラウドと録音だけを出すこと、新しい板(状態の 1 行とボタン 1 つ・声を変えたステップの数・B の答えの並び・音声がないときと、いちばん新しい音声の種類ごと(録音・Colab・この PC)の開いたときの答え・差し替えた端末の確かめ(メモリが少ない・スマートフォンやタブレット:「この PC」を出すが押せず、わけを添え、クラウドにする)・egatari.json に何も書かないこと・C のボタン・2 人の声の欄の言葉・外したものがないこと)。node tools/test-colab-app.mjs は手順 1〜3(番号の札と見出し・確かめは 1 回だけ・手順 2 の下の a〜d と時間・書き出した後と取り込んだ後の ✓・フォルダを選ぶ仕組みなしのふつうのファイルの選択での ZIP ファイル。COLAB_SHOTS=<フォルダ> で板の画面を幅 1280 と 390 で写す)。node tools/test-audio-core.mjs(npm test に入っている)は後処理を tts/core.py と比べ(uv と ffmpeg があれば)、MP3 とそれを戻した長さ、読み辞書を tts/yomi.py と、記録と古さ、音声を替えた段 A の保存を確かめる。node tools/test-tier-a.mjs(これも npm test に入っている)は組み直さない保存だけを、examples/minimal と examples/tmlr2026-calibration で確かめる:場所を見分ける差分、ヘッドレス Chrome での再生、展開とまとめ直し、ほかの書き手のファイル、知らない項目、音声の差し替え、新しい教材、断る場合。node tools/test-workspace.mjs は、メモリの上のフォルダと権利の規則をブラウザなしで確かめる。スライドのファイル deck.html を開くこと(たずねる窓・キャンセル・フォルダを開く…・このファイルだけ:deck.html だけのメモリの上の教材が品質チェックを通り、保存先をたずねてから Egatari ファイルに保存できる。examples/tmlr2026-calibration/deck.html だけでは、ないファイルが知らせになる)、組んだ out/deck.html・再生専用のファイル・ほかの HTML をそれぞれの言葉で断ること、最初の画面からすべてのサンプルを開けること(コードの確かめは独自のコードのあるものだけ)、dist/examples/ が根と下のパスで配られ、オフライン版のエディタにはサンプルの一覧が出ないことも確かめる。バージョンを並べたサイト(組んだものを根と /v<版>/ に、知らせを持たない古い写しの代わりを /v0.0.1/ に)も組み、根のバージョンの一覧・古いバージョンを選ぶこと・凍結の知らせと最新版へのリンク(両方の言葉)・/v<版>/ が自分の app.js を読みサンプルを開けること、発表者ビューで始めた自動再生でプレビューの音声が(音を消さずに)鳴り、発表者ビュー自身は何も鳴らさないことを確かめる。node tools/test-site-versions.mjs(npm test に入っている)は、同じバイトになるまとめ方・危ない中身を断ること・sha256 の確かめ・組み立てをブラウザなしで確かめる。

node tools/test-recording.mjs [作業用のフォルダ] [--shots 画像のフォルダ](npm test に入っている)は、偽のマイクとキーボードだけで録音モードを確かめる(Space・Enter・Backspace・C・矢印・Esc、cue と sync、取り直し、live region の知らせ、プレビューの inert、知らせの道の安全、音声の板の「● 録音 (r)」:板のステップで開き、1 段録って Esc で板に戻ると新しい音声が出る)。node tools/test-audio.mjs は音声の板と、録音モードを通した音量の調整・音が割れた知らせ・600 秒の上限(試験では短くする)・使っていない音声・マイクを使えないときを確かめる。node tools/test-rec-core.mjs は C の押し方が cue になる計算を確かめる

画面の言葉

ふだんはブラウザの言語(日本語か英語)に合わせる。右上の English / 日本語 のボタンで切り替えるか、…/?lang=en・?lang=ja で開く。選んだ言葉は覚えておき、教材を開いたまま切り替えても同じフォルダを開き直す(開いた Egatari ファイルは閉じる。保存していない変更があれば先にたずねる)。編集のツール(編集モード・原稿の欄・台本の引き出し・コメント)は編集アプリの言葉に合わせる(開発サーバーでは教材の言語 <html lang> に合わせる)。