From 20c368d3fca72522797105803cf3c465026a6506 Mon Sep 17 00:00:00 2001 From: Duncan Tourolle Date: Sun, 30 Aug 2026 00:09:37 +0200 Subject: [PATCH] Give each touch gesture one meaning, and give tap-to-open back MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit I broke opening a photograph. The dwell added in "Tell a tap on a photograph from a hand going past" required a finger to stay down 120 ms, and a deliberate tap is routinely quicker than that — so the grid stopped opening anything. Duration was the wrong discriminator: a tap and a brush are the same length. **Travel is what separates them, and a graze is by definition a moving contact.** A press now records where it landed and the release compares: within 12px it is a tap, beyond that the hand was going somewhere else. No dwell, so no deliberate tap can be refused, and the rule is the same for a finger and a mouse — one rule instead of two, and the `touch` argument the dwell needed goes away with it. Two real conflicts went with it, because a gesture set that overlaps itself is unlearnable however each half is documented. **A drag was also a hold.** Grabbing a cell and moving inside 450 ms left the hold timer armed underneath the drag, so it fired mid-gesture and put the grid into selection mode nobody asked for — the drag finished into a mode that changed what every later tap meant. Starting a drag now cancels it, exactly as a pinch already did. **A double tap was also a range.** In selection mode two taps on one cell selected everything back to where selecting began: no visible state, no warning, from a thing a hand does by accident. "Select to…" does that job and announces itself first, so the double tap is gone and two taps are now two toggles that land where they started. `extend_to_row` went with it — a second range implementation that only the double tap reached, where every other range goes through `apply_press`. The resulting vocabulary, one meaning each: tap opens, tap-and-slide does nothing, hold starts selecting, drag files, two fingers resize, and while selecting a tap only ever toggles. Co-Authored-By: Claude Opus 5 (1M context) --- docs/traceability.md | 60 +++--- ui/dr-ui/src/collections_ui.rs | 322 ++++++--------------------------- ui/dr-ui/src/library_ui.rs | 8 +- ui/dr-ui/ui/app.slint | 8 +- ui/dr-ui/ui/library.slint | 162 ++++++++++++++--- 5 files changed, 223 insertions(+), 337 deletions(-) diff --git a/docs/traceability.md b/docs/traceability.md index afdcf7c..37537b7 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 | 301 | -| TRACES tags found | 989 | +| Source files scanned | 303 | +| TRACES tags found | 986 | | Requirements defined | 179 | | Requirements covered | 120 | | **Coverage** | **67.0%** (120/179) | @@ -33,59 +33,59 @@ _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:479`](../tools/traceability/src/lib.rs#L479), [`tools/traceability/src/lib.rs:511`](../tools/traceability/src/lib.rs#L511), [`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-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:1205`](../ui/dr-ui/src/lib.rs#L1205), [`ui/dr-ui/ui/import.slint:5`](../ui/dr-ui/ui/import.slint#L5), [`ui/dr-ui/ui/library.slint:1051`](../ui/dr-ui/ui/library.slint#L1051), [`ui/dr-ui/ui/library.slint:1218`](../ui/dr-ui/ui/library.slint#L1218), [`ui/dr-ui/ui/library.slint:886`](../ui/dr-ui/ui/library.slint#L886) | | 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:1205`](../ui/dr-ui/src/lib.rs#L1205), [`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:1307`](../ui/dr-ui/src/collections_ui.rs#L1307), [`ui/dr-ui/src/collections_ui.rs:2221`](../ui/dr-ui/src/collections_ui.rs#L2221), [`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-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:1226`](../ui/dr-ui/src/collections_ui.rs#L1226), [`ui/dr-ui/src/collections_ui.rs:2099`](../ui/dr-ui/src/collections_ui.rs#L2099), [`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:479`](../tools/traceability/src/lib.rs#L479) | -| 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:3709`](../ui/dr-ui/src/library_ui.rs#L3709), [`ui/dr-ui/src/library_ui.rs:4715`](../ui/dr-ui/src/library_ui.rs#L4715), [`ui/dr-ui/ui/app.slint:374`](../ui/dr-ui/ui/app.slint#L374), [`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-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:3709`](../ui/dr-ui/src/library_ui.rs#L3709), [`ui/dr-ui/src/library_ui.rs:4709`](../ui/dr-ui/src/library_ui.rs#L4709), [`ui/dr-ui/ui/app.slint:374`](../ui/dr-ui/ui/app.slint#L374), [`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:1650`](../ui/dr-ui/src/collections_ui.rs#L1650), [`ui/dr-ui/src/collections_ui.rs:1756`](../ui/dr-ui/src/collections_ui.rs#L1756), [`ui/dr-ui/src/collections_ui.rs:1805`](../ui/dr-ui/src/collections_ui.rs#L1805), [`ui/dr-ui/src/collections_ui.rs:254`](../ui/dr-ui/src/collections_ui.rs#L254), [`ui/dr-ui/src/collections_ui.rs:383`](../ui/dr-ui/src/collections_ui.rs#L383), [`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:6642`](../ui/dr-ui/src/library_ui.rs#L6642), [`ui/dr-ui/src/library_ui.rs:6653`](../ui/dr-ui/src/library_ui.rs#L6653), [`ui/dr-ui/src/library_ui.rs:6666`](../ui/dr-ui/src/library_ui.rs#L6666), [`ui/dr-ui/src/library_ui.rs:6681`](../ui/dr-ui/src/library_ui.rs#L6681), [`ui/dr-ui/src/library_ui.rs:6690`](../ui/dr-ui/src/library_ui.rs#L6690), [`ui/dr-ui/ui/app.slint:310`](../ui/dr-ui/ui/app.slint#L310), [`ui/dr-ui/ui/app.slint:509`](../ui/dr-ui/ui/app.slint#L509), [`ui/dr-ui/ui/library.slint:1275`](../ui/dr-ui/ui/library.slint#L1275), [`ui/dr-ui/ui/library.slint:1299`](../ui/dr-ui/ui/library.slint#L1299), [`ui/dr-ui/ui/library.slint:1341`](../ui/dr-ui/ui/library.slint#L1341), [`ui/dr-ui/ui/library.slint:18`](../ui/dr-ui/ui/library.slint#L18), [`ui/dr-ui/ui/library.slint:879`](../ui/dr-ui/ui/library.slint#L879), [`ui/dr-ui/ui/library.slint:931`](../ui/dr-ui/ui/library.slint#L931) | -| 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:5382`](../ui/dr-ui/src/library_ui.rs#L5382), [`ui/dr-ui/src/library_ui.rs:5435`](../ui/dr-ui/src/library_ui.rs#L5435), [`ui/dr-ui/src/library_ui.rs:6782`](../ui/dr-ui/src/library_ui.rs#L6782), [`ui/dr-ui/ui/app.slint:322`](../ui/dr-ui/ui/app.slint#L322), [`ui/dr-ui/ui/app.slint:509`](../ui/dr-ui/ui/app.slint#L509), [`ui/dr-ui/ui/app.slint:803`](../ui/dr-ui/ui/app.slint#L803), [`ui/dr-ui/ui/library.slint:109`](../ui/dr-ui/ui/library.slint#L109), [`ui/dr-ui/ui/library.slint:1434`](../ui/dr-ui/ui/library.slint#L1434), [`ui/dr-ui/ui/library.slint:931`](../ui/dr-ui/ui/library.slint#L931), [`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:1669`](../ui/dr-ui/src/collections_ui.rs#L1669), [`ui/dr-ui/src/collections_ui.rs:1919`](../ui/dr-ui/src/collections_ui.rs#L1919), [`ui/dr-ui/src/collections_ui.rs:1`](../ui/dr-ui/src/collections_ui.rs#L1), [`ui/dr-ui/src/collections_ui.rs:987`](../ui/dr-ui/src/collections_ui.rs#L987), [`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:3571`](../ui/dr-ui/src/library_ui.rs#L3571), [`ui/dr-ui/src/library_ui.rs:4298`](../ui/dr-ui/src/library_ui.rs#L4298), [`ui/dr-ui/ui/app.slint:313`](../ui/dr-ui/ui/app.slint#L313), [`ui/dr-ui/ui/app.slint:504`](../ui/dr-ui/ui/app.slint#L504), [`ui/dr-ui/ui/collections.slint:4`](../ui/dr-ui/ui/collections.slint#L4), [`ui/dr-ui/ui/library.slint:2871`](../ui/dr-ui/ui/library.slint#L2871), [`ui/dr-ui/ui/library.slint:902`](../ui/dr-ui/ui/library.slint#L902), [`ui/dr-ui/ui/library.slint:921`](../ui/dr-ui/ui/library.slint#L921) | -| 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:3720`](../ui/dr-ui/src/develop.rs#L3720), [`ui/dr-ui/src/develop.rs:3749`](../ui/dr-ui/src/develop.rs#L3749), [`ui/dr-ui/src/export.rs:750`](../ui/dr-ui/src/export.rs#L750), [`ui/dr-ui/src/lib.rs:1484`](../ui/dr-ui/src/lib.rs#L1484), [`ui/dr-ui/src/lib.rs:1941`](../ui/dr-ui/src/lib.rs#L1941), [`ui/dr-ui/src/lib.rs:2076`](../ui/dr-ui/src/lib.rs#L2076), [`ui/dr-ui/src/lib.rs:563`](../ui/dr-ui/src/lib.rs#L563), [`ui/dr-ui/src/lib.rs:988`](../ui/dr-ui/src/lib.rs#L988), [`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:5007`](../ui/dr-ui/src/library_ui.rs#L5007), [`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:3147`](../ui/dr-ui/src/develop.rs#L3147), [`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:2414`](../ui/dr-ui/src/library_ui.rs#L2414), [`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:2852`](../ui/dr-ui/src/library_ui.rs#L2852), [`ui/dr-ui/src/library_ui.rs:3074`](../ui/dr-ui/src/library_ui.rs#L3074), [`ui/dr-ui/src/library_ui.rs:3352`](../ui/dr-ui/src/library_ui.rs#L3352), [`ui/dr-ui/src/library_ui.rs:3440`](../ui/dr-ui/src/library_ui.rs#L3440), [`ui/dr-ui/src/library_ui.rs:3622`](../ui/dr-ui/src/library_ui.rs#L3622), [`ui/dr-ui/src/library_ui.rs:3736`](../ui/dr-ui/src/library_ui.rs#L3736), [`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:5480`](../ui/dr-ui/src/library_ui.rs#L5480), [`ui/dr-ui/src/library_ui.rs:5595`](../ui/dr-ui/src/library_ui.rs#L5595), [`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-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:1519`](../ui/dr-ui/src/collections_ui.rs#L1519), [`ui/dr-ui/src/collections_ui.rs:1625`](../ui/dr-ui/src/collections_ui.rs#L1625), [`ui/dr-ui/src/collections_ui.rs:1674`](../ui/dr-ui/src/collections_ui.rs#L1674), [`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:6636`](../ui/dr-ui/src/library_ui.rs#L6636), [`ui/dr-ui/src/library_ui.rs:6647`](../ui/dr-ui/src/library_ui.rs#L6647), [`ui/dr-ui/src/library_ui.rs:6660`](../ui/dr-ui/src/library_ui.rs#L6660), [`ui/dr-ui/src/library_ui.rs:6675`](../ui/dr-ui/src/library_ui.rs#L6675), [`ui/dr-ui/src/library_ui.rs:6684`](../ui/dr-ui/src/library_ui.rs#L6684), [`ui/dr-ui/ui/app.slint:310`](../ui/dr-ui/ui/app.slint#L310), [`ui/dr-ui/ui/app.slint:509`](../ui/dr-ui/ui/app.slint#L509), [`ui/dr-ui/ui/library.slint:1283`](../ui/dr-ui/ui/library.slint#L1283), [`ui/dr-ui/ui/library.slint:1307`](../ui/dr-ui/ui/library.slint#L1307), [`ui/dr-ui/ui/library.slint:1360`](../ui/dr-ui/ui/library.slint#L1360), [`ui/dr-ui/ui/library.slint:18`](../ui/dr-ui/ui/library.slint#L18), [`ui/dr-ui/ui/library.slint:879`](../ui/dr-ui/ui/library.slint#L879), [`ui/dr-ui/ui/library.slint:931`](../ui/dr-ui/ui/library.slint#L931) | +| 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:5376`](../ui/dr-ui/src/library_ui.rs#L5376), [`ui/dr-ui/src/library_ui.rs:5429`](../ui/dr-ui/src/library_ui.rs#L5429), [`ui/dr-ui/src/library_ui.rs:6776`](../ui/dr-ui/src/library_ui.rs#L6776), [`ui/dr-ui/ui/app.slint:322`](../ui/dr-ui/ui/app.slint#L322), [`ui/dr-ui/ui/app.slint:509`](../ui/dr-ui/ui/app.slint#L509), [`ui/dr-ui/ui/app.slint:802`](../ui/dr-ui/ui/app.slint#L802), [`ui/dr-ui/ui/library.slint:109`](../ui/dr-ui/ui/library.slint#L109), [`ui/dr-ui/ui/library.slint:1453`](../ui/dr-ui/ui/library.slint#L1453), [`ui/dr-ui/ui/library.slint:931`](../ui/dr-ui/ui/library.slint#L931), [`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:1538`](../ui/dr-ui/src/collections_ui.rs#L1538), [`ui/dr-ui/src/collections_ui.rs:1788`](../ui/dr-ui/src/collections_ui.rs#L1788), [`ui/dr-ui/src/collections_ui.rs:1`](../ui/dr-ui/src/collections_ui.rs#L1), [`ui/dr-ui/src/collections_ui.rs:922`](../ui/dr-ui/src/collections_ui.rs#L922), [`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:3571`](../ui/dr-ui/src/library_ui.rs#L3571), [`ui/dr-ui/src/library_ui.rs:4298`](../ui/dr-ui/src/library_ui.rs#L4298), [`ui/dr-ui/ui/app.slint:313`](../ui/dr-ui/ui/app.slint#L313), [`ui/dr-ui/ui/app.slint:504`](../ui/dr-ui/ui/app.slint#L504), [`ui/dr-ui/ui/collections.slint:4`](../ui/dr-ui/ui/collections.slint#L4), [`ui/dr-ui/ui/library.slint:2924`](../ui/dr-ui/ui/library.slint#L2924), [`ui/dr-ui/ui/library.slint:902`](../ui/dr-ui/ui/library.slint#L902), [`ui/dr-ui/ui/library.slint:921`](../ui/dr-ui/ui/library.slint#L921) | +| 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:3720`](../ui/dr-ui/src/develop.rs#L3720), [`ui/dr-ui/src/develop.rs:3749`](../ui/dr-ui/src/develop.rs#L3749), [`ui/dr-ui/src/export.rs:750`](../ui/dr-ui/src/export.rs#L750), [`ui/dr-ui/src/lib.rs:1484`](../ui/dr-ui/src/lib.rs#L1484), [`ui/dr-ui/src/lib.rs:1941`](../ui/dr-ui/src/lib.rs#L1941), [`ui/dr-ui/src/lib.rs:2076`](../ui/dr-ui/src/lib.rs#L2076), [`ui/dr-ui/src/lib.rs:563`](../ui/dr-ui/src/lib.rs#L563), [`ui/dr-ui/src/lib.rs:988`](../ui/dr-ui/src/lib.rs#L988), [`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:5001`](../ui/dr-ui/src/library_ui.rs#L5001), [`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:3147`](../ui/dr-ui/src/develop.rs#L3147), [`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:2414`](../ui/dr-ui/src/library_ui.rs#L2414), [`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:2852`](../ui/dr-ui/src/library_ui.rs#L2852), [`ui/dr-ui/src/library_ui.rs:3074`](../ui/dr-ui/src/library_ui.rs#L3074), [`ui/dr-ui/src/library_ui.rs:3352`](../ui/dr-ui/src/library_ui.rs#L3352), [`ui/dr-ui/src/library_ui.rs:3440`](../ui/dr-ui/src/library_ui.rs#L3440), [`ui/dr-ui/src/library_ui.rs:3622`](../ui/dr-ui/src/library_ui.rs#L3622), [`ui/dr-ui/src/library_ui.rs:3736`](../ui/dr-ui/src/library_ui.rs#L3736), [`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:5474`](../ui/dr-ui/src/library_ui.rs#L5474), [`ui/dr-ui/src/library_ui.rs:5589`](../ui/dr-ui/src/library_ui.rs#L5589), [`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:1944`](../ui/dr-ui/src/develop.rs#L1944), [`ui/dr-ui/src/develop.rs:195`](../ui/dr-ui/src/develop.rs#L195), [`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:2048`](../ui/dr-ui/src/lib.rs#L2048), [`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/shaders/focus_peak.wgsl:1`](../core/dr-gpu/src/shaders/focus_peak.wgsl#L1), [`ui/dr-ui/src/develop.rs:2930`](../ui/dr-ui/src/develop.rs#L2930), [`ui/dr-ui/src/develop.rs:2941`](../ui/dr-ui/src/develop.rs#L2941), [`ui/dr-ui/src/develop.rs:2947`](../ui/dr-ui/src/develop.rs#L2947), [`ui/dr-ui/src/develop.rs:2964`](../ui/dr-ui/src/develop.rs#L2964), [`ui/dr-ui/src/develop.rs:726`](../ui/dr-ui/src/develop.rs#L726), [`ui/dr-ui/src/develop.rs:732`](../ui/dr-ui/src/develop.rs#L732), [`ui/dr-ui/src/lib.rs:1523`](../ui/dr-ui/src/lib.rs#L1523), [`ui/dr-ui/src/lib.rs:1601`](../ui/dr-ui/src/lib.rs#L1601), [`ui/dr-ui/src/lib.rs:1674`](../ui/dr-ui/src/lib.rs#L1674), [`ui/dr-ui/src/lib.rs:1708`](../ui/dr-ui/src/lib.rs#L1708), [`ui/dr-ui/src/lib.rs:2958`](../ui/dr-ui/src/lib.rs#L2958), [`ui/dr-ui/src/lib.rs:323`](../ui/dr-ui/src/lib.rs#L323), [`ui/dr-ui/src/peaking.rs:1`](../ui/dr-ui/src/peaking.rs#L1), [`ui/dr-ui/ui/app.slint:1729`](../ui/dr-ui/ui/app.slint#L1729), [`ui/dr-ui/ui/app.slint:2274`](../ui/dr-ui/ui/app.slint#L2274), [`ui/dr-ui/ui/app.slint:75`](../ui/dr-ui/ui/app.slint#L75), [`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/shaders/focus_peak.wgsl:1`](../core/dr-gpu/src/shaders/focus_peak.wgsl#L1), [`ui/dr-ui/src/develop.rs:2930`](../ui/dr-ui/src/develop.rs#L2930), [`ui/dr-ui/src/develop.rs:2941`](../ui/dr-ui/src/develop.rs#L2941), [`ui/dr-ui/src/develop.rs:2947`](../ui/dr-ui/src/develop.rs#L2947), [`ui/dr-ui/src/develop.rs:2964`](../ui/dr-ui/src/develop.rs#L2964), [`ui/dr-ui/src/develop.rs:726`](../ui/dr-ui/src/develop.rs#L726), [`ui/dr-ui/src/develop.rs:732`](../ui/dr-ui/src/develop.rs#L732), [`ui/dr-ui/src/lib.rs:1523`](../ui/dr-ui/src/lib.rs#L1523), [`ui/dr-ui/src/lib.rs:1601`](../ui/dr-ui/src/lib.rs#L1601), [`ui/dr-ui/src/lib.rs:1674`](../ui/dr-ui/src/lib.rs#L1674), [`ui/dr-ui/src/lib.rs:1708`](../ui/dr-ui/src/lib.rs#L1708), [`ui/dr-ui/src/lib.rs:2958`](../ui/dr-ui/src/lib.rs#L2958), [`ui/dr-ui/src/lib.rs:323`](../ui/dr-ui/src/lib.rs#L323), [`ui/dr-ui/src/peaking.rs:1`](../ui/dr-ui/src/peaking.rs#L1), [`ui/dr-ui/ui/app.slint:1727`](../ui/dr-ui/ui/app.slint#L1727), [`ui/dr-ui/ui/app.slint:2272`](../ui/dr-ui/ui/app.slint#L2272), [`ui/dr-ui/ui/app.slint:75`](../ui/dr-ui/ui/app.slint#L75), [`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:260`](../ui/dr-ui/ui/identity.slint#L260) | +| 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:1448`](../ui/dr-ui/src/develop.rs#L1448), [`ui/dr-ui/src/develop.rs:164`](../ui/dr-ui/src/develop.rs#L164), [`ui/dr-ui/src/develop.rs:1926`](../ui/dr-ui/src/develop.rs#L1926), [`ui/dr-ui/src/develop.rs:1944`](../ui/dr-ui/src/develop.rs#L1944), [`ui/dr-ui/src/develop.rs:1958`](../ui/dr-ui/src/develop.rs#L1958), [`ui/dr-ui/src/develop.rs:1980`](../ui/dr-ui/src/develop.rs#L1980), [`ui/dr-ui/src/develop.rs:2126`](../ui/dr-ui/src/develop.rs#L2126), [`ui/dr-ui/src/develop.rs:2224`](../ui/dr-ui/src/develop.rs#L2224), [`ui/dr-ui/src/develop.rs:327`](../ui/dr-ui/src/develop.rs#L327), [`ui/dr-ui/src/develop.rs:3418`](../ui/dr-ui/src/develop.rs#L3418), [`ui/dr-ui/src/develop.rs:3448`](../ui/dr-ui/src/develop.rs#L3448), [`ui/dr-ui/src/develop.rs:3514`](../ui/dr-ui/src/develop.rs#L3514), [`ui/dr-ui/src/develop.rs:3528`](../ui/dr-ui/src/develop.rs#L3528), [`ui/dr-ui/src/develop.rs:364`](../ui/dr-ui/src/develop.rs#L364), [`ui/dr-ui/src/develop.rs:3720`](../ui/dr-ui/src/develop.rs#L3720), [`ui/dr-ui/src/develop.rs:4380`](../ui/dr-ui/src/develop.rs#L4380), [`ui/dr-ui/src/develop.rs:4434`](../ui/dr-ui/src/develop.rs#L4434), [`ui/dr-ui/src/develop.rs:4478`](../ui/dr-ui/src/develop.rs#L4478), [`ui/dr-ui/src/develop.rs:4528`](../ui/dr-ui/src/develop.rs#L4528), [`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:746`](../ui/dr-ui/src/develop.rs#L746), [`ui/dr-ui/src/develop.rs:793`](../ui/dr-ui/src/develop.rs#L793), [`ui/dr-ui/src/develop.rs:822`](../ui/dr-ui/src/develop.rs#L822), [`ui/dr-ui/src/lib.rs:1582`](../ui/dr-ui/src/lib.rs#L1582), [`ui/dr-ui/src/lib.rs:2351`](../ui/dr-ui/src/lib.rs#L2351), [`ui/dr-ui/src/lib.rs:2547`](../ui/dr-ui/src/lib.rs#L2547), [`ui/dr-ui/src/lib.rs:2719`](../ui/dr-ui/src/lib.rs#L2719), [`ui/dr-ui/src/lib.rs:2783`](../ui/dr-ui/src/lib.rs#L2783), [`ui/dr-ui/src/lib.rs:2837`](../ui/dr-ui/src/lib.rs#L2837), [`ui/dr-ui/src/lib.rs:329`](../ui/dr-ui/src/lib.rs#L329), [`ui/dr-ui/src/lib.rs:372`](../ui/dr-ui/src/lib.rs#L372), [`ui/dr-ui/src/lib.rs:395`](../ui/dr-ui/src/lib.rs#L395), [`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:136`](../ui/dr-ui/ui/app.slint#L136), [`ui/dr-ui/ui/app.slint:182`](../ui/dr-ui/ui/app.slint#L182), [`ui/dr-ui/ui/app.slint:1931`](../ui/dr-ui/ui/app.slint#L1931), [`ui/dr-ui/ui/app.slint:913`](../ui/dr-ui/ui/app.slint#L913), [`ui/dr-ui/ui/masks.slint:524`](../ui/dr-ui/ui/masks.slint#L524) | +| 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:1448`](../ui/dr-ui/src/develop.rs#L1448), [`ui/dr-ui/src/develop.rs:164`](../ui/dr-ui/src/develop.rs#L164), [`ui/dr-ui/src/develop.rs:1926`](../ui/dr-ui/src/develop.rs#L1926), [`ui/dr-ui/src/develop.rs:1944`](../ui/dr-ui/src/develop.rs#L1944), [`ui/dr-ui/src/develop.rs:1958`](../ui/dr-ui/src/develop.rs#L1958), [`ui/dr-ui/src/develop.rs:1980`](../ui/dr-ui/src/develop.rs#L1980), [`ui/dr-ui/src/develop.rs:2126`](../ui/dr-ui/src/develop.rs#L2126), [`ui/dr-ui/src/develop.rs:2224`](../ui/dr-ui/src/develop.rs#L2224), [`ui/dr-ui/src/develop.rs:327`](../ui/dr-ui/src/develop.rs#L327), [`ui/dr-ui/src/develop.rs:3418`](../ui/dr-ui/src/develop.rs#L3418), [`ui/dr-ui/src/develop.rs:3448`](../ui/dr-ui/src/develop.rs#L3448), [`ui/dr-ui/src/develop.rs:3514`](../ui/dr-ui/src/develop.rs#L3514), [`ui/dr-ui/src/develop.rs:3528`](../ui/dr-ui/src/develop.rs#L3528), [`ui/dr-ui/src/develop.rs:364`](../ui/dr-ui/src/develop.rs#L364), [`ui/dr-ui/src/develop.rs:3720`](../ui/dr-ui/src/develop.rs#L3720), [`ui/dr-ui/src/develop.rs:4380`](../ui/dr-ui/src/develop.rs#L4380), [`ui/dr-ui/src/develop.rs:4434`](../ui/dr-ui/src/develop.rs#L4434), [`ui/dr-ui/src/develop.rs:4478`](../ui/dr-ui/src/develop.rs#L4478), [`ui/dr-ui/src/develop.rs:4528`](../ui/dr-ui/src/develop.rs#L4528), [`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:746`](../ui/dr-ui/src/develop.rs#L746), [`ui/dr-ui/src/develop.rs:793`](../ui/dr-ui/src/develop.rs#L793), [`ui/dr-ui/src/develop.rs:822`](../ui/dr-ui/src/develop.rs#L822), [`ui/dr-ui/src/lib.rs:1582`](../ui/dr-ui/src/lib.rs#L1582), [`ui/dr-ui/src/lib.rs:2351`](../ui/dr-ui/src/lib.rs#L2351), [`ui/dr-ui/src/lib.rs:2547`](../ui/dr-ui/src/lib.rs#L2547), [`ui/dr-ui/src/lib.rs:2719`](../ui/dr-ui/src/lib.rs#L2719), [`ui/dr-ui/src/lib.rs:2783`](../ui/dr-ui/src/lib.rs#L2783), [`ui/dr-ui/src/lib.rs:2837`](../ui/dr-ui/src/lib.rs#L2837), [`ui/dr-ui/src/lib.rs:329`](../ui/dr-ui/src/lib.rs#L329), [`ui/dr-ui/src/lib.rs:372`](../ui/dr-ui/src/lib.rs#L372), [`ui/dr-ui/src/lib.rs:395`](../ui/dr-ui/src/lib.rs#L395), [`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:136`](../ui/dr-ui/ui/app.slint#L136), [`ui/dr-ui/ui/app.slint:182`](../ui/dr-ui/ui/app.slint#L182), [`ui/dr-ui/ui/app.slint:1929`](../ui/dr-ui/ui/app.slint#L1929), [`ui/dr-ui/ui/app.slint:912`](../ui/dr-ui/ui/app.slint#L912), [`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:1345`](../ui/dr-ui/src/develop.rs#L1345), [`ui/dr-ui/src/lib.rs:678`](../ui/dr-ui/src/lib.rs#L678), [`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:5107`](../ui/dr-ui/src/develop.rs#L5107) | | 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:3162`](../ui/dr-ui/src/develop.rs#L3162), [`ui/dr-ui/src/develop.rs:3179`](../ui/dr-ui/src/develop.rs#L3179), [`ui/dr-ui/src/develop.rs:3191`](../ui/dr-ui/src/develop.rs#L3191), [`ui/dr-ui/src/develop.rs:3229`](../ui/dr-ui/src/develop.rs#L3229), [`ui/dr-ui/src/develop.rs:3238`](../ui/dr-ui/src/develop.rs#L3238), [`ui/dr-ui/src/develop.rs:3341`](../ui/dr-ui/src/develop.rs#L3341), [`ui/dr-ui/src/develop.rs:3757`](../ui/dr-ui/src/develop.rs#L3757), [`ui/dr-ui/src/develop.rs:3772`](../ui/dr-ui/src/develop.rs#L3772), [`ui/dr-ui/src/lib.rs:2325`](../ui/dr-ui/src/lib.rs#L2325), [`ui/dr-ui/src/lib.rs:611`](../ui/dr-ui/src/lib.rs#L611), [`ui/dr-ui/src/lib.rs:669`](../ui/dr-ui/src/lib.rs#L669), [`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:2466`](../ui/dr-ui/ui/app.slint#L2466), [`ui/dr-ui/ui/app.slint:641`](../ui/dr-ui/ui/app.slint#L641) | +| 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:3162`](../ui/dr-ui/src/develop.rs#L3162), [`ui/dr-ui/src/develop.rs:3179`](../ui/dr-ui/src/develop.rs#L3179), [`ui/dr-ui/src/develop.rs:3191`](../ui/dr-ui/src/develop.rs#L3191), [`ui/dr-ui/src/develop.rs:3229`](../ui/dr-ui/src/develop.rs#L3229), [`ui/dr-ui/src/develop.rs:3238`](../ui/dr-ui/src/develop.rs#L3238), [`ui/dr-ui/src/develop.rs:3341`](../ui/dr-ui/src/develop.rs#L3341), [`ui/dr-ui/src/develop.rs:3757`](../ui/dr-ui/src/develop.rs#L3757), [`ui/dr-ui/src/develop.rs:3772`](../ui/dr-ui/src/develop.rs#L3772), [`ui/dr-ui/src/lib.rs:2325`](../ui/dr-ui/src/lib.rs#L2325), [`ui/dr-ui/src/lib.rs:611`](../ui/dr-ui/src/lib.rs#L611), [`ui/dr-ui/src/lib.rs:669`](../ui/dr-ui/src/lib.rs#L669), [`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:2464`](../ui/dr-ui/ui/app.slint#L2464), [`ui/dr-ui/ui/app.slint:640`](../ui/dr-ui/ui/app.slint#L640) | | 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:2143`](../ui/dr-ui/src/develop.rs#L2143), [`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:338`](../core/dr-gpu/src/lib.rs#L338), [`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:3191`](../ui/dr-ui/src/develop.rs#L3191), [`ui/dr-ui/src/develop.rs:3772`](../ui/dr-ui/src/develop.rs#L3772), [`ui/dr-ui/src/develop.rs:3802`](../ui/dr-ui/src/develop.rs#L3802), [`ui/dr-ui/src/develop.rs:3815`](../ui/dr-ui/src/develop.rs#L3815), [`ui/dr-ui/src/develop.rs:3827`](../ui/dr-ui/src/develop.rs#L3827), [`ui/dr-ui/src/develop.rs:3843`](../ui/dr-ui/src/develop.rs#L3843), [`ui/dr-ui/src/develop.rs:3875`](../ui/dr-ui/src/develop.rs#L3875), [`ui/dr-ui/src/develop.rs:3879`](../ui/dr-ui/src/develop.rs#L3879), [`ui/dr-ui/src/develop.rs:3898`](../ui/dr-ui/src/develop.rs#L3898), [`ui/dr-ui/src/develop.rs:3914`](../ui/dr-ui/src/develop.rs#L3914), [`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:1517`](../ui/dr-ui/src/lib.rs#L1517), [`ui/dr-ui/src/lib.rs:1560`](../ui/dr-ui/src/lib.rs#L1560), [`ui/dr-ui/src/lib.rs:1568`](../ui/dr-ui/src/lib.rs#L1568), [`ui/dr-ui/src/lib.rs:2521`](../ui/dr-ui/src/lib.rs#L2521), [`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:3714`](../ui/dr-ui/src/develop.rs#L3714), [`ui/dr-ui/src/develop.rs:3735`](../ui/dr-ui/src/develop.rs#L3735), [`ui/dr-ui/src/lib.rs:1484`](../ui/dr-ui/src/lib.rs#L1484), [`ui/dr-ui/src/lib.rs:2136`](../ui/dr-ui/src/lib.rs#L2136), [`ui/dr-ui/src/lib.rs:2165`](../ui/dr-ui/src/lib.rs#L2165), [`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:2674`](../ui/dr-ui/src/library_ui.rs#L2674), [`ui/dr-ui/src/library_ui.rs:3074`](../ui/dr-ui/src/library_ui.rs#L3074), [`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:1509`](../ui/dr-ui/ui/app.slint#L1509), [`ui/dr-ui/ui/app.slint:2555`](../ui/dr-ui/ui/app.slint#L2555), [`ui/dr-ui/ui/app.slint:713`](../ui/dr-ui/ui/app.slint#L713), [`ui/dr-ui/ui/app.slint:724`](../ui/dr-ui/ui/app.slint#L724), [`ui/dr-ui/ui/library.slint:1461`](../ui/dr-ui/ui/library.slint#L1461), [`ui/dr-ui/ui/library.slint:1468`](../ui/dr-ui/ui/library.slint#L1468), [`ui/dr-ui/ui/library.slint:857`](../ui/dr-ui/ui/library.slint#L857), [`ui/dr-ui/ui/library.slint:873`](../ui/dr-ui/ui/library.slint#L873), [`ui/dr-ui/ui/library.slint:942`](../ui/dr-ui/ui/library.slint#L942), [`ui/dr-ui/ui/library.slint:957`](../ui/dr-ui/ui/library.slint#L957), [`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-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:3714`](../ui/dr-ui/src/develop.rs#L3714), [`ui/dr-ui/src/develop.rs:3735`](../ui/dr-ui/src/develop.rs#L3735), [`ui/dr-ui/src/lib.rs:1484`](../ui/dr-ui/src/lib.rs#L1484), [`ui/dr-ui/src/lib.rs:2136`](../ui/dr-ui/src/lib.rs#L2136), [`ui/dr-ui/src/lib.rs:2165`](../ui/dr-ui/src/lib.rs#L2165), [`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:2674`](../ui/dr-ui/src/library_ui.rs#L2674), [`ui/dr-ui/src/library_ui.rs:3074`](../ui/dr-ui/src/library_ui.rs#L3074), [`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:1508`](../ui/dr-ui/ui/app.slint#L1508), [`ui/dr-ui/ui/app.slint:2553`](../ui/dr-ui/ui/app.slint#L2553), [`ui/dr-ui/ui/app.slint:712`](../ui/dr-ui/ui/app.slint#L712), [`ui/dr-ui/ui/app.slint:723`](../ui/dr-ui/ui/app.slint#L723), [`ui/dr-ui/ui/library.slint:1480`](../ui/dr-ui/ui/library.slint#L1480), [`ui/dr-ui/ui/library.slint:1487`](../ui/dr-ui/ui/library.slint#L1487), [`ui/dr-ui/ui/library.slint:857`](../ui/dr-ui/ui/library.slint#L857), [`ui/dr-ui/ui/library.slint:873`](../ui/dr-ui/ui/library.slint#L873), [`ui/dr-ui/ui/library.slint:942`](../ui/dr-ui/ui/library.slint#L942), [`ui/dr-ui/ui/library.slint:957`](../ui/dr-ui/ui/library.slint#L957), [`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:3843`](../ui/dr-ui/src/develop.rs#L3843), [`ui/dr-ui/src/develop.rs:3875`](../ui/dr-ui/src/develop.rs#L3875), [`ui/dr-ui/src/lib.rs:1568`](../ui/dr-ui/src/lib.rs#L1568), [`ui/dr-ui/src/lib.rs:2521`](../ui/dr-ui/src/lib.rs#L2521), [`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:2295`](../ui/dr-ui/src/develop.rs#L2295), [`ui/dr-ui/src/develop.rs:2333`](../ui/dr-ui/src/develop.rs#L2333), [`ui/dr-ui/src/develop.rs:2398`](../ui/dr-ui/src/develop.rs#L2398), [`ui/dr-ui/src/develop.rs:2481`](../ui/dr-ui/src/develop.rs#L2481), [`ui/dr-ui/src/develop.rs:2495`](../ui/dr-ui/src/develop.rs#L2495), [`ui/dr-ui/src/develop.rs:776`](../ui/dr-ui/src/develop.rs#L776), [`ui/dr-ui/src/labels.rs:52`](../ui/dr-ui/src/labels.rs#L52), [`ui/dr-ui/src/lib.rs:1589`](../ui/dr-ui/src/lib.rs#L1589), [`ui/dr-ui/src/lib.rs:2639`](../ui/dr-ui/src/lib.rs#L2639), [`ui/dr-ui/src/lib.rs:334`](../ui/dr-ui/src/lib.rs#L334), [`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:126`](../ui/dr-ui/ui/app.slint#L126), [`ui/dr-ui/ui/app.slint:1834`](../ui/dr-ui/ui/app.slint#L1834), [`ui/dr-ui/ui/app.slint:2009`](../ui/dr-ui/ui/app.slint#L2009), [`ui/dr-ui/ui/app.slint:2372`](../ui/dr-ui/ui/app.slint#L2372), [`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-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:2295`](../ui/dr-ui/src/develop.rs#L2295), [`ui/dr-ui/src/develop.rs:2333`](../ui/dr-ui/src/develop.rs#L2333), [`ui/dr-ui/src/develop.rs:2398`](../ui/dr-ui/src/develop.rs#L2398), [`ui/dr-ui/src/develop.rs:2481`](../ui/dr-ui/src/develop.rs#L2481), [`ui/dr-ui/src/develop.rs:2495`](../ui/dr-ui/src/develop.rs#L2495), [`ui/dr-ui/src/develop.rs:776`](../ui/dr-ui/src/develop.rs#L776), [`ui/dr-ui/src/labels.rs:52`](../ui/dr-ui/src/labels.rs#L52), [`ui/dr-ui/src/lib.rs:1589`](../ui/dr-ui/src/lib.rs#L1589), [`ui/dr-ui/src/lib.rs:2639`](../ui/dr-ui/src/lib.rs#L2639), [`ui/dr-ui/src/lib.rs:334`](../ui/dr-ui/src/lib.rs#L334), [`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:126`](../ui/dr-ui/ui/app.slint#L126), [`ui/dr-ui/ui/app.slint:1832`](../ui/dr-ui/ui/app.slint#L1832), [`ui/dr-ui/ui/app.slint:2007`](../ui/dr-ui/ui/app.slint#L2007), [`ui/dr-ui/ui/app.slint:2370`](../ui/dr-ui/ui/app.slint#L2370), [`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:159`](../core/dr-gpu/src/lib.rs#L159), [`core/dr-gpu/src/lib.rs:179`](../core/dr-gpu/src/lib.rs#L179), [`core/dr-gpu/src/lib.rs:57`](../core/dr-gpu/src/lib.rs#L57), [`core/dr-gpu/src/lib.rs:80`](../core/dr-gpu/src/lib.rs#L80), [`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:2819`](../ui/dr-ui/src/develop.rs#L2819), [`ui/dr-ui/src/develop.rs:4169`](../ui/dr-ui/src/develop.rs#L4169), [`ui/dr-ui/src/develop.rs:4652`](../ui/dr-ui/src/develop.rs#L4652), [`ui/dr-ui/src/develop.rs:4686`](../ui/dr-ui/src/develop.rs#L4686), [`ui/dr-ui/src/lib.rs:76`](../ui/dr-ui/src/lib.rs#L76), [`ui/dr-ui/src/lib.rs:819`](../ui/dr-ui/src/lib.rs#L819), [`ui/dr-ui/src/lib.rs:878`](../ui/dr-ui/src/lib.rs#L878) | | 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:2849`](../ui/dr-ui/src/develop.rs#L2849), [`ui/dr-ui/src/develop.rs:5944`](../ui/dr-ui/src/develop.rs#L5944), [`ui/dr-ui/src/lib.rs:1545`](../ui/dr-ui/src/lib.rs#L1545), [`ui/dr-ui/src/lib.rs:3022`](../ui/dr-ui/src/lib.rs#L3022) | | 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:2898`](../ui/dr-ui/src/develop.rs#L2898), [`ui/dr-ui/src/develop.rs:5754`](../ui/dr-ui/src/develop.rs#L5754), [`ui/dr-ui/src/develop.rs:5786`](../ui/dr-ui/src/develop.rs#L5786), [`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:1655`](../ui/dr-ui/src/lib.rs#L1655), [`ui/dr-ui/src/lib.rs:318`](../ui/dr-ui/src/lib.rs#L318), [`ui/dr-ui/ui/app.slint:70`](../ui/dr-ui/ui/app.slint#L70), [`ui/dr-ui/ui/histogram.slint:122`](../ui/dr-ui/ui/histogram.slint#L122), [`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:2795`](../ui/dr-ui/src/develop.rs#L2795), [`ui/dr-ui/src/develop.rs:2849`](../ui/dr-ui/src/develop.rs#L2849), [`ui/dr-ui/src/develop.rs:5944`](../ui/dr-ui/src/develop.rs#L5944), [`ui/dr-ui/src/develop.rs:5990`](../ui/dr-ui/src/develop.rs#L5990), [`ui/dr-ui/src/develop.rs:6009`](../ui/dr-ui/src/develop.rs#L6009), [`ui/dr-ui/src/develop.rs:807`](../ui/dr-ui/src/develop.rs#L807), [`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:1506`](../ui/dr-ui/src/lib.rs#L1506), [`ui/dr-ui/src/lib.rs:1545`](../ui/dr-ui/src/lib.rs#L1545), [`ui/dr-ui/src/lib.rs:2935`](../ui/dr-ui/src/lib.rs#L2935), [`ui/dr-ui/src/lib.rs:3022`](../ui/dr-ui/src/lib.rs#L3022), [`ui/dr-ui/ui/app.slint:1682`](../ui/dr-ui/ui/app.slint#L1682), [`ui/dr-ui/ui/app.slint:49`](../ui/dr-ui/ui/app.slint#L49), [`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-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:2795`](../ui/dr-ui/src/develop.rs#L2795), [`ui/dr-ui/src/develop.rs:2849`](../ui/dr-ui/src/develop.rs#L2849), [`ui/dr-ui/src/develop.rs:5944`](../ui/dr-ui/src/develop.rs#L5944), [`ui/dr-ui/src/develop.rs:5990`](../ui/dr-ui/src/develop.rs#L5990), [`ui/dr-ui/src/develop.rs:6009`](../ui/dr-ui/src/develop.rs#L6009), [`ui/dr-ui/src/develop.rs:807`](../ui/dr-ui/src/develop.rs#L807), [`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:1506`](../ui/dr-ui/src/lib.rs#L1506), [`ui/dr-ui/src/lib.rs:1545`](../ui/dr-ui/src/lib.rs#L1545), [`ui/dr-ui/src/lib.rs:2935`](../ui/dr-ui/src/lib.rs#L2935), [`ui/dr-ui/src/lib.rs:3022`](../ui/dr-ui/src/lib.rs#L3022), [`ui/dr-ui/ui/app.slint:1680`](../ui/dr-ui/ui/app.slint#L1680), [`ui/dr-ui/ui/app.slint:49`](../ui/dr-ui/ui/app.slint#L49), [`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:6009`](../ui/dr-ui/src/develop.rs#L6009), [`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:424`](../ui/dr-ui/src/lib.rs#L424), [`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:208`](../ui/dr-ui/src/lib.rs#L208), [`ui/dr-ui/src/lib.rs:2267`](../ui/dr-ui/src/lib.rs#L2267), [`ui/dr-ui/src/lib.rs:424`](../ui/dr-ui/src/lib.rs#L424), [`ui/dr-ui/src/lib.rs:459`](../ui/dr-ui/src/lib.rs#L459), [`ui/dr-ui/src/lib.rs:486`](../ui/dr-ui/src/lib.rs#L486), [`ui/dr-ui/src/library_ui.rs:3457`](../ui/dr-ui/src/library_ui.rs#L3457), [`ui/dr-ui/src/library_ui.rs:585`](../ui/dr-ui/src/library_ui.rs#L585), [`ui/dr-ui/src/library_ui.rs:6624`](../ui/dr-ui/src/library_ui.rs#L6624), [`ui/dr-ui/src/library_ui.rs:6701`](../ui/dr-ui/src/library_ui.rs#L6701), [`ui/dr-ui/src/library_ui.rs:6713`](../ui/dr-ui/src/library_ui.rs#L6713), [`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:1049`](../ui/dr-ui/ui/app.slint#L1049), [`ui/dr-ui/ui/app.slint:1519`](../ui/dr-ui/ui/app.slint#L1519), [`ui/dr-ui/ui/library.slint:1471`](../ui/dr-ui/ui/library.slint#L1471), [`ui/dr-ui/ui/library.slint:861`](../ui/dr-ui/ui/library.slint#L861), [`ui/dr-ui/ui/library.slint:971`](../ui/dr-ui/ui/library.slint#L971) | +| 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:208`](../ui/dr-ui/src/lib.rs#L208), [`ui/dr-ui/src/lib.rs:2267`](../ui/dr-ui/src/lib.rs#L2267), [`ui/dr-ui/src/lib.rs:424`](../ui/dr-ui/src/lib.rs#L424), [`ui/dr-ui/src/lib.rs:459`](../ui/dr-ui/src/lib.rs#L459), [`ui/dr-ui/src/lib.rs:486`](../ui/dr-ui/src/lib.rs#L486), [`ui/dr-ui/src/library_ui.rs:3457`](../ui/dr-ui/src/library_ui.rs#L3457), [`ui/dr-ui/src/library_ui.rs:585`](../ui/dr-ui/src/library_ui.rs#L585), [`ui/dr-ui/src/library_ui.rs:6618`](../ui/dr-ui/src/library_ui.rs#L6618), [`ui/dr-ui/src/library_ui.rs:6695`](../ui/dr-ui/src/library_ui.rs#L6695), [`ui/dr-ui/src/library_ui.rs:6707`](../ui/dr-ui/src/library_ui.rs#L6707), [`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:1048`](../ui/dr-ui/ui/app.slint#L1048), [`ui/dr-ui/ui/app.slint:1518`](../ui/dr-ui/ui/app.slint#L1518), [`ui/dr-ui/ui/library.slint:1490`](../ui/dr-ui/ui/library.slint#L1490), [`ui/dr-ui/ui/library.slint:861`](../ui/dr-ui/ui/library.slint#L861), [`ui/dr-ui/ui/library.slint:971`](../ui/dr-ui/ui/library.slint#L971) | | 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:3106`](../ui/dr-ui/src/develop.rs#L3106), [`ui/dr-ui/src/lib.rs:424`](../ui/dr-ui/src/lib.rs#L424) | | 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) | @@ -93,13 +93,13 @@ _None._ | 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:3709`](../ui/dr-ui/src/library_ui.rs#L3709), [`ui/dr-ui/src/library_ui.rs:4715`](../ui/dr-ui/src/library_ui.rs#L4715), [`ui/dr-ui/ui/app.slint:374`](../ui/dr-ui/ui/app.slint#L374), [`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:3709`](../ui/dr-ui/src/library_ui.rs#L3709), [`ui/dr-ui/src/library_ui.rs:4709`](../ui/dr-ui/src/library_ui.rs#L4709), [`ui/dr-ui/ui/app.slint:374`](../ui/dr-ui/ui/app.slint#L374), [`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:3467`](../ui/dr-ui/src/collections_ui.rs#L3467), [`ui/dr-ui/src/collections_ui.rs:664`](../ui/dr-ui/src/collections_ui.rs#L664), [`ui/dr-ui/src/collections_ui.rs:732`](../ui/dr-ui/src/collections_ui.rs#L732), [`ui/dr-ui/src/lib.rs:1971`](../ui/dr-ui/src/lib.rs#L1971), [`ui/dr-ui/src/lib.rs:3085`](../ui/dr-ui/src/lib.rs#L3085), [`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:2148`](../ui/dr-ui/src/library_ui.rs#L2148), [`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:5497`](../ui/dr-ui/src/library_ui.rs#L5497), [`ui/dr-ui/src/library_ui.rs:5515`](../ui/dr-ui/src/library_ui.rs#L5515), [`ui/dr-ui/src/library_ui.rs:5527`](../ui/dr-ui/src/library_ui.rs#L5527), [`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:2545`](../ui/dr-ui/ui/app.slint#L2545), [`ui/dr-ui/ui/app.slint:498`](../ui/dr-ui/ui/app.slint#L498), [`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:1017`](../ui/dr-ui/ui/library.slint#L1017) | +| 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:3249`](../ui/dr-ui/src/collections_ui.rs#L3249), [`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:1971`](../ui/dr-ui/src/lib.rs#L1971), [`ui/dr-ui/src/lib.rs:3085`](../ui/dr-ui/src/lib.rs#L3085), [`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:2148`](../ui/dr-ui/src/library_ui.rs#L2148), [`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:5491`](../ui/dr-ui/src/library_ui.rs#L5491), [`ui/dr-ui/src/library_ui.rs:5509`](../ui/dr-ui/src/library_ui.rs#L5509), [`ui/dr-ui/src/library_ui.rs:5521`](../ui/dr-ui/src/library_ui.rs#L5521), [`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:2543`](../ui/dr-ui/ui/app.slint#L2543), [`ui/dr-ui/ui/app.slint:498`](../ui/dr-ui/ui/app.slint#L498), [`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:1017`](../ui/dr-ui/ui/library.slint#L1017) | | 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:3467`](../ui/dr-ui/src/collections_ui.rs#L3467), [`ui/dr-ui/src/collections_ui.rs:664`](../ui/dr-ui/src/collections_ui.rs#L664), [`ui/dr-ui/src/collections_ui.rs:732`](../ui/dr-ui/src/collections_ui.rs#L732), [`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:3249`](../ui/dr-ui/src/collections_ui.rs#L3249), [`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-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:3709`](../ui/dr-ui/src/library_ui.rs#L3709), [`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:1205`](../ui/dr-ui/src/lib.rs#L1205), [`ui/dr-ui/ui/import.slint:5`](../ui/dr-ui/ui/import.slint#L5) | @@ -118,19 +118,19 @@ _None._ | 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:208`](../ui/dr-ui/src/lib.rs#L208) | | 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:3167`](../ui/dr-ui/src/lib.rs#L3167), [`ui/dr-ui/src/lib.rs:84`](../ui/dr-ui/src/lib.rs#L84), [`ui/dr-ui/src/masks_ui.rs:816`](../ui/dr-ui/src/masks_ui.rs#L816), [`ui/dr-ui/ui/identity.slint:165`](../ui/dr-ui/ui/identity.slint#L165), [`ui/dr-ui/ui/library.slint:1083`](../ui/dr-ui/ui/library.slint#L1083) | -| FR-UI-2 | [`ui/dr-ui/src/collections_ui.rs:1067`](../ui/dr-ui/src/collections_ui.rs#L1067), [`ui/dr-ui/src/collections_ui.rs:1093`](../ui/dr-ui/src/collections_ui.rs#L1093), [`ui/dr-ui/src/collections_ui.rs:119`](../ui/dr-ui/src/collections_ui.rs#L119), [`ui/dr-ui/src/collections_ui.rs:1580`](../ui/dr-ui/src/collections_ui.rs#L1580), [`ui/dr-ui/src/collections_ui.rs:1594`](../ui/dr-ui/src/collections_ui.rs#L1594), [`ui/dr-ui/src/collections_ui.rs:1640`](../ui/dr-ui/src/collections_ui.rs#L1640), [`ui/dr-ui/src/collections_ui.rs:170`](../ui/dr-ui/src/collections_ui.rs#L170), [`ui/dr-ui/src/collections_ui.rs:1892`](../ui/dr-ui/src/collections_ui.rs#L1892), [`ui/dr-ui/src/collections_ui.rs:528`](../ui/dr-ui/src/collections_ui.rs#L528), [`ui/dr-ui/src/collections_ui.rs:557`](../ui/dr-ui/src/collections_ui.rs#L557), [`ui/dr-ui/src/lib.rs:84`](../ui/dr-ui/src/lib.rs#L84), [`ui/dr-ui/src/lib.rs:91`](../ui/dr-ui/src/lib.rs#L91), [`ui/dr-ui/src/library_ui.rs:308`](../ui/dr-ui/src/library_ui.rs#L308), [`ui/dr-ui/src/library_ui.rs:5382`](../ui/dr-ui/src/library_ui.rs#L5382), [`ui/dr-ui/src/library_ui.rs:5527`](../ui/dr-ui/src/library_ui.rs#L5527), [`ui/dr-ui/src/library_ui.rs:6732`](../ui/dr-ui/src/library_ui.rs#L6732), [`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:2115`](../ui/dr-ui/ui/app.slint#L2115), [`ui/dr-ui/ui/app.slint:528`](../ui/dr-ui/ui/app.slint#L528), [`ui/dr-ui/ui/app.slint:535`](../ui/dr-ui/ui/app.slint#L535), [`ui/dr-ui/ui/app.slint:56`](../ui/dr-ui/ui/app.slint#L56), [`ui/dr-ui/ui/app.slint:884`](../ui/dr-ui/ui/app.slint#L884), [`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/histogram.slint:127`](../ui/dr-ui/ui/histogram.slint#L127), [`ui/dr-ui/ui/history.slint:118`](../ui/dr-ui/ui/history.slint#L118), [`ui/dr-ui/ui/library.slint:1252`](../ui/dr-ui/ui/library.slint#L1252), [`ui/dr-ui/ui/library.slint:1259`](../ui/dr-ui/ui/library.slint#L1259), [`ui/dr-ui/ui/library.slint:1265`](../ui/dr-ui/ui/library.slint#L1265), [`ui/dr-ui/ui/library.slint:1306`](../ui/dr-ui/ui/library.slint#L1306), [`ui/dr-ui/ui/library.slint:2621`](../ui/dr-ui/ui/library.slint#L2621), [`ui/dr-ui/ui/library.slint:849`](../ui/dr-ui/ui/library.slint#L849), [`ui/dr-ui/ui/library.slint:902`](../ui/dr-ui/ui/library.slint#L902), [`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:2224`](../ui/dr-ui/src/develop.rs#L2224), [`ui/dr-ui/src/develop.rs:2333`](../ui/dr-ui/src/develop.rs#L2333), [`ui/dr-ui/src/library_ui.rs:4503`](../ui/dr-ui/src/library_ui.rs#L4503), [`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:1931`](../ui/dr-ui/ui/app.slint#L1931), [`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 | [`ui/dr-ui/src/collections_ui.rs:1067`](../ui/dr-ui/src/collections_ui.rs#L1067), [`ui/dr-ui/src/collections_ui.rs:1077`](../ui/dr-ui/src/collections_ui.rs#L1077), [`ui/dr-ui/src/collections_ui.rs:1093`](../ui/dr-ui/src/collections_ui.rs#L1093), [`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:1580`](../ui/dr-ui/src/collections_ui.rs#L1580), [`ui/dr-ui/src/collections_ui.rs:1594`](../ui/dr-ui/src/collections_ui.rs#L1594), [`ui/dr-ui/src/collections_ui.rs:160`](../ui/dr-ui/src/collections_ui.rs#L160), [`ui/dr-ui/src/collections_ui.rs:1640`](../ui/dr-ui/src/collections_ui.rs#L1640), [`ui/dr-ui/src/collections_ui.rs:170`](../ui/dr-ui/src/collections_ui.rs#L170), [`ui/dr-ui/src/collections_ui.rs:1756`](../ui/dr-ui/src/collections_ui.rs#L1756), [`ui/dr-ui/src/collections_ui.rs:1892`](../ui/dr-ui/src/collections_ui.rs#L1892), [`ui/dr-ui/src/collections_ui.rs:1919`](../ui/dr-ui/src/collections_ui.rs#L1919), [`ui/dr-ui/src/collections_ui.rs:2804`](../ui/dr-ui/src/collections_ui.rs#L2804), [`ui/dr-ui/src/collections_ui.rs:346`](../ui/dr-ui/src/collections_ui.rs#L346), [`ui/dr-ui/src/collections_ui.rs:528`](../ui/dr-ui/src/collections_ui.rs#L528), [`ui/dr-ui/src/collections_ui.rs:557`](../ui/dr-ui/src/collections_ui.rs#L557), [`ui/dr-ui/src/collections_ui.rs:625`](../ui/dr-ui/src/collections_ui.rs#L625), [`ui/dr-ui/src/library_ui.rs:4503`](../ui/dr-ui/src/library_ui.rs#L4503), [`ui/dr-ui/src/library_ui.rs:4530`](../ui/dr-ui/src/library_ui.rs#L4530), [`ui/dr-ui/src/library_ui.rs:4555`](../ui/dr-ui/src/library_ui.rs#L4555), [`ui/dr-ui/src/library_ui.rs:4658`](../ui/dr-ui/src/library_ui.rs#L4658), [`ui/dr-ui/src/library_ui.rs:4686`](../ui/dr-ui/src/library_ui.rs#L4686), [`ui/dr-ui/src/library_ui.rs:5515`](../ui/dr-ui/src/library_ui.rs#L5515), [`ui/dr-ui/src/library_ui.rs:5527`](../ui/dr-ui/src/library_ui.rs#L5527), [`ui/dr-ui/ui/app.slint:1771`](../ui/dr-ui/ui/app.slint#L1771), [`ui/dr-ui/ui/app.slint:504`](../ui/dr-ui/ui/app.slint#L504), [`ui/dr-ui/ui/app.slint:535`](../ui/dr-ui/ui/app.slint#L535), [`ui/dr-ui/ui/library.slint:1252`](../ui/dr-ui/ui/library.slint#L1252), [`ui/dr-ui/ui/library.slint:1259`](../ui/dr-ui/ui/library.slint#L1259), [`ui/dr-ui/ui/library.slint:1265`](../ui/dr-ui/ui/library.slint#L1265), [`ui/dr-ui/ui/library.slint:1299`](../ui/dr-ui/ui/library.slint#L1299), [`ui/dr-ui/ui/library.slint:1306`](../ui/dr-ui/ui/library.slint#L1306), [`ui/dr-ui/ui/library.slint:2621`](../ui/dr-ui/ui/library.slint#L2621), [`ui/dr-ui/ui/library.slint:849`](../ui/dr-ui/ui/library.slint#L849), [`ui/dr-ui/ui/library.slint:902`](../ui/dr-ui/ui/library.slint#L902), [`ui/dr-ui/ui/library.slint:921`](../ui/dr-ui/ui/library.slint#L921) | +| FR-UI-1 | [`ui/dr-ui/src/lib.rs:3167`](../ui/dr-ui/src/lib.rs#L3167), [`ui/dr-ui/src/lib.rs:84`](../ui/dr-ui/src/lib.rs#L84), [`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:1083`](../ui/dr-ui/ui/library.slint#L1083) | +| FR-UI-2 | [`ui/dr-ui/src/collections_ui.rs:1002`](../ui/dr-ui/src/collections_ui.rs#L1002), [`ui/dr-ui/src/collections_ui.rs:1012`](../ui/dr-ui/src/collections_ui.rs#L1012), [`ui/dr-ui/src/collections_ui.rs:119`](../ui/dr-ui/src/collections_ui.rs#L119), [`ui/dr-ui/src/collections_ui.rs:1495`](../ui/dr-ui/src/collections_ui.rs#L1495), [`ui/dr-ui/src/collections_ui.rs:1509`](../ui/dr-ui/src/collections_ui.rs#L1509), [`ui/dr-ui/src/collections_ui.rs:160`](../ui/dr-ui/src/collections_ui.rs#L160), [`ui/dr-ui/src/collections_ui.rs:1761`](../ui/dr-ui/src/collections_ui.rs#L1761), [`ui/dr-ui/src/collections_ui.rs:2812`](../ui/dr-ui/src/collections_ui.rs#L2812), [`ui/dr-ui/src/collections_ui.rs:486`](../ui/dr-ui/src/collections_ui.rs#L486), [`ui/dr-ui/src/lib.rs:84`](../ui/dr-ui/src/lib.rs#L84), [`ui/dr-ui/src/lib.rs:91`](../ui/dr-ui/src/lib.rs#L91), [`ui/dr-ui/src/library_ui.rs:308`](../ui/dr-ui/src/library_ui.rs#L308), [`ui/dr-ui/src/library_ui.rs:5376`](../ui/dr-ui/src/library_ui.rs#L5376), [`ui/dr-ui/src/library_ui.rs:5521`](../ui/dr-ui/src/library_ui.rs#L5521), [`ui/dr-ui/src/library_ui.rs:6726`](../ui/dr-ui/src/library_ui.rs#L6726), [`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:2113`](../ui/dr-ui/ui/app.slint#L2113), [`ui/dr-ui/ui/app.slint:528`](../ui/dr-ui/ui/app.slint#L528), [`ui/dr-ui/ui/app.slint:535`](../ui/dr-ui/ui/app.slint#L535), [`ui/dr-ui/ui/app.slint:56`](../ui/dr-ui/ui/app.slint#L56), [`ui/dr-ui/ui/app.slint:883`](../ui/dr-ui/ui/app.slint#L883), [`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/histogram.slint:127`](../ui/dr-ui/ui/histogram.slint#L127), [`ui/dr-ui/ui/history.slint:118`](../ui/dr-ui/ui/history.slint#L118), [`ui/dr-ui/ui/library.slint:1244`](../ui/dr-ui/ui/library.slint#L1244), [`ui/dr-ui/ui/library.slint:1251`](../ui/dr-ui/ui/library.slint#L1251), [`ui/dr-ui/ui/library.slint:1314`](../ui/dr-ui/ui/library.slint#L1314), [`ui/dr-ui/ui/library.slint:2667`](../ui/dr-ui/ui/library.slint#L2667), [`ui/dr-ui/ui/library.slint:849`](../ui/dr-ui/ui/library.slint#L849), [`ui/dr-ui/ui/library.slint:902`](../ui/dr-ui/ui/library.slint#L902), [`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:2224`](../ui/dr-ui/src/develop.rs#L2224), [`ui/dr-ui/src/develop.rs:2333`](../ui/dr-ui/src/develop.rs#L2333), [`ui/dr-ui/src/library_ui.rs:4503`](../ui/dr-ui/src/library_ui.rs#L4503), [`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:1929`](../ui/dr-ui/ui/app.slint#L1929), [`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:365`](../tools/traceability/src/gestures.rs#L365), [`ui/dr-ui/src/collections_ui.rs:1002`](../ui/dr-ui/src/collections_ui.rs#L1002), [`ui/dr-ui/src/collections_ui.rs:1012`](../ui/dr-ui/src/collections_ui.rs#L1012), [`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:1495`](../ui/dr-ui/src/collections_ui.rs#L1495), [`ui/dr-ui/src/collections_ui.rs:1509`](../ui/dr-ui/src/collections_ui.rs#L1509), [`ui/dr-ui/src/collections_ui.rs:160`](../ui/dr-ui/src/collections_ui.rs#L160), [`ui/dr-ui/src/collections_ui.rs:1625`](../ui/dr-ui/src/collections_ui.rs#L1625), [`ui/dr-ui/src/collections_ui.rs:1761`](../ui/dr-ui/src/collections_ui.rs#L1761), [`ui/dr-ui/src/collections_ui.rs:1788`](../ui/dr-ui/src/collections_ui.rs#L1788), [`ui/dr-ui/src/collections_ui.rs:1887`](../ui/dr-ui/src/collections_ui.rs#L1887), [`ui/dr-ui/src/collections_ui.rs:2812`](../ui/dr-ui/src/collections_ui.rs#L2812), [`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/library_ui.rs:4503`](../ui/dr-ui/src/library_ui.rs#L4503), [`ui/dr-ui/src/library_ui.rs:4549`](../ui/dr-ui/src/library_ui.rs#L4549), [`ui/dr-ui/src/library_ui.rs:4652`](../ui/dr-ui/src/library_ui.rs#L4652), [`ui/dr-ui/src/library_ui.rs:4680`](../ui/dr-ui/src/library_ui.rs#L4680), [`ui/dr-ui/src/library_ui.rs:5509`](../ui/dr-ui/src/library_ui.rs#L5509), [`ui/dr-ui/src/library_ui.rs:5521`](../ui/dr-ui/src/library_ui.rs#L5521), [`ui/dr-ui/ui/app.slint:1769`](../ui/dr-ui/ui/app.slint#L1769), [`ui/dr-ui/ui/app.slint:504`](../ui/dr-ui/ui/app.slint#L504), [`ui/dr-ui/ui/app.slint:535`](../ui/dr-ui/ui/app.slint#L535), [`ui/dr-ui/ui/library.slint:1244`](../ui/dr-ui/ui/library.slint#L1244), [`ui/dr-ui/ui/library.slint:1251`](../ui/dr-ui/ui/library.slint#L1251), [`ui/dr-ui/ui/library.slint:1307`](../ui/dr-ui/ui/library.slint#L1307), [`ui/dr-ui/ui/library.slint:1314`](../ui/dr-ui/ui/library.slint#L1314), [`ui/dr-ui/ui/library.slint:2667`](../ui/dr-ui/ui/library.slint#L2667), [`ui/dr-ui/ui/library.slint:849`](../ui/dr-ui/ui/library.slint#L849), [`ui/dr-ui/ui/library.slint:902`](../ui/dr-ui/ui/library.slint#L902), [`ui/dr-ui/ui/library.slint:921`](../ui/dr-ui/ui/library.slint#L921) | | 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:2604`](../ui/dr-ui/src/lib.rs#L2604), [`ui/dr-ui/src/lib.rs:3206`](../ui/dr-ui/src/lib.rs#L3206), [`ui/dr-ui/src/lib.rs:3391`](../ui/dr-ui/src/lib.rs#L3391), [`ui/dr-ui/src/masks_ui.rs:863`](../ui/dr-ui/src/masks_ui.rs#L863), [`ui/dr-ui/ui/app.slint:107`](../ui/dr-ui/ui/app.slint#L107), [`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:2301`](../ui/dr-ui/src/lib.rs#L2301), [`ui/dr-ui/ui/app.slint:1060`](../ui/dr-ui/ui/app.slint#L1060), [`ui/dr-ui/ui/library.slint:971`](../ui/dr-ui/ui/library.slint#L971) | +| 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:2301`](../ui/dr-ui/src/lib.rs#L2301), [`ui/dr-ui/ui/app.slint:1059`](../ui/dr-ui/ui/app.slint#L1059), [`ui/dr-ui/ui/library.slint:971`](../ui/dr-ui/ui/library.slint#L971) | | 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/lib.rs:266`](../tools/traceability/src/lib.rs#L266) | +| 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:479`](../tools/traceability/src/lib.rs#L479) | +| 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:2964`](../ui/dr-ui/src/develop.rs#L2964), [`ui/dr-ui/src/lib.rs:1674`](../ui/dr-ui/src/lib.rs#L1674) | | 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:4176`](../ui/dr-ui/src/library_ui.rs#L4176), [`ui/dr-ui/src/library_ui.rs:64`](../ui/dr-ui/src/library_ui.rs#L64) | @@ -149,7 +149,7 @@ _None._ | NFR-SEC-2 | [`core/dr-sync/src/account.rs:298`](../core/dr-sync/src/account.rs#L298), [`platform/dr-plat/src/secrets.rs:82`](../platform/dr-plat/src/secrets.rs#L82) | | NFR-SEC-3 | [`core/dr-sync-nextcloud/src/lib.rs:1`](../core/dr-sync-nextcloud/src/lib.rs#L1), [`core/dr-sync-nextcloud/src/provider.rs:1`](../core/dr-sync-nextcloud/src/provider.rs#L1) | | NFR-SEC-5 | [`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/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/ui/identity.slint:1`](../ui/dr-ui/ui/identity.slint#L1) | -| R1 | [`tools/traceability/src/lib.rs:495`](../tools/traceability/src/lib.rs#L495), [`tools/traceability/src/lib.rs:499`](../tools/traceability/src/lib.rs#L499) | +| R1 | [`tools/traceability/src/lib.rs:497`](../tools/traceability/src/lib.rs#L497), [`tools/traceability/src/lib.rs:501`](../tools/traceability/src/lib.rs#L501) | | R3 | [`core/dr-export/src/lib.rs:1`](../core/dr-export/src/lib.rs#L1), [`core/dr-pipeline/src/lib.rs:1`](../core/dr-pipeline/src/lib.rs#L1) | | R4 | [`core/dr-gpu/src/lib.rs:338`](../core/dr-gpu/src/lib.rs#L338) | | R6 | [`core/dr-sync-nextcloud/src/lib.rs:1`](../core/dr-sync-nextcloud/src/lib.rs#L1) | diff --git a/ui/dr-ui/src/collections_ui.rs b/ui/dr-ui/src/collections_ui.rs index 2031fe7..719402d 100644 --- a/ui/dr-ui/src/collections_ui.rs +++ b/ui/dr-ui/src/collections_ui.rs @@ -157,16 +157,6 @@ pub struct CollectionsController { /// develop view on the second ctrl-click. Slint does not report modifiers on /// `clicked`, so the press records them and the click consults this. modified_press: std::cell::Cell, - /// TRACES: FR-UI-4 - /// When the press that began the current gesture landed, and whether a - /// finger did it. - /// - /// Read by the click that follows, to tell a tap from a graze — see - /// [`CollectionsController::press_was_a_graze`]. `None` between gestures, - /// which a click with no press before it is treated as: it cannot have been - /// deliberate if nothing pressed. - pressed_at: std::cell::Cell>, - touch_press: std::cell::Cell, /// TRACES: FR-UI-2 | FR-UI-4 /// Whether a tap in the grid selects rather than opens. /// @@ -343,38 +333,6 @@ impl CollectionsController { self.modified_press.get() } - /// TRACES: FR-UI-4 - /// Whether the contact that is ending was too brief to have meant anything. - /// - /// A hand crossing a tablet on its way to the scroll it intended produces a - /// press and a release a few tens of milliseconds apart, in the same place — - /// indistinguishable, to a `TouchArea`, from a tap, and it was opening - /// whichever photograph happened to be under the knuckle. Travel is already - /// answered (the Flickable claims the pointer and the press is cancelled); - /// what was left is the contact that does not travel and does not last. - /// - /// **Only a finger is held to this.** A mouse click is a discrete decision - /// made by a button and is routinely over in thirty milliseconds; applying - /// a dwell to it would make the desktop feel broken to fix a problem the - /// desktop does not have. - /// - /// And it only withholds the *open*. The press has already selected the - /// cell under the finger, which is the right failure mode: a graze leaves - /// something visible and reversible on screen rather than silently doing - /// nothing, and rather than throwing the user into develop. - pub fn press_was_a_graze(&self) -> bool { - if !self.touch_press.get() { - return false; - } - match self.pressed_at.get() { - Some(at) => at.elapsed() < std::time::Duration::from_millis(TAP_MIN_MS), - // A click with no press recorded before it. Not a graze — there is - // nothing to say it was one — and refusing it would be the one way - // this rule could make a photograph unopenable. - None => false, - } - } - /// Selected image ids, in a stable order. pub fn selected(&self) -> Vec { self.selection.borrow().iter().copied().collect() @@ -554,29 +512,6 @@ pub fn press_remembering_anchor( } } -/// TRACES: FR-UI-2 | FR-UI-4 -/// Extend the selection to `row` — the touch form of a shift-click. -/// -/// Added to the selection rather than replacing it: this is reached only from -/// selection mode, which the user entered deliberately, and a gesture that -/// silently discarded the run they gathered a moment ago would make gathering -/// two runs impossible. -#[allow(clippy::too_many_arguments)] -pub fn extend_to_row( - selection: &mut BTreeSet, - anchor: &mut Option, - previous: Option, - ids: &[ImageId], - offset: usize, - row: usize, - span: &dyn Fn(usize, usize) -> Vec, -) { - // Falling back to the current anchor makes a double tap with no history - // select just that cell, which is what a double tap already did. - *anchor = previous.or(*anchor); - apply_press(selection, anchor, ids, offset, row, true, true, span); -} - /// Apply a press and push the result into the grid — the whole of what a /// click, or an arrow key, does to the selection. /// @@ -1074,22 +1009,6 @@ const SPRING_DELAY_MS: u64 = 500; /// the hand lets go first, having concluded nothing was going to happen. pub(crate) const HOLD_DELAY_MS: u64 = 450; -/// TRACES: FR-UI-4 -/// How long a finger must stay down before letting go counts as opening a -/// photograph. -/// -/// **The floor under a tap, where `HOLD_DELAY_MS` is the ceiling.** Between the -/// two is a tap; below is a graze that only selects; above is a hold that -/// starts a selection. The three have to be one scale or the gesture set stops -/// being learnable. -/// -/// 120 ms is a tenth of the hold and about twice a brush. It costs nothing in -/// felt latency because it does not *delay* anything — the open still happens -/// on release, and this only decides whether that release counted — so the -/// error it can make is one-sided: an unusually quick deliberate tap selects -/// instead of opening, and the photograph is one further tap away. -pub(crate) const TAP_MIN_MS: u64 = 120; - /// TRACES: FR-UI-2 | FR-UI-4 /// Start the timer that turns a held cell into a selection. /// @@ -1559,17 +1478,13 @@ pub fn wire( let weak = window.as_weak(); let ctl = ctl.clone(); let visible = visible_ids.clone(); - window.on_library_cell_pressed(move |row, ctrl_held, shift_held, touch| { + window.on_library_cell_pressed(move |row, ctrl_held, shift_held| { let Some(w) = weak.upgrade() else { return }; let ids = visible(); // Consulted by the click that follows: a modified press is building // a selection and must not also navigate to develop. ctl.modified_press.set(ctrl_held || shift_held); - // And so is this: how long the contact lasts is what separates a - // tap from a graze, and only the press knows when it started. - ctl.pressed_at.set(Some(std::time::Instant::now())); - ctl.touch_press.set(touch); // Where the window starts, so the press is recorded as the ordinal // it is rather than as a row that stops meaning this photograph on @@ -1591,52 +1506,6 @@ pub fn wire( }); } - // TRACES: FR-UI-2 | FR-UI-4 - // A double tap in selection mode: take everything between the cell the - // selection started from and this one. - // - // This is shift-click, reached by the one gesture touch has left. Hold to - // start selecting, double-tap the far end, and a run of forty photographs - // is three touches — then the whole selection drags onto a collection as - // one, which is the thing this sequence exists to make possible. - // - // The range is *added*, not replaced, so a second run can be picked up - // without losing the first — ctrl+shift's behaviour, and the right one - // here: a mode the user entered deliberately should accumulate rather than - // throw away what they have already gathered. - { - let weak = window.as_weak(); - let ctl = ctl.clone(); - let visible = visible_ids.clone(); - window.on_library_cell_double_clicked(move |row| { - let Some(w) = weak.upgrade() else { return }; - // Outside selection mode a double tap is two ordinary clicks, and - // the first has already opened the image. Nothing to do. - if !ctl.select_mode.get() { - return; - } - // The hold that would have fired mid-double-tap. - *ctl.hold_timer.borrow_mut() = None; - - let ids = visible(); - let offset = w.get_library_offset().max(0) as usize; - - // Extended from the cell the user started at, not from the one the - // two taps just moved the anchor onto. - extend_to_row( - &mut ctl.selection.borrow_mut(), - &mut ctl.anchor.borrow_mut(), - ctl.previous_anchor.get(), - &ids, - offset, - row as usize, - &|first, last| ctl.span(first, last), - ); - ctl.set_cursor(Some(offset + row as usize)); - sync_selection(&w, &ctl, &ids); - }); - } - // TRACES: FR-UI-2 | FR-UI-4 // The press ended — lifted, or taken by the Flickable when the finger // travelled. Either way the hold is off. @@ -2015,6 +1884,15 @@ pub fn wire( let Some(w) = weak.upgrade() else { return }; let ids = visible(); + // TRACES: FR-UI-4 + // A drag is not a hold, and the timer must not outlive the press + // that armed it. Grabbing a cell and moving inside 450 ms left the + // hold armed underneath the drag, so it fired mid-gesture and put + // the grid into selection mode the user had not asked for — the + // drag finished into a mode that changed what every later tap + // meant. The pinch already cancels for exactly this reason. + *ctl.hold_timer.borrow_mut() = None; + // Dragging an *unselected* cell carries only that one, and makes it // the selection — otherwise the images that travel are not the ones // the user grabbed. Dragging a selected cell carries the whole @@ -2801,52 +2679,6 @@ mod tests { Vec::new() } - /// TRACES: FR-UI-4 - /// A hand brushing the tablet on its way to a scroll must not open a - /// photograph. It still *selects* one — the press did that, and something - /// visible and reversible is the right thing to be left with. - #[test] - fn a_graze_does_not_open_a_photograph() { - let ctl = CollectionsController::new(crate::activity::ActivityLog::new()); - ctl.touch_press.set(true); - ctl.pressed_at.set(Some(std::time::Instant::now())); - assert!( - ctl.press_was_a_graze(), - "a release in the same instant as the press is not a tap" - ); - } - - /// And a finger that stayed down is a tap, not a graze. - #[test] - fn a_deliberate_tap_opens_a_photograph() { - let ctl = CollectionsController::new(crate::activity::ActivityLog::new()); - ctl.touch_press.set(true); - ctl.pressed_at.set(Some( - std::time::Instant::now() - std::time::Duration::from_millis(TAP_MIN_MS + 10), - )); - assert!(!ctl.press_was_a_graze()); - } - - /// The desktop is not held to the dwell. A mouse button is a discrete - /// decision and is routinely down for thirty milliseconds. - #[test] - fn a_mouse_click_is_never_a_graze() { - let ctl = CollectionsController::new(crate::activity::ActivityLog::new()); - ctl.touch_press.set(false); - ctl.pressed_at.set(Some(std::time::Instant::now())); - assert!(!ctl.press_was_a_graze()); - } - - /// The floor has to sit under the ceiling, or there is no tap between them: - /// every press would be either a graze or a hold. - #[test] - fn a_tap_has_room_between_a_graze_and_a_hold() { - // A `const` block, so this is a compile error rather than a test - // failure: the two numbers are constants, and a gesture set with no - // room for a tap in it should not get as far as being run. - const { assert!(TAP_MIN_MS < HOLD_DELAY_MS) }; - } - #[test] fn dragging_a_collection_onto_another_moves_it() { // The gesture the tree rearrangement exists for: no images carried, a @@ -2977,6 +2809,48 @@ mod tests { assert_eq!(sel.len(), 3, "rows 10..=12"); } + /// TRACES: FR-UI-2 | FR-UI-4 + /// Two taps on one cell put it back where it started, and take nothing else. + /// + /// This is the behaviour that replaced the double-tap range. That gesture + /// selected everything between the cell and wherever the selection began — + /// silently, with no visible state, from a thing a hand does by accident. + /// "Select to…" does the same job and says so first, so a double tap is now + /// two toggles and nothing more: the only outcome a user can predict from + /// what is on the screen. + #[test] + fn two_taps_on_one_cell_cancel_out_and_take_no_range() { + let all = ids(30); + let span = library(&all); + let mut sel = BTreeSet::new(); + let mut anchor = None; + let mut previous = None; + + // Selecting began somewhere else, so a range gesture would have had an + // anchor to sweep from. + press_remembering_anchor( + &mut sel, + &mut anchor, + &mut previous, + &all, + 0, + 4, + false, + false, + &span, + ); + assert_eq!(sel.len(), 1); + + tap(&mut sel, &mut anchor, &mut previous, &all, 11); + tap(&mut sel, &mut anchor, &mut previous, &all, 11); + + assert_eq!( + sel.iter().copied().collect::>(), + vec![ImageId(5)], + "a double tap took a run instead of toggling one cell twice" + ); + } + /// One tap in selection mode: a press reported as ctrl-held, which is what /// `library.slint` sends while the mode is on. fn tap( @@ -2999,98 +2873,6 @@ mod tests { ); } - #[test] - fn a_double_tap_takes_the_run_between_it_and_where_selecting_began() { - // The whole touch gesture, in the order a finger performs it: hold one - // photograph to start selecting, then double-tap the far end of the run. - // Both taps of that double tap land on the same cell — the first turns - // it on, the second turns it off — and the double tap that follows has - // to select the range anyway. - let all = ids(20); - let span = library(&all); - let mut sel = BTreeSet::new(); - let mut anchor = None; - let mut previous = None; - - // The long press: an ordinary plain press, which is what the cell got - // before the hold timer fired. - press_remembering_anchor( - &mut sel, - &mut anchor, - &mut previous, - &all, - 0, - 4, - false, - false, - &span, - ); - - tap(&mut sel, &mut anchor, &mut previous, &all, 11); - tap(&mut sel, &mut anchor, &mut previous, &all, 11); - assert!( - !sel.contains(&ImageId(12)), - "the two taps cancelled out, which is what makes the double tap's \ - job to select the range rather than to add one cell" - ); - - extend_to_row(&mut sel, &mut anchor, previous, &all, 0, 11, &span); - - assert_eq!(sel.len(), 8, "rows 4..=11"); - assert!(sel.contains(&ImageId(5)) && sel.contains(&ImageId(12))); - } - - #[test] - fn a_double_tap_keeps_a_run_gathered_earlier() { - // Two runs, which is why the extension unions rather than replaces: a - // user in selection mode is gathering, and the second gesture must not - // throw away the first. - let all = ids(30); - let span = library(&all); - let mut sel = BTreeSet::new(); - let mut anchor = None; - let mut previous = None; - - press_remembering_anchor( - &mut sel, - &mut anchor, - &mut previous, - &all, - 0, - 0, - false, - false, - &span, - ); - tap(&mut sel, &mut anchor, &mut previous, &all, 3); - tap(&mut sel, &mut anchor, &mut previous, &all, 3); - extend_to_row(&mut sel, &mut anchor, previous, &all, 0, 3, &span); - assert_eq!(sel.len(), 4, "rows 0..=3"); - - // A second run, begun with a plain tap somewhere else. - tap(&mut sel, &mut anchor, &mut previous, &all, 20); - tap(&mut sel, &mut anchor, &mut previous, &all, 25); - tap(&mut sel, &mut anchor, &mut previous, &all, 25); - extend_to_row(&mut sel, &mut anchor, previous, &all, 0, 25, &span); - - assert_eq!(sel.len(), 10, "rows 0..=3 and 20..=25"); - assert!(sel.contains(&ImageId(1)) && sel.contains(&ImageId(26))); - } - - #[test] - fn a_double_tap_with_nothing_to_extend_from_selects_only_that_cell() { - // The degenerate case: selection mode entered from the header's button - // rather than by holding a cell, so nothing has anchored yet. - let all = ids(10); - let span = library(&all); - let mut sel = BTreeSet::new(); - let mut anchor = None; - let previous = None; - - extend_to_row(&mut sel, &mut anchor, previous, &all, 0, 6, &span); - assert_eq!(sel.iter().copied().collect::>(), vec![ImageId(7)]); - } - #[test] fn ctrl_shift_adds_a_second_range_to_the_selection() { // Picking up a second run without losing the first: the one case where diff --git a/ui/dr-ui/src/library_ui.rs b/ui/dr-ui/src/library_ui.rs index 15224f2..f2707e2 100644 --- a/ui/dr-ui/src/library_ui.rs +++ b/ui/dr-ui/src/library_ui.rs @@ -4527,13 +4527,7 @@ pub fn wire( if coll_for_click.press_was_modified() { return; } - // TRACES: FR-UI-4 - // And a graze is not a tap. The press has already selected the cell, - // so the user sees what they touched; what they do not get is a - // photograph opened by a hand on its way past. - if coll_for_click.press_was_a_graze() { - return; - } + let path = ctl.paths.borrow().get(i as usize).cloned(); if let Some(path) = path { // Leave the grid for the develop view. The status bar's diff --git a/ui/dr-ui/ui/app.slint b/ui/dr-ui/ui/app.slint index 6053a57..7f7d53c 100644 --- a/ui/dr-ui/ui/app.slint +++ b/ui/dr-ui/ui/app.slint @@ -534,7 +534,6 @@ export component AppWindow inherits Window { callback library-cell-press-ended(); /// TRACES: FR-UI-2 | FR-UI-4 /// Two taps on a cell: in selection mode, the far end of a range. - callback library-cell-double-clicked(int); /// Renaming started on a row, by id — a double-click, or `F2`. callback collection-rename-start(int); /// A rename was committed: the collection's id and the new name. @@ -584,7 +583,7 @@ export component AppWindow inherits Window { callback library-drag-finished(); in property library-selected-count: 0; - callback library-cell-pressed(int, bool, bool, bool); + callback library-cell-pressed(int, bool, bool); callback library-remove-from-collection(); // The keyboard cursor: where the arrows are in the library, as an image @@ -1558,11 +1557,10 @@ in property panel-visible: true; open-settings() => { root.settings-open(); } open-people() => { root.identity-open(); } - cell-pressed(i, ctrl, shift, touch) => { - root.library-cell-pressed(i, ctrl, shift, touch); + cell-pressed(i, ctrl, shift) => { + root.library-cell-pressed(i, ctrl, shift); } cell-press-ended() => { root.library-cell-press-ended(); } - cell-double-clicked(i) => { root.library-cell-double-clicked(i); } select-mode: root.library-select-mode; toggle-select-mode() => { root.library-toggle-select-mode(); } // The sidebar's rows, not a second model: the sheet files diff --git a/ui/dr-ui/ui/library.slint b/ui/dr-ui/ui/library.slint index d3c08f8..4b9f7e9 100644 --- a/ui/dr-ui/ui/library.slint +++ b/ui/dr-ui/ui/library.slint @@ -1240,15 +1240,7 @@ export component LibraryGrid inherits Rectangle { // also why there is no badge position to compute here any more. /// Modifier state at press time, so Rust can decide replace / add / extend /// without the .slint file encoding the selection policy. - /// - /// The last argument is **whether a finger did it**, and it is here because - /// a finger and a pointer need different rules about what counts as a tap. - /// A mouse click is over in tens of milliseconds and means it; a hand - /// brushing a tablet on its way somewhere else produces exactly the same - /// press-and-release, and used to land the user in develop. Rust holds the - /// rule (`collections_ui::TAP_MIN_MS`) beside the hold timer it has to sit - /// between — this file only reports which kind of contact it was. - callback cell-pressed(int, bool, bool, bool); + callback cell-pressed(int, bool, bool); /// TRACES: FR-UI-2 | FR-UI-4 /// The press on a cell ended — lifted, or taken away by the Flickable when /// the finger travelled. Cancels the long-press timer that would otherwise @@ -1257,12 +1249,6 @@ export component LibraryGrid inherits Rectangle { /// visible cell. callback cell-press-ended(); /// TRACES: FR-UI-2 | FR-UI-4 - /// Two taps on the same cell. In selection mode this is the touch form of - /// shift-click: everything from where the selection started to here. Rust - /// decides — outside that mode a double tap is two ordinary clicks and the - /// first has already opened the image. - callback cell-double-clicked(int); - /// TRACES: FR-UI-2 | FR-UI-4 /// Whether a tap selects rather than opens. /// /// Held in Rust beside the selection it modifies, so the long press and the @@ -1270,6 +1256,28 @@ export component LibraryGrid inherits Rectangle { /// can disagree. In this mode a plain tap toggles a cell — exactly what /// ctrl-click does with a pointer, which is why the press below passes it /// as the ctrl flag rather than as a third selection policy. + // GESTURE: Start selecting several photographs + // where: Library grid + // touch: Press and hold a photograph, or press Select in the header + // pointer: Ctrl-click, or press Select in the header + // why: Touch has no ctrl, so without a mode there is no way to + // select a second photograph — the first tap would open it. + // The hold is the fast way in and the button is the one that + // can be found. + // + // GESTURE: Add or remove one photograph + // where: Library grid + // touch: While selecting, tap it + // pointer: Ctrl-click it + // why: While selecting, a tap never opens. That is the whole point + // of the mode: one meaning per gesture at a time. Press Done to + // get tap-to-open back. + // + // GESTURE: Leave selecting + // where: Library grid + // touch: Press Done in the header + // pointer: Press Done in the header + // keys: Escape in property select-mode: false; callback toggle-select-mode(); /// TRACES: FR-CAT-5 @@ -1326,6 +1334,17 @@ export component LibraryGrid inherits Rectangle { /// no state for it, because it arrives as `cell-pressed`'s shift argument /// and lands in `apply_press` as the shift-click it already knows how to /// apply. + // GESTURE: Select a range + // where: Library grid + // touch: While selecting, press "Select to…", then tap the last + // photograph of the run + // pointer: Shift-click the last photograph of the run + // why: This replaced a double tap, which had no visible state and + // could take forty photographs by accident. The run is resolved + // by the catalog rather than by what is on screen, so the grid + // can scroll between the two taps — the ranges that hurt on a + // tablet are longer than a screenful, which is exactly where a + // finger sweep runs out. property ranging: false; // A range armed against nothing has no anchor to extend from, and the strip @@ -2054,6 +2073,18 @@ export component LibraryGrid inherits Rectangle { // belongs on the filter bar; this chip is the whole feature's // front door and the tray below is where both terms and the // any/all choice actually are. + // GESTURE: Find photographs with two people in them + // where: Library grid + // touch: Open the People chip on the filter bar, tap each + // name, then switch the chip beside them to "all of + // them" + // pointer: Open the People chip on the filter bar, click each + // name, then switch the chip beside them to "all of + // them" + // why: "Any of them" is a union and "all of them" is an + // intersection. The tray is where both terms and the + // choice between them live, because a filter belongs + // on the filter bar. FilterChip { icon: root.people-tray ? "chevron-down" : "chevron-right"; label: "People"; @@ -2333,6 +2364,13 @@ export component LibraryGrid inherits Rectangle { // The way out that is not "undo every tap". Distinct from // "Done", which leaves select mode entirely: clearing keeps the // mode, so the next selection can start straight away. + // GESTURE: Drop the selection but keep selecting + // where: Library grid + // touch: Press Clear in the selection strip + // pointer: Press Clear in the selection strip + // why: Distinct from Done, which leaves the mode + // entirely. Clearing keeps it, so the next + // selection can start straight away. if !root.ranging: Button { text: "Clear"; y: (parent.height - self.height) / 2; @@ -2343,6 +2381,14 @@ export component LibraryGrid inherits Rectangle { // do by hand: a scoped grid of two hundred frames is two hundred // taps otherwise, and "all of them, except those three" is a far // more common shape than the taps it took to say it. + // GESTURE: Select everything the grid is showing + // where: Library grid + // touch: While selecting, press "Select all" + // pointer: While selecting, press "Select all" + // why: A scoped grid of two hundred frames is two hundred + // taps otherwise, and "all of them, except those + // three" is a far more common shape than the taps it + // took to say it. if !root.ranging: Button { text: "Select all"; y: (parent.height - self.height) / 2; @@ -2776,6 +2822,13 @@ export component LibraryGrid inherits Rectangle { // tall sat at the top of a viewport thousands of rows long and // was under the fingers only while the grid had not been // scrolled. Anywhere else the gesture found nothing to land on. + // GESTURE: Resize the thumbnails + // where: Library grid + // touch: Pinch the grid with two fingers + // pointer: Ctrl and the scroll wheel + // why: There is no wheel on a tablet, so without the + // pinch the cell size could only be changed by a + // control a finger cannot reach. grid-pinch := ScaleRotateGestureHandler { width: 100%; height: parent.viewport-height; @@ -2918,6 +2971,17 @@ export component LibraryGrid inherits Rectangle { visible: cell.period-heading != ""; } + // GESTURE: File photographs in a collection + // where: Library grid + // touch: Drag a photograph — or a whole selection — onto a + // collection in the sidebar. Starting a drag stops + // the press becoming a hold, so it cannot leave you + // in selection mode. + // pointer: Drag a photograph — or a whole selection — onto a + // collection in the sidebar + // why: The selection is what the drag carries, which is + // why selecting several is worth the mode: forty + // photographs file in one gesture. for cell[i] in root.cells: DragArea { // Cells are positioned at their **absolute** place in the // library, not their index in the loaded window: the window @@ -3137,13 +3201,47 @@ export component LibraryGrid inherits Rectangle { // `clicked` fires before the `up` that follows it, so // it can only raise a flag — the decision to open has // to wait for the event that names the finger. + // GESTURE: Open a photograph + // where: Library grid + // touch: Tap it — a single tap, any length + // pointer: Click it + // why: A tap opens; a tap that *moved* does not. + // Travel is what separates a deliberate tap + // from a hand brushing past, and it is the + // only thing that does: the two are the same + // length. An earlier version required the + // finger to dwell 120 ms instead, and that + // rejected ordinary taps — a real tap is + // often quicker than a brush. property down-finger: -1; property click-pending: false; + // Where the press landed, so the release can tell how + // far the finger travelled. + // + // The Flickable already cancels a press that becomes a + // scroll, but only once it has claimed the gesture, + // which takes more travel than a graze has. This + // catches the rest: a contact that slid across the cell + // and lifted was reaching for something else. + property press-x: 0; + property press-y: 0; + + /// How far a finger may slide and still be a tap. + /// + /// A thumb's contact patch is wider than this, so no + /// stationary tap approaches it; a hand moving across + /// the glass passes it within one frame. Below about + /// this the number stops describing intent and starts + /// describing how steady the user's hand is. + property tap-slop: 12px; + pointer-event(ev) => { if (ev.kind == PointerEventKind.down) { self.down-finger = ev.touch-finger-id; self.click-pending = false; + self.press-x = self.mouse-x; + self.press-y = self.mouse-y; // A finger, not a pointer — see `touched`. if (ev.touch-finger-id != 0) { root.touched = true; @@ -3164,10 +3262,6 @@ export component LibraryGrid inherits Rectangle { i, ev.modifiers.control || root.select-mode, ev.modifiers.shift || root.ranging, - // Finger id 0 is the mouse — the same - // convention the pinch arbitration a - // few lines up already relies on. - ev.touch-finger-id != 0, ); // One shot. The range was between two taps // and the second has landed; left armed, it @@ -3187,7 +3281,9 @@ export component LibraryGrid inherits Rectangle { // unmodified. if (self.click-pending && !root.pinching - && ev.touch-finger-id == self.down-finger) { + && ev.touch-finger-id == self.down-finger + && abs(self.mouse-x - self.press-x) < self.tap-slop + && abs(self.mouse-y - self.press-y) < self.tap-slop) { root.cell-clicked(i); } self.click-pending = false; @@ -3204,12 +3300,28 @@ export component LibraryGrid inherits Rectangle { } clicked => { self.click-pending = true; } - // The far end of a range, in selection mode. Slint - // delivers `clicked` for the first tap as well, which - // is why the toggling is idempotent-by-union in Rust - // rather than this file trying to swallow one of them. - double-clicked => { root.cell-double-clicked(i); } + // **No `double-clicked` here, deliberately.** A double + // tap used to take a range in selection mode. It was + // the only gesture touch had for shift-click, and + // "Select to…" replaced it with a control that says + // what it is about to do. Leaving both meant two quick + // taps on one cell — a thing a hand does by accident — + // silently selecting a run of forty photographs, with + // no visible state to explain where they came from. + // + // Now two taps are two toggles and land back where they + // started, which is the only thing a user can predict + // from what is on screen. + // GESTURE: Rate a photograph without opening it + // where: Library grid + // touch: Tap a star on the cell + // pointer: Hover the cell, then click a star + // keys: 0 to 5 on the selection + // why: A star has to take the press without it + // also reaching the cell, or every rating + // throws the user into develop. + // // --- the rating strip, INSIDE the cell's hit area --- // // **A child of `cell-touch`, not a sibling of it.** Two