[m10-B] auto-cut drops no-op kept cuts (orchestrator amendment)

A hand-placed cut is kept only if it genuinely changes the angle: the plan now
merges surviving cuts with the placed ones, walks the merged list tracking the
EFFECTIVE camera, and drops in-range user cuts whose camera equals it. Real
case: 4.50->cam2 became a no-op once auto-cut placed cam2 at 1.4161 - it
rendered as nothing but read as an edit in the saved file. Removed in the same
group() so it stays one undo; popover and toast report kept vs dropped; cuts
outside the placed range are still never touched.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
type-two 2026-07-26 11:52:02 +10:00
parent 29694afda5
commit 838edd0e1f
5 changed files with 494 additions and 12 deletions

View File

@ -529,3 +529,39 @@ NEXT: nothing required. Backlog if a session 9 lands, in order: (1) "nudge to
(2) box-select still only grabs keys, not clip/audio blocks or cuts; (3)
per-drag undo coalesce (a mousemove drag still pushes one entry per frame);
(4) film-level `audio[]` has no UI — the obvious partner to ♪ align.
## 2026-07-26 session 8b (SYNC13 follow-up: drop no-op kept cuts)
DONE: orchestrator's M10-B acceptance note actioned — a kept cut that selects the
camera already live is now DROPPED, not preserved. `autoCutPlan` (`timeline.js:668-690`)
no longer filters `kept` positionally; it merges the surviving existing cuts with
the about-to-be-placed ones, sorts by t, walks the merged list tracking the
EFFECTIVE camera, and splits in-range user cuts into `kept` (changes the angle)
vs `dropped` (`camera === eff` — cuts cam2→cam2, i.e. nothing). `autoCut`
(`:704`) removes `dropped` alongside `replaced`, inside the same `group()`, so it
is still ONE undo. Popover line now reads "… · 2 of your cuts kept · 1 dropped
(no camera change)"; the apply toast says which and why.
Walking the MERGED list (not comparing to the previous array element) is the
point: the duplicate only exists once the auto cuts are in — 4.5:cam2 is a
perfectly good cut in the file as saved, and only becomes a no-op because
auto-cut puts cam2 at 1.4161.
TEST: +3 cases (`timeline_test.mjs:566-598`): a cut that changes the angle is kept
(unchanged behaviour, still asserted), a cut duplicating the incoming auto camera
is dropped and ONE undo restores it with everything else, and a mixed pair
(2.0:camA redundant after the 1.4161 auto camA / 6.0:camA real after the 5.1654
auto camB) drops exactly one and keeps exactly one. Also asserts the final list
has no consecutive camera repeat AT ALL, which is the property that was missing.
Replayed the orchestrator's own case on `scenes/music-video.json`: file cuts
`0:cam1, 4.5:cam2` → auto-cut cadence 2 → `0:cam1 1.42:cam2 5.17:cam3 8.91:cam4
12.66:cam1`, the 4.5 no-op gone, no repeats, one undo byte-identical to the file.
`node scenegod/web/timeline_test.mjs` green; `node --check` clean on all four.
DECISIONS:
- The drop is limited to cuts INSIDE the placed range and only when the camera is
genuinely unchanged. A user cut before the first or after the last placed cut is
still never touched — auto-cut has no business outside its own range.
- Noted for whoever picks up `♪ align`: the "name the grid source in the status
line" pattern is endorsed by the orchestrator; shot lists can in principle span
scenes with different grids, and saying which one was used is the honest answer
rather than silently picking. Keep that pattern for anything similar.
BLOCKED/REQUESTS: unchanged from session 8.
NEXT: unchanged from session 8 (nudge-to-grid, box-select beyond keys, per-drag undo
coalesce, film-level audio[] UI).

View File

