diff --git a/docs/spot-removal.md b/docs/spot-removal.md index 0ebd07d..2ed0d28 100644 --- a/docs/spot-removal.md +++ b/docs/spot-removal.md @@ -399,10 +399,16 @@ what stops that from ever being possible. ### 10.1 The mode -A third chip in `ModeStrip`, beside Crop and Local, and a `ViewMode::spots`. -The strip's own documentation already predicted this shape for the brush; the +A `ViewMode::spots`, and a row in `ToolRail`'s table beside Crop and Local. +That table's own documentation already predicts this shape for the brush; the spot tool is the same shape and arrives first. +(It landed as a third chip in `ModeStrip`, at the head of the develop column. +The three canvas tools have since moved out to a fixed rail down the left of +the develop view — `ui/dr-ui/ui/toolrail.slint` carries why — and what remains +of that strip is the adjustment-group filters, now `GroupStrip`. Nothing about +the mode itself changed in the move.) + ### 10.2 Gestures | Gesture | Effect | diff --git a/docs/traceability.md b/docs/traceability.md index 10200b9..a4500e6 100644 --- a/docs/traceability.md +++ b/docs/traceability.md @@ -9,8 +9,8 @@ Denominators are parsed from [`requirements.md`](requirements.md) at run time, n | Metric | Value | |---|---| -| Source files scanned | 309 | -| TRACES tags found | 1015 | +| Source files scanned | 310 | +| TRACES tags found | 1008 | | Requirements defined | 179 | | Requirements covered | 122 | | **Coverage** | **68.2%** (122/179) | @@ -34,107 +34,107 @@ _None._ | ID | Tagged in | |---|---| | FR-CAT-1 | [`core/dr-catalog/src/scan.rs:1`](../core/dr-catalog/src/scan.rs#L1), [`core/dr-catalog/src/walk.rs:109`](../core/dr-catalog/src/walk.rs#L109), [`core/dr-catalog/src/walk.rs:162`](../core/dr-catalog/src/walk.rs#L162), [`core/dr-catalog/src/walk.rs:1`](../core/dr-catalog/src/walk.rs#L1), [`core/dr-sync/src/scan.rs:93`](../core/dr-sync/src/scan.rs#L93), [`core/dr-types/src/lib.rs:201`](../core/dr-types/src/lib.rs#L201), [`core/dr-types/src/lib.rs:270`](../core/dr-types/src/lib.rs#L270), [`core/dr-types/src/lib.rs:303`](../core/dr-types/src/lib.rs#L303), [`platform/dr-plat/src/storage.rs:1`](../platform/dr-plat/src/storage.rs#L1), [`platform/dr-plat/src/storage.rs:216`](../platform/dr-plat/src/storage.rs#L216), [`tools/traceability/src/lib.rs:481`](../tools/traceability/src/lib.rs#L481), [`tools/traceability/src/lib.rs:513`](../tools/traceability/src/lib.rs#L513), [`ui/dr-ui/src/activity.rs:1`](../ui/dr-ui/src/activity.rs#L1), [`ui/dr-ui/src/library.rs:1`](../ui/dr-ui/src/library.rs#L1) | -| FR-CAT-10 | [`core/dr-ingest/src/layout.rs:1`](../core/dr-ingest/src/layout.rs#L1), [`core/dr-ingest/src/lib.rs:1`](../core/dr-ingest/src/lib.rs#L1), [`core/dr-ingest/src/lib.rs:733`](../core/dr-ingest/src/lib.rs#L733), [`core/dr-types/src/settings.rs:206`](../core/dr-types/src/settings.rs#L206), [`platform/dr-plat/src/storage.rs:287`](../platform/dr-plat/src/storage.rs#L287), [`platform/dr-plat/src/storage.rs:586`](../platform/dr-plat/src/storage.rs#L586), [`platform/dr-plat/src/volumes.rs:1`](../platform/dr-plat/src/volumes.rs#L1), [`platform/dr-plat/src/volumes.rs:62`](../platform/dr-plat/src/volumes.rs#L62), [`ui/dr-ui/src/import.rs:1`](../ui/dr-ui/src/import.rs#L1), [`ui/dr-ui/src/import.rs:336`](../ui/dr-ui/src/import.rs#L336), [`ui/dr-ui/src/import_ui.rs:1`](../ui/dr-ui/src/import_ui.rs#L1), [`ui/dr-ui/src/lib.rs:1215`](../ui/dr-ui/src/lib.rs#L1215), [`ui/dr-ui/ui/import.slint:5`](../ui/dr-ui/ui/import.slint#L5), [`ui/dr-ui/ui/library.slint:1047`](../ui/dr-ui/ui/library.slint#L1047), [`ui/dr-ui/ui/library.slint:1226`](../ui/dr-ui/ui/library.slint#L1226), [`ui/dr-ui/ui/library.slint:879`](../ui/dr-ui/ui/library.slint#L879) | -| FR-CAT-11 | [`core/dr-catalog/src/dedup.rs:1`](../core/dr-catalog/src/dedup.rs#L1), [`core/dr-ingest/src/lib.rs:1`](../core/dr-ingest/src/lib.rs#L1), [`core/dr-ingest/src/lib.rs:392`](../core/dr-ingest/src/lib.rs#L392), [`core/dr-sync/src/upload.rs:40`](../core/dr-sync/src/upload.rs#L40), [`ui/dr-ui/src/import.rs:1`](../ui/dr-ui/src/import.rs#L1), [`ui/dr-ui/src/import_ui.rs:1`](../ui/dr-ui/src/import_ui.rs#L1), [`ui/dr-ui/src/lib.rs:1215`](../ui/dr-ui/src/lib.rs#L1215), [`ui/dr-ui/src/library.rs:175`](../ui/dr-ui/src/library.rs#L175), [`ui/dr-ui/src/library.rs:2491`](../ui/dr-ui/src/library.rs#L2491), [`ui/dr-ui/ui/import.slint:5`](../ui/dr-ui/ui/import.slint#L5) | +| FR-CAT-10 | [`core/dr-ingest/src/layout.rs:1`](../core/dr-ingest/src/layout.rs#L1), [`core/dr-ingest/src/lib.rs:1`](../core/dr-ingest/src/lib.rs#L1), [`core/dr-ingest/src/lib.rs:733`](../core/dr-ingest/src/lib.rs#L733), [`core/dr-types/src/settings.rs:206`](../core/dr-types/src/settings.rs#L206), [`platform/dr-plat/src/storage.rs:287`](../platform/dr-plat/src/storage.rs#L287), [`platform/dr-plat/src/storage.rs:586`](../platform/dr-plat/src/storage.rs#L586), [`platform/dr-plat/src/volumes.rs:1`](../platform/dr-plat/src/volumes.rs#L1), [`platform/dr-plat/src/volumes.rs:62`](../platform/dr-plat/src/volumes.rs#L62), [`ui/dr-ui/src/import.rs:1`](../ui/dr-ui/src/import.rs#L1), [`ui/dr-ui/src/import.rs:336`](../ui/dr-ui/src/import.rs#L336), [`ui/dr-ui/src/import_ui.rs:1`](../ui/dr-ui/src/import_ui.rs#L1), [`ui/dr-ui/src/lib.rs:1221`](../ui/dr-ui/src/lib.rs#L1221), [`ui/dr-ui/ui/import.slint:5`](../ui/dr-ui/ui/import.slint#L5), [`ui/dr-ui/ui/library.slint:1047`](../ui/dr-ui/ui/library.slint#L1047), [`ui/dr-ui/ui/library.slint:1226`](../ui/dr-ui/ui/library.slint#L1226), [`ui/dr-ui/ui/library.slint:879`](../ui/dr-ui/ui/library.slint#L879) | +| FR-CAT-11 | [`core/dr-catalog/src/dedup.rs:1`](../core/dr-catalog/src/dedup.rs#L1), [`core/dr-ingest/src/lib.rs:1`](../core/dr-ingest/src/lib.rs#L1), [`core/dr-ingest/src/lib.rs:392`](../core/dr-ingest/src/lib.rs#L392), [`core/dr-sync/src/upload.rs:40`](../core/dr-sync/src/upload.rs#L40), [`ui/dr-ui/src/import.rs:1`](../ui/dr-ui/src/import.rs#L1), [`ui/dr-ui/src/import_ui.rs:1`](../ui/dr-ui/src/import_ui.rs#L1), [`ui/dr-ui/src/lib.rs:1221`](../ui/dr-ui/src/lib.rs#L1221), [`ui/dr-ui/src/library.rs:175`](../ui/dr-ui/src/library.rs#L175), [`ui/dr-ui/src/library.rs:2491`](../ui/dr-ui/src/library.rs#L2491), [`ui/dr-ui/ui/import.slint:5`](../ui/dr-ui/ui/import.slint#L5) | | FR-CAT-12 | [`core/dr-pipeline/src/sidecar.rs:119`](../core/dr-pipeline/src/sidecar.rs#L119) | | FR-CAT-13 | [`core/dr-catalog/src/keywords.rs:1`](../core/dr-catalog/src/keywords.rs#L1) | | FR-CAT-15 | [`core/dr-catalog/src/schema.rs:720`](../core/dr-catalog/src/schema.rs#L720), [`core/dr-catalog/src/trash.rs:1`](../core/dr-catalog/src/trash.rs#L1), [`core/dr-sync-nextcloud/src/lib.rs:457`](../core/dr-sync-nextcloud/src/lib.rs#L457), [`core/dr-sync/src/lib.rs:135`](../core/dr-sync/src/lib.rs#L135), [`core/dr-sync/src/scan.rs:563`](../core/dr-sync/src/scan.rs#L563), [`core/dr-sync/src/scan.rs:57`](../core/dr-sync/src/scan.rs#L57), [`core/dr-thumbs/src/lib.rs:376`](../core/dr-thumbs/src/lib.rs#L376), [`ui/dr-ui/src/collections_ui.rs:1232`](../ui/dr-ui/src/collections_ui.rs#L1232), [`ui/dr-ui/src/collections_ui.rs:2105`](../ui/dr-ui/src/collections_ui.rs#L2105), [`ui/dr-ui/src/library.rs:175`](../ui/dr-ui/src/library.rs#L175), [`ui/dr-ui/src/library.rs:192`](../ui/dr-ui/src/library.rs#L192), [`ui/dr-ui/src/library.rs:241`](../ui/dr-ui/src/library.rs#L241), [`ui/dr-ui/src/library.rs:3992`](../ui/dr-ui/src/library.rs#L3992), [`ui/dr-ui/src/library.rs:4026`](../ui/dr-ui/src/library.rs#L4026), [`ui/dr-ui/src/library_ui.rs:190`](../ui/dr-ui/src/library_ui.rs#L190), [`ui/dr-ui/src/library_ui.rs:778`](../ui/dr-ui/src/library_ui.rs#L778), [`ui/dr-ui/src/trash.rs:1`](../ui/dr-ui/src/trash.rs#L1), [`ui/dr-ui/ui/collections.slint:572`](../ui/dr-ui/ui/collections.slint#L572) | | FR-CAT-1a | [`core/dr-catalog/src/walk.rs:1`](../core/dr-catalog/src/walk.rs#L1), [`core/dr-types/src/lib.rs:54`](../core/dr-types/src/lib.rs#L54), [`platform/dr-plat/src/storage.rs:1`](../platform/dr-plat/src/storage.rs#L1), [`platform/dr-plat/src/storage.rs:216`](../platform/dr-plat/src/storage.rs#L216), [`platform/dr-plat/src/storage.rs:46`](../platform/dr-plat/src/storage.rs#L46) | | FR-CAT-2 | [`core/dr-catalog/src/lib.rs:1`](../core/dr-catalog/src/lib.rs#L1), [`core/dr-catalog/src/schema.rs:1`](../core/dr-catalog/src/schema.rs#L1), [`tools/traceability/src/lib.rs:481`](../tools/traceability/src/lib.rs#L481) | -| FR-CAT-3 | [`core/dr-catalog/src/jobs.rs:1`](../core/dr-catalog/src/jobs.rs#L1), [`core/dr-catalog/src/walk.rs:66`](../core/dr-catalog/src/walk.rs#L66), [`core/dr-sync/src/scan.rs:69`](../core/dr-sync/src/scan.rs#L69), [`core/dr-thumbs/src/codec.rs:1`](../core/dr-thumbs/src/codec.rs#L1), [`core/dr-thumbs/src/lib.rs:1`](../core/dr-thumbs/src/lib.rs#L1), [`ui/dr-ui/src/derived_sync.rs:1`](../ui/dr-ui/src/derived_sync.rs#L1), [`ui/dr-ui/src/import.rs:463`](../ui/dr-ui/src/import.rs#L463), [`ui/dr-ui/src/import.rs:488`](../ui/dr-ui/src/import.rs#L488), [`ui/dr-ui/src/library.rs:2964`](../ui/dr-ui/src/library.rs#L2964), [`ui/dr-ui/src/library.rs:3472`](../ui/dr-ui/src/library.rs#L3472), [`ui/dr-ui/src/library_ui.rs:172`](../ui/dr-ui/src/library_ui.rs#L172), [`ui/dr-ui/src/library_ui.rs:3731`](../ui/dr-ui/src/library_ui.rs#L3731), [`ui/dr-ui/src/library_ui.rs:4749`](../ui/dr-ui/src/library_ui.rs#L4749), [`ui/dr-ui/ui/app.slint:386`](../ui/dr-ui/ui/app.slint#L386), [`ui/dr-ui/ui/settings.slint:387`](../ui/dr-ui/ui/settings.slint#L387), [`ui/dr-ui/ui/settings.slint:73`](../ui/dr-ui/ui/settings.slint#L73) | +| FR-CAT-3 | [`core/dr-catalog/src/jobs.rs:1`](../core/dr-catalog/src/jobs.rs#L1), [`core/dr-catalog/src/walk.rs:66`](../core/dr-catalog/src/walk.rs#L66), [`core/dr-sync/src/scan.rs:69`](../core/dr-sync/src/scan.rs#L69), [`core/dr-thumbs/src/codec.rs:1`](../core/dr-thumbs/src/codec.rs#L1), [`core/dr-thumbs/src/lib.rs:1`](../core/dr-thumbs/src/lib.rs#L1), [`ui/dr-ui/src/derived_sync.rs:1`](../ui/dr-ui/src/derived_sync.rs#L1), [`ui/dr-ui/src/import.rs:463`](../ui/dr-ui/src/import.rs#L463), [`ui/dr-ui/src/import.rs:488`](../ui/dr-ui/src/import.rs#L488), [`ui/dr-ui/src/library.rs:2964`](../ui/dr-ui/src/library.rs#L2964), [`ui/dr-ui/src/library.rs:3472`](../ui/dr-ui/src/library.rs#L3472), [`ui/dr-ui/src/library_ui.rs:172`](../ui/dr-ui/src/library_ui.rs#L172), [`ui/dr-ui/src/library_ui.rs:3731`](../ui/dr-ui/src/library_ui.rs#L3731), [`ui/dr-ui/src/library_ui.rs:4749`](../ui/dr-ui/src/library_ui.rs#L4749), [`ui/dr-ui/ui/app.slint:387`](../ui/dr-ui/ui/app.slint#L387), [`ui/dr-ui/ui/settings.slint:387`](../ui/dr-ui/ui/settings.slint#L387), [`ui/dr-ui/ui/settings.slint:73`](../ui/dr-ui/ui/settings.slint#L73) | | FR-CAT-4 | [`core/dr-catalog/src/lib.rs:1`](../core/dr-catalog/src/lib.rs#L1), [`core/dr-catalog/src/query.rs:1`](../core/dr-catalog/src/query.rs#L1), [`core/dr-catalog/src/schema.rs:330`](../core/dr-catalog/src/schema.rs#L330), [`ui/dr-ui/src/library.rs:1`](../ui/dr-ui/src/library.rs#L1), [`ui/dr-ui/src/library.rs:222`](../ui/dr-ui/src/library.rs#L222), [`ui/dr-ui/src/library_ui.rs:1`](../ui/dr-ui/src/library_ui.rs#L1) | -| FR-CAT-5 | [`core/dr-catalog/src/keywords.rs:1`](../core/dr-catalog/src/keywords.rs#L1), [`core/dr-catalog/src/merge.rs:1`](../core/dr-catalog/src/merge.rs#L1), [`core/dr-catalog/src/rating.rs:1`](../core/dr-catalog/src/rating.rs#L1), [`core/dr-catalog/src/schema.rs:1138`](../core/dr-catalog/src/schema.rs#L1138), [`core/dr-catalog/src/schema.rs:635`](../core/dr-catalog/src/schema.rs#L635), [`core/dr-decode/src/lib.rs:285`](../core/dr-decode/src/lib.rs#L285), [`core/dr-decode/src/lib.rs:404`](../core/dr-decode/src/lib.rs#L404), [`core/dr-pipeline/src/sidecar.rs:136`](../core/dr-pipeline/src/sidecar.rs#L136), [`ui/dr-ui/src/collections_ui.rs:1525`](../ui/dr-ui/src/collections_ui.rs#L1525), [`ui/dr-ui/src/collections_ui.rs:1631`](../ui/dr-ui/src/collections_ui.rs#L1631), [`ui/dr-ui/src/collections_ui.rs:1680`](../ui/dr-ui/src/collections_ui.rs#L1680), [`ui/dr-ui/src/collections_ui.rs:244`](../ui/dr-ui/src/collections_ui.rs#L244), [`ui/dr-ui/src/collections_ui.rs:341`](../ui/dr-ui/src/collections_ui.rs#L341), [`ui/dr-ui/src/collections_ui.rs:90`](../ui/dr-ui/src/collections_ui.rs#L90), [`ui/dr-ui/src/library.rs:4040`](../ui/dr-ui/src/library.rs#L4040), [`ui/dr-ui/src/library_ui.rs:653`](../ui/dr-ui/src/library_ui.rs#L653), [`ui/dr-ui/src/library_ui.rs:6676`](../ui/dr-ui/src/library_ui.rs#L6676), [`ui/dr-ui/src/library_ui.rs:6687`](../ui/dr-ui/src/library_ui.rs#L6687), [`ui/dr-ui/src/library_ui.rs:6700`](../ui/dr-ui/src/library_ui.rs#L6700), [`ui/dr-ui/src/library_ui.rs:6715`](../ui/dr-ui/src/library_ui.rs#L6715), [`ui/dr-ui/src/library_ui.rs:6724`](../ui/dr-ui/src/library_ui.rs#L6724), [`ui/dr-ui/ui/app.slint:322`](../ui/dr-ui/ui/app.slint#L322), [`ui/dr-ui/ui/app.slint:521`](../ui/dr-ui/ui/app.slint#L521), [`ui/dr-ui/ui/library.slint:1298`](../ui/dr-ui/ui/library.slint#L1298), [`ui/dr-ui/ui/library.slint:1322`](../ui/dr-ui/ui/library.slint#L1322), [`ui/dr-ui/ui/library.slint:1375`](../ui/dr-ui/ui/library.slint#L1375), [`ui/dr-ui/ui/library.slint:19`](../ui/dr-ui/ui/library.slint#L19), [`ui/dr-ui/ui/library.slint:872`](../ui/dr-ui/ui/library.slint#L872), [`ui/dr-ui/ui/library.slint:927`](../ui/dr-ui/ui/library.slint#L927) | -| FR-CAT-6 | [`core/dr-catalog/src/collections.rs:1`](../core/dr-catalog/src/collections.rs#L1), [`core/dr-catalog/src/keywords.rs:1`](../core/dr-catalog/src/keywords.rs#L1), [`core/dr-catalog/src/lib.rs:1`](../core/dr-catalog/src/lib.rs#L1), [`core/dr-catalog/src/query.rs:1`](../core/dr-catalog/src/query.rs#L1), [`core/dr-catalog/src/rating.rs:1`](../core/dr-catalog/src/rating.rs#L1), [`core/dr-catalog/src/schema.rs:635`](../core/dr-catalog/src/schema.rs#L635), [`core/dr-types/src/selector.rs:1`](../core/dr-types/src/selector.rs#L1), [`core/dr-types/src/settings.rs:64`](../core/dr-types/src/settings.rs#L64), [`core/dr-types/src/time.rs:67`](../core/dr-types/src/time.rs#L67), [`core/dr-types/src/time.rs:90`](../core/dr-types/src/time.rs#L90), [`ui/dr-ui/src/library.rs:246`](../ui/dr-ui/src/library.rs#L246), [`ui/dr-ui/src/library.rs:4433`](../ui/dr-ui/src/library.rs#L4433), [`ui/dr-ui/src/library_ui.rs:337`](../ui/dr-ui/src/library_ui.rs#L337), [`ui/dr-ui/src/library_ui.rs:410`](../ui/dr-ui/src/library_ui.rs#L410), [`ui/dr-ui/src/library_ui.rs:5416`](../ui/dr-ui/src/library_ui.rs#L5416), [`ui/dr-ui/src/library_ui.rs:5469`](../ui/dr-ui/src/library_ui.rs#L5469), [`ui/dr-ui/src/library_ui.rs:6816`](../ui/dr-ui/src/library_ui.rs#L6816), [`ui/dr-ui/ui/app.slint:334`](../ui/dr-ui/ui/app.slint#L334), [`ui/dr-ui/ui/app.slint:521`](../ui/dr-ui/ui/app.slint#L521), [`ui/dr-ui/ui/app.slint:817`](../ui/dr-ui/ui/app.slint#L817), [`ui/dr-ui/ui/library.slint:110`](../ui/dr-ui/ui/library.slint#L110), [`ui/dr-ui/ui/library.slint:1468`](../ui/dr-ui/ui/library.slint#L1468), [`ui/dr-ui/ui/library.slint:927`](../ui/dr-ui/ui/library.slint#L927), [`ui/dr-ui/ui/settings.slint:150`](../ui/dr-ui/ui/settings.slint#L150) | -| FR-CAT-7 | [`core/dr-catalog/src/collections.rs:1`](../core/dr-catalog/src/collections.rs#L1), [`core/dr-catalog/src/merge.rs:1`](../core/dr-catalog/src/merge.rs#L1), [`core/dr-catalog/src/sync.rs:1`](../core/dr-catalog/src/sync.rs#L1), [`core/dr-types/src/selector.rs:1`](../core/dr-types/src/selector.rs#L1), [`ui/dr-ui/src/collections_ui.rs:1544`](../ui/dr-ui/src/collections_ui.rs#L1544), [`ui/dr-ui/src/collections_ui.rs:1794`](../ui/dr-ui/src/collections_ui.rs#L1794), [`ui/dr-ui/src/collections_ui.rs:1`](../ui/dr-ui/src/collections_ui.rs#L1), [`ui/dr-ui/src/collections_ui.rs:928`](../ui/dr-ui/src/collections_ui.rs#L928), [`ui/dr-ui/src/derived_sync.rs:1`](../ui/dr-ui/src/derived_sync.rs#L1), [`ui/dr-ui/src/library.rs:4238`](../ui/dr-ui/src/library.rs#L4238), [`ui/dr-ui/src/library.rs:4264`](../ui/dr-ui/src/library.rs#L4264), [`ui/dr-ui/src/library.rs:4319`](../ui/dr-ui/src/library.rs#L4319), [`ui/dr-ui/src/library_ui.rs:3593`](../ui/dr-ui/src/library_ui.rs#L3593), [`ui/dr-ui/src/library_ui.rs:4320`](../ui/dr-ui/src/library_ui.rs#L4320), [`ui/dr-ui/ui/app.slint:325`](../ui/dr-ui/ui/app.slint#L325), [`ui/dr-ui/ui/app.slint:516`](../ui/dr-ui/ui/app.slint#L516), [`ui/dr-ui/ui/collections.slint:4`](../ui/dr-ui/ui/collections.slint#L4), [`ui/dr-ui/ui/library.slint:2828`](../ui/dr-ui/ui/library.slint#L2828), [`ui/dr-ui/ui/library.slint:898`](../ui/dr-ui/ui/library.slint#L898), [`ui/dr-ui/ui/library.slint:917`](../ui/dr-ui/ui/library.slint#L917) | -| FR-CAT-8 | [`core/dr-pipeline/src/graph.rs:346`](../core/dr-pipeline/src/graph.rs#L346), [`core/dr-pipeline/src/graph.rs:385`](../core/dr-pipeline/src/graph.rs#L385), [`core/dr-pipeline/src/ops/curve.rs:137`](../core/dr-pipeline/src/ops/curve.rs#L137), [`core/dr-pipeline/src/ops/curve.rs:656`](../core/dr-pipeline/src/ops/curve.rs#L656), [`core/dr-pipeline/src/sidecar.rs:1637`](../core/dr-pipeline/src/sidecar.rs#L1637), [`core/dr-pipeline/src/sidecar.rs:93`](../core/dr-pipeline/src/sidecar.rs#L93), [`core/dr-pipeline/src/state.rs:1`](../core/dr-pipeline/src/state.rs#L1), [`core/dr-pipeline/src/state.rs:75`](../core/dr-pipeline/src/state.rs#L75), [`core/dr-pipeline/tests/tone_curve.rs:34`](../core/dr-pipeline/tests/tone_curve.rs#L34), [`ui/dr-ui/src/develop.rs:3802`](../ui/dr-ui/src/develop.rs#L3802), [`ui/dr-ui/src/develop.rs:3831`](../ui/dr-ui/src/develop.rs#L3831), [`ui/dr-ui/src/export.rs:750`](../ui/dr-ui/src/export.rs#L750), [`ui/dr-ui/src/lib.rs:1494`](../ui/dr-ui/src/lib.rs#L1494), [`ui/dr-ui/src/lib.rs:1984`](../ui/dr-ui/src/lib.rs#L1984), [`ui/dr-ui/src/lib.rs:2119`](../ui/dr-ui/src/lib.rs#L2119), [`ui/dr-ui/src/lib.rs:573`](../ui/dr-ui/src/lib.rs#L573), [`ui/dr-ui/src/lib.rs:998`](../ui/dr-ui/src/lib.rs#L998), [`ui/dr-ui/src/library.rs:1903`](../ui/dr-ui/src/library.rs#L1903), [`ui/dr-ui/src/library.rs:492`](../ui/dr-ui/src/library.rs#L492), [`ui/dr-ui/src/library.rs:539`](../ui/dr-ui/src/library.rs#L539), [`ui/dr-ui/src/library.rs:576`](../ui/dr-ui/src/library.rs#L576), [`ui/dr-ui/src/library.rs:823`](../ui/dr-ui/src/library.rs#L823), [`ui/dr-ui/src/library_ui.rs:5041`](../ui/dr-ui/src/library_ui.rs#L5041), [`ui/dr-ui/src/sidecar_cache.rs:1`](../ui/dr-ui/src/sidecar_cache.rs#L1) | +| FR-CAT-5 | [`core/dr-catalog/src/keywords.rs:1`](../core/dr-catalog/src/keywords.rs#L1), [`core/dr-catalog/src/merge.rs:1`](../core/dr-catalog/src/merge.rs#L1), [`core/dr-catalog/src/rating.rs:1`](../core/dr-catalog/src/rating.rs#L1), [`core/dr-catalog/src/schema.rs:1138`](../core/dr-catalog/src/schema.rs#L1138), [`core/dr-catalog/src/schema.rs:635`](../core/dr-catalog/src/schema.rs#L635), [`core/dr-decode/src/lib.rs:285`](../core/dr-decode/src/lib.rs#L285), [`core/dr-decode/src/lib.rs:404`](../core/dr-decode/src/lib.rs#L404), [`core/dr-pipeline/src/sidecar.rs:136`](../core/dr-pipeline/src/sidecar.rs#L136), [`ui/dr-ui/src/collections_ui.rs:1525`](../ui/dr-ui/src/collections_ui.rs#L1525), [`ui/dr-ui/src/collections_ui.rs:1631`](../ui/dr-ui/src/collections_ui.rs#L1631), [`ui/dr-ui/src/collections_ui.rs:1680`](../ui/dr-ui/src/collections_ui.rs#L1680), [`ui/dr-ui/src/collections_ui.rs:244`](../ui/dr-ui/src/collections_ui.rs#L244), [`ui/dr-ui/src/collections_ui.rs:341`](../ui/dr-ui/src/collections_ui.rs#L341), [`ui/dr-ui/src/collections_ui.rs:90`](../ui/dr-ui/src/collections_ui.rs#L90), [`ui/dr-ui/src/library.rs:4040`](../ui/dr-ui/src/library.rs#L4040), [`ui/dr-ui/src/library_ui.rs:653`](../ui/dr-ui/src/library_ui.rs#L653), [`ui/dr-ui/src/library_ui.rs:6676`](../ui/dr-ui/src/library_ui.rs#L6676), [`ui/dr-ui/src/library_ui.rs:6687`](../ui/dr-ui/src/library_ui.rs#L6687), [`ui/dr-ui/src/library_ui.rs:6700`](../ui/dr-ui/src/library_ui.rs#L6700), [`ui/dr-ui/src/library_ui.rs:6715`](../ui/dr-ui/src/library_ui.rs#L6715), [`ui/dr-ui/src/library_ui.rs:6724`](../ui/dr-ui/src/library_ui.rs#L6724), [`ui/dr-ui/ui/app.slint:323`](../ui/dr-ui/ui/app.slint#L323), [`ui/dr-ui/ui/app.slint:522`](../ui/dr-ui/ui/app.slint#L522), [`ui/dr-ui/ui/library.slint:1298`](../ui/dr-ui/ui/library.slint#L1298), [`ui/dr-ui/ui/library.slint:1322`](../ui/dr-ui/ui/library.slint#L1322), [`ui/dr-ui/ui/library.slint:1375`](../ui/dr-ui/ui/library.slint#L1375), [`ui/dr-ui/ui/library.slint:19`](../ui/dr-ui/ui/library.slint#L19), [`ui/dr-ui/ui/library.slint:872`](../ui/dr-ui/ui/library.slint#L872), [`ui/dr-ui/ui/library.slint:927`](../ui/dr-ui/ui/library.slint#L927) | +| FR-CAT-6 | [`core/dr-catalog/src/collections.rs:1`](../core/dr-catalog/src/collections.rs#L1), [`core/dr-catalog/src/keywords.rs:1`](../core/dr-catalog/src/keywords.rs#L1), [`core/dr-catalog/src/lib.rs:1`](../core/dr-catalog/src/lib.rs#L1), [`core/dr-catalog/src/query.rs:1`](../core/dr-catalog/src/query.rs#L1), [`core/dr-catalog/src/rating.rs:1`](../core/dr-catalog/src/rating.rs#L1), [`core/dr-catalog/src/schema.rs:635`](../core/dr-catalog/src/schema.rs#L635), [`core/dr-types/src/selector.rs:1`](../core/dr-types/src/selector.rs#L1), [`core/dr-types/src/settings.rs:64`](../core/dr-types/src/settings.rs#L64), [`core/dr-types/src/time.rs:67`](../core/dr-types/src/time.rs#L67), [`core/dr-types/src/time.rs:90`](../core/dr-types/src/time.rs#L90), [`ui/dr-ui/src/library.rs:246`](../ui/dr-ui/src/library.rs#L246), [`ui/dr-ui/src/library.rs:4433`](../ui/dr-ui/src/library.rs#L4433), [`ui/dr-ui/src/library_ui.rs:337`](../ui/dr-ui/src/library_ui.rs#L337), [`ui/dr-ui/src/library_ui.rs:410`](../ui/dr-ui/src/library_ui.rs#L410), [`ui/dr-ui/src/library_ui.rs:5416`](../ui/dr-ui/src/library_ui.rs#L5416), [`ui/dr-ui/src/library_ui.rs:5469`](../ui/dr-ui/src/library_ui.rs#L5469), [`ui/dr-ui/src/library_ui.rs:6816`](../ui/dr-ui/src/library_ui.rs#L6816), [`ui/dr-ui/ui/app.slint:335`](../ui/dr-ui/ui/app.slint#L335), [`ui/dr-ui/ui/app.slint:522`](../ui/dr-ui/ui/app.slint#L522), [`ui/dr-ui/ui/app.slint:818`](../ui/dr-ui/ui/app.slint#L818), [`ui/dr-ui/ui/library.slint:110`](../ui/dr-ui/ui/library.slint#L110), [`ui/dr-ui/ui/library.slint:1468`](../ui/dr-ui/ui/library.slint#L1468), [`ui/dr-ui/ui/library.slint:927`](../ui/dr-ui/ui/library.slint#L927), [`ui/dr-ui/ui/settings.slint:150`](../ui/dr-ui/ui/settings.slint#L150) | +| FR-CAT-7 | [`core/dr-catalog/src/collections.rs:1`](../core/dr-catalog/src/collections.rs#L1), [`core/dr-catalog/src/merge.rs:1`](../core/dr-catalog/src/merge.rs#L1), [`core/dr-catalog/src/sync.rs:1`](../core/dr-catalog/src/sync.rs#L1), [`core/dr-types/src/selector.rs:1`](../core/dr-types/src/selector.rs#L1), [`ui/dr-ui/src/collections_ui.rs:1544`](../ui/dr-ui/src/collections_ui.rs#L1544), [`ui/dr-ui/src/collections_ui.rs:1794`](../ui/dr-ui/src/collections_ui.rs#L1794), [`ui/dr-ui/src/collections_ui.rs:1`](../ui/dr-ui/src/collections_ui.rs#L1), [`ui/dr-ui/src/collections_ui.rs:928`](../ui/dr-ui/src/collections_ui.rs#L928), [`ui/dr-ui/src/derived_sync.rs:1`](../ui/dr-ui/src/derived_sync.rs#L1), [`ui/dr-ui/src/library.rs:4238`](../ui/dr-ui/src/library.rs#L4238), [`ui/dr-ui/src/library.rs:4264`](../ui/dr-ui/src/library.rs#L4264), [`ui/dr-ui/src/library.rs:4319`](../ui/dr-ui/src/library.rs#L4319), [`ui/dr-ui/src/library_ui.rs:3593`](../ui/dr-ui/src/library_ui.rs#L3593), [`ui/dr-ui/src/library_ui.rs:4320`](../ui/dr-ui/src/library_ui.rs#L4320), [`ui/dr-ui/ui/app.slint:326`](../ui/dr-ui/ui/app.slint#L326), [`ui/dr-ui/ui/app.slint:517`](../ui/dr-ui/ui/app.slint#L517), [`ui/dr-ui/ui/collections.slint:4`](../ui/dr-ui/ui/collections.slint#L4), [`ui/dr-ui/ui/library.slint:2828`](../ui/dr-ui/ui/library.slint#L2828), [`ui/dr-ui/ui/library.slint:898`](../ui/dr-ui/ui/library.slint#L898), [`ui/dr-ui/ui/library.slint:917`](../ui/dr-ui/ui/library.slint#L917) | +| FR-CAT-8 | [`core/dr-pipeline/src/graph.rs:346`](../core/dr-pipeline/src/graph.rs#L346), [`core/dr-pipeline/src/graph.rs:385`](../core/dr-pipeline/src/graph.rs#L385), [`core/dr-pipeline/src/ops/curve.rs:137`](../core/dr-pipeline/src/ops/curve.rs#L137), [`core/dr-pipeline/src/ops/curve.rs:656`](../core/dr-pipeline/src/ops/curve.rs#L656), [`core/dr-pipeline/src/sidecar.rs:1637`](../core/dr-pipeline/src/sidecar.rs#L1637), [`core/dr-pipeline/src/sidecar.rs:93`](../core/dr-pipeline/src/sidecar.rs#L93), [`core/dr-pipeline/src/state.rs:1`](../core/dr-pipeline/src/state.rs#L1), [`core/dr-pipeline/src/state.rs:75`](../core/dr-pipeline/src/state.rs#L75), [`core/dr-pipeline/tests/tone_curve.rs:34`](../core/dr-pipeline/tests/tone_curve.rs#L34), [`ui/dr-ui/src/develop.rs:3802`](../ui/dr-ui/src/develop.rs#L3802), [`ui/dr-ui/src/develop.rs:3831`](../ui/dr-ui/src/develop.rs#L3831), [`ui/dr-ui/src/export.rs:750`](../ui/dr-ui/src/export.rs#L750), [`ui/dr-ui/src/lib.rs:1004`](../ui/dr-ui/src/lib.rs#L1004), [`ui/dr-ui/src/lib.rs:1500`](../ui/dr-ui/src/lib.rs#L1500), [`ui/dr-ui/src/lib.rs:1990`](../ui/dr-ui/src/lib.rs#L1990), [`ui/dr-ui/src/lib.rs:2125`](../ui/dr-ui/src/lib.rs#L2125), [`ui/dr-ui/src/lib.rs:579`](../ui/dr-ui/src/lib.rs#L579), [`ui/dr-ui/src/library.rs:1903`](../ui/dr-ui/src/library.rs#L1903), [`ui/dr-ui/src/library.rs:492`](../ui/dr-ui/src/library.rs#L492), [`ui/dr-ui/src/library.rs:539`](../ui/dr-ui/src/library.rs#L539), [`ui/dr-ui/src/library.rs:576`](../ui/dr-ui/src/library.rs#L576), [`ui/dr-ui/src/library.rs:823`](../ui/dr-ui/src/library.rs#L823), [`ui/dr-ui/src/library_ui.rs:5041`](../ui/dr-ui/src/library_ui.rs#L5041), [`ui/dr-ui/src/sidecar_cache.rs:1`](../ui/dr-ui/src/sidecar_cache.rs#L1) | | FR-CAT-9 | [`core/dr-catalog/src/cache.rs:1`](../core/dr-catalog/src/cache.rs#L1), [`core/dr-catalog/src/scan.rs:1`](../core/dr-catalog/src/scan.rs#L1), [`core/dr-catalog/src/schema.rs:692`](../core/dr-catalog/src/schema.rs#L692), [`core/dr-catalog/src/walk.rs:1022`](../core/dr-catalog/src/walk.rs#L1022), [`core/dr-catalog/src/walk.rs:162`](../core/dr-catalog/src/walk.rs#L162), [`core/dr-catalog/src/walk.rs:1`](../core/dr-catalog/src/walk.rs#L1), [`core/dr-catalog/src/walk.rs:435`](../core/dr-catalog/src/walk.rs#L435), [`core/dr-catalog/src/walk.rs:728`](../core/dr-catalog/src/walk.rs#L728), [`core/dr-sync-nextcloud/src/desktop_client.rs:30`](../core/dr-sync-nextcloud/src/desktop_client.rs#L30), [`core/dr-sync/src/error.rs:113`](../core/dr-sync/src/error.rs#L113), [`core/dr-sync/src/reachability.rs:1`](../core/dr-sync/src/reachability.rs#L1), [`core/dr-sync/src/scan.rs:175`](../core/dr-sync/src/scan.rs#L175), [`core/dr-sync/src/scan.rs:464`](../core/dr-sync/src/scan.rs#L464), [`core/dr-types/src/lib.rs:120`](../core/dr-types/src/lib.rs#L120), [`ui/dr-ui/src/develop.rs:3229`](../ui/dr-ui/src/develop.rs#L3229), [`ui/dr-ui/src/library.rs:1222`](../ui/dr-ui/src/library.rs#L1222), [`ui/dr-ui/src/library.rs:1275`](../ui/dr-ui/src/library.rs#L1275), [`ui/dr-ui/src/library.rs:1306`](../ui/dr-ui/src/library.rs#L1306), [`ui/dr-ui/src/library.rs:1411`](../ui/dr-ui/src/library.rs#L1411), [`ui/dr-ui/src/library.rs:161`](../ui/dr-ui/src/library.rs#L161), [`ui/dr-ui/src/library.rs:1863`](../ui/dr-ui/src/library.rs#L1863), [`ui/dr-ui/src/library.rs:1939`](../ui/dr-ui/src/library.rs#L1939), [`ui/dr-ui/src/library.rs:266`](../ui/dr-ui/src/library.rs#L266), [`ui/dr-ui/src/library.rs:4541`](../ui/dr-ui/src/library.rs#L4541), [`ui/dr-ui/src/library.rs:576`](../ui/dr-ui/src/library.rs#L576), [`ui/dr-ui/src/library.rs:807`](../ui/dr-ui/src/library.rs#L807), [`ui/dr-ui/src/library.rs:823`](../ui/dr-ui/src/library.rs#L823), [`ui/dr-ui/src/library.rs:877`](../ui/dr-ui/src/library.rs#L877), [`ui/dr-ui/src/library_ui.rs:1045`](../ui/dr-ui/src/library_ui.rs#L1045), [`ui/dr-ui/src/library_ui.rs:1636`](../ui/dr-ui/src/library_ui.rs#L1636), [`ui/dr-ui/src/library_ui.rs:1680`](../ui/dr-ui/src/library_ui.rs#L1680), [`ui/dr-ui/src/library_ui.rs:1696`](../ui/dr-ui/src/library_ui.rs#L1696), [`ui/dr-ui/src/library_ui.rs:1790`](../ui/dr-ui/src/library_ui.rs#L1790), [`ui/dr-ui/src/library_ui.rs:232`](../ui/dr-ui/src/library_ui.rs#L232), [`ui/dr-ui/src/library_ui.rs:2436`](../ui/dr-ui/src/library_ui.rs#L2436), [`ui/dr-ui/src/library_ui.rs:265`](../ui/dr-ui/src/library_ui.rs#L265), [`ui/dr-ui/src/library_ui.rs:273`](../ui/dr-ui/src/library_ui.rs#L273), [`ui/dr-ui/src/library_ui.rs:2874`](../ui/dr-ui/src/library_ui.rs#L2874), [`ui/dr-ui/src/library_ui.rs:3096`](../ui/dr-ui/src/library_ui.rs#L3096), [`ui/dr-ui/src/library_ui.rs:3374`](../ui/dr-ui/src/library_ui.rs#L3374), [`ui/dr-ui/src/library_ui.rs:3462`](../ui/dr-ui/src/library_ui.rs#L3462), [`ui/dr-ui/src/library_ui.rs:3644`](../ui/dr-ui/src/library_ui.rs#L3644), [`ui/dr-ui/src/library_ui.rs:3758`](../ui/dr-ui/src/library_ui.rs#L3758), [`ui/dr-ui/src/library_ui.rs:463`](../ui/dr-ui/src/library_ui.rs#L463), [`ui/dr-ui/src/library_ui.rs:526`](../ui/dr-ui/src/library_ui.rs#L526), [`ui/dr-ui/src/library_ui.rs:5514`](../ui/dr-ui/src/library_ui.rs#L5514), [`ui/dr-ui/src/library_ui.rs:5629`](../ui/dr-ui/src/library_ui.rs#L5629), [`ui/dr-ui/src/presets.rs:446`](../ui/dr-ui/src/presets.rs#L446), [`ui/dr-ui/src/presets.rs:458`](../ui/dr-ui/src/presets.rs#L458), [`ui/dr-ui/src/sidecar_cache.rs:1`](../ui/dr-ui/src/sidecar_cache.rs#L1) | | FR-CULL-1 | [`core/dr-decode/src/preview.rs:121`](../core/dr-decode/src/preview.rs#L121) | -| FR-CULL-10 | [`core/dr-catalog/src/faces.rs:1`](../core/dr-catalog/src/faces.rs#L1), [`core/dr-catalog/src/schema.rs:369`](../core/dr-catalog/src/schema.rs#L369), [`core/dr-catalog/src/schema.rs:521`](../core/dr-catalog/src/schema.rs#L521), [`core/dr-face/src/assign.rs:1`](../core/dr-face/src/assign.rs#L1), [`core/dr-face/src/neighbours.rs:1`](../core/dr-face/src/neighbours.rs#L1), [`core/dr-types/src/settings.rs:117`](../core/dr-types/src/settings.rs#L117), [`ui/dr-ui/src/develop.rs:120`](../ui/dr-ui/src/develop.rs#L120), [`ui/dr-ui/src/develop.rs:129`](../ui/dr-ui/src/develop.rs#L129), [`ui/dr-ui/src/develop.rs:195`](../ui/dr-ui/src/develop.rs#L195), [`ui/dr-ui/src/develop.rs:1968`](../ui/dr-ui/src/develop.rs#L1968), [`ui/dr-ui/src/develop.rs:688`](../ui/dr-ui/src/develop.rs#L688), [`ui/dr-ui/src/faces.rs:1`](../ui/dr-ui/src/faces.rs#L1), [`ui/dr-ui/src/identity.rs:1`](../ui/dr-ui/src/identity.rs#L1), [`ui/dr-ui/src/identity_ui.rs:1`](../ui/dr-ui/src/identity_ui.rs#L1), [`ui/dr-ui/src/lib.rs:2091`](../ui/dr-ui/src/lib.rs#L2091), [`ui/dr-ui/ui/identity.slint:1`](../ui/dr-ui/ui/identity.slint#L1) | +| FR-CULL-10 | [`core/dr-catalog/src/faces.rs:1`](../core/dr-catalog/src/faces.rs#L1), [`core/dr-catalog/src/schema.rs:369`](../core/dr-catalog/src/schema.rs#L369), [`core/dr-catalog/src/schema.rs:521`](../core/dr-catalog/src/schema.rs#L521), [`core/dr-face/src/assign.rs:1`](../core/dr-face/src/assign.rs#L1), [`core/dr-face/src/neighbours.rs:1`](../core/dr-face/src/neighbours.rs#L1), [`core/dr-types/src/settings.rs:117`](../core/dr-types/src/settings.rs#L117), [`ui/dr-ui/src/develop.rs:120`](../ui/dr-ui/src/develop.rs#L120), [`ui/dr-ui/src/develop.rs:129`](../ui/dr-ui/src/develop.rs#L129), [`ui/dr-ui/src/develop.rs:195`](../ui/dr-ui/src/develop.rs#L195), [`ui/dr-ui/src/develop.rs:1968`](../ui/dr-ui/src/develop.rs#L1968), [`ui/dr-ui/src/develop.rs:688`](../ui/dr-ui/src/develop.rs#L688), [`ui/dr-ui/src/faces.rs:1`](../ui/dr-ui/src/faces.rs#L1), [`ui/dr-ui/src/identity.rs:1`](../ui/dr-ui/src/identity.rs#L1), [`ui/dr-ui/src/identity_ui.rs:1`](../ui/dr-ui/src/identity_ui.rs#L1), [`ui/dr-ui/src/lib.rs:2097`](../ui/dr-ui/src/lib.rs#L2097), [`ui/dr-ui/ui/identity.slint:1`](../ui/dr-ui/ui/identity.slint#L1) | | FR-CULL-11 | [`core/dr-catalog/src/faces.rs:1`](../core/dr-catalog/src/faces.rs#L1), [`core/dr-catalog/src/schema.rs:521`](../core/dr-catalog/src/schema.rs#L521), [`ui/dr-ui/src/identity.rs:1`](../ui/dr-ui/src/identity.rs#L1), [`ui/dr-ui/src/identity_ui.rs:1`](../ui/dr-ui/src/identity_ui.rs#L1), [`ui/dr-ui/src/library.rs:287`](../ui/dr-ui/src/library.rs#L287), [`ui/dr-ui/src/library.rs:317`](../ui/dr-ui/src/library.rs#L317), [`ui/dr-ui/ui/identity.slint:1`](../ui/dr-ui/ui/identity.slint#L1) | | FR-CULL-12 | [`core/dr-catalog/src/faces.rs:1`](../core/dr-catalog/src/faces.rs#L1), [`core/dr-catalog/src/schema.rs:369`](../core/dr-catalog/src/schema.rs#L369), [`core/dr-catalog/src/schema.rs:521`](../core/dr-catalog/src/schema.rs#L521), [`ui/dr-ui/src/identity.rs:1`](../ui/dr-ui/src/identity.rs#L1), [`ui/dr-ui/ui/identity.slint:1`](../ui/dr-ui/ui/identity.slint#L1) | | FR-CULL-2 | [`core/dr-decode/src/locate.rs:1`](../core/dr-decode/src/locate.rs#L1), [`core/dr-decode/src/preview.rs:148`](../core/dr-decode/src/preview.rs#L148), [`ui/dr-ui/src/import.rs:463`](../ui/dr-ui/src/import.rs#L463) | -| FR-CULL-3 | [`core/dr-gpu/src/focus.rs:154`](../core/dr-gpu/src/focus.rs#L154), [`core/dr-gpu/src/focus.rs:186`](../core/dr-gpu/src/focus.rs#L186), [`core/dr-gpu/src/focus.rs:1`](../core/dr-gpu/src/focus.rs#L1), [`core/dr-gpu/src/focus.rs:317`](../core/dr-gpu/src/focus.rs#L317), [`core/dr-gpu/src/raw_histogram.rs:129`](../core/dr-gpu/src/raw_histogram.rs#L129), [`core/dr-gpu/src/raw_histogram.rs:1`](../core/dr-gpu/src/raw_histogram.rs#L1), [`core/dr-gpu/src/raw_histogram.rs:272`](../core/dr-gpu/src/raw_histogram.rs#L272), [`core/dr-gpu/src/raw_histogram.rs:407`](../core/dr-gpu/src/raw_histogram.rs#L407), [`core/dr-gpu/src/shaders/focus_peak.wgsl:1`](../core/dr-gpu/src/shaders/focus_peak.wgsl#L1), [`core/dr-gpu/src/shaders/raw_histogram.wgsl:1`](../core/dr-gpu/src/shaders/raw_histogram.wgsl#L1), [`ui/dr-ui/src/develop.rs:2954`](../ui/dr-ui/src/develop.rs#L2954), [`ui/dr-ui/src/develop.rs:2967`](../ui/dr-ui/src/develop.rs#L2967), [`ui/dr-ui/src/develop.rs:3012`](../ui/dr-ui/src/develop.rs#L3012), [`ui/dr-ui/src/develop.rs:3023`](../ui/dr-ui/src/develop.rs#L3023), [`ui/dr-ui/src/develop.rs:3029`](../ui/dr-ui/src/develop.rs#L3029), [`ui/dr-ui/src/develop.rs:3046`](../ui/dr-ui/src/develop.rs#L3046), [`ui/dr-ui/src/develop.rs:5929`](../ui/dr-ui/src/develop.rs#L5929), [`ui/dr-ui/src/develop.rs:5993`](../ui/dr-ui/src/develop.rs#L5993), [`ui/dr-ui/src/develop.rs:6016`](../ui/dr-ui/src/develop.rs#L6016), [`ui/dr-ui/src/develop.rs:726`](../ui/dr-ui/src/develop.rs#L726), [`ui/dr-ui/src/develop.rs:746`](../ui/dr-ui/src/develop.rs#L746), [`ui/dr-ui/src/develop.rs:752`](../ui/dr-ui/src/develop.rs#L752), [`ui/dr-ui/src/histogram.rs:1`](../ui/dr-ui/src/histogram.rs#L1), [`ui/dr-ui/src/histogram.rs:208`](../ui/dr-ui/src/histogram.rs#L208), [`ui/dr-ui/src/histogram.rs:228`](../ui/dr-ui/src/histogram.rs#L228), [`ui/dr-ui/src/histogram.rs:272`](../ui/dr-ui/src/histogram.rs#L272), [`ui/dr-ui/src/histogram.rs:541`](../ui/dr-ui/src/histogram.rs#L541), [`ui/dr-ui/src/histogram.rs:562`](../ui/dr-ui/src/histogram.rs#L562), [`ui/dr-ui/src/histogram.rs:590`](../ui/dr-ui/src/histogram.rs#L590), [`ui/dr-ui/src/histogram.rs:618`](../ui/dr-ui/src/histogram.rs#L618), [`ui/dr-ui/src/histogram.rs:655`](../ui/dr-ui/src/histogram.rs#L655), [`ui/dr-ui/src/lib.rs:1533`](../ui/dr-ui/src/lib.rs#L1533), [`ui/dr-ui/src/lib.rs:1611`](../ui/dr-ui/src/lib.rs#L1611), [`ui/dr-ui/src/lib.rs:1710`](../ui/dr-ui/src/lib.rs#L1710), [`ui/dr-ui/src/lib.rs:1751`](../ui/dr-ui/src/lib.rs#L1751), [`ui/dr-ui/src/lib.rs:3001`](../ui/dr-ui/src/lib.rs#L3001), [`ui/dr-ui/src/lib.rs:333`](../ui/dr-ui/src/lib.rs#L333), [`ui/dr-ui/src/peaking.rs:1`](../ui/dr-ui/src/peaking.rs#L1), [`ui/dr-ui/ui/app.slint:1743`](../ui/dr-ui/ui/app.slint#L1743), [`ui/dr-ui/ui/app.slint:2289`](../ui/dr-ui/ui/app.slint#L2289), [`ui/dr-ui/ui/app.slint:87`](../ui/dr-ui/ui/app.slint#L87), [`ui/dr-ui/ui/peaking.slint:1`](../ui/dr-ui/ui/peaking.slint#L1), [`ui/dr-ui/ui/peaking.slint:25`](../ui/dr-ui/ui/peaking.slint#L25), [`ui/dr-ui/ui/peaking.slint:56`](../ui/dr-ui/ui/peaking.slint#L56) | +| FR-CULL-3 | [`core/dr-gpu/src/focus.rs:154`](../core/dr-gpu/src/focus.rs#L154), [`core/dr-gpu/src/focus.rs:186`](../core/dr-gpu/src/focus.rs#L186), [`core/dr-gpu/src/focus.rs:1`](../core/dr-gpu/src/focus.rs#L1), [`core/dr-gpu/src/focus.rs:317`](../core/dr-gpu/src/focus.rs#L317), [`core/dr-gpu/src/raw_histogram.rs:129`](../core/dr-gpu/src/raw_histogram.rs#L129), [`core/dr-gpu/src/raw_histogram.rs:1`](../core/dr-gpu/src/raw_histogram.rs#L1), [`core/dr-gpu/src/raw_histogram.rs:272`](../core/dr-gpu/src/raw_histogram.rs#L272), [`core/dr-gpu/src/raw_histogram.rs:407`](../core/dr-gpu/src/raw_histogram.rs#L407), [`core/dr-gpu/src/shaders/focus_peak.wgsl:1`](../core/dr-gpu/src/shaders/focus_peak.wgsl#L1), [`core/dr-gpu/src/shaders/raw_histogram.wgsl:1`](../core/dr-gpu/src/shaders/raw_histogram.wgsl#L1), [`ui/dr-ui/src/develop.rs:2954`](../ui/dr-ui/src/develop.rs#L2954), [`ui/dr-ui/src/develop.rs:2967`](../ui/dr-ui/src/develop.rs#L2967), [`ui/dr-ui/src/develop.rs:3012`](../ui/dr-ui/src/develop.rs#L3012), [`ui/dr-ui/src/develop.rs:3023`](../ui/dr-ui/src/develop.rs#L3023), [`ui/dr-ui/src/develop.rs:3029`](../ui/dr-ui/src/develop.rs#L3029), [`ui/dr-ui/src/develop.rs:3046`](../ui/dr-ui/src/develop.rs#L3046), [`ui/dr-ui/src/develop.rs:5929`](../ui/dr-ui/src/develop.rs#L5929), [`ui/dr-ui/src/develop.rs:5993`](../ui/dr-ui/src/develop.rs#L5993), [`ui/dr-ui/src/develop.rs:6016`](../ui/dr-ui/src/develop.rs#L6016), [`ui/dr-ui/src/develop.rs:726`](../ui/dr-ui/src/develop.rs#L726), [`ui/dr-ui/src/develop.rs:746`](../ui/dr-ui/src/develop.rs#L746), [`ui/dr-ui/src/develop.rs:752`](../ui/dr-ui/src/develop.rs#L752), [`ui/dr-ui/src/histogram.rs:1`](../ui/dr-ui/src/histogram.rs#L1), [`ui/dr-ui/src/histogram.rs:208`](../ui/dr-ui/src/histogram.rs#L208), [`ui/dr-ui/src/histogram.rs:228`](../ui/dr-ui/src/histogram.rs#L228), [`ui/dr-ui/src/histogram.rs:272`](../ui/dr-ui/src/histogram.rs#L272), [`ui/dr-ui/src/histogram.rs:541`](../ui/dr-ui/src/histogram.rs#L541), [`ui/dr-ui/src/histogram.rs:562`](../ui/dr-ui/src/histogram.rs#L562), [`ui/dr-ui/src/histogram.rs:590`](../ui/dr-ui/src/histogram.rs#L590), [`ui/dr-ui/src/histogram.rs:618`](../ui/dr-ui/src/histogram.rs#L618), [`ui/dr-ui/src/histogram.rs:655`](../ui/dr-ui/src/histogram.rs#L655), [`ui/dr-ui/src/lib.rs:1539`](../ui/dr-ui/src/lib.rs#L1539), [`ui/dr-ui/src/lib.rs:1617`](../ui/dr-ui/src/lib.rs#L1617), [`ui/dr-ui/src/lib.rs:1716`](../ui/dr-ui/src/lib.rs#L1716), [`ui/dr-ui/src/lib.rs:1757`](../ui/dr-ui/src/lib.rs#L1757), [`ui/dr-ui/src/lib.rs:3007`](../ui/dr-ui/src/lib.rs#L3007), [`ui/dr-ui/src/lib.rs:339`](../ui/dr-ui/src/lib.rs#L339), [`ui/dr-ui/src/peaking.rs:1`](../ui/dr-ui/src/peaking.rs#L1), [`ui/dr-ui/ui/app.slint:1769`](../ui/dr-ui/ui/app.slint#L1769), [`ui/dr-ui/ui/app.slint:2347`](../ui/dr-ui/ui/app.slint#L2347), [`ui/dr-ui/ui/app.slint:88`](../ui/dr-ui/ui/app.slint#L88), [`ui/dr-ui/ui/peaking.slint:1`](../ui/dr-ui/ui/peaking.slint#L1), [`ui/dr-ui/ui/peaking.slint:25`](../ui/dr-ui/ui/peaking.slint#L25), [`ui/dr-ui/ui/peaking.slint:56`](../ui/dr-ui/ui/peaking.slint#L56) | | FR-CULL-4 | [`core/dr-catalog/src/rating.rs:1`](../core/dr-catalog/src/rating.rs#L1), [`core/dr-pipeline/src/sidecar.rs:136`](../core/dr-pipeline/src/sidecar.rs#L136), [`ui/dr-ui/src/library.rs:246`](../ui/dr-ui/src/library.rs#L246), [`ui/dr-ui/src/library.rs:492`](../ui/dr-ui/src/library.rs#L492) | | FR-CULL-5 | [`core/dr-catalog/src/bursts.rs:1`](../core/dr-catalog/src/bursts.rs#L1), [`core/dr-catalog/src/schema.rs:412`](../core/dr-catalog/src/schema.rs#L412), [`ui/dr-ui/src/bursts.rs:1`](../ui/dr-ui/src/bursts.rs#L1), [`ui/dr-ui/src/library.rs:202`](../ui/dr-ui/src/library.rs#L202), [`ui/dr-ui/src/library.rs:5142`](../ui/dr-ui/src/library.rs#L5142) | | FR-CULL-8 | [`core/dr-catalog/src/face_shard.rs:1`](../core/dr-catalog/src/face_shard.rs#L1), [`core/dr-catalog/src/faces.rs:1`](../core/dr-catalog/src/faces.rs#L1), [`core/dr-catalog/src/schema.rs:480`](../core/dr-catalog/src/schema.rs#L480), [`core/dr-catalog/src/schema.rs:521`](../core/dr-catalog/src/schema.rs#L521), [`ui/dr-ui/src/faces.rs:1`](../ui/dr-ui/src/faces.rs#L1), [`ui/dr-ui/src/library.rs:2965`](../ui/dr-ui/src/library.rs#L2965), [`ui/dr-ui/src/library.rs:3069`](../ui/dr-ui/src/library.rs#L3069), [`ui/dr-ui/ui/settings.slint:419`](../ui/dr-ui/ui/settings.slint#L419), [`ui/dr-ui/ui/settings.slint:82`](../ui/dr-ui/ui/settings.slint#L82) | | FR-CULL-9 | [`core/dr-catalog/src/faces.rs:1`](../core/dr-catalog/src/faces.rs#L1), [`core/dr-catalog/src/schema.rs:521`](../core/dr-catalog/src/schema.rs#L521), [`core/dr-face/src/assign.rs:1`](../core/dr-face/src/assign.rs#L1), [`core/dr-face/src/neighbours.rs:1`](../core/dr-face/src/neighbours.rs#L1), [`core/dr-types/src/settings.rs:117`](../core/dr-types/src/settings.rs#L117), [`ui/dr-ui/src/faces.rs:1`](../ui/dr-ui/src/faces.rs#L1), [`ui/dr-ui/src/identity_ui.rs:1`](../ui/dr-ui/src/identity_ui.rs#L1), [`ui/dr-ui/ui/identity.slint:276`](../ui/dr-ui/ui/identity.slint#L276) | | FR-DEV-1 | [`core/dr-pipeline/src/graph.rs:1`](../core/dr-pipeline/src/graph.rs#L1), [`core/dr-pipeline/src/sidecar.rs:1`](../core/dr-pipeline/src/sidecar.rs#L1) | | FR-DEV-2 | [`core/dr-pipeline/src/operation.rs:389`](../core/dr-pipeline/src/operation.rs#L389) | -| FR-DEV-3 | [`core/dr-gpu/src/adjust.rs:2203`](../core/dr-gpu/src/adjust.rs#L2203), [`core/dr-gpu/src/adjust.rs:651`](../core/dr-gpu/src/adjust.rs#L651), [`core/dr-gpu/src/adjust.rs:770`](../core/dr-gpu/src/adjust.rs#L770), [`core/dr-gpu/src/adjust.rs:84`](../core/dr-gpu/src/adjust.rs#L84), [`core/dr-gpu/tests/tone_curve.rs:1`](../core/dr-gpu/tests/tone_curve.rs#L1), [`core/dr-pipeline/src/detail.rs:434`](../core/dr-pipeline/src/detail.rs#L434), [`core/dr-pipeline/src/detail.rs:524`](../core/dr-pipeline/src/detail.rs#L524), [`core/dr-pipeline/src/framing.rs:177`](../core/dr-pipeline/src/framing.rs#L177), [`core/dr-pipeline/src/framing.rs:234`](../core/dr-pipeline/src/framing.rs#L234), [`core/dr-pipeline/src/framing.rs:314`](../core/dr-pipeline/src/framing.rs#L314), [`core/dr-pipeline/src/framing.rs:488`](../core/dr-pipeline/src/framing.rs#L488), [`core/dr-pipeline/src/framing.rs:743`](../core/dr-pipeline/src/framing.rs#L743), [`core/dr-pipeline/src/graph.rs:170`](../core/dr-pipeline/src/graph.rs#L170), [`core/dr-pipeline/src/graph.rs:578`](../core/dr-pipeline/src/graph.rs#L578), [`core/dr-pipeline/src/mask.rs:121`](../core/dr-pipeline/src/mask.rs#L121), [`core/dr-pipeline/src/operation.rs:330`](../core/dr-pipeline/src/operation.rs#L330), [`core/dr-pipeline/src/operation.rs:516`](../core/dr-pipeline/src/operation.rs#L516), [`core/dr-pipeline/src/ops/capture_sharpen.rs:1`](../core/dr-pipeline/src/ops/capture_sharpen.rs#L1), [`core/dr-pipeline/src/ops/capture_sharpen.rs:210`](../core/dr-pipeline/src/ops/capture_sharpen.rs#L210), [`core/dr-pipeline/src/ops/curve.rs:100`](../core/dr-pipeline/src/ops/curve.rs#L100), [`core/dr-pipeline/src/ops/curve.rs:1`](../core/dr-pipeline/src/ops/curve.rs#L1), [`core/dr-pipeline/src/ops/curve.rs:219`](../core/dr-pipeline/src/ops/curve.rs#L219), [`core/dr-pipeline/src/ops/curve.rs:635`](../core/dr-pipeline/src/ops/curve.rs#L635), [`core/dr-pipeline/src/ops/local_contrast.rs:1`](../core/dr-pipeline/src/ops/local_contrast.rs#L1), [`core/dr-pipeline/src/ops/noise_reduction.rs:1`](../core/dr-pipeline/src/ops/noise_reduction.rs#L1), [`core/dr-pipeline/src/ops/noise_reduction.rs:273`](../core/dr-pipeline/src/ops/noise_reduction.rs#L273), [`core/dr-pipeline/src/sidecar.rs:157`](../core/dr-pipeline/src/sidecar.rs#L157), [`core/dr-pipeline/src/sidecar.rs:1637`](../core/dr-pipeline/src/sidecar.rs#L1637), [`core/dr-pipeline/src/sidecar.rs:1697`](../core/dr-pipeline/src/sidecar.rs#L1697), [`core/dr-pipeline/tests/tone_curve.rs:1`](../core/dr-pipeline/tests/tone_curve.rs#L1), [`ui/dr-ui/src/develop.rs:102`](../ui/dr-ui/src/develop.rs#L102), [`ui/dr-ui/src/develop.rs:1472`](../ui/dr-ui/src/develop.rs#L1472), [`ui/dr-ui/src/develop.rs:164`](../ui/dr-ui/src/develop.rs#L164), [`ui/dr-ui/src/develop.rs:1950`](../ui/dr-ui/src/develop.rs#L1950), [`ui/dr-ui/src/develop.rs:1968`](../ui/dr-ui/src/develop.rs#L1968), [`ui/dr-ui/src/develop.rs:1982`](../ui/dr-ui/src/develop.rs#L1982), [`ui/dr-ui/src/develop.rs:2004`](../ui/dr-ui/src/develop.rs#L2004), [`ui/dr-ui/src/develop.rs:2150`](../ui/dr-ui/src/develop.rs#L2150), [`ui/dr-ui/src/develop.rs:2248`](../ui/dr-ui/src/develop.rs#L2248), [`ui/dr-ui/src/develop.rs:327`](../ui/dr-ui/src/develop.rs#L327), [`ui/dr-ui/src/develop.rs:3500`](../ui/dr-ui/src/develop.rs#L3500), [`ui/dr-ui/src/develop.rs:3530`](../ui/dr-ui/src/develop.rs#L3530), [`ui/dr-ui/src/develop.rs:3596`](../ui/dr-ui/src/develop.rs#L3596), [`ui/dr-ui/src/develop.rs:3610`](../ui/dr-ui/src/develop.rs#L3610), [`ui/dr-ui/src/develop.rs:364`](../ui/dr-ui/src/develop.rs#L364), [`ui/dr-ui/src/develop.rs:3802`](../ui/dr-ui/src/develop.rs#L3802), [`ui/dr-ui/src/develop.rs:4462`](../ui/dr-ui/src/develop.rs#L4462), [`ui/dr-ui/src/develop.rs:4516`](../ui/dr-ui/src/develop.rs#L4516), [`ui/dr-ui/src/develop.rs:4560`](../ui/dr-ui/src/develop.rs#L4560), [`ui/dr-ui/src/develop.rs:4610`](../ui/dr-ui/src/develop.rs#L4610), [`ui/dr-ui/src/develop.rs:587`](../ui/dr-ui/src/develop.rs#L587), [`ui/dr-ui/src/develop.rs:648`](../ui/dr-ui/src/develop.rs#L648), [`ui/dr-ui/src/develop.rs:766`](../ui/dr-ui/src/develop.rs#L766), [`ui/dr-ui/src/develop.rs:813`](../ui/dr-ui/src/develop.rs#L813), [`ui/dr-ui/src/develop.rs:842`](../ui/dr-ui/src/develop.rs#L842), [`ui/dr-ui/src/lib.rs:1592`](../ui/dr-ui/src/lib.rs#L1592), [`ui/dr-ui/src/lib.rs:2394`](../ui/dr-ui/src/lib.rs#L2394), [`ui/dr-ui/src/lib.rs:2590`](../ui/dr-ui/src/lib.rs#L2590), [`ui/dr-ui/src/lib.rs:2762`](../ui/dr-ui/src/lib.rs#L2762), [`ui/dr-ui/src/lib.rs:2826`](../ui/dr-ui/src/lib.rs#L2826), [`ui/dr-ui/src/lib.rs:2880`](../ui/dr-ui/src/lib.rs#L2880), [`ui/dr-ui/src/lib.rs:339`](../ui/dr-ui/src/lib.rs#L339), [`ui/dr-ui/src/lib.rs:382`](../ui/dr-ui/src/lib.rs#L382), [`ui/dr-ui/src/lib.rs:405`](../ui/dr-ui/src/lib.rs#L405), [`ui/dr-ui/src/library.rs:539`](../ui/dr-ui/src/library.rs#L539), [`ui/dr-ui/src/masks_ui.rs:218`](../ui/dr-ui/src/masks_ui.rs#L218), [`ui/dr-ui/src/masks_ui.rs:41`](../ui/dr-ui/src/masks_ui.rs#L41), [`ui/dr-ui/src/masks_ui.rs:816`](../ui/dr-ui/src/masks_ui.rs#L816), [`ui/dr-ui/src/masks_ui.rs:930`](../ui/dr-ui/src/masks_ui.rs#L930), [`ui/dr-ui/src/segmentation.rs:219`](../ui/dr-ui/src/segmentation.rs#L219), [`ui/dr-ui/src/segmentation.rs:322`](../ui/dr-ui/src/segmentation.rs#L322), [`ui/dr-ui/src/segmentation.rs:350`](../ui/dr-ui/src/segmentation.rs#L350), [`ui/dr-ui/ui/adjust.slint:517`](../ui/dr-ui/ui/adjust.slint#L517), [`ui/dr-ui/ui/adjust.slint:635`](../ui/dr-ui/ui/adjust.slint#L635), [`ui/dr-ui/ui/app.slint:148`](../ui/dr-ui/ui/app.slint#L148), [`ui/dr-ui/ui/app.slint:1945`](../ui/dr-ui/ui/app.slint#L1945), [`ui/dr-ui/ui/app.slint:194`](../ui/dr-ui/ui/app.slint#L194), [`ui/dr-ui/ui/app.slint:927`](../ui/dr-ui/ui/app.slint#L927), [`ui/dr-ui/ui/masks.slint:524`](../ui/dr-ui/ui/masks.slint#L524) | -| FR-DEV-3a | [`core/dr-pipeline/build.rs:756`](../core/dr-pipeline/build.rs#L756), [`core/dr-pipeline/ops/exposure.yaml:1`](../core/dr-pipeline/ops/exposure.yaml#L1), [`core/dr-pipeline/src/descriptor.rs:194`](../core/dr-pipeline/src/descriptor.rs#L194), [`core/dr-pipeline/src/descriptor.rs:234`](../core/dr-pipeline/src/descriptor.rs#L234), [`core/dr-pipeline/src/descriptor.rs:258`](../core/dr-pipeline/src/descriptor.rs#L258), [`core/dr-pipeline/src/descriptor.rs:313`](../core/dr-pipeline/src/descriptor.rs#L313), [`core/dr-pipeline/src/framing.rs:385`](../core/dr-pipeline/src/framing.rs#L385), [`core/dr-pipeline/src/graph.rs:24`](../core/dr-pipeline/src/graph.rs#L24), [`core/dr-pipeline/src/graph.rs:251`](../core/dr-pipeline/src/graph.rs#L251), [`core/dr-pipeline/src/graph.rs:46`](../core/dr-pipeline/src/graph.rs#L46), [`core/dr-pipeline/src/graph.rs:59`](../core/dr-pipeline/src/graph.rs#L59), [`core/dr-pipeline/src/mask.rs:955`](../core/dr-pipeline/src/mask.rs#L955), [`core/dr-pipeline/src/operation.rs:232`](../core/dr-pipeline/src/operation.rs#L232), [`core/dr-pipeline/src/operation.rs:365`](../core/dr-pipeline/src/operation.rs#L365), [`core/dr-pipeline/src/ops/curve.rs:319`](../core/dr-pipeline/src/ops/curve.rs#L319), [`ui/dr-ui/src/develop.rs:1369`](../ui/dr-ui/src/develop.rs#L1369), [`ui/dr-ui/src/lib.rs:688`](../ui/dr-ui/src/lib.rs#L688), [`ui/dr-ui/tests/ui_names_no_operation.rs:1`](../ui/dr-ui/tests/ui_names_no_operation.rs#L1) | +| FR-DEV-3 | [`core/dr-gpu/src/adjust.rs:2203`](../core/dr-gpu/src/adjust.rs#L2203), [`core/dr-gpu/src/adjust.rs:651`](../core/dr-gpu/src/adjust.rs#L651), [`core/dr-gpu/src/adjust.rs:770`](../core/dr-gpu/src/adjust.rs#L770), [`core/dr-gpu/src/adjust.rs:84`](../core/dr-gpu/src/adjust.rs#L84), [`core/dr-gpu/tests/tone_curve.rs:1`](../core/dr-gpu/tests/tone_curve.rs#L1), [`core/dr-pipeline/src/detail.rs:434`](../core/dr-pipeline/src/detail.rs#L434), [`core/dr-pipeline/src/detail.rs:524`](../core/dr-pipeline/src/detail.rs#L524), [`core/dr-pipeline/src/framing.rs:177`](../core/dr-pipeline/src/framing.rs#L177), [`core/dr-pipeline/src/framing.rs:234`](../core/dr-pipeline/src/framing.rs#L234), [`core/dr-pipeline/src/framing.rs:314`](../core/dr-pipeline/src/framing.rs#L314), [`core/dr-pipeline/src/framing.rs:488`](../core/dr-pipeline/src/framing.rs#L488), [`core/dr-pipeline/src/framing.rs:743`](../core/dr-pipeline/src/framing.rs#L743), [`core/dr-pipeline/src/graph.rs:170`](../core/dr-pipeline/src/graph.rs#L170), [`core/dr-pipeline/src/graph.rs:578`](../core/dr-pipeline/src/graph.rs#L578), [`core/dr-pipeline/src/mask.rs:121`](../core/dr-pipeline/src/mask.rs#L121), [`core/dr-pipeline/src/operation.rs:330`](../core/dr-pipeline/src/operation.rs#L330), [`core/dr-pipeline/src/operation.rs:516`](../core/dr-pipeline/src/operation.rs#L516), [`core/dr-pipeline/src/ops/capture_sharpen.rs:1`](../core/dr-pipeline/src/ops/capture_sharpen.rs#L1), [`core/dr-pipeline/src/ops/capture_sharpen.rs:210`](../core/dr-pipeline/src/ops/capture_sharpen.rs#L210), [`core/dr-pipeline/src/ops/curve.rs:100`](../core/dr-pipeline/src/ops/curve.rs#L100), [`core/dr-pipeline/src/ops/curve.rs:1`](../core/dr-pipeline/src/ops/curve.rs#L1), [`core/dr-pipeline/src/ops/curve.rs:219`](../core/dr-pipeline/src/ops/curve.rs#L219), [`core/dr-pipeline/src/ops/curve.rs:635`](../core/dr-pipeline/src/ops/curve.rs#L635), [`core/dr-pipeline/src/ops/local_contrast.rs:1`](../core/dr-pipeline/src/ops/local_contrast.rs#L1), [`core/dr-pipeline/src/ops/noise_reduction.rs:1`](../core/dr-pipeline/src/ops/noise_reduction.rs#L1), [`core/dr-pipeline/src/ops/noise_reduction.rs:273`](../core/dr-pipeline/src/ops/noise_reduction.rs#L273), [`core/dr-pipeline/src/sidecar.rs:157`](../core/dr-pipeline/src/sidecar.rs#L157), [`core/dr-pipeline/src/sidecar.rs:1637`](../core/dr-pipeline/src/sidecar.rs#L1637), [`core/dr-pipeline/src/sidecar.rs:1697`](../core/dr-pipeline/src/sidecar.rs#L1697), [`core/dr-pipeline/tests/tone_curve.rs:1`](../core/dr-pipeline/tests/tone_curve.rs#L1), [`ui/dr-ui/src/develop.rs:102`](../ui/dr-ui/src/develop.rs#L102), [`ui/dr-ui/src/develop.rs:1472`](../ui/dr-ui/src/develop.rs#L1472), [`ui/dr-ui/src/develop.rs:164`](../ui/dr-ui/src/develop.rs#L164), [`ui/dr-ui/src/develop.rs:1950`](../ui/dr-ui/src/develop.rs#L1950), [`ui/dr-ui/src/develop.rs:1968`](../ui/dr-ui/src/develop.rs#L1968), [`ui/dr-ui/src/develop.rs:1982`](../ui/dr-ui/src/develop.rs#L1982), [`ui/dr-ui/src/develop.rs:2004`](../ui/dr-ui/src/develop.rs#L2004), [`ui/dr-ui/src/develop.rs:2150`](../ui/dr-ui/src/develop.rs#L2150), [`ui/dr-ui/src/develop.rs:2248`](../ui/dr-ui/src/develop.rs#L2248), [`ui/dr-ui/src/develop.rs:327`](../ui/dr-ui/src/develop.rs#L327), [`ui/dr-ui/src/develop.rs:3500`](../ui/dr-ui/src/develop.rs#L3500), [`ui/dr-ui/src/develop.rs:3530`](../ui/dr-ui/src/develop.rs#L3530), [`ui/dr-ui/src/develop.rs:3596`](../ui/dr-ui/src/develop.rs#L3596), [`ui/dr-ui/src/develop.rs:3610`](../ui/dr-ui/src/develop.rs#L3610), [`ui/dr-ui/src/develop.rs:364`](../ui/dr-ui/src/develop.rs#L364), [`ui/dr-ui/src/develop.rs:3802`](../ui/dr-ui/src/develop.rs#L3802), [`ui/dr-ui/src/develop.rs:4462`](../ui/dr-ui/src/develop.rs#L4462), [`ui/dr-ui/src/develop.rs:4516`](../ui/dr-ui/src/develop.rs#L4516), [`ui/dr-ui/src/develop.rs:4560`](../ui/dr-ui/src/develop.rs#L4560), [`ui/dr-ui/src/develop.rs:4610`](../ui/dr-ui/src/develop.rs#L4610), [`ui/dr-ui/src/develop.rs:587`](../ui/dr-ui/src/develop.rs#L587), [`ui/dr-ui/src/develop.rs:648`](../ui/dr-ui/src/develop.rs#L648), [`ui/dr-ui/src/develop.rs:766`](../ui/dr-ui/src/develop.rs#L766), [`ui/dr-ui/src/develop.rs:813`](../ui/dr-ui/src/develop.rs#L813), [`ui/dr-ui/src/develop.rs:842`](../ui/dr-ui/src/develop.rs#L842), [`ui/dr-ui/src/lib.rs:1598`](../ui/dr-ui/src/lib.rs#L1598), [`ui/dr-ui/src/lib.rs:2400`](../ui/dr-ui/src/lib.rs#L2400), [`ui/dr-ui/src/lib.rs:2596`](../ui/dr-ui/src/lib.rs#L2596), [`ui/dr-ui/src/lib.rs:2768`](../ui/dr-ui/src/lib.rs#L2768), [`ui/dr-ui/src/lib.rs:2832`](../ui/dr-ui/src/lib.rs#L2832), [`ui/dr-ui/src/lib.rs:2886`](../ui/dr-ui/src/lib.rs#L2886), [`ui/dr-ui/src/lib.rs:345`](../ui/dr-ui/src/lib.rs#L345), [`ui/dr-ui/src/lib.rs:388`](../ui/dr-ui/src/lib.rs#L388), [`ui/dr-ui/src/lib.rs:411`](../ui/dr-ui/src/lib.rs#L411), [`ui/dr-ui/src/library.rs:539`](../ui/dr-ui/src/library.rs#L539), [`ui/dr-ui/src/masks_ui.rs:218`](../ui/dr-ui/src/masks_ui.rs#L218), [`ui/dr-ui/src/masks_ui.rs:41`](../ui/dr-ui/src/masks_ui.rs#L41), [`ui/dr-ui/src/masks_ui.rs:816`](../ui/dr-ui/src/masks_ui.rs#L816), [`ui/dr-ui/src/masks_ui.rs:930`](../ui/dr-ui/src/masks_ui.rs#L930), [`ui/dr-ui/src/segmentation.rs:219`](../ui/dr-ui/src/segmentation.rs#L219), [`ui/dr-ui/src/segmentation.rs:322`](../ui/dr-ui/src/segmentation.rs#L322), [`ui/dr-ui/src/segmentation.rs:350`](../ui/dr-ui/src/segmentation.rs#L350), [`ui/dr-ui/ui/adjust.slint:517`](../ui/dr-ui/ui/adjust.slint#L517), [`ui/dr-ui/ui/adjust.slint:620`](../ui/dr-ui/ui/adjust.slint#L620), [`ui/dr-ui/ui/app.slint:149`](../ui/dr-ui/ui/app.slint#L149), [`ui/dr-ui/ui/app.slint:195`](../ui/dr-ui/ui/app.slint#L195), [`ui/dr-ui/ui/app.slint:1971`](../ui/dr-ui/ui/app.slint#L1971), [`ui/dr-ui/ui/app.slint:928`](../ui/dr-ui/ui/app.slint#L928), [`ui/dr-ui/ui/masks.slint:516`](../ui/dr-ui/ui/masks.slint#L516) | +| FR-DEV-3a | [`core/dr-pipeline/build.rs:756`](../core/dr-pipeline/build.rs#L756), [`core/dr-pipeline/ops/exposure.yaml:1`](../core/dr-pipeline/ops/exposure.yaml#L1), [`core/dr-pipeline/src/descriptor.rs:194`](../core/dr-pipeline/src/descriptor.rs#L194), [`core/dr-pipeline/src/descriptor.rs:234`](../core/dr-pipeline/src/descriptor.rs#L234), [`core/dr-pipeline/src/descriptor.rs:258`](../core/dr-pipeline/src/descriptor.rs#L258), [`core/dr-pipeline/src/descriptor.rs:313`](../core/dr-pipeline/src/descriptor.rs#L313), [`core/dr-pipeline/src/framing.rs:385`](../core/dr-pipeline/src/framing.rs#L385), [`core/dr-pipeline/src/graph.rs:24`](../core/dr-pipeline/src/graph.rs#L24), [`core/dr-pipeline/src/graph.rs:251`](../core/dr-pipeline/src/graph.rs#L251), [`core/dr-pipeline/src/graph.rs:46`](../core/dr-pipeline/src/graph.rs#L46), [`core/dr-pipeline/src/graph.rs:59`](../core/dr-pipeline/src/graph.rs#L59), [`core/dr-pipeline/src/mask.rs:955`](../core/dr-pipeline/src/mask.rs#L955), [`core/dr-pipeline/src/operation.rs:232`](../core/dr-pipeline/src/operation.rs#L232), [`core/dr-pipeline/src/operation.rs:365`](../core/dr-pipeline/src/operation.rs#L365), [`core/dr-pipeline/src/ops/curve.rs:319`](../core/dr-pipeline/src/ops/curve.rs#L319), [`ui/dr-ui/src/develop.rs:1369`](../ui/dr-ui/src/develop.rs#L1369), [`ui/dr-ui/src/lib.rs:694`](../ui/dr-ui/src/lib.rs#L694), [`ui/dr-ui/tests/ui_names_no_operation.rs:1`](../ui/dr-ui/tests/ui_names_no_operation.rs#L1) | | FR-DEV-3b | [`core/dr-pipeline/src/descriptor.rs:258`](../core/dr-pipeline/src/descriptor.rs#L258), [`core/dr-pipeline/src/framing.rs:385`](../core/dr-pipeline/src/framing.rs#L385), [`core/dr-pipeline/src/graph.rs:59`](../core/dr-pipeline/src/graph.rs#L59), [`core/dr-pipeline/src/operation.rs:365`](../core/dr-pipeline/src/operation.rs#L365) | | FR-DEV-3c | [`core/dr-pipeline/build.rs:756`](../core/dr-pipeline/build.rs#L756), [`core/dr-pipeline/ops/exposure.yaml:1`](../core/dr-pipeline/ops/exposure.yaml#L1), [`core/dr-pipeline/src/graph.rs:251`](../core/dr-pipeline/src/graph.rs#L251), [`core/dr-pipeline/src/graph.rs:46`](../core/dr-pipeline/src/graph.rs#L46), [`core/dr-pipeline/src/mask.rs:955`](../core/dr-pipeline/src/mask.rs#L955), [`ui/dr-ui/src/develop.rs:5189`](../ui/dr-ui/src/develop.rs#L5189) | | FR-DEV-3d | [`core/dr-gpu/src/adjust.rs:104`](../core/dr-gpu/src/adjust.rs#L104), [`core/dr-gpu/src/adjust.rs:1079`](../core/dr-gpu/src/adjust.rs#L1079), [`core/dr-gpu/src/adjust.rs:770`](../core/dr-gpu/src/adjust.rs#L770), [`core/dr-gpu/src/adjust.rs:84`](../core/dr-gpu/src/adjust.rs#L84), [`core/dr-gpu/src/adjust.rs:986`](../core/dr-gpu/src/adjust.rs#L986), [`core/dr-gpu/tests/capture_sharpen.rs:434`](../core/dr-gpu/tests/capture_sharpen.rs#L434), [`core/dr-gpu/tests/detail_stage.rs:242`](../core/dr-gpu/tests/detail_stage.rs#L242), [`core/dr-gpu/tests/local_contrast.rs:558`](../core/dr-gpu/tests/local_contrast.rs#L558), [`core/dr-gpu/tests/noise_reduction.rs:556`](../core/dr-gpu/tests/noise_reduction.rs#L556), [`core/dr-pipeline/src/framing.rs:314`](../core/dr-pipeline/src/framing.rs#L314), [`core/dr-pipeline/src/graph.rs:617`](../core/dr-pipeline/src/graph.rs#L617), [`core/dr-pipeline/src/operation.rs:32`](../core/dr-pipeline/src/operation.rs#L32), [`core/dr-pipeline/src/operation.rs:389`](../core/dr-pipeline/src/operation.rs#L389), [`core/dr-pipeline/src/operation.rs:53`](../core/dr-pipeline/src/operation.rs#L53), [`core/dr-pipeline/src/operation.rs:71`](../core/dr-pipeline/src/operation.rs#L71) | | FR-DEV-3e | [`core/dr-decode/src/base_curve.rs:145`](../core/dr-decode/src/base_curve.rs#L145), [`core/dr-decode/src/base_curve.rs:158`](../core/dr-decode/src/base_curve.rs#L158), [`core/dr-decode/src/base_curve.rs:1`](../core/dr-decode/src/base_curve.rs#L1), [`core/dr-decode/src/base_curve.rs:267`](../core/dr-decode/src/base_curve.rs#L267), [`core/dr-decode/src/base_curve.rs:347`](../core/dr-decode/src/base_curve.rs#L347), [`core/dr-decode/src/base_curve.rs:55`](../core/dr-decode/src/base_curve.rs#L55), [`core/dr-decode/src/lib.rs:121`](../core/dr-decode/src/lib.rs#L121), [`core/dr-decode/src/lib.rs:708`](../core/dr-decode/src/lib.rs#L708), [`core/dr-decode/src/lib.rs:748`](../core/dr-decode/src/lib.rs#L748), [`core/dr-decode/src/profile.rs:102`](../core/dr-decode/src/profile.rs#L102), [`core/dr-decode/src/profile.rs:151`](../core/dr-decode/src/profile.rs#L151), [`core/dr-decode/src/profile.rs:1`](../core/dr-decode/src/profile.rs#L1), [`core/dr-decode/src/profile.rs:235`](../core/dr-decode/src/profile.rs#L235), [`core/dr-decode/src/profile.rs:286`](../core/dr-decode/src/profile.rs#L286), [`core/dr-decode/src/profile.rs:343`](../core/dr-decode/src/profile.rs#L343), [`core/dr-decode/src/profile.rs:458`](../core/dr-decode/src/profile.rs#L458), [`core/dr-decode/src/profile.rs:492`](../core/dr-decode/src/profile.rs#L492), [`core/dr-decode/src/profile.rs:630`](../core/dr-decode/src/profile.rs#L630), [`core/dr-gpu/src/adjust.rs:37`](../core/dr-gpu/src/adjust.rs#L37), [`core/dr-gpu/src/adjust.rs:967`](../core/dr-gpu/src/adjust.rs#L967), [`core/dr-gpu/src/demosaic.rs:121`](../core/dr-gpu/src/demosaic.rs#L121), [`core/dr-gpu/src/demosaic.rs:86`](../core/dr-gpu/src/demosaic.rs#L86), [`core/dr-gpu/tests/base_curve.rs:1`](../core/dr-gpu/tests/base_curve.rs#L1), [`core/dr-pipeline/src/operation.rs:1495`](../core/dr-pipeline/src/operation.rs#L1495), [`core/dr-pipeline/src/operation.rs:1576`](../core/dr-pipeline/src/operation.rs#L1576), [`core/dr-pipeline/src/operation.rs:1601`](../core/dr-pipeline/src/operation.rs#L1601), [`core/dr-pipeline/src/operation.rs:1616`](../core/dr-pipeline/src/operation.rs#L1616), [`core/dr-pipeline/src/operation.rs:1640`](../core/dr-pipeline/src/operation.rs#L1640), [`core/dr-pipeline/src/operation.rs:310`](../core/dr-pipeline/src/operation.rs#L310), [`core/dr-pipeline/src/operation.rs:440`](../core/dr-pipeline/src/operation.rs#L440), [`core/dr-pipeline/src/operation.rs:450`](../core/dr-pipeline/src/operation.rs#L450), [`core/dr-pipeline/src/operation.rs:600`](../core/dr-pipeline/src/operation.rs#L600) | -| FR-DEV-3f | [`core/dr-film/src/bake.rs:271`](../core/dr-film/src/bake.rs#L271), [`core/dr-film/src/bake.rs:62`](../core/dr-film/src/bake.rs#L62), [`core/dr-film/src/boolean_grain.rs:1`](../core/dr-film/src/boolean_grain.rs#L1), [`core/dr-film/src/boolean_grain.rs:78`](../core/dr-film/src/boolean_grain.rs#L78), [`core/dr-film/src/grain.rs:140`](../core/dr-film/src/grain.rs#L140), [`core/dr-film/src/grain.rs:1`](../core/dr-film/src/grain.rs#L1), [`core/dr-film/src/grain.rs:302`](../core/dr-film/src/grain.rs#L302), [`core/dr-film/src/grain.rs:79`](../core/dr-film/src/grain.rs#L79), [`core/dr-film/src/lib.rs:160`](../core/dr-film/src/lib.rs#L160), [`core/dr-film/src/lib.rs:1`](../core/dr-film/src/lib.rs#L1), [`core/dr-film/src/profile.rs:100`](../core/dr-film/src/profile.rs#L100), [`core/dr-film/src/profile.rs:142`](../core/dr-film/src/profile.rs#L142), [`core/dr-film/src/profile.rs:182`](../core/dr-film/src/profile.rs#L182), [`core/dr-film/src/profile.rs:259`](../core/dr-film/src/profile.rs#L259), [`core/dr-film/src/profile.rs:502`](../core/dr-film/src/profile.rs#L502), [`core/dr-film/src/profile.rs:73`](../core/dr-film/src/profile.rs#L73), [`core/dr-gpu/src/adjust.rs:139`](../core/dr-gpu/src/adjust.rs#L139), [`core/dr-gpu/src/adjust.rs:196`](../core/dr-gpu/src/adjust.rs#L196), [`core/dr-gpu/src/adjust.rs:357`](../core/dr-gpu/src/adjust.rs#L357), [`core/dr-gpu/src/adjust.rs:483`](../core/dr-gpu/src/adjust.rs#L483), [`core/dr-gpu/src/adjust.rs:77`](../core/dr-gpu/src/adjust.rs#L77), [`core/dr-gpu/tests/film_sim.rs:191`](../core/dr-gpu/tests/film_sim.rs#L191), [`core/dr-gpu/tests/film_sim.rs:1`](../core/dr-gpu/tests/film_sim.rs#L1), [`core/dr-pipeline/src/graph.rs:102`](../core/dr-pipeline/src/graph.rs#L102), [`core/dr-pipeline/src/graph.rs:125`](../core/dr-pipeline/src/graph.rs#L125), [`core/dr-pipeline/src/graph.rs:325`](../core/dr-pipeline/src/graph.rs#L325), [`core/dr-pipeline/src/operation.rs:1065`](../core/dr-pipeline/src/operation.rs#L1065), [`core/dr-pipeline/src/operation.rs:1094`](../core/dr-pipeline/src/operation.rs#L1094), [`core/dr-pipeline/src/operation.rs:1495`](../core/dr-pipeline/src/operation.rs#L1495), [`core/dr-pipeline/src/operation.rs:296`](../core/dr-pipeline/src/operation.rs#L296), [`core/dr-pipeline/src/operation.rs:310`](../core/dr-pipeline/src/operation.rs#L310), [`core/dr-pipeline/src/ops/film_sim.rs:129`](../core/dr-pipeline/src/ops/film_sim.rs#L129), [`core/dr-pipeline/src/ops/film_sim.rs:153`](../core/dr-pipeline/src/ops/film_sim.rs#L153), [`core/dr-pipeline/src/ops/film_sim.rs:1`](../core/dr-pipeline/src/ops/film_sim.rs#L1), [`core/dr-pipeline/src/ops/film_sim.rs:331`](../core/dr-pipeline/src/ops/film_sim.rs#L331), [`core/dr-pipeline/src/ops/film_sim.rs:43`](../core/dr-pipeline/src/ops/film_sim.rs#L43), [`core/dr-pipeline/src/ops/film_sim.rs:87`](../core/dr-pipeline/src/ops/film_sim.rs#L87), [`core/dr-pipeline/src/ops/film_sim.rs:92`](../core/dr-pipeline/src/ops/film_sim.rs#L92), [`core/dr-pipeline/src/sidecar.rs:112`](../core/dr-pipeline/src/sidecar.rs#L112), [`core/dr-pipeline/src/sidecar.rs:168`](../core/dr-pipeline/src/sidecar.rs#L168), [`core/dr-pipeline/src/sidecar.rs:1958`](../core/dr-pipeline/src/sidecar.rs#L1958), [`core/dr-pipeline/src/sidecar.rs:2034`](../core/dr-pipeline/src/sidecar.rs#L2034), [`core/dr-pipeline/src/sidecar.rs:534`](../core/dr-pipeline/src/sidecar.rs#L534), [`core/dr-pipeline/src/sidecar.rs:661`](../core/dr-pipeline/src/sidecar.rs#L661), [`core/dr-pipeline/src/sidecar.rs:793`](../core/dr-pipeline/src/sidecar.rs#L793), [`core/dr-pipeline/src/state.rs:100`](../core/dr-pipeline/src/state.rs#L100), [`core/dr-pipeline/src/state.rs:115`](../core/dr-pipeline/src/state.rs#L115), [`core/dr-pipeline/src/state.rs:60`](../core/dr-pipeline/src/state.rs#L60), [`ui/dr-ui/src/develop.rs:3244`](../ui/dr-ui/src/develop.rs#L3244), [`ui/dr-ui/src/develop.rs:3261`](../ui/dr-ui/src/develop.rs#L3261), [`ui/dr-ui/src/develop.rs:3273`](../ui/dr-ui/src/develop.rs#L3273), [`ui/dr-ui/src/develop.rs:3311`](../ui/dr-ui/src/develop.rs#L3311), [`ui/dr-ui/src/develop.rs:3320`](../ui/dr-ui/src/develop.rs#L3320), [`ui/dr-ui/src/develop.rs:3423`](../ui/dr-ui/src/develop.rs#L3423), [`ui/dr-ui/src/develop.rs:3839`](../ui/dr-ui/src/develop.rs#L3839), [`ui/dr-ui/src/develop.rs:3854`](../ui/dr-ui/src/develop.rs#L3854), [`ui/dr-ui/src/lib.rs:2368`](../ui/dr-ui/src/lib.rs#L2368), [`ui/dr-ui/src/lib.rs:621`](../ui/dr-ui/src/lib.rs#L621), [`ui/dr-ui/src/lib.rs:679`](../ui/dr-ui/src/lib.rs#L679), [`ui/dr-ui/src/library.rs:530`](../ui/dr-ui/src/library.rs#L530), [`ui/dr-ui/src/library.rs:778`](../ui/dr-ui/src/library.rs#L778), [`ui/dr-ui/src/presets.rs:395`](../ui/dr-ui/src/presets.rs#L395), [`ui/dr-ui/ui/adjust.slint:1034`](../ui/dr-ui/ui/adjust.slint#L1034), [`ui/dr-ui/ui/adjust.slint:1116`](../ui/dr-ui/ui/adjust.slint#L1116), [`ui/dr-ui/ui/app.slint:2481`](../ui/dr-ui/ui/app.slint#L2481), [`ui/dr-ui/ui/app.slint:655`](../ui/dr-ui/ui/app.slint#L655) | +| FR-DEV-3f | [`core/dr-film/src/bake.rs:271`](../core/dr-film/src/bake.rs#L271), [`core/dr-film/src/bake.rs:62`](../core/dr-film/src/bake.rs#L62), [`core/dr-film/src/boolean_grain.rs:1`](../core/dr-film/src/boolean_grain.rs#L1), [`core/dr-film/src/boolean_grain.rs:78`](../core/dr-film/src/boolean_grain.rs#L78), [`core/dr-film/src/grain.rs:140`](../core/dr-film/src/grain.rs#L140), [`core/dr-film/src/grain.rs:1`](../core/dr-film/src/grain.rs#L1), [`core/dr-film/src/grain.rs:302`](../core/dr-film/src/grain.rs#L302), [`core/dr-film/src/grain.rs:79`](../core/dr-film/src/grain.rs#L79), [`core/dr-film/src/lib.rs:160`](../core/dr-film/src/lib.rs#L160), [`core/dr-film/src/lib.rs:1`](../core/dr-film/src/lib.rs#L1), [`core/dr-film/src/profile.rs:100`](../core/dr-film/src/profile.rs#L100), [`core/dr-film/src/profile.rs:142`](../core/dr-film/src/profile.rs#L142), [`core/dr-film/src/profile.rs:182`](../core/dr-film/src/profile.rs#L182), [`core/dr-film/src/profile.rs:259`](../core/dr-film/src/profile.rs#L259), [`core/dr-film/src/profile.rs:502`](../core/dr-film/src/profile.rs#L502), [`core/dr-film/src/profile.rs:73`](../core/dr-film/src/profile.rs#L73), [`core/dr-gpu/src/adjust.rs:139`](../core/dr-gpu/src/adjust.rs#L139), [`core/dr-gpu/src/adjust.rs:196`](../core/dr-gpu/src/adjust.rs#L196), [`core/dr-gpu/src/adjust.rs:357`](../core/dr-gpu/src/adjust.rs#L357), [`core/dr-gpu/src/adjust.rs:483`](../core/dr-gpu/src/adjust.rs#L483), [`core/dr-gpu/src/adjust.rs:77`](../core/dr-gpu/src/adjust.rs#L77), [`core/dr-gpu/tests/film_sim.rs:191`](../core/dr-gpu/tests/film_sim.rs#L191), [`core/dr-gpu/tests/film_sim.rs:1`](../core/dr-gpu/tests/film_sim.rs#L1), [`core/dr-pipeline/src/graph.rs:102`](../core/dr-pipeline/src/graph.rs#L102), [`core/dr-pipeline/src/graph.rs:125`](../core/dr-pipeline/src/graph.rs#L125), [`core/dr-pipeline/src/graph.rs:325`](../core/dr-pipeline/src/graph.rs#L325), [`core/dr-pipeline/src/operation.rs:1065`](../core/dr-pipeline/src/operation.rs#L1065), [`core/dr-pipeline/src/operation.rs:1094`](../core/dr-pipeline/src/operation.rs#L1094), [`core/dr-pipeline/src/operation.rs:1495`](../core/dr-pipeline/src/operation.rs#L1495), [`core/dr-pipeline/src/operation.rs:296`](../core/dr-pipeline/src/operation.rs#L296), [`core/dr-pipeline/src/operation.rs:310`](../core/dr-pipeline/src/operation.rs#L310), [`core/dr-pipeline/src/ops/film_sim.rs:129`](../core/dr-pipeline/src/ops/film_sim.rs#L129), [`core/dr-pipeline/src/ops/film_sim.rs:153`](../core/dr-pipeline/src/ops/film_sim.rs#L153), [`core/dr-pipeline/src/ops/film_sim.rs:1`](../core/dr-pipeline/src/ops/film_sim.rs#L1), [`core/dr-pipeline/src/ops/film_sim.rs:331`](../core/dr-pipeline/src/ops/film_sim.rs#L331), [`core/dr-pipeline/src/ops/film_sim.rs:43`](../core/dr-pipeline/src/ops/film_sim.rs#L43), [`core/dr-pipeline/src/ops/film_sim.rs:87`](../core/dr-pipeline/src/ops/film_sim.rs#L87), [`core/dr-pipeline/src/ops/film_sim.rs:92`](../core/dr-pipeline/src/ops/film_sim.rs#L92), [`core/dr-pipeline/src/sidecar.rs:112`](../core/dr-pipeline/src/sidecar.rs#L112), [`core/dr-pipeline/src/sidecar.rs:168`](../core/dr-pipeline/src/sidecar.rs#L168), [`core/dr-pipeline/src/sidecar.rs:1958`](../core/dr-pipeline/src/sidecar.rs#L1958), [`core/dr-pipeline/src/sidecar.rs:2034`](../core/dr-pipeline/src/sidecar.rs#L2034), [`core/dr-pipeline/src/sidecar.rs:534`](../core/dr-pipeline/src/sidecar.rs#L534), [`core/dr-pipeline/src/sidecar.rs:661`](../core/dr-pipeline/src/sidecar.rs#L661), [`core/dr-pipeline/src/sidecar.rs:793`](../core/dr-pipeline/src/sidecar.rs#L793), [`core/dr-pipeline/src/state.rs:100`](../core/dr-pipeline/src/state.rs#L100), [`core/dr-pipeline/src/state.rs:115`](../core/dr-pipeline/src/state.rs#L115), [`core/dr-pipeline/src/state.rs:60`](../core/dr-pipeline/src/state.rs#L60), [`ui/dr-ui/src/develop.rs:3244`](../ui/dr-ui/src/develop.rs#L3244), [`ui/dr-ui/src/develop.rs:3261`](../ui/dr-ui/src/develop.rs#L3261), [`ui/dr-ui/src/develop.rs:3273`](../ui/dr-ui/src/develop.rs#L3273), [`ui/dr-ui/src/develop.rs:3311`](../ui/dr-ui/src/develop.rs#L3311), [`ui/dr-ui/src/develop.rs:3320`](../ui/dr-ui/src/develop.rs#L3320), [`ui/dr-ui/src/develop.rs:3423`](../ui/dr-ui/src/develop.rs#L3423), [`ui/dr-ui/src/develop.rs:3839`](../ui/dr-ui/src/develop.rs#L3839), [`ui/dr-ui/src/develop.rs:3854`](../ui/dr-ui/src/develop.rs#L3854), [`ui/dr-ui/src/lib.rs:2374`](../ui/dr-ui/src/lib.rs#L2374), [`ui/dr-ui/src/lib.rs:627`](../ui/dr-ui/src/lib.rs#L627), [`ui/dr-ui/src/lib.rs:685`](../ui/dr-ui/src/lib.rs#L685), [`ui/dr-ui/src/library.rs:530`](../ui/dr-ui/src/library.rs#L530), [`ui/dr-ui/src/library.rs:778`](../ui/dr-ui/src/library.rs#L778), [`ui/dr-ui/src/presets.rs:395`](../ui/dr-ui/src/presets.rs#L395), [`ui/dr-ui/ui/adjust.slint:1026`](../ui/dr-ui/ui/adjust.slint#L1026), [`ui/dr-ui/ui/adjust.slint:950`](../ui/dr-ui/ui/adjust.slint#L950), [`ui/dr-ui/ui/app.slint:2539`](../ui/dr-ui/ui/app.slint#L2539), [`ui/dr-ui/ui/app.slint:656`](../ui/dr-ui/ui/app.slint#L656) | | FR-DEV-3h | [`core/dr-decode/src/lib.rs:404`](../core/dr-decode/src/lib.rs#L404), [`core/dr-decode/src/preview.rs:29`](../core/dr-decode/src/preview.rs#L29), [`core/dr-pipeline/src/framing.rs:1050`](../core/dr-pipeline/src/framing.rs#L1050), [`core/dr-pipeline/src/framing.rs:328`](../core/dr-pipeline/src/framing.rs#L328), [`core/dr-pipeline/src/framing.rs:488`](../core/dr-pipeline/src/framing.rs#L488), [`core/dr-types/src/lib.rs:337`](../core/dr-types/src/lib.rs#L337), [`core/dr-types/src/lib.rs:445`](../core/dr-types/src/lib.rs#L445), [`core/dr-types/src/lib.rs:457`](../core/dr-types/src/lib.rs#L457), [`core/dr-types/src/lib.rs:473`](../core/dr-types/src/lib.rs#L473), [`ui/dr-ui/src/develop.rs:139`](../ui/dr-ui/src/develop.rs#L139), [`ui/dr-ui/src/develop.rs:2167`](../ui/dr-ui/src/develop.rs#L2167), [`ui/dr-ui/src/segmentation.rs:322`](../ui/dr-ui/src/segmentation.rs#L322) | | FR-DEV-4 | [`core/dr-gpu/src/adjust.rs:770`](../core/dr-gpu/src/adjust.rs#L770), [`core/dr-gpu/src/lib.rs:351`](../core/dr-gpu/src/lib.rs#L351), [`ui/dr-ui/ui/crop.slint:1`](../ui/dr-ui/ui/crop.slint#L1) | -| FR-DEV-5 | [`core/dr-pipeline/src/graph.rs:346`](../core/dr-pipeline/src/graph.rs#L346), [`core/dr-pipeline/src/graph.rs:385`](../core/dr-pipeline/src/graph.rs#L385), [`core/dr-pipeline/src/history.rs:102`](../core/dr-pipeline/src/history.rs#L102), [`core/dr-pipeline/src/history.rs:110`](../core/dr-pipeline/src/history.rs#L110), [`core/dr-pipeline/src/history.rs:127`](../core/dr-pipeline/src/history.rs#L127), [`core/dr-pipeline/src/history.rs:184`](../core/dr-pipeline/src/history.rs#L184), [`core/dr-pipeline/src/history.rs:1`](../core/dr-pipeline/src/history.rs#L1), [`core/dr-pipeline/src/history.rs:214`](../core/dr-pipeline/src/history.rs#L214), [`core/dr-pipeline/src/history.rs:234`](../core/dr-pipeline/src/history.rs#L234), [`core/dr-pipeline/src/history.rs:293`](../core/dr-pipeline/src/history.rs#L293), [`core/dr-pipeline/src/history.rs:479`](../core/dr-pipeline/src/history.rs#L479), [`core/dr-pipeline/src/history.rs:489`](../core/dr-pipeline/src/history.rs#L489), [`core/dr-pipeline/src/history.rs:499`](../core/dr-pipeline/src/history.rs#L499), [`core/dr-pipeline/src/history.rs:526`](../core/dr-pipeline/src/history.rs#L526), [`core/dr-pipeline/src/history.rs:86`](../core/dr-pipeline/src/history.rs#L86), [`core/dr-pipeline/src/state.rs:1`](../core/dr-pipeline/src/state.rs#L1), [`core/dr-pipeline/src/state.rs:75`](../core/dr-pipeline/src/state.rs#L75), [`ui/dr-ui/src/develop.rs:3273`](../ui/dr-ui/src/develop.rs#L3273), [`ui/dr-ui/src/develop.rs:3854`](../ui/dr-ui/src/develop.rs#L3854), [`ui/dr-ui/src/develop.rs:3884`](../ui/dr-ui/src/develop.rs#L3884), [`ui/dr-ui/src/develop.rs:3897`](../ui/dr-ui/src/develop.rs#L3897), [`ui/dr-ui/src/develop.rs:3909`](../ui/dr-ui/src/develop.rs#L3909), [`ui/dr-ui/src/develop.rs:3925`](../ui/dr-ui/src/develop.rs#L3925), [`ui/dr-ui/src/develop.rs:3957`](../ui/dr-ui/src/develop.rs#L3957), [`ui/dr-ui/src/develop.rs:3961`](../ui/dr-ui/src/develop.rs#L3961), [`ui/dr-ui/src/develop.rs:3980`](../ui/dr-ui/src/develop.rs#L3980), [`ui/dr-ui/src/develop.rs:3996`](../ui/dr-ui/src/develop.rs#L3996), [`ui/dr-ui/src/develop.rs:709`](../ui/dr-ui/src/develop.rs#L709), [`ui/dr-ui/src/labels.rs:12`](../ui/dr-ui/src/labels.rs#L12), [`ui/dr-ui/src/labels.rs:215`](../ui/dr-ui/src/labels.rs#L215), [`ui/dr-ui/src/lib.rs:1527`](../ui/dr-ui/src/lib.rs#L1527), [`ui/dr-ui/src/lib.rs:1570`](../ui/dr-ui/src/lib.rs#L1570), [`ui/dr-ui/src/lib.rs:1578`](../ui/dr-ui/src/lib.rs#L1578), [`ui/dr-ui/src/lib.rs:2564`](../ui/dr-ui/src/lib.rs#L2564), [`ui/dr-ui/ui/history.slint:1`](../ui/dr-ui/ui/history.slint#L1) | -| FR-DEV-6 | [`core/dr-pipeline/src/preset.rs:1`](../core/dr-pipeline/src/preset.rs#L1), [`core/dr-pipeline/src/preset.rs:381`](../core/dr-pipeline/src/preset.rs#L381), [`core/dr-pipeline/src/preset.rs:414`](../core/dr-pipeline/src/preset.rs#L414), [`core/dr-pipeline/src/starter.rs:1`](../core/dr-pipeline/src/starter.rs#L1), [`core/dr-preset-xmp/src/lib.rs:1`](../core/dr-preset-xmp/src/lib.rs#L1), [`core/dr-types/src/settings.rs:272`](../core/dr-types/src/settings.rs#L272), [`ui/dr-ui/src/develop.rs:3796`](../ui/dr-ui/src/develop.rs#L3796), [`ui/dr-ui/src/develop.rs:3817`](../ui/dr-ui/src/develop.rs#L3817), [`ui/dr-ui/src/lib.rs:1494`](../ui/dr-ui/src/lib.rs#L1494), [`ui/dr-ui/src/lib.rs:2179`](../ui/dr-ui/src/lib.rs#L2179), [`ui/dr-ui/src/lib.rs:2208`](../ui/dr-ui/src/lib.rs#L2208), [`ui/dr-ui/src/library.rs:1903`](../ui/dr-ui/src/library.rs#L1903), [`ui/dr-ui/src/library.rs:492`](../ui/dr-ui/src/library.rs#L492), [`ui/dr-ui/src/library.rs:520`](../ui/dr-ui/src/library.rs#L520), [`ui/dr-ui/src/library_ui.rs:2696`](../ui/dr-ui/src/library_ui.rs#L2696), [`ui/dr-ui/src/library_ui.rs:3096`](../ui/dr-ui/src/library_ui.rs#L3096), [`ui/dr-ui/src/library_ui.rs:494`](../ui/dr-ui/src/library_ui.rs#L494), [`ui/dr-ui/src/preset_store.rs:1`](../ui/dr-ui/src/preset_store.rs#L1), [`ui/dr-ui/src/presets.rs:1`](../ui/dr-ui/src/presets.rs#L1), [`ui/dr-ui/src/presets.rs:657`](../ui/dr-ui/src/presets.rs#L657), [`ui/dr-ui/src/presets.rs:691`](../ui/dr-ui/src/presets.rs#L691), [`ui/dr-ui/ui/adjust.slint:709`](../ui/dr-ui/ui/adjust.slint#L709), [`ui/dr-ui/ui/adjust.slint:736`](../ui/dr-ui/ui/adjust.slint#L736), [`ui/dr-ui/ui/adjust.slint:779`](../ui/dr-ui/ui/adjust.slint#L779), [`ui/dr-ui/ui/app.slint:1523`](../ui/dr-ui/ui/app.slint#L1523), [`ui/dr-ui/ui/app.slint:2570`](../ui/dr-ui/ui/app.slint#L2570), [`ui/dr-ui/ui/app.slint:727`](../ui/dr-ui/ui/app.slint#L727), [`ui/dr-ui/ui/app.slint:738`](../ui/dr-ui/ui/app.slint#L738), [`ui/dr-ui/ui/library.slint:1495`](../ui/dr-ui/ui/library.slint#L1495), [`ui/dr-ui/ui/library.slint:1502`](../ui/dr-ui/ui/library.slint#L1502), [`ui/dr-ui/ui/library.slint:850`](../ui/dr-ui/ui/library.slint#L850), [`ui/dr-ui/ui/library.slint:866`](../ui/dr-ui/ui/library.slint#L866), [`ui/dr-ui/ui/library.slint:938`](../ui/dr-ui/ui/library.slint#L938), [`ui/dr-ui/ui/library.slint:953`](../ui/dr-ui/ui/library.slint#L953), [`ui/dr-ui/ui/presets.slint:105`](../ui/dr-ui/ui/presets.slint#L105), [`ui/dr-ui/ui/presets.slint:113`](../ui/dr-ui/ui/presets.slint#L113), [`ui/dr-ui/ui/presets.slint:19`](../ui/dr-ui/ui/presets.slint#L19), [`ui/dr-ui/ui/presets.slint:276`](../ui/dr-ui/ui/presets.slint#L276), [`ui/dr-ui/ui/presets.slint:297`](../ui/dr-ui/ui/presets.slint#L297), [`ui/dr-ui/ui/presets.slint:5`](../ui/dr-ui/ui/presets.slint#L5), [`ui/dr-ui/ui/presets.slint:60`](../ui/dr-ui/ui/presets.slint#L60), [`ui/dr-ui/ui/settings.slint:101`](../ui/dr-ui/ui/settings.slint#L101), [`ui/dr-ui/ui/settings.slint:557`](../ui/dr-ui/ui/settings.slint#L557) | -| FR-DEV-7 | [`core/dr-pipeline/src/history.rs:214`](../core/dr-pipeline/src/history.rs#L214), [`core/dr-pipeline/src/history.rs:499`](../core/dr-pipeline/src/history.rs#L499), [`core/dr-pipeline/src/history.rs:526`](../core/dr-pipeline/src/history.rs#L526), [`ui/dr-ui/src/develop.rs:3925`](../ui/dr-ui/src/develop.rs#L3925), [`ui/dr-ui/src/develop.rs:3957`](../ui/dr-ui/src/develop.rs#L3957), [`ui/dr-ui/src/lib.rs:1578`](../ui/dr-ui/src/lib.rs#L1578), [`ui/dr-ui/src/lib.rs:2564`](../ui/dr-ui/src/lib.rs#L2564), [`ui/dr-ui/ui/history.slint:1`](../ui/dr-ui/ui/history.slint#L1) | -| FR-DEV-8 | [`core/dr-gpu/src/detail.rs:405`](../core/dr-gpu/src/detail.rs#L405), [`core/dr-gpu/src/detail.rs:623`](../core/dr-gpu/src/detail.rs#L623), [`core/dr-gpu/tests/detail_instances.rs:1`](../core/dr-gpu/tests/detail_instances.rs#L1), [`core/dr-gpu/tests/spot_removal.rs:1`](../core/dr-gpu/tests/spot_removal.rs#L1), [`core/dr-pipeline/src/detail.rs:410`](../core/dr-pipeline/src/detail.rs#L410), [`core/dr-pipeline/src/detail.rs:434`](../core/dr-pipeline/src/detail.rs#L434), [`core/dr-pipeline/src/detail.rs:469`](../core/dr-pipeline/src/detail.rs#L469), [`core/dr-pipeline/src/detail.rs:555`](../core/dr-pipeline/src/detail.rs#L555), [`core/dr-pipeline/src/graph.rs:114`](../core/dr-pipeline/src/graph.rs#L114), [`core/dr-pipeline/src/graph.rs:192`](../core/dr-pipeline/src/graph.rs#L192), [`core/dr-pipeline/src/graph.rs:686`](../core/dr-pipeline/src/graph.rs#L686), [`core/dr-pipeline/src/operation.rs:330`](../core/dr-pipeline/src/operation.rs#L330), [`core/dr-pipeline/src/operation.rs:554`](../core/dr-pipeline/src/operation.rs#L554), [`core/dr-pipeline/src/sidecar.rs:184`](../core/dr-pipeline/src/sidecar.rs#L184), [`core/dr-pipeline/src/sidecar.rs:353`](../core/dr-pipeline/src/sidecar.rs#L353), [`core/dr-pipeline/src/sidecar.rs:673`](../core/dr-pipeline/src/sidecar.rs#L673), [`core/dr-pipeline/src/sidecar.rs:809`](../core/dr-pipeline/src/sidecar.rs#L809), [`core/dr-pipeline/src/sidecar.rs:863`](../core/dr-pipeline/src/sidecar.rs#L863), [`core/dr-pipeline/src/sidecar.rs:893`](../core/dr-pipeline/src/sidecar.rs#L893), [`core/dr-pipeline/src/spot.rs:115`](../core/dr-pipeline/src/spot.rs#L115), [`core/dr-pipeline/src/spot.rs:151`](../core/dr-pipeline/src/spot.rs#L151), [`core/dr-pipeline/src/spot.rs:1`](../core/dr-pipeline/src/spot.rs#L1), [`core/dr-pipeline/src/spot.rs:207`](../core/dr-pipeline/src/spot.rs#L207), [`core/dr-pipeline/src/spot.rs:387`](../core/dr-pipeline/src/spot.rs#L387), [`core/dr-pipeline/src/spot.rs:472`](../core/dr-pipeline/src/spot.rs#L472), [`core/dr-pipeline/src/spot.rs:582`](../core/dr-pipeline/src/spot.rs#L582), [`core/dr-pipeline/src/spot.rs:673`](../core/dr-pipeline/src/spot.rs#L673), [`core/dr-pipeline/src/state.rs:103`](../core/dr-pipeline/src/state.rs#L103), [`core/dr-pipeline/tests/spot_sidecar.rs:1`](../core/dr-pipeline/tests/spot_sidecar.rs#L1), [`core/dr-pipeline/tests/spots.rs:1`](../core/dr-pipeline/tests/spots.rs#L1), [`ui/dr-ui/src/develop.rs:2319`](../ui/dr-ui/src/develop.rs#L2319), [`ui/dr-ui/src/develop.rs:2357`](../ui/dr-ui/src/develop.rs#L2357), [`ui/dr-ui/src/develop.rs:2422`](../ui/dr-ui/src/develop.rs#L2422), [`ui/dr-ui/src/develop.rs:2505`](../ui/dr-ui/src/develop.rs#L2505), [`ui/dr-ui/src/develop.rs:2519`](../ui/dr-ui/src/develop.rs#L2519), [`ui/dr-ui/src/develop.rs:796`](../ui/dr-ui/src/develop.rs#L796), [`ui/dr-ui/src/labels.rs:52`](../ui/dr-ui/src/labels.rs#L52), [`ui/dr-ui/src/lib.rs:1599`](../ui/dr-ui/src/lib.rs#L1599), [`ui/dr-ui/src/lib.rs:2682`](../ui/dr-ui/src/lib.rs#L2682), [`ui/dr-ui/src/lib.rs:344`](../ui/dr-ui/src/lib.rs#L344), [`ui/dr-ui/src/spots_ui.rs:19`](../ui/dr-ui/src/spots_ui.rs#L19), [`ui/dr-ui/src/spots_ui.rs:1`](../ui/dr-ui/src/spots_ui.rs#L1), [`ui/dr-ui/src/spots_ui.rs:265`](../ui/dr-ui/src/spots_ui.rs#L265), [`ui/dr-ui/ui/adjust.slint:810`](../ui/dr-ui/ui/adjust.slint#L810), [`ui/dr-ui/ui/app.slint:138`](../ui/dr-ui/ui/app.slint#L138), [`ui/dr-ui/ui/app.slint:1848`](../ui/dr-ui/ui/app.slint#L1848), [`ui/dr-ui/ui/app.slint:2023`](../ui/dr-ui/ui/app.slint#L2023), [`ui/dr-ui/ui/app.slint:2387`](../ui/dr-ui/ui/app.slint#L2387), [`ui/dr-ui/ui/spots.slint:180`](../ui/dr-ui/ui/spots.slint#L180), [`ui/dr-ui/ui/spots.slint:48`](../ui/dr-ui/ui/spots.slint#L48), [`ui/dr-ui/ui/spots.slint:5`](../ui/dr-ui/ui/spots.slint#L5) | -| FR-DSP-1 | [`core/dr-gpu/src/adjust.rs:2126`](../core/dr-gpu/src/adjust.rs#L2126), [`core/dr-gpu/src/adjust.rs:2203`](../core/dr-gpu/src/adjust.rs#L2203), [`core/dr-gpu/src/adjust.rs:2288`](../core/dr-gpu/src/adjust.rs#L2288), [`core/dr-gpu/src/adjust.rs:54`](../core/dr-gpu/src/adjust.rs#L54), [`core/dr-gpu/src/adjust.rs:770`](../core/dr-gpu/src/adjust.rs#L770), [`core/dr-gpu/src/lib.rs:172`](../core/dr-gpu/src/lib.rs#L172), [`core/dr-gpu/src/lib.rs:192`](../core/dr-gpu/src/lib.rs#L192), [`core/dr-gpu/src/lib.rs:70`](../core/dr-gpu/src/lib.rs#L70), [`core/dr-gpu/src/lib.rs:93`](../core/dr-gpu/src/lib.rs#L93), [`core/dr-gpu/tests/capture_sharpen.rs:200`](../core/dr-gpu/tests/capture_sharpen.rs#L200), [`core/dr-gpu/tests/detail_stage.rs:328`](../core/dr-gpu/tests/detail_stage.rs#L328), [`core/dr-gpu/tests/local_contrast.rs:264`](../core/dr-gpu/tests/local_contrast.rs#L264), [`core/dr-gpu/tests/noise_reduction.rs:378`](../core/dr-gpu/tests/noise_reduction.rs#L378), [`core/dr-pipeline/src/detail.rs:136`](../core/dr-pipeline/src/detail.rs#L136), [`core/dr-pipeline/src/detail.rs:524`](../core/dr-pipeline/src/detail.rs#L524), [`core/dr-pipeline/src/graph.rs:548`](../core/dr-pipeline/src/graph.rs#L548), [`core/dr-pipeline/src/graph.rs:578`](../core/dr-pipeline/src/graph.rs#L578), [`core/dr-pipeline/src/ops/capture_sharpen.rs:1`](../core/dr-pipeline/src/ops/capture_sharpen.rs#L1), [`core/dr-pipeline/src/ops/capture_sharpen.rs:659`](../core/dr-pipeline/src/ops/capture_sharpen.rs#L659), [`core/dr-pipeline/src/ops/local_contrast.rs:1`](../core/dr-pipeline/src/ops/local_contrast.rs#L1), [`core/dr-pipeline/src/ops/local_contrast.rs:971`](../core/dr-pipeline/src/ops/local_contrast.rs#L971), [`core/dr-pipeline/src/ops/noise_reduction.rs:700`](../core/dr-pipeline/src/ops/noise_reduction.rs#L700), [`core/dr-pipeline/src/spot.rs:673`](../core/dr-pipeline/src/spot.rs#L673), [`ui/dr-ui/src/develop.rs:2843`](../ui/dr-ui/src/develop.rs#L2843), [`ui/dr-ui/src/develop.rs:4251`](../ui/dr-ui/src/develop.rs#L4251), [`ui/dr-ui/src/develop.rs:4734`](../ui/dr-ui/src/develop.rs#L4734), [`ui/dr-ui/src/develop.rs:4768`](../ui/dr-ui/src/develop.rs#L4768), [`ui/dr-ui/src/lib.rs:81`](../ui/dr-ui/src/lib.rs#L81), [`ui/dr-ui/src/lib.rs:829`](../ui/dr-ui/src/lib.rs#L829), [`ui/dr-ui/src/lib.rs:888`](../ui/dr-ui/src/lib.rs#L888) | +| FR-DEV-5 | [`core/dr-pipeline/src/graph.rs:346`](../core/dr-pipeline/src/graph.rs#L346), [`core/dr-pipeline/src/graph.rs:385`](../core/dr-pipeline/src/graph.rs#L385), [`core/dr-pipeline/src/history.rs:102`](../core/dr-pipeline/src/history.rs#L102), [`core/dr-pipeline/src/history.rs:110`](../core/dr-pipeline/src/history.rs#L110), [`core/dr-pipeline/src/history.rs:127`](../core/dr-pipeline/src/history.rs#L127), [`core/dr-pipeline/src/history.rs:184`](../core/dr-pipeline/src/history.rs#L184), [`core/dr-pipeline/src/history.rs:1`](../core/dr-pipeline/src/history.rs#L1), [`core/dr-pipeline/src/history.rs:214`](../core/dr-pipeline/src/history.rs#L214), [`core/dr-pipeline/src/history.rs:234`](../core/dr-pipeline/src/history.rs#L234), [`core/dr-pipeline/src/history.rs:293`](../core/dr-pipeline/src/history.rs#L293), [`core/dr-pipeline/src/history.rs:479`](../core/dr-pipeline/src/history.rs#L479), [`core/dr-pipeline/src/history.rs:489`](../core/dr-pipeline/src/history.rs#L489), [`core/dr-pipeline/src/history.rs:499`](../core/dr-pipeline/src/history.rs#L499), [`core/dr-pipeline/src/history.rs:526`](../core/dr-pipeline/src/history.rs#L526), [`core/dr-pipeline/src/history.rs:86`](../core/dr-pipeline/src/history.rs#L86), [`core/dr-pipeline/src/state.rs:1`](../core/dr-pipeline/src/state.rs#L1), [`core/dr-pipeline/src/state.rs:75`](../core/dr-pipeline/src/state.rs#L75), [`ui/dr-ui/src/develop.rs:3273`](../ui/dr-ui/src/develop.rs#L3273), [`ui/dr-ui/src/develop.rs:3854`](../ui/dr-ui/src/develop.rs#L3854), [`ui/dr-ui/src/develop.rs:3884`](../ui/dr-ui/src/develop.rs#L3884), [`ui/dr-ui/src/develop.rs:3897`](../ui/dr-ui/src/develop.rs#L3897), [`ui/dr-ui/src/develop.rs:3909`](../ui/dr-ui/src/develop.rs#L3909), [`ui/dr-ui/src/develop.rs:3925`](../ui/dr-ui/src/develop.rs#L3925), [`ui/dr-ui/src/develop.rs:3957`](../ui/dr-ui/src/develop.rs#L3957), [`ui/dr-ui/src/develop.rs:3961`](../ui/dr-ui/src/develop.rs#L3961), [`ui/dr-ui/src/develop.rs:3980`](../ui/dr-ui/src/develop.rs#L3980), [`ui/dr-ui/src/develop.rs:3996`](../ui/dr-ui/src/develop.rs#L3996), [`ui/dr-ui/src/develop.rs:709`](../ui/dr-ui/src/develop.rs#L709), [`ui/dr-ui/src/labels.rs:12`](../ui/dr-ui/src/labels.rs#L12), [`ui/dr-ui/src/labels.rs:215`](../ui/dr-ui/src/labels.rs#L215), [`ui/dr-ui/src/lib.rs:1533`](../ui/dr-ui/src/lib.rs#L1533), [`ui/dr-ui/src/lib.rs:1576`](../ui/dr-ui/src/lib.rs#L1576), [`ui/dr-ui/src/lib.rs:1584`](../ui/dr-ui/src/lib.rs#L1584), [`ui/dr-ui/src/lib.rs:2570`](../ui/dr-ui/src/lib.rs#L2570), [`ui/dr-ui/ui/history.slint:1`](../ui/dr-ui/ui/history.slint#L1) | +| FR-DEV-6 | [`core/dr-pipeline/src/preset.rs:1`](../core/dr-pipeline/src/preset.rs#L1), [`core/dr-pipeline/src/preset.rs:381`](../core/dr-pipeline/src/preset.rs#L381), [`core/dr-pipeline/src/preset.rs:414`](../core/dr-pipeline/src/preset.rs#L414), [`core/dr-pipeline/src/starter.rs:1`](../core/dr-pipeline/src/starter.rs#L1), [`core/dr-preset-xmp/src/lib.rs:1`](../core/dr-preset-xmp/src/lib.rs#L1), [`core/dr-types/src/settings.rs:272`](../core/dr-types/src/settings.rs#L272), [`ui/dr-ui/src/develop.rs:3796`](../ui/dr-ui/src/develop.rs#L3796), [`ui/dr-ui/src/develop.rs:3817`](../ui/dr-ui/src/develop.rs#L3817), [`ui/dr-ui/src/lib.rs:1500`](../ui/dr-ui/src/lib.rs#L1500), [`ui/dr-ui/src/lib.rs:2185`](../ui/dr-ui/src/lib.rs#L2185), [`ui/dr-ui/src/lib.rs:2214`](../ui/dr-ui/src/lib.rs#L2214), [`ui/dr-ui/src/library.rs:1903`](../ui/dr-ui/src/library.rs#L1903), [`ui/dr-ui/src/library.rs:492`](../ui/dr-ui/src/library.rs#L492), [`ui/dr-ui/src/library.rs:520`](../ui/dr-ui/src/library.rs#L520), [`ui/dr-ui/src/library_ui.rs:2696`](../ui/dr-ui/src/library_ui.rs#L2696), [`ui/dr-ui/src/library_ui.rs:3096`](../ui/dr-ui/src/library_ui.rs#L3096), [`ui/dr-ui/src/library_ui.rs:494`](../ui/dr-ui/src/library_ui.rs#L494), [`ui/dr-ui/src/preset_store.rs:1`](../ui/dr-ui/src/preset_store.rs#L1), [`ui/dr-ui/src/presets.rs:1`](../ui/dr-ui/src/presets.rs#L1), [`ui/dr-ui/src/presets.rs:657`](../ui/dr-ui/src/presets.rs#L657), [`ui/dr-ui/src/presets.rs:691`](../ui/dr-ui/src/presets.rs#L691), [`ui/dr-ui/ui/adjust.slint:694`](../ui/dr-ui/ui/adjust.slint#L694), [`ui/dr-ui/ui/adjust.slint:721`](../ui/dr-ui/ui/adjust.slint#L721), [`ui/dr-ui/ui/adjust.slint:755`](../ui/dr-ui/ui/adjust.slint#L755), [`ui/dr-ui/ui/app.slint:1524`](../ui/dr-ui/ui/app.slint#L1524), [`ui/dr-ui/ui/app.slint:2628`](../ui/dr-ui/ui/app.slint#L2628), [`ui/dr-ui/ui/app.slint:728`](../ui/dr-ui/ui/app.slint#L728), [`ui/dr-ui/ui/app.slint:739`](../ui/dr-ui/ui/app.slint#L739), [`ui/dr-ui/ui/library.slint:1495`](../ui/dr-ui/ui/library.slint#L1495), [`ui/dr-ui/ui/library.slint:1502`](../ui/dr-ui/ui/library.slint#L1502), [`ui/dr-ui/ui/library.slint:850`](../ui/dr-ui/ui/library.slint#L850), [`ui/dr-ui/ui/library.slint:866`](../ui/dr-ui/ui/library.slint#L866), [`ui/dr-ui/ui/library.slint:938`](../ui/dr-ui/ui/library.slint#L938), [`ui/dr-ui/ui/library.slint:953`](../ui/dr-ui/ui/library.slint#L953), [`ui/dr-ui/ui/presets.slint:105`](../ui/dr-ui/ui/presets.slint#L105), [`ui/dr-ui/ui/presets.slint:113`](../ui/dr-ui/ui/presets.slint#L113), [`ui/dr-ui/ui/presets.slint:19`](../ui/dr-ui/ui/presets.slint#L19), [`ui/dr-ui/ui/presets.slint:276`](../ui/dr-ui/ui/presets.slint#L276), [`ui/dr-ui/ui/presets.slint:297`](../ui/dr-ui/ui/presets.slint#L297), [`ui/dr-ui/ui/presets.slint:5`](../ui/dr-ui/ui/presets.slint#L5), [`ui/dr-ui/ui/presets.slint:60`](../ui/dr-ui/ui/presets.slint#L60), [`ui/dr-ui/ui/settings.slint:101`](../ui/dr-ui/ui/settings.slint#L101), [`ui/dr-ui/ui/settings.slint:557`](../ui/dr-ui/ui/settings.slint#L557) | +| FR-DEV-7 | [`core/dr-pipeline/src/history.rs:214`](../core/dr-pipeline/src/history.rs#L214), [`core/dr-pipeline/src/history.rs:499`](../core/dr-pipeline/src/history.rs#L499), [`core/dr-pipeline/src/history.rs:526`](../core/dr-pipeline/src/history.rs#L526), [`ui/dr-ui/src/develop.rs:3925`](../ui/dr-ui/src/develop.rs#L3925), [`ui/dr-ui/src/develop.rs:3957`](../ui/dr-ui/src/develop.rs#L3957), [`ui/dr-ui/src/lib.rs:1584`](../ui/dr-ui/src/lib.rs#L1584), [`ui/dr-ui/src/lib.rs:2570`](../ui/dr-ui/src/lib.rs#L2570), [`ui/dr-ui/ui/history.slint:1`](../ui/dr-ui/ui/history.slint#L1) | +| FR-DEV-8 | [`core/dr-gpu/src/detail.rs:405`](../core/dr-gpu/src/detail.rs#L405), [`core/dr-gpu/src/detail.rs:623`](../core/dr-gpu/src/detail.rs#L623), [`core/dr-gpu/tests/detail_instances.rs:1`](../core/dr-gpu/tests/detail_instances.rs#L1), [`core/dr-gpu/tests/spot_removal.rs:1`](../core/dr-gpu/tests/spot_removal.rs#L1), [`core/dr-pipeline/src/detail.rs:410`](../core/dr-pipeline/src/detail.rs#L410), [`core/dr-pipeline/src/detail.rs:434`](../core/dr-pipeline/src/detail.rs#L434), [`core/dr-pipeline/src/detail.rs:469`](../core/dr-pipeline/src/detail.rs#L469), [`core/dr-pipeline/src/detail.rs:555`](../core/dr-pipeline/src/detail.rs#L555), [`core/dr-pipeline/src/graph.rs:114`](../core/dr-pipeline/src/graph.rs#L114), [`core/dr-pipeline/src/graph.rs:192`](../core/dr-pipeline/src/graph.rs#L192), [`core/dr-pipeline/src/graph.rs:686`](../core/dr-pipeline/src/graph.rs#L686), [`core/dr-pipeline/src/operation.rs:330`](../core/dr-pipeline/src/operation.rs#L330), [`core/dr-pipeline/src/operation.rs:554`](../core/dr-pipeline/src/operation.rs#L554), [`core/dr-pipeline/src/sidecar.rs:184`](../core/dr-pipeline/src/sidecar.rs#L184), [`core/dr-pipeline/src/sidecar.rs:353`](../core/dr-pipeline/src/sidecar.rs#L353), [`core/dr-pipeline/src/sidecar.rs:673`](../core/dr-pipeline/src/sidecar.rs#L673), [`core/dr-pipeline/src/sidecar.rs:809`](../core/dr-pipeline/src/sidecar.rs#L809), [`core/dr-pipeline/src/sidecar.rs:863`](../core/dr-pipeline/src/sidecar.rs#L863), [`core/dr-pipeline/src/sidecar.rs:893`](../core/dr-pipeline/src/sidecar.rs#L893), [`core/dr-pipeline/src/spot.rs:115`](../core/dr-pipeline/src/spot.rs#L115), [`core/dr-pipeline/src/spot.rs:151`](../core/dr-pipeline/src/spot.rs#L151), [`core/dr-pipeline/src/spot.rs:1`](../core/dr-pipeline/src/spot.rs#L1), [`core/dr-pipeline/src/spot.rs:207`](../core/dr-pipeline/src/spot.rs#L207), [`core/dr-pipeline/src/spot.rs:387`](../core/dr-pipeline/src/spot.rs#L387), [`core/dr-pipeline/src/spot.rs:472`](../core/dr-pipeline/src/spot.rs#L472), [`core/dr-pipeline/src/spot.rs:582`](../core/dr-pipeline/src/spot.rs#L582), [`core/dr-pipeline/src/spot.rs:673`](../core/dr-pipeline/src/spot.rs#L673), [`core/dr-pipeline/src/state.rs:103`](../core/dr-pipeline/src/state.rs#L103), [`core/dr-pipeline/tests/spot_sidecar.rs:1`](../core/dr-pipeline/tests/spot_sidecar.rs#L1), [`core/dr-pipeline/tests/spots.rs:1`](../core/dr-pipeline/tests/spots.rs#L1), [`ui/dr-ui/src/develop.rs:2319`](../ui/dr-ui/src/develop.rs#L2319), [`ui/dr-ui/src/develop.rs:2357`](../ui/dr-ui/src/develop.rs#L2357), [`ui/dr-ui/src/develop.rs:2422`](../ui/dr-ui/src/develop.rs#L2422), [`ui/dr-ui/src/develop.rs:2505`](../ui/dr-ui/src/develop.rs#L2505), [`ui/dr-ui/src/develop.rs:2519`](../ui/dr-ui/src/develop.rs#L2519), [`ui/dr-ui/src/develop.rs:796`](../ui/dr-ui/src/develop.rs#L796), [`ui/dr-ui/src/labels.rs:52`](../ui/dr-ui/src/labels.rs#L52), [`ui/dr-ui/src/lib.rs:1605`](../ui/dr-ui/src/lib.rs#L1605), [`ui/dr-ui/src/lib.rs:2688`](../ui/dr-ui/src/lib.rs#L2688), [`ui/dr-ui/src/lib.rs:350`](../ui/dr-ui/src/lib.rs#L350), [`ui/dr-ui/src/spots_ui.rs:19`](../ui/dr-ui/src/spots_ui.rs#L19), [`ui/dr-ui/src/spots_ui.rs:1`](../ui/dr-ui/src/spots_ui.rs#L1), [`ui/dr-ui/src/spots_ui.rs:265`](../ui/dr-ui/src/spots_ui.rs#L265), [`ui/dr-ui/ui/adjust.slint:786`](../ui/dr-ui/ui/adjust.slint#L786), [`ui/dr-ui/ui/app.slint:139`](../ui/dr-ui/ui/app.slint#L139), [`ui/dr-ui/ui/app.slint:1874`](../ui/dr-ui/ui/app.slint#L1874), [`ui/dr-ui/ui/app.slint:2049`](../ui/dr-ui/ui/app.slint#L2049), [`ui/dr-ui/ui/app.slint:2445`](../ui/dr-ui/ui/app.slint#L2445), [`ui/dr-ui/ui/icons.slint:338`](../ui/dr-ui/ui/icons.slint#L338), [`ui/dr-ui/ui/spots.slint:172`](../ui/dr-ui/ui/spots.slint#L172), [`ui/dr-ui/ui/spots.slint:48`](../ui/dr-ui/ui/spots.slint#L48), [`ui/dr-ui/ui/spots.slint:5`](../ui/dr-ui/ui/spots.slint#L5) | +| FR-DSP-1 | [`core/dr-gpu/src/adjust.rs:2126`](../core/dr-gpu/src/adjust.rs#L2126), [`core/dr-gpu/src/adjust.rs:2203`](../core/dr-gpu/src/adjust.rs#L2203), [`core/dr-gpu/src/adjust.rs:2288`](../core/dr-gpu/src/adjust.rs#L2288), [`core/dr-gpu/src/adjust.rs:54`](../core/dr-gpu/src/adjust.rs#L54), [`core/dr-gpu/src/adjust.rs:770`](../core/dr-gpu/src/adjust.rs#L770), [`core/dr-gpu/src/lib.rs:172`](../core/dr-gpu/src/lib.rs#L172), [`core/dr-gpu/src/lib.rs:192`](../core/dr-gpu/src/lib.rs#L192), [`core/dr-gpu/src/lib.rs:70`](../core/dr-gpu/src/lib.rs#L70), [`core/dr-gpu/src/lib.rs:93`](../core/dr-gpu/src/lib.rs#L93), [`core/dr-gpu/tests/capture_sharpen.rs:200`](../core/dr-gpu/tests/capture_sharpen.rs#L200), [`core/dr-gpu/tests/detail_stage.rs:328`](../core/dr-gpu/tests/detail_stage.rs#L328), [`core/dr-gpu/tests/local_contrast.rs:264`](../core/dr-gpu/tests/local_contrast.rs#L264), [`core/dr-gpu/tests/noise_reduction.rs:378`](../core/dr-gpu/tests/noise_reduction.rs#L378), [`core/dr-pipeline/src/detail.rs:136`](../core/dr-pipeline/src/detail.rs#L136), [`core/dr-pipeline/src/detail.rs:524`](../core/dr-pipeline/src/detail.rs#L524), [`core/dr-pipeline/src/graph.rs:548`](../core/dr-pipeline/src/graph.rs#L548), [`core/dr-pipeline/src/graph.rs:578`](../core/dr-pipeline/src/graph.rs#L578), [`core/dr-pipeline/src/ops/capture_sharpen.rs:1`](../core/dr-pipeline/src/ops/capture_sharpen.rs#L1), [`core/dr-pipeline/src/ops/capture_sharpen.rs:659`](../core/dr-pipeline/src/ops/capture_sharpen.rs#L659), [`core/dr-pipeline/src/ops/local_contrast.rs:1`](../core/dr-pipeline/src/ops/local_contrast.rs#L1), [`core/dr-pipeline/src/ops/local_contrast.rs:971`](../core/dr-pipeline/src/ops/local_contrast.rs#L971), [`core/dr-pipeline/src/ops/noise_reduction.rs:700`](../core/dr-pipeline/src/ops/noise_reduction.rs#L700), [`core/dr-pipeline/src/spot.rs:673`](../core/dr-pipeline/src/spot.rs#L673), [`ui/dr-ui/src/develop.rs:2843`](../ui/dr-ui/src/develop.rs#L2843), [`ui/dr-ui/src/develop.rs:4251`](../ui/dr-ui/src/develop.rs#L4251), [`ui/dr-ui/src/develop.rs:4734`](../ui/dr-ui/src/develop.rs#L4734), [`ui/dr-ui/src/develop.rs:4768`](../ui/dr-ui/src/develop.rs#L4768), [`ui/dr-ui/src/lib.rs:81`](../ui/dr-ui/src/lib.rs#L81), [`ui/dr-ui/src/lib.rs:835`](../ui/dr-ui/src/lib.rs#L835), [`ui/dr-ui/src/lib.rs:894`](../ui/dr-ui/src/lib.rs#L894) | | FR-DSP-3 | [`core/dr-gpu/tests/frame_budget.rs:101`](../core/dr-gpu/tests/frame_budget.rs#L101), [`core/dr-gpu/tests/local_contrast.rs:329`](../core/dr-gpu/tests/local_contrast.rs#L329), [`core/dr-pipeline/src/ops/local_contrast.rs:447`](../core/dr-pipeline/src/ops/local_contrast.rs#L447) | | FR-DSP-5 | [`core/dr-gpu/tests/frame_budget.rs:101`](../core/dr-gpu/tests/frame_budget.rs#L101), [`core/dr-gpu/tests/zoom_resolution.rs:135`](../core/dr-gpu/tests/zoom_resolution.rs#L135), [`core/dr-gpu/tests/zoom_resolution.rs:166`](../core/dr-gpu/tests/zoom_resolution.rs#L166), [`core/dr-gpu/tests/zoom_resolution.rs:1`](../core/dr-gpu/tests/zoom_resolution.rs#L1), [`core/dr-gpu/tests/zoom_resolution.rs:216`](../core/dr-gpu/tests/zoom_resolution.rs#L216) | -| FR-DSP-6 | [`core/dr-pipeline/src/operation.rs:483`](../core/dr-pipeline/src/operation.rs#L483), [`core/dr-types/src/colour.rs:1`](../core/dr-types/src/colour.rs#L1), [`ui/dr-ui/src/develop.rs:2873`](../ui/dr-ui/src/develop.rs#L2873), [`ui/dr-ui/src/develop.rs:6162`](../ui/dr-ui/src/develop.rs#L6162), [`ui/dr-ui/src/lib.rs:1555`](../ui/dr-ui/src/lib.rs#L1555), [`ui/dr-ui/src/lib.rs:3065`](../ui/dr-ui/src/lib.rs#L3065) | -| FR-DSP-7 | [`core/dr-gpu/src/histogram.rs:147`](../core/dr-gpu/src/histogram.rs#L147), [`core/dr-gpu/src/histogram.rs:1`](../core/dr-gpu/src/histogram.rs#L1), [`core/dr-gpu/src/histogram.rs:281`](../core/dr-gpu/src/histogram.rs#L281), [`core/dr-gpu/src/histogram.rs:50`](../core/dr-gpu/src/histogram.rs#L50), [`core/dr-gpu/src/shaders/histogram.wgsl:1`](../core/dr-gpu/src/shaders/histogram.wgsl#L1), [`ui/dr-ui/src/develop.rs:2922`](../ui/dr-ui/src/develop.rs#L2922), [`ui/dr-ui/src/develop.rs:5836`](../ui/dr-ui/src/develop.rs#L5836), [`ui/dr-ui/src/develop.rs:5868`](../ui/dr-ui/src/develop.rs#L5868), [`ui/dr-ui/src/develop.rs:720`](../ui/dr-ui/src/develop.rs#L720), [`ui/dr-ui/src/histogram.rs:1`](../ui/dr-ui/src/histogram.rs#L1), [`ui/dr-ui/src/lib.rs:1665`](../ui/dr-ui/src/lib.rs#L1665), [`ui/dr-ui/src/lib.rs:323`](../ui/dr-ui/src/lib.rs#L323), [`ui/dr-ui/ui/app.slint:72`](../ui/dr-ui/ui/app.slint#L72), [`ui/dr-ui/ui/histogram.slint:163`](../ui/dr-ui/ui/histogram.slint#L163), [`ui/dr-ui/ui/histogram.slint:1`](../ui/dr-ui/ui/histogram.slint#L1) | -| FR-DSP-8 | [`platform/dr-plat/src/display.rs:1`](../platform/dr-plat/src/display.rs#L1), [`platform/dr-plat/src/display/icc.rs:1`](../platform/dr-plat/src/display/icc.rs#L1), [`platform/dr-plat/src/display/wayland.rs:1`](../platform/dr-plat/src/display/wayland.rs#L1), [`platform/dr-plat/src/display/x11.rs:1`](../platform/dr-plat/src/display/x11.rs#L1), [`ui/dr-ui/src/develop.rs:2819`](../ui/dr-ui/src/develop.rs#L2819), [`ui/dr-ui/src/develop.rs:2873`](../ui/dr-ui/src/develop.rs#L2873), [`ui/dr-ui/src/develop.rs:6162`](../ui/dr-ui/src/develop.rs#L6162), [`ui/dr-ui/src/develop.rs:6208`](../ui/dr-ui/src/develop.rs#L6208), [`ui/dr-ui/src/develop.rs:6227`](../ui/dr-ui/src/develop.rs#L6227), [`ui/dr-ui/src/develop.rs:827`](../ui/dr-ui/src/develop.rs#L827), [`ui/dr-ui/src/display_ui.rs:192`](../ui/dr-ui/src/display_ui.rs#L192), [`ui/dr-ui/src/display_ui.rs:1`](../ui/dr-ui/src/display_ui.rs#L1), [`ui/dr-ui/src/display_ui.rs:325`](../ui/dr-ui/src/display_ui.rs#L325), [`ui/dr-ui/src/display_ui.rs:346`](../ui/dr-ui/src/display_ui.rs#L346), [`ui/dr-ui/src/display_ui.rs:379`](../ui/dr-ui/src/display_ui.rs#L379), [`ui/dr-ui/src/lib.rs:1516`](../ui/dr-ui/src/lib.rs#L1516), [`ui/dr-ui/src/lib.rs:1555`](../ui/dr-ui/src/lib.rs#L1555), [`ui/dr-ui/src/lib.rs:2978`](../ui/dr-ui/src/lib.rs#L2978), [`ui/dr-ui/src/lib.rs:3065`](../ui/dr-ui/src/lib.rs#L3065), [`ui/dr-ui/ui/app.slint:1696`](../ui/dr-ui/ui/app.slint#L1696), [`ui/dr-ui/ui/app.slint:51`](../ui/dr-ui/ui/app.slint#L51), [`ui/dr-ui/ui/settings.slint:124`](../ui/dr-ui/ui/settings.slint#L124), [`ui/dr-ui/ui/settings.slint:794`](../ui/dr-ui/ui/settings.slint#L794) | +| FR-DSP-6 | [`core/dr-pipeline/src/operation.rs:483`](../core/dr-pipeline/src/operation.rs#L483), [`core/dr-types/src/colour.rs:1`](../core/dr-types/src/colour.rs#L1), [`ui/dr-ui/src/develop.rs:2873`](../ui/dr-ui/src/develop.rs#L2873), [`ui/dr-ui/src/develop.rs:6162`](../ui/dr-ui/src/develop.rs#L6162), [`ui/dr-ui/src/lib.rs:1561`](../ui/dr-ui/src/lib.rs#L1561), [`ui/dr-ui/src/lib.rs:3071`](../ui/dr-ui/src/lib.rs#L3071) | +| FR-DSP-7 | [`core/dr-gpu/src/histogram.rs:147`](../core/dr-gpu/src/histogram.rs#L147), [`core/dr-gpu/src/histogram.rs:1`](../core/dr-gpu/src/histogram.rs#L1), [`core/dr-gpu/src/histogram.rs:281`](../core/dr-gpu/src/histogram.rs#L281), [`core/dr-gpu/src/histogram.rs:50`](../core/dr-gpu/src/histogram.rs#L50), [`core/dr-gpu/src/shaders/histogram.wgsl:1`](../core/dr-gpu/src/shaders/histogram.wgsl#L1), [`ui/dr-ui/src/develop.rs:2922`](../ui/dr-ui/src/develop.rs#L2922), [`ui/dr-ui/src/develop.rs:5836`](../ui/dr-ui/src/develop.rs#L5836), [`ui/dr-ui/src/develop.rs:5868`](../ui/dr-ui/src/develop.rs#L5868), [`ui/dr-ui/src/develop.rs:720`](../ui/dr-ui/src/develop.rs#L720), [`ui/dr-ui/src/histogram.rs:1`](../ui/dr-ui/src/histogram.rs#L1), [`ui/dr-ui/src/lib.rs:1671`](../ui/dr-ui/src/lib.rs#L1671), [`ui/dr-ui/src/lib.rs:329`](../ui/dr-ui/src/lib.rs#L329), [`ui/dr-ui/ui/app.slint:73`](../ui/dr-ui/ui/app.slint#L73), [`ui/dr-ui/ui/histogram.slint:167`](../ui/dr-ui/ui/histogram.slint#L167), [`ui/dr-ui/ui/histogram.slint:1`](../ui/dr-ui/ui/histogram.slint#L1) | +| FR-DSP-8 | [`platform/dr-plat/src/display.rs:1`](../platform/dr-plat/src/display.rs#L1), [`platform/dr-plat/src/display/icc.rs:1`](../platform/dr-plat/src/display/icc.rs#L1), [`platform/dr-plat/src/display/wayland.rs:1`](../platform/dr-plat/src/display/wayland.rs#L1), [`platform/dr-plat/src/display/x11.rs:1`](../platform/dr-plat/src/display/x11.rs#L1), [`ui/dr-ui/src/develop.rs:2819`](../ui/dr-ui/src/develop.rs#L2819), [`ui/dr-ui/src/develop.rs:2873`](../ui/dr-ui/src/develop.rs#L2873), [`ui/dr-ui/src/develop.rs:6162`](../ui/dr-ui/src/develop.rs#L6162), [`ui/dr-ui/src/develop.rs:6208`](../ui/dr-ui/src/develop.rs#L6208), [`ui/dr-ui/src/develop.rs:6227`](../ui/dr-ui/src/develop.rs#L6227), [`ui/dr-ui/src/develop.rs:827`](../ui/dr-ui/src/develop.rs#L827), [`ui/dr-ui/src/display_ui.rs:192`](../ui/dr-ui/src/display_ui.rs#L192), [`ui/dr-ui/src/display_ui.rs:1`](../ui/dr-ui/src/display_ui.rs#L1), [`ui/dr-ui/src/display_ui.rs:325`](../ui/dr-ui/src/display_ui.rs#L325), [`ui/dr-ui/src/display_ui.rs:346`](../ui/dr-ui/src/display_ui.rs#L346), [`ui/dr-ui/src/display_ui.rs:379`](../ui/dr-ui/src/display_ui.rs#L379), [`ui/dr-ui/src/lib.rs:1522`](../ui/dr-ui/src/lib.rs#L1522), [`ui/dr-ui/src/lib.rs:1561`](../ui/dr-ui/src/lib.rs#L1561), [`ui/dr-ui/src/lib.rs:2984`](../ui/dr-ui/src/lib.rs#L2984), [`ui/dr-ui/src/lib.rs:3071`](../ui/dr-ui/src/lib.rs#L3071), [`ui/dr-ui/ui/app.slint:1722`](../ui/dr-ui/ui/app.slint#L1722), [`ui/dr-ui/ui/app.slint:52`](../ui/dr-ui/ui/app.slint#L52), [`ui/dr-ui/ui/settings.slint:124`](../ui/dr-ui/ui/settings.slint#L124), [`ui/dr-ui/ui/settings.slint:794`](../ui/dr-ui/ui/settings.slint#L794) | | FR-EXP-1 | [`core/dr-export/src/encode.rs:1`](../core/dr-export/src/encode.rs#L1), [`core/dr-export/src/lib.rs:1`](../core/dr-export/src/lib.rs#L1), [`core/dr-types/src/settings.rs:1`](../core/dr-types/src/settings.rs#L1), [`ui/dr-ui/src/settings_ui.rs:1`](../ui/dr-ui/src/settings_ui.rs#L1) | | FR-EXP-2 | [`core/dr-export/src/encode.rs:1`](../core/dr-export/src/encode.rs#L1), [`core/dr-export/src/error.rs:26`](../core/dr-export/src/error.rs#L26), [`core/dr-export/src/icc.rs:1`](../core/dr-export/src/icc.rs#L1), [`core/dr-export/src/lib.rs:153`](../core/dr-export/src/lib.rs#L153), [`core/dr-export/src/lib.rs:1`](../core/dr-export/src/lib.rs#L1), [`core/dr-export/src/lib.rs:53`](../core/dr-export/src/lib.rs#L53), [`core/dr-gpu/src/adjust.rs:2436`](../core/dr-gpu/src/adjust.rs#L2436), [`core/dr-pipeline/src/graph.rs:538`](../core/dr-pipeline/src/graph.rs#L538), [`core/dr-pipeline/src/graph.rs:592`](../core/dr-pipeline/src/graph.rs#L592), [`core/dr-pipeline/src/operation.rs:483`](../core/dr-pipeline/src/operation.rs#L483), [`core/dr-types/src/colour.rs:1`](../core/dr-types/src/colour.rs#L1), [`core/dr-types/src/settings.rs:1`](../core/dr-types/src/settings.rs#L1), [`core/dr-types/src/settings.rs:713`](../core/dr-types/src/settings.rs#L713), [`ui/dr-ui/src/develop.rs:6227`](../ui/dr-ui/src/develop.rs#L6227), [`ui/dr-ui/src/settings_ui.rs:1`](../ui/dr-ui/src/settings_ui.rs#L1) | | FR-EXP-3 | [`core/dr-export/src/lib.rs:182`](../core/dr-export/src/lib.rs#L182), [`core/dr-export/src/lib.rs:1`](../core/dr-export/src/lib.rs#L1), [`core/dr-export/src/size.rs:136`](../core/dr-export/src/size.rs#L136), [`core/dr-export/src/size.rs:1`](../core/dr-export/src/size.rs#L1), [`core/dr-export/src/size.rs:25`](../core/dr-export/src/size.rs#L25), [`core/dr-export/src/size.rs:84`](../core/dr-export/src/size.rs#L84), [`core/dr-types/src/settings.rs:1`](../core/dr-types/src/settings.rs#L1), [`core/dr-types/src/settings.rs:758`](../core/dr-types/src/settings.rs#L758), [`core/dr-types/src/settings.rs:766`](../core/dr-types/src/settings.rs#L766), [`core/dr-types/src/settings.rs:782`](../core/dr-types/src/settings.rs#L782), [`core/dr-types/src/settings.rs:851`](../core/dr-types/src/settings.rs#L851), [`core/dr-types/src/settings.rs:879`](../core/dr-types/src/settings.rs#L879), [`core/dr-types/src/settings.rs:890`](../core/dr-types/src/settings.rs#L890), [`core/dr-types/src/settings.rs:896`](../core/dr-types/src/settings.rs#L896), [`ui/dr-ui/src/settings_ui.rs:1`](../ui/dr-ui/src/settings_ui.rs#L1), [`ui/dr-ui/src/settings_ui.rs:207`](../ui/dr-ui/src/settings_ui.rs#L207), [`ui/dr-ui/src/settings_ui.rs:220`](../ui/dr-ui/src/settings_ui.rs#L220), [`ui/dr-ui/src/settings_ui.rs:235`](../ui/dr-ui/src/settings_ui.rs#L235), [`ui/dr-ui/src/settings_ui.rs:565`](../ui/dr-ui/src/settings_ui.rs#L565), [`ui/dr-ui/ui/settings.slint:697`](../ui/dr-ui/ui/settings.slint#L697), [`ui/dr-ui/ui/settings.slint:707`](../ui/dr-ui/ui/settings.slint#L707) | | FR-EXP-4 | [`core/dr-export/src/lib.rs:1`](../core/dr-export/src/lib.rs#L1), [`core/dr-export/src/sharpen.rs:1`](../core/dr-export/src/sharpen.rs#L1), [`core/dr-export/src/size.rs:1`](../core/dr-export/src/size.rs#L1), [`ui/dr-ui/src/settings_ui.rs:1`](../ui/dr-ui/src/settings_ui.rs#L1) | | FR-EXP-5 | [`ui/dr-ui/src/settings_store.rs:1`](../ui/dr-ui/src/settings_store.rs#L1) | -| FR-EXP-6 | [`core/dr-export/src/lib.rs:1`](../core/dr-export/src/lib.rs#L1), [`core/dr-export/src/name.rs:1`](../core/dr-export/src/name.rs#L1), [`core/dr-types/src/settings.rs:1`](../core/dr-types/src/settings.rs#L1), [`ui/dr-ui/src/export.rs:1`](../ui/dr-ui/src/export.rs#L1), [`ui/dr-ui/src/lib.rs:434`](../ui/dr-ui/src/lib.rs#L434), [`ui/dr-ui/src/settings_ui.rs:1`](../ui/dr-ui/src/settings_ui.rs#L1), [`ui/dr-ui/src/settings_ui.rs:49`](../ui/dr-ui/src/settings_ui.rs#L49), [`ui/dr-ui/src/settings_ui.rs:679`](../ui/dr-ui/src/settings_ui.rs#L679) | -| FR-EXP-7 | [`ui/dr-ui/src/activity.rs:83`](../ui/dr-ui/src/activity.rs#L83), [`ui/dr-ui/src/export.rs:1`](../ui/dr-ui/src/export.rs#L1), [`ui/dr-ui/src/export.rs:942`](../ui/dr-ui/src/export.rs#L942), [`ui/dr-ui/src/lib.rs:213`](../ui/dr-ui/src/lib.rs#L213), [`ui/dr-ui/src/lib.rs:2310`](../ui/dr-ui/src/lib.rs#L2310), [`ui/dr-ui/src/lib.rs:434`](../ui/dr-ui/src/lib.rs#L434), [`ui/dr-ui/src/lib.rs:469`](../ui/dr-ui/src/lib.rs#L469), [`ui/dr-ui/src/lib.rs:496`](../ui/dr-ui/src/lib.rs#L496), [`ui/dr-ui/src/library_ui.rs:3479`](../ui/dr-ui/src/library_ui.rs#L3479), [`ui/dr-ui/src/library_ui.rs:585`](../ui/dr-ui/src/library_ui.rs#L585), [`ui/dr-ui/src/library_ui.rs:6658`](../ui/dr-ui/src/library_ui.rs#L6658), [`ui/dr-ui/src/library_ui.rs:6735`](../ui/dr-ui/src/library_ui.rs#L6735), [`ui/dr-ui/src/library_ui.rs:6747`](../ui/dr-ui/src/library_ui.rs#L6747), [`ui/dr-ui/src/library_ui.rs:685`](../ui/dr-ui/src/library_ui.rs#L685), [`ui/dr-ui/src/library_ui.rs:742`](../ui/dr-ui/src/library_ui.rs#L742), [`ui/dr-ui/ui/app.slint:1063`](../ui/dr-ui/ui/app.slint#L1063), [`ui/dr-ui/ui/app.slint:1533`](../ui/dr-ui/ui/app.slint#L1533), [`ui/dr-ui/ui/library.slint:1505`](../ui/dr-ui/ui/library.slint#L1505), [`ui/dr-ui/ui/library.slint:854`](../ui/dr-ui/ui/library.slint#L854), [`ui/dr-ui/ui/library.slint:967`](../ui/dr-ui/ui/library.slint#L967) | +| FR-EXP-6 | [`core/dr-export/src/lib.rs:1`](../core/dr-export/src/lib.rs#L1), [`core/dr-export/src/name.rs:1`](../core/dr-export/src/name.rs#L1), [`core/dr-types/src/settings.rs:1`](../core/dr-types/src/settings.rs#L1), [`ui/dr-ui/src/export.rs:1`](../ui/dr-ui/src/export.rs#L1), [`ui/dr-ui/src/lib.rs:440`](../ui/dr-ui/src/lib.rs#L440), [`ui/dr-ui/src/settings_ui.rs:1`](../ui/dr-ui/src/settings_ui.rs#L1), [`ui/dr-ui/src/settings_ui.rs:49`](../ui/dr-ui/src/settings_ui.rs#L49), [`ui/dr-ui/src/settings_ui.rs:679`](../ui/dr-ui/src/settings_ui.rs#L679) | +| FR-EXP-7 | [`ui/dr-ui/src/activity.rs:83`](../ui/dr-ui/src/activity.rs#L83), [`ui/dr-ui/src/export.rs:1`](../ui/dr-ui/src/export.rs#L1), [`ui/dr-ui/src/export.rs:942`](../ui/dr-ui/src/export.rs#L942), [`ui/dr-ui/src/lib.rs:219`](../ui/dr-ui/src/lib.rs#L219), [`ui/dr-ui/src/lib.rs:2316`](../ui/dr-ui/src/lib.rs#L2316), [`ui/dr-ui/src/lib.rs:440`](../ui/dr-ui/src/lib.rs#L440), [`ui/dr-ui/src/lib.rs:475`](../ui/dr-ui/src/lib.rs#L475), [`ui/dr-ui/src/lib.rs:502`](../ui/dr-ui/src/lib.rs#L502), [`ui/dr-ui/src/library_ui.rs:3479`](../ui/dr-ui/src/library_ui.rs#L3479), [`ui/dr-ui/src/library_ui.rs:585`](../ui/dr-ui/src/library_ui.rs#L585), [`ui/dr-ui/src/library_ui.rs:6658`](../ui/dr-ui/src/library_ui.rs#L6658), [`ui/dr-ui/src/library_ui.rs:6735`](../ui/dr-ui/src/library_ui.rs#L6735), [`ui/dr-ui/src/library_ui.rs:6747`](../ui/dr-ui/src/library_ui.rs#L6747), [`ui/dr-ui/src/library_ui.rs:685`](../ui/dr-ui/src/library_ui.rs#L685), [`ui/dr-ui/src/library_ui.rs:742`](../ui/dr-ui/src/library_ui.rs#L742), [`ui/dr-ui/ui/app.slint:1064`](../ui/dr-ui/ui/app.slint#L1064), [`ui/dr-ui/ui/app.slint:1534`](../ui/dr-ui/ui/app.slint#L1534), [`ui/dr-ui/ui/library.slint:1505`](../ui/dr-ui/ui/library.slint#L1505), [`ui/dr-ui/ui/library.slint:854`](../ui/dr-ui/ui/library.slint#L854), [`ui/dr-ui/ui/library.slint:967`](../ui/dr-ui/ui/library.slint#L967) | | FR-EXP-8 | [`core/dr-decode/src/lib.rs:326`](../core/dr-decode/src/lib.rs#L326), [`core/dr-decode/src/lib.rs:350`](../core/dr-decode/src/lib.rs#L350), [`core/dr-decode/src/lib.rs:364`](../core/dr-decode/src/lib.rs#L364), [`core/dr-decode/src/lib.rs:71`](../core/dr-decode/src/lib.rs#L71), [`core/dr-decode/src/lib.rs:79`](../core/dr-decode/src/lib.rs#L79), [`core/dr-decode/src/lib.rs:82`](../core/dr-decode/src/lib.rs#L82), [`core/dr-decode/src/locate.rs:1164`](../core/dr-decode/src/locate.rs#L1164), [`core/dr-decode/src/locate.rs:1223`](../core/dr-decode/src/locate.rs#L1223), [`core/dr-decode/src/locate.rs:316`](../core/dr-decode/src/locate.rs#L316), [`core/dr-decode/src/locate.rs:487`](../core/dr-decode/src/locate.rs#L487), [`core/dr-decode/src/locate.rs:571`](../core/dr-decode/src/locate.rs#L571), [`core/dr-decode/src/locate.rs:584`](../core/dr-decode/src/locate.rs#L584), [`core/dr-decode/src/locate.rs:667`](../core/dr-decode/src/locate.rs#L667), [`core/dr-export/examples/export.rs:99`](../core/dr-export/examples/export.rs#L99), [`core/dr-export/src/encode.rs:117`](../core/dr-export/src/encode.rs#L117), [`core/dr-export/src/encode.rs:161`](../core/dr-export/src/encode.rs#L161), [`core/dr-export/src/encode.rs:1`](../core/dr-export/src/encode.rs#L1), [`core/dr-export/src/encode.rs:206`](../core/dr-export/src/encode.rs#L206), [`core/dr-export/src/encode.rs:235`](../core/dr-export/src/encode.rs#L235), [`core/dr-export/src/encode.rs:311`](../core/dr-export/src/encode.rs#L311), [`core/dr-export/src/encode.rs:325`](../core/dr-export/src/encode.rs#L325), [`core/dr-export/src/encode.rs:408`](../core/dr-export/src/encode.rs#L408), [`core/dr-export/src/encode.rs:456`](../core/dr-export/src/encode.rs#L456), [`core/dr-export/src/encode.rs:70`](../core/dr-export/src/encode.rs#L70), [`core/dr-export/src/encode.rs:795`](../core/dr-export/src/encode.rs#L795), [`core/dr-export/src/encode.rs:809`](../core/dr-export/src/encode.rs#L809), [`core/dr-export/src/encode.rs:850`](../core/dr-export/src/encode.rs#L850), [`core/dr-export/src/encode.rs:898`](../core/dr-export/src/encode.rs#L898), [`core/dr-export/src/exif.rs:1`](../core/dr-export/src/exif.rs#L1), [`core/dr-export/src/lib.rs:136`](../core/dr-export/src/lib.rs#L136), [`core/dr-export/src/metadata.rs:1`](../core/dr-export/src/metadata.rs#L1), [`core/dr-export/src/metadata.rs:41`](../core/dr-export/src/metadata.rs#L41), [`core/dr-export/src/metadata.rs:74`](../core/dr-export/src/metadata.rs#L74), [`core/dr-types/src/lib.rs:653`](../core/dr-types/src/lib.rs#L653), [`core/dr-types/src/settings.rs:426`](../core/dr-types/src/settings.rs#L426), [`ui/dr-ui/src/export.rs:619`](../ui/dr-ui/src/export.rs#L619), [`ui/dr-ui/src/export.rs:647`](../ui/dr-ui/src/export.rs#L647), [`ui/dr-ui/src/export.rs:777`](../ui/dr-ui/src/export.rs#L777), [`ui/dr-ui/src/export.rs:794`](../ui/dr-ui/src/export.rs#L794), [`ui/dr-ui/src/settings_ui.rs:1`](../ui/dr-ui/src/settings_ui.rs#L1) | -| FR-EXP-9 | [`core/dr-decode/src/lib.rs:506`](../core/dr-decode/src/lib.rs#L506), [`core/dr-export/src/lib.rs:128`](../core/dr-export/src/lib.rs#L128), [`core/dr-export/src/lib.rs:1`](../core/dr-export/src/lib.rs#L1), [`core/dr-gpu/src/adjust.rs:1106`](../core/dr-gpu/src/adjust.rs#L1106), [`ui/dr-ui/src/develop.rs:3188`](../ui/dr-ui/src/develop.rs#L3188), [`ui/dr-ui/src/lib.rs:434`](../ui/dr-ui/src/lib.rs#L434) | +| FR-EXP-9 | [`core/dr-decode/src/lib.rs:506`](../core/dr-decode/src/lib.rs#L506), [`core/dr-export/src/lib.rs:128`](../core/dr-export/src/lib.rs#L128), [`core/dr-export/src/lib.rs:1`](../core/dr-export/src/lib.rs#L1), [`core/dr-gpu/src/adjust.rs:1106`](../core/dr-gpu/src/adjust.rs#L1106), [`ui/dr-ui/src/develop.rs:3188`](../ui/dr-ui/src/develop.rs#L3188), [`ui/dr-ui/src/lib.rs:440`](../ui/dr-ui/src/lib.rs#L440) | | FR-NC-1 | [`core/dr-sync-nextcloud/src/auth.rs:132`](../core/dr-sync-nextcloud/src/auth.rs#L132), [`core/dr-sync-nextcloud/src/auth.rs:44`](../core/dr-sync-nextcloud/src/auth.rs#L44), [`core/dr-sync-nextcloud/src/provider.rs:1`](../core/dr-sync-nextcloud/src/provider.rs#L1), [`core/dr-sync/src/account.rs:355`](../core/dr-sync/src/account.rs#L355), [`ui/dr-ui/src/launch.rs:277`](../ui/dr-ui/src/launch.rs#L277), [`ui/dr-ui/src/launch.rs:61`](../ui/dr-ui/src/launch.rs#L61), [`ui/dr-ui/src/launch_ui.rs:417`](../ui/dr-ui/src/launch_ui.rs#L417) | -| FR-NC-10 | [`core/dr-sync/src/account.rs:220`](../core/dr-sync/src/account.rs#L220), [`ui/dr-ui/src/export.rs:1`](../ui/dr-ui/src/export.rs#L1), [`ui/dr-ui/src/lib.rs:496`](../ui/dr-ui/src/lib.rs#L496), [`ui/dr-ui/src/library.rs:1101`](../ui/dr-ui/src/library.rs#L1101), [`ui/dr-ui/src/library.rs:1939`](../ui/dr-ui/src/library.rs#L1939), [`ui/dr-ui/src/library.rs:576`](../ui/dr-ui/src/library.rs#L576), [`ui/dr-ui/src/library.rs:877`](../ui/dr-ui/src/library.rs#L877), [`ui/dr-ui/src/library_ui.rs:1696`](../ui/dr-ui/src/library_ui.rs#L1696), [`ui/dr-ui/src/library_ui.rs:3479`](../ui/dr-ui/src/library_ui.rs#L3479), [`ui/dr-ui/src/library_ui.rs:526`](../ui/dr-ui/src/library_ui.rs#L526), [`ui/dr-ui/src/sidecar_cache.rs:1`](../ui/dr-ui/src/sidecar_cache.rs#L1) | +| FR-NC-10 | [`core/dr-sync/src/account.rs:220`](../core/dr-sync/src/account.rs#L220), [`ui/dr-ui/src/export.rs:1`](../ui/dr-ui/src/export.rs#L1), [`ui/dr-ui/src/lib.rs:502`](../ui/dr-ui/src/lib.rs#L502), [`ui/dr-ui/src/library.rs:1101`](../ui/dr-ui/src/library.rs#L1101), [`ui/dr-ui/src/library.rs:1939`](../ui/dr-ui/src/library.rs#L1939), [`ui/dr-ui/src/library.rs:576`](../ui/dr-ui/src/library.rs#L576), [`ui/dr-ui/src/library.rs:877`](../ui/dr-ui/src/library.rs#L877), [`ui/dr-ui/src/library_ui.rs:1696`](../ui/dr-ui/src/library_ui.rs#L1696), [`ui/dr-ui/src/library_ui.rs:3479`](../ui/dr-ui/src/library_ui.rs#L3479), [`ui/dr-ui/src/library_ui.rs:526`](../ui/dr-ui/src/library_ui.rs#L526), [`ui/dr-ui/src/sidecar_cache.rs:1`](../ui/dr-ui/src/sidecar_cache.rs#L1) | | FR-NC-12 | [`core/dr-sync-folder/src/lib.rs:1`](../core/dr-sync-folder/src/lib.rs#L1), [`core/dr-sync-nextcloud/src/lib.rs:40`](../core/dr-sync-nextcloud/src/lib.rs#L40), [`core/dr-sync-nextcloud/src/lib.rs:914`](../core/dr-sync-nextcloud/src/lib.rs#L914), [`core/dr-sync-nextcloud/src/provider.rs:1`](../core/dr-sync-nextcloud/src/provider.rs#L1), [`core/dr-sync/src/account.rs:1`](../core/dr-sync/src/account.rs#L1), [`core/dr-sync/src/account.rs:81`](../core/dr-sync/src/account.rs#L81), [`core/dr-sync/src/lib.rs:218`](../core/dr-sync/src/lib.rs#L218), [`core/dr-sync/src/lib.rs:51`](../core/dr-sync/src/lib.rs#L51), [`core/dr-sync/src/provider.rs:106`](../core/dr-sync/src/provider.rs#L106), [`core/dr-sync/src/provider.rs:1`](../core/dr-sync/src/provider.rs#L1), [`core/dr-sync/src/provider.rs:53`](../core/dr-sync/src/provider.rs#L53), [`core/dr-sync/src/reachability.rs:1`](../core/dr-sync/src/reachability.rs#L1), [`ui/dr-ui/src/remote.rs:1`](../ui/dr-ui/src/remote.rs#L1) | | FR-NC-13 | [`core/dr-sync-folder/src/lib.rs:197`](../core/dr-sync-folder/src/lib.rs#L197), [`core/dr-sync-folder/src/lib.rs:1`](../core/dr-sync-folder/src/lib.rs#L1), [`core/dr-sync-folder/src/lib.rs:73`](../core/dr-sync-folder/src/lib.rs#L73), [`core/dr-sync/src/provider.rs:106`](../core/dr-sync/src/provider.rs#L106), [`ui/dr-ui/src/launch_ui.rs:316`](../ui/dr-ui/src/launch_ui.rs#L316), [`ui/dr-ui/src/remote.rs:1`](../ui/dr-ui/src/remote.rs#L1) | | FR-NC-2 | [`core/dr-sync/src/account.rs:1`](../core/dr-sync/src/account.rs#L1), [`core/dr-sync/src/account.rs:298`](../core/dr-sync/src/account.rs#L298), [`core/dr-sync/src/account.rs:355`](../core/dr-sync/src/account.rs#L355), [`core/dr-sync/src/account.rs:59`](../core/dr-sync/src/account.rs#L59), [`platform/dr-plat/src/secrets.rs:82`](../platform/dr-plat/src/secrets.rs#L82) | -| FR-NC-3 | [`core/dr-decode/src/locate.rs:1`](../core/dr-decode/src/locate.rs#L1), [`core/dr-decode/src/preview.rs:148`](../core/dr-decode/src/preview.rs#L148), [`core/dr-sync/src/capability.rs:85`](../core/dr-sync/src/capability.rs#L85), [`core/dr-thumbs/src/lib.rs:1`](../core/dr-thumbs/src/lib.rs#L1), [`ui/dr-ui/src/library.rs:1`](../ui/dr-ui/src/library.rs#L1), [`ui/dr-ui/src/library.rs:2964`](../ui/dr-ui/src/library.rs#L2964), [`ui/dr-ui/src/library.rs:3472`](../ui/dr-ui/src/library.rs#L3472), [`ui/dr-ui/src/library_ui.rs:1`](../ui/dr-ui/src/library_ui.rs#L1), [`ui/dr-ui/src/library_ui.rs:3731`](../ui/dr-ui/src/library_ui.rs#L3731), [`ui/dr-ui/src/library_ui.rs:4749`](../ui/dr-ui/src/library_ui.rs#L4749), [`ui/dr-ui/ui/app.slint:386`](../ui/dr-ui/ui/app.slint#L386), [`ui/dr-ui/ui/settings.slint:387`](../ui/dr-ui/ui/settings.slint#L387), [`ui/dr-ui/ui/settings.slint:73`](../ui/dr-ui/ui/settings.slint#L73) | +| FR-NC-3 | [`core/dr-decode/src/locate.rs:1`](../core/dr-decode/src/locate.rs#L1), [`core/dr-decode/src/preview.rs:148`](../core/dr-decode/src/preview.rs#L148), [`core/dr-sync/src/capability.rs:85`](../core/dr-sync/src/capability.rs#L85), [`core/dr-thumbs/src/lib.rs:1`](../core/dr-thumbs/src/lib.rs#L1), [`ui/dr-ui/src/library.rs:1`](../ui/dr-ui/src/library.rs#L1), [`ui/dr-ui/src/library.rs:2964`](../ui/dr-ui/src/library.rs#L2964), [`ui/dr-ui/src/library.rs:3472`](../ui/dr-ui/src/library.rs#L3472), [`ui/dr-ui/src/library_ui.rs:1`](../ui/dr-ui/src/library_ui.rs#L1), [`ui/dr-ui/src/library_ui.rs:3731`](../ui/dr-ui/src/library_ui.rs#L3731), [`ui/dr-ui/src/library_ui.rs:4749`](../ui/dr-ui/src/library_ui.rs#L4749), [`ui/dr-ui/ui/app.slint:387`](../ui/dr-ui/ui/app.slint#L387), [`ui/dr-ui/ui/settings.slint:387`](../ui/dr-ui/ui/settings.slint#L387), [`ui/dr-ui/ui/settings.slint:73`](../ui/dr-ui/ui/settings.slint#L73) | | FR-NC-4 | [`core/dr-sync-folder/src/lib.rs:197`](../core/dr-sync-folder/src/lib.rs#L197), [`core/dr-sync-nextcloud/src/propfind.rs:103`](../core/dr-sync-nextcloud/src/propfind.rs#L103), [`core/dr-sync-nextcloud/src/propfind.rs:51`](../core/dr-sync-nextcloud/src/propfind.rs#L51), [`core/dr-sync/src/capability.rs:6`](../core/dr-sync/src/capability.rs#L6), [`core/dr-sync/src/lib.rs:218`](../core/dr-sync/src/lib.rs#L218), [`core/dr-sync/src/scan.rs:93`](../core/dr-sync/src/scan.rs#L93), [`ui/dr-ui/src/launch.rs:61`](../ui/dr-ui/src/launch.rs#L61) | | FR-NC-5 | [`core/dr-sync-nextcloud/src/propfind.rs:51`](../core/dr-sync-nextcloud/src/propfind.rs#L51), [`ui/dr-ui/src/import.rs:488`](../ui/dr-ui/src/import.rs#L488) | | FR-NC-6 | [`ui/dr-ui/src/activity.rs:1`](../ui/dr-ui/src/activity.rs#L1) | -| FR-NC-6a | [`core/dr-catalog/src/cache.rs:1`](../core/dr-catalog/src/cache.rs#L1), [`core/dr-catalog/src/cache.rs:225`](../core/dr-catalog/src/cache.rs#L225), [`core/dr-catalog/src/schema.rs:1093`](../core/dr-catalog/src/schema.rs#L1093), [`core/dr-catalog/src/schema.rs:692`](../core/dr-catalog/src/schema.rs#L692), [`core/dr-sync-folder/src/borrow.rs:1`](../core/dr-sync-folder/src/borrow.rs#L1), [`core/dr-types/src/selector.rs:1`](../core/dr-types/src/selector.rs#L1), [`core/dr-types/src/settings.rs:1`](../core/dr-types/src/settings.rs#L1), [`ui/dr-ui/src/collections_ui.rs:3255`](../ui/dr-ui/src/collections_ui.rs#L3255), [`ui/dr-ui/src/collections_ui.rs:599`](../ui/dr-ui/src/collections_ui.rs#L599), [`ui/dr-ui/src/collections_ui.rs:667`](../ui/dr-ui/src/collections_ui.rs#L667), [`ui/dr-ui/src/lib.rs:2014`](../ui/dr-ui/src/lib.rs#L2014), [`ui/dr-ui/src/lib.rs:3128`](../ui/dr-ui/src/lib.rs#L3128), [`ui/dr-ui/src/library.rs:1565`](../ui/dr-ui/src/library.rs#L1565), [`ui/dr-ui/src/library.rs:1588`](../ui/dr-ui/src/library.rs#L1588), [`ui/dr-ui/src/library.rs:1863`](../ui/dr-ui/src/library.rs#L1863), [`ui/dr-ui/src/library_ui.rs:1121`](../ui/dr-ui/src/library_ui.rs#L1121), [`ui/dr-ui/src/library_ui.rs:1194`](../ui/dr-ui/src/library_ui.rs#L1194), [`ui/dr-ui/src/library_ui.rs:1295`](../ui/dr-ui/src/library_ui.rs#L1295), [`ui/dr-ui/src/library_ui.rs:1350`](../ui/dr-ui/src/library_ui.rs#L1350), [`ui/dr-ui/src/library_ui.rs:1485`](../ui/dr-ui/src/library_ui.rs#L1485), [`ui/dr-ui/src/library_ui.rs:1603`](../ui/dr-ui/src/library_ui.rs#L1603), [`ui/dr-ui/src/library_ui.rs:2171`](../ui/dr-ui/src/library_ui.rs#L2171), [`ui/dr-ui/src/library_ui.rs:289`](../ui/dr-ui/src/library_ui.rs#L289), [`ui/dr-ui/src/library_ui.rs:300`](../ui/dr-ui/src/library_ui.rs#L300), [`ui/dr-ui/src/library_ui.rs:308`](../ui/dr-ui/src/library_ui.rs#L308), [`ui/dr-ui/src/library_ui.rs:320`](../ui/dr-ui/src/library_ui.rs#L320), [`ui/dr-ui/src/library_ui.rs:329`](../ui/dr-ui/src/library_ui.rs#L329), [`ui/dr-ui/src/library_ui.rs:422`](../ui/dr-ui/src/library_ui.rs#L422), [`ui/dr-ui/src/library_ui.rs:432`](../ui/dr-ui/src/library_ui.rs#L432), [`ui/dr-ui/src/library_ui.rs:479`](../ui/dr-ui/src/library_ui.rs#L479), [`ui/dr-ui/src/library_ui.rs:542`](../ui/dr-ui/src/library_ui.rs#L542), [`ui/dr-ui/src/library_ui.rs:5531`](../ui/dr-ui/src/library_ui.rs#L5531), [`ui/dr-ui/src/library_ui.rs:5549`](../ui/dr-ui/src/library_ui.rs#L5549), [`ui/dr-ui/src/library_ui.rs:5561`](../ui/dr-ui/src/library_ui.rs#L5561), [`ui/dr-ui/src/library_ui.rs:573`](../ui/dr-ui/src/library_ui.rs#L573), [`ui/dr-ui/src/library_ui.rs:585`](../ui/dr-ui/src/library_ui.rs#L585), [`ui/dr-ui/src/settings_store.rs:1`](../ui/dr-ui/src/settings_store.rs#L1), [`ui/dr-ui/src/settings_ui.rs:1`](../ui/dr-ui/src/settings_ui.rs#L1), [`ui/dr-ui/ui/app.slint:2560`](../ui/dr-ui/ui/app.slint#L2560), [`ui/dr-ui/ui/app.slint:510`](../ui/dr-ui/ui/app.slint#L510), [`ui/dr-ui/ui/collections.slint:249`](../ui/dr-ui/ui/collections.slint#L249), [`ui/dr-ui/ui/collections.slint:369`](../ui/dr-ui/ui/collections.slint#L369), [`ui/dr-ui/ui/collections.slint:52`](../ui/dr-ui/ui/collections.slint#L52), [`ui/dr-ui/ui/collections.slint:682`](../ui/dr-ui/ui/collections.slint#L682), [`ui/dr-ui/ui/collections.slint:84`](../ui/dr-ui/ui/collections.slint#L84), [`ui/dr-ui/ui/icons.slint:260`](../ui/dr-ui/ui/icons.slint#L260), [`ui/dr-ui/ui/library.slint:1013`](../ui/dr-ui/ui/library.slint#L1013) | +| FR-NC-6a | [`core/dr-catalog/src/cache.rs:1`](../core/dr-catalog/src/cache.rs#L1), [`core/dr-catalog/src/cache.rs:225`](../core/dr-catalog/src/cache.rs#L225), [`core/dr-catalog/src/schema.rs:1093`](../core/dr-catalog/src/schema.rs#L1093), [`core/dr-catalog/src/schema.rs:692`](../core/dr-catalog/src/schema.rs#L692), [`core/dr-sync-folder/src/borrow.rs:1`](../core/dr-sync-folder/src/borrow.rs#L1), [`core/dr-types/src/selector.rs:1`](../core/dr-types/src/selector.rs#L1), [`core/dr-types/src/settings.rs:1`](../core/dr-types/src/settings.rs#L1), [`ui/dr-ui/src/collections_ui.rs:3255`](../ui/dr-ui/src/collections_ui.rs#L3255), [`ui/dr-ui/src/collections_ui.rs:599`](../ui/dr-ui/src/collections_ui.rs#L599), [`ui/dr-ui/src/collections_ui.rs:667`](../ui/dr-ui/src/collections_ui.rs#L667), [`ui/dr-ui/src/lib.rs:2020`](../ui/dr-ui/src/lib.rs#L2020), [`ui/dr-ui/src/lib.rs:3134`](../ui/dr-ui/src/lib.rs#L3134), [`ui/dr-ui/src/library.rs:1565`](../ui/dr-ui/src/library.rs#L1565), [`ui/dr-ui/src/library.rs:1588`](../ui/dr-ui/src/library.rs#L1588), [`ui/dr-ui/src/library.rs:1863`](../ui/dr-ui/src/library.rs#L1863), [`ui/dr-ui/src/library_ui.rs:1121`](../ui/dr-ui/src/library_ui.rs#L1121), [`ui/dr-ui/src/library_ui.rs:1194`](../ui/dr-ui/src/library_ui.rs#L1194), [`ui/dr-ui/src/library_ui.rs:1295`](../ui/dr-ui/src/library_ui.rs#L1295), [`ui/dr-ui/src/library_ui.rs:1350`](../ui/dr-ui/src/library_ui.rs#L1350), [`ui/dr-ui/src/library_ui.rs:1485`](../ui/dr-ui/src/library_ui.rs#L1485), [`ui/dr-ui/src/library_ui.rs:1603`](../ui/dr-ui/src/library_ui.rs#L1603), [`ui/dr-ui/src/library_ui.rs:2171`](../ui/dr-ui/src/library_ui.rs#L2171), [`ui/dr-ui/src/library_ui.rs:289`](../ui/dr-ui/src/library_ui.rs#L289), [`ui/dr-ui/src/library_ui.rs:300`](../ui/dr-ui/src/library_ui.rs#L300), [`ui/dr-ui/src/library_ui.rs:308`](../ui/dr-ui/src/library_ui.rs#L308), [`ui/dr-ui/src/library_ui.rs:320`](../ui/dr-ui/src/library_ui.rs#L320), [`ui/dr-ui/src/library_ui.rs:329`](../ui/dr-ui/src/library_ui.rs#L329), [`ui/dr-ui/src/library_ui.rs:422`](../ui/dr-ui/src/library_ui.rs#L422), [`ui/dr-ui/src/library_ui.rs:432`](../ui/dr-ui/src/library_ui.rs#L432), [`ui/dr-ui/src/library_ui.rs:479`](../ui/dr-ui/src/library_ui.rs#L479), [`ui/dr-ui/src/library_ui.rs:542`](../ui/dr-ui/src/library_ui.rs#L542), [`ui/dr-ui/src/library_ui.rs:5531`](../ui/dr-ui/src/library_ui.rs#L5531), [`ui/dr-ui/src/library_ui.rs:5549`](../ui/dr-ui/src/library_ui.rs#L5549), [`ui/dr-ui/src/library_ui.rs:5561`](../ui/dr-ui/src/library_ui.rs#L5561), [`ui/dr-ui/src/library_ui.rs:573`](../ui/dr-ui/src/library_ui.rs#L573), [`ui/dr-ui/src/library_ui.rs:585`](../ui/dr-ui/src/library_ui.rs#L585), [`ui/dr-ui/src/settings_store.rs:1`](../ui/dr-ui/src/settings_store.rs#L1), [`ui/dr-ui/src/settings_ui.rs:1`](../ui/dr-ui/src/settings_ui.rs#L1), [`ui/dr-ui/ui/app.slint:2618`](../ui/dr-ui/ui/app.slint#L2618), [`ui/dr-ui/ui/app.slint:511`](../ui/dr-ui/ui/app.slint#L511), [`ui/dr-ui/ui/collections.slint:249`](../ui/dr-ui/ui/collections.slint#L249), [`ui/dr-ui/ui/collections.slint:369`](../ui/dr-ui/ui/collections.slint#L369), [`ui/dr-ui/ui/collections.slint:52`](../ui/dr-ui/ui/collections.slint#L52), [`ui/dr-ui/ui/collections.slint:682`](../ui/dr-ui/ui/collections.slint#L682), [`ui/dr-ui/ui/collections.slint:84`](../ui/dr-ui/ui/collections.slint#L84), [`ui/dr-ui/ui/icons.slint:261`](../ui/dr-ui/ui/icons.slint#L261), [`ui/dr-ui/ui/library.slint:1013`](../ui/dr-ui/ui/library.slint#L1013) | | FR-NC-6b | [`ui/dr-ui/src/library_ui.rs:1350`](../ui/dr-ui/src/library_ui.rs#L1350), [`ui/dr-ui/src/memory.rs:1`](../ui/dr-ui/src/memory.rs#L1) | -| FR-NC-6c | [`core/dr-catalog/src/cache.rs:225`](../core/dr-catalog/src/cache.rs#L225), [`core/dr-sync-folder/src/borrow.rs:1`](../core/dr-sync-folder/src/borrow.rs#L1), [`core/dr-sync-folder/src/lib.rs:197`](../core/dr-sync-folder/src/lib.rs#L197), [`core/dr-sync-folder/src/lib.rs:73`](../core/dr-sync-folder/src/lib.rs#L73), [`core/dr-sync-folder/src/lib.rs:818`](../core/dr-sync-folder/src/lib.rs#L818), [`core/dr-sync-folder/src/lib.rs:857`](../core/dr-sync-folder/src/lib.rs#L857), [`core/dr-sync-folder/src/vfs.rs:1`](../core/dr-sync-folder/src/vfs.rs#L1), [`core/dr-sync-nextcloud/src/desktop_client.rs:167`](../core/dr-sync-nextcloud/src/desktop_client.rs#L167), [`core/dr-sync-nextcloud/src/desktop_client.rs:30`](../core/dr-sync-nextcloud/src/desktop_client.rs#L30), [`core/dr-sync/src/capability.rs:41`](../core/dr-sync/src/capability.rs#L41), [`core/dr-sync/src/error.rs:39`](../core/dr-sync/src/error.rs#L39), [`core/dr-sync/src/lib.rs:158`](../core/dr-sync/src/lib.rs#L158), [`core/dr-sync/src/types.rs:101`](../core/dr-sync/src/types.rs#L101), [`core/dr-types/src/lib.rs:120`](../core/dr-types/src/lib.rs#L120), [`core/dr-types/src/lib.rs:202`](../core/dr-types/src/lib.rs#L202), [`ui/dr-ui/src/activity.rs:1`](../ui/dr-ui/src/activity.rs#L1), [`ui/dr-ui/src/collections_ui.rs:3255`](../ui/dr-ui/src/collections_ui.rs#L3255), [`ui/dr-ui/src/collections_ui.rs:599`](../ui/dr-ui/src/collections_ui.rs#L599), [`ui/dr-ui/src/collections_ui.rs:667`](../ui/dr-ui/src/collections_ui.rs#L667), [`ui/dr-ui/src/derived_sync.rs:555`](../ui/dr-ui/src/derived_sync.rs#L555), [`ui/dr-ui/src/derived_sync.rs:627`](../ui/dr-ui/src/derived_sync.rs#L627), [`ui/dr-ui/src/library.rs:1685`](../ui/dr-ui/src/library.rs#L1685), [`ui/dr-ui/src/library.rs:1775`](../ui/dr-ui/src/library.rs#L1775), [`ui/dr-ui/src/library.rs:3254`](../ui/dr-ui/src/library.rs#L3254), [`ui/dr-ui/src/library.rs:3592`](../ui/dr-ui/src/library.rs#L3592), [`ui/dr-ui/src/library.rs:981`](../ui/dr-ui/src/library.rs#L981), [`ui/dr-ui/src/library_ui.rs:1121`](../ui/dr-ui/src/library_ui.rs#L1121), [`ui/dr-ui/src/library_ui.rs:1194`](../ui/dr-ui/src/library_ui.rs#L1194), [`ui/dr-ui/src/library_ui.rs:1393`](../ui/dr-ui/src/library_ui.rs#L1393), [`ui/dr-ui/src/remote.rs:40`](../ui/dr-ui/src/remote.rs#L40), [`ui/dr-ui/ui/collections.slint:249`](../ui/dr-ui/ui/collections.slint#L249), [`ui/dr-ui/ui/collections.slint:682`](../ui/dr-ui/ui/collections.slint#L682), [`ui/dr-ui/ui/icons.slint:260`](../ui/dr-ui/ui/icons.slint#L260) | +| FR-NC-6c | [`core/dr-catalog/src/cache.rs:225`](../core/dr-catalog/src/cache.rs#L225), [`core/dr-sync-folder/src/borrow.rs:1`](../core/dr-sync-folder/src/borrow.rs#L1), [`core/dr-sync-folder/src/lib.rs:197`](../core/dr-sync-folder/src/lib.rs#L197), [`core/dr-sync-folder/src/lib.rs:73`](../core/dr-sync-folder/src/lib.rs#L73), [`core/dr-sync-folder/src/lib.rs:818`](../core/dr-sync-folder/src/lib.rs#L818), [`core/dr-sync-folder/src/lib.rs:857`](../core/dr-sync-folder/src/lib.rs#L857), [`core/dr-sync-folder/src/vfs.rs:1`](../core/dr-sync-folder/src/vfs.rs#L1), [`core/dr-sync-nextcloud/src/desktop_client.rs:167`](../core/dr-sync-nextcloud/src/desktop_client.rs#L167), [`core/dr-sync-nextcloud/src/desktop_client.rs:30`](../core/dr-sync-nextcloud/src/desktop_client.rs#L30), [`core/dr-sync/src/capability.rs:41`](../core/dr-sync/src/capability.rs#L41), [`core/dr-sync/src/error.rs:39`](../core/dr-sync/src/error.rs#L39), [`core/dr-sync/src/lib.rs:158`](../core/dr-sync/src/lib.rs#L158), [`core/dr-sync/src/types.rs:101`](../core/dr-sync/src/types.rs#L101), [`core/dr-types/src/lib.rs:120`](../core/dr-types/src/lib.rs#L120), [`core/dr-types/src/lib.rs:202`](../core/dr-types/src/lib.rs#L202), [`ui/dr-ui/src/activity.rs:1`](../ui/dr-ui/src/activity.rs#L1), [`ui/dr-ui/src/collections_ui.rs:3255`](../ui/dr-ui/src/collections_ui.rs#L3255), [`ui/dr-ui/src/collections_ui.rs:599`](../ui/dr-ui/src/collections_ui.rs#L599), [`ui/dr-ui/src/collections_ui.rs:667`](../ui/dr-ui/src/collections_ui.rs#L667), [`ui/dr-ui/src/derived_sync.rs:555`](../ui/dr-ui/src/derived_sync.rs#L555), [`ui/dr-ui/src/derived_sync.rs:627`](../ui/dr-ui/src/derived_sync.rs#L627), [`ui/dr-ui/src/library.rs:1685`](../ui/dr-ui/src/library.rs#L1685), [`ui/dr-ui/src/library.rs:1775`](../ui/dr-ui/src/library.rs#L1775), [`ui/dr-ui/src/library.rs:3254`](../ui/dr-ui/src/library.rs#L3254), [`ui/dr-ui/src/library.rs:3592`](../ui/dr-ui/src/library.rs#L3592), [`ui/dr-ui/src/library.rs:981`](../ui/dr-ui/src/library.rs#L981), [`ui/dr-ui/src/library_ui.rs:1121`](../ui/dr-ui/src/library_ui.rs#L1121), [`ui/dr-ui/src/library_ui.rs:1194`](../ui/dr-ui/src/library_ui.rs#L1194), [`ui/dr-ui/src/library_ui.rs:1393`](../ui/dr-ui/src/library_ui.rs#L1393), [`ui/dr-ui/src/remote.rs:40`](../ui/dr-ui/src/remote.rs#L40), [`ui/dr-ui/ui/collections.slint:249`](../ui/dr-ui/ui/collections.slint#L249), [`ui/dr-ui/ui/collections.slint:682`](../ui/dr-ui/ui/collections.slint#L682), [`ui/dr-ui/ui/icons.slint:261`](../ui/dr-ui/ui/icons.slint#L261) | | FR-NC-6d | [`core/dr-sync-folder/src/borrow.rs:1`](../core/dr-sync-folder/src/borrow.rs#L1), [`core/dr-sync-folder/src/lib.rs:1`](../core/dr-sync-folder/src/lib.rs#L1), [`core/dr-sync-folder/src/vfs.rs:1`](../core/dr-sync-folder/src/vfs.rs#L1) | | FR-NC-7 | [`core/dr-catalog/src/face_shard.rs:1`](../core/dr-catalog/src/face_shard.rs#L1), [`core/dr-sync-nextcloud/src/lib.rs:105`](../core/dr-sync-nextcloud/src/lib.rs#L105), [`ui/dr-ui/src/derived_sync.rs:1`](../ui/dr-ui/src/derived_sync.rs#L1), [`ui/dr-ui/src/library.rs:3472`](../ui/dr-ui/src/library.rs#L3472), [`ui/dr-ui/src/library_ui.rs:3731`](../ui/dr-ui/src/library_ui.rs#L3731), [`ui/dr-ui/ui/settings.slint:387`](../ui/dr-ui/ui/settings.slint#L387) | -| FR-NC-7a | [`core/dr-ingest/src/layout.rs:1`](../core/dr-ingest/src/layout.rs#L1), [`core/dr-sync/src/upload.rs:1`](../core/dr-sync/src/upload.rs#L1), [`core/dr-sync/src/upload.rs:40`](../core/dr-sync/src/upload.rs#L40), [`core/dr-types/src/settings.rs:206`](../core/dr-types/src/settings.rs#L206), [`ui/dr-ui/src/import.rs:1`](../ui/dr-ui/src/import.rs#L1), [`ui/dr-ui/src/import.rs:97`](../ui/dr-ui/src/import.rs#L97), [`ui/dr-ui/src/import_ui.rs:1`](../ui/dr-ui/src/import_ui.rs#L1), [`ui/dr-ui/src/lib.rs:1215`](../ui/dr-ui/src/lib.rs#L1215), [`ui/dr-ui/ui/import.slint:5`](../ui/dr-ui/ui/import.slint#L5) | -| FR-NC-7b | [`core/dr-ingest/src/lib.rs:733`](../core/dr-ingest/src/lib.rs#L733), [`core/dr-sync/src/upload.rs:1`](../core/dr-sync/src/upload.rs#L1), [`ui/dr-ui/src/import.rs:122`](../ui/dr-ui/src/import.rs#L122), [`ui/dr-ui/src/import.rs:336`](../ui/dr-ui/src/import.rs#L336), [`ui/dr-ui/src/import.rs:584`](../ui/dr-ui/src/import.rs#L584), [`ui/dr-ui/src/import.rs:97`](../ui/dr-ui/src/import.rs#L97), [`ui/dr-ui/src/import_ui.rs:1`](../ui/dr-ui/src/import_ui.rs#L1), [`ui/dr-ui/src/lib.rs:1215`](../ui/dr-ui/src/lib.rs#L1215) | -| FR-NC-8 | [`core/dr-pipeline/src/sidecar.rs:119`](../core/dr-pipeline/src/sidecar.rs#L119), [`core/dr-pipeline/src/sidecar.rs:93`](../core/dr-pipeline/src/sidecar.rs#L93), [`ui/dr-ui/src/lib.rs:1984`](../ui/dr-ui/src/lib.rs#L1984), [`ui/dr-ui/src/library.rs:492`](../ui/dr-ui/src/library.rs#L492), [`ui/dr-ui/src/library_ui.rs:494`](../ui/dr-ui/src/library_ui.rs#L494) | +| FR-NC-7a | [`core/dr-ingest/src/layout.rs:1`](../core/dr-ingest/src/layout.rs#L1), [`core/dr-sync/src/upload.rs:1`](../core/dr-sync/src/upload.rs#L1), [`core/dr-sync/src/upload.rs:40`](../core/dr-sync/src/upload.rs#L40), [`core/dr-types/src/settings.rs:206`](../core/dr-types/src/settings.rs#L206), [`ui/dr-ui/src/import.rs:1`](../ui/dr-ui/src/import.rs#L1), [`ui/dr-ui/src/import.rs:97`](../ui/dr-ui/src/import.rs#L97), [`ui/dr-ui/src/import_ui.rs:1`](../ui/dr-ui/src/import_ui.rs#L1), [`ui/dr-ui/src/lib.rs:1221`](../ui/dr-ui/src/lib.rs#L1221), [`ui/dr-ui/ui/import.slint:5`](../ui/dr-ui/ui/import.slint#L5) | +| FR-NC-7b | [`core/dr-ingest/src/lib.rs:733`](../core/dr-ingest/src/lib.rs#L733), [`core/dr-sync/src/upload.rs:1`](../core/dr-sync/src/upload.rs#L1), [`ui/dr-ui/src/import.rs:122`](../ui/dr-ui/src/import.rs#L122), [`ui/dr-ui/src/import.rs:336`](../ui/dr-ui/src/import.rs#L336), [`ui/dr-ui/src/import.rs:584`](../ui/dr-ui/src/import.rs#L584), [`ui/dr-ui/src/import.rs:97`](../ui/dr-ui/src/import.rs#L97), [`ui/dr-ui/src/import_ui.rs:1`](../ui/dr-ui/src/import_ui.rs#L1), [`ui/dr-ui/src/lib.rs:1221`](../ui/dr-ui/src/lib.rs#L1221) | +| FR-NC-8 | [`core/dr-pipeline/src/sidecar.rs:119`](../core/dr-pipeline/src/sidecar.rs#L119), [`core/dr-pipeline/src/sidecar.rs:93`](../core/dr-pipeline/src/sidecar.rs#L93), [`ui/dr-ui/src/lib.rs:1990`](../ui/dr-ui/src/lib.rs#L1990), [`ui/dr-ui/src/library.rs:492`](../ui/dr-ui/src/library.rs#L492), [`ui/dr-ui/src/library_ui.rs:494`](../ui/dr-ui/src/library_ui.rs#L494) | | FR-NC-9 | [`core/dr-catalog/src/merge.rs:1`](../core/dr-catalog/src/merge.rs#L1), [`core/dr-catalog/src/schema.rs:635`](../core/dr-catalog/src/schema.rs#L635), [`core/dr-catalog/src/sync.rs:1`](../core/dr-catalog/src/sync.rs#L1), [`core/dr-pipeline/src/sidecar.rs:157`](../core/dr-pipeline/src/sidecar.rs#L157), [`core/dr-pipeline/src/sidecar.rs:184`](../core/dr-pipeline/src/sidecar.rs#L184), [`core/dr-pipeline/src/sidecar.rs:2034`](../core/dr-pipeline/src/sidecar.rs#L2034), [`core/dr-pipeline/src/sidecar.rs:353`](../core/dr-pipeline/src/sidecar.rs#L353), [`core/dr-pipeline/src/sidecar.rs:451`](../core/dr-pipeline/src/sidecar.rs#L451), [`core/dr-pipeline/src/spot.rs:245`](../core/dr-pipeline/src/spot.rs#L245), [`core/dr-pipeline/tests/spot_sidecar.rs:1`](../core/dr-pipeline/tests/spot_sidecar.rs#L1), [`ui/dr-ui/src/derived_sync.rs:555`](../ui/dr-ui/src/derived_sync.rs#L555), [`ui/dr-ui/src/library.rs:1031`](../ui/dr-ui/src/library.rs#L1031), [`ui/dr-ui/src/library.rs:877`](../ui/dr-ui/src/library.rs#L877) | | FR-PLAT-AND-1 | [`core/dr-types/src/lib.rs:54`](../core/dr-types/src/lib.rs#L54), [`platform/dr-plat/src/volumes.rs:62`](../platform/dr-plat/src/volumes.rs#L62) | | FR-PLAT-AND-2 | [`core/dr-catalog/src/walk.rs:1022`](../core/dr-catalog/src/walk.rs#L1022), [`core/dr-catalog/src/walk.rs:435`](../core/dr-catalog/src/walk.rs#L435), [`core/dr-sync-folder/src/lib.rs:242`](../core/dr-sync-folder/src/lib.rs#L242), [`core/dr-sync-folder/src/tests.rs:51`](../core/dr-sync-folder/src/tests.rs#L51), [`core/dr-sync/src/error.rs:113`](../core/dr-sync/src/error.rs#L113), [`core/dr-sync/src/error.rs:195`](../core/dr-sync/src/error.rs#L195), [`core/dr-sync/src/scan.rs:175`](../core/dr-sync/src/scan.rs#L175), [`core/dr-sync/src/scan.rs:464`](../core/dr-sync/src/scan.rs#L464), [`core/dr-sync/src/scan.rs:490`](../core/dr-sync/src/scan.rs#L490), [`core/dr-sync/src/scan.rs:519`](../core/dr-sync/src/scan.rs#L519), [`ui/dr-ui/src/library.rs:1222`](../ui/dr-ui/src/library.rs#L1222), [`ui/dr-ui/src/library.rs:1275`](../ui/dr-ui/src/library.rs#L1275), [`ui/dr-ui/src/library.rs:1306`](../ui/dr-ui/src/library.rs#L1306), [`ui/dr-ui/src/library.rs:1411`](../ui/dr-ui/src/library.rs#L1411), [`ui/dr-ui/src/library_ui.rs:1045`](../ui/dr-ui/src/library_ui.rs#L1045), [`ui/dr-ui/src/library_ui.rs:1644`](../ui/dr-ui/src/library_ui.rs#L1644), [`ui/dr-ui/src/library_ui.rs:273`](../ui/dr-ui/src/library_ui.rs#L273), [`ui/dr-ui/src/library_ui.rs:463`](../ui/dr-ui/src/library_ui.rs#L463), [`ui/dr-ui/src/library_ui.rs:966`](../ui/dr-ui/src/library_ui.rs#L966) | | FR-PLAT-AND-3 | [`core/dr-catalog/src/jobs.rs:1`](../core/dr-catalog/src/jobs.rs#L1), [`core/dr-catalog/src/runner.rs:1`](../core/dr-catalog/src/runner.rs#L1) | | FR-PLAT-AND-4 | [`core/dr-catalog/src/runner.rs:1`](../core/dr-catalog/src/runner.rs#L1) | -| FR-PLAT-AND-5 | [`apps/darkroom-android/src/lib.rs:71`](../apps/darkroom-android/src/lib.rs#L71), [`core/dr-gpu/src/adjust.rs:1029`](../core/dr-gpu/src/adjust.rs#L1029), [`core/dr-gpu/src/detail.rs:161`](../core/dr-gpu/src/detail.rs#L161), [`core/dr-gpu/src/detail.rs:547`](../core/dr-gpu/src/detail.rs#L547), [`core/dr-gpu/tests/detail_stage.rs:417`](../core/dr-gpu/tests/detail_stage.rs#L417), [`ui/dr-ui/src/develop.rs:3151`](../ui/dr-ui/src/develop.rs#L3151), [`ui/dr-ui/src/identity_ui.rs:115`](../ui/dr-ui/src/identity_ui.rs#L115), [`ui/dr-ui/src/lib.rs:1039`](../ui/dr-ui/src/lib.rs#L1039), [`ui/dr-ui/src/lib.rs:1468`](../ui/dr-ui/src/lib.rs#L1468), [`ui/dr-ui/src/memory.rs:163`](../ui/dr-ui/src/memory.rs#L163), [`ui/dr-ui/src/memory.rs:1`](../ui/dr-ui/src/memory.rs#L1) | +| FR-PLAT-AND-5 | [`apps/darkroom-android/src/lib.rs:71`](../apps/darkroom-android/src/lib.rs#L71), [`core/dr-gpu/src/adjust.rs:1029`](../core/dr-gpu/src/adjust.rs#L1029), [`core/dr-gpu/src/detail.rs:161`](../core/dr-gpu/src/detail.rs#L161), [`core/dr-gpu/src/detail.rs:547`](../core/dr-gpu/src/detail.rs#L547), [`core/dr-gpu/tests/detail_stage.rs:417`](../core/dr-gpu/tests/detail_stage.rs#L417), [`ui/dr-ui/src/develop.rs:3151`](../ui/dr-ui/src/develop.rs#L3151), [`ui/dr-ui/src/identity_ui.rs:115`](../ui/dr-ui/src/identity_ui.rs#L115), [`ui/dr-ui/src/lib.rs:1045`](../ui/dr-ui/src/lib.rs#L1045), [`ui/dr-ui/src/lib.rs:1474`](../ui/dr-ui/src/lib.rs#L1474), [`ui/dr-ui/src/memory.rs:163`](../ui/dr-ui/src/memory.rs#L163), [`ui/dr-ui/src/memory.rs:1`](../ui/dr-ui/src/memory.rs#L1) | | FR-PLAT-AND-6 | [`apps/darkroom-android/src/lib.rs:204`](../apps/darkroom-android/src/lib.rs#L204) | -| FR-PLAT-LIN-1 | [`core/dr-types/src/settings.rs:1`](../core/dr-types/src/settings.rs#L1), [`platform/dr-plat/src/storage.rs:344`](../platform/dr-plat/src/storage.rs#L344), [`ui/dr-ui/src/lib.rs:938`](../ui/dr-ui/src/lib.rs#L938), [`ui/dr-ui/src/preset_store.rs:1`](../ui/dr-ui/src/preset_store.rs#L1), [`ui/dr-ui/src/settings_store.rs:1`](../ui/dr-ui/src/settings_store.rs#L1) | +| FR-PLAT-LIN-1 | [`core/dr-types/src/settings.rs:1`](../core/dr-types/src/settings.rs#L1), [`platform/dr-plat/src/storage.rs:344`](../platform/dr-plat/src/storage.rs#L344), [`ui/dr-ui/src/lib.rs:944`](../ui/dr-ui/src/lib.rs#L944), [`ui/dr-ui/src/preset_store.rs:1`](../ui/dr-ui/src/preset_store.rs#L1), [`ui/dr-ui/src/settings_store.rs:1`](../ui/dr-ui/src/settings_store.rs#L1) | | FR-PLAT-LIN-2 | [`platform/dr-plat/src/display.rs:1`](../platform/dr-plat/src/display.rs#L1), [`platform/dr-plat/src/display/wayland.rs:1`](../platform/dr-plat/src/display/wayland.rs#L1), [`platform/dr-plat/src/display/x11.rs:1`](../platform/dr-plat/src/display/x11.rs#L1) | | FR-PLG-2 | [`core/dr-pipeline/src/declared/decl.rs:1`](../core/dr-pipeline/src/declared/decl.rs#L1), [`core/dr-pipeline/src/declared/expr.rs:152`](../core/dr-pipeline/src/declared/expr.rs#L152), [`core/dr-pipeline/src/declared/expr.rs:1`](../core/dr-pipeline/src/declared/expr.rs#L1), [`core/dr-pipeline/src/declared/mod.rs:1`](../core/dr-pipeline/src/declared/mod.rs#L1), [`core/dr-pipeline/src/declared/mod.rs:82`](../core/dr-pipeline/src/declared/mod.rs#L82), [`core/dr-pipeline/src/descriptor.rs:15`](../core/dr-pipeline/src/descriptor.rs#L15), [`core/dr-pipeline/src/descriptor.rs:652`](../core/dr-pipeline/src/descriptor.rs#L652), [`core/dr-pipeline/src/operation.rs:232`](../core/dr-pipeline/src/operation.rs#L232), [`core/dr-pipeline/tests/declared_parity.rs:1`](../core/dr-pipeline/tests/declared_parity.rs#L1), [`core/dr-pipeline/tests/declared_parity.rs:240`](../core/dr-pipeline/tests/declared_parity.rs#L240), [`core/dr-pipeline/tests/declared_parity.rs:305`](../core/dr-pipeline/tests/declared_parity.rs#L305), [`core/dr-pipeline/tests/declared_parity.rs:358`](../core/dr-pipeline/tests/declared_parity.rs#L358), [`core/dr-pipeline/tests/declared_parity.rs:416`](../core/dr-pipeline/tests/declared_parity.rs#L416) | | FR-PLG-2d | [`core/dr-pipeline/src/declared/decl.rs:112`](../core/dr-pipeline/src/declared/decl.rs#L112), [`core/dr-pipeline/src/declared/decl.rs:152`](../core/dr-pipeline/src/declared/decl.rs#L152), [`core/dr-pipeline/src/declared/decl.rs:1`](../core/dr-pipeline/src/declared/decl.rs#L1), [`core/dr-pipeline/src/declared/decl.rs:420`](../core/dr-pipeline/src/declared/decl.rs#L420), [`core/dr-pipeline/src/declared/decl.rs:67`](../core/dr-pipeline/src/declared/decl.rs#L67), [`core/dr-pipeline/src/declared/mod.rs:1`](../core/dr-pipeline/src/declared/mod.rs#L1), [`core/dr-pipeline/src/declared/mod.rs:384`](../core/dr-pipeline/src/declared/mod.rs#L384), [`core/dr-pipeline/src/declared/mod.rs:403`](../core/dr-pipeline/src/declared/mod.rs#L403) | | FR-RAW-1 | [`core/dr-decode/src/lib.rs:243`](../core/dr-decode/src/lib.rs#L243), [`core/dr-types/src/lib.rs:130`](../core/dr-types/src/lib.rs#L130), [`core/dr-types/src/lib.rs:201`](../core/dr-types/src/lib.rs#L201) | | FR-RAW-3 | [`core/dr-decode/src/lib.rs:139`](../core/dr-decode/src/lib.rs#L139), [`core/dr-decode/src/lib.rs:506`](../core/dr-decode/src/lib.rs#L506), [`core/dr-decode/src/locate.rs:1366`](../core/dr-decode/src/locate.rs#L1366) | -| FR-RAW-4 | [`core/dr-decode/src/error.rs:1`](../core/dr-decode/src/error.rs#L1), [`ui/dr-ui/src/lib.rs:213`](../ui/dr-ui/src/lib.rs#L213) | +| FR-RAW-4 | [`core/dr-decode/src/error.rs:1`](../core/dr-decode/src/error.rs#L1), [`ui/dr-ui/src/lib.rs:219`](../ui/dr-ui/src/lib.rs#L219) | | FR-RAW-5 | [`core/dr-decode/src/lib.rs:167`](../core/dr-decode/src/lib.rs#L167), [`core/dr-gpu/src/demosaic.rs:34`](../core/dr-gpu/src/demosaic.rs#L34), [`core/dr-gpu/src/demosaic.rs:602`](../core/dr-gpu/src/demosaic.rs#L602), [`core/dr-gpu/src/demosaic.rs:681`](../core/dr-gpu/src/demosaic.rs#L681), [`core/dr-gpu/src/demosaic.rs:805`](../core/dr-gpu/src/demosaic.rs#L805) | -| FR-UI-1 | [`ui/dr-ui/src/lib.rs:3210`](../ui/dr-ui/src/lib.rs#L3210), [`ui/dr-ui/src/lib.rs:89`](../ui/dr-ui/src/lib.rs#L89), [`ui/dr-ui/src/masks_ui.rs:816`](../ui/dr-ui/src/masks_ui.rs#L816), [`ui/dr-ui/ui/identity.slint:181`](../ui/dr-ui/ui/identity.slint#L181), [`ui/dr-ui/ui/library.slint:1091`](../ui/dr-ui/ui/library.slint#L1091) | -| FR-UI-2 | [`ui/dr-ui/src/collections_ui.rs:1008`](../ui/dr-ui/src/collections_ui.rs#L1008), [`ui/dr-ui/src/collections_ui.rs:1018`](../ui/dr-ui/src/collections_ui.rs#L1018), [`ui/dr-ui/src/collections_ui.rs:119`](../ui/dr-ui/src/collections_ui.rs#L119), [`ui/dr-ui/src/collections_ui.rs:1501`](../ui/dr-ui/src/collections_ui.rs#L1501), [`ui/dr-ui/src/collections_ui.rs:1515`](../ui/dr-ui/src/collections_ui.rs#L1515), [`ui/dr-ui/src/collections_ui.rs:160`](../ui/dr-ui/src/collections_ui.rs#L160), [`ui/dr-ui/src/collections_ui.rs:1767`](../ui/dr-ui/src/collections_ui.rs#L1767), [`ui/dr-ui/src/collections_ui.rs:2818`](../ui/dr-ui/src/collections_ui.rs#L2818), [`ui/dr-ui/src/collections_ui.rs:486`](../ui/dr-ui/src/collections_ui.rs#L486), [`ui/dr-ui/src/gestures.rs:1`](../ui/dr-ui/src/gestures.rs#L1), [`ui/dr-ui/src/lib.rs:89`](../ui/dr-ui/src/lib.rs#L89), [`ui/dr-ui/src/lib.rs:96`](../ui/dr-ui/src/lib.rs#L96), [`ui/dr-ui/src/library_ui.rs:308`](../ui/dr-ui/src/library_ui.rs#L308), [`ui/dr-ui/src/library_ui.rs:5416`](../ui/dr-ui/src/library_ui.rs#L5416), [`ui/dr-ui/src/library_ui.rs:5561`](../ui/dr-ui/src/library_ui.rs#L5561), [`ui/dr-ui/src/library_ui.rs:6766`](../ui/dr-ui/src/library_ui.rs#L6766), [`ui/dr-ui/ui/adjust.slint:1072`](../ui/dr-ui/ui/adjust.slint#L1072), [`ui/dr-ui/ui/adjust.slint:544`](../ui/dr-ui/ui/adjust.slint#L544), [`ui/dr-ui/ui/adjust.slint:741`](../ui/dr-ui/ui/adjust.slint#L741), [`ui/dr-ui/ui/app.slint:2129`](../ui/dr-ui/ui/app.slint#L2129), [`ui/dr-ui/ui/app.slint:540`](../ui/dr-ui/ui/app.slint#L540), [`ui/dr-ui/ui/app.slint:547`](../ui/dr-ui/ui/app.slint#L547), [`ui/dr-ui/ui/app.slint:58`](../ui/dr-ui/ui/app.slint#L58), [`ui/dr-ui/ui/app.slint:898`](../ui/dr-ui/ui/app.slint#L898), [`ui/dr-ui/ui/controls.slint:474`](../ui/dr-ui/ui/controls.slint#L474), [`ui/dr-ui/ui/develop.slint:223`](../ui/dr-ui/ui/develop.slint#L223), [`ui/dr-ui/ui/gestures.slint:1`](../ui/dr-ui/ui/gestures.slint#L1), [`ui/dr-ui/ui/histogram.slint:187`](../ui/dr-ui/ui/histogram.slint#L187), [`ui/dr-ui/ui/history.slint:118`](../ui/dr-ui/ui/history.slint#L118), [`ui/dr-ui/ui/library.slint:1259`](../ui/dr-ui/ui/library.slint#L1259), [`ui/dr-ui/ui/library.slint:1266`](../ui/dr-ui/ui/library.slint#L1266), [`ui/dr-ui/ui/library.slint:1329`](../ui/dr-ui/ui/library.slint#L1329), [`ui/dr-ui/ui/library.slint:2561`](../ui/dr-ui/ui/library.slint#L2561), [`ui/dr-ui/ui/library.slint:3866`](../ui/dr-ui/ui/library.slint#L3866), [`ui/dr-ui/ui/library.slint:842`](../ui/dr-ui/ui/library.slint#L842), [`ui/dr-ui/ui/library.slint:898`](../ui/dr-ui/ui/library.slint#L898), [`ui/dr-ui/ui/masks.slint:314`](../ui/dr-ui/ui/masks.slint#L314), [`ui/dr-ui/ui/peaking.slint:82`](../ui/dr-ui/ui/peaking.slint#L82), [`ui/dr-ui/ui/presets.slint:19`](../ui/dr-ui/ui/presets.slint#L19), [`ui/dr-ui/ui/settings.slint:110`](../ui/dr-ui/ui/settings.slint#L110), [`ui/dr-ui/ui/spots.slint:88`](../ui/dr-ui/ui/spots.slint#L88) | -| FR-UI-3 | [`ui/dr-ui/src/develop.rs:2248`](../ui/dr-ui/src/develop.rs#L2248), [`ui/dr-ui/src/develop.rs:2357`](../ui/dr-ui/src/develop.rs#L2357), [`ui/dr-ui/src/library_ui.rs:4525`](../ui/dr-ui/src/library_ui.rs#L4525), [`ui/dr-ui/src/masks_ui.rs:218`](../ui/dr-ui/src/masks_ui.rs#L218), [`ui/dr-ui/src/masks_ui.rs:908`](../ui/dr-ui/src/masks_ui.rs#L908), [`ui/dr-ui/src/masks_ui.rs:930`](../ui/dr-ui/src/masks_ui.rs#L930), [`ui/dr-ui/src/spots_ui.rs:19`](../ui/dr-ui/src/spots_ui.rs#L19), [`ui/dr-ui/ui/app.slint:1945`](../ui/dr-ui/ui/app.slint#L1945), [`ui/dr-ui/ui/collections.slint:4`](../ui/dr-ui/ui/collections.slint#L4), [`ui/dr-ui/ui/collections.slint:682`](../ui/dr-ui/ui/collections.slint#L682), [`ui/dr-ui/ui/masks.slint:524`](../ui/dr-ui/ui/masks.slint#L524) | -| FR-UI-4 | [`tools/traceability/src/gestures.rs:1`](../tools/traceability/src/gestures.rs#L1), [`tools/traceability/src/gestures.rs:366`](../tools/traceability/src/gestures.rs#L366), [`ui/dr-ui/src/collections_ui.rs:1008`](../ui/dr-ui/src/collections_ui.rs#L1008), [`ui/dr-ui/src/collections_ui.rs:1018`](../ui/dr-ui/src/collections_ui.rs#L1018), [`ui/dr-ui/src/collections_ui.rs:119`](../ui/dr-ui/src/collections_ui.rs#L119), [`ui/dr-ui/src/collections_ui.rs:132`](../ui/dr-ui/src/collections_ui.rs#L132), [`ui/dr-ui/src/collections_ui.rs:1501`](../ui/dr-ui/src/collections_ui.rs#L1501), [`ui/dr-ui/src/collections_ui.rs:1515`](../ui/dr-ui/src/collections_ui.rs#L1515), [`ui/dr-ui/src/collections_ui.rs:160`](../ui/dr-ui/src/collections_ui.rs#L160), [`ui/dr-ui/src/collections_ui.rs:1631`](../ui/dr-ui/src/collections_ui.rs#L1631), [`ui/dr-ui/src/collections_ui.rs:1767`](../ui/dr-ui/src/collections_ui.rs#L1767), [`ui/dr-ui/src/collections_ui.rs:1794`](../ui/dr-ui/src/collections_ui.rs#L1794), [`ui/dr-ui/src/collections_ui.rs:1893`](../ui/dr-ui/src/collections_ui.rs#L1893), [`ui/dr-ui/src/collections_ui.rs:2818`](../ui/dr-ui/src/collections_ui.rs#L2818), [`ui/dr-ui/src/collections_ui.rs:486`](../ui/dr-ui/src/collections_ui.rs#L486), [`ui/dr-ui/src/collections_ui.rs:560`](../ui/dr-ui/src/collections_ui.rs#L560), [`ui/dr-ui/src/gesture_book.rs:3`](../ui/dr-ui/src/gesture_book.rs#L3), [`ui/dr-ui/src/gestures.rs:1`](../ui/dr-ui/src/gestures.rs#L1), [`ui/dr-ui/src/library_ui.rs:4525`](../ui/dr-ui/src/library_ui.rs#L4525), [`ui/dr-ui/src/library_ui.rs:4537`](../ui/dr-ui/src/library_ui.rs#L4537), [`ui/dr-ui/src/library_ui.rs:4589`](../ui/dr-ui/src/library_ui.rs#L4589), [`ui/dr-ui/src/library_ui.rs:4692`](../ui/dr-ui/src/library_ui.rs#L4692), [`ui/dr-ui/src/library_ui.rs:4720`](../ui/dr-ui/src/library_ui.rs#L4720), [`ui/dr-ui/src/library_ui.rs:5549`](../ui/dr-ui/src/library_ui.rs#L5549), [`ui/dr-ui/src/library_ui.rs:5561`](../ui/dr-ui/src/library_ui.rs#L5561), [`ui/dr-ui/ui/app.slint:1785`](../ui/dr-ui/ui/app.slint#L1785), [`ui/dr-ui/ui/app.slint:516`](../ui/dr-ui/ui/app.slint#L516), [`ui/dr-ui/ui/app.slint:547`](../ui/dr-ui/ui/app.slint#L547), [`ui/dr-ui/ui/app.slint:632`](../ui/dr-ui/ui/app.slint#L632), [`ui/dr-ui/ui/gestures.slint:1`](../ui/dr-ui/ui/gestures.slint#L1), [`ui/dr-ui/ui/library.slint:1067`](../ui/dr-ui/ui/library.slint#L1067), [`ui/dr-ui/ui/library.slint:1234`](../ui/dr-ui/ui/library.slint#L1234), [`ui/dr-ui/ui/library.slint:1259`](../ui/dr-ui/ui/library.slint#L1259), [`ui/dr-ui/ui/library.slint:1266`](../ui/dr-ui/ui/library.slint#L1266), [`ui/dr-ui/ui/library.slint:1322`](../ui/dr-ui/ui/library.slint#L1322), [`ui/dr-ui/ui/library.slint:1329`](../ui/dr-ui/ui/library.slint#L1329), [`ui/dr-ui/ui/library.slint:2561`](../ui/dr-ui/ui/library.slint#L2561), [`ui/dr-ui/ui/library.slint:3866`](../ui/dr-ui/ui/library.slint#L3866), [`ui/dr-ui/ui/library.slint:842`](../ui/dr-ui/ui/library.slint#L842), [`ui/dr-ui/ui/library.slint:892`](../ui/dr-ui/ui/library.slint#L892), [`ui/dr-ui/ui/library.slint:898`](../ui/dr-ui/ui/library.slint#L898), [`ui/dr-ui/ui/library.slint:917`](../ui/dr-ui/ui/library.slint#L917) | -| FR-UI-5 | [`ui/dr-ui/src/collections_ui.rs:1`](../ui/dr-ui/src/collections_ui.rs#L1), [`ui/dr-ui/src/lib.rs:2647`](../ui/dr-ui/src/lib.rs#L2647), [`ui/dr-ui/src/lib.rs:3249`](../ui/dr-ui/src/lib.rs#L3249), [`ui/dr-ui/src/lib.rs:3434`](../ui/dr-ui/src/lib.rs#L3434), [`ui/dr-ui/src/masks_ui.rs:863`](../ui/dr-ui/src/masks_ui.rs#L863), [`ui/dr-ui/ui/app.slint:119`](../ui/dr-ui/ui/app.slint#L119), [`ui/dr-ui/ui/collections.slint:4`](../ui/dr-ui/ui/collections.slint#L4) | +| FR-UI-1 | [`ui/dr-ui/src/lib.rs:3216`](../ui/dr-ui/src/lib.rs#L3216), [`ui/dr-ui/src/lib.rs:89`](../ui/dr-ui/src/lib.rs#L89), [`ui/dr-ui/src/lib.rs:96`](../ui/dr-ui/src/lib.rs#L96), [`ui/dr-ui/src/masks_ui.rs:816`](../ui/dr-ui/src/masks_ui.rs#L816), [`ui/dr-ui/ui/app.slint:2162`](../ui/dr-ui/ui/app.slint#L2162), [`ui/dr-ui/ui/identity.slint:181`](../ui/dr-ui/ui/identity.slint#L181), [`ui/dr-ui/ui/library.slint:1091`](../ui/dr-ui/ui/library.slint#L1091), [`ui/dr-ui/ui/toolrail.slint:88`](../ui/dr-ui/ui/toolrail.slint#L88) | +| FR-UI-2 | [`ui/dr-ui/src/collections_ui.rs:1008`](../ui/dr-ui/src/collections_ui.rs#L1008), [`ui/dr-ui/src/collections_ui.rs:1018`](../ui/dr-ui/src/collections_ui.rs#L1018), [`ui/dr-ui/src/collections_ui.rs:119`](../ui/dr-ui/src/collections_ui.rs#L119), [`ui/dr-ui/src/collections_ui.rs:1501`](../ui/dr-ui/src/collections_ui.rs#L1501), [`ui/dr-ui/src/collections_ui.rs:1515`](../ui/dr-ui/src/collections_ui.rs#L1515), [`ui/dr-ui/src/collections_ui.rs:160`](../ui/dr-ui/src/collections_ui.rs#L160), [`ui/dr-ui/src/collections_ui.rs:1767`](../ui/dr-ui/src/collections_ui.rs#L1767), [`ui/dr-ui/src/collections_ui.rs:2818`](../ui/dr-ui/src/collections_ui.rs#L2818), [`ui/dr-ui/src/collections_ui.rs:486`](../ui/dr-ui/src/collections_ui.rs#L486), [`ui/dr-ui/src/gestures.rs:1`](../ui/dr-ui/src/gestures.rs#L1), [`ui/dr-ui/src/lib.rs:89`](../ui/dr-ui/src/lib.rs#L89), [`ui/dr-ui/src/library_ui.rs:308`](../ui/dr-ui/src/library_ui.rs#L308), [`ui/dr-ui/src/library_ui.rs:5416`](../ui/dr-ui/src/library_ui.rs#L5416), [`ui/dr-ui/src/library_ui.rs:5561`](../ui/dr-ui/src/library_ui.rs#L5561), [`ui/dr-ui/src/library_ui.rs:6766`](../ui/dr-ui/src/library_ui.rs#L6766), [`ui/dr-ui/ui/app.slint:541`](../ui/dr-ui/ui/app.slint#L541), [`ui/dr-ui/ui/app.slint:548`](../ui/dr-ui/ui/app.slint#L548), [`ui/dr-ui/ui/app.slint:59`](../ui/dr-ui/ui/app.slint#L59), [`ui/dr-ui/ui/app.slint:899`](../ui/dr-ui/ui/app.slint#L899), [`ui/dr-ui/ui/controls.slint:474`](../ui/dr-ui/ui/controls.slint#L474), [`ui/dr-ui/ui/gestures.slint:1`](../ui/dr-ui/ui/gestures.slint#L1), [`ui/dr-ui/ui/library.slint:1259`](../ui/dr-ui/ui/library.slint#L1259), [`ui/dr-ui/ui/library.slint:1266`](../ui/dr-ui/ui/library.slint#L1266), [`ui/dr-ui/ui/library.slint:1329`](../ui/dr-ui/ui/library.slint#L1329), [`ui/dr-ui/ui/library.slint:2561`](../ui/dr-ui/ui/library.slint#L2561), [`ui/dr-ui/ui/library.slint:3866`](../ui/dr-ui/ui/library.slint#L3866), [`ui/dr-ui/ui/library.slint:842`](../ui/dr-ui/ui/library.slint#L842), [`ui/dr-ui/ui/library.slint:898`](../ui/dr-ui/ui/library.slint#L898), [`ui/dr-ui/ui/presets.slint:19`](../ui/dr-ui/ui/presets.slint#L19), [`ui/dr-ui/ui/settings.slint:110`](../ui/dr-ui/ui/settings.slint#L110) | +| FR-UI-3 | [`ui/dr-ui/src/develop.rs:2248`](../ui/dr-ui/src/develop.rs#L2248), [`ui/dr-ui/src/develop.rs:2357`](../ui/dr-ui/src/develop.rs#L2357), [`ui/dr-ui/src/library_ui.rs:4525`](../ui/dr-ui/src/library_ui.rs#L4525), [`ui/dr-ui/src/masks_ui.rs:218`](../ui/dr-ui/src/masks_ui.rs#L218), [`ui/dr-ui/src/masks_ui.rs:908`](../ui/dr-ui/src/masks_ui.rs#L908), [`ui/dr-ui/src/masks_ui.rs:930`](../ui/dr-ui/src/masks_ui.rs#L930), [`ui/dr-ui/src/spots_ui.rs:19`](../ui/dr-ui/src/spots_ui.rs#L19), [`ui/dr-ui/ui/app.slint:1971`](../ui/dr-ui/ui/app.slint#L1971), [`ui/dr-ui/ui/collections.slint:4`](../ui/dr-ui/ui/collections.slint#L4), [`ui/dr-ui/ui/collections.slint:682`](../ui/dr-ui/ui/collections.slint#L682), [`ui/dr-ui/ui/masks.slint:516`](../ui/dr-ui/ui/masks.slint#L516) | +| FR-UI-4 | [`tools/traceability/src/gestures.rs:1`](../tools/traceability/src/gestures.rs#L1), [`tools/traceability/src/gestures.rs:366`](../tools/traceability/src/gestures.rs#L366), [`ui/dr-ui/src/collections_ui.rs:1008`](../ui/dr-ui/src/collections_ui.rs#L1008), [`ui/dr-ui/src/collections_ui.rs:1018`](../ui/dr-ui/src/collections_ui.rs#L1018), [`ui/dr-ui/src/collections_ui.rs:119`](../ui/dr-ui/src/collections_ui.rs#L119), [`ui/dr-ui/src/collections_ui.rs:132`](../ui/dr-ui/src/collections_ui.rs#L132), [`ui/dr-ui/src/collections_ui.rs:1501`](../ui/dr-ui/src/collections_ui.rs#L1501), [`ui/dr-ui/src/collections_ui.rs:1515`](../ui/dr-ui/src/collections_ui.rs#L1515), [`ui/dr-ui/src/collections_ui.rs:160`](../ui/dr-ui/src/collections_ui.rs#L160), [`ui/dr-ui/src/collections_ui.rs:1631`](../ui/dr-ui/src/collections_ui.rs#L1631), [`ui/dr-ui/src/collections_ui.rs:1767`](../ui/dr-ui/src/collections_ui.rs#L1767), [`ui/dr-ui/src/collections_ui.rs:1794`](../ui/dr-ui/src/collections_ui.rs#L1794), [`ui/dr-ui/src/collections_ui.rs:1893`](../ui/dr-ui/src/collections_ui.rs#L1893), [`ui/dr-ui/src/collections_ui.rs:2818`](../ui/dr-ui/src/collections_ui.rs#L2818), [`ui/dr-ui/src/collections_ui.rs:486`](../ui/dr-ui/src/collections_ui.rs#L486), [`ui/dr-ui/src/collections_ui.rs:560`](../ui/dr-ui/src/collections_ui.rs#L560), [`ui/dr-ui/src/gesture_book.rs:3`](../ui/dr-ui/src/gesture_book.rs#L3), [`ui/dr-ui/src/gestures.rs:1`](../ui/dr-ui/src/gestures.rs#L1), [`ui/dr-ui/src/library_ui.rs:4525`](../ui/dr-ui/src/library_ui.rs#L4525), [`ui/dr-ui/src/library_ui.rs:4537`](../ui/dr-ui/src/library_ui.rs#L4537), [`ui/dr-ui/src/library_ui.rs:4589`](../ui/dr-ui/src/library_ui.rs#L4589), [`ui/dr-ui/src/library_ui.rs:4692`](../ui/dr-ui/src/library_ui.rs#L4692), [`ui/dr-ui/src/library_ui.rs:4720`](../ui/dr-ui/src/library_ui.rs#L4720), [`ui/dr-ui/src/library_ui.rs:5549`](../ui/dr-ui/src/library_ui.rs#L5549), [`ui/dr-ui/src/library_ui.rs:5561`](../ui/dr-ui/src/library_ui.rs#L5561), [`ui/dr-ui/ui/app.slint:1811`](../ui/dr-ui/ui/app.slint#L1811), [`ui/dr-ui/ui/app.slint:517`](../ui/dr-ui/ui/app.slint#L517), [`ui/dr-ui/ui/app.slint:548`](../ui/dr-ui/ui/app.slint#L548), [`ui/dr-ui/ui/app.slint:633`](../ui/dr-ui/ui/app.slint#L633), [`ui/dr-ui/ui/gestures.slint:1`](../ui/dr-ui/ui/gestures.slint#L1), [`ui/dr-ui/ui/library.slint:1067`](../ui/dr-ui/ui/library.slint#L1067), [`ui/dr-ui/ui/library.slint:1234`](../ui/dr-ui/ui/library.slint#L1234), [`ui/dr-ui/ui/library.slint:1259`](../ui/dr-ui/ui/library.slint#L1259), [`ui/dr-ui/ui/library.slint:1266`](../ui/dr-ui/ui/library.slint#L1266), [`ui/dr-ui/ui/library.slint:1322`](../ui/dr-ui/ui/library.slint#L1322), [`ui/dr-ui/ui/library.slint:1329`](../ui/dr-ui/ui/library.slint#L1329), [`ui/dr-ui/ui/library.slint:2561`](../ui/dr-ui/ui/library.slint#L2561), [`ui/dr-ui/ui/library.slint:3866`](../ui/dr-ui/ui/library.slint#L3866), [`ui/dr-ui/ui/library.slint:842`](../ui/dr-ui/ui/library.slint#L842), [`ui/dr-ui/ui/library.slint:892`](../ui/dr-ui/ui/library.slint#L892), [`ui/dr-ui/ui/library.slint:898`](../ui/dr-ui/ui/library.slint#L898), [`ui/dr-ui/ui/library.slint:917`](../ui/dr-ui/ui/library.slint#L917) | +| FR-UI-5 | [`ui/dr-ui/src/collections_ui.rs:1`](../ui/dr-ui/src/collections_ui.rs#L1), [`ui/dr-ui/src/lib.rs:2653`](../ui/dr-ui/src/lib.rs#L2653), [`ui/dr-ui/src/lib.rs:3255`](../ui/dr-ui/src/lib.rs#L3255), [`ui/dr-ui/src/lib.rs:3440`](../ui/dr-ui/src/lib.rs#L3440), [`ui/dr-ui/src/masks_ui.rs:863`](../ui/dr-ui/src/masks_ui.rs#L863), [`ui/dr-ui/ui/app.slint:120`](../ui/dr-ui/ui/app.slint#L120), [`ui/dr-ui/ui/collections.slint:4`](../ui/dr-ui/ui/collections.slint#L4) | | FR-UI-6 | [`ui/dr-ui/ui/widgets.slint:1`](../ui/dr-ui/ui/widgets.slint#L1) | | FR-UI-7 | [`core/dr-pipeline/src/descriptor.rs:177`](../core/dr-pipeline/src/descriptor.rs#L177), [`core/dr-pipeline/src/framing.rs:385`](../core/dr-pipeline/src/framing.rs#L385) | | NFR-ARCH-2 | [`core/dr-catalog/src/jobs.rs:1`](../core/dr-catalog/src/jobs.rs#L1), [`ui/dr-ui/src/faces.rs:1`](../ui/dr-ui/src/faces.rs#L1), [`ui/dr-ui/src/library.rs:3069`](../ui/dr-ui/src/library.rs#L3069) | -| NFR-ARCH-3 | [`ui/dr-ui/src/export.rs:1553`](../ui/dr-ui/src/export.rs#L1553), [`ui/dr-ui/src/export.rs:1579`](../ui/dr-ui/src/export.rs#L1579), [`ui/dr-ui/src/export.rs:409`](../ui/dr-ui/src/export.rs#L409), [`ui/dr-ui/src/export.rs:435`](../ui/dr-ui/src/export.rs#L435), [`ui/dr-ui/src/lib.rs:2344`](../ui/dr-ui/src/lib.rs#L2344), [`ui/dr-ui/ui/app.slint:1074`](../ui/dr-ui/ui/app.slint#L1074), [`ui/dr-ui/ui/library.slint:967`](../ui/dr-ui/ui/library.slint#L967) | +| NFR-ARCH-3 | [`ui/dr-ui/src/export.rs:1553`](../ui/dr-ui/src/export.rs#L1553), [`ui/dr-ui/src/export.rs:1579`](../ui/dr-ui/src/export.rs#L1579), [`ui/dr-ui/src/export.rs:409`](../ui/dr-ui/src/export.rs#L409), [`ui/dr-ui/src/export.rs:435`](../ui/dr-ui/src/export.rs#L435), [`ui/dr-ui/src/lib.rs:2350`](../ui/dr-ui/src/lib.rs#L2350), [`ui/dr-ui/ui/app.slint:1075`](../ui/dr-ui/ui/app.slint#L1075), [`ui/dr-ui/ui/library.slint:967`](../ui/dr-ui/ui/library.slint#L967) | | NFR-ARCH-4 | [`core/dr-catalog/src/error.rs:1`](../core/dr-catalog/src/error.rs#L1), [`core/dr-export/src/error.rs:1`](../core/dr-export/src/error.rs#L1), [`core/dr-thumbs/src/error.rs:1`](../core/dr-thumbs/src/error.rs#L1), [`platform/dr-plat/src/storage.rs:148`](../platform/dr-plat/src/storage.rs#L148), [`ui/dr-ui/src/export.rs:499`](../ui/dr-ui/src/export.rs#L499) | | NFR-OPS-1 | [`tools/traceability/src/gestures.rs:1`](../tools/traceability/src/gestures.rs#L1), [`tools/traceability/src/lib.rs:268`](../tools/traceability/src/lib.rs#L268) | | NFR-OPS-3 | [`core/dr-types/src/settings.rs:1`](../core/dr-types/src/settings.rs#L1), [`ui/dr-ui/src/settings_store.rs:1`](../ui/dr-ui/src/settings_store.rs#L1) | | NFR-P1 | [`core/dr-catalog/src/lib.rs:1`](../core/dr-catalog/src/lib.rs#L1), [`core/dr-catalog/src/scan.rs:1`](../core/dr-catalog/src/scan.rs#L1), [`core/dr-catalog/src/walk.rs:162`](../core/dr-catalog/src/walk.rs#L162), [`core/dr-catalog/src/walk.rs:1`](../core/dr-catalog/src/walk.rs#L1), [`tools/traceability/src/lib.rs:481`](../tools/traceability/src/lib.rs#L481) | | NFR-P13 | [`core/dr-decode/src/preview.rs:121`](../core/dr-decode/src/preview.rs#L121) | -| NFR-P14 | [`core/dr-gpu/src/focus.rs:186`](../core/dr-gpu/src/focus.rs#L186), [`core/dr-gpu/src/focus.rs:1`](../core/dr-gpu/src/focus.rs#L1), [`core/dr-gpu/src/focus.rs:317`](../core/dr-gpu/src/focus.rs#L317), [`core/dr-gpu/src/shaders/focus_peak.wgsl:1`](../core/dr-gpu/src/shaders/focus_peak.wgsl#L1), [`ui/dr-ui/src/develop.rs:3046`](../ui/dr-ui/src/develop.rs#L3046), [`ui/dr-ui/src/lib.rs:1710`](../ui/dr-ui/src/lib.rs#L1710) | +| NFR-P14 | [`core/dr-gpu/src/focus.rs:186`](../core/dr-gpu/src/focus.rs#L186), [`core/dr-gpu/src/focus.rs:1`](../core/dr-gpu/src/focus.rs#L1), [`core/dr-gpu/src/focus.rs:317`](../core/dr-gpu/src/focus.rs#L317), [`core/dr-gpu/src/shaders/focus_peak.wgsl:1`](../core/dr-gpu/src/shaders/focus_peak.wgsl#L1), [`ui/dr-ui/src/develop.rs:3046`](../ui/dr-ui/src/develop.rs#L3046), [`ui/dr-ui/src/lib.rs:1716`](../ui/dr-ui/src/lib.rs#L1716) | | NFR-P5 | [`core/dr-catalog/src/schema.rs:330`](../core/dr-catalog/src/schema.rs#L330), [`ui/dr-ui/src/library.rs:4132`](../ui/dr-ui/src/library.rs#L4132), [`ui/dr-ui/src/library.rs:5066`](../ui/dr-ui/src/library.rs#L5066), [`ui/dr-ui/src/library_ui.rs:4198`](../ui/dr-ui/src/library_ui.rs#L4198), [`ui/dr-ui/src/library_ui.rs:64`](../ui/dr-ui/src/library_ui.rs#L64) | | NFR-P9 | [`ui/dr-ui/src/collections_ui.rs:1`](../ui/dr-ui/src/collections_ui.rs#L1), [`ui/dr-ui/src/export.rs:942`](../ui/dr-ui/src/export.rs#L942), [`ui/dr-ui/src/library.rs:1`](../ui/dr-ui/src/library.rs#L1), [`ui/dr-ui/src/library_ui.rs:1`](../ui/dr-ui/src/library_ui.rs#L1), [`ui/dr-ui/src/trash.rs:1`](../ui/dr-ui/src/trash.rs#L1) | | NFR-PORT-1 | [`core/dr-catalog/src/walk.rs:1`](../core/dr-catalog/src/walk.rs#L1), [`core/dr-types/src/lib.rs:270`](../core/dr-types/src/lib.rs#L270), [`core/dr-types/src/lib.rs:303`](../core/dr-types/src/lib.rs#L303), [`platform/dr-plat/src/display.rs:1`](../platform/dr-plat/src/display.rs#L1), [`platform/dr-plat/src/storage.rs:1`](../platform/dr-plat/src/storage.rs#L1), [`platform/dr-plat/src/storage.rs:216`](../platform/dr-plat/src/storage.rs#L216), [`platform/dr-plat/src/storage.rs:287`](../platform/dr-plat/src/storage.rs#L287), [`platform/dr-plat/src/storage.rs:344`](../platform/dr-plat/src/storage.rs#L344), [`platform/dr-plat/src/volumes.rs:1`](../platform/dr-plat/src/volumes.rs#L1), [`platform/dr-plat/src/volumes.rs:62`](../platform/dr-plat/src/volumes.rs#L62) | diff --git a/ui/dr-ui/src/lib.rs b/ui/dr-ui/src/lib.rs index e7c3364..aebae15 100644 --- a/ui/dr-ui/src/lib.rs +++ b/ui/dr-ui/src/lib.rs @@ -93,20 +93,26 @@ const MAX_DISPLAY_DIM: u32 = 2048; /// compact layout exactly as a tablet in portrait would. const EXPANDED_MIN_WIDTH: f32 = 820.0; -/// TRACES: FR-UI-2 +/// TRACES: FR-UI-1 /// The largest share of the window the develop column may take. /// -/// The column sizes itself to the widest thing it holds — the generated mode -/// strip, the Copy/Paste pair, the histogram's axis labels — so on a rich -/// operation set it would otherwise keep growing. This is where that stops. -/// The majority of the window stays with the photograph, which is what the -/// column is there to serve. +/// A policy, not a size. The column is a fixed `panel-width` (`style.yaml`), +/// so on any window with room for it this does nothing at all — it bites only +/// where 360px would be most of the screen, and what it says there is that the +/// majority of the window stays with the photograph the column exists to +/// serve. +/// +/// It used to do more, because the column used to size itself to the widest +/// thing it held and could therefore grow without limit on a rich operation +/// set. It cannot any more; this is the remaining half of that guard, kept for +/// the case the fixed width does not cover. const PANEL_MAX_FRACTION: f32 = 0.45; /// The floor under that share, so a narrow window still gets a usable column /// rather than one squeezed below the width its own controls were drawn for. -/// Matches the 280px the column asks for at minimum: below this the cap would -/// be doing the clipping the cap exists to avoid. +/// Under `panel-width` by design: between the two the column narrows from 360 +/// to 280 on a small window and stops, which is the range the sliders inside +/// it stay accurate over. const PANEL_MIN_WIDTH: f32 = 280.0; /// How long after the last change a draft frame is replaced by a sharp one. @@ -3231,7 +3237,7 @@ fn apply_layout_class(window: &AppWindow, width: f32, panels: &PanelChoices) { window.set_expanded(expanded); window.set_layout_class(if expanded { "expanded" } else { "compact" }.into()); - // FR-UI-2: the ceiling on the develop column, computed here for the same + // FR-UI-1: the ceiling on the develop column, computed here for the same // reason the class is — a width that both derives from and feeds the // layout is a binding loop in Slint. window.set_panel_max_width((width * PANEL_MAX_FRACTION).max(PANEL_MIN_WIDTH)); diff --git a/ui/dr-ui/style.yaml b/ui/dr-ui/style.yaml index 8f09731..f7d35a7 100644 --- a/ui/dr-ui/style.yaml +++ b/ui/dr-ui/style.yaml @@ -187,6 +187,55 @@ lengths: Floor on button width, so a one-word label is still a comfortable target and a row of buttons has an even rhythm. + _develop: + section: the develop view's two fixed columns + note: | + Both are *mandated* sizes rather than measured ones, which is the + opposite of how the rest of this interface is laid out, and the reason + is that these two flank the photograph. Everything else may grow to fit + its contents; a column beside the image cannot, because the pixels it + takes come out of the picture and a control gaining a word is not a + reason to give the photograph less room. + + What that costs is that a panel wider than the number below clips, and + the Flickables inside it are what make the overflow reachable. That is + the trade being made deliberately: a control you may have to scroll to + is worse than one you can see, and a photograph that changes size when + you switch tools is worse than both. + + rail-width: + value: 60 + doc: | + The tool rail down the left of the develop view. Wide enough for a 20px + icon over a `text-sm` label at the longest name in the table, and narrow + enough to stay a rail rather than becoming a third panel. + rail-entry-height: + value: 54 + doc: | + One tool in that rail. Over `touch-target`, because unlike the controls + inside a panel these are not crowding anything — the rail holds four + entries on a screen with room for a dozen. + + panel-width: + value: 360 + doc: | + The develop column on the other side. One number for tablet and desktop + alike, replacing the 280 the first was drawn for and the 380 the second + was — the alternative is a column that changes width with the window, + which is a photograph that changes size when you resize by a pixel. + + **Measured, not chosen.** The column's contents report a minimum width of + 344 in every mode — photo, local and repair alike — and below that they + do not compress, they clip: a `Text` that does not elide reports the same + minimum as preferred, and most of this column is text. 320 was tried + first and sliced "Paste" down the middle. So this is that floor plus + enough not to be sitting on it. + + To re-measure after changing a panel, bind a `Text` in `app.slint` to + `column.min-width` and read it off the running app; there is no way to + get the number out of the layout engine short of asking it. + + swatch: value: 12 note: | diff --git a/ui/dr-ui/ui/adjust.slint b/ui/dr-ui/ui/adjust.slint index ecbb95d..17dbaf1 100644 --- a/ui/dr-ui/ui/adjust.slint +++ b/ui/dr-ui/ui/adjust.slint @@ -541,21 +541,6 @@ export component GeometryPanel inherits Rectangle { callback portrait-toggled(); callback reset(); - /// TRACES: FR-UI-2 - /// How wide this panel has to be before it starts clipping itself. - /// - /// Every panel in the develop column declares one, and the column takes - /// the largest — that is the whole of how the column is sized. It replaced - /// two guessed constants (280px for a tablet, 380px for a desktop) that - /// could not track a panel gaining a control, and did not. - /// - /// Published as `min-width` as well as read by name: the first is what - /// makes the enclosing layout aggregate these automatically, including for - /// the panels that come and go with the mode and so cannot be referenced - /// from outside their `if`. - out property content-width: layout.preferred-width; - min-width: root.content-width; - height: layout.preferred-height; layout := VerticalLayout { @@ -738,15 +723,6 @@ export component TransferPanel inherits VerticalLayout { /// same thought given a name — this edit, kept. callback open-presets(); - /// TRACES: FR-UI-2 - /// How wide this panel has to be before it starts clipping itself — the - /// same question every panel in the develop column answers. - /// - /// No `min-width` beside it, unlike the others: this component *is* a - /// layout, so it already reports its own minimum to whatever contains it, - /// and a `min-width` bound to its own preferred size is a binding loop. - out property content-width: self.preferred-width; - padding: Theme.gap; spacing: Theme.gap-sm; @@ -817,24 +793,22 @@ export enum ViewMode { spots, } -/// The strip: what the photographer is working on. +/// The group strip: which kind of adjustment the column is showing. /// -/// Two kinds of entry, deliberately together. +/// One kind of entry, which is the change. This was `ModeStrip` and carried +/// two: the canvas tools — crop, local, repair — as filled chips, and the +/// adjustment groups as underlined words, in a single row that asked the eye +/// to tell a mode from a filter by the shape of its highlight. The tools are +/// in `ToolRail` now (`toolrail.slint`, which carries the reasoning), and what +/// is left here is one row of one thing. /// -/// **Modes** — crop and local — change the canvas as well as the column. They -/// are drawn as chips and lit with the accent, which means *active* everywhere -/// else in this interface and means exactly that here. -/// -/// **Groups** — the rest — filter the adjustments to one kind. They are -/// underlined instead, because the accent is already spoken for and because -/// they are a different sort of state: a mode is something you are *in*, a -/// group is something you are *looking at*. -/// -/// Keeping them apart visually is what lets them be independent. Picking a -/// group in local mode filters the selected layer's chain and does not leave -/// the mode, so "Light" means the same thing wherever it is pressed — the -/// alternative, where a group press silently dropped the scope, would be the -/// §1.1 fault reintroduced from the other end. +/// A group is something you are *looking at*, not something you are *in*, and +/// that distinction is now made by the two controls being in different places +/// rather than by two treatments of one control. It is also why the two stay +/// independent: picking a group while a tool is held filters the selected +/// layer's chain and does not put the tool down, so "Light" means the same +/// thing wherever it is pressed — the alternative, where a group press +/// silently dropped the scope, would be the §1.1 fault from the other end. /// /// **Pinned above the scrolling column, not inside a panel.** It began inside /// `AdjustPanel`, which put it below five other panels and off the bottom of a @@ -844,29 +818,15 @@ export enum ViewMode { /// /// **This file names no group.** The strings arrive already resolved from /// whatever the operations declared themselves to be about, so a new operation -/// joins a group without an edit here (FR-DEV-3a). The two modes are not -/// operations — crop is a gesture on the canvas and local is a scope — so -/// naming them breaks nothing. -export component ModeStrip inherits Rectangle { +/// joins a group without an edit here (FR-DEV-3a). With the tools gone there is +/// no longer any hand-written word in this row at all, save "All". +export component GroupStrip inherits Rectangle { in property <[string]> tabs; /// Index into `tabs`, or -1 for "everything". in property active-tab: -1; - in property mode: ViewMode.photo; in property enabled: true; callback picked(int); - callback mode-picked(ViewMode); - - /// How much width this row actually needs, for the column that pins it. - /// - /// Read rather than guessed: the chips are one per mode plus one per group - /// the operation set declares, so the number is generated and no constant - /// in the column could stay in step with it. The Flickable below is still - /// the answer when the column cannot be given that much — it is the floor - /// under a control that must never become unreachable — but it is no longer - /// the *first* answer, which is what made a generated row into a row you - /// had to know to pan. - out property content-width: layout.preferred-width; background: Theme.surface; height: root.enabled ? layout.preferred-height : 0px; @@ -874,9 +834,15 @@ export component ModeStrip inherits Rectangle { // Scrolls rather than overflowing, exactly as the develop status strip // does and for the same reason: a `HorizontalLayout` given less width than - // its children need does not shrink them, it runs off the end. Two modes - // plus however many groups the operation set declares is already more than - // a 280px column holds, and the column is where this is pinned. + // its children need does not shrink them, it runs off the end. + // + // This is now the *only* answer, and it is the right one here. The column + // this sits in is a mandated width (`panel-width` in `style.yaml`) while + // the row's contents are one word per group the operation set declares — + // generated, and so unbounded in principle. It used to publish a + // `content-width` that the column sized itself from, which made a rich + // operation set quietly take width from the photograph. A row that pans is + // the price of a photograph that does not move. Flickable { width: 100%; height: 100%; @@ -890,67 +856,17 @@ export component ModeStrip inherits Rectangle { spacing: Theme.gap-sm; alignment: start; - // A chip per mode. Drawn as an outline that fills when active rather - // than as an underline, so at a glance the strip reads as two runs - // and it is never ambiguous which half a lit entry belongs to. + // **Where a canvas tool goes: not here.** A mode that arms a gesture + // on the photograph is a row in `ToolRail`'s table, one file over. // - // **Where a canvas tool goes.** A mode that arms a gesture on the - // photograph and scopes the column joins this list and the `ViewMode` - // enum, and needs nothing else here. *Repair* is the first to arrive - // that way (FR-DEV-8); painting a mask is the same shape and still to - // come — `MaskSource::Brush` and the stroke calls on `MaskLayer` - // already exist in the core, and what is missing on this side is only - // the canvas interaction the repairs now have a pattern for. - for entry in [ - { label: "Crop", value: ViewMode.crop }, - { label: "Local", value: ViewMode.local }, - { label: "Repair", value: ViewMode.spots }, - ]: mode-chip := TouchArea { - width: mode-name.preferred-width + 2 * Theme.gap-sm; - height: Theme.touch-target; - mouse-cursor: pointer; - - property on: root.mode == entry.value; - - // Pressing the mode you are already in leaves it, which is what - // makes the strip the way out as well as the way in — the same - // control both directions, as the crop button was. - clicked => { - root.mode-picked(self.on ? ViewMode.photo : entry.value); - } - - Rectangle { - y: (parent.height - self.height) / 2; - height: Theme.control-height; - width: parent.width; - border-radius: Theme.radius; - border-width: 1px; - border-color: mode-chip.on ? Theme.active : Theme.rule; - background: mode-chip.on - ? Theme.active-dim - : (mode-chip.has-hover ? Theme.hover : transparent); - } - - mode-name := Text { - text: entry.label; - // Dark on the lit fill, which is near-white: the same - // inversion `Button`'s primary state makes. - color: mode-chip.on ? Theme.ground : Theme.ink-dim; - font-size: Theme.text-sm; - font-weight: 600; - vertical-alignment: center; - horizontal-alignment: center; - } - } - - // The divider between the two kinds. One pixel, and it is what stops - // the strip reading as one undifferentiated row of five words. - Rectangle { - width: 1px; - height: Theme.touch-target; - background: Theme.rule; - } - + // Three of them used to sit at the head of this row as filled chips, + // with a one-pixel divider after them. Both are gone, and nothing has + // replaced them — no heading, no lead-in. A run of words with one + // underlined is a tab bar, which is exactly what this is, and it needs + // saying only while there is something else in the row to be told + // apart from. The width that buys back is the point: this row pans + // when the operation set is rich, so anything permanently occupying + // its left-hand end is paid for by every group after the third. all := TouchArea { width: 34px; height: Theme.touch-target; @@ -1069,18 +985,12 @@ export component AdjustPanel inherits Rectangle { /// scrolls as one, so the panel reports the drag and the column obeys it. out property slider-dragging: false; - /// TRACES: FR-UI-2 - /// How wide this panel has to be before it starts clipping itself. The - /// develop column is the largest of these and nothing else; publishing it - /// as `min-width` too is what makes the enclosing layout aggregate them - /// without this panel having to be referenced by name. - /// - /// The sliders are the part that matters. Each is a label, a value and a - /// track, and a track squeezed below the width its handle needs is a - /// control that cannot be set accurately — which is the whole job. - out property content-width: layout.preferred-width; - min-width: root.content-width; - + // **The sliders are what `panel-width` was chosen against.** No panel gets + // a say in the column's width any more — it is one number in `style.yaml` + // — but this is the panel that number has to be right for. Each row is a + // label, a value and a track, and a track squeezed below the width its + // handle needs is a control that cannot be set accurately, which is the + // whole job. If the column is ever narrowed, narrow it against this. layout := VerticalLayout { padding: Theme.gap; spacing: Theme.gap-sm; diff --git a/ui/dr-ui/ui/app.slint b/ui/dr-ui/ui/app.slint index 6dfeb4c..7d21dbb 100644 --- a/ui/dr-ui/ui/app.slint +++ b/ui/dr-ui/ui/app.slint @@ -1,5 +1,5 @@ import { Theme } from "theme.slint"; -import { AdjustPanel, GeometryPanel, ModeStrip, ParamRow, TransferPanel, ViewMode } from "adjust.slint"; +import { AdjustPanel, GeometryPanel, GroupStrip, ParamRow, TransferPanel, ViewMode } from "adjust.slint"; import { GradientHandle, GradientHandles, HandleRole, MaskPanel, MaskRow, SubjectRow } from "masks.slint"; import { SpotHandle, SpotHandles, SpotPanel, SpotRole } from "spots.slint"; import { CropOverlay } from "crop.slint"; @@ -16,6 +16,7 @@ import { FocusMarks, FocusPanel } from "peaking.slint"; import { SettingsPage } from "settings.slint"; import { ImportPage } from "import.slint"; import { StatusBar, InfoPanel } from "develop.slint"; +import { ToolRail } from "toolrail.slint"; export { LibraryCell, TimelineBar, CollectionRow, ActivityRow, HistogramView, PersonChip } export { GestureRow } @@ -1675,6 +1676,31 @@ in property panel-visible: true; } HorizontalLayout { + // **The tools, on the far side from their consequences.** + // + // A fixed rail rather than a row of chips inside the develop + // column, which is where these three used to live. The column + // can be put away — that is the whole point of the toggle in + // the strip above — and putting the tools away with it meant + // the way *out* of crop disappeared along with the way in. + // Hence the "Done Cropping" button floating over the canvas + // below: one control duplicated to paper over the other being + // reachable only sometimes. + // + // The rail does not close, so a tool can always be put down + // where it was picked up. `toolrail.slint` has the rest of the + // reasoning and the table that generates it. + // + // Not conditioned on `total > 0` from out here: the rail + // collapses itself on `enabled`, and an `if` in this layout is + // the shape that has caused binding loops in this file before + // (see the develop column below). + ToolRail { + enabled: root.total > 0 && root.load-error == ""; + mode: root.view-mode; + picked(m) => { root.mode-picked(m); } + } + // The canvas: compute output composited directly. No CPU // round-trip anywhere in this path (ARCH §6.1). canvas-area := Rectangle { @@ -2052,12 +2078,19 @@ in property panel-visible: true; // beside what it is reporting on. Crop moved to the panel // because it is an edit, and edits live with the other edits. // - // A way out of whichever mode is on is still reachable from - // here — the develop column may be closed on a narrow - // window, and the strip that enters a mode is pinned inside - // it. Stranding the user in a mode with no visible way out - // is worse than one duplicated control, and it is worse - // still now that there are two modes to be stranded in. + // **"Done" is no longer here because it has to be.** It was: + // the control that entered a mode was pinned inside the + // develop column, the column closes, and stranding someone + // in crop with no visible way out was worse than one + // duplicated control. The tool rail does not close, so that + // reason has gone. + // + // It stays because of where it is. Finishing a crop is a + // decision *about the photograph*, taken while looking at + // the photograph, and a confirmation the width of the + // window away from the thing being confirmed is a + // confirmation you take on trust. The rail is now the + // second way out rather than the first. if root.total > 0 && root.load-error == "": HorizontalLayout { x: 12px; y: parent.height - self.preferred-height - 12px; @@ -2126,55 +2159,54 @@ in property panel-visible: true; // width, which the layout then influences. Slint flags it, and // it can panic at runtime. develop-column := Rectangle { - // TRACES: FR-UI-2 - // **As wide as what it holds.** + // TRACES: FR-UI-1 + // **One width, stated once, and not measured.** // - // It was 280px, chosen for a tablet where the column is a - // large fraction of the screen and every pixel of it is - // taken from the photograph. That was too narrow on a - // desktop, so a second number — 380px — was added for the - // expanded class. Both were guesses at how much room the - // widest row in this column needs, and a guess is exactly - // what cannot be right here: the mode strip is two modes, a - // separator, "All", and one chip per attribute the - // operation set *declares*, so the row is generated and no - // constant in this file can track it. When the guess came - // up short the strip scrolled sideways, and a control you - // have to pan to reach is one you do not know is there. + // This column used to size itself from its contents: every + // panel published a `content-width`, declared it as its own + // `min-width`, and the column took the largest. That was an + // answer to a real problem — before it, the width was two + // guessed constants (280px for a tablet, 380px for a + // desktop) and the generated chip row outgrew both, so a + // control ended up somewhere you had to pan to find. // - // **So the column asks instead.** Every panel that can - // appear in it publishes a `content-width` — how wide it - // has to be before it clips itself — and also declares that - // as its `min-width`. The `min-width` is what makes this - // aggregate on its own: `column` below is a layout, so it - // already reports the largest minimum among its children, - // and it does so for the panels that come and go with the - // mode as well, which sit inside `if`s and cannot be named - // from out here. Grep `content-width` in this directory to - // see every panel that has a say. + // **It solved that by making the photograph pay.** The + // pixels a sidebar takes come out of the picture beside it, + // and a measured sidebar spends them on whatever happens to + // be widest: an axis label gaining a digit made the image + // smaller, and switching tools swapped one set of panels for + // another and shifted the image sideways under the eye + // that was judging it. In an application whose entire job is + // showing you a photograph accurately, the frame around it + // must not move because a caption changed. // - // The mode strip is named explicitly only because it is - // pinned *outside* that layout, so nothing else would - // measure it. + // So the number is mandated: `panel-width`, in + // `style.yaml`, next to the reasoning and next to the rail + // on the other side, which is fixed for the same reason. A + // panel that wants more than that clips, and the Flickable + // below is what makes the rest of it reachable — the same + // fallback as before, now the first answer rather than the + // last. `AdjustPanel` is the panel the number was chosen + // against; its note says why. // - // There is no floor. A floor is another guess, and the - // panels state their own minimums now. The one thing left - // over the measurement is `panel-max-width` — not a size - // but a policy, that a column may not take the window from - // the photograph it exists to serve — and past that the - // Flickables inside are the fallback, as they have always - // been. It comes from Rust rather than from `root.width` - // because reading the window width inside the layout that - // sets it is the binding loop the comment on `expanded` - // above describes; Rust already measures the window for - // `layout-class`, so this is one more thing said in the - // same breath. - property content-width: max( - develop-strip.content-width, - column.preferred-width, - ); + // The generated row that started all this is not a problem + // any more either, because it is no longer in the column's + // way: the tools moved to `ToolRail` and what is left is + // group filters, which pan within their own strip without + // anything else having to move. + // + // `panel-max-width` survives, and it is the one thing here + // that is not a size: it is the policy that a column may + // not take the window from the photograph it exists to + // serve, and it bites only on a window narrow enough that + // 360px would. It comes from Rust rather than from + // `root.width` because reading the window width inside the + // layout that sets it is the binding loop the comment on + // `expanded` above describes; Rust already measures the + // window for `layout-class`, so this is one more thing said + // in the same breath. width: root.panel-visible - ? min(root.panel-max-width, self.content-width) + ? min(root.panel-max-width, Theme.panel-width) : 0px; visible: root.panel-visible; background: Theme.surface; @@ -2201,13 +2233,11 @@ in property panel-visible: true; // would both sit at its origin and overlap. The strip is pinned by // being outside the Flickable rather than by any coordinate. VerticalLayout { - develop-strip := ModeStrip { + GroupStrip { enabled: root.adjust-enabled; - mode: root.view-mode; tabs: root.adjust-tabs; active-tab: root.adjust-active-tab; picked(i) => { root.adjust-tab-picked(i); } - mode-picked(m) => { root.mode-picked(m); } } Flickable { @@ -2226,12 +2256,40 @@ in property panel-visible: true; // the far side. It looked like a rendering fault // and it was an alignment one. // - // Floored at the Flickable's own width so the - // ordinary case — a column sized to fit, which is - // now every case the cap does not bite — puts the - // content at x: 0 and stretches it, rather than - // leaving it preferred-width and adrift. - viewport-width: max(self.width, column.preferred-width); + // **`min-width`, not `preferred-width`, and that is + // what makes a mandated column work at all.** + // + // With the preferred width here, the content laid + // itself out at whatever size it would have liked + // and the column clipped the difference: Paste came + // out sliced down the middle and the panel's reset + // was over the window's edge. That is the same + // fault as above wearing a different hat — the + // content was never told how much room it had, so + // it could not adapt to having less. + // + // The floor is the layout's *minimum* instead. A + // preferred width is what a panel would enjoy; a + // minimum is what it cannot go below, and between + // the two the layout does the work it exists to do + // — rows tighten, stretches give way — so the + // column fits because it was asked to rather than + // by luck. + // + // That does less here than it sounds like, and it + // is worth knowing why: this column's minimum and + // its preferred width are within a few pixels of + // each other, because a `Text` that does not elide + // reports the same for both and most of what is in + // here is text. So `panel-width` still has to be a + // number the contents actually fit in — see its + // note in `style.yaml` for the measurement. What + // this binding buys is that the clipping, when it + // comes, is of a panel that genuinely cannot + // shrink rather than of one that simply was not + // asked to, and that panning is then a real + // fallback rather than a permanent condition. + viewport-width: max(self.width, column.min-width); interactive: !adjust.slider-dragging; // **What the column holds is the mode's answer.** @@ -2569,7 +2627,7 @@ in property panel-visible: true; // thing the dialogue covers. // TRACES: FR-DEV-6 // Over the shell rather than inside a view, because both views open - // it — and because the develop column is 320px wide, which is not + // it — and because the develop column is 360px wide, which is not // enough to list presets and rename one in. if root.presets-open: PresetSheet { width: 100%; diff --git a/ui/dr-ui/ui/controls.slint b/ui/dr-ui/ui/controls.slint index cee8045..0282927 100644 --- a/ui/dr-ui/ui/controls.slint +++ b/ui/dr-ui/ui/controls.slint @@ -492,7 +492,7 @@ export component FieldRow inherits HorizontalLayout { // // **The chip width is fixed, not a share of the container's.** Dividing // `self.width` looks right and clips: the develop column sets its width to -// `min(panel-max-width, content-width)` with `clip: true`, so when the policy +// `min(panel-max-width, panel-width)` with `clip: true`, so when the policy // bites, `self.width` here is the width that was *asked for* and the visible // column is narrower. export component ChipGrid inherits Rectangle { diff --git a/ui/dr-ui/ui/develop.slint b/ui/dr-ui/ui/develop.slint index d460aed..cbb3643 100644 --- a/ui/dr-ui/ui/develop.slint +++ b/ui/dr-ui/ui/develop.slint @@ -220,14 +220,6 @@ export component InfoPanel inherits Rectangle { in property exposure; in property dimensions; - /// TRACES: FR-UI-2 - /// How wide this panel has to be before it starts clipping itself. The - /// develop column is the largest of these and nothing else; publishing it - /// as `min-width` too is what makes the enclosing layout aggregate them - /// without this panel having to be referenced by name. - out property content-width: panel.preferred-width; - min-width: root.content-width; - background: transparent; height: panel.preferred-height; diff --git a/ui/dr-ui/ui/histogram.slint b/ui/dr-ui/ui/histogram.slint index 086c549..ee92358 100644 --- a/ui/dr-ui/ui/histogram.slint +++ b/ui/dr-ui/ui/histogram.slint @@ -77,8 +77,12 @@ export struct HistogramView { // FR-CULL-3 is written for. // // Kept short in Rust, and that is a layout constraint: `FieldRow` draws - // the hint as an unwrapped Text, so its natural width becomes this panel's - // preferred width and the develop column takes the largest of those. + // the hint as an unwrapped Text, and a Text that does not elide reports + // the same *minimum* width as preferred. The develop column no longer + // takes the largest of those — it is a mandated `panel-width` — which + // makes this constraint sharper rather than softer: an over-long hint no + // longer widens the column, it pushes the column's minimum past the width + // it has and clips the panel instead. hint: string, // What the plot says when there is nothing to draw. Never "0%" and never @@ -183,22 +187,20 @@ export component HistogramPanel inherits Rectangle { /// two above it, so there is exactly one place the choice is made. property shown: root.mode == 1 ? root.raw-data : root.data; - - /// TRACES: FR-UI-2 - /// How wide this panel has to be before it starts clipping itself. - /// - /// Every panel in the develop column declares one, and the column takes - /// the largest — that is the whole of how the column is sized. It replaced - /// two guessed constants (280px for a tablet, 380px for a desktop) that - /// could not track a panel gaining a control, and did not. - /// - /// Published as `min-width` as well as read by name: the first is what - /// makes the enclosing layout aggregate these automatically, including for - /// the panels that come and go with the mode and so cannot be referenced - /// from outside their `if`. - out property content-width: panel.preferred-width; - min-width: root.content-width; - + // **This panel does not get a say in how wide the column is.** + // + // It used to: every panel in the develop column published a + // `content-width`, the column took the largest, and that was the whole of + // how the column was sized. The trouble is what the column is next to. A + // sidebar measured from its contents takes its width out of the + // photograph, so an axis label gaining a digit made the picture smaller, + // and switching tools swapped one set of panels for another and moved the + // image sideways on the screen. + // + // The column is `panel-width` now, stated once in `style.yaml`. A panel + // that wants more than that clips, and the Flickable the column puts + // around this is what makes the rest reachable. See the `_develop` note in + // `style.yaml` for the trade. background: transparent; height: panel.preferred-height; diff --git a/ui/dr-ui/ui/history.slint b/ui/dr-ui/ui/history.slint index 4a79145..9acad69 100644 --- a/ui/dr-ui/ui/history.slint +++ b/ui/dr-ui/ui/history.slint @@ -115,14 +115,6 @@ export component HistoryPanel inherits Rectangle { // No explicit height either, for the same reason `AdjustPanel` and // `MaskPanel` declare none: the row count changes as the photographer // works, and a height pinned to a layout's preferred size is one more - /// TRACES: FR-UI-2 - /// How wide this panel has to be before it starts clipping itself. The - /// develop column is the largest of these and nothing else; publishing it - /// as `min-width` too is what makes the enclosing layout aggregate them - /// without this panel having to be referenced by name. - out property content-width: layout.preferred-width; - min-width: root.content-width; - // thing that has to keep up with a repeater. layout := VerticalLayout { padding: Theme.gap; diff --git a/ui/dr-ui/ui/icons.slint b/ui/dr-ui/ui/icons.slint index cf4d946..65ffdae 100644 --- a/ui/dr-ui/ui/icons.slint +++ b/ui/dr-ui/ui/icons.slint @@ -59,6 +59,7 @@ component Ink inherits Path { // rotate-ccw rotate-cw flip-h flip-v // collection collection-smart // offline offline-held +// photo crop mask repair export component Icon inherits Rectangle { in property name; /// The single colour the whole drawing takes. Named `ink` rather than @@ -285,4 +286,64 @@ export component Icon inherits Rectangle { stroke-width: root.weight; commands: "M 4.2 15.4 L 19.8 15.4 L 19.8 19.8 L 4.2 19.8 Z"; } + + // --- develop tools ----------------------------------------------------- + // + // One per entry in `ToolRail`'s table (toolrail.slint). They are drawn at + // 20px in a rail that is nothing but icons, which is larger than anything + // else in this file gets — and they need it. A rail is *scanned*, not + // read: the label under each one confirms a guess the silhouette has + // already made, and if the silhouette makes no guess the label is doing + // all the work and the icon is decoration. + // + // So they are told apart by outline rather than by interior detail. Three + // of the four deliberately break the frame the fourth sits inside. + + // The whole photograph: a frame with a horizon in it. The default tool, so + // it is the most literal drawing here — it means "nothing is armed", and + // the way to say that is to show the subject with nothing laid over it. + if root.name == "photo": Ink { + stroke: root.ink; + stroke-width: root.weight; + commands: "M 3.4 5.2 L 20.6 5.2 L 20.6 18.8 L 3.4 18.8 Z " + + "M 3.4 15.4 L 8.8 10 L 13 14.2 L 15.8 11.4 L 20.6 16.2"; + } + + // Crop marks: two overlapping right angles, the shape every editor uses. + // Drawn out to the edge of the view box on purpose — a crop is the one + // tool here that acts on the frame rather than within it. + if root.name == "crop": Ink { + stroke: root.ink; + stroke-width: root.weight; + commands: "M 7.4 2.6 L 7.4 16.6 L 21.4 16.6 " + + "M 2.6 7.4 L 16.6 7.4 L 16.6 21.4"; + } + + // A local adjustment: the half-filled circle that means "this side and not + // that one" wherever tone is edited. The fill carries it — an outlined + // circle is a shape, a half-filled one is a *selection* — and the two + // halves are the same circle, so nothing shifts if the pair is ever drawn + // in different colours. + if root.name == "mask": Ink { + stroke: root.ink; + stroke-width: root.weight; + commands: "M 12 3.6 A 8.4 8.4 0 1 0 12 20.4 A 8.4 8.4 0 1 0 12 3.6 Z"; + } + if root.name == "mask": Ink { + fill: root.ink; + stroke-width: root.weight; + commands: "M 12 3.6 A 8.4 8.4 0 0 1 12 20.4 Z"; + } + + // TRACES: FR-DEV-8 + // A repair: two circles, one sampling into the other. That is literally + // what a spot is here — a source and a destination, which is why its + // handles on the canvas come in pairs — so the icon is the tool's own data + // rather than a metaphor borrowed from a plaster or a rubber stamp. + if root.name == "repair": Ink { + stroke: root.ink; + stroke-width: root.weight; + commands: "M 4.6 14.8 A 5 5 0 1 0 14.6 14.8 A 5 5 0 1 0 4.6 14.8 Z " + + "M 11.8 9 A 4 4 0 1 0 19.8 9 A 4 4 0 1 0 11.8 9 Z"; + } } diff --git a/ui/dr-ui/ui/masks.slint b/ui/dr-ui/ui/masks.slint index aacccea..f3bf94f 100644 --- a/ui/dr-ui/ui/masks.slint +++ b/ui/dr-ui/ui/masks.slint @@ -311,14 +311,6 @@ export component MaskPanel inherits Rectangle { // the "Find regions" button — the sort of fault that is invisible in the // source and obvious the moment anyone looks at the panel. Conditioning // each child on its own keeps every element a direct child of one layout, - /// TRACES: FR-UI-2 - /// How wide this panel has to be before it starts clipping itself. The - /// develop column is the largest of these and nothing else; publishing it - /// as `min-width` too is what makes the enclosing layout aggregate them - /// without this panel having to be referenced by name. - out property content-width: layout.preferred-width; - min-width: root.content-width; - // which is the layout that measures them. layout := VerticalLayout { padding: Theme.gap; diff --git a/ui/dr-ui/ui/peaking.slint b/ui/dr-ui/ui/peaking.slint index 3821e55..e9b7e51 100644 --- a/ui/dr-ui/ui/peaking.slint +++ b/ui/dr-ui/ui/peaking.slint @@ -79,18 +79,12 @@ export component FocusPanel inherits Rectangle { background: Theme.surface; - /// TRACES: FR-UI-2 - /// How wide this panel has to be before it clips itself. The develop - /// column is the largest of these and nothing else; see `SpotPanel` and - /// `HistogramPanel` for the whole protocol. - /// - /// Both chip rows wrap at three, which is what keeps this number at the - /// narrowest column the application supports rather than at four chips - /// abreast — a single row of four would set the width of the entire - /// sidebar for every other panel in it. - out property content-width: layout.preferred-width; - min-width: root.content-width; - + // Both chip rows wrap at three rather than running four abreast. That was + // once about not setting the sidebar's width for every other panel in it; + // the column is a mandated `panel-width` now and no panel sets it, so what + // the wrap buys today is simply that these fit inside it rather than + // needing to be panned to. + // // Flat rather than nested, for the reason `SpotPanel` and `MaskPanel` both // give: a nested conditional layout under-reports its height here and the // rows below it get drawn on top of one another. Every row carries its own @@ -140,9 +134,11 @@ export component FocusPanel inherits Rectangle { // frame cannot be measured for sharpness (see `FocusPeakPass`). // // Kept to one short sentence on purpose. A wrapping Text reports - // its *unwrapped* width as its preferred one, and this panel's - // `content-width` is what the develop column sizes itself from — - // a paragraph here would hold the whole sidebar open. + // its *unwrapped* width as its preferred one, so a paragraph here + // makes this panel's preferred width the length of the paragraph. + // That no longer drags the sidebar open with it — the column is a + // mandated width — but it does still decide how much of the row + // the panel wants, and a sentence is the honest amount to ask for. text: "Marks pause while a control is dragged."; wrap: word-wrap; } diff --git a/ui/dr-ui/ui/spots.slint b/ui/dr-ui/ui/spots.slint index 4bb7cec..b654978 100644 --- a/ui/dr-ui/ui/spots.slint +++ b/ui/dr-ui/ui/spots.slint @@ -85,14 +85,6 @@ export component SpotPanel inherits Rectangle { background: Theme.surface; - /// TRACES: FR-UI-2 - /// How wide this panel has to be before it starts clipping itself. The - /// develop column is the largest of these and nothing else; publishing it - /// as `min-width` too is what makes the enclosing layout aggregate them - /// without this panel having to be referenced by name. - out property content-width: layout.preferred-width; - min-width: root.content-width; - // Flat rather than nested, for the reason `MaskPanel` gives: a nested // conditional layout under-reported its height and drew rows on top of one // another. diff --git a/ui/dr-ui/ui/toolrail.slint b/ui/dr-ui/ui/toolrail.slint new file mode 100644 index 0000000..da913f8 --- /dev/null +++ b/ui/dr-ui/ui/toolrail.slint @@ -0,0 +1,195 @@ +// The develop view's tool rail: which tool the photographer is holding. +// +// **One table, one file.** Everything that decides what this rail contains is +// the array literal in `TOOLS` below. A tool is a row in it — an icon name, a +// word, and the `ViewMode` it arms — and adding one is that row plus a drawing +// in `icons.slint` plus a variant on the enum. Nothing in `app.slint` is +// touched, nothing here is per-tool, and there is no second list anywhere that +// could fall out of step with this one. That is the whole design: the rail is +// generated, so it cannot be *partly* updated. +// +// **Why it left the chip strip.** These four used to be chips at the top of +// the develop column, sharing a row with the adjustment groups — two kinds of +// state in one strip, told apart by the shape of their highlight. Three things +// were wrong with that, and only the third is about tidiness: +// +// 1. The column can be put away. The strip went with it, so the way *out* of +// crop went away with the way in, and the fix was a second "Done +// Cropping" button floating over the canvas — one control duplicated +// because the first one was reachable only sometimes. +// 2. The strip sized the column. Its chips are generated from the operation +// set, so the widest thing in the develop sidebar was a row nobody had +// chosen the contents of, and a richer operation set silently took width +// from the photograph. +// 3. A mode and a filter are not the same kind of thing. "Crop" changes what +// a click on the photograph does; "Light" changes which sliders are on +// screen. Putting them in one row and distinguishing them by underline +// versus fill asks the eye to carry a distinction the layout could just +// make. +// +// The rail is always up, so (1) is gone; it is a fixed width that no operation +// set can influence, so (2) is gone; and it is somewhere else entirely, so (3) +// is gone. What is left in the column is a row of group filters and nothing +// else — see `GroupStrip` in `adjust.slint`. +// +// **Down the left, not the right.** The develop column is on the right and +// holds the *consequences* of a choice — the sliders the tool exposes. The +// choice itself goes on the far side, so the eye's path across the window is +// tool, photograph, adjustment, in that order, and the rail never moves when +// the column opens and closes beside it. + +import { Theme } from "theme.slint"; +import { Icon } from "icons.slint"; +import { ViewMode } from "adjust.slint"; + +// One tool. A struct rather than four parallel arrays so a row cannot be +// half-added — the compiler will not let a new entry omit its icon. +struct Tool { + /// A name from `icons.slint`'s vocabulary. A typo here draws nothing, + /// which is loud: the entry becomes a label with a hole above it. + icon: string, + /// What it is called. One word — see `rail-width` in `style.yaml`. + label: string, + /// What arming it puts the canvas into. + mode: ViewMode, +} + +export component ToolRail inherits Rectangle { + /// Which tool is held. Owned by Rust, like every other piece of session + /// state: the rail asks for a mode and is told what the mode became, so a + /// change made anywhere else — the keyboard, the back gesture, the button + /// over the canvas — lights the same entry. + in property mode: ViewMode.photo; + /// Whether there is a photograph to point a tool at. The rail collapses + /// rather than greying out: an empty develop view has no tools, and four + /// dead icons beside a blank canvas suggest otherwise. + in property enabled: true; + + callback picked(ViewMode); + + // **The table.** Add a row to get a tool. + // + // Order is the order they appear, and it is not arbitrary: `photo` first + // because it is the resting state and the way back from everywhere else, + // then the three that arm a gesture on the canvas, roughly in the order a + // photograph is worked — frame it, then adjust parts of it, then clean it + // up. + // + // `MaskSource::Brush` is the next one to land here. The core already has + // the stroke calls; what is missing is the canvas interaction, and when it + // arrives this file's share of the work is one line. + private property <[Tool]> tools: [ + { icon: "photo", label: "Photo", mode: ViewMode.photo }, + { icon: "crop", label: "Crop", mode: ViewMode.crop }, + { icon: "mask", label: "Local", mode: ViewMode.local }, + { icon: "repair", label: "Repair", mode: ViewMode.spots }, + ]; + + // TRACES: FR-UI-1 + // Fixed, and the point of the exercise. This rail flanks the photograph, + // so its width is taken out of the picture — and a rail measured from its + // contents would hand that decision to whichever tool label happens to be + // longest. `style.yaml` carries the number and the reasoning. + width: root.enabled ? Theme.rail-width : 0px; + visible: root.enabled; + background: Theme.surface; + clip: true; + + // No Flickable. Every other strip in this view has one, because every + // other strip is generated from something the user's data decides and can + // therefore outgrow its space. This list is four entries written in this + // file, running down an axis with a whole window of room — the shortest + // supported window fits fourteen. If that ever stops being true the answer + // is a rail that scrolls, not a rail that overflows, and this comment is + // where to start. + VerticalLayout { + padding-top: Theme.gap-sm; + spacing: 0px; + alignment: start; + + for tool in root.tools: entry := TouchArea { + height: Theme.rail-entry-height; + mouse-cursor: pointer; + + property on: root.mode == tool.mode; + + // Pressing the tool you are holding puts it down, exactly as the + // chips did: the same control both directions. `photo` is the + // exception — it *is* putting the tool down, so pressing it while + // it is lit is a no-op rather than a toggle into itself. + clicked => { + root.picked(entry.on ? ViewMode.photo : tool.mode); + } + + // The lit tile, and the only marker there is. Inset from the + // rail's edges so the run of four reads as four things rather than + // as one striped column. + // + // A bright bar against the outer edge was tried alongside it, on + // the theory that a rail is scanned from the side and needs + // something unambiguous. It is not needed and it is not + // unambiguous: `active-dim` is near-white and `hover` is a shade + // above the surface, so the held tool and a tool under the pointer + // are not two similar greys — they are opposite ends of the + // palette. The bar sat against the lit tile and merged with it. + Rectangle { + x: Theme.gap-sm / 2; + width: parent.width - Theme.gap-sm; + height: parent.height - 2px; + y: 1px; + border-radius: Theme.radius; + background: entry.on + ? Theme.active-dim + : (entry.has-hover ? Theme.hover : transparent); + } + + VerticalLayout { + alignment: center; + spacing: 3px; + + HorizontalLayout { + alignment: center; + Icon { + name: tool.icon; + size: 20px; + // Dark on the lit tile, which is near-white: the same + // inversion `Button`'s primary state makes, and the + // same one the chips made before this. + ink: entry.on + ? Theme.ground + : (entry.has-hover ? Theme.ink : Theme.ink-dim); + } + } + + // Named, not just drawn. An icon-only rail is a quiz — these + // four are conventional enough to guess and not conventional + // enough to be sure of, and "sure" is what a tool that changes + // what a click does has to be. The word is `text-sm` and dim, + // so it reads as the icon's caption rather than as a button in + // its own right. + Text { + text: tool.label; + font-size: Theme.text-sm; + color: entry.on + ? Theme.ground + : (entry.has-hover ? Theme.ink : Theme.ink-faint); + horizontal-alignment: center; + // Elided rather than wrapped: a two-line label would make + // this entry taller than the three beside it, and a rail + // whose rows are different heights reads as a list of + // unrelated things. + overflow: elide; + } + } + } + } + + // The rail's own edge. Drawn here rather than by whatever contains it, so + // the rail is a complete thing wherever it is put — and on the right, + // where it meets the canvas. + Rectangle { + x: parent.width - 1px; + width: 1px; + background: Theme.rule; + } +}