Timeline selectors and ranges
Composed Video and Audio timelines expose native-grid placement markers. Video boundaries are exact project frames. Audio boundaries are exact project samples. Explicit names on values that reach a final concatenation become placement names:
clip {
image("title.png", 1s) as intro
image("credits.png", 2s) as credits
} as edit
$edit
during($edit::credits) {
zoom_in(2%)
}
Selector paths
Authors can nest selector paths, such as
$edit::chapter::interview::start. A placement selector without a final
boundary denotes its complete closed-open range. Terminal ::start,
::middle, and ::end select exact coordinates and remain reserved as boundary
words. A placement with one of those spellings requires an additional boundary
component. For example, use
$edit::middle::start..$edit::middle::end. Bare $edit::middle always remains
the midpoint of $edit.
A uniquely placed bare reference contributes its reference name implicitly.
Identity-preserving programs such as
zoom_in retain that marker. When an operation has already bound its timeline,
a selector may omit leading ancestors when the remaining suffix identifies one
addressable descendant. For example, $interview::start or
$chapter::interview::start may stand for a longer path under the bound root.
Multiple matches are ambiguous and require more leading names or the owning timeline. The compiler searches the shared view DAG without expanding every reused occurrence. Explicitly rooted selectors remain exact paths.
Names define the path
Selector structure follows names rather than operation history. Anonymous
composition layers are transparent, so these forms expose the same direct
a and b placements:
image("a.png", 1s) as a
image("b.png", 1s) as b
concat
concat as edit
image("a.png", 1s) as a
image("b.png", 1s) as b
join { concat } as edit
Both accept $edit::a and $edit::b. Anonymous one-input concatenation,
stack-block boundaries, and associative regrouping do not add path components.
Naming an occurrence does create a boundary:
image("a.png", 1s) as a
image("b.png", 1s) as b
concat as pair
image("c.png", 1s) as c
concat as edit
trim(value=$edit, range=$edit::pair::a)
Here $edit::a is invalid because the authored pair boundary cannot be
skipped. A name continues to denote the exact view captured at its declaration,
even when later anonymous composition wraps that occurrence.
At one parent level, a placement spelling is addressable only when exactly one
occurrence has that spelling. Explicit as labels, inferred bare-reference
labels, and operation-created labels do not shadow one another. Any duplicate
spelling is ambiguous and needs a distinct explicit name.
Trimming and replacing ranges
Use marker ranges with the timeline that owns their root. join
preserves the exact views of untouched inputs and exposes named values created
by its body as placements in the joined result. trim and during accept rooted
marker ranges for both Video and Audio. trim
preserves child placements only when their complete closed-open region is
provably inside the selected range. It rebases their starts to the trimmed
timeline. The compiler omits partially surviving or symbolically uncertain
placements.
A trimmed occurrence keeps its own placement label when later composed.
Audio uses the same selector, contextual-suffix, and interval-replacement rules:
audio("intro.wav") as intro
audio("song.wav") as song
join as mix
during(timeline=$mix, range=$mix::song) {
repeat(2)
}
during splices timeline layouts as well as media. Base placements fully before
the replaced range keep their coordinates. Placements fully after it shift by
the replacement-duration delta. Placements that intersect the replaced range,
or whose side the compiler cannot prove symbolically, do not survive.
The result exposes the inserted body as ::replacement and retains its nested layout.
The during result contract reserves that spelling. If a base placement named
replacement survives the edit, compilation reports
E_TIMELINE_PLACEMENT_CONFLICT. It does not shadow either occurrence. during
permits a base placement with that name when the selected range removes it.
Transition regions
Transitions expose operation-owned regions. flash_cut provides sequential
::before and ::after regions. crossfade provides ::before, ::after,
and the shared ::overlap region:
image("before.png", 2s)
image("after.png", 2s)
crossfade(500ms) as transition
trim(range=$transition::overlap)
The before and after regions retain their nested placement layouts, so a
path such as $transition::before::title remains addressable. Their ranges
overlap in a crossfade and remain sequential in a flash cut. All normal
boundaries, including ::middle, apply to these regions.
Coordinate arithmetic
Timeline coordinates use exact rational arithmetic. Coordinates with the same root support addition and subtraction. Number may scale them. Either Duration unit family may offset them:
during(
50% * ($edit::intro::start + $edit::credits::start)
..($edit::credits::end - 3f)
) {
zoom_in(2%)
}
Intermediate coordinates may be negative or beyond the owning timeline. The
compiler checks native-grid alignment, ordering, and final bounds when the
expression becomes a TimeRange. ::middle is therefore a valid exact rational
coordinate between frames or samples. An unaligned value reports the applicable
frame- or sample-alignment error.
Video and Audio trim retain marker expressions with boundaries that depend on
unprobed media. Preflight resolves them after it determines the referenced
source domains. The prepared operation contains an ordinary exact frame or
sample range. during uses the same deferred native-range model. It lowers to
existing slice and concat primitives.
A Video during body receives the selected extent symbolically. An image
without an explicit duration inherits that media-dependent extent. Preflight
resolves it to a concrete frame count. Audio during does not reinterpret a
sample extent as a Video frame request.
Reusing selectors with aliases
Aliases make long marker expressions reusable:
credits_lead_in = $edit::credits::start - 500ms
credits_end = $edit::credits::end
during($credits_lead_in..$credits_end) {
zoom_in(2%)
}
Timeline selectors inside aliases require their explicit root. A
timeline-anchored call supports contextual suffix lookup such as
$interview::start or $chapter::interview::start. An alias should use the
complete rooted path. This keeps its meaning independent of later uses.
Diagnostic layout
Timeline selector diagnostics print the compiler’s actual rooted occurrence layout. Each child includes its root-relative closed-open range. The tree is the canonical selector layout, not a record of anonymous operation wrappers.
The compiler marks genuinely unnamed leaves and ambiguous labels as not directly addressable. Mixed-root arithmetic shows both roots. For a marker range used with the wrong input, the diagnostic shows the marker root beside the bound input layouts. Diagnostic trees show at most 64 occurrences and 12 nesting levels.