@ -1773,3 +1773,401 @@ INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/82 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/83 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/84 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/85 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/86 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/87 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/88 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/89 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/90 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/91 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/92 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/93 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/94 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/95 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/96 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/97 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/98 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/99 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/100 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/101 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/102 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/103 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/104 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/105 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/106 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/107 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/108 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/109 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/110 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/111 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/112 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/113 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/114 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/115 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/116 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/117 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/118 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/119 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/120 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/121 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/122 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/123 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/124 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/125 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/126 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/127 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/128 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/129 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/130 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/131 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/132 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/133 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/134 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/135 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/136 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/137 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/138 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/139 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/140 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/141 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/142 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/143 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/144 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/145 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/146 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/147 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/148 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/149 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/150 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/151 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/152 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/153 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/154 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/155 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/156 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/157 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/158 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/159 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/160 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/161 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/162 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/163 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/164 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/165 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/166 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/167 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/168 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/169 HTTP/1.1" 200 OK
INFO: 127.0.0.1:60355 - "GET /web/timeline.js HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/170 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/171 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/172 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/173 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/174 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/175 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/176 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/177 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/178 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/179 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/180 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/181 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/182 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/183 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/184 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/185 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/186 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/187 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/188 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/189 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/190 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/191 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/192 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/193 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/194 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/195 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/196 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/197 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/198 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/199 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/200 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/201 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/202 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/203 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/204 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/205 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/206 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/207 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/208 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/209 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/210 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/211 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/212 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/213 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/214 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/215 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/216 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/217 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/218 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/219 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/220 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/221 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/222 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/223 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/224 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/225 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/226 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/227 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/228 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/229 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/230 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/231 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/232 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/233 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/234 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/235 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/236 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/237 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/238 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/239 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/240 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/241 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/242 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/243 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/244 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/245 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/246 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/247 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/248 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/249 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/250 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/251 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/252 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/253 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/254 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/255 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/256 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/257 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/258 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/259 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/260 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/261 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/262 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/263 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/264 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/265 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/266 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/267 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/268 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/269 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/270 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/271 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/272 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/273 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/274 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/275 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/276 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/277 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/278 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/279 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/280 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/281 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/282 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/283 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/284 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/285 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/286 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/287 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/288 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/289 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/290 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/291 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/292 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/293 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/294 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/295 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/296 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/297 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/298 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/299 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/300 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/301 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/302 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/303 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/304 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/305 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/306 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/307 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/308 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/309 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/310 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/311 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/312 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/313 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/314 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/315 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/316 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/317 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/318 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/319 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/320 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/321 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/322 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/323 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/324 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/325 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/326 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/327 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/328 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/329 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/330 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/331 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/332 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/333 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/334 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/335 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/336 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/337 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/338 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/339 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/340 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/341 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/342 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/343 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/344 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/345 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/346 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/347 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/348 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/349 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/350 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/351 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/352 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/353 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/354 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/355 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/356 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/357 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/358 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/359 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/360 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/361 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/362 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/363 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/364 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/365 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/366 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/367 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/368 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/369 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/370 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/371 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/372 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/373 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/374 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/375 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/376 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/377 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/378 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/379 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/380 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/381 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/382 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/383 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/384 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/385 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/386 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/387 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/388 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/389 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/390 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/391 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/392 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/393 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/394 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/395 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/396 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/397 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/398 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/399 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/400 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/401 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/402 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/403 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/404 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/405 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/406 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/407 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/408 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/409 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/410 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/411 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/412 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/413 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/414 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/415 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/416 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/417 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/418 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/419 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/420 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/421 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/422 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/423 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/424 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/425 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/426 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/427 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/428 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/429 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/430 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/431 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/432 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/433 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/434 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/435 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/436 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/437 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/438 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/439 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/440 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/441 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/442 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/443 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/444 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/445 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/446 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/447 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/448 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/449 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/450 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/451 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/452 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/453 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/454 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/455 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/456 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/457 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/458 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/459 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/460 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/461 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/462 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/463 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/464 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/465 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/466 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/467 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/468 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/469 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/470 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/471 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/472 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/473 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/474 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/475 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/476 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/477 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/478 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/frame/479 HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "POST /render/ea9cb4e30f8744b7b3a8ba2534baa0df/end HTTP/1.1" 200 OK
INFO: 127.0.0.1:59773 - "GET /render/ea9cb4e30f8744b7b3a8ba2534baa0df/status HTTP/1.1" 200 OK

View File

