Build Information
Successful build of KadrUI, reference v0.21.0 (32e974), with Swift 6.3 for macOS (SPM) on 31 Aug 2026 16:57:55 UTC.
Swift 6 data race errors: 0
Build Command
env DEVELOPER_DIR=/Applications/Xcode-26.5.0.app xcrun swift build --arch arm64Build Log
========================================
RunAll
========================================
Builder version: 5.0.2
Interrupt handler set up.
========================================
Checkout
========================================
Clone URL: https://github.com/SteliyanH/kadr-ui.git
Reference: v0.21.0
Initialized empty Git repository in /Users/admin/builder/spi-builder-workspace/.git/
From https://github.com/SteliyanH/kadr-ui
* tag v0.21.0 -> FETCH_HEAD
HEAD is now at 32e974b Merge pull request #143 from SteliyanH/develop
Cloned https://github.com/SteliyanH/kadr-ui.git
Revision (git rev-parse @):
32e974b57783100174adb88f31066fe10c8f54f7
SPI manifest file found: $PWD/.spi.yml
SUCCESS checkout https://github.com/SteliyanH/kadr-ui.git at v0.21.0
Fetching https://github.com/swiftlang/swift-syntax
Fetching https://github.com/pointfreeco/xctest-dynamic-overlay
Fetching https://github.com/pointfreeco/swift-custom-dump
Fetching https://github.com/SteliyanH/kadr.git
Fetching https://github.com/nalexn/ViewInspector
Fetching https://github.com/pointfreeco/swift-snapshot-testing
[1/2034] Fetching kadr
[42/4761] Fetching kadr, xctest-dynamic-overlay
[70/17755] Fetching kadr, xctest-dynamic-overlay, viewinspector
[3895/23456] Fetching kadr, xctest-dynamic-overlay, viewinspector, swift-custom-dump
Fetched https://github.com/pointfreeco/swift-custom-dump from cache (1.72s)
Fetched https://github.com/pointfreeco/xctest-dynamic-overlay from cache (1.73s)
[14209/15028] Fetching kadr, viewinspector
[14210/31420] Fetching kadr, viewinspector, swift-snapshot-testing
[14211/110793] Fetching kadr, viewinspector, swift-snapshot-testing, swift-syntax
Fetched https://github.com/nalexn/ViewInspector from cache (8.83s)
Fetched https://github.com/SteliyanH/kadr.git from cache (8.83s)
Fetched https://github.com/swiftlang/swift-syntax from cache (8.83s)
Fetched https://github.com/pointfreeco/swift-snapshot-testing from cache (8.83s)
Creating working copy for https://github.com/pointfreeco/swift-snapshot-testing
Creating working copy for https://github.com/SteliyanH/kadr.git
Creating working copy for https://github.com/nalexn/ViewInspector
Creating working copy for https://github.com/pointfreeco/xctest-dynamic-overlay
Creating working copy for https://github.com/pointfreeco/swift-custom-dump
Creating working copy for https://github.com/swiftlang/swift-syntax
Working copy of https://github.com/pointfreeco/swift-custom-dump resolved at 1.5.0
Working copy of https://github.com/pointfreeco/xctest-dynamic-overlay resolved at 1.9.0
Working copy of https://github.com/SteliyanH/kadr.git resolved at 1.0.0
Working copy of https://github.com/nalexn/ViewInspector resolved at 0.10.3
Working copy of https://github.com/pointfreeco/swift-snapshot-testing resolved at 1.19.2
Working copy of https://github.com/swiftlang/swift-syntax resolved at 603.0.1
========================================
ResolveProductDependencies
========================================
Resolving dependencies ...
{
"identity": ".resolve-product-dependencies",
"name": "resolve-dependencies",
"url": "/Users/admin/builder/spi-builder-workspace/.resolve-product-dependencies",
"version": "unspecified",
"path": "/Users/admin/builder/spi-builder-workspace/.resolve-product-dependencies",
"traits": [
"default"
],
"dependencies": [
{
"identity": "kadr-ui",
"name": "KadrUI",
"url": "https://github.com/SteliyanH/kadr-ui.git",
"version": "unspecified",
"path": "/Users/admin/builder/spi-builder-workspace/.resolve-product-dependencies/.build/checkouts/kadr-ui",
"traits": [
"default"
],
"dependencies": [
{
"identity": "kadr",
"name": "Kadr",
"url": "https://github.com/SteliyanH/kadr.git",
"version": "1.1.0",
"path": "/Users/admin/builder/spi-builder-workspace/.resolve-product-dependencies/.build/checkouts/kadr",
"traits": [
"default"
],
"dependencies": [
]
}
]
}
]
}
Fetching https://github.com/SteliyanH/kadr-ui.git
[1/1105] Fetching kadr-ui
Fetched https://github.com/SteliyanH/kadr-ui.git from cache (3.70s)
Fetching https://github.com/SteliyanH/kadr.git from cache
Fetched https://github.com/SteliyanH/kadr.git from cache (0.62s)
Computing version for https://github.com/SteliyanH/kadr.git
Computed https://github.com/SteliyanH/kadr.git at 1.1.0 (1.07s)
Creating working copy for https://github.com/SteliyanH/kadr.git
Working copy of https://github.com/SteliyanH/kadr.git resolved at 1.1.0
Creating working copy for https://github.com/SteliyanH/kadr-ui.git
Working copy of https://github.com/SteliyanH/kadr-ui.git resolved at v0.21.0 (32e974b)
warning: '.resolve-product-dependencies': dependency 'kadr-ui' is not used by any target
Found 1 product dependencies
- Kadr
========================================
Build
========================================
Selected platform: macosSpm
Swift version: 6.3
Building package at path: $PWD
https://github.com/SteliyanH/kadr-ui.git
Running build ...
env DEVELOPER_DIR=/Applications/Xcode-26.5.0.app xcrun swift build --arch arm64
Building for debugging...
[0/3] Write sources
[2/3] Write swift-version-69A768CDF2A0BEE1.txt
[4/67] Compiling Kadr FilterID.swift
[5/67] Compiling Kadr Frame.swift
[6/67] Compiling Kadr LayerID.swift
[7/67] Compiling Kadr Layout.swift
[8/67] Compiling Kadr Position.swift
[9/67] Compiling Kadr Size.swift
[10/67] Compiling Kadr Transform.swift
[11/74] Compiling Kadr Animatable.swift
[12/74] Compiling Kadr Animation.swift
[13/74] Compiling Kadr TimingFunction.swift
[14/74] Compiling Kadr AudioBuilder.swift
[15/74] Compiling Kadr AudioTimePitchAlgorithm.swift
[16/74] Compiling Kadr AudioTrack.swift
[17/74] Compiling Kadr BackgroundMusic.swift
[18/74] Compiling Kadr ThumbnailGenerator.swift
[19/74] Compiling Kadr KadrError+LocalizedError.swift
[20/74] Compiling Kadr KadrError.swift
[21/74] Compiling Kadr ExportProgress.swift
[22/74] Compiling Kadr ExportSettings.swift
[23/74] Compiling Kadr Exporter.swift
[24/74] Compiling Kadr Preset.swift
[25/74] Compiling Kadr KadrVideoCompositor.swift
[26/74] Compiling Kadr MaskCompositor.swift
[27/74] Compiling Kadr MultiInputCompositor.swift
[28/74] Compiling Kadr OverlayRenderer.swift
[29/74] Compiling Kadr PlaybackComposer.swift
[30/74] Compiling Kadr ReverseProcessor.swift
[31/74] Compiling Kadr SpeedCurveSampler.swift
[32/74] Compiling Kadr ChromaKey.swift
[33/74] Compiling Kadr Filter.swift
[34/74] Compiling Kadr FilterKind.swift
[35/74] Compiling Kadr LUT.swift
[36/74] Compiling Kadr Anchor.swift
[37/74] Compiling Kadr ClipID.swift
[38/74] Compiling Kadr CropRegion.swift
[39/74] Compiling Kadr TextOverlay.swift
[40/74] Compiling Kadr TextShadow.swift
[41/74] Compiling Kadr TextStroke.swift
[42/74] Compiling Kadr TextStyle.swift
[43/74] Compiling Kadr Watermark.swift
[44/74] Compiling Kadr PlatformTypes.swift
[45/74] Compiling Kadr Timecode.swift
[46/74] Compiling Kadr Caption.swift
[47/74] Compiling Kadr Clip.swift
[48/74] Compiling Kadr ImageClip+Color.swift
[49/74] Compiling Kadr ImageClip.swift
[50/74] Compiling Kadr SampleMedia.swift
[51/74] Compiling Kadr TitleSequence.swift
[52/74] Compiling Kadr Track.swift
[53/74] Compiling Kadr Clip+AnimationClearing.swift
[54/74] Compiling Kadr Clip+FilterID.swift
[55/74] Compiling Kadr Clip+Speed.swift
[56/74] Compiling Kadr ImageOverlay.swift
[57/74] Compiling Kadr Overlay.swift
[58/74] Compiling Kadr StickerOverlay.swift
[59/74] Compiling Kadr TextAnimation.swift
[60/74] Compiling Kadr CancellationToken.swift
[61/74] Compiling Kadr CompositionBuilder.swift
[62/74] Compiling Kadr Compositor.swift
[63/74] Compiling Kadr CropCompositor.swift
[64/74] Compiling Kadr ExportEngine.swift
[65/74] Compiling Kadr FilterProcessor.swift
[66/74] Compiling Kadr ImageEncoder.swift
[67/74] Emitting module Kadr
[68/74] Compiling Kadr Transition.swift
[69/74] Compiling Kadr Video.swift
[70/74] Compiling Kadr VideoBuilder.swift
[71/74] Compiling Kadr VideoClip.swift
[72/74] Compiling Kadr AssetWriterExporter.swift
[73/74] Compiling Kadr AudioWaveform.swift
[74/74] Compiling Kadr AudioWaveformLoader.swift
[75/96] Emitting module KadrUI
[76/98] Compiling KadrUI TimelineZoom.swift
[77/98] Compiling KadrUI TransitionPicker.swift
[78/98] Compiling KadrUI AnimatedTextLayerView.swift
[79/98] Compiling KadrUI AudioWaveform.swift
[80/98] Compiling KadrUI CaptionEditor.swift
[81/98] Compiling KadrUI VideoSampling.swift
[82/98] Compiling KadrUI ZoomSnapThreshold.swift
[83/98] Compiling KadrUI ClipSplitter.swift
[84/98] Compiling KadrUI InspectorPanel.swift
[85/98] Compiling KadrUI KadrAppearance.swift
[86/98] Compiling KadrUI PlatformBridge.swift
[87/98] Compiling KadrUI SpeedCurveEditor.swift
[88/98] Compiling KadrUI TransportBand.swift
/Users/admin/builder/spi-builder-workspace/Sources/KadrUI/VideoPreview.swift:179:17: warning: main actor-isolated property 'isSeekingFromBinding' can not be mutated from a Sendable closure
79 | /// Guards the feedback loop between `currentTime` and the observer: without
80 | /// it, every tick writes the binding, which seeks, which ticks.
81 | @State private var isSeekingFromBinding = false
| `- note: mutation of this property is only permitted within the actor
82 |
83 | /// Create a preview for `video`.
:
177 | isSeekingFromBinding = true
178 | player.seek(to: time, toleranceBefore: .zero, toleranceAfter: .zero) { _ in
179 | isSeekingFromBinding = false
| `- warning: main actor-isolated property 'isSeekingFromBinding' can not be mutated from a Sendable closure
180 | }
181 | }
/Users/admin/builder/spi-builder-workspace/Sources/KadrUI/VideoPreview.swift:217:20: warning: main actor-isolated property 'isSeekingFromBinding' can not be referenced from a Sendable closure
79 | /// Guards the feedback loop between `currentTime` and the observer: without
80 | /// it, every tick writes the binding, which seeks, which ticks.
81 | @State private var isSeekingFromBinding = false
| `- note: property declared here
82 |
83 | /// Create a preview for `video`.
:
215 | // Skip the tick that our own seek produced, or the binding would
216 | // fight the observer.
217 | guard !isSeekingFromBinding else { return }
| `- warning: main actor-isolated property 'isSeekingFromBinding' can not be referenced from a Sendable closure
218 |
219 | if let currentTime, currentTime.wrappedValue != time {
/Users/admin/builder/spi-builder-workspace/Sources/KadrUI/VideoPreview.swift:220:17: warning: main actor-isolated property 'lastPushedTime' can not be mutated from a Sendable closure
66 | /// which is what allows the seek threshold below to be frame-scale instead
67 | /// of a blunt 0.05s — see `seekEpsilon`.
68 | @State private var lastPushedTime: CMTime?
| `- note: mutation of this property is only permitted within the actor
69 |
70 | /// Attached only when sampling is requested. An `AVPlayerItemVideoOutput`
:
218 |
219 | if let currentTime, currentTime.wrappedValue != time {
220 | lastPushedTime = time
| `- warning: main actor-isolated property 'lastPushedTime' can not be mutated from a Sendable closure
221 | currentTime.wrappedValue = time
222 | }
/Users/admin/builder/spi-builder-workspace/Sources/KadrUI/VideoPreview.swift:227:20: warning: main actor-isolated property 'loopBox' can not be referenced from a Sendable closure
58 | /// binding a loop toggle to `loops:` saw it do nothing until something else
59 | /// happened to rebuild the player.
60 | @State private var loopBox = LoopBox()
| `- note: property declared here
61 |
62 | /// The last position this view pushed into `currentTime` itself.
:
225 | let atEnd = time >= item.duration
226 | if atEnd {
227 | if loopBox.loops {
| `- warning: main actor-isolated property 'loopBox' can not be referenced from a Sendable closure
228 | player.seek(to: .zero)
229 | player.play()
[89/98] Compiling KadrUI VideoPreview.swift
/Users/admin/builder/spi-builder-workspace/Sources/KadrUI/VideoPreview.swift:179:17: warning: main actor-isolated property 'isSeekingFromBinding' can not be mutated from a Sendable closure
79 | /// Guards the feedback loop between `currentTime` and the observer: without
80 | /// it, every tick writes the binding, which seeks, which ticks.
81 | @State private var isSeekingFromBinding = false
| `- note: mutation of this property is only permitted within the actor
82 |
83 | /// Create a preview for `video`.
:
177 | isSeekingFromBinding = true
178 | player.seek(to: time, toleranceBefore: .zero, toleranceAfter: .zero) { _ in
179 | isSeekingFromBinding = false
| `- warning: main actor-isolated property 'isSeekingFromBinding' can not be mutated from a Sendable closure
180 | }
181 | }
/Users/admin/builder/spi-builder-workspace/Sources/KadrUI/VideoPreview.swift:217:20: warning: main actor-isolated property 'isSeekingFromBinding' can not be referenced from a Sendable closure
79 | /// Guards the feedback loop between `currentTime` and the observer: without
80 | /// it, every tick writes the binding, which seeks, which ticks.
81 | @State private var isSeekingFromBinding = false
| `- note: property declared here
82 |
83 | /// Create a preview for `video`.
:
215 | // Skip the tick that our own seek produced, or the binding would
216 | // fight the observer.
217 | guard !isSeekingFromBinding else { return }
| `- warning: main actor-isolated property 'isSeekingFromBinding' can not be referenced from a Sendable closure
218 |
219 | if let currentTime, currentTime.wrappedValue != time {
/Users/admin/builder/spi-builder-workspace/Sources/KadrUI/VideoPreview.swift:220:17: warning: main actor-isolated property 'lastPushedTime' can not be mutated from a Sendable closure
66 | /// which is what allows the seek threshold below to be frame-scale instead
67 | /// of a blunt 0.05s — see `seekEpsilon`.
68 | @State private var lastPushedTime: CMTime?
| `- note: mutation of this property is only permitted within the actor
69 |
70 | /// Attached only when sampling is requested. An `AVPlayerItemVideoOutput`
:
218 |
219 | if let currentTime, currentTime.wrappedValue != time {
220 | lastPushedTime = time
| `- warning: main actor-isolated property 'lastPushedTime' can not be mutated from a Sendable closure
221 | currentTime.wrappedValue = time
222 | }
/Users/admin/builder/spi-builder-workspace/Sources/KadrUI/VideoPreview.swift:227:20: warning: main actor-isolated property 'loopBox' can not be referenced from a Sendable closure
58 | /// binding a loop toggle to `loops:` saw it do nothing until something else
59 | /// happened to rebuild the player.
60 | @State private var loopBox = LoopBox()
| `- note: property declared here
61 |
62 | /// The last position this view pushed into `currentTime` itself.
:
225 | let atEnd = time >= item.duration
226 | if atEnd {
227 | if loopBox.loops {
| `- warning: main actor-isolated property 'loopBox' can not be referenced from a Sendable closure
228 | player.seek(to: .zero)
229 | player.play()
[90/98] Compiling KadrUI KadrUI.swift
[91/98] Compiling KadrUI KeyframeEditor.swift
[92/98] Compiling KadrUI OverlayHost.swift
[93/98] Compiling KadrUI ThumbnailStrip.swift
[94/98] Compiling KadrUI TimelineEvents.swift
[95/98] Compiling KadrUI TimelineLanes.swift
[96/98] Compiling KadrUI TimelineView.swift
[97/98] Compiling KadrUI OverlayInspector.swift
[98/98] Compiling KadrUI OverlayKeyframeEditor.swift
Build complete! (16.39s)
Build complete.
{
"dependencies" : [
{
"identity" : "kadr",
"requirement" : {
"range" : [
{
"lower_bound" : "1.0.0",
"upper_bound" : "2.0.0"
}
]
},
"type" : "sourceControl",
"url" : "https://github.com/SteliyanH/kadr.git"
},
{
"identity" : "swift-snapshot-testing",
"requirement" : {
"range" : [
{
"lower_bound" : "1.18.0",
"upper_bound" : "2.0.0"
}
]
},
"type" : "sourceControl",
"url" : "https://github.com/pointfreeco/swift-snapshot-testing"
},
{
"identity" : "viewinspector",
"requirement" : {
"range" : [
{
"lower_bound" : "0.10.0",
"upper_bound" : "1.0.0"
}
]
},
"type" : "sourceControl",
"url" : "https://github.com/nalexn/ViewInspector"
}
],
"manifest_display_name" : "KadrUI",
"name" : "KadrUI",
"path" : "/Users/admin/builder/spi-builder-workspace",
"platforms" : [
{
"name" : "ios",
"version" : "17.0"
},
{
"name" : "macos",
"version" : "14.0"
},
{
"name" : "tvos",
"version" : "17.0"
},
{
"name" : "visionos",
"version" : "1.0"
}
],
"products" : [
{
"name" : "KadrUI",
"targets" : [
"KadrUI"
],
"type" : {
"library" : [
"automatic"
]
}
}
],
"targets" : [
{
"c99name" : "KadrUITests",
"module_type" : "SwiftTarget",
"name" : "KadrUITests",
"path" : "Tests/KadrUITests",
"product_dependencies" : [
"SnapshotTesting",
"ViewInspector"
],
"sources" : [
"AccessibilityTests.swift",
"AnimatedTextLayerViewTests.swift",
"AudioWaveformShapeTests.swift",
"AuthoringSurfaceTests.swift",
"CallbackEventStructsTests.swift",
"CaptionEditorTests.swift",
"ClipSplitterTests.swift",
"CrossfadeBoundariesTests.swift",
"FixedCenterPlayheadTests.swift",
"GestureWiringTests.swift",
"InspectorPanelTests.swift",
"InspectorSectionsAndTextEffectsTests.swift",
"KadrAppearanceTests.swift",
"KadrUITests.swift",
"KeyframeEditorTests.swift",
"MultiSelectAndLongPressTests.swift",
"OnClipDragSnapTests.swift",
"OverlayGestureTests.swift",
"OverlayHostHelpersTests.swift",
"OverlayHostMultiSelectTests.swift",
"OverlayHostTests.swift",
"OverlayInspectorTests.swift",
"SnapshotStrategy+macOSSwiftUI.swift",
"SnapshotTests.swift",
"SpeedCurveEditorTests.swift",
"ThumbnailStripTests.swift",
"TimelineLanesTests.swift",
"TimelineMetricsTests.swift",
"TimelineScrollAndClipA11yTests.swift",
"TimelineViewTests.swift",
"TimelineZoomTests.swift",
"TransportBandTests.swift",
"VideoPreviewIdentityAndSeekTests.swift",
"VideoPreviewPlaybackTests.swift",
"VideoPreviewTests.swift",
"VideoSamplingTests.swift",
"ZoomSnapThresholdTests.swift"
],
"target_dependencies" : [
"KadrUI"
],
"type" : "test"
},
{
"c99name" : "KadrUI",
"module_type" : "SwiftTarget",
"name" : "KadrUI",
"path" : "Sources/KadrUI",
"product_dependencies" : [
"Kadr"
],
"product_memberships" : [
"KadrUI"
],
"sources" : [
"AnimatedTextLayerView.swift",
"AudioWaveform.swift",
"CaptionEditor.swift",
"ClipSplitter.swift",
"InspectorPanel.swift",
"KadrAppearance.swift",
"KadrUI.swift",
"KeyframeEditor.swift",
"OverlayHost.swift",
"OverlayInspector.swift",
"OverlayKeyframeEditor.swift",
"PlatformBridge.swift",
"SpeedCurveEditor.swift",
"ThumbnailStrip.swift",
"TimelineEvents.swift",
"TimelineLanes.swift",
"TimelineView.swift",
"TimelineZoom.swift",
"TransitionPicker.swift",
"TransportBand.swift",
"VideoPreview.swift",
"VideoSampling.swift",
"ZoomSnapThreshold.swift"
],
"type" : "library"
}
],
"tools_version" : "6.0"
}
✅ Doc result (pending) reported
========================================
GenerateDocs
========================================
Generating docs at path: $PWD/.docs/steliyanh/kadr-ui/v0.21.0
Repository: SteliyanH/kadr-ui
Swift version used: 6.3
Target: KadrUI
Extracting symbol information for 'KadrUI'...
Finished extracting symbol information for 'KadrUI'. (60.47s)
Building documentation for 'KadrUI'...
warning: 'Kadr' doesn't exist at '/KadrUI/CaptionEditor'
--> ../CaptionEditor.swift:5:35-5:39
3 | import Kadr
4 |
5 + /// A list-style cue editor for ``Kadr/Video/captions(_:)``. Each row exposes the
6 | /// cue's text plus its start / end timestamps, with quick "set to playhead"
7 | /// shortcuts and a delete button. A trailing **+ Add cue** button appends a new
warning: 'Kadr' doesn't exist at '/KadrUI/ClipSplitter'
--> ../ClipSplitter.swift:20:48-20:52
18 | /// ```
19 | ///
20 + /// **What it will not do.** A clip inside a ``Kadr/Track``, a
21 | /// ``Kadr/Transition``, and a clip with a non-1× speed rate are all refused
22 | /// rather than approximated — see ``ClipSplitter/Failure``. Splitting a retimed
warning: 'Kadr' doesn't exist at '/KadrUI/ClipSplitter'
--> ../ClipSplitter.swift:21:7-21:11
19 | ///
20 | /// **What it will not do.** A clip inside a ``Kadr/Track``, a
21 + /// ``Kadr/Transition``, and a clip with a non-1× speed rate are all refused
22 | /// rather than approximated — see ``ClipSplitter/Failure``. Splitting a retimed
23 | /// clip means solving for source time through the speed curve, and getting that
warning: 'Kadr' doesn't exist at '/KadrUI/ClipSplitter/Failure/clipInsideTrack'
--> ../ClipSplitter.swift:33:36-33:40
31 | /// No clip with that id exists in the composition.
32 | case clipNotFound
33 + /// The clip is inside a ``Kadr/Track``. Splitting within a track would
34 | /// change the track's internal timing, which the caller has to decide
35 | /// about.
warning: 'Kadr' doesn't exist at '/KadrUI/ClipSplitter/Failure/notSplittable'
--> ../ClipSplitter.swift:37:29-37:33
35 | /// about.
36 | case clipInsideTrack
37 + /// The clip is a ``Kadr/Transition``, which has no content to cut.
38 | case notSplittable
39 | /// The time falls outside the clip, or exactly on one of its edges —
warning: 'Kadr' doesn't exist at '/KadrUI/ClipSplitter/contains(_:in:)'
--> ../ClipSplitter.swift:195:66-195:70
193 | }
194 |
195 + /// Whether `id` is anywhere in `clip`, including inside a ``Kadr/Track``.
196 | public static func contains(_ id: ClipID, in clip: any Clip) -> Bool {
197 | if clip.clipID == id { return true }
warning: 'Kadr' doesn't exist at '/KadrUI/InspectorPanel'
--> ../InspectorPanel.swift:7:62-7:66
5 | ///
6 | /// Tap a clip on the timeline (binding `selectedClipID` shared between both views) and the
7 + /// inspector populates with sliders for the v0.8 surface: ``Kadr/Transform`` (center X/Y,
8 | /// rotation, scale, anchor), ``Kadr/Clip/opacity``, and per-filter intensity. Slider edits
9 | /// fire callbacks that mirror ``TimelineView/onReorder`` / ``TimelineView/onTrim``: the
warning: 'Kadr' doesn't exist at '/KadrUI/InspectorPanel'
--> ../InspectorPanel.swift:8:33-8:37
6 | /// Tap a clip on the timeline (binding `selectedClipID` shared between both views) and the
7 | /// inspector populates with sliders for the v0.8 surface: ``Kadr/Transform`` (center X/Y,
8 + /// rotation, scale, anchor), ``Kadr/Clip/opacity``, and per-filter intensity. Slider edits
9 | /// fire callbacks that mirror ``TimelineView/onReorder`` / ``TimelineView/onTrim``: the
10 | /// panel does not mutate the `Video` (it can't — `Video` is immutable). The consumer
warning: 'onReorder' doesn't exist at '/KadrUI/TimelineView'
--> ../InspectorPanel.swift:9:47-9:56
7 | /// inspector populates with sliders for the v0.8 surface: ``Kadr/Transform`` (center X/Y,
8 | /// rotation, scale, anchor), ``Kadr/Clip/opacity``, and per-filter intensity. Slider edits
9 + /// fire callbacks that mirror ``TimelineView/onReorder`` / ``TimelineView/onTrim``: the
10 | /// panel does not mutate the `Video` (it can't — `Video` is immutable). The consumer
11 | /// rebuilds the composition with the new value.
warning: 'onTrim' doesn't exist at '/KadrUI/TimelineView'
--> ../InspectorPanel.swift:9:76-9:82
7 | /// inspector populates with sliders for the v0.8 surface: ``Kadr/Transform`` (center X/Y,
8 | /// rotation, scale, anchor), ``Kadr/Clip/opacity``, and per-filter intensity. Slider edits
9 + /// fire callbacks that mirror ``TimelineView/onReorder`` / ``TimelineView/onTrim``: the
10 | /// panel does not mutate the `Video` (it can't — `Video` is immutable). The consumer
11 | /// rebuilds the composition with the new value.
warning: 'Kadr' doesn't exist at '/KadrUI/InspectorPanel/Section'
--> ../InspectorPanel.swift:49:25-49:29
47 | /// - selectedClipID: Binding shared with a ``TimelineView`` so the two stay in sync.
48 | /// - onTransform: Fires when the user edits any Transform slider. Receives the full
49 + /// resulting ``Kadr/Transform`` (the panel always emits a complete value, never a
50 | /// partial delta). Consumer rebuilds the `Video` with the new transform on the
51 | /// identified clip.
warning: 'Kadr' doesn't exist at '/KadrUI/InspectorPanel/Section'
--> ../InspectorPanel.swift:55:60-55:64
53 | /// `0...1`.
54 | /// - onFilterIntensity: Fires when the user edits a per-filter intensity slider.
55 + /// Receives the clip's `ClipID`, the index into ``Kadr/VideoClip/filters``, and
56 | /// the new scalar in the filter's natural range. Consumer rebuilds the filter via
57 | /// ``Kadr/Filter/withScalar(_:)`` (or however they prefer).
warning: 'Kadr' doesn't exist at '/KadrUI/InspectorPanel/Section'
--> ../InspectorPanel.swift:57:15-57:19
55 | /// Receives the clip's `ClipID`, the index into ``Kadr/VideoClip/filters``, and
56 | /// the new scalar in the filter's natural range. Consumer rebuilds the filter via
57 + /// ``Kadr/Filter/withScalar(_:)`` (or however they prefer).
58 | /// One group of controls in the panel.
59 | ///
warning: 'Kadr' doesn't exist at '/KadrUI/InspectorPanel/clipFor(id:in:)'
--> ../InspectorPanel.swift:318:46-318:50
316 | extension InspectorPanel {
317 |
318 + /// Look up a clip in a composition by ``Kadr/ClipID``. Searches the top-level chain
319 | /// and inside any ``Kadr/Track`` blocks. Returns the first match, or `nil` if no clip
320 | /// with that ID exists. Pure — exposed for testing and for callers who want to read
warning: 'Kadr' doesn't exist at '/KadrUI/InspectorPanel/clipFor(id:in:)'
--> ../InspectorPanel.swift:319:26-319:30
317 |
318 | /// Look up a clip in a composition by ``Kadr/ClipID``. Searches the top-level chain
319 + /// and inside any ``Kadr/Track`` blocks. Returns the first match, or `nil` if no clip
320 | /// with that ID exists. Pure — exposed for testing and for callers who want to read
321 | /// the same clip the inspector is showing.
warning: 'Kadr' doesn't exist at '/KadrUI/KeyframeProperty/transform'
--> ../KeyframeEditor.swift:7:22-7:26
5 | /// Identifies an animatable property surfaced as a row in ``KeyframeEditor``.
6 | public enum KeyframeProperty: Sendable, Hashable {
7 + /// The clip's ``Kadr/Clip/transform``. Drives ``Kadr/Clip/transformAnimation``.
8 | case transform
9 | /// The clip's ``Kadr/Clip/opacity``. Drives ``Kadr/Clip/opacityAnimation``.
warning: 'Kadr' doesn't exist at '/KadrUI/KeyframeProperty/transform'
--> ../KeyframeEditor.swift:7:54-7:58
5 | /// Identifies an animatable property surfaced as a row in ``KeyframeEditor``.
6 | public enum KeyframeProperty: Sendable, Hashable {
7 + /// The clip's ``Kadr/Clip/transform``. Drives ``Kadr/Clip/transformAnimation``.
8 | case transform
9 | /// The clip's ``Kadr/Clip/opacity``. Drives ``Kadr/Clip/opacityAnimation``.
warning: 'Kadr' doesn't exist at '/KadrUI/KeyframeProperty/opacity'
--> ../KeyframeEditor.swift:9:22-9:26
7 | /// The clip's ``Kadr/Clip/transform``. Drives ``Kadr/Clip/transformAnimation``.
8 | case transform
9 + /// The clip's ``Kadr/Clip/opacity``. Drives ``Kadr/Clip/opacityAnimation``.
10 | case opacity
11 | /// A ``Kadr/VideoClip/filters`` entry by index. Drives the matching
warning: 'Kadr' doesn't exist at '/KadrUI/KeyframeProperty/opacity'
--> ../KeyframeEditor.swift:9:52-9:56
7 | /// The clip's ``Kadr/Clip/transform``. Drives ``Kadr/Clip/transformAnimation``.
8 | case transform
9 + /// The clip's ``Kadr/Clip/opacity``. Drives ``Kadr/Clip/opacityAnimation``.
10 | case opacity
11 | /// A ``Kadr/VideoClip/filters`` entry by index. Drives the matching
warning: 'Kadr' doesn't exist at '/KadrUI/KeyframeProperty/filter(index:)'
--> ../KeyframeEditor.swift:11:13-11:17
9 | /// The clip's ``Kadr/Clip/opacity``. Drives ``Kadr/Clip/opacityAnimation``.
10 | case opacity
11 + /// A ``Kadr/VideoClip/filters`` entry by index. Drives the matching
12 | /// ``Kadr/VideoClip/filterAnimations`` entry. Out-of-range indices are dropped at
13 | /// render time.
warning: 'Kadr' doesn't exist at '/KadrUI/KeyframeProperty/filter(index:)'
--> ../KeyframeEditor.swift:12:11-12:15
10 | case opacity
11 | /// A ``Kadr/VideoClip/filters`` entry by index. Drives the matching
12 + /// ``Kadr/VideoClip/filterAnimations`` entry. Out-of-range indices are dropped at
13 | /// render time.
14 | case filter(index: Int)
warning: 'Kadr' doesn't exist at '/KadrUI/KeyframeEditor/propertyOptions(for:)'
--> ../KeyframeEditor.swift:228:33-228:37
226 | /// The properties to surface as rows for a clip. Always emits `.transform` and
227 | /// `.opacity` (every Kadr clip type carries the surface). Adds a `.filter(index:)`
228 + /// row for each entry in ``Kadr/VideoClip/filters`` that has an animatable scalar
229 | /// (matches ``InspectorPanel/scalar(of:)`` returning non-`nil`). Pure, testable.
230 | public static func propertyOptions(for clip: any Clip) -> [KeyframeProperty] {
warning: 'scalar(of:)' doesn't exist at '/KadrUI/InspectorPanel'
--> ../KeyframeEditor.swift:229:35-229:46
227 | /// `.opacity` (every Kadr clip type carries the surface). Adds a `.filter(index:)`
228 | /// row for each entry in ``Kadr/VideoClip/filters`` that has an animatable scalar
229 + /// (matches ``InspectorPanel/scalar(of:)`` returning non-`nil`). Pure, testable.
230 | public static func propertyOptions(for clip: any Clip) -> [KeyframeProperty] {
231 | var rows: [KeyframeProperty] = [.transform, .opacity]
warning: 'Kadr' doesn't exist at '/KadrUI/OverlayHost'
--> ../OverlayHost.swift:5:51-5:55
3 | import CoreMedia
4 |
5 + /// A SwiftUI overlay layer that renders a Kadr ``Kadr/Video``'s overlays over preview content.
6 | ///
7 | /// Why this exists: Kadr 0.4.0 intentionally does **not** bake overlays into the preview
warning: 'Kadr' doesn't exist at '/KadrUI/OverlayHost'
--> ../OverlayHost.swift:11:7-11:11
9 | /// and especially to hit-test them with SwiftUI gestures — they must be rendered as
10 | /// SwiftUI views layered over the player. `OverlayHost` does that, using
11 + /// ``Kadr/Layout/resolveFrame(position:size:anchor:in:)`` so positions match the engine
12 | /// pixel-for-pixel.
13 | ///
warning: 'Kadr' doesn't exist at '/KadrUI/OverlayHost'
--> ../OverlayHost.swift:35:7-35:11
33 | ///
34 | /// **Time-aware visibility.** Pass `currentTime` to honor each overlay's
35 + /// ``Kadr/Overlay/visibilityRange``. Overlays with a non-`nil` range render only while
36 | /// `currentTime` is inside the range. Overlays without a range always render. Without
37 | /// `currentTime`, all overlays render unconditionally (preview matches export of an
warning: 'Kadr' doesn't exist at '/KadrUI/OverlayHost/init(_:contentMode:currentTime:selectedLayerID:selectedLayerIDs:customRenderer:)'
--> ../OverlayHost.swift:85:49-85:53
83 | /// Create an overlay host for `video`.
84 | /// - Parameters:
85 + /// - video: The Kadr composition whose ``Kadr/Video/overlays`` are rendered.
86 | /// - contentMode: How the composition's display rectangle fits inside the host's
87 | /// bounds. Defaults to `.fit`.
warning: 'Kadr' doesn't exist at '/KadrUI/OverlayHost/init(_:contentMode:currentTime:selectedLayerID:selectedLayerIDs:customRenderer:)'
--> ../OverlayHost.swift:89:15-89:19
87 | /// bounds. Defaults to `.fit`.
88 | /// - currentTime: Composition time used to honor each overlay's
89 + /// ``Kadr/Overlay/visibilityRange``. When `nil` (the default), all overlays render
90 | /// unconditionally.
91 | /// - customRenderer: Optional per-overlay renderer. Return a view to replace the
warning: Parameter 'selectedLayerID' is missing documentation
--> ../OverlayHost.swift:93:31-93:31
91 | /// - customRenderer: Optional per-overlay renderer. Return a view to replace the
| ╰─suggestion: Document 'selectedLayerID' parameter
92 | /// default rendering for that overlay; return `nil` to fall through to the
93 + /// built-in renderer.
94 | public init(
95 | _ video: Video,
warning: Parameter 'selectedLayerIDs' is missing documentation
--> ../OverlayHost.swift:93:31-93:31
91 | /// - customRenderer: Optional per-overlay renderer. Return a view to replace the
| ╰─suggestion: Document 'selectedLayerIDs' parameter
92 | /// default rendering for that overlay; return `nil` to fall through to the
93 + /// built-in renderer.
94 | public init(
95 | _ video: Video,
warning: 'overlayView(for:in:)' doesn't exist at '/KadrUI/OverlayHost/overlayMatchesSelection(id:single:set:)'
--> ../OverlayHost.swift:209:14-209:34
207 | /// Whether an overlay with `id` should render as selected, given the
208 | /// union of the single-binding and set-binding selection state. Used
209 + /// by ``overlayView(for:in:)`` so the rule has a single seam.
210 | ///
211 | /// Mirrors v0.9.2's ``TimelineView/clipMatchesSelection(id:single:set:)``.
warning: 'Kadr' doesn't exist at '/KadrUI/OverlayHost/onLayerTap(_:)'
--> ../OverlayHost.swift:372:69-372:73
370 | extension OverlayHost {
371 |
372 + /// Attach a tap handler that fires with the tapped overlay's ``Kadr/LayerID``.
373 | ///
374 | /// Only overlays with a non-`nil` ``Kadr/LayerID/`` participate. The handler is
warning: 'Kadr' doesn't exist at '/KadrUI/OverlayHost/onLayerTap(_:)'
--> ../OverlayHost.swift:374:42-374:46
372 | /// Attach a tap handler that fires with the tapped overlay's ``Kadr/LayerID``.
373 | ///
374 + /// Only overlays with a non-`nil` ``Kadr/LayerID/`` participate. The handler is
375 | /// invoked on `MainActor`; it's safe to mutate `@State` from inside.
376 | ///
warning: 'Kadr' doesn't exist at '/KadrUI/OverlayHost/onLayerDrag(onChanged:onEnded:)'
--> ../OverlayHost.swift:387:69-387:73
385 | }
386 |
387 + /// Attach drag handlers that fire with the dragged overlay's ``Kadr/LayerID`` and
388 | /// the cumulative translation in the host's coordinate space.
389 | ///
warning: 'Kadr' doesn't exist at '/KadrUI/OverlayHost/onLayerDrag(onChanged:onEnded:)'
--> ../OverlayHost.swift:392:56-392:60
390 | /// Use `onChanged` to track movement during the drag (e.g. update a preview transform);
391 | /// use `onEnded` to commit the final position. Both are optional; pass `nil` to skip
392 + /// either phase. Only overlays with a non-`nil` ``Kadr/LayerID`` participate.
393 | /// Drag uses a 5-pt minimum distance so taps and drags don't conflict.
394 | ///
warning: 'Kadr' doesn't exist at '/KadrUI/OverlayTextAnimationKind'
--> ../OverlayInspector.swift:6:51-6:55
4 |
5 | /// One of the four built-in overlay-targeted text animations exposed in the
6 + /// inspector picker. Maps onto Kadr's concrete ``Kadr/TextAnimation`` types
7 | /// (`FadeIn`, `SlideIn`, `ScaleUp`); a custom-built `TextAnimation` round-trips
8 | /// as ``OverlayTextAnimationKind/custom`` and can't be edited via the picker —
warning: 'Kadr' doesn't exist at '/KadrUI/InspectorPanel/overlayFor(id:in:)'
--> ../OverlayInspector.swift:24:50-24:54
22 | extension InspectorPanel {
23 |
24 + /// Look up an overlay in a composition by ``Kadr/LayerID``. Returns the
25 | /// first match, or `nil` if no overlay with that ID is set. Pure, testable.
26 | nonisolated public static func overlayFor(id: LayerID, in video: Video) -> (any Overlay)? {
warning: 'Kadr' doesn't exist at '/KadrUI/InspectorPanel/textAnimationKind(for:)'
--> ../OverlayInspector.swift:30:22-30:26
28 | }
29 |
30 + /// Map a Kadr ``Kadr/TextAnimation`` (any concrete conformer) onto the
31 | /// inspector's ``OverlayTextAnimationKind`` picker case. Falls back to
32 | /// ``OverlayTextAnimationKind/custom`` for consumer-built animations.
warning: 'Kadr' doesn't exist at '/KadrUI/InspectorPanel/textAnimation(forKind:)'
--> ../OverlayInspector.swift:47:33-47:37
45 | }
46 |
47 + /// Build a concrete Kadr ``Kadr/TextAnimation`` for a picker selection.
48 | /// Returns `nil` for ``OverlayTextAnimationKind/none`` and
49 | /// ``OverlayTextAnimationKind/custom`` (custom animations the picker can't
warning: 'Kadr' doesn't exist at '/KadrUI/OverlayInspectorPanel'
--> ../OverlayInspector.swift:66:32-66:36
64 | // MARK: - OverlayInspectorPanel (public surface)
65 |
66 + /// Inspector for a selected ``Kadr/Overlay``. Sibling to ``InspectorPanel``
67 | /// (which targets clips) — same callback shape, different domain.
68 | ///
warning: 'Kadr' doesn't exist at '/KadrUI/OverlayInspectorPanel'
--> ../OverlayInspector.swift:69:27-69:31
67 | /// (which targets clips) — same callback shape, different domain.
68 | ///
69 + /// Surfaces the common ``Kadr/Overlay`` properties (position / anchor / opacity)
70 | /// plus type-specific affordances:
71 | /// - ``Kadr/TextOverlay`` — text field, text-animation picker
warning: 'Kadr' doesn't exist at '/KadrUI/OverlayInspectorPanel'
--> ../OverlayInspector.swift:71:9-71:13
69 | /// Surfaces the common ``Kadr/Overlay`` properties (position / anchor / opacity)
70 | /// plus type-specific affordances:
71 + /// - ``Kadr/TextOverlay`` — text field, text-animation picker
72 | /// - ``Kadr/StickerOverlay`` — rotation slider
73 | /// - ``Kadr/ImageOverlay`` — common only (covers
warning: 'Kadr' doesn't exist at '/KadrUI/OverlayInspectorPanel'
--> ../OverlayInspector.swift:72:9-72:13
70 | /// plus type-specific affordances:
71 | /// - ``Kadr/TextOverlay`` — text field, text-animation picker
72 + /// - ``Kadr/StickerOverlay`` — rotation slider
73 | /// - ``Kadr/ImageOverlay`` — common only (covers
74 | /// ``Kadr/Video/watermark(_:position:size:opacity:)`` instances; their
warning: 'Kadr' doesn't exist at '/KadrUI/OverlayInspectorPanel'
--> ../OverlayInspector.swift:73:9-73:13
71 | /// - ``Kadr/TextOverlay`` — text field, text-animation picker
72 | /// - ``Kadr/StickerOverlay`` — rotation slider
73 + /// - ``Kadr/ImageOverlay`` — common only (covers
74 | /// ``Kadr/Video/watermark(_:position:size:opacity:)`` instances; their
75 | /// ``Kadr/Overlay/layerID`` is `"watermark"`)
warning: 'Kadr' doesn't exist at '/KadrUI/OverlayInspectorPanel'
--> ../OverlayInspector.swift:74:9-74:13
72 | /// - ``Kadr/StickerOverlay`` — rotation slider
73 | /// - ``Kadr/ImageOverlay`` — common only (covers
74 + /// ``Kadr/Video/watermark(_:position:size:opacity:)`` instances; their
75 | /// ``Kadr/Overlay/layerID`` is `"watermark"`)
76 | ///
warning: 'Kadr' doesn't exist at '/KadrUI/OverlayInspectorPanel'
--> ../OverlayInspector.swift:75:9-75:13
73 | /// - ``Kadr/ImageOverlay`` — common only (covers
74 | /// ``Kadr/Video/watermark(_:position:size:opacity:)`` instances; their
75 + /// ``Kadr/Overlay/layerID`` is `"watermark"`)
76 | ///
77 | /// **Read-only model.** Edits surface through callbacks; the consumer rebuilds
warning: 'Kadr' doesn't exist at '/KadrUI/OverlayProperty'
--> ../OverlayKeyframeEditor.swift:7:9-7:13
5 | /// Identifies an animatable property surfaced as a row in
6 | /// ``OverlayKeyframeEditor``. Property availability per overlay kind:
7 + /// - ``Kadr/ImageOverlay`` — `.position`, `.size`
8 | /// - ``Kadr/StickerOverlay`` — `.position`, `.size`
9 | /// - ``Kadr/TextOverlay`` — none (kadr's text overlays use the enum-driven
warning: 'Kadr' doesn't exist at '/KadrUI/OverlayProperty'
--> ../OverlayKeyframeEditor.swift:8:9-8:13
6 | /// ``OverlayKeyframeEditor``. Property availability per overlay kind:
7 | /// - ``Kadr/ImageOverlay`` — `.position`, `.size`
8 + /// - ``Kadr/StickerOverlay`` — `.position`, `.size`
9 | /// - ``Kadr/TextOverlay`` — none (kadr's text overlays use the enum-driven
10 | /// ``Kadr/TextAnimation`` instead of keyframes)
warning: 'Kadr' doesn't exist at '/KadrUI/OverlayProperty'
--> ../OverlayKeyframeEditor.swift:9:9-9:13
7 | /// - ``Kadr/ImageOverlay`` — `.position`, `.size`
8 | /// - ``Kadr/StickerOverlay`` — `.position`, `.size`
9 + /// - ``Kadr/TextOverlay`` — none (kadr's text overlays use the enum-driven
10 | /// ``Kadr/TextAnimation`` instead of keyframes)
11 | /// - ``Kadr/Video/watermark(_:position:size:opacity:)`` — same as `ImageOverlay`
warning: 'Kadr' doesn't exist at '/KadrUI/OverlayProperty'
--> ../OverlayKeyframeEditor.swift:10:9-10:13
8 | /// - ``Kadr/StickerOverlay`` — `.position`, `.size`
9 | /// - ``Kadr/TextOverlay`` — none (kadr's text overlays use the enum-driven
10 + /// ``Kadr/TextAnimation`` instead of keyframes)
11 | /// - ``Kadr/Video/watermark(_:position:size:opacity:)`` — same as `ImageOverlay`
12 | public enum OverlayProperty: Sendable, Hashable {
warning: 'Kadr' doesn't exist at '/KadrUI/OverlayProperty'
--> ../OverlayKeyframeEditor.swift:11:9-11:13
9 | /// - ``Kadr/TextOverlay`` — none (kadr's text overlays use the enum-driven
10 | /// ``Kadr/TextAnimation`` instead of keyframes)
11 + /// - ``Kadr/Video/watermark(_:position:size:opacity:)`` — same as `ImageOverlay`
12 | public enum OverlayProperty: Sendable, Hashable {
13 | case position
warning: 'Kadr' doesn't exist at '/KadrUI/OverlayKeyframeEditor'
--> ../OverlayKeyframeEditor.swift:17:51-17:55
15 | }
16 |
17 + /// Per-property keyframe editor for a selected ``Kadr/Overlay``. Mirrors the
18 | /// v0.6 ``KeyframeEditor`` (which targets clips) — same gesture model (tap
19 | /// empty area to add at playhead, long-press a marker to remove, drag to
warning: 'Kadr' doesn't exist at '/KadrUI/OverlayKeyframeEditor/propertyOptions(for:)'
--> ../OverlayKeyframeEditor.swift:186:27-186:31
184 |
185 | /// The keyframe-able properties for an overlay. Pure, testable. Returns an
186 + /// empty array for ``Kadr/TextOverlay`` (not keyframe-able in kadr v0.10)
187 | /// and for any conformer kadr-ui doesn't recognize.
188 | nonisolated public static func propertyOptions(for overlay: any Overlay) -> [OverlayProperty] {
warning: 'Kadr' doesn't exist at '/KadrUI/SpeedCurveEditor'
--> ../SpeedCurveEditor.swift:5:32-5:36
3 | import Kadr
4 |
5 + /// A 2D keyframe editor for ``Kadr/VideoClip/speed(curve:)``. Time runs along the
6 | /// x-axis (clip-relative, anchored to the clip's `trimRange`); speed multiplier
7 | /// runs along a log-scaled y-axis with `1.0` rendered as a baseline gridline.
warning: 'Kadr' doesn't exist at '/KadrUI/SpeedCurveEditor'
--> ../SpeedCurveEditor.swift:13:38-13:42
11 | /// **Read-only model.** The editor never mutates the clip directly — `Video` is
12 | /// immutable. Edits surface through ``SpeedCurveEditor/init(clip:currentTime:height:onUpdate:)``'s
13 + /// `onUpdate` callback as a fresh ``Kadr/Animation`` value (or `nil` to clear);
14 | /// the consumer rebuilds the clip via `clip.speed(.curved(_:))` or `clip.speed(.flat(_:))`.
15 | ///
warning: 'Kadr' doesn't exist at '/KadrUI/SpeedCurveEditor/init(clip:currentTime:height:onUpdate:)'
--> ../SpeedCurveEditor.swift:53:25-53:29
51 | /// Create a speed-curve editor for `clip`.
52 | /// - Parameters:
53 + /// - clip: The ``Kadr/VideoClip`` whose speed curve is being authored.
54 | /// The editor reads ``Kadr/VideoClip/speedCurve`` for the current
55 | /// keyframe set and ``Kadr/VideoClip/trimRange`` (falling back to
warning: 'Kadr' doesn't exist at '/KadrUI/SpeedCurveEditor/init(clip:currentTime:height:onUpdate:)'
--> ../SpeedCurveEditor.swift:54:32-54:36
52 | /// - Parameters:
53 | /// - clip: The ``Kadr/VideoClip`` whose speed curve is being authored.
54 + /// The editor reads ``Kadr/VideoClip/speedCurve`` for the current
55 | /// keyframe set and ``Kadr/VideoClip/trimRange`` (falling back to
56 | /// ``Kadr/Clip/duration``) for the time axis range.
warning: 'Kadr' doesn't exist at '/KadrUI/SpeedCurveEditor/init(clip:currentTime:height:onUpdate:)'
--> ../SpeedCurveEditor.swift:55:32-55:36
53 | /// - clip: The ``Kadr/VideoClip`` whose speed curve is being authored.
54 | /// The editor reads ``Kadr/VideoClip/speedCurve`` for the current
55 + /// keyframe set and ``Kadr/VideoClip/trimRange`` (falling back to
56 | /// ``Kadr/Clip/duration``) for the time axis range.
57 | /// - currentTime: Optional binding to a composition-relative playhead.
warning: 'Kadr' doesn't exist at '/KadrUI/SpeedCurveEditor/init(clip:currentTime:height:onUpdate:)'
--> ../SpeedCurveEditor.swift:56:15-56:19
54 | /// The editor reads ``Kadr/VideoClip/speedCurve`` for the current
55 | /// keyframe set and ``Kadr/VideoClip/trimRange`` (falling back to
56 + /// ``Kadr/Clip/duration``) for the time axis range.
57 | /// - currentTime: Optional binding to a composition-relative playhead.
58 | /// When non-`nil`, a vertical line marks the playhead's projection
warning: 'Kadr' doesn't exist at '/KadrUI/SpeedCurveEditor/init(clip:currentTime:height:onUpdate:)'
--> ../SpeedCurveEditor.swift:63:15-63:19
61 | /// - onUpdate: Fired when the user adds, removes, retimes, or rescales
62 | /// a keyframe — or changes the timing function. Receives a fresh
63 + /// ``Kadr/Animation`` (or `nil` to clear). Consumer rebuilds the
64 | /// clip via `clip.speed(.curved(_:))` or `clip.speed(.flat(_:))`.
65 | public init(
warning: 'Kadr' doesn't exist at '/KadrUI/ThumbnailStrip'
--> ../ThumbnailStrip.swift:10:65-10:69
8 | #endif
9 |
10 + /// A horizontal strip of evenly-spaced thumbnails for a Kadr ``Kadr/Video`` composition.
11 | ///
12 | /// Each thumbnail is rendered through ``Kadr/Video/thumbnail(at:)``, so it honors the same
warning: 'Kadr' doesn't exist at '/KadrUI/ThumbnailStrip'
--> ../ThumbnailStrip.swift:12:42-12:46
10 | /// A horizontal strip of evenly-spaced thumbnails for a Kadr ``Kadr/Video`` composition.
11 | ///
12 + /// Each thumbnail is rendered through ``Kadr/Video/thumbnail(at:)``, so it honors the same
13 | /// crop and preset resolution the engine would use. Useful as a scrubbing strip below a
14 | /// ``VideoPreview``, or as a standalone visual summary of a composition.
warning: 'Kadr' doesn't exist at '/KadrUI/ThumbnailStrip'
--> ../ThumbnailStrip.swift:31:33-31:37
29 | /// strip is on screen.
30 | ///
31 + /// **Empty composition.** If ``Kadr/Video/duration`` is zero (e.g. an untrimmed
32 | /// `VideoClip` whose asset hasn't been loaded), the strip renders nothing.
33 | public struct ThumbnailStrip: View {
warning: 'Kadr' doesn't exist at '/KadrUI/ClipReorderEvent/newClips'
--> ../TimelineEvents.swift:20:17-20:21
18 |
19 | /// The full rebuilt `video.clips` array, ready to be passed back into a
20 + /// fresh ``Kadr/Video``. Transitions automatically travel with their
21 | /// preceding media clip — consumers don't see a freestanding
22 | /// ``Kadr/Transition`` mid-reorder.
warning: 'Kadr' doesn't exist at '/KadrUI/ClipReorderEvent/newClips'
--> ../TimelineEvents.swift:22:11-22:15
20 | /// fresh ``Kadr/Video``. Transitions automatically travel with their
21 | /// preceding media clip — consumers don't see a freestanding
22 + /// ``Kadr/Transition`` mid-reorder.
23 | public let newClips: [any Clip]
24 |
warning: 'Kadr' doesn't exist at '/KadrUI/TimelineView'
--> ../TimelineView.swift:5:58-5:62
3 | import Kadr
4 |
5 + /// A read-only horizontal timeline visualizing a Kadr ``Kadr/Video`` composition's
6 | /// clip layout, transitions, and audio tracks.
7 | ///
warning: 'Kadr' doesn't exist at '/KadrUI/TimelineView'
--> ../TimelineView.swift:25:7-25:11
23 | /// for an untrimmed clip (the source asset's duration isn't known without an async load).
24 | /// On first appear, `TimelineView` walks the composition and asynchronously loads
25 + /// ``Kadr/VideoClip/metadata`` for any untrimmed `VideoClip`s, then re-lays out using
26 | /// the resolved durations. Until each load completes the corresponding clip renders at
27 | /// zero width.
warning: 'Kadr' doesn't exist at '/KadrUI/TimelineView'
--> ../TimelineView.swift:36:8-36:12
34 | ///
35 | /// **Multi-lane.** When the composition has Kadr 0.6+ multi-track content
36 + /// (``Kadr/Track`` blocks or clips pinned with `.at(time:)`), the timeline switches to
37 | /// a stacked-lane render: lane 0 is the implicit chain, then one lane per `Track` in
38 | /// declaration order, then greedy-packed rows of free-floaters, then optional audio
warning: 'init(_:currentTime:selectedClipID:zoom:...)' doesn't exist at '/KadrUI/TimelineView/fixedCenterPlayhead(_:)'
--> ../TimelineView.swift:612:22-612:65
610 | /// toward the right edge as time advances.
611 | ///
612 + /// No-op when ``init(_:currentTime:selectedClipID:zoom:...)`` was not given
613 | /// `currentTime` — the playhead only renders in that case — or when `zoom`
614 | /// was not bound (without zoom there's no scroll view to drive). Manual
warning: 'onReorder' doesn't exist at '/KadrUI/TimelineView/onClipDragSnap(_:)'
--> ../TimelineView.swift:694:26-694:35
692 | /// adjacent-slot boundary — the moment the dragged clip would land on a
693 | /// new resting position if released. Same callback fires for chain
694 + /// reorders (when ``onReorder`` is bound) and Track-internal reorders
695 | /// (when ``onTrackReorder`` is bound). Consumers fire haptics from here.
696 | ///
warning: 'onTrackReorder' doesn't exist at '/KadrUI/TimelineView/onClipDragSnap(_:)'
--> ../TimelineView.swift:695:17-695:31
693 | /// new resting position if released. Same callback fires for chain
694 | /// reorders (when ``onReorder`` is bound) and Track-internal reorders
695 + /// (when ``onTrackReorder`` is bound). Consumers fire haptics from here.
696 | ///
697 | /// ```swift
warning: 'Kadr' doesn't exist at '/KadrUI/TimelineView/onLongPressClip(_:)'
--> ../TimelineView.swift:714:26-714:30
712 |
713 | /// Attach a callback that fires on a 0.5s long-press of any media clip
714 + /// with a non-nil ``Kadr/Clip/clipID``. Composes with the existing tap
715 | /// gesture via `simultaneousGesture` — the long-press fires only when
716 | /// the user holds without dragging (the 10-pt minimum-distance reorder
warning: 'reorderGesture(for:pxPerSecond:)' doesn't exist at '/KadrUI/TimelineView/snapTransition(previous:current:)'
--> ../TimelineView.swift:785:52-785:84
783 | /// Returns the new "last fired" target index after observing a transition
784 | /// from `previous` to `current`, plus whether the snap callback should
785 + /// fire. Mirrors the gesture-side update in ``reorderGesture(for:pxPerSecond:)``
786 | /// and ``trackReorderGesture(trackIndex:clipIndex:items:pxPerSecond:)`` so
787 | /// the change-detection rule has a single testable seam:
warning: 'trackReorderGesture(trackIndex:clipIndex:items:pxPerSecond:)' doesn't exist at '/KadrUI/TimelineView/snapTransition(previous:current:)'
--> ../TimelineView.swift:786:15-786:75
784 | /// from `previous` to `current`, plus whether the snap callback should
785 | /// fire. Mirrors the gesture-side update in ``reorderGesture(for:pxPerSecond:)``
786 + /// and ``trackReorderGesture(trackIndex:clipIndex:items:pxPerSecond:)`` so
787 | /// the change-detection rule has a single testable seam:
788 | /// - First observation of a value (`previous == nil`) latches the target
warning: 'Kadr' doesn't exist at '/KadrUI/TransitionKind'
--> ../TransitionPicker.swift:7:7-7:11
5 | /// The kinds of transition kadr can insert, as a value you can enumerate.
6 | ///
7 + /// ``Kadr/Transition`` carries associated values — a duration, and for slide a
8 | /// direction — so it cannot be `CaseIterable`. This is the menu-shaped view of
9 | /// it, in the same spirit as ``Kadr/FilterKind``.
warning: 'Kadr' doesn't exist at '/KadrUI/TransitionKind'
--> ../TransitionPicker.swift:9:33-9:37
7 | /// ``Kadr/Transition`` carries associated values — a duration, and for slide a
8 | /// direction — so it cannot be `CaseIterable`. This is the menu-shaped view of
9 + /// it, in the same spirit as ``Kadr/FilterKind``.
10 | ///
11 | /// Added in v0.19.
warning: 'rawValue' doesn't exist at '/KadrUI/TransitionKind/displayName'
--> ../TransitionPicker.swift:19:39-19:47
17 | public var id: String { rawValue }
18 |
19 + /// An English name, for menus. ``rawValue`` is a stable key a localised app
20 | /// can look up instead.
21 | public var displayName: String {
warning: 'Kadr' doesn't exist at '/KadrUI/TransitionKind/kind(of:)'
--> ../TransitionPicker.swift:45:27-45:31
43 | /// Which kind an existing transition is.
44 | ///
45 + /// Exhaustive over ``Kadr/Transition``, so a new transition case fails the
46 | /// build here until it is classified.
47 | public static func kind(of transition: Kadr.Transition) -> TransitionKind {
warning: 'Kadr' doesn't exist at '/KadrUI/SlideDirectionOption'
--> ../TransitionPicker.swift:56:27-56:31
54 | }
55 |
56 + /// Menu-shaped view of ``Kadr/SlideDirection``.
57 | ///
58 | /// A local mirror rather than an extension on kadr's type, deliberately.
warning: 'rawValue' doesn't exist at '/KadrUI/SlideDirectionOption/displayName'
--> ../TransitionPicker.swift:74:39-74:47
72 | public var id: String { rawValue }
73 |
74 + /// An English name, for menus. ``rawValue`` is a stable key a localised app
75 | /// can look up instead.
76 | public var displayName: String {
warning: 'Kadr' doesn't exist at '/KadrUI/TransitionPicker'
--> ../TransitionPicker.swift:112:22-112:26
110 | /// package offered a way to author one: every consumer building an editor wrote
111 | /// the same picker. Like the rest of KadrUI this view mutates nothing. It emits
112 + /// a fully-formed ``Kadr/Transition`` and the consumer rebuilds.
113 | ///
114 | /// ```swift
warning: 'Kadr' doesn't exist at '/KadrUI/VideoPreview'
--> ../VideoPreview.swift:6:43-6:47
4 | import Kadr
5 |
6 + /// A SwiftUI view that previews a Kadr ``Kadr/Video`` composition using `AVKit.VideoPlayer`.
7 | ///
8 | /// Drop a `Video` into a `VideoPreview` to play the composition without writing it to disk first.
warning: 'Kadr' doesn't exist at '/KadrUI/VideoPreview'
--> ../VideoPreview.swift:9:33-9:37
7 | ///
8 | /// Drop a `Video` into a `VideoPreview` to play the composition without writing it to disk first.
9 + /// What you see matches what ``Kadr/Video/export(to:)`` would write *except* overlays, which Kadr's
10 | /// preview surface intentionally excludes (`AVVideoCompositionCoreAnimationTool` is export-only).
11 | /// Render overlays as views layered over `VideoPreview` using
warning: 'Kadr' doesn't exist at '/KadrUI/VideoPreview'
--> ../VideoPreview.swift:12:7-12:11
10 | /// preview surface intentionally excludes (`AVVideoCompositionCoreAnimationTool` is export-only).
11 | /// Render overlays as views layered over `VideoPreview` using
12 + /// ``Kadr/Layout/resolveFrame(position:size:anchor:in:)`` for placement.
13 | ///
14 | /// ```swift
warning: 'Kadr' doesn't exist at '/KadrUI/VideoPreview'
--> ../VideoPreview.swift:27:67-27:71
25 | /// ```
26 | ///
27 + /// **Lifecycle.** The composition is loaded asynchronously via ``Kadr/Video/makePlayerItem()`` on first
28 | /// appear. While loading, the view shows a black background with a centered progress indicator. If
29 | /// loading fails, the view shows a black background with a warning glyph; pass an `onLoadFailure`
warning: 'Kadr' doesn't exist at '/KadrUI/VideoPreview/init(_:isPlaying:currentTime:loops:showsPlaybackControls:reloadToken:onLoadFailure:onSampleColor:)'
--> ../VideoPreview.swift:90:15-90:19
88 | /// insufficient — e.g. when you've edited a clip in place. Default `nil`.
89 | /// - onLoadFailure: Optional callback invoked on the main actor if
90 + /// ``Kadr/Video/makePlayerItem()`` throws. Default `nil`.
91 | /// - onSampleColor: Optional eyedropper. When set, a tap on the picture
92 | /// reports the colour under it plus the normalised point, so the caller
warning: Parameter 'showsPlaybackControls' is missing documentation
--> ../VideoPreview.swift:105:75-105:75
103 | /// - loops: When `true`, playback restarts at zero instead of stopping.
104 | /// Deliberately a plain value, not persisted state — looping is a
105 + /// session preference, and the package has no business owning it.
106 | public init(
107 | _ video: Video,
Finished building documentation for 'KadrUI' (8.38s)
Generated documentation archive at:
/Users/admin/builder/spi-builder-workspace/.docs/steliyanh/kadr-ui/v0.21.0
Fetching https://github.com/swiftlang/swift-docc-plugin
Updating https://github.com/pointfreeco/swift-custom-dump
Updating https://github.com/pointfreeco/swift-snapshot-testing
Updating https://github.com/nalexn/ViewInspector
Updated https://github.com/nalexn/ViewInspector (0.62s)
Updated https://github.com/pointfreeco/swift-snapshot-testing (0.67s)
Updated https://github.com/pointfreeco/swift-custom-dump (0.67s)
[1/2345] Fetching swift-docc-plugin
Updating https://github.com/SteliyanH/kadr.git
Updating https://github.com/swiftlang/swift-syntax
Updating https://github.com/pointfreeco/xctest-dynamic-overlay
Fetched https://github.com/swiftlang/swift-docc-plugin from cache (1.96s)
Updated https://github.com/SteliyanH/kadr.git (0.66s)
Computing version for https://github.com/nalexn/ViewInspector
Updated https://github.com/swiftlang/swift-syntax (1.01s)
Updated https://github.com/pointfreeco/xctest-dynamic-overlay (1.01s)
Computed https://github.com/nalexn/ViewInspector at 0.10.3 (3.10s)
Computing version for https://github.com/pointfreeco/swift-snapshot-testing
Computed https://github.com/pointfreeco/swift-snapshot-testing at 1.19.2 (0.46s)
Computing version for https://github.com/SteliyanH/kadr.git
Computed https://github.com/SteliyanH/kadr.git at 1.0.0 (0.42s)
Computing version for https://github.com/swiftlang/swift-syntax
Computed https://github.com/swiftlang/swift-syntax at 603.0.1 (0.62s)
Computing version for https://github.com/pointfreeco/swift-custom-dump
Computed https://github.com/pointfreeco/swift-custom-dump at 1.5.0 (0.44s)
Computing version for https://github.com/pointfreeco/xctest-dynamic-overlay
Computed https://github.com/pointfreeco/xctest-dynamic-overlay at 1.9.0 (0.46s)
Computing version for https://github.com/swiftlang/swift-docc-plugin
Computed https://github.com/swiftlang/swift-docc-plugin at 1.5.0 (0.62s)
Fetching https://github.com/swiftlang/swift-docc-symbolkit
[1/3817] Fetching swift-docc-symbolkit
Fetched https://github.com/swiftlang/swift-docc-symbolkit from cache (1.35s)
Computing version for https://github.com/swiftlang/swift-docc-symbolkit
Computed https://github.com/swiftlang/swift-docc-symbolkit at 1.0.0 (2.03s)
Creating working copy for https://github.com/swiftlang/swift-docc-plugin
Working copy of https://github.com/swiftlang/swift-docc-plugin resolved at 1.5.0
Creating working copy for https://github.com/swiftlang/swift-docc-symbolkit
Working copy of https://github.com/swiftlang/swift-docc-symbolkit resolved at 1.0.0
Building for debugging...
[0/8] Write sources
[2/8] Write snippet-extract-tool-entitlement.plist
[2/8] Write sources
[4/8] Write swift-version-69A768CDF2A0BEE1.txt
[6/54] Emitting module SymbolKit
[7/58] Compiling SymbolKit Relationship.swift
[8/58] Compiling SymbolKit RelationshipKind.swift
[9/58] Compiling SymbolKit SourceOrigin.swift
[10/58] Compiling SymbolKit GenericConstraints.swift
[11/58] Compiling SymbolKit Swift.swift
[12/58] Compiling SymbolKit SourceRange.swift
[13/58] Compiling SymbolKit Metadata.swift
[14/58] Compiling SymbolKit Module.swift
[15/58] Compiling SymbolKit OperatingSystem.swift
[16/58] Compiling SymbolKit Platform.swift
[17/58] Compiling SymbolKit DeclarationFragments.swift
[18/58] Compiling SymbolKit Fragment.swift
[19/58] Compiling SymbolKit FragmentKind.swift
[20/58] Compiling SymbolKit FunctionParameter.swift
[21/58] Compiling SymbolKit FunctionSignature.swift
[22/58] Compiling SymbolKit Mixin+Equals.swift
[23/58] Compiling SymbolKit Mixin+Hash.swift
[24/58] Compiling SymbolKit Mixin.swift
[25/58] Compiling SymbolKit LineList.swift
[26/58] Compiling SymbolKit Position.swift
[27/58] Compiling SymbolKit Names.swift
[28/58] Compiling SymbolKit SPI.swift
[29/58] Compiling SymbolKit Snippet.swift
[30/58] Compiling SymbolKit Extension.swift
[31/58] Compiling SymbolKit SemanticVersion.swift
[32/58] Compiling SymbolKit AccessControl.swift
[33/58] Compiling SymbolKit Availability.swift
[34/58] Compiling SymbolKit AvailabilityItem.swift
[35/58] Compiling SymbolKit Domain.swift
[36/58] Compiling SymbolKit GenericConstraint.swift
[37/58] Compiling SymbolKit GenericParameter.swift
[38/58] Compiling SymbolKit Generics.swift
[39/58] Compiling SymbolKit Namespace.swift
[40/58] Compiling SymbolKit Identifier.swift
[41/58] Compiling SymbolKit KindIdentifier.swift
[42/58] Compiling SymbolKit Location.swift
[43/58] Compiling SymbolKit Mutability.swift
[44/58] Compiling Snippets SnippetLanguage.swift
[45/58] Compiling Snippets Snippet.swift
[46/58] Compiling Snippets SnippetParser.swift
[47/58] Emitting module Snippets
[48/58] Compiling SymbolKit UnifiedSymbol+Encodable.swift
[49/58] Compiling SymbolKit UnifiedSymbol.swift
[50/58] Compiling SymbolKit UnifiedSymbolGraph+Encodable.swift
[51/58] Compiling SymbolKit UnifiedSymbolGraph.swift
[52/58] Compiling SymbolKit Symbol.swift
[53/58] Compiling SymbolKit SymbolKind.swift
[54/58] Compiling SymbolKit SymbolGraph.swift
[55/58] Compiling SymbolKit GraphCollector.swift
[56/62] Compiling snippet_extract URL+Status.swift
[57/62] Compiling snippet_extract SymbolGraph+Snippet.swift
[58/62] Emitting module snippet_extract
[59/62] Compiling snippet_extract SnippetBuildCommand.swift
[59/62] Write Objects.LinkFileList
[60/62] Linking snippet-extract-tool
[61/62] Applying snippet-extract-tool
Build of product 'snippet-extract' complete! (4.60s)
Building for debugging...
[0/1] Write swift-version-69A768CDF2A0BEE1.txt
Build of target: 'KadrUI' complete! (0.51s)
20394
136 /Users/admin/builder/spi-builder-workspace/.docs/steliyanh/kadr-ui/v0.21.0
✅ Doc result (uploading) reported
========================================
SyncDocs
========================================
Doc archive source directory: $PWD/.docs/steliyanh/kadr-ui/v0.21.0
File count: 20394
Doc size: 136.0MB
Preparing doc bundle ...
Using presigned URL upload - AWS credentials not required
Uploading -steliyanh-kadr-ui-v0.21.0-bd934747.zip to presigned URL
Starting upload of 28114531 bytes...
Upload completed successfully
Done.