@ -669,14 +669,29 @@ export class Timeline {
// so a hand-placed cut near the downbeat is absorbed rather than duplicated
// into a flash frame). Cuts elsewhere in the range are left alone.
const replaced = this.cameraCuts.filter((c) => times.some((t) => Math.abs(c.t - t) <= eps));
// Hand-placed cuts elsewhere in the range are NOT touched (deleting someone's
// edit is over-reach) — but they interleave, and one of them can repeat a
// camera. Report them so the popover can say so instead of the user
// wondering why a beat-perfect edit has a stutter in it.
const kept = this.cameraCuts.filter((c) => c.t >= times[0] && c.t <= times[times.length - 1]
&& !replaced.includes(c) && !times.some((t) => Math.abs(c.t - t) <= eps));
// Hand-placed cuts elsewhere in the range are NOT touched — deleting someone's
// edit is over-reach — with ONE exception (SYNC13, orchestrator): a kept cut
// that selects the camera already live at that instant is a literal no-op. It
// cuts from cam2 to cam2, nothing happens on screen, and it still rides into
// the saved scene looking like an edit. Those are dropped; the rest are
// reported as `kept` so the popover can own the interleave out loud.
// The "already live" camera is the EFFECTIVE one after the auto cuts are
// merged in, so walk the merged list in time order rather than comparing
// against the previous array element.
const survivors = this.cameraCuts.filter((c) => !replaced.includes(c));
const merged = [...survivors.map((c) => ({ c, auto: false })), ...cuts.map((c) => ({ c, auto: true }))]
.sort((a, b) => a.c.t - b.c.t);
const kept = [], dropped = [];
let eff = null;
for (const m of merged) {
if (!m.auto && m.c.t >= times[0] && m.c.t <= times[times.length - 1]) {
if (m.c.camera === eff) { dropped.push(m.c); continue; } // cuts from X to X = nothing
kept.push(m.c);
}
eff = m.c.camera;
}
return {
ok: true, cuts, replaced, kept, cameras: cams, cadence,
ok: true, cuts, replaced, kept, dropped, cameras: cams, cadence,
barPeriod: this._beatPeriod('bar'), confidence: g.confidence ?? 0, bpm: g.bpm,
from, to,
};
@ -689,6 +704,7 @@ export class Timeline {
if (!plan.ok) throw new Error(plan.error);
this.group(() => {
for (const c of plan.replaced) this.removeCut(c);
for (const c of plan.dropped) this.removeCut(c); // no-op cuts (cam X → cam X)
for (const c of plan.cuts) this.addCut(c.t, c.camera);
});
this.seek(this.time); // the new cut under the playhead goes live

View File

@ -586,11 +586,12 @@ assert.equal(tlAC.cameraCuts.filter((c) => Math.abs(c.t - bars[2]) < 1e-9).lengt
tlAC.undo(); tlAC.undo();
assert.equal(tlAC.cameraCuts.length, 0, 'undo unwinds the replacement too');
// a hand-placed cut BETWEEN downbeats is left alone — and disclosed, because it
// interleaves and can repeat a camera (the popover says so; we don't delete it)
tlAC.addCut(4.5, 'camB');
// a hand-placed cut BETWEEN downbeats that GENUINELY changes the angle is left
// alone — and disclosed, because it interleaves with the beat cuts
tlAC.addCut(4.5, 'camB'); // cadence 2 puts camA at 1.4161 → this really cuts
const pk = tlAC.autoCutPlan({ cadence: 2 });
assert.equal(pk.kept.length, 1, 'an off-grid cut inside the range is reported as kept');
assert.equal(pk.kept.length, 1, 'an off-grid cut that changes camera is reported as kept');
assert.equal(pk.dropped.length, 0, 'and is not dropped');
assert.equal(pk.replaced.length, 0, 'and is NOT counted as a replacement');
tlAC.autoCut({ cadence: 2 });
assert.equal(tlAC.cameraCuts.length, 5, 'the user\'s own cut survives auto-cut (4 placed + 1 kept)');
@ -598,6 +599,35 @@ assert.ok(tlAC.cameraCuts.some((c) => c.t === 4.5 && c.camera === 'camB'), 'exac
tlAC.undo(); tlAC.undo();
assert.equal(tlAC.cameraCuts.length, 0, 'and both come back off');
// SYNC13: a kept cut that selects the camera ALREADY LIVE is a no-op — it cuts
// camA→camA, nothing happens on screen, and it would ride into the saved scene
// looking like an edit. Drop it, and say so.
tlAC.addCut(4.5, 'camA'); // camA is live from the 1.4161 auto cut
const beforeDrop = structuredClone(tlAC.cameraCuts);
const pd = tlAC.autoCutPlan({ cadence: 2 });
assert.equal(pd.dropped.length, 1, 'a no-op cut is reported as dropped');
assert.equal(pd.kept.length, 0, 'and is not reported as kept');
assert.equal(pd.dropped[0].t, 4.5, 'the right cut is named');
tlAC.autoCut({ cadence: 2 });
assert.equal(tlAC.cameraCuts.length, 4, 'the no-op cut is gone — only the 4 beat cuts remain');
assert.ok(!tlAC.cameraCuts.some((c) => c.t === 4.5), 'specifically that one');
assert.ok(tlAC.cameraCuts.every((c, i, a) => i === 0 || c.camera !== a[i - 1].camera), 'the final list has no camera repeat at all');
tlAC.undo();
assert.deepEqual(tlAC.cameraCuts, beforeDrop, 'ONE undo restores the dropped cut along with everything else');
tlAC.undo();
assert.equal(tlAC.cameraCuts.length, 0, 'and the manual cut comes off with the next undo');
// the effective camera is judged AFTER the auto cuts merge in, not against the
// previous array element: this cut duplicates a camera that only exists once
// auto-cut has run, and is still caught
tlAC.addCut(2.0, 'camA'); // 1.4161 auto = camA → 2.0 changes nothing
tlAC.addCut(6.0, 'camA'); // 5.1654 auto = camB → 6.0 IS a real cut
const pe = tlAC.autoCutPlan({ cadence: 2 });
assert.deepEqual(pe.dropped.map((c) => c.t), [2.0], 'only the genuinely redundant one is dropped');
assert.deepEqual(pe.kept.map((c) => c.t), [6.0], 'the one that changes the angle is kept');
tlAC.undo(); tlAC.undo();
assert.equal(tlAC.cameraCuts.length, 0, 'test cuts cleaned up');
// range = from the playhead, and the camera already live doesn't repeat across it
tlAC.seek(6);
tlAC.addCut(0, 'camA'); // camA is live going into the range

View File

@ -875,7 +875,8 @@ export class TimelineUI {
cnt.textContent = `will place ${plan.cuts.length} cut${plan.cuts.length === 1 ? '' : 's'}`
+ (every > 0 ? ` · one every ${every.toFixed(2)}s` : '')
+ (plan.replaced.length ? ` · ${plan.replaced.length} existing replaced` : '')
+ (plan.kept.length ? ` · ${plan.kept.length} of your own cut${plan.kept.length === 1 ? '' : 's'} left in place between them` : '')
+ (plan.kept.length ? ` · ${plan.kept.length} of your cut${plan.kept.length === 1 ? '' : 's'} kept` : '')
+ (plan.dropped.length ? ` · ${plan.dropped.length} dropped (no camera change)` : '')
+ (plan.confidence < 0.35 ? ` · LOW grid confidence (${plan.confidence.toFixed(2)})` : '');
};
menu.querySelector('.cad').onchange = refresh;
@ -890,6 +891,7 @@ export class TimelineUI {
this.draw();
this._toast(`${plan.cuts.length} cuts on the downbeats · every ${plan.cadence} bar${plan.cadence === 1 ? '' : 's'}`
+ ` · ${plan.cameras.length} cameras cycling`
+ (plan.dropped.length ? ` · dropped ${plan.dropped.length} no-op cut${plan.dropped.length === 1 ? '' : 's'} (cut to the camera already live)` : '')
+ (plan.confidence < 0.35 ? ` · LOW grid confidence (${plan.confidence.toFixed(2)}) — check it against the music` : '')
+ ' · Cmd/Ctrl+Z undoes the lot');
};