diff --git a/core/dr-pipeline/ops/white_balance.yaml b/core/dr-pipeline/ops/white_balance.yaml index 4096965..821255a 100644 --- a/core/dr-pipeline/ops/white_balance.yaml +++ b/core/dr-pipeline/ops/white_balance.yaml @@ -32,6 +32,33 @@ params: label: param.tint kind: amount +# An eyedropper, where the frontend has a canvas to hang one on. +# +# Sampling a neutral is the first move of the global tonal pass — every colour +# judgement afterwards is measured against where the grey was put — and it is +# a thing you do by pointing at the photograph, not by guessing at two sliders +# until a wall stops looking green. +# +# A *hint*, on the usual terms: the two parameters below stay ordinary +# addressable scalars, and a frontend with nowhere to host a sampler renders +# them as the sliders they already were. This one is additive rather than a +# replacement — the picker writes temperature and tint and the photographer +# still nudges them afterwards — which is a difference the frontend draws for +# itself; nothing here has to say it. +# +# The order matters and is the widget kind's own contract: the first parameter +# trades red against blue, the second green against magenta. +presentation: + widgets: [white_point] + params: [temperature, tint] + demand: + # A neutral is a point on the picture, so both axes at once. + two_dimensional: true + # Deliberately false. A grey card, a cloud, a white wall — the things + # worth sampling are large, and FR-UI-7 grows the hit region to the + # modality in any case, so a thumb is as workable as a mouse. + precise_pointing: false + # Temperature trades red against blue; tint trades green against magenta. # Both are scaled so the full range is a strong but not destructive # correction: ±0.5 in log2 at the extremes — half a stop of channel shift, diff --git a/core/dr-pipeline/src/descriptor.rs b/core/dr-pipeline/src/descriptor.rs index 2d877fb..0241d56 100644 --- a/core/dr-pipeline/src/descriptor.rs +++ b/core/dr-pipeline/src/descriptor.rs @@ -170,6 +170,24 @@ pub enum WidgetKind { /// On-canvas brush strokes. BrushMask, /// An eyedropper bound to the canvas, setting white balance from a pixel. + /// + /// **The one widget that reads the photograph rather than driving it**, + /// and that is what gives it a contract the others do not need. A curve + /// tells its frontend where its points are and the frontend moves them; an + /// eyedropper is handed a colour and has to work out what the parameters + /// should become, which is only possible if the operation says enough + /// about itself to be inverted: + /// + /// * The first two parameters in [`Presentation::params`] are its axes — + /// the first trading red against blue, the second green against + /// magenta — and each is monotonic in its axis. + /// * The operation publishes exactly three uniforms: the linear + /// per-channel gains, in red, green, blue order. + /// + /// The same kind of contract [`Self::ToneCurve`] carries when it says its + /// parameters are point coordinates interleaved, and it is checked rather + /// than trusted — see [`crate::neutral`], which does the inverting so that + /// no frontend has to hold a second copy of the declared response. WhitePoint, } diff --git a/core/dr-pipeline/src/graph.rs b/core/dr-pipeline/src/graph.rs index 5ad986c..7964dce 100644 --- a/core/dr-pipeline/src/graph.rs +++ b/core/dr-pipeline/src/graph.rs @@ -16,7 +16,7 @@ use crate::descriptor::{ use crate::framing::{CropRect, Framing}; use crate::lens::LensProfile; use crate::mask::MaskStack; -use crate::operation::{compose_full, ComposedShader, Operation}; +use crate::operation::{compose_full, ComposedShader, Operation, Uniform}; use crate::ops; use crate::preset::{Preset, Scope}; use crate::spot::SpotSet; @@ -436,6 +436,33 @@ impl EditGraph { warps.chain(ops).chain(std::iter::once(framing)).collect() } + /// TRACES: FR-DEV-3a + /// What one operation's uniforms currently evaluate to. + /// + /// The same numbers [`Self::compose`] would bake into the uniform block, + /// asked for one node rather than for the whole chain. `None` where no + /// operation carries that id — the framing and the lens warps are not in + /// `ops`, and neither publishes uniforms of this kind. + /// + /// **Why anything outside composition wants these.** A widget that reads + /// the photograph rather than driving it — an eyedropper, above all — has + /// to invert the operation: it knows what the pixel is and what it should + /// become, and needs the parameter values that get it there. The mapping + /// from parameters to effect lives in the node's own declaration, and + /// this is the only way to ask it what that mapping currently says + /// without composing a shader and rendering one. See [`crate::neutral`], + /// which is the one caller. + /// + /// Cheap: a declared node evaluates a handful of small arithmetic + /// expressions. It is not, however, a per-frame path, and it is not on + /// one — composition reads the same values by its own route. + pub fn uniforms_of(&self, op: OpId) -> Option> { + self.ops + .iter() + .find(|o| o.descriptor().id == op) + .map(|o| o.uniforms()) + } + /// Set a parameter, clamping to the descriptor's declared range. /// /// Clamping here rather than in each operation means an operation never diff --git a/core/dr-pipeline/src/lib.rs b/core/dr-pipeline/src/lib.rs index f3567fb..aaf07b9 100644 --- a/core/dr-pipeline/src/lib.rs +++ b/core/dr-pipeline/src/lib.rs @@ -41,6 +41,7 @@ pub mod graph; pub mod history; pub mod lens; pub mod mask; +pub mod neutral; pub mod operation; pub mod ops; pub mod preset; diff --git a/core/dr-pipeline/src/neutral.rs b/core/dr-pipeline/src/neutral.rs new file mode 100644 index 0000000..0c45eed --- /dev/null +++ b/core/dr-pipeline/src/neutral.rs @@ -0,0 +1,391 @@ +//! TRACES: FR-DEV-3 | FR-DEV-3a +//! Turning a colour that ought to be grey into white balance parameters. +//! +//! # Why this is in the core and not in the interface +//! +//! FR-DEV-3 asks for a white balance picker: point at something neutral and +//! the correction follows. The pointing is the interface's — it owns the +//! canvas, the pixel and the modality — but the *arithmetic* is not, and the +//! reason is ARCH §4.3a rather than tidiness. How far a hundred units of +//! temperature move red against blue is declared in +//! `core/dr-pipeline/ops/white_balance.yaml`, in one expression, and an +//! interface that inverted it would be holding a second copy of a number it +//! is not allowed to know. The copy would then be wrong the first time +//! somebody adjusted the range, silently, in the direction of "the picker is +//! slightly off". +//! +//! So the interface hands over a colour and this hands back a moved graph. +//! +//! # What it is allowed to assume, which is a widget kind and not an operation +//! +//! Nothing here names white balance. It looks for the operation that asks for +//! [`WidgetKind::WhitePoint`], and everything else is that widget kind's own +//! contract — the same kind of contract [`WidgetKind::ToneCurve`] carries when +//! it says its parameters are point coordinates interleaved: +//! +//! * The **first two parameters** the presentation names are the axes. The +//! first trades red against blue, the second green against magenta. +//! * The operation publishes **exactly three uniforms: the linear per-channel +//! gains, in red, green, blue order.** That is what an eyedropper needs in +//! order to be invertible at all, and it is the honest way to say so — +//! a node whose effect on a grey is not three gains is not a node an +//! eyedropper can drive, and declaring the widget on one is the mistake +//! this refuses rather than approximates. +//! +//! Checked rather than trusted: a node that declares the widget and publishes +//! four uniforms gets no picker, and its sliders go on working. +//! +//! # Why a search rather than an inversion +//! +//! The declared expression is arbitrary — `exp2` today, a table lookup or a +//! polynomial tomorrow — and only its *monotonicity* is part of the bargain: +//! warmer is warmer all the way along, or the slider is not a slider. A +//! bisection needs exactly that and nothing more, so it stays correct across +//! every expression the declaration language can grow, where a closed-form +//! inverse would be a second definition of the node maintained here. +//! +//! It is also free. Twenty halvings of two ranges, three times over, is a few +//! hundred evaluations of two small arithmetic expressions — on a click, not +//! on a frame. + +use crate::descriptor::{OpId, ParamId, ParamKind, WidgetKind}; +use crate::graph::{EditGraph, OpCapability}; + +/// Halvings per axis. +/// +/// Twenty resolves a ±100 control to about a five-thousandth of a unit, which +/// is far under the precision any of them is displayed at. There is no reason +/// to stop earlier: each step is two multiplications. +const STEPS: u32 = 20; + +/// How many times the two axes are solved in turn. +/// +/// One pass suffices for a node whose axes are independent, which is what +/// "trades red against blue" and "trades green against magenta" describe. The +/// repeats are for a node whose are not — a green correction that also lifts +/// red would leave the first axis a little out — and they cost nothing worth +/// counting. +const ROUNDS: u32 = 3; + +/// Below this a channel carries no ratio worth balancing. +/// +/// A sample in the deep shadows, or one taken on a blown highlight where a +/// channel has already clipped to nothing, has no white balance in it: the +/// logarithms below would run away and the picker would slam a slider to its +/// stop. Refusing is the honest answer, and the caller reports that the point +/// was not usable rather than moving the photograph. +const FLOOR: f32 = 1e-4; + +/// TRACES: FR-DEV-3 +/// Move the graph so that `sample` renders neutral. +/// +/// `sample` is linear RGB, as the operation's own gains multiply it — that is, +/// measured with the sampling operation at its defaults. Returns whether the +/// graph was moved: `false` where the chain offers no white point widget, or +/// where the colour has no balance in it to correct. +/// +/// **Absolute, not relative.** The values written depend on the colour and not +/// on where the sliders happened to be, so sampling the same wall twice lands +/// in the same place — and sampling a second, better neutral corrects the +/// photograph rather than correcting the correction. +pub fn neutralise(graph: &mut EditGraph, sample: [f32; 3]) -> bool { + if sample.iter().any(|c| !c.is_finite() || *c < FLOOR) { + return false; + } + let Some(axes) = sampler(graph) else { + return false; + }; + // The uniform contract, checked before anything moves. A node that + // declares the widget and publishes something other than three gains + // cannot be driven from a pixel, and half-solving it would leave the + // photograph somewhere nobody asked for. + if gains(graph, axes.op).is_none() { + return false; + } + + for _ in 0..ROUNDS { + solve( + graph, + axes.op, + axes.warm, + axes.warm_axis, + sample, + warm_error, + ); + solve( + graph, + axes.op, + axes.green, + axes.green_axis, + sample, + green_error, + ); + } + true +} + +/// The operation an eyedropper writes to, and the two axes it moves. +struct Axes { + op: OpId, + /// Red against blue, with its declared travel and display precision. + warm: ParamId, + warm_axis: (f32, f32, u8), + /// Green against magenta, on the same terms. + green: ParamId, + green_axis: (f32, f32, u8), +} + +/// Find the operation that asked to be driven from a pixel. +/// +/// The *first* one, if a chain ever carries two. Two white points in one chain +/// is a chain that has already decided something odd, and picking the first is +/// at least the same answer every time. +fn sampler(graph: &EditGraph) -> Option { + graph.capabilities().into_iter().find_map(|cap| { + let presentation = cap.presentation.as_ref()?; + if !presentation.widgets.contains(&WidgetKind::WhitePoint) { + return None; + } + let mut owned = presentation.params.iter().copied(); + let warm = owned.next()?; + let green = owned.next()?; + Some(Axes { + op: cap.id, + warm, + warm_axis: axis(&cap, warm)?, + green, + green_axis: axis(&cap, green)?, + }) + }) +} + +/// How far a parameter may be moved and how finely, from its own declaration. +/// +/// A non-scalar axis is refused rather than coerced: a bisection over a list +/// of named alternatives is meaningless, and an operation offering one has not +/// declared what this widget kind needs. +fn axis(cap: &OpCapability, param: ParamId) -> Option<(f32, f32, u8)> { + cap.params + .iter() + .find(|p| p.id == param) + .and_then(|p| match &p.kind { + ParamKind::Scalar { + min, + max, + precision, + .. + } => Some((*min, *max, *precision)), + _ => None, + }) +} + +/// Round to the precision the parameter is displayed at. +/// +/// **The search has to stop somewhere, and this is the honest place.** Twenty +/// halvings land on something like -63.0117, which the panel would draw as +/// -63 and a photographer could never reproduce by hand — so the two would +/// disagree about what the control says, and a slider nudged one unit either +/// way would silently discard a fraction nobody could see. +/// +/// It also fixes the case that matters most: sampling something that is +/// *already* neutral. Unrounded, that lands a ten-thousandth off zero, which +/// is a photograph marked modified and a step on the undo stack for a +/// correction of nothing. +fn snap(value: f32, precision: u8) -> f32 { + let scale = 10f32.powi(i32::from(precision)); + (value * scale).round() / scale +} + +/// The three linear gains this operation currently applies, in RGB order. +/// +/// `None` unless there are exactly three, which is the widget kind's contract +/// stated as a check. See the module note for why it is a contract and not a +/// guess. +fn gains(graph: &EditGraph, op: OpId) -> Option<[f32; 3]> { + let uniforms = graph.uniforms_of(op)?; + match uniforms.as_slice() { + [r, g, b] => Some([r.value, g.value, b.value]), + _ => None, + } +} + +/// How far red sits from blue in the corrected sample, in stops. +/// +/// Logarithms because the correction is multiplicative and the controls are +/// symmetric: warming by n and cooling by n are exact reciprocals, so an error +/// measured as a ratio is linear in the thing being searched and a difference +/// of products is not. +fn warm_error(gains: [f32; 3], sample: [f32; 3]) -> f32 { + (gains[0] * sample[0]).ln() - (gains[2] * sample[2]).ln() +} + +/// How far green sits from the red-blue midpoint, in stops. +/// +/// Against the midpoint rather than against red alone, so that the two axes do +/// not fight: with red and blue already balanced the two are the same number, +/// and while they are not, green is being pulled toward where the other axis +/// is heading rather than toward one end of it. +fn green_error(gains: [f32; 3], sample: [f32; 3]) -> f32 { + let r = (gains[0] * sample[0]).ln(); + let b = (gains[2] * sample[2]).ln(); + (gains[1] * sample[1]).ln() - 0.5 * (r + b) +} + +/// Drive one axis until `error` crosses zero, and leave it there. +/// +/// The direction is read off the ends rather than assumed: which way "warmer" +/// runs is the node's business, and a picker that had guessed would move the +/// slider the wrong way on the first node that disagreed with it. +fn solve( + graph: &mut EditGraph, + op: OpId, + param: ParamId, + (min, max, precision): (f32, f32, u8), + sample: [f32; 3], + error: fn([f32; 3], [f32; 3]) -> f32, +) { + let at = |graph: &mut EditGraph, value: f32| -> f32 { + graph.set_param(op, param, value); + gains(graph, op).map_or(0.0, |g| error(g, sample)) + }; + + let mut low = min; + let mut high = max; + let low_error = at(graph, low); + let high_error = at(graph, high); + + // No crossing inside the declared travel: the correction this colour needs + // is more than the control can give. Taken as far as it goes, which is + // what a photographer would do by hand — refusing would leave a badly cast + // frame uncorrected because it could not be corrected *entirely*. + if low_error.is_sign_positive() == high_error.is_sign_positive() { + let end = if low_error.abs() <= high_error.abs() { + low + } else { + high + }; + graph.set_param(op, param, snap(end, precision)); + return; + } + + for _ in 0..STEPS { + let middle = 0.5 * (low + high); + if at(graph, middle).is_sign_positive() == low_error.is_sign_positive() { + low = middle; + } else { + high = middle; + } + } + graph.set_param(op, param, snap(0.5 * (low + high), precision)); +} + +#[cfg(test)] +mod tests { + use super::*; + + /// The spread of a triple, relative to its middle channel. + fn cast(rendered: [f32; 3]) -> f32 { + let high = rendered.iter().copied().fold(f32::MIN, f32::max); + let low = rendered.iter().copied().fold(f32::MAX, f32::min); + (high - low) / rendered[1].max(f32::EPSILON) + } + + /// What the sampled colour becomes once the graph has been moved. + fn corrected(graph: &EditGraph, sample: [f32; 3]) -> [f32; 3] { + let axes = sampler(graph).expect("the default chain declares a white point"); + let g = gains(graph, axes.op).expect("three gains"); + [g[0] * sample[0], g[1] * sample[1], g[2] * sample[2]] + } + + /// TRACES: FR-DEV-3 + /// The whole point: a warm grey comes back grey. + #[test] + fn sampling_a_warm_grey_makes_it_grey() { + let mut graph = EditGraph::default_chain(); + let sample = [0.62, 0.50, 0.40]; + assert!(cast(sample) > 0.3, "the premise: this is a strong cast"); + + assert!(neutralise(&mut graph, sample)); + assert!( + cast(corrected(&graph, sample)) < 0.02, + "the sample should render neutral: {:?}", + corrected(&graph, sample) + ); + } + + /// TRACES: FR-DEV-3 + /// And so does a cold one, which is the other half of the same claim: the + /// search finds its own direction rather than being told one. + #[test] + fn sampling_a_cold_grey_makes_it_grey_too() { + let mut graph = EditGraph::default_chain(); + let sample = [0.40, 0.50, 0.62]; + + assert!(neutralise(&mut graph, sample)); + assert!( + cast(corrected(&graph, sample)) < 0.02, + "{:?}", + corrected(&graph, sample) + ); + } + + /// TRACES: FR-DEV-3 + /// Sampling is absolute: the second sample corrects the photograph, not + /// the previous correction. + /// + /// The failure this guards is the one every relative picker has — sample a + /// wall, decide a cloud was better, sample the cloud, and land somewhere + /// neither of them describes. + #[test] + fn a_second_sample_replaces_the_first_rather_than_compounding_it() { + let mut graph = EditGraph::default_chain(); + + assert!(neutralise(&mut graph, [0.62, 0.50, 0.40])); + assert!(neutralise(&mut graph, [0.44, 0.50, 0.56])); + + let second = [0.44, 0.50, 0.56]; + assert!( + cast(corrected(&graph, second)) < 0.02, + "{:?}", + corrected(&graph, second) + ); + } + + /// TRACES: FR-DEV-3 + /// A sample with nothing in it is refused rather than acted on. + /// + /// Black has no white balance. A picker that treated it as one would take + /// the ratio of two numbers that are both noise and slam the controls to + /// their stops, which reads as the feature being broken rather than as the + /// point having been a poor choice. + #[test] + fn a_sample_with_no_balance_in_it_moves_nothing() { + let mut graph = EditGraph::default_chain(); + let before = crate::Preset::capture(&graph); + + assert!(!neutralise(&mut graph, [0.0, 0.0, 0.0])); + assert!(!neutralise(&mut graph, [f32::NAN, 0.5, 0.5])); + + assert_eq!(crate::Preset::capture(&graph), before); + } + + /// TRACES: FR-DEV-3a + /// The picker is found through the widget kind, not through a name. + /// + /// If this ever fails because the declaration moved, the right fix is in + /// the declaration: nothing here is entitled to know which node it is. + #[test] + fn the_chain_offers_exactly_one_white_point() { + let graph = EditGraph::default_chain(); + let found = graph + .capabilities() + .into_iter() + .filter(|c| { + c.presentation + .as_ref() + .is_some_and(|p| p.widgets.contains(&WidgetKind::WhitePoint)) + }) + .count(); + assert_eq!(found, 1, "one operation should ask to be driven by a pixel"); + } +} diff --git a/docs/traceability.md b/docs/traceability.md index 6f60a74..6b49ee9 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 | 336 | -| TRACES tags found | 1154 | +| Source files scanned | 337 | +| TRACES tags found | 1180 | | Requirements defined | 180 | | Requirements covered | 128 | | **Coverage** | **71.1%** (128/180) | @@ -34,114 +34,114 @@ _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:118`](../core/dr-sync/src/scan.rs#L118), [`core/dr-types/src/lib.rs:203`](../core/dr-types/src/lib.rs#L203), [`core/dr-types/src/lib.rs:272`](../core/dr-types/src/lib.rs#L272), [`core/dr-types/src/lib.rs:305`](../core/dr-types/src/lib.rs#L305), [`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), [`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:1374`](../ui/dr-ui/src/lib.rs#L1374), [`ui/dr-ui/ui/import.slint:5`](../ui/dr-ui/ui/import.slint#L5), [`ui/dr-ui/ui/library.slint:1028`](../ui/dr-ui/ui/library.slint#L1028), [`ui/dr-ui/ui/library.slint:1244`](../ui/dr-ui/ui/library.slint#L1244), [`ui/dr-ui/ui/library.slint:974`](../ui/dr-ui/ui/library.slint#L974) | -| 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:1374`](../ui/dr-ui/src/lib.rs#L1374), [`ui/dr-ui/src/library.rs:183`](../ui/dr-ui/src/library.rs#L183), [`ui/dr-ui/src/library.rs:2819`](../ui/dr-ui/src/library.rs#L2819), [`ui/dr-ui/ui/import.slint:5`](../ui/dr-ui/ui/import.slint#L5) | +| FR-CAT-10 | [`core/dr-ingest/src/layout.rs:1`](../core/dr-ingest/src/layout.rs#L1), [`core/dr-ingest/src/lib.rs:1`](../core/dr-ingest/src/lib.rs#L1), [`core/dr-ingest/src/lib.rs:733`](../core/dr-ingest/src/lib.rs#L733), [`core/dr-types/src/settings.rs:206`](../core/dr-types/src/settings.rs#L206), [`platform/dr-plat/src/storage.rs:287`](../platform/dr-plat/src/storage.rs#L287), [`platform/dr-plat/src/storage.rs:586`](../platform/dr-plat/src/storage.rs#L586), [`platform/dr-plat/src/volumes.rs:1`](../platform/dr-plat/src/volumes.rs#L1), [`platform/dr-plat/src/volumes.rs:62`](../platform/dr-plat/src/volumes.rs#L62), [`ui/dr-ui/src/import.rs:1`](../ui/dr-ui/src/import.rs#L1), [`ui/dr-ui/src/import.rs:336`](../ui/dr-ui/src/import.rs#L336), [`ui/dr-ui/src/import_ui.rs:1`](../ui/dr-ui/src/import_ui.rs#L1), [`ui/dr-ui/src/lib.rs:1379`](../ui/dr-ui/src/lib.rs#L1379), [`ui/dr-ui/ui/import.slint:5`](../ui/dr-ui/ui/import.slint#L5), [`ui/dr-ui/ui/library.slint:1028`](../ui/dr-ui/ui/library.slint#L1028), [`ui/dr-ui/ui/library.slint:1244`](../ui/dr-ui/ui/library.slint#L1244), [`ui/dr-ui/ui/library.slint:974`](../ui/dr-ui/ui/library.slint#L974) | +| 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:1379`](../ui/dr-ui/src/lib.rs#L1379), [`ui/dr-ui/src/library.rs:183`](../ui/dr-ui/src/library.rs#L183), [`ui/dr-ui/src/library.rs:2819`](../ui/dr-ui/src/library.rs#L2819), [`ui/dr-ui/ui/import.slint:5`](../ui/dr-ui/ui/import.slint#L5) | | FR-CAT-12 | [`core/dr-pipeline/src/sidecar.rs:120`](../core/dr-pipeline/src/sidecar.rs#L120) | | FR-CAT-13 | [`core/dr-xmp/src/lib.rs:1`](../core/dr-xmp/src/lib.rs#L1), [`core/dr-xmp/src/lib.rs:331`](../core/dr-xmp/src/lib.rs#L331), [`core/dr-xmp/src/lib.rs:442`](../core/dr-xmp/src/lib.rs#L442), [`core/dr-xmp/src/lib.rs:535`](../core/dr-xmp/src/lib.rs#L535), [`core/dr-xmp/src/lib.rs:733`](../core/dr-xmp/src/lib.rs#L733), [`core/dr-xmp/src/lib.rs:746`](../core/dr-xmp/src/lib.rs#L746), [`core/dr-xmp/src/read.rs:1`](../core/dr-xmp/src/read.rs#L1), [`core/dr-xmp/src/write.rs:1`](../core/dr-xmp/src/write.rs#L1), [`core/dr-xmp/tests/round_trip.rs:1`](../core/dr-xmp/tests/round_trip.rs#L1) | | FR-CAT-15 | [`core/dr-catalog/src/schema.rs:813`](../core/dr-catalog/src/schema.rs#L813), [`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:604`](../core/dr-sync/src/scan.rs#L604), [`core/dr-sync/src/scan.rs:82`](../core/dr-sync/src/scan.rs#L82), [`core/dr-thumbs/src/lib.rs:376`](../core/dr-thumbs/src/lib.rs#L376), [`core/dr-types/src/place.rs:91`](../core/dr-types/src/place.rs#L91), [`ui/dr-ui/src/collections_ui.rs:1283`](../ui/dr-ui/src/collections_ui.rs#L1283), [`ui/dr-ui/src/collections_ui.rs:2189`](../ui/dr-ui/src/collections_ui.rs#L2189), [`ui/dr-ui/src/library.rs:183`](../ui/dr-ui/src/library.rs#L183), [`ui/dr-ui/src/library.rs:200`](../ui/dr-ui/src/library.rs#L200), [`ui/dr-ui/src/library.rs:249`](../ui/dr-ui/src/library.rs#L249), [`ui/dr-ui/src/library.rs:4440`](../ui/dr-ui/src/library.rs#L4440), [`ui/dr-ui/src/library.rs:4474`](../ui/dr-ui/src/library.rs#L4474), [`ui/dr-ui/src/library_ui.rs:238`](../ui/dr-ui/src/library_ui.rs#L238), [`ui/dr-ui/src/library_ui.rs:838`](../ui/dr-ui/src/library_ui.rs#L838), [`ui/dr-ui/src/trash.rs:1`](../ui/dr-ui/src/trash.rs#L1), [`ui/dr-ui/ui/collections.slint:621`](../ui/dr-ui/ui/collections.slint#L621) | | FR-CAT-1a | [`core/dr-catalog/src/walk.rs:1`](../core/dr-catalog/src/walk.rs#L1), [`core/dr-types/src/lib.rs:56`](../core/dr-types/src/lib.rs#L56), [`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) | -| 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:94`](../core/dr-sync/src/scan.rs#L94), [`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:3292`](../ui/dr-ui/src/library.rs#L3292), [`ui/dr-ui/src/library.rs:3883`](../ui/dr-ui/src/library.rs#L3883), [`ui/dr-ui/src/library_ui.rs:177`](../ui/dr-ui/src/library_ui.rs#L177), [`ui/dr-ui/src/library_ui.rs:4235`](../ui/dr-ui/src/library_ui.rs#L4235), [`ui/dr-ui/src/library_ui.rs:5734`](../ui/dr-ui/src/library_ui.rs#L5734), [`ui/dr-ui/ui/app.slint:466`](../ui/dr-ui/ui/app.slint#L466), [`ui/dr-ui/ui/settings.slint:395`](../ui/dr-ui/ui/settings.slint#L395), [`ui/dr-ui/ui/settings.slint:73`](../ui/dr-ui/ui/settings.slint#L73) | +| FR-CAT-3 | [`core/dr-catalog/src/jobs.rs:1`](../core/dr-catalog/src/jobs.rs#L1), [`core/dr-catalog/src/walk.rs:66`](../core/dr-catalog/src/walk.rs#L66), [`core/dr-sync/src/scan.rs:94`](../core/dr-sync/src/scan.rs#L94), [`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:3292`](../ui/dr-ui/src/library.rs#L3292), [`ui/dr-ui/src/library.rs:3883`](../ui/dr-ui/src/library.rs#L3883), [`ui/dr-ui/src/library_ui.rs:177`](../ui/dr-ui/src/library_ui.rs#L177), [`ui/dr-ui/src/library_ui.rs:4235`](../ui/dr-ui/src/library_ui.rs#L4235), [`ui/dr-ui/src/library_ui.rs:5734`](../ui/dr-ui/src/library_ui.rs#L5734), [`ui/dr-ui/ui/app.slint:490`](../ui/dr-ui/ui/app.slint#L490), [`ui/dr-ui/ui/settings.slint:395`](../ui/dr-ui/ui/settings.slint#L395), [`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:356`](../core/dr-catalog/src/schema.rs#L356), [`ui/dr-ui/src/library.rs:1`](../ui/dr-ui/src/library.rs#L1), [`ui/dr-ui/src/library.rs:230`](../ui/dr-ui/src/library.rs#L230), [`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:1231`](../core/dr-catalog/src/schema.rs#L1231), [`core/dr-catalog/src/schema.rs:728`](../core/dr-catalog/src/schema.rs#L728), [`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:137`](../core/dr-pipeline/src/sidecar.rs#L137), [`ui/dr-ui/src/collections_ui.rs:1579`](../ui/dr-ui/src/collections_ui.rs#L1579), [`ui/dr-ui/src/collections_ui.rs:1685`](../ui/dr-ui/src/collections_ui.rs#L1685), [`ui/dr-ui/src/collections_ui.rs:1734`](../ui/dr-ui/src/collections_ui.rs#L1734), [`ui/dr-ui/src/collections_ui.rs:238`](../ui/dr-ui/src/collections_ui.rs#L238), [`ui/dr-ui/src/collections_ui.rs:335`](../ui/dr-ui/src/collections_ui.rs#L335), [`ui/dr-ui/src/collections_ui.rs:87`](../ui/dr-ui/src/collections_ui.rs#L87), [`ui/dr-ui/src/library.rs:4488`](../ui/dr-ui/src/library.rs#L4488), [`ui/dr-ui/src/library_ui.rs:713`](../ui/dr-ui/src/library_ui.rs#L713), [`ui/dr-ui/src/library_ui.rs:7691`](../ui/dr-ui/src/library_ui.rs#L7691), [`ui/dr-ui/src/library_ui.rs:7702`](../ui/dr-ui/src/library_ui.rs#L7702), [`ui/dr-ui/src/library_ui.rs:7715`](../ui/dr-ui/src/library_ui.rs#L7715), [`ui/dr-ui/src/library_ui.rs:7730`](../ui/dr-ui/src/library_ui.rs#L7730), [`ui/dr-ui/src/library_ui.rs:7739`](../ui/dr-ui/src/library_ui.rs#L7739), [`ui/dr-ui/ui/app.slint:387`](../ui/dr-ui/ui/app.slint#L387), [`ui/dr-ui/ui/app.slint:609`](../ui/dr-ui/ui/app.slint#L609), [`ui/dr-ui/ui/library.slint:1350`](../ui/dr-ui/ui/library.slint#L1350), [`ui/dr-ui/ui/library.slint:1374`](../ui/dr-ui/ui/library.slint#L1374), [`ui/dr-ui/ui/library.slint:1427`](../ui/dr-ui/ui/library.slint#L1427), [`ui/dr-ui/ui/library.slint:19`](../ui/dr-ui/ui/library.slint#L19), [`ui/dr-ui/ui/library.slint:4101`](../ui/dr-ui/ui/library.slint#L4101) | -| 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:728`](../core/dr-catalog/src/schema.rs#L728), [`core/dr-types/src/place.rs:1`](../core/dr-types/src/place.rs#L1), [`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:254`](../ui/dr-ui/src/library.rs#L254), [`ui/dr-ui/src/library.rs:4964`](../ui/dr-ui/src/library.rs#L4964), [`ui/dr-ui/src/library_ui.rs:389`](../ui/dr-ui/src/library_ui.rs#L389), [`ui/dr-ui/src/library_ui.rs:470`](../ui/dr-ui/src/library_ui.rs#L470), [`ui/dr-ui/src/library_ui.rs:6421`](../ui/dr-ui/src/library_ui.rs#L6421), [`ui/dr-ui/src/library_ui.rs:6474`](../ui/dr-ui/src/library_ui.rs#L6474), [`ui/dr-ui/src/library_ui.rs:7831`](../ui/dr-ui/src/library_ui.rs#L7831), [`ui/dr-ui/ui/app.slint:399`](../ui/dr-ui/ui/app.slint#L399), [`ui/dr-ui/ui/app.slint:609`](../ui/dr-ui/ui/app.slint#L609), [`ui/dr-ui/ui/app.slint:924`](../ui/dr-ui/ui/app.slint#L924), [`ui/dr-ui/ui/library.slint:111`](../ui/dr-ui/ui/library.slint#L111), [`ui/dr-ui/ui/library.slint:1537`](../ui/dr-ui/ui/library.slint#L1537), [`ui/dr-ui/ui/library.slint:4101`](../ui/dr-ui/ui/library.slint#L4101), [`ui/dr-ui/ui/settings.slint:158`](../ui/dr-ui/ui/settings.slint#L158) | -| 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:1073`](../ui/dr-ui/src/collections_ui.rs#L1073), [`ui/dr-ui/src/collections_ui.rs:117`](../ui/dr-ui/src/collections_ui.rs#L117), [`ui/dr-ui/src/collections_ui.rs:1552`](../ui/dr-ui/src/collections_ui.rs#L1552), [`ui/dr-ui/src/collections_ui.rs:1598`](../ui/dr-ui/src/collections_ui.rs#L1598), [`ui/dr-ui/src/collections_ui.rs:1848`](../ui/dr-ui/src/collections_ui.rs#L1848), [`ui/dr-ui/src/collections_ui.rs:1913`](../ui/dr-ui/src/collections_ui.rs#L1913), [`ui/dr-ui/src/collections_ui.rs:1973`](../ui/dr-ui/src/collections_ui.rs#L1973), [`ui/dr-ui/src/collections_ui.rs:1`](../ui/dr-ui/src/collections_ui.rs#L1), [`ui/dr-ui/src/collections_ui.rs:2963`](../ui/dr-ui/src/collections_ui.rs#L2963), [`ui/dr-ui/src/collections_ui.rs:365`](../ui/dr-ui/src/collections_ui.rs#L365), [`ui/dr-ui/src/collections_ui.rs:569`](../ui/dr-ui/src/collections_ui.rs#L569), [`ui/dr-ui/src/collections_ui.rs:965`](../ui/dr-ui/src/collections_ui.rs#L965), [`ui/dr-ui/src/derived_sync.rs:1`](../ui/dr-ui/src/derived_sync.rs#L1), [`ui/dr-ui/src/library.rs:4769`](../ui/dr-ui/src/library.rs#L4769), [`ui/dr-ui/src/library.rs:4795`](../ui/dr-ui/src/library.rs#L4795), [`ui/dr-ui/src/library.rs:4850`](../ui/dr-ui/src/library.rs#L4850), [`ui/dr-ui/src/library_ui.rs:2700`](../ui/dr-ui/src/library_ui.rs#L2700), [`ui/dr-ui/src/library_ui.rs:4097`](../ui/dr-ui/src/library_ui.rs#L4097), [`ui/dr-ui/src/library_ui.rs:4848`](../ui/dr-ui/src/library_ui.rs#L4848), [`ui/dr-ui/ui/app.slint:390`](../ui/dr-ui/ui/app.slint#L390), [`ui/dr-ui/ui/app.slint:604`](../ui/dr-ui/ui/app.slint#L604), [`ui/dr-ui/ui/app.slint:633`](../ui/dr-ui/ui/app.slint#L633), [`ui/dr-ui/ui/collections.slint:4`](../ui/dr-ui/ui/collections.slint#L4), [`ui/dr-ui/ui/library.slint:1317`](../ui/dr-ui/ui/library.slint#L1317), [`ui/dr-ui/ui/library.slint:2886`](../ui/dr-ui/ui/library.slint#L2886), [`ui/dr-ui/ui/library.slint:4079`](../ui/dr-ui/ui/library.slint#L4079), [`ui/dr-ui/ui/library.slint:993`](../ui/dr-ui/ui/library.slint#L993) | -| FR-CAT-8 | [`core/dr-catalog/src/schema.rs:532`](../core/dr-catalog/src/schema.rs#L532), [`core/dr-pipeline/src/coverage.rs:1`](../core/dr-pipeline/src/coverage.rs#L1), [`core/dr-pipeline/src/graph.rs:465`](../core/dr-pipeline/src/graph.rs#L465), [`core/dr-pipeline/src/graph.rs:513`](../core/dr-pipeline/src/graph.rs#L513), [`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:1165`](../core/dr-pipeline/src/sidecar.rs#L1165), [`core/dr-pipeline/src/sidecar.rs:1831`](../core/dr-pipeline/src/sidecar.rs#L1831), [`core/dr-pipeline/src/sidecar.rs:94`](../core/dr-pipeline/src/sidecar.rs#L94), [`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), [`core/dr-sync/src/scan.rs:31`](../core/dr-sync/src/scan.rs#L31), [`core/dr-sync/src/scan.rs:45`](../core/dr-sync/src/scan.rs#L45), [`core/dr-sync/src/scan.rs:912`](../core/dr-sync/src/scan.rs#L912), [`ui/dr-ui/src/develop.rs:1933`](../ui/dr-ui/src/develop.rs#L1933), [`ui/dr-ui/src/develop.rs:4429`](../ui/dr-ui/src/develop.rs#L4429), [`ui/dr-ui/src/develop.rs:4458`](../ui/dr-ui/src/develop.rs#L4458), [`ui/dr-ui/src/develop.rs:5491`](../ui/dr-ui/src/develop.rs#L5491), [`ui/dr-ui/src/develop.rs:5545`](../ui/dr-ui/src/develop.rs#L5545), [`ui/dr-ui/src/develop.rs:5647`](../ui/dr-ui/src/develop.rs#L5647), [`ui/dr-ui/src/export.rs:799`](../ui/dr-ui/src/export.rs#L799), [`ui/dr-ui/src/lib.rs:1152`](../ui/dr-ui/src/lib.rs#L1152), [`ui/dr-ui/src/lib.rs:1668`](../ui/dr-ui/src/lib.rs#L1668), [`ui/dr-ui/src/lib.rs:2211`](../ui/dr-ui/src/lib.rs#L2211), [`ui/dr-ui/src/lib.rs:2348`](../ui/dr-ui/src/lib.rs#L2348), [`ui/dr-ui/src/lib.rs:704`](../ui/dr-ui/src/lib.rs#L704), [`ui/dr-ui/src/library.rs:1376`](../ui/dr-ui/src/library.rs#L1376), [`ui/dr-ui/src/library.rs:1411`](../ui/dr-ui/src/library.rs#L1411), [`ui/dr-ui/src/library.rs:2219`](../ui/dr-ui/src/library.rs#L2219), [`ui/dr-ui/src/library.rs:500`](../ui/dr-ui/src/library.rs#L500), [`ui/dr-ui/src/library.rs:547`](../ui/dr-ui/src/library.rs#L547), [`ui/dr-ui/src/library.rs:584`](../ui/dr-ui/src/library.rs#L584), [`ui/dr-ui/src/library.rs:7144`](../ui/dr-ui/src/library.rs#L7144), [`ui/dr-ui/src/library.rs:73`](../ui/dr-ui/src/library.rs#L73), [`ui/dr-ui/src/library.rs:845`](../ui/dr-ui/src/library.rs#L845), [`ui/dr-ui/src/library_ui.rs:1265`](../ui/dr-ui/src/library_ui.rs#L1265), [`ui/dr-ui/src/library_ui.rs:6057`](../ui/dr-ui/src/library_ui.rs#L6057), [`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:785`](../core/dr-catalog/src/schema.rs#L785), [`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:200`](../core/dr-sync/src/scan.rs#L200), [`core/dr-sync/src/scan.rs:505`](../core/dr-sync/src/scan.rs#L505), [`core/dr-types/src/lib.rs:122`](../core/dr-types/src/lib.rs#L122), [`ui/dr-ui/src/develop.rs:3718`](../ui/dr-ui/src/develop.rs#L3718), [`ui/dr-ui/src/develop.rs:3761`](../ui/dr-ui/src/develop.rs#L3761), [`ui/dr-ui/src/library.rs:1276`](../ui/dr-ui/src/library.rs#L1276), [`ui/dr-ui/src/library.rs:1329`](../ui/dr-ui/src/library.rs#L1329), [`ui/dr-ui/src/library.rs:1360`](../ui/dr-ui/src/library.rs#L1360), [`ui/dr-ui/src/library.rs:1411`](../ui/dr-ui/src/library.rs#L1411), [`ui/dr-ui/src/library.rs:169`](../ui/dr-ui/src/library.rs#L169), [`ui/dr-ui/src/library.rs:1727`](../ui/dr-ui/src/library.rs#L1727), [`ui/dr-ui/src/library.rs:2179`](../ui/dr-ui/src/library.rs#L2179), [`ui/dr-ui/src/library.rs:2255`](../ui/dr-ui/src/library.rs#L2255), [`ui/dr-ui/src/library.rs:274`](../ui/dr-ui/src/library.rs#L274), [`ui/dr-ui/src/library.rs:5072`](../ui/dr-ui/src/library.rs#L5072), [`ui/dr-ui/src/library.rs:584`](../ui/dr-ui/src/library.rs#L584), [`ui/dr-ui/src/library.rs:829`](../ui/dr-ui/src/library.rs#L829), [`ui/dr-ui/src/library.rs:845`](../ui/dr-ui/src/library.rs#L845), [`ui/dr-ui/src/library.rs:899`](../ui/dr-ui/src/library.rs#L899), [`ui/dr-ui/src/library_ui.rs:1332`](../ui/dr-ui/src/library_ui.rs#L1332), [`ui/dr-ui/src/library_ui.rs:1923`](../ui/dr-ui/src/library_ui.rs#L1923), [`ui/dr-ui/src/library_ui.rs:1967`](../ui/dr-ui/src/library_ui.rs#L1967), [`ui/dr-ui/src/library_ui.rs:1983`](../ui/dr-ui/src/library_ui.rs#L1983), [`ui/dr-ui/src/library_ui.rs:2077`](../ui/dr-ui/src/library_ui.rs#L2077), [`ui/dr-ui/src/library_ui.rs:284`](../ui/dr-ui/src/library_ui.rs#L284), [`ui/dr-ui/src/library_ui.rs:2939`](../ui/dr-ui/src/library_ui.rs#L2939), [`ui/dr-ui/src/library_ui.rs:317`](../ui/dr-ui/src/library_ui.rs#L317), [`ui/dr-ui/src/library_ui.rs:325`](../ui/dr-ui/src/library_ui.rs#L325), [`ui/dr-ui/src/library_ui.rs:3377`](../ui/dr-ui/src/library_ui.rs#L3377), [`ui/dr-ui/src/library_ui.rs:3599`](../ui/dr-ui/src/library_ui.rs#L3599), [`ui/dr-ui/src/library_ui.rs:3877`](../ui/dr-ui/src/library_ui.rs#L3877), [`ui/dr-ui/src/library_ui.rs:3965`](../ui/dr-ui/src/library_ui.rs#L3965), [`ui/dr-ui/src/library_ui.rs:4148`](../ui/dr-ui/src/library_ui.rs#L4148), [`ui/dr-ui/src/library_ui.rs:4262`](../ui/dr-ui/src/library_ui.rs#L4262), [`ui/dr-ui/src/library_ui.rs:523`](../ui/dr-ui/src/library_ui.rs#L523), [`ui/dr-ui/src/library_ui.rs:586`](../ui/dr-ui/src/library_ui.rs#L586), [`ui/dr-ui/src/library_ui.rs:6519`](../ui/dr-ui/src/library_ui.rs#L6519), [`ui/dr-ui/src/library_ui.rs:6634`](../ui/dr-ui/src/library_ui.rs#L6634), [`ui/dr-ui/src/presets.rs:468`](../ui/dr-ui/src/presets.rs#L468), [`ui/dr-ui/src/presets.rs:480`](../ui/dr-ui/src/presets.rs#L480), [`ui/dr-ui/src/sidecar_cache.rs:1`](../ui/dr-ui/src/sidecar_cache.rs#L1), [`ui/dr-ui/tests/export_ignores_the_viewport.rs:1`](../ui/dr-ui/tests/export_ignores_the_viewport.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:1231`](../core/dr-catalog/src/schema.rs#L1231), [`core/dr-catalog/src/schema.rs:728`](../core/dr-catalog/src/schema.rs#L728), [`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:137`](../core/dr-pipeline/src/sidecar.rs#L137), [`ui/dr-ui/src/collections_ui.rs:1579`](../ui/dr-ui/src/collections_ui.rs#L1579), [`ui/dr-ui/src/collections_ui.rs:1685`](../ui/dr-ui/src/collections_ui.rs#L1685), [`ui/dr-ui/src/collections_ui.rs:1734`](../ui/dr-ui/src/collections_ui.rs#L1734), [`ui/dr-ui/src/collections_ui.rs:238`](../ui/dr-ui/src/collections_ui.rs#L238), [`ui/dr-ui/src/collections_ui.rs:335`](../ui/dr-ui/src/collections_ui.rs#L335), [`ui/dr-ui/src/collections_ui.rs:87`](../ui/dr-ui/src/collections_ui.rs#L87), [`ui/dr-ui/src/library.rs:4488`](../ui/dr-ui/src/library.rs#L4488), [`ui/dr-ui/src/library_ui.rs:713`](../ui/dr-ui/src/library_ui.rs#L713), [`ui/dr-ui/src/library_ui.rs:7691`](../ui/dr-ui/src/library_ui.rs#L7691), [`ui/dr-ui/src/library_ui.rs:7702`](../ui/dr-ui/src/library_ui.rs#L7702), [`ui/dr-ui/src/library_ui.rs:7715`](../ui/dr-ui/src/library_ui.rs#L7715), [`ui/dr-ui/src/library_ui.rs:7730`](../ui/dr-ui/src/library_ui.rs#L7730), [`ui/dr-ui/src/library_ui.rs:7739`](../ui/dr-ui/src/library_ui.rs#L7739), [`ui/dr-ui/ui/app.slint:411`](../ui/dr-ui/ui/app.slint#L411), [`ui/dr-ui/ui/app.slint:633`](../ui/dr-ui/ui/app.slint#L633), [`ui/dr-ui/ui/library.slint:1350`](../ui/dr-ui/ui/library.slint#L1350), [`ui/dr-ui/ui/library.slint:1374`](../ui/dr-ui/ui/library.slint#L1374), [`ui/dr-ui/ui/library.slint:1427`](../ui/dr-ui/ui/library.slint#L1427), [`ui/dr-ui/ui/library.slint:19`](../ui/dr-ui/ui/library.slint#L19), [`ui/dr-ui/ui/library.slint:4101`](../ui/dr-ui/ui/library.slint#L4101) | +| 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:728`](../core/dr-catalog/src/schema.rs#L728), [`core/dr-types/src/place.rs:1`](../core/dr-types/src/place.rs#L1), [`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:254`](../ui/dr-ui/src/library.rs#L254), [`ui/dr-ui/src/library.rs:4964`](../ui/dr-ui/src/library.rs#L4964), [`ui/dr-ui/src/library_ui.rs:389`](../ui/dr-ui/src/library_ui.rs#L389), [`ui/dr-ui/src/library_ui.rs:470`](../ui/dr-ui/src/library_ui.rs#L470), [`ui/dr-ui/src/library_ui.rs:6421`](../ui/dr-ui/src/library_ui.rs#L6421), [`ui/dr-ui/src/library_ui.rs:6474`](../ui/dr-ui/src/library_ui.rs#L6474), [`ui/dr-ui/src/library_ui.rs:7831`](../ui/dr-ui/src/library_ui.rs#L7831), [`ui/dr-ui/ui/app.slint:423`](../ui/dr-ui/ui/app.slint#L423), [`ui/dr-ui/ui/app.slint:633`](../ui/dr-ui/ui/app.slint#L633), [`ui/dr-ui/ui/app.slint:948`](../ui/dr-ui/ui/app.slint#L948), [`ui/dr-ui/ui/library.slint:111`](../ui/dr-ui/ui/library.slint#L111), [`ui/dr-ui/ui/library.slint:1537`](../ui/dr-ui/ui/library.slint#L1537), [`ui/dr-ui/ui/library.slint:4101`](../ui/dr-ui/ui/library.slint#L4101), [`ui/dr-ui/ui/settings.slint:158`](../ui/dr-ui/ui/settings.slint#L158) | +| 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:1073`](../ui/dr-ui/src/collections_ui.rs#L1073), [`ui/dr-ui/src/collections_ui.rs:117`](../ui/dr-ui/src/collections_ui.rs#L117), [`ui/dr-ui/src/collections_ui.rs:1552`](../ui/dr-ui/src/collections_ui.rs#L1552), [`ui/dr-ui/src/collections_ui.rs:1598`](../ui/dr-ui/src/collections_ui.rs#L1598), [`ui/dr-ui/src/collections_ui.rs:1848`](../ui/dr-ui/src/collections_ui.rs#L1848), [`ui/dr-ui/src/collections_ui.rs:1913`](../ui/dr-ui/src/collections_ui.rs#L1913), [`ui/dr-ui/src/collections_ui.rs:1973`](../ui/dr-ui/src/collections_ui.rs#L1973), [`ui/dr-ui/src/collections_ui.rs:1`](../ui/dr-ui/src/collections_ui.rs#L1), [`ui/dr-ui/src/collections_ui.rs:2963`](../ui/dr-ui/src/collections_ui.rs#L2963), [`ui/dr-ui/src/collections_ui.rs:365`](../ui/dr-ui/src/collections_ui.rs#L365), [`ui/dr-ui/src/collections_ui.rs:569`](../ui/dr-ui/src/collections_ui.rs#L569), [`ui/dr-ui/src/collections_ui.rs:965`](../ui/dr-ui/src/collections_ui.rs#L965), [`ui/dr-ui/src/derived_sync.rs:1`](../ui/dr-ui/src/derived_sync.rs#L1), [`ui/dr-ui/src/library.rs:4769`](../ui/dr-ui/src/library.rs#L4769), [`ui/dr-ui/src/library.rs:4795`](../ui/dr-ui/src/library.rs#L4795), [`ui/dr-ui/src/library.rs:4850`](../ui/dr-ui/src/library.rs#L4850), [`ui/dr-ui/src/library_ui.rs:2700`](../ui/dr-ui/src/library_ui.rs#L2700), [`ui/dr-ui/src/library_ui.rs:4097`](../ui/dr-ui/src/library_ui.rs#L4097), [`ui/dr-ui/src/library_ui.rs:4848`](../ui/dr-ui/src/library_ui.rs#L4848), [`ui/dr-ui/ui/app.slint:414`](../ui/dr-ui/ui/app.slint#L414), [`ui/dr-ui/ui/app.slint:628`](../ui/dr-ui/ui/app.slint#L628), [`ui/dr-ui/ui/app.slint:657`](../ui/dr-ui/ui/app.slint#L657), [`ui/dr-ui/ui/collections.slint:4`](../ui/dr-ui/ui/collections.slint#L4), [`ui/dr-ui/ui/library.slint:1317`](../ui/dr-ui/ui/library.slint#L1317), [`ui/dr-ui/ui/library.slint:2886`](../ui/dr-ui/ui/library.slint#L2886), [`ui/dr-ui/ui/library.slint:4079`](../ui/dr-ui/ui/library.slint#L4079), [`ui/dr-ui/ui/library.slint:993`](../ui/dr-ui/ui/library.slint#L993) | +| FR-CAT-8 | [`core/dr-catalog/src/schema.rs:532`](../core/dr-catalog/src/schema.rs#L532), [`core/dr-pipeline/src/coverage.rs:1`](../core/dr-pipeline/src/coverage.rs#L1), [`core/dr-pipeline/src/graph.rs:492`](../core/dr-pipeline/src/graph.rs#L492), [`core/dr-pipeline/src/graph.rs:540`](../core/dr-pipeline/src/graph.rs#L540), [`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:1165`](../core/dr-pipeline/src/sidecar.rs#L1165), [`core/dr-pipeline/src/sidecar.rs:1831`](../core/dr-pipeline/src/sidecar.rs#L1831), [`core/dr-pipeline/src/sidecar.rs:94`](../core/dr-pipeline/src/sidecar.rs#L94), [`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), [`core/dr-sync/src/scan.rs:31`](../core/dr-sync/src/scan.rs#L31), [`core/dr-sync/src/scan.rs:45`](../core/dr-sync/src/scan.rs#L45), [`core/dr-sync/src/scan.rs:912`](../core/dr-sync/src/scan.rs#L912), [`ui/dr-ui/src/develop.rs:1985`](../ui/dr-ui/src/develop.rs#L1985), [`ui/dr-ui/src/develop.rs:4593`](../ui/dr-ui/src/develop.rs#L4593), [`ui/dr-ui/src/develop.rs:4622`](../ui/dr-ui/src/develop.rs#L4622), [`ui/dr-ui/src/develop.rs:5686`](../ui/dr-ui/src/develop.rs#L5686), [`ui/dr-ui/src/develop.rs:5740`](../ui/dr-ui/src/develop.rs#L5740), [`ui/dr-ui/src/develop.rs:5842`](../ui/dr-ui/src/develop.rs#L5842), [`ui/dr-ui/src/export.rs:799`](../ui/dr-ui/src/export.rs#L799), [`ui/dr-ui/src/lib.rs:1157`](../ui/dr-ui/src/lib.rs#L1157), [`ui/dr-ui/src/lib.rs:1673`](../ui/dr-ui/src/lib.rs#L1673), [`ui/dr-ui/src/lib.rs:2216`](../ui/dr-ui/src/lib.rs#L2216), [`ui/dr-ui/src/lib.rs:2353`](../ui/dr-ui/src/lib.rs#L2353), [`ui/dr-ui/src/lib.rs:709`](../ui/dr-ui/src/lib.rs#L709), [`ui/dr-ui/src/library.rs:1376`](../ui/dr-ui/src/library.rs#L1376), [`ui/dr-ui/src/library.rs:1411`](../ui/dr-ui/src/library.rs#L1411), [`ui/dr-ui/src/library.rs:2219`](../ui/dr-ui/src/library.rs#L2219), [`ui/dr-ui/src/library.rs:500`](../ui/dr-ui/src/library.rs#L500), [`ui/dr-ui/src/library.rs:547`](../ui/dr-ui/src/library.rs#L547), [`ui/dr-ui/src/library.rs:584`](../ui/dr-ui/src/library.rs#L584), [`ui/dr-ui/src/library.rs:7144`](../ui/dr-ui/src/library.rs#L7144), [`ui/dr-ui/src/library.rs:73`](../ui/dr-ui/src/library.rs#L73), [`ui/dr-ui/src/library.rs:845`](../ui/dr-ui/src/library.rs#L845), [`ui/dr-ui/src/library_ui.rs:1265`](../ui/dr-ui/src/library_ui.rs#L1265), [`ui/dr-ui/src/library_ui.rs:6057`](../ui/dr-ui/src/library_ui.rs#L6057), [`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:785`](../core/dr-catalog/src/schema.rs#L785), [`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:200`](../core/dr-sync/src/scan.rs#L200), [`core/dr-sync/src/scan.rs:505`](../core/dr-sync/src/scan.rs#L505), [`core/dr-types/src/lib.rs:122`](../core/dr-types/src/lib.rs#L122), [`ui/dr-ui/src/develop.rs:3882`](../ui/dr-ui/src/develop.rs#L3882), [`ui/dr-ui/src/develop.rs:3925`](../ui/dr-ui/src/develop.rs#L3925), [`ui/dr-ui/src/library.rs:1276`](../ui/dr-ui/src/library.rs#L1276), [`ui/dr-ui/src/library.rs:1329`](../ui/dr-ui/src/library.rs#L1329), [`ui/dr-ui/src/library.rs:1360`](../ui/dr-ui/src/library.rs#L1360), [`ui/dr-ui/src/library.rs:1411`](../ui/dr-ui/src/library.rs#L1411), [`ui/dr-ui/src/library.rs:169`](../ui/dr-ui/src/library.rs#L169), [`ui/dr-ui/src/library.rs:1727`](../ui/dr-ui/src/library.rs#L1727), [`ui/dr-ui/src/library.rs:2179`](../ui/dr-ui/src/library.rs#L2179), [`ui/dr-ui/src/library.rs:2255`](../ui/dr-ui/src/library.rs#L2255), [`ui/dr-ui/src/library.rs:274`](../ui/dr-ui/src/library.rs#L274), [`ui/dr-ui/src/library.rs:5072`](../ui/dr-ui/src/library.rs#L5072), [`ui/dr-ui/src/library.rs:584`](../ui/dr-ui/src/library.rs#L584), [`ui/dr-ui/src/library.rs:829`](../ui/dr-ui/src/library.rs#L829), [`ui/dr-ui/src/library.rs:845`](../ui/dr-ui/src/library.rs#L845), [`ui/dr-ui/src/library.rs:899`](../ui/dr-ui/src/library.rs#L899), [`ui/dr-ui/src/library_ui.rs:1332`](../ui/dr-ui/src/library_ui.rs#L1332), [`ui/dr-ui/src/library_ui.rs:1923`](../ui/dr-ui/src/library_ui.rs#L1923), [`ui/dr-ui/src/library_ui.rs:1967`](../ui/dr-ui/src/library_ui.rs#L1967), [`ui/dr-ui/src/library_ui.rs:1983`](../ui/dr-ui/src/library_ui.rs#L1983), [`ui/dr-ui/src/library_ui.rs:2077`](../ui/dr-ui/src/library_ui.rs#L2077), [`ui/dr-ui/src/library_ui.rs:284`](../ui/dr-ui/src/library_ui.rs#L284), [`ui/dr-ui/src/library_ui.rs:2939`](../ui/dr-ui/src/library_ui.rs#L2939), [`ui/dr-ui/src/library_ui.rs:317`](../ui/dr-ui/src/library_ui.rs#L317), [`ui/dr-ui/src/library_ui.rs:325`](../ui/dr-ui/src/library_ui.rs#L325), [`ui/dr-ui/src/library_ui.rs:3377`](../ui/dr-ui/src/library_ui.rs#L3377), [`ui/dr-ui/src/library_ui.rs:3599`](../ui/dr-ui/src/library_ui.rs#L3599), [`ui/dr-ui/src/library_ui.rs:3877`](../ui/dr-ui/src/library_ui.rs#L3877), [`ui/dr-ui/src/library_ui.rs:3965`](../ui/dr-ui/src/library_ui.rs#L3965), [`ui/dr-ui/src/library_ui.rs:4148`](../ui/dr-ui/src/library_ui.rs#L4148), [`ui/dr-ui/src/library_ui.rs:4262`](../ui/dr-ui/src/library_ui.rs#L4262), [`ui/dr-ui/src/library_ui.rs:523`](../ui/dr-ui/src/library_ui.rs#L523), [`ui/dr-ui/src/library_ui.rs:586`](../ui/dr-ui/src/library_ui.rs#L586), [`ui/dr-ui/src/library_ui.rs:6519`](../ui/dr-ui/src/library_ui.rs#L6519), [`ui/dr-ui/src/library_ui.rs:6634`](../ui/dr-ui/src/library_ui.rs#L6634), [`ui/dr-ui/src/presets.rs:468`](../ui/dr-ui/src/presets.rs#L468), [`ui/dr-ui/src/presets.rs:480`](../ui/dr-ui/src/presets.rs#L480), [`ui/dr-ui/src/sidecar_cache.rs:1`](../ui/dr-ui/src/sidecar_cache.rs#L1), [`ui/dr-ui/tests/export_ignores_the_viewport.rs:1`](../ui/dr-ui/tests/export_ignores_the_viewport.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:395`](../core/dr-catalog/src/schema.rs#L395), [`core/dr-catalog/src/schema.rs:614`](../core/dr-catalog/src/schema.rs#L614), [`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:121`](../ui/dr-ui/src/develop.rs#L121), [`ui/dr-ui/src/develop.rs:130`](../ui/dr-ui/src/develop.rs#L130), [`ui/dr-ui/src/develop.rs:196`](../ui/dr-ui/src/develop.rs#L196), [`ui/dr-ui/src/develop.rs:2165`](../ui/dr-ui/src/develop.rs#L2165), [`ui/dr-ui/src/develop.rs:689`](../ui/dr-ui/src/develop.rs#L689), [`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:2320`](../ui/dr-ui/src/lib.rs#L2320), [`ui/dr-ui/ui/identity.slint:1`](../ui/dr-ui/ui/identity.slint#L1) | +| FR-CULL-10 | [`core/dr-catalog/src/faces.rs:1`](../core/dr-catalog/src/faces.rs#L1), [`core/dr-catalog/src/schema.rs:395`](../core/dr-catalog/src/schema.rs#L395), [`core/dr-catalog/src/schema.rs:614`](../core/dr-catalog/src/schema.rs#L614), [`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:121`](../ui/dr-ui/src/develop.rs#L121), [`ui/dr-ui/src/develop.rs:130`](../ui/dr-ui/src/develop.rs#L130), [`ui/dr-ui/src/develop.rs:196`](../ui/dr-ui/src/develop.rs#L196), [`ui/dr-ui/src/develop.rs:2217`](../ui/dr-ui/src/develop.rs#L2217), [`ui/dr-ui/src/develop.rs:689`](../ui/dr-ui/src/develop.rs#L689), [`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:2325`](../ui/dr-ui/src/lib.rs#L2325), [`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:614`](../core/dr-catalog/src/schema.rs#L614), [`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:295`](../ui/dr-ui/src/library.rs#L295), [`ui/dr-ui/src/library.rs:325`](../ui/dr-ui/src/library.rs#L325), [`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:395`](../core/dr-catalog/src/schema.rs#L395), [`core/dr-catalog/src/schema.rs:614`](../core/dr-catalog/src/schema.rs#L614), [`ui/dr-ui/src/identity.rs:1`](../ui/dr-ui/src/identity.rs#L1), [`ui/dr-ui/ui/identity.slint:1`](../ui/dr-ui/ui/identity.slint#L1) | | FR-CULL-2 | [`core/dr-decode/src/locate.rs:1`](../core/dr-decode/src/locate.rs#L1), [`core/dr-decode/src/preview.rs:148`](../core/dr-decode/src/preview.rs#L148), [`ui/dr-ui/src/import.rs:463`](../ui/dr-ui/src/import.rs#L463) | -| FR-CULL-3 | [`core/dr-gpu/src/focus.rs:154`](../core/dr-gpu/src/focus.rs#L154), [`core/dr-gpu/src/focus.rs:186`](../core/dr-gpu/src/focus.rs#L186), [`core/dr-gpu/src/focus.rs:1`](../core/dr-gpu/src/focus.rs#L1), [`core/dr-gpu/src/focus.rs:317`](../core/dr-gpu/src/focus.rs#L317), [`core/dr-gpu/src/raw_histogram.rs:129`](../core/dr-gpu/src/raw_histogram.rs#L129), [`core/dr-gpu/src/raw_histogram.rs:1`](../core/dr-gpu/src/raw_histogram.rs#L1), [`core/dr-gpu/src/raw_histogram.rs:272`](../core/dr-gpu/src/raw_histogram.rs#L272), [`core/dr-gpu/src/raw_histogram.rs:407`](../core/dr-gpu/src/raw_histogram.rs#L407), [`core/dr-gpu/src/shaders/focus_peak.wgsl:1`](../core/dr-gpu/src/shaders/focus_peak.wgsl#L1), [`core/dr-gpu/src/shaders/raw_histogram.wgsl:1`](../core/dr-gpu/src/shaders/raw_histogram.wgsl#L1), [`ui/dr-ui/src/develop.rs:3261`](../ui/dr-ui/src/develop.rs#L3261), [`ui/dr-ui/src/develop.rs:3274`](../ui/dr-ui/src/develop.rs#L3274), [`ui/dr-ui/src/develop.rs:3319`](../ui/dr-ui/src/develop.rs#L3319), [`ui/dr-ui/src/develop.rs:3330`](../ui/dr-ui/src/develop.rs#L3330), [`ui/dr-ui/src/develop.rs:3336`](../ui/dr-ui/src/develop.rs#L3336), [`ui/dr-ui/src/develop.rs:3353`](../ui/dr-ui/src/develop.rs#L3353), [`ui/dr-ui/src/develop.rs:7196`](../ui/dr-ui/src/develop.rs#L7196), [`ui/dr-ui/src/develop.rs:7260`](../ui/dr-ui/src/develop.rs#L7260), [`ui/dr-ui/src/develop.rs:7283`](../ui/dr-ui/src/develop.rs#L7283), [`ui/dr-ui/src/develop.rs:763`](../ui/dr-ui/src/develop.rs#L763), [`ui/dr-ui/src/develop.rs:783`](../ui/dr-ui/src/develop.rs#L783), [`ui/dr-ui/src/develop.rs:789`](../ui/dr-ui/src/develop.rs#L789), [`ui/dr-ui/src/histogram.rs:1`](../ui/dr-ui/src/histogram.rs#L1), [`ui/dr-ui/src/histogram.rs:208`](../ui/dr-ui/src/histogram.rs#L208), [`ui/dr-ui/src/histogram.rs:228`](../ui/dr-ui/src/histogram.rs#L228), [`ui/dr-ui/src/histogram.rs:272`](../ui/dr-ui/src/histogram.rs#L272), [`ui/dr-ui/src/histogram.rs:544`](../ui/dr-ui/src/histogram.rs#L544), [`ui/dr-ui/src/histogram.rs:565`](../ui/dr-ui/src/histogram.rs#L565), [`ui/dr-ui/src/histogram.rs:593`](../ui/dr-ui/src/histogram.rs#L593), [`ui/dr-ui/src/histogram.rs:621`](../ui/dr-ui/src/histogram.rs#L621), [`ui/dr-ui/src/histogram.rs:658`](../ui/dr-ui/src/histogram.rs#L658), [`ui/dr-ui/src/lib.rs:1707`](../ui/dr-ui/src/lib.rs#L1707), [`ui/dr-ui/src/lib.rs:1804`](../ui/dr-ui/src/lib.rs#L1804), [`ui/dr-ui/src/lib.rs:1911`](../ui/dr-ui/src/lib.rs#L1911), [`ui/dr-ui/src/lib.rs:1952`](../ui/dr-ui/src/lib.rs#L1952), [`ui/dr-ui/src/lib.rs:3307`](../ui/dr-ui/src/lib.rs#L3307), [`ui/dr-ui/src/lib.rs:391`](../ui/dr-ui/src/lib.rs#L391), [`ui/dr-ui/src/peaking.rs:1`](../ui/dr-ui/src/peaking.rs#L1), [`ui/dr-ui/ui/app.slint:1915`](../ui/dr-ui/ui/app.slint#L1915), [`ui/dr-ui/ui/app.slint:2621`](../ui/dr-ui/ui/app.slint#L2621), [`ui/dr-ui/ui/app.slint:95`](../ui/dr-ui/ui/app.slint#L95), [`ui/dr-ui/ui/peaking.slint:1`](../ui/dr-ui/ui/peaking.slint#L1), [`ui/dr-ui/ui/peaking.slint:25`](../ui/dr-ui/ui/peaking.slint#L25), [`ui/dr-ui/ui/peaking.slint:56`](../ui/dr-ui/ui/peaking.slint#L56) | +| FR-CULL-3 | [`core/dr-gpu/src/focus.rs:154`](../core/dr-gpu/src/focus.rs#L154), [`core/dr-gpu/src/focus.rs:186`](../core/dr-gpu/src/focus.rs#L186), [`core/dr-gpu/src/focus.rs:1`](../core/dr-gpu/src/focus.rs#L1), [`core/dr-gpu/src/focus.rs:317`](../core/dr-gpu/src/focus.rs#L317), [`core/dr-gpu/src/raw_histogram.rs:129`](../core/dr-gpu/src/raw_histogram.rs#L129), [`core/dr-gpu/src/raw_histogram.rs:1`](../core/dr-gpu/src/raw_histogram.rs#L1), [`core/dr-gpu/src/raw_histogram.rs:272`](../core/dr-gpu/src/raw_histogram.rs#L272), [`core/dr-gpu/src/raw_histogram.rs:407`](../core/dr-gpu/src/raw_histogram.rs#L407), [`core/dr-gpu/src/shaders/focus_peak.wgsl:1`](../core/dr-gpu/src/shaders/focus_peak.wgsl#L1), [`core/dr-gpu/src/shaders/raw_histogram.wgsl:1`](../core/dr-gpu/src/shaders/raw_histogram.wgsl#L1), [`ui/dr-ui/src/develop.rs:3313`](../ui/dr-ui/src/develop.rs#L3313), [`ui/dr-ui/src/develop.rs:3326`](../ui/dr-ui/src/develop.rs#L3326), [`ui/dr-ui/src/develop.rs:3371`](../ui/dr-ui/src/develop.rs#L3371), [`ui/dr-ui/src/develop.rs:3382`](../ui/dr-ui/src/develop.rs#L3382), [`ui/dr-ui/src/develop.rs:3388`](../ui/dr-ui/src/develop.rs#L3388), [`ui/dr-ui/src/develop.rs:3405`](../ui/dr-ui/src/develop.rs#L3405), [`ui/dr-ui/src/develop.rs:7435`](../ui/dr-ui/src/develop.rs#L7435), [`ui/dr-ui/src/develop.rs:7499`](../ui/dr-ui/src/develop.rs#L7499), [`ui/dr-ui/src/develop.rs:7522`](../ui/dr-ui/src/develop.rs#L7522), [`ui/dr-ui/src/develop.rs:763`](../ui/dr-ui/src/develop.rs#L763), [`ui/dr-ui/src/develop.rs:783`](../ui/dr-ui/src/develop.rs#L783), [`ui/dr-ui/src/develop.rs:789`](../ui/dr-ui/src/develop.rs#L789), [`ui/dr-ui/src/histogram.rs:1`](../ui/dr-ui/src/histogram.rs#L1), [`ui/dr-ui/src/histogram.rs:208`](../ui/dr-ui/src/histogram.rs#L208), [`ui/dr-ui/src/histogram.rs:228`](../ui/dr-ui/src/histogram.rs#L228), [`ui/dr-ui/src/histogram.rs:272`](../ui/dr-ui/src/histogram.rs#L272), [`ui/dr-ui/src/histogram.rs:544`](../ui/dr-ui/src/histogram.rs#L544), [`ui/dr-ui/src/histogram.rs:565`](../ui/dr-ui/src/histogram.rs#L565), [`ui/dr-ui/src/histogram.rs:593`](../ui/dr-ui/src/histogram.rs#L593), [`ui/dr-ui/src/histogram.rs:621`](../ui/dr-ui/src/histogram.rs#L621), [`ui/dr-ui/src/histogram.rs:658`](../ui/dr-ui/src/histogram.rs#L658), [`ui/dr-ui/src/lib.rs:1712`](../ui/dr-ui/src/lib.rs#L1712), [`ui/dr-ui/src/lib.rs:1809`](../ui/dr-ui/src/lib.rs#L1809), [`ui/dr-ui/src/lib.rs:1916`](../ui/dr-ui/src/lib.rs#L1916), [`ui/dr-ui/src/lib.rs:1957`](../ui/dr-ui/src/lib.rs#L1957), [`ui/dr-ui/src/lib.rs:3345`](../ui/dr-ui/src/lib.rs#L3345), [`ui/dr-ui/src/lib.rs:396`](../ui/dr-ui/src/lib.rs#L396), [`ui/dr-ui/src/peaking.rs:1`](../ui/dr-ui/src/peaking.rs#L1), [`ui/dr-ui/ui/app.slint:1939`](../ui/dr-ui/ui/app.slint#L1939), [`ui/dr-ui/ui/app.slint:2682`](../ui/dr-ui/ui/app.slint#L2682), [`ui/dr-ui/ui/app.slint:95`](../ui/dr-ui/ui/app.slint#L95), [`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:137`](../core/dr-pipeline/src/sidecar.rs#L137), [`ui/dr-ui/src/library.rs:254`](../ui/dr-ui/src/library.rs#L254), [`ui/dr-ui/src/library.rs:500`](../ui/dr-ui/src/library.rs#L500) | | FR-CULL-5 | [`core/dr-catalog/src/bursts.rs:1`](../core/dr-catalog/src/bursts.rs#L1), [`core/dr-catalog/src/schema.rs:438`](../core/dr-catalog/src/schema.rs#L438), [`ui/dr-ui/src/bursts.rs:1`](../ui/dr-ui/src/bursts.rs#L1), [`ui/dr-ui/src/library.rs:210`](../ui/dr-ui/src/library.rs#L210), [`ui/dr-ui/src/library.rs:5853`](../ui/dr-ui/src/library.rs#L5853) | -| 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:506`](../core/dr-catalog/src/schema.rs#L506), [`core/dr-catalog/src/schema.rs:573`](../core/dr-catalog/src/schema.rs#L573), [`core/dr-catalog/src/schema.rs:614`](../core/dr-catalog/src/schema.rs#L614), [`core/dr-face/src/align.rs:291`](../core/dr-face/src/align.rs#L291), [`ui/dr-ui/examples/face_native.rs:1`](../ui/dr-ui/examples/face_native.rs#L1), [`ui/dr-ui/src/faces.rs:1`](../ui/dr-ui/src/faces.rs#L1), [`ui/dr-ui/src/faces.rs:330`](../ui/dr-ui/src/faces.rs#L330), [`ui/dr-ui/src/faces.rs:346`](../ui/dr-ui/src/faces.rs#L346), [`ui/dr-ui/src/identity_ui.rs:540`](../ui/dr-ui/src/identity_ui.rs#L540), [`ui/dr-ui/src/lib.rs:1326`](../ui/dr-ui/src/lib.rs#L1326), [`ui/dr-ui/src/library.rs:3293`](../ui/dr-ui/src/library.rs#L3293), [`ui/dr-ui/src/library.rs:3385`](../ui/dr-ui/src/library.rs#L3385), [`ui/dr-ui/src/library.rs:3606`](../ui/dr-ui/src/library.rs#L3606), [`ui/dr-ui/src/library.rs:3742`](../ui/dr-ui/src/library.rs#L3742), [`ui/dr-ui/src/library.rs:3778`](../ui/dr-ui/src/library.rs#L3778), [`ui/dr-ui/ui/settings.slint:427`](../ui/dr-ui/ui/settings.slint#L427), [`ui/dr-ui/ui/settings.slint:82`](../ui/dr-ui/ui/settings.slint#L82) | +| 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:506`](../core/dr-catalog/src/schema.rs#L506), [`core/dr-catalog/src/schema.rs:573`](../core/dr-catalog/src/schema.rs#L573), [`core/dr-catalog/src/schema.rs:614`](../core/dr-catalog/src/schema.rs#L614), [`core/dr-face/src/align.rs:291`](../core/dr-face/src/align.rs#L291), [`ui/dr-ui/examples/face_native.rs:1`](../ui/dr-ui/examples/face_native.rs#L1), [`ui/dr-ui/src/faces.rs:1`](../ui/dr-ui/src/faces.rs#L1), [`ui/dr-ui/src/faces.rs:330`](../ui/dr-ui/src/faces.rs#L330), [`ui/dr-ui/src/faces.rs:346`](../ui/dr-ui/src/faces.rs#L346), [`ui/dr-ui/src/identity_ui.rs:540`](../ui/dr-ui/src/identity_ui.rs#L540), [`ui/dr-ui/src/lib.rs:1331`](../ui/dr-ui/src/lib.rs#L1331), [`ui/dr-ui/src/library.rs:3293`](../ui/dr-ui/src/library.rs#L3293), [`ui/dr-ui/src/library.rs:3385`](../ui/dr-ui/src/library.rs#L3385), [`ui/dr-ui/src/library.rs:3606`](../ui/dr-ui/src/library.rs#L3606), [`ui/dr-ui/src/library.rs:3742`](../ui/dr-ui/src/library.rs#L3742), [`ui/dr-ui/src/library.rs:3778`](../ui/dr-ui/src/library.rs#L3778), [`ui/dr-ui/ui/settings.slint:427`](../ui/dr-ui/ui/settings.slint#L427), [`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:614`](../core/dr-catalog/src/schema.rs#L614), [`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:283`](../ui/dr-ui/ui/identity.slint#L283) | | 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-12 | [`core/dr-pipeline/ops/colour_grading.yaml:1`](../core/dr-pipeline/ops/colour_grading.yaml#L1) | | FR-DEV-18 | [`core/dr-pipeline/src/ops/dehaze.rs:1`](../core/dr-pipeline/src/ops/dehaze.rs#L1), [`core/dr-pipeline/src/ops/dehaze.rs:221`](../core/dr-pipeline/src/ops/dehaze.rs#L221) | | FR-DEV-10 | [`core/dr-gpu/src/mask.rs:1062`](../core/dr-gpu/src/mask.rs#L1062), [`core/dr-gpu/src/mask.rs:1150`](../core/dr-gpu/src/mask.rs#L1150), [`core/dr-gpu/src/mask.rs:402`](../core/dr-gpu/src/mask.rs#L402), [`core/dr-gpu/src/mask.rs:444`](../core/dr-gpu/src/mask.rs#L444), [`core/dr-gpu/src/mask.rs:58`](../core/dr-gpu/src/mask.rs#L58), [`core/dr-gpu/src/mask.rs:60`](../core/dr-gpu/src/mask.rs#L60), [`core/dr-gpu/src/mask.rs:658`](../core/dr-gpu/src/mask.rs#L658), [`core/dr-gpu/src/mask.rs:717`](../core/dr-gpu/src/mask.rs#L717), [`core/dr-gpu/src/mask.rs:829`](../core/dr-gpu/src/mask.rs#L829), [`core/dr-gpu/src/mask.rs:85`](../core/dr-gpu/src/mask.rs#L85), [`core/dr-gpu/src/shaders/mask.wgsl:101`](../core/dr-gpu/src/shaders/mask.wgsl#L101), [`core/dr-gpu/src/shaders/mask.wgsl:59`](../core/dr-gpu/src/shaders/mask.wgsl#L59), [`core/dr-gpu/tests/range_masks.rs:119`](../core/dr-gpu/tests/range_masks.rs#L119), [`core/dr-gpu/tests/range_masks.rs:147`](../core/dr-gpu/tests/range_masks.rs#L147), [`core/dr-gpu/tests/range_masks.rs:175`](../core/dr-gpu/tests/range_masks.rs#L175), [`core/dr-gpu/tests/range_masks.rs:1`](../core/dr-gpu/tests/range_masks.rs#L1), [`core/dr-gpu/tests/range_masks.rs:94`](../core/dr-gpu/tests/range_masks.rs#L94), [`core/dr-pipeline/src/mask.rs:125`](../core/dr-pipeline/src/mask.rs#L125), [`core/dr-pipeline/src/mask.rs:2162`](../core/dr-pipeline/src/mask.rs#L2162), [`core/dr-pipeline/src/mask.rs:2175`](../core/dr-pipeline/src/mask.rs#L2175), [`core/dr-pipeline/src/mask.rs:2194`](../core/dr-pipeline/src/mask.rs#L2194), [`core/dr-pipeline/src/mask.rs:2208`](../core/dr-pipeline/src/mask.rs#L2208), [`core/dr-pipeline/src/mask.rs:2218`](../core/dr-pipeline/src/mask.rs#L2218), [`core/dr-pipeline/src/mask.rs:709`](../core/dr-pipeline/src/mask.rs#L709), [`core/dr-pipeline/src/mask.rs:748`](../core/dr-pipeline/src/mask.rs#L748), [`core/dr-pipeline/src/mask.rs:808`](../core/dr-pipeline/src/mask.rs#L808), [`core/dr-pipeline/src/mask.rs:827`](../core/dr-pipeline/src/mask.rs#L827), [`core/dr-pipeline/src/mask.rs:851`](../core/dr-pipeline/src/mask.rs#L851), [`core/dr-pipeline/src/mask.rs:863`](../core/dr-pipeline/src/mask.rs#L863), [`core/dr-pipeline/src/mask.rs:875`](../core/dr-pipeline/src/mask.rs#L875), [`core/dr-pipeline/src/sidecar.rs:1132`](../core/dr-pipeline/src/sidecar.rs#L1132), [`core/dr-pipeline/src/sidecar.rs:1320`](../core/dr-pipeline/src/sidecar.rs#L1320), [`core/dr-pipeline/src/sidecar.rs:1414`](../core/dr-pipeline/src/sidecar.rs#L1414), [`core/dr-pipeline/src/sidecar.rs:1518`](../core/dr-pipeline/src/sidecar.rs#L1518), [`core/dr-pipeline/src/sidecar.rs:1602`](../core/dr-pipeline/src/sidecar.rs#L1602), [`core/dr-pipeline/tests/mask_sidecar.rs:1132`](../core/dr-pipeline/tests/mask_sidecar.rs#L1132), [`core/dr-pipeline/tests/mask_sidecar.rs:1161`](../core/dr-pipeline/tests/mask_sidecar.rs#L1161), [`core/dr-pipeline/tests/mask_sidecar.rs:1179`](../core/dr-pipeline/tests/mask_sidecar.rs#L1179), [`core/dr-pipeline/tests/mask_sidecar.rs:1209`](../core/dr-pipeline/tests/mask_sidecar.rs#L1209), [`ui/dr-ui/src/develop.rs:2081`](../ui/dr-ui/src/develop.rs#L2081), [`ui/dr-ui/src/develop.rs:2936`](../ui/dr-ui/src/develop.rs#L2936), [`ui/dr-ui/src/develop.rs:2962`](../ui/dr-ui/src/develop.rs#L2962), [`ui/dr-ui/src/develop.rs:2994`](../ui/dr-ui/src/develop.rs#L2994), [`ui/dr-ui/src/develop.rs:3018`](../ui/dr-ui/src/develop.rs#L3018), [`ui/dr-ui/src/develop.rs:3027`](../ui/dr-ui/src/develop.rs#L3027), [`ui/dr-ui/src/develop.rs:3036`](../ui/dr-ui/src/develop.rs#L3036), [`ui/dr-ui/src/develop.rs:3056`](../ui/dr-ui/src/develop.rs#L3056), [`ui/dr-ui/src/labels.rs:52`](../ui/dr-ui/src/labels.rs#L52), [`ui/dr-ui/src/masks_ui.rs:628`](../ui/dr-ui/src/masks_ui.rs#L628), [`ui/dr-ui/src/masks_ui.rs:741`](../ui/dr-ui/src/masks_ui.rs#L741) | | FR-DEV-2 | [`core/dr-pipeline/src/operation.rs:403`](../core/dr-pipeline/src/operation.rs#L403) | -| FR-DEV-3 | [`core/dr-gpu/src/adjust.rs:2217`](../core/dr-gpu/src/adjust.rs#L2217), [`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/coverage.rs:122`](../core/dr-pipeline/src/coverage.rs#L122), [`core/dr-pipeline/src/coverage.rs:1`](../core/dr-pipeline/src/coverage.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:498`](../core/dr-pipeline/src/framing.rs#L498), [`core/dr-pipeline/src/framing.rs:753`](../core/dr-pipeline/src/framing.rs#L753), [`core/dr-pipeline/src/graph.rs:209`](../core/dr-pipeline/src/graph.rs#L209), [`core/dr-pipeline/src/graph.rs:290`](../core/dr-pipeline/src/graph.rs#L290), [`core/dr-pipeline/src/graph.rs:735`](../core/dr-pipeline/src/graph.rs#L735), [`core/dr-pipeline/src/mask.rs:151`](../core/dr-pipeline/src/mask.rs#L151), [`core/dr-pipeline/src/operation.rs:330`](../core/dr-pipeline/src/operation.rs#L330), [`core/dr-pipeline/src/operation.rs:535`](../core/dr-pipeline/src/operation.rs#L535), [`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:1165`](../core/dr-pipeline/src/sidecar.rs#L1165), [`core/dr-pipeline/src/sidecar.rs:158`](../core/dr-pipeline/src/sidecar.rs#L158), [`core/dr-pipeline/src/sidecar.rs:1831`](../core/dr-pipeline/src/sidecar.rs#L1831), [`core/dr-pipeline/src/sidecar.rs:1891`](../core/dr-pipeline/src/sidecar.rs#L1891), [`core/dr-pipeline/tests/tone_curve.rs:1`](../core/dr-pipeline/tests/tone_curve.rs#L1), [`core/dr-segment/src/refine.rs:850`](../core/dr-segment/src/refine.rs#L850), [`ui/dr-ui/src/develop.rs:103`](../ui/dr-ui/src/develop.rs#L103), [`ui/dr-ui/src/develop.rs:1517`](../ui/dr-ui/src/develop.rs#L1517), [`ui/dr-ui/src/develop.rs:165`](../ui/dr-ui/src/develop.rs#L165), [`ui/dr-ui/src/develop.rs:1933`](../ui/dr-ui/src/develop.rs#L1933), [`ui/dr-ui/src/develop.rs:2147`](../ui/dr-ui/src/develop.rs#L2147), [`ui/dr-ui/src/develop.rs:2165`](../ui/dr-ui/src/develop.rs#L2165), [`ui/dr-ui/src/develop.rs:2179`](../ui/dr-ui/src/develop.rs#L2179), [`ui/dr-ui/src/develop.rs:2201`](../ui/dr-ui/src/develop.rs#L2201), [`ui/dr-ui/src/develop.rs:2347`](../ui/dr-ui/src/develop.rs#L2347), [`ui/dr-ui/src/develop.rs:2445`](../ui/dr-ui/src/develop.rs#L2445), [`ui/dr-ui/src/develop.rs:328`](../ui/dr-ui/src/develop.rs#L328), [`ui/dr-ui/src/develop.rs:3568`](../ui/dr-ui/src/develop.rs#L3568), [`ui/dr-ui/src/develop.rs:3628`](../ui/dr-ui/src/develop.rs#L3628), [`ui/dr-ui/src/develop.rs:365`](../ui/dr-ui/src/develop.rs#L365), [`ui/dr-ui/src/develop.rs:4029`](../ui/dr-ui/src/develop.rs#L4029), [`ui/dr-ui/src/develop.rs:4059`](../ui/dr-ui/src/develop.rs#L4059), [`ui/dr-ui/src/develop.rs:4125`](../ui/dr-ui/src/develop.rs#L4125), [`ui/dr-ui/src/develop.rs:4139`](../ui/dr-ui/src/develop.rs#L4139), [`ui/dr-ui/src/develop.rs:4341`](../ui/dr-ui/src/develop.rs#L4341), [`ui/dr-ui/src/develop.rs:4429`](../ui/dr-ui/src/develop.rs#L4429), [`ui/dr-ui/src/develop.rs:5257`](../ui/dr-ui/src/develop.rs#L5257), [`ui/dr-ui/src/develop.rs:5491`](../ui/dr-ui/src/develop.rs#L5491), [`ui/dr-ui/src/develop.rs:5647`](../ui/dr-ui/src/develop.rs#L5647), [`ui/dr-ui/src/develop.rs:5783`](../ui/dr-ui/src/develop.rs#L5783), [`ui/dr-ui/src/develop.rs:5827`](../ui/dr-ui/src/develop.rs#L5827), [`ui/dr-ui/src/develop.rs:5877`](../ui/dr-ui/src/develop.rs#L5877), [`ui/dr-ui/src/develop.rs:588`](../ui/dr-ui/src/develop.rs#L588), [`ui/dr-ui/src/develop.rs:649`](../ui/dr-ui/src/develop.rs#L649), [`ui/dr-ui/src/develop.rs:803`](../ui/dr-ui/src/develop.rs#L803), [`ui/dr-ui/src/develop.rs:850`](../ui/dr-ui/src/develop.rs#L850), [`ui/dr-ui/src/develop.rs:879`](../ui/dr-ui/src/develop.rs#L879), [`ui/dr-ui/src/lib.rs:1785`](../ui/dr-ui/src/lib.rs#L1785), [`ui/dr-ui/src/lib.rs:2639`](../ui/dr-ui/src/lib.rs#L2639), [`ui/dr-ui/src/lib.rs:2863`](../ui/dr-ui/src/lib.rs#L2863), [`ui/dr-ui/src/lib.rs:3068`](../ui/dr-ui/src/lib.rs#L3068), [`ui/dr-ui/src/lib.rs:3132`](../ui/dr-ui/src/lib.rs#L3132), [`ui/dr-ui/src/lib.rs:3186`](../ui/dr-ui/src/lib.rs#L3186), [`ui/dr-ui/src/lib.rs:397`](../ui/dr-ui/src/lib.rs#L397), [`ui/dr-ui/src/lib.rs:502`](../ui/dr-ui/src/lib.rs#L502), [`ui/dr-ui/src/lib.rs:525`](../ui/dr-ui/src/lib.rs#L525), [`ui/dr-ui/src/library.rs:547`](../ui/dr-ui/src/library.rs#L547), [`ui/dr-ui/src/masks_ui.rs:249`](../ui/dr-ui/src/masks_ui.rs#L249), [`ui/dr-ui/src/masks_ui.rs:41`](../ui/dr-ui/src/masks_ui.rs#L41), [`ui/dr-ui/src/masks_ui.rs:884`](../ui/dr-ui/src/masks_ui.rs#L884), [`ui/dr-ui/src/masks_ui.rs:998`](../ui/dr-ui/src/masks_ui.rs#L998), [`ui/dr-ui/src/presets.rs:409`](../ui/dr-ui/src/presets.rs#L409), [`ui/dr-ui/src/segmentation.rs:116`](../ui/dr-ui/src/segmentation.rs#L116), [`ui/dr-ui/src/segmentation.rs:330`](../ui/dr-ui/src/segmentation.rs#L330), [`ui/dr-ui/src/segmentation.rs:346`](../ui/dr-ui/src/segmentation.rs#L346), [`ui/dr-ui/src/segmentation.rs:476`](../ui/dr-ui/src/segmentation.rs#L476), [`ui/dr-ui/src/segmentation.rs:504`](../ui/dr-ui/src/segmentation.rs#L504), [`ui/dr-ui/ui/adjust.slint:547`](../ui/dr-ui/ui/adjust.slint#L547), [`ui/dr-ui/ui/adjust.slint:666`](../ui/dr-ui/ui/adjust.slint#L666), [`ui/dr-ui/ui/app.slint:1040`](../ui/dr-ui/ui/app.slint#L1040), [`ui/dr-ui/ui/app.slint:156`](../ui/dr-ui/ui/app.slint#L156), [`ui/dr-ui/ui/app.slint:202`](../ui/dr-ui/ui/app.slint#L202), [`ui/dr-ui/ui/app.slint:2134`](../ui/dr-ui/ui/app.slint#L2134), [`ui/dr-ui/ui/app.slint:68`](../ui/dr-ui/ui/app.slint#L68), [`ui/dr-ui/ui/develop.slint:220`](../ui/dr-ui/ui/develop.slint#L220), [`ui/dr-ui/ui/masks.slint:612`](../ui/dr-ui/ui/masks.slint#L612) | -| FR-DEV-3a | [`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:395`](../core/dr-pipeline/src/framing.rs#L395), [`core/dr-pipeline/src/graph.rs:25`](../core/dr-pipeline/src/graph.rs#L25), [`core/dr-pipeline/src/graph.rs:337`](../core/dr-pipeline/src/graph.rs#L337), [`core/dr-pipeline/src/graph.rs:47`](../core/dr-pipeline/src/graph.rs#L47), [`core/dr-pipeline/src/graph.rs:60`](../core/dr-pipeline/src/graph.rs#L60), [`core/dr-pipeline/src/mask.rs:1108`](../core/dr-pipeline/src/mask.rs#L1108), [`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:1414`](../ui/dr-ui/src/develop.rs#L1414), [`ui/dr-ui/src/lib.rs:819`](../ui/dr-ui/src/lib.rs#L819), [`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:395`](../core/dr-pipeline/src/framing.rs#L395), [`core/dr-pipeline/src/graph.rs:60`](../core/dr-pipeline/src/graph.rs#L60), [`core/dr-pipeline/src/operation.rs:365`](../core/dr-pipeline/src/operation.rs#L365), [`ui/dr-ui/ui/app.slint:2367`](../ui/dr-ui/ui/app.slint#L2367) | -| FR-DEV-3c | [`core/dr-pipeline/ops/exposure.yaml:1`](../core/dr-pipeline/ops/exposure.yaml#L1), [`core/dr-pipeline/src/graph.rs:337`](../core/dr-pipeline/src/graph.rs#L337), [`core/dr-pipeline/src/graph.rs:47`](../core/dr-pipeline/src/graph.rs#L47), [`core/dr-pipeline/src/mask.rs:1108`](../core/dr-pipeline/src/mask.rs#L1108), [`ui/dr-ui/src/develop.rs:6456`](../ui/dr-ui/src/develop.rs#L6456) | -| 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:774`](../core/dr-pipeline/src/graph.rs#L774), [`core/dr-pipeline/src/operation.rs:32`](../core/dr-pipeline/src/operation.rs#L32), [`core/dr-pipeline/src/operation.rs:403`](../core/dr-pipeline/src/operation.rs#L403), [`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-3 | [`core/dr-gpu/src/adjust.rs:2217`](../core/dr-gpu/src/adjust.rs#L2217), [`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/coverage.rs:122`](../core/dr-pipeline/src/coverage.rs#L122), [`core/dr-pipeline/src/coverage.rs:1`](../core/dr-pipeline/src/coverage.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:498`](../core/dr-pipeline/src/framing.rs#L498), [`core/dr-pipeline/src/framing.rs:753`](../core/dr-pipeline/src/framing.rs#L753), [`core/dr-pipeline/src/graph.rs:209`](../core/dr-pipeline/src/graph.rs#L209), [`core/dr-pipeline/src/graph.rs:290`](../core/dr-pipeline/src/graph.rs#L290), [`core/dr-pipeline/src/graph.rs:762`](../core/dr-pipeline/src/graph.rs#L762), [`core/dr-pipeline/src/mask.rs:151`](../core/dr-pipeline/src/mask.rs#L151), [`core/dr-pipeline/src/neutral.rs:1`](../core/dr-pipeline/src/neutral.rs#L1), [`core/dr-pipeline/src/neutral.rs:300`](../core/dr-pipeline/src/neutral.rs#L300), [`core/dr-pipeline/src/neutral.rs:316`](../core/dr-pipeline/src/neutral.rs#L316), [`core/dr-pipeline/src/neutral.rs:332`](../core/dr-pipeline/src/neutral.rs#L332), [`core/dr-pipeline/src/neutral.rs:354`](../core/dr-pipeline/src/neutral.rs#L354), [`core/dr-pipeline/src/neutral.rs:79`](../core/dr-pipeline/src/neutral.rs#L79), [`core/dr-pipeline/src/operation.rs:330`](../core/dr-pipeline/src/operation.rs#L330), [`core/dr-pipeline/src/operation.rs:535`](../core/dr-pipeline/src/operation.rs#L535), [`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:1165`](../core/dr-pipeline/src/sidecar.rs#L1165), [`core/dr-pipeline/src/sidecar.rs:158`](../core/dr-pipeline/src/sidecar.rs#L158), [`core/dr-pipeline/src/sidecar.rs:1831`](../core/dr-pipeline/src/sidecar.rs#L1831), [`core/dr-pipeline/src/sidecar.rs:1891`](../core/dr-pipeline/src/sidecar.rs#L1891), [`core/dr-pipeline/tests/tone_curve.rs:1`](../core/dr-pipeline/tests/tone_curve.rs#L1), [`core/dr-segment/src/refine.rs:850`](../core/dr-segment/src/refine.rs#L850), [`ui/dr-ui/src/develop.rs:103`](../ui/dr-ui/src/develop.rs#L103), [`ui/dr-ui/src/develop.rs:1188`](../ui/dr-ui/src/develop.rs#L1188), [`ui/dr-ui/src/develop.rs:1277`](../ui/dr-ui/src/develop.rs#L1277), [`ui/dr-ui/src/develop.rs:1313`](../ui/dr-ui/src/develop.rs#L1313), [`ui/dr-ui/src/develop.rs:1569`](../ui/dr-ui/src/develop.rs#L1569), [`ui/dr-ui/src/develop.rs:165`](../ui/dr-ui/src/develop.rs#L165), [`ui/dr-ui/src/develop.rs:1985`](../ui/dr-ui/src/develop.rs#L1985), [`ui/dr-ui/src/develop.rs:2199`](../ui/dr-ui/src/develop.rs#L2199), [`ui/dr-ui/src/develop.rs:2217`](../ui/dr-ui/src/develop.rs#L2217), [`ui/dr-ui/src/develop.rs:2231`](../ui/dr-ui/src/develop.rs#L2231), [`ui/dr-ui/src/develop.rs:2253`](../ui/dr-ui/src/develop.rs#L2253), [`ui/dr-ui/src/develop.rs:2399`](../ui/dr-ui/src/develop.rs#L2399), [`ui/dr-ui/src/develop.rs:2497`](../ui/dr-ui/src/develop.rs#L2497), [`ui/dr-ui/src/develop.rs:328`](../ui/dr-ui/src/develop.rs#L328), [`ui/dr-ui/src/develop.rs:3576`](../ui/dr-ui/src/develop.rs#L3576), [`ui/dr-ui/src/develop.rs:365`](../ui/dr-ui/src/develop.rs#L365), [`ui/dr-ui/src/develop.rs:3732`](../ui/dr-ui/src/develop.rs#L3732), [`ui/dr-ui/src/develop.rs:3792`](../ui/dr-ui/src/develop.rs#L3792), [`ui/dr-ui/src/develop.rs:4193`](../ui/dr-ui/src/develop.rs#L4193), [`ui/dr-ui/src/develop.rs:4223`](../ui/dr-ui/src/develop.rs#L4223), [`ui/dr-ui/src/develop.rs:4289`](../ui/dr-ui/src/develop.rs#L4289), [`ui/dr-ui/src/develop.rs:4303`](../ui/dr-ui/src/develop.rs#L4303), [`ui/dr-ui/src/develop.rs:4505`](../ui/dr-ui/src/develop.rs#L4505), [`ui/dr-ui/src/develop.rs:4593`](../ui/dr-ui/src/develop.rs#L4593), [`ui/dr-ui/src/develop.rs:5421`](../ui/dr-ui/src/develop.rs#L5421), [`ui/dr-ui/src/develop.rs:5614`](../ui/dr-ui/src/develop.rs#L5614), [`ui/dr-ui/src/develop.rs:5686`](../ui/dr-ui/src/develop.rs#L5686), [`ui/dr-ui/src/develop.rs:5842`](../ui/dr-ui/src/develop.rs#L5842), [`ui/dr-ui/src/develop.rs:588`](../ui/dr-ui/src/develop.rs#L588), [`ui/dr-ui/src/develop.rs:5978`](../ui/dr-ui/src/develop.rs#L5978), [`ui/dr-ui/src/develop.rs:6022`](../ui/dr-ui/src/develop.rs#L6022), [`ui/dr-ui/src/develop.rs:6072`](../ui/dr-ui/src/develop.rs#L6072), [`ui/dr-ui/src/develop.rs:6497`](../ui/dr-ui/src/develop.rs#L6497), [`ui/dr-ui/src/develop.rs:649`](../ui/dr-ui/src/develop.rs#L649), [`ui/dr-ui/src/develop.rs:803`](../ui/dr-ui/src/develop.rs#L803), [`ui/dr-ui/src/develop.rs:850`](../ui/dr-ui/src/develop.rs#L850), [`ui/dr-ui/src/develop.rs:879`](../ui/dr-ui/src/develop.rs#L879), [`ui/dr-ui/src/labels.rs:32`](../ui/dr-ui/src/labels.rs#L32), [`ui/dr-ui/src/lib.rs:1790`](../ui/dr-ui/src/lib.rs#L1790), [`ui/dr-ui/src/lib.rs:2644`](../ui/dr-ui/src/lib.rs#L2644), [`ui/dr-ui/src/lib.rs:2842`](../ui/dr-ui/src/lib.rs#L2842), [`ui/dr-ui/src/lib.rs:2901`](../ui/dr-ui/src/lib.rs#L2901), [`ui/dr-ui/src/lib.rs:3106`](../ui/dr-ui/src/lib.rs#L3106), [`ui/dr-ui/src/lib.rs:3170`](../ui/dr-ui/src/lib.rs#L3170), [`ui/dr-ui/src/lib.rs:3224`](../ui/dr-ui/src/lib.rs#L3224), [`ui/dr-ui/src/lib.rs:381`](../ui/dr-ui/src/lib.rs#L381), [`ui/dr-ui/src/lib.rs:402`](../ui/dr-ui/src/lib.rs#L402), [`ui/dr-ui/src/lib.rs:507`](../ui/dr-ui/src/lib.rs#L507), [`ui/dr-ui/src/lib.rs:530`](../ui/dr-ui/src/lib.rs#L530), [`ui/dr-ui/src/library.rs:547`](../ui/dr-ui/src/library.rs#L547), [`ui/dr-ui/src/masks_ui.rs:249`](../ui/dr-ui/src/masks_ui.rs#L249), [`ui/dr-ui/src/masks_ui.rs:41`](../ui/dr-ui/src/masks_ui.rs#L41), [`ui/dr-ui/src/masks_ui.rs:884`](../ui/dr-ui/src/masks_ui.rs#L884), [`ui/dr-ui/src/masks_ui.rs:998`](../ui/dr-ui/src/masks_ui.rs#L998), [`ui/dr-ui/src/presets.rs:409`](../ui/dr-ui/src/presets.rs#L409), [`ui/dr-ui/src/segmentation.rs:116`](../ui/dr-ui/src/segmentation.rs#L116), [`ui/dr-ui/src/segmentation.rs:330`](../ui/dr-ui/src/segmentation.rs#L330), [`ui/dr-ui/src/segmentation.rs:346`](../ui/dr-ui/src/segmentation.rs#L346), [`ui/dr-ui/src/segmentation.rs:476`](../ui/dr-ui/src/segmentation.rs#L476), [`ui/dr-ui/src/segmentation.rs:504`](../ui/dr-ui/src/segmentation.rs#L504), [`ui/dr-ui/ui/adjust.slint:1060`](../ui/dr-ui/ui/adjust.slint#L1060), [`ui/dr-ui/ui/adjust.slint:125`](../ui/dr-ui/ui/adjust.slint#L125), [`ui/dr-ui/ui/adjust.slint:1356`](../ui/dr-ui/ui/adjust.slint#L1356), [`ui/dr-ui/ui/adjust.slint:157`](../ui/dr-ui/ui/adjust.slint#L157), [`ui/dr-ui/ui/adjust.slint:45`](../ui/dr-ui/ui/adjust.slint#L45), [`ui/dr-ui/ui/adjust.slint:611`](../ui/dr-ui/ui/adjust.slint#L611), [`ui/dr-ui/ui/adjust.slint:730`](../ui/dr-ui/ui/adjust.slint#L730), [`ui/dr-ui/ui/app.slint:1064`](../ui/dr-ui/ui/app.slint#L1064), [`ui/dr-ui/ui/app.slint:156`](../ui/dr-ui/ui/app.slint#L156), [`ui/dr-ui/ui/app.slint:202`](../ui/dr-ui/ui/app.slint#L202), [`ui/dr-ui/ui/app.slint:2068`](../ui/dr-ui/ui/app.slint#L2068), [`ui/dr-ui/ui/app.slint:2195`](../ui/dr-ui/ui/app.slint#L2195), [`ui/dr-ui/ui/app.slint:242`](../ui/dr-ui/ui/app.slint#L242), [`ui/dr-ui/ui/app.slint:2879`](../ui/dr-ui/ui/app.slint#L2879), [`ui/dr-ui/ui/app.slint:68`](../ui/dr-ui/ui/app.slint#L68), [`ui/dr-ui/ui/develop.slint:220`](../ui/dr-ui/ui/develop.slint#L220), [`ui/dr-ui/ui/masks.slint:612`](../ui/dr-ui/ui/masks.slint#L612) | +| FR-DEV-3a | [`core/dr-pipeline/ops/exposure.yaml:1`](../core/dr-pipeline/ops/exposure.yaml#L1), [`core/dr-pipeline/src/descriptor.rs:212`](../core/dr-pipeline/src/descriptor.rs#L212), [`core/dr-pipeline/src/descriptor.rs:252`](../core/dr-pipeline/src/descriptor.rs#L252), [`core/dr-pipeline/src/descriptor.rs:276`](../core/dr-pipeline/src/descriptor.rs#L276), [`core/dr-pipeline/src/descriptor.rs:331`](../core/dr-pipeline/src/descriptor.rs#L331), [`core/dr-pipeline/src/framing.rs:395`](../core/dr-pipeline/src/framing.rs#L395), [`core/dr-pipeline/src/graph.rs:25`](../core/dr-pipeline/src/graph.rs#L25), [`core/dr-pipeline/src/graph.rs:337`](../core/dr-pipeline/src/graph.rs#L337), [`core/dr-pipeline/src/graph.rs:439`](../core/dr-pipeline/src/graph.rs#L439), [`core/dr-pipeline/src/graph.rs:47`](../core/dr-pipeline/src/graph.rs#L47), [`core/dr-pipeline/src/graph.rs:60`](../core/dr-pipeline/src/graph.rs#L60), [`core/dr-pipeline/src/mask.rs:1108`](../core/dr-pipeline/src/mask.rs#L1108), [`core/dr-pipeline/src/neutral.rs:1`](../core/dr-pipeline/src/neutral.rs#L1), [`core/dr-pipeline/src/neutral.rs:372`](../core/dr-pipeline/src/neutral.rs#L372), [`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:1200`](../ui/dr-ui/src/develop.rs#L1200), [`ui/dr-ui/src/develop.rs:1464`](../ui/dr-ui/src/develop.rs#L1464), [`ui/dr-ui/src/develop.rs:6497`](../ui/dr-ui/src/develop.rs#L6497), [`ui/dr-ui/src/lib.rs:824`](../ui/dr-ui/src/lib.rs#L824), [`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:276`](../core/dr-pipeline/src/descriptor.rs#L276), [`core/dr-pipeline/src/framing.rs:395`](../core/dr-pipeline/src/framing.rs#L395), [`core/dr-pipeline/src/graph.rs:60`](../core/dr-pipeline/src/graph.rs#L60), [`core/dr-pipeline/src/operation.rs:365`](../core/dr-pipeline/src/operation.rs#L365), [`ui/dr-ui/ui/app.slint:2428`](../ui/dr-ui/ui/app.slint#L2428) | +| FR-DEV-3c | [`core/dr-pipeline/ops/exposure.yaml:1`](../core/dr-pipeline/ops/exposure.yaml#L1), [`core/dr-pipeline/src/graph.rs:337`](../core/dr-pipeline/src/graph.rs#L337), [`core/dr-pipeline/src/graph.rs:47`](../core/dr-pipeline/src/graph.rs#L47), [`core/dr-pipeline/src/mask.rs:1108`](../core/dr-pipeline/src/mask.rs#L1108), [`ui/dr-ui/src/develop.rs:6695`](../ui/dr-ui/src/develop.rs#L6695) | +| 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:801`](../core/dr-pipeline/src/graph.rs#L801), [`core/dr-pipeline/src/operation.rs:32`](../core/dr-pipeline/src/operation.rs#L32), [`core/dr-pipeline/src/operation.rs:403`](../core/dr-pipeline/src/operation.rs#L403), [`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:1762`](../core/dr-pipeline/src/operation.rs#L1762), [`core/dr-pipeline/src/operation.rs:1843`](../core/dr-pipeline/src/operation.rs#L1843), [`core/dr-pipeline/src/operation.rs:1868`](../core/dr-pipeline/src/operation.rs#L1868), [`core/dr-pipeline/src/operation.rs:1883`](../core/dr-pipeline/src/operation.rs#L1883), [`core/dr-pipeline/src/operation.rs:1907`](../core/dr-pipeline/src/operation.rs#L1907), [`core/dr-pipeline/src/operation.rs:310`](../core/dr-pipeline/src/operation.rs#L310), [`core/dr-pipeline/src/operation.rs:454`](../core/dr-pipeline/src/operation.rs#L454), [`core/dr-pipeline/src/operation.rs:464`](../core/dr-pipeline/src/operation.rs#L464), [`core/dr-pipeline/src/operation.rs:625`](../core/dr-pipeline/src/operation.rs#L625) | -| 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:103`](../core/dr-pipeline/src/graph.rs#L103), [`core/dr-pipeline/src/graph.rs:153`](../core/dr-pipeline/src/graph.rs#L153), [`core/dr-pipeline/src/graph.rs:444`](../core/dr-pipeline/src/graph.rs#L444), [`core/dr-pipeline/src/operation.rs:1137`](../core/dr-pipeline/src/operation.rs#L1137), [`core/dr-pipeline/src/operation.rs:1165`](../core/dr-pipeline/src/operation.rs#L1165), [`core/dr-pipeline/src/operation.rs:1211`](../core/dr-pipeline/src/operation.rs#L1211), [`core/dr-pipeline/src/operation.rs:1762`](../core/dr-pipeline/src/operation.rs#L1762), [`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:102`](../core/dr-pipeline/src/ops/film_sim.rs#L102), [`core/dr-pipeline/src/ops/film_sim.rs:139`](../core/dr-pipeline/src/ops/film_sim.rs#L139), [`core/dr-pipeline/src/ops/film_sim.rs:163`](../core/dr-pipeline/src/ops/film_sim.rs#L163), [`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:341`](../core/dr-pipeline/src/ops/film_sim.rs#L341), [`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:97`](../core/dr-pipeline/src/ops/film_sim.rs#L97), [`core/dr-pipeline/src/sidecar.rs:113`](../core/dr-pipeline/src/sidecar.rs#L113), [`core/dr-pipeline/src/sidecar.rs:169`](../core/dr-pipeline/src/sidecar.rs#L169), [`core/dr-pipeline/src/sidecar.rs:2177`](../core/dr-pipeline/src/sidecar.rs#L2177), [`core/dr-pipeline/src/sidecar.rs:2253`](../core/dr-pipeline/src/sidecar.rs#L2253), [`core/dr-pipeline/src/sidecar.rs:535`](../core/dr-pipeline/src/sidecar.rs#L535), [`core/dr-pipeline/src/sidecar.rs:779`](../core/dr-pipeline/src/sidecar.rs#L779), [`core/dr-pipeline/src/sidecar.rs:911`](../core/dr-pipeline/src/sidecar.rs#L911), [`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:3776`](../ui/dr-ui/src/develop.rs#L3776), [`ui/dr-ui/src/develop.rs:3793`](../ui/dr-ui/src/develop.rs#L3793), [`ui/dr-ui/src/develop.rs:3805`](../ui/dr-ui/src/develop.rs#L3805), [`ui/dr-ui/src/develop.rs:3843`](../ui/dr-ui/src/develop.rs#L3843), [`ui/dr-ui/src/develop.rs:3852`](../ui/dr-ui/src/develop.rs#L3852), [`ui/dr-ui/src/develop.rs:3955`](../ui/dr-ui/src/develop.rs#L3955), [`ui/dr-ui/src/develop.rs:4466`](../ui/dr-ui/src/develop.rs#L4466), [`ui/dr-ui/src/develop.rs:4481`](../ui/dr-ui/src/develop.rs#L4481), [`ui/dr-ui/src/lib.rs:2613`](../ui/dr-ui/src/lib.rs#L2613), [`ui/dr-ui/src/lib.rs:752`](../ui/dr-ui/src/lib.rs#L752), [`ui/dr-ui/src/lib.rs:810`](../ui/dr-ui/src/lib.rs#L810), [`ui/dr-ui/src/library.rs:538`](../ui/dr-ui/src/library.rs#L538), [`ui/dr-ui/src/library.rs:800`](../ui/dr-ui/src/library.rs#L800), [`ui/dr-ui/src/presets.rs:417`](../ui/dr-ui/src/presets.rs#L417), [`ui/dr-ui/ui/adjust.slint:1072`](../ui/dr-ui/ui/adjust.slint#L1072), [`ui/dr-ui/ui/adjust.slint:996`](../ui/dr-ui/ui/adjust.slint#L996), [`ui/dr-ui/ui/app.slint:2818`](../ui/dr-ui/ui/app.slint#L2818), [`ui/dr-ui/ui/app.slint:750`](../ui/dr-ui/ui/app.slint#L750) | -| 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:1067`](../core/dr-pipeline/src/framing.rs#L1067), [`core/dr-pipeline/src/framing.rs:328`](../core/dr-pipeline/src/framing.rs#L328), [`core/dr-pipeline/src/framing.rs:498`](../core/dr-pipeline/src/framing.rs#L498), [`core/dr-types/src/lib.rs:339`](../core/dr-types/src/lib.rs#L339), [`core/dr-types/src/lib.rs:447`](../core/dr-types/src/lib.rs#L447), [`core/dr-types/src/lib.rs:459`](../core/dr-types/src/lib.rs#L459), [`core/dr-types/src/lib.rs:475`](../core/dr-types/src/lib.rs#L475), [`ui/dr-ui/src/develop.rs:140`](../ui/dr-ui/src/develop.rs#L140), [`ui/dr-ui/src/develop.rs:2364`](../ui/dr-ui/src/develop.rs#L2364), [`ui/dr-ui/src/segmentation.rs:476`](../ui/dr-ui/src/segmentation.rs#L476) | +| 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:103`](../core/dr-pipeline/src/graph.rs#L103), [`core/dr-pipeline/src/graph.rs:153`](../core/dr-pipeline/src/graph.rs#L153), [`core/dr-pipeline/src/graph.rs:471`](../core/dr-pipeline/src/graph.rs#L471), [`core/dr-pipeline/src/operation.rs:1137`](../core/dr-pipeline/src/operation.rs#L1137), [`core/dr-pipeline/src/operation.rs:1165`](../core/dr-pipeline/src/operation.rs#L1165), [`core/dr-pipeline/src/operation.rs:1211`](../core/dr-pipeline/src/operation.rs#L1211), [`core/dr-pipeline/src/operation.rs:1762`](../core/dr-pipeline/src/operation.rs#L1762), [`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:102`](../core/dr-pipeline/src/ops/film_sim.rs#L102), [`core/dr-pipeline/src/ops/film_sim.rs:139`](../core/dr-pipeline/src/ops/film_sim.rs#L139), [`core/dr-pipeline/src/ops/film_sim.rs:163`](../core/dr-pipeline/src/ops/film_sim.rs#L163), [`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:341`](../core/dr-pipeline/src/ops/film_sim.rs#L341), [`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:97`](../core/dr-pipeline/src/ops/film_sim.rs#L97), [`core/dr-pipeline/src/sidecar.rs:113`](../core/dr-pipeline/src/sidecar.rs#L113), [`core/dr-pipeline/src/sidecar.rs:169`](../core/dr-pipeline/src/sidecar.rs#L169), [`core/dr-pipeline/src/sidecar.rs:2177`](../core/dr-pipeline/src/sidecar.rs#L2177), [`core/dr-pipeline/src/sidecar.rs:2253`](../core/dr-pipeline/src/sidecar.rs#L2253), [`core/dr-pipeline/src/sidecar.rs:535`](../core/dr-pipeline/src/sidecar.rs#L535), [`core/dr-pipeline/src/sidecar.rs:779`](../core/dr-pipeline/src/sidecar.rs#L779), [`core/dr-pipeline/src/sidecar.rs:911`](../core/dr-pipeline/src/sidecar.rs#L911), [`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:3940`](../ui/dr-ui/src/develop.rs#L3940), [`ui/dr-ui/src/develop.rs:3957`](../ui/dr-ui/src/develop.rs#L3957), [`ui/dr-ui/src/develop.rs:3969`](../ui/dr-ui/src/develop.rs#L3969), [`ui/dr-ui/src/develop.rs:4007`](../ui/dr-ui/src/develop.rs#L4007), [`ui/dr-ui/src/develop.rs:4016`](../ui/dr-ui/src/develop.rs#L4016), [`ui/dr-ui/src/develop.rs:4119`](../ui/dr-ui/src/develop.rs#L4119), [`ui/dr-ui/src/develop.rs:4630`](../ui/dr-ui/src/develop.rs#L4630), [`ui/dr-ui/src/develop.rs:4645`](../ui/dr-ui/src/develop.rs#L4645), [`ui/dr-ui/src/lib.rs:2618`](../ui/dr-ui/src/lib.rs#L2618), [`ui/dr-ui/src/lib.rs:757`](../ui/dr-ui/src/lib.rs#L757), [`ui/dr-ui/src/lib.rs:815`](../ui/dr-ui/src/lib.rs#L815), [`ui/dr-ui/src/library.rs:538`](../ui/dr-ui/src/library.rs#L538), [`ui/dr-ui/src/library.rs:800`](../ui/dr-ui/src/library.rs#L800), [`ui/dr-ui/src/presets.rs:417`](../ui/dr-ui/src/presets.rs#L417), [`ui/dr-ui/ui/adjust.slint:1073`](../ui/dr-ui/ui/adjust.slint#L1073), [`ui/dr-ui/ui/adjust.slint:1149`](../ui/dr-ui/ui/adjust.slint#L1149), [`ui/dr-ui/ui/app.slint:2890`](../ui/dr-ui/ui/app.slint#L2890), [`ui/dr-ui/ui/app.slint:774`](../ui/dr-ui/ui/app.slint#L774) | +| 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:1067`](../core/dr-pipeline/src/framing.rs#L1067), [`core/dr-pipeline/src/framing.rs:328`](../core/dr-pipeline/src/framing.rs#L328), [`core/dr-pipeline/src/framing.rs:498`](../core/dr-pipeline/src/framing.rs#L498), [`core/dr-types/src/lib.rs:339`](../core/dr-types/src/lib.rs#L339), [`core/dr-types/src/lib.rs:447`](../core/dr-types/src/lib.rs#L447), [`core/dr-types/src/lib.rs:459`](../core/dr-types/src/lib.rs#L459), [`core/dr-types/src/lib.rs:475`](../core/dr-types/src/lib.rs#L475), [`ui/dr-ui/src/develop.rs:140`](../ui/dr-ui/src/develop.rs#L140), [`ui/dr-ui/src/develop.rs:2416`](../ui/dr-ui/src/develop.rs#L2416), [`ui/dr-ui/src/segmentation.rs:476`](../ui/dr-ui/src/segmentation.rs#L476) | | FR-DEV-4 | [`core/dr-gpu/src/adjust.rs:770`](../core/dr-gpu/src/adjust.rs#L770), [`core/dr-gpu/src/lib.rs:351`](../core/dr-gpu/src/lib.rs#L351), [`ui/dr-ui/ui/crop.slint:1`](../ui/dr-ui/ui/crop.slint#L1) | -| FR-DEV-5 | [`core/dr-pipeline/src/graph.rs:465`](../core/dr-pipeline/src/graph.rs#L465), [`core/dr-pipeline/src/graph.rs:513`](../core/dr-pipeline/src/graph.rs#L513), [`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:3805`](../ui/dr-ui/src/develop.rs#L3805), [`ui/dr-ui/src/develop.rs:4481`](../ui/dr-ui/src/develop.rs#L4481), [`ui/dr-ui/src/develop.rs:4511`](../ui/dr-ui/src/develop.rs#L4511), [`ui/dr-ui/src/develop.rs:4524`](../ui/dr-ui/src/develop.rs#L4524), [`ui/dr-ui/src/develop.rs:4536`](../ui/dr-ui/src/develop.rs#L4536), [`ui/dr-ui/src/develop.rs:4552`](../ui/dr-ui/src/develop.rs#L4552), [`ui/dr-ui/src/develop.rs:4584`](../ui/dr-ui/src/develop.rs#L4584), [`ui/dr-ui/src/develop.rs:4588`](../ui/dr-ui/src/develop.rs#L4588), [`ui/dr-ui/src/develop.rs:4607`](../ui/dr-ui/src/develop.rs#L4607), [`ui/dr-ui/src/develop.rs:4623`](../ui/dr-ui/src/develop.rs#L4623), [`ui/dr-ui/src/develop.rs:5430`](../ui/dr-ui/src/develop.rs#L5430), [`ui/dr-ui/src/develop.rs:5450`](../ui/dr-ui/src/develop.rs#L5450), [`ui/dr-ui/src/develop.rs:746`](../ui/dr-ui/src/develop.rs#L746), [`ui/dr-ui/src/labels.rs:12`](../ui/dr-ui/src/labels.rs#L12), [`ui/dr-ui/src/labels.rs:231`](../ui/dr-ui/src/labels.rs#L231), [`ui/dr-ui/src/lib.rs:1701`](../ui/dr-ui/src/lib.rs#L1701), [`ui/dr-ui/src/lib.rs:1763`](../ui/dr-ui/src/lib.rs#L1763), [`ui/dr-ui/src/lib.rs:1771`](../ui/dr-ui/src/lib.rs#L1771), [`ui/dr-ui/src/lib.rs:2837`](../ui/dr-ui/src/lib.rs#L2837), [`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:4423`](../ui/dr-ui/src/develop.rs#L4423), [`ui/dr-ui/src/develop.rs:4444`](../ui/dr-ui/src/develop.rs#L4444), [`ui/dr-ui/src/lib.rs:1668`](../ui/dr-ui/src/lib.rs#L1668), [`ui/dr-ui/src/lib.rs:2418`](../ui/dr-ui/src/lib.rs#L2418), [`ui/dr-ui/src/lib.rs:2447`](../ui/dr-ui/src/lib.rs#L2447), [`ui/dr-ui/src/library.rs:2219`](../ui/dr-ui/src/library.rs#L2219), [`ui/dr-ui/src/library.rs:500`](../ui/dr-ui/src/library.rs#L500), [`ui/dr-ui/src/library.rs:528`](../ui/dr-ui/src/library.rs#L528), [`ui/dr-ui/src/library_ui.rs:3199`](../ui/dr-ui/src/library_ui.rs#L3199), [`ui/dr-ui/src/library_ui.rs:3599`](../ui/dr-ui/src/library_ui.rs#L3599), [`ui/dr-ui/src/library_ui.rs:554`](../ui/dr-ui/src/library_ui.rs#L554), [`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:679`](../ui/dr-ui/src/presets.rs#L679), [`ui/dr-ui/src/presets.rs:713`](../ui/dr-ui/src/presets.rs#L713), [`ui/dr-ui/ui/adjust.slint:740`](../ui/dr-ui/ui/adjust.slint#L740), [`ui/dr-ui/ui/adjust.slint:767`](../ui/dr-ui/ui/adjust.slint#L767), [`ui/dr-ui/ui/adjust.slint:801`](../ui/dr-ui/ui/adjust.slint#L801), [`ui/dr-ui/ui/app.slint:1659`](../ui/dr-ui/ui/app.slint#L1659), [`ui/dr-ui/ui/app.slint:2907`](../ui/dr-ui/ui/app.slint#L2907), [`ui/dr-ui/ui/app.slint:834`](../ui/dr-ui/ui/app.slint#L834), [`ui/dr-ui/ui/app.slint:845`](../ui/dr-ui/ui/app.slint#L845), [`ui/dr-ui/ui/library.slint:1564`](../ui/dr-ui/ui/library.slint#L1564), [`ui/dr-ui/ui/library.slint:1570`](../ui/dr-ui/ui/library.slint#L1570), [`ui/dr-ui/ui/library.slint:4117`](../ui/dr-ui/ui/library.slint#L4117), [`ui/dr-ui/ui/library.slint:4132`](../ui/dr-ui/ui/library.slint#L4132), [`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:595`](../ui/dr-ui/ui/settings.slint#L595) | -| 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:3458`](../ui/dr-ui/src/develop.rs#L3458), [`ui/dr-ui/src/develop.rs:3499`](../ui/dr-ui/src/develop.rs#L3499), [`ui/dr-ui/src/develop.rs:4552`](../ui/dr-ui/src/develop.rs#L4552), [`ui/dr-ui/src/develop.rs:4584`](../ui/dr-ui/src/develop.rs#L4584), [`ui/dr-ui/src/develop.rs:5450`](../ui/dr-ui/src/develop.rs#L5450), [`ui/dr-ui/src/lib.rs:1771`](../ui/dr-ui/src/lib.rs#L1771), [`ui/dr-ui/src/lib.rs:1832`](../ui/dr-ui/src/lib.rs#L1832), [`ui/dr-ui/src/lib.rs:2809`](../ui/dr-ui/src/lib.rs#L2809), [`ui/dr-ui/src/lib.rs:2837`](../ui/dr-ui/src/lib.rs#L2837), [`ui/dr-ui/src/lib.rs:373`](../ui/dr-ui/src/lib.rs#L373), [`ui/dr-ui/ui/app.slint:2194`](../ui/dr-ui/ui/app.slint#L2194), [`ui/dr-ui/ui/app.slint:2209`](../ui/dr-ui/ui/app.slint#L2209), [`ui/dr-ui/ui/app.slint:224`](../ui/dr-ui/ui/app.slint#L224), [`ui/dr-ui/ui/app.slint:2367`](../ui/dr-ui/ui/app.slint#L2367), [`ui/dr-ui/ui/history.slint:1`](../ui/dr-ui/ui/history.slint#L1), [`ui/dr-ui/ui/widgets.slint:71`](../ui/dr-ui/ui/widgets.slint#L71) | -| 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:115`](../core/dr-pipeline/src/graph.rs#L115), [`core/dr-pipeline/src/graph.rs:231`](../core/dr-pipeline/src/graph.rs#L231), [`core/dr-pipeline/src/graph.rs:859`](../core/dr-pipeline/src/graph.rs#L859), [`core/dr-pipeline/src/operation.rs:330`](../core/dr-pipeline/src/operation.rs#L330), [`core/dr-pipeline/src/operation.rs:579`](../core/dr-pipeline/src/operation.rs#L579), [`core/dr-pipeline/src/sidecar.rs:1011`](../core/dr-pipeline/src/sidecar.rs#L1011), [`core/dr-pipeline/src/sidecar.rs:185`](../core/dr-pipeline/src/sidecar.rs#L185), [`core/dr-pipeline/src/sidecar.rs:354`](../core/dr-pipeline/src/sidecar.rs#L354), [`core/dr-pipeline/src/sidecar.rs:791`](../core/dr-pipeline/src/sidecar.rs#L791), [`core/dr-pipeline/src/sidecar.rs:927`](../core/dr-pipeline/src/sidecar.rs#L927), [`core/dr-pipeline/src/sidecar.rs:981`](../core/dr-pipeline/src/sidecar.rs#L981), [`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:2516`](../ui/dr-ui/src/develop.rs#L2516), [`ui/dr-ui/src/develop.rs:2554`](../ui/dr-ui/src/develop.rs#L2554), [`ui/dr-ui/src/develop.rs:2619`](../ui/dr-ui/src/develop.rs#L2619), [`ui/dr-ui/src/develop.rs:2702`](../ui/dr-ui/src/develop.rs#L2702), [`ui/dr-ui/src/develop.rs:2716`](../ui/dr-ui/src/develop.rs#L2716), [`ui/dr-ui/src/develop.rs:833`](../ui/dr-ui/src/develop.rs#L833), [`ui/dr-ui/src/labels.rs:53`](../ui/dr-ui/src/labels.rs#L53), [`ui/dr-ui/src/lib.rs:1792`](../ui/dr-ui/src/lib.rs#L1792), [`ui/dr-ui/src/lib.rs:2988`](../ui/dr-ui/src/lib.rs#L2988), [`ui/dr-ui/src/lib.rs:402`](../ui/dr-ui/src/lib.rs#L402), [`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:832`](../ui/dr-ui/ui/adjust.slint#L832), [`ui/dr-ui/ui/app.slint:146`](../ui/dr-ui/ui/app.slint#L146), [`ui/dr-ui/ui/app.slint:2020`](../ui/dr-ui/ui/app.slint#L2020), [`ui/dr-ui/ui/app.slint:2231`](../ui/dr-ui/ui/app.slint#L2231), [`ui/dr-ui/ui/app.slint:2719`](../ui/dr-ui/ui/app.slint#L2719), [`ui/dr-ui/ui/icons.slint:338`](../ui/dr-ui/ui/icons.slint#L338), [`ui/dr-ui/ui/spots.slint:172`](../ui/dr-ui/ui/spots.slint#L172), [`ui/dr-ui/ui/spots.slint:48`](../ui/dr-ui/ui/spots.slint#L48), [`ui/dr-ui/ui/spots.slint:5`](../ui/dr-ui/ui/spots.slint#L5) | -| FR-DSP-1 | [`core/dr-gpu/src/adjust.rs:2140`](../core/dr-gpu/src/adjust.rs#L2140), [`core/dr-gpu/src/adjust.rs:2217`](../core/dr-gpu/src/adjust.rs#L2217), [`core/dr-gpu/src/adjust.rs:2302`](../core/dr-gpu/src/adjust.rs#L2302), [`core/dr-gpu/src/adjust.rs:54`](../core/dr-gpu/src/adjust.rs#L54), [`core/dr-gpu/src/adjust.rs:770`](../core/dr-gpu/src/adjust.rs#L770), [`core/dr-gpu/src/lib.rs:172`](../core/dr-gpu/src/lib.rs#L172), [`core/dr-gpu/src/lib.rs:192`](../core/dr-gpu/src/lib.rs#L192), [`core/dr-gpu/src/lib.rs:70`](../core/dr-gpu/src/lib.rs#L70), [`core/dr-gpu/src/lib.rs:93`](../core/dr-gpu/src/lib.rs#L93), [`core/dr-gpu/tests/capture_sharpen.rs:200`](../core/dr-gpu/tests/capture_sharpen.rs#L200), [`core/dr-gpu/tests/detail_stage.rs:328`](../core/dr-gpu/tests/detail_stage.rs#L328), [`core/dr-gpu/tests/local_contrast.rs:264`](../core/dr-gpu/tests/local_contrast.rs#L264), [`core/dr-gpu/tests/noise_reduction.rs:378`](../core/dr-gpu/tests/noise_reduction.rs#L378), [`core/dr-pipeline/src/detail.rs:136`](../core/dr-pipeline/src/detail.rs#L136), [`core/dr-pipeline/src/detail.rs:524`](../core/dr-pipeline/src/detail.rs#L524), [`core/dr-pipeline/src/graph.rs:705`](../core/dr-pipeline/src/graph.rs#L705), [`core/dr-pipeline/src/graph.rs:735`](../core/dr-pipeline/src/graph.rs#L735), [`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:3150`](../ui/dr-ui/src/develop.rs#L3150), [`ui/dr-ui/src/develop.rs:4291`](../ui/dr-ui/src/develop.rs#L4291), [`ui/dr-ui/src/develop.rs:4878`](../ui/dr-ui/src/develop.rs#L4878), [`ui/dr-ui/src/develop.rs:6001`](../ui/dr-ui/src/develop.rs#L6001), [`ui/dr-ui/src/develop.rs:6035`](../ui/dr-ui/src/develop.rs#L6035), [`ui/dr-ui/src/lib.rs:1019`](../ui/dr-ui/src/lib.rs#L1019), [`ui/dr-ui/src/lib.rs:93`](../ui/dr-ui/src/lib.rs#L93), [`ui/dr-ui/src/lib.rs:960`](../ui/dr-ui/src/lib.rs#L960) | +| FR-DEV-5 | [`core/dr-pipeline/src/graph.rs:492`](../core/dr-pipeline/src/graph.rs#L492), [`core/dr-pipeline/src/graph.rs:540`](../core/dr-pipeline/src/graph.rs#L540), [`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:3576`](../ui/dr-ui/src/develop.rs#L3576), [`ui/dr-ui/src/develop.rs:3969`](../ui/dr-ui/src/develop.rs#L3969), [`ui/dr-ui/src/develop.rs:4645`](../ui/dr-ui/src/develop.rs#L4645), [`ui/dr-ui/src/develop.rs:4675`](../ui/dr-ui/src/develop.rs#L4675), [`ui/dr-ui/src/develop.rs:4688`](../ui/dr-ui/src/develop.rs#L4688), [`ui/dr-ui/src/develop.rs:4700`](../ui/dr-ui/src/develop.rs#L4700), [`ui/dr-ui/src/develop.rs:4716`](../ui/dr-ui/src/develop.rs#L4716), [`ui/dr-ui/src/develop.rs:4748`](../ui/dr-ui/src/develop.rs#L4748), [`ui/dr-ui/src/develop.rs:4752`](../ui/dr-ui/src/develop.rs#L4752), [`ui/dr-ui/src/develop.rs:4771`](../ui/dr-ui/src/develop.rs#L4771), [`ui/dr-ui/src/develop.rs:4787`](../ui/dr-ui/src/develop.rs#L4787), [`ui/dr-ui/src/develop.rs:5594`](../ui/dr-ui/src/develop.rs#L5594), [`ui/dr-ui/src/develop.rs:5614`](../ui/dr-ui/src/develop.rs#L5614), [`ui/dr-ui/src/develop.rs:5645`](../ui/dr-ui/src/develop.rs#L5645), [`ui/dr-ui/src/develop.rs:746`](../ui/dr-ui/src/develop.rs#L746), [`ui/dr-ui/src/labels.rs:12`](../ui/dr-ui/src/labels.rs#L12), [`ui/dr-ui/src/labels.rs:240`](../ui/dr-ui/src/labels.rs#L240), [`ui/dr-ui/src/lib.rs:1706`](../ui/dr-ui/src/lib.rs#L1706), [`ui/dr-ui/src/lib.rs:1768`](../ui/dr-ui/src/lib.rs#L1768), [`ui/dr-ui/src/lib.rs:1776`](../ui/dr-ui/src/lib.rs#L1776), [`ui/dr-ui/src/lib.rs:2875`](../ui/dr-ui/src/lib.rs#L2875), [`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:4587`](../ui/dr-ui/src/develop.rs#L4587), [`ui/dr-ui/src/develop.rs:4608`](../ui/dr-ui/src/develop.rs#L4608), [`ui/dr-ui/src/lib.rs:1673`](../ui/dr-ui/src/lib.rs#L1673), [`ui/dr-ui/src/lib.rs:2423`](../ui/dr-ui/src/lib.rs#L2423), [`ui/dr-ui/src/lib.rs:2452`](../ui/dr-ui/src/lib.rs#L2452), [`ui/dr-ui/src/library.rs:2219`](../ui/dr-ui/src/library.rs#L2219), [`ui/dr-ui/src/library.rs:500`](../ui/dr-ui/src/library.rs#L500), [`ui/dr-ui/src/library.rs:528`](../ui/dr-ui/src/library.rs#L528), [`ui/dr-ui/src/library_ui.rs:3199`](../ui/dr-ui/src/library_ui.rs#L3199), [`ui/dr-ui/src/library_ui.rs:3599`](../ui/dr-ui/src/library_ui.rs#L3599), [`ui/dr-ui/src/library_ui.rs:554`](../ui/dr-ui/src/library_ui.rs#L554), [`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:679`](../ui/dr-ui/src/presets.rs#L679), [`ui/dr-ui/src/presets.rs:713`](../ui/dr-ui/src/presets.rs#L713), [`ui/dr-ui/ui/adjust.slint:804`](../ui/dr-ui/ui/adjust.slint#L804), [`ui/dr-ui/ui/adjust.slint:831`](../ui/dr-ui/ui/adjust.slint#L831), [`ui/dr-ui/ui/adjust.slint:865`](../ui/dr-ui/ui/adjust.slint#L865), [`ui/dr-ui/ui/app.slint:1683`](../ui/dr-ui/ui/app.slint#L1683), [`ui/dr-ui/ui/app.slint:2979`](../ui/dr-ui/ui/app.slint#L2979), [`ui/dr-ui/ui/app.slint:858`](../ui/dr-ui/ui/app.slint#L858), [`ui/dr-ui/ui/app.slint:869`](../ui/dr-ui/ui/app.slint#L869), [`ui/dr-ui/ui/library.slint:1564`](../ui/dr-ui/ui/library.slint#L1564), [`ui/dr-ui/ui/library.slint:1570`](../ui/dr-ui/ui/library.slint#L1570), [`ui/dr-ui/ui/library.slint:4117`](../ui/dr-ui/ui/library.slint#L4117), [`ui/dr-ui/ui/library.slint:4132`](../ui/dr-ui/ui/library.slint#L4132), [`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:595`](../ui/dr-ui/ui/settings.slint#L595) | +| 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:3510`](../ui/dr-ui/src/develop.rs#L3510), [`ui/dr-ui/src/develop.rs:3551`](../ui/dr-ui/src/develop.rs#L3551), [`ui/dr-ui/src/develop.rs:4716`](../ui/dr-ui/src/develop.rs#L4716), [`ui/dr-ui/src/develop.rs:4748`](../ui/dr-ui/src/develop.rs#L4748), [`ui/dr-ui/src/develop.rs:5645`](../ui/dr-ui/src/develop.rs#L5645), [`ui/dr-ui/src/lib.rs:1776`](../ui/dr-ui/src/lib.rs#L1776), [`ui/dr-ui/src/lib.rs:1837`](../ui/dr-ui/src/lib.rs#L1837), [`ui/dr-ui/src/lib.rs:2814`](../ui/dr-ui/src/lib.rs#L2814), [`ui/dr-ui/src/lib.rs:2875`](../ui/dr-ui/src/lib.rs#L2875), [`ui/dr-ui/src/lib.rs:373`](../ui/dr-ui/src/lib.rs#L373), [`ui/dr-ui/ui/app.slint:224`](../ui/dr-ui/ui/app.slint#L224), [`ui/dr-ui/ui/app.slint:2255`](../ui/dr-ui/ui/app.slint#L2255), [`ui/dr-ui/ui/app.slint:2270`](../ui/dr-ui/ui/app.slint#L2270), [`ui/dr-ui/ui/app.slint:2428`](../ui/dr-ui/ui/app.slint#L2428), [`ui/dr-ui/ui/history.slint:1`](../ui/dr-ui/ui/history.slint#L1), [`ui/dr-ui/ui/widgets.slint:71`](../ui/dr-ui/ui/widgets.slint#L71) | +| 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:115`](../core/dr-pipeline/src/graph.rs#L115), [`core/dr-pipeline/src/graph.rs:231`](../core/dr-pipeline/src/graph.rs#L231), [`core/dr-pipeline/src/graph.rs:886`](../core/dr-pipeline/src/graph.rs#L886), [`core/dr-pipeline/src/operation.rs:330`](../core/dr-pipeline/src/operation.rs#L330), [`core/dr-pipeline/src/operation.rs:579`](../core/dr-pipeline/src/operation.rs#L579), [`core/dr-pipeline/src/sidecar.rs:1011`](../core/dr-pipeline/src/sidecar.rs#L1011), [`core/dr-pipeline/src/sidecar.rs:185`](../core/dr-pipeline/src/sidecar.rs#L185), [`core/dr-pipeline/src/sidecar.rs:354`](../core/dr-pipeline/src/sidecar.rs#L354), [`core/dr-pipeline/src/sidecar.rs:791`](../core/dr-pipeline/src/sidecar.rs#L791), [`core/dr-pipeline/src/sidecar.rs:927`](../core/dr-pipeline/src/sidecar.rs#L927), [`core/dr-pipeline/src/sidecar.rs:981`](../core/dr-pipeline/src/sidecar.rs#L981), [`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:2568`](../ui/dr-ui/src/develop.rs#L2568), [`ui/dr-ui/src/develop.rs:2606`](../ui/dr-ui/src/develop.rs#L2606), [`ui/dr-ui/src/develop.rs:2671`](../ui/dr-ui/src/develop.rs#L2671), [`ui/dr-ui/src/develop.rs:2754`](../ui/dr-ui/src/develop.rs#L2754), [`ui/dr-ui/src/develop.rs:2768`](../ui/dr-ui/src/develop.rs#L2768), [`ui/dr-ui/src/develop.rs:833`](../ui/dr-ui/src/develop.rs#L833), [`ui/dr-ui/src/labels.rs:61`](../ui/dr-ui/src/labels.rs#L61), [`ui/dr-ui/src/lib.rs:1797`](../ui/dr-ui/src/lib.rs#L1797), [`ui/dr-ui/src/lib.rs:3026`](../ui/dr-ui/src/lib.rs#L3026), [`ui/dr-ui/src/lib.rs:407`](../ui/dr-ui/src/lib.rs#L407), [`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:896`](../ui/dr-ui/ui/adjust.slint#L896), [`ui/dr-ui/ui/app.slint:146`](../ui/dr-ui/ui/app.slint#L146), [`ui/dr-ui/ui/app.slint:2044`](../ui/dr-ui/ui/app.slint#L2044), [`ui/dr-ui/ui/app.slint:2292`](../ui/dr-ui/ui/app.slint#L2292), [`ui/dr-ui/ui/app.slint:2780`](../ui/dr-ui/ui/app.slint#L2780), [`ui/dr-ui/ui/icons.slint:338`](../ui/dr-ui/ui/icons.slint#L338), [`ui/dr-ui/ui/spots.slint:172`](../ui/dr-ui/ui/spots.slint#L172), [`ui/dr-ui/ui/spots.slint:48`](../ui/dr-ui/ui/spots.slint#L48), [`ui/dr-ui/ui/spots.slint:5`](../ui/dr-ui/ui/spots.slint#L5) | +| FR-DSP-1 | [`core/dr-gpu/src/adjust.rs:2140`](../core/dr-gpu/src/adjust.rs#L2140), [`core/dr-gpu/src/adjust.rs:2217`](../core/dr-gpu/src/adjust.rs#L2217), [`core/dr-gpu/src/adjust.rs:2302`](../core/dr-gpu/src/adjust.rs#L2302), [`core/dr-gpu/src/adjust.rs:54`](../core/dr-gpu/src/adjust.rs#L54), [`core/dr-gpu/src/adjust.rs:770`](../core/dr-gpu/src/adjust.rs#L770), [`core/dr-gpu/src/lib.rs:172`](../core/dr-gpu/src/lib.rs#L172), [`core/dr-gpu/src/lib.rs:192`](../core/dr-gpu/src/lib.rs#L192), [`core/dr-gpu/src/lib.rs:70`](../core/dr-gpu/src/lib.rs#L70), [`core/dr-gpu/src/lib.rs:93`](../core/dr-gpu/src/lib.rs#L93), [`core/dr-gpu/tests/capture_sharpen.rs:200`](../core/dr-gpu/tests/capture_sharpen.rs#L200), [`core/dr-gpu/tests/detail_stage.rs:328`](../core/dr-gpu/tests/detail_stage.rs#L328), [`core/dr-gpu/tests/local_contrast.rs:264`](../core/dr-gpu/tests/local_contrast.rs#L264), [`core/dr-gpu/tests/noise_reduction.rs:378`](../core/dr-gpu/tests/noise_reduction.rs#L378), [`core/dr-pipeline/src/detail.rs:136`](../core/dr-pipeline/src/detail.rs#L136), [`core/dr-pipeline/src/detail.rs:524`](../core/dr-pipeline/src/detail.rs#L524), [`core/dr-pipeline/src/graph.rs:732`](../core/dr-pipeline/src/graph.rs#L732), [`core/dr-pipeline/src/graph.rs:762`](../core/dr-pipeline/src/graph.rs#L762), [`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:3202`](../ui/dr-ui/src/develop.rs#L3202), [`ui/dr-ui/src/develop.rs:4455`](../ui/dr-ui/src/develop.rs#L4455), [`ui/dr-ui/src/develop.rs:5042`](../ui/dr-ui/src/develop.rs#L5042), [`ui/dr-ui/src/develop.rs:6196`](../ui/dr-ui/src/develop.rs#L6196), [`ui/dr-ui/src/develop.rs:6230`](../ui/dr-ui/src/develop.rs#L6230), [`ui/dr-ui/src/lib.rs:1024`](../ui/dr-ui/src/lib.rs#L1024), [`ui/dr-ui/src/lib.rs:93`](../ui/dr-ui/src/lib.rs#L93), [`ui/dr-ui/src/lib.rs:965`](../ui/dr-ui/src/lib.rs#L965) | | 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:497`](../core/dr-pipeline/src/operation.rs#L497), [`core/dr-types/src/colour.rs:1`](../core/dr-types/src/colour.rs#L1), [`ui/dr-ui/src/develop.rs:3180`](../ui/dr-ui/src/develop.rs#L3180), [`ui/dr-ui/src/develop.rs:7429`](../ui/dr-ui/src/develop.rs#L7429), [`ui/dr-ui/src/lib.rs:1748`](../ui/dr-ui/src/lib.rs#L1748), [`ui/dr-ui/src/lib.rs:3371`](../ui/dr-ui/src/lib.rs#L3371) | -| 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:3229`](../ui/dr-ui/src/develop.rs#L3229), [`ui/dr-ui/src/develop.rs:7103`](../ui/dr-ui/src/develop.rs#L7103), [`ui/dr-ui/src/develop.rs:7135`](../ui/dr-ui/src/develop.rs#L7135), [`ui/dr-ui/src/develop.rs:757`](../ui/dr-ui/src/develop.rs#L757), [`ui/dr-ui/src/histogram.rs:1`](../ui/dr-ui/src/histogram.rs#L1), [`ui/dr-ui/src/lib.rs:1866`](../ui/dr-ui/src/lib.rs#L1866), [`ui/dr-ui/src/lib.rs:381`](../ui/dr-ui/src/lib.rs#L381), [`ui/dr-ui/ui/app.slint:80`](../ui/dr-ui/ui/app.slint#L80), [`ui/dr-ui/ui/histogram.slint:168`](../ui/dr-ui/ui/histogram.slint#L168), [`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:3126`](../ui/dr-ui/src/develop.rs#L3126), [`ui/dr-ui/src/develop.rs:3180`](../ui/dr-ui/src/develop.rs#L3180), [`ui/dr-ui/src/develop.rs:7429`](../ui/dr-ui/src/develop.rs#L7429), [`ui/dr-ui/src/develop.rs:7475`](../ui/dr-ui/src/develop.rs#L7475), [`ui/dr-ui/src/develop.rs:7494`](../ui/dr-ui/src/develop.rs#L7494), [`ui/dr-ui/src/develop.rs:864`](../ui/dr-ui/src/develop.rs#L864), [`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:1690`](../ui/dr-ui/src/lib.rs#L1690), [`ui/dr-ui/src/lib.rs:1748`](../ui/dr-ui/src/lib.rs#L1748), [`ui/dr-ui/src/lib.rs:3284`](../ui/dr-ui/src/lib.rs#L3284), [`ui/dr-ui/src/lib.rs:3371`](../ui/dr-ui/src/lib.rs#L3371), [`ui/dr-ui/ui/app.slint:1868`](../ui/dr-ui/ui/app.slint#L1868), [`ui/dr-ui/ui/app.slint:53`](../ui/dr-ui/ui/app.slint#L53), [`ui/dr-ui/ui/settings.slint:132`](../ui/dr-ui/ui/settings.slint#L132), [`ui/dr-ui/ui/settings.slint:832`](../ui/dr-ui/ui/settings.slint#L832) | +| FR-DSP-6 | [`core/dr-pipeline/src/operation.rs:497`](../core/dr-pipeline/src/operation.rs#L497), [`core/dr-types/src/colour.rs:1`](../core/dr-types/src/colour.rs#L1), [`ui/dr-ui/src/develop.rs:3232`](../ui/dr-ui/src/develop.rs#L3232), [`ui/dr-ui/src/develop.rs:7668`](../ui/dr-ui/src/develop.rs#L7668), [`ui/dr-ui/src/lib.rs:1753`](../ui/dr-ui/src/lib.rs#L1753), [`ui/dr-ui/src/lib.rs:3409`](../ui/dr-ui/src/lib.rs#L3409) | +| 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:3281`](../ui/dr-ui/src/develop.rs#L3281), [`ui/dr-ui/src/develop.rs:7342`](../ui/dr-ui/src/develop.rs#L7342), [`ui/dr-ui/src/develop.rs:7374`](../ui/dr-ui/src/develop.rs#L7374), [`ui/dr-ui/src/develop.rs:757`](../ui/dr-ui/src/develop.rs#L757), [`ui/dr-ui/src/histogram.rs:1`](../ui/dr-ui/src/histogram.rs#L1), [`ui/dr-ui/src/lib.rs:1871`](../ui/dr-ui/src/lib.rs#L1871), [`ui/dr-ui/src/lib.rs:386`](../ui/dr-ui/src/lib.rs#L386), [`ui/dr-ui/ui/app.slint:80`](../ui/dr-ui/ui/app.slint#L80), [`ui/dr-ui/ui/histogram.slint:168`](../ui/dr-ui/ui/histogram.slint#L168), [`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:3178`](../ui/dr-ui/src/develop.rs#L3178), [`ui/dr-ui/src/develop.rs:3232`](../ui/dr-ui/src/develop.rs#L3232), [`ui/dr-ui/src/develop.rs:7668`](../ui/dr-ui/src/develop.rs#L7668), [`ui/dr-ui/src/develop.rs:7714`](../ui/dr-ui/src/develop.rs#L7714), [`ui/dr-ui/src/develop.rs:7733`](../ui/dr-ui/src/develop.rs#L7733), [`ui/dr-ui/src/develop.rs:864`](../ui/dr-ui/src/develop.rs#L864), [`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:1695`](../ui/dr-ui/src/lib.rs#L1695), [`ui/dr-ui/src/lib.rs:1753`](../ui/dr-ui/src/lib.rs#L1753), [`ui/dr-ui/src/lib.rs:3322`](../ui/dr-ui/src/lib.rs#L3322), [`ui/dr-ui/src/lib.rs:3409`](../ui/dr-ui/src/lib.rs#L3409), [`ui/dr-ui/ui/app.slint:1892`](../ui/dr-ui/ui/app.slint#L1892), [`ui/dr-ui/ui/app.slint:53`](../ui/dr-ui/ui/app.slint#L53), [`ui/dr-ui/ui/settings.slint:132`](../ui/dr-ui/ui/settings.slint#L132), [`ui/dr-ui/ui/settings.slint:832`](../ui/dr-ui/ui/settings.slint#L832) | | 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:2450`](../core/dr-gpu/src/adjust.rs#L2450), [`core/dr-pipeline/src/graph.rs:688`](../core/dr-pipeline/src/graph.rs#L688), [`core/dr-pipeline/src/graph.rs:749`](../core/dr-pipeline/src/graph.rs#L749), [`core/dr-pipeline/src/operation.rs:497`](../core/dr-pipeline/src/operation.rs#L497), [`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:761`](../core/dr-types/src/settings.rs#L761), [`ui/dr-ui/src/develop.rs:7494`](../ui/dr-ui/src/develop.rs#L7494), [`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:2450`](../core/dr-gpu/src/adjust.rs#L2450), [`core/dr-pipeline/src/graph.rs:715`](../core/dr-pipeline/src/graph.rs#L715), [`core/dr-pipeline/src/graph.rs:776`](../core/dr-pipeline/src/graph.rs#L776), [`core/dr-pipeline/src/operation.rs:497`](../core/dr-pipeline/src/operation.rs#L497), [`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:761`](../core/dr-types/src/settings.rs#L761), [`ui/dr-ui/src/develop.rs:7733`](../ui/dr-ui/src/develop.rs#L7733), [`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:806`](../core/dr-types/src/settings.rs#L806), [`core/dr-types/src/settings.rs:814`](../core/dr-types/src/settings.rs#L814), [`core/dr-types/src/settings.rs:830`](../core/dr-types/src/settings.rs#L830), [`core/dr-types/src/settings.rs:899`](../core/dr-types/src/settings.rs#L899), [`core/dr-types/src/settings.rs:927`](../core/dr-types/src/settings.rs#L927), [`core/dr-types/src/settings.rs:938`](../core/dr-types/src/settings.rs#L938), [`core/dr-types/src/settings.rs:944`](../core/dr-types/src/settings.rs#L944), [`ui/dr-ui/src/settings_ui.rs:1`](../ui/dr-ui/src/settings_ui.rs#L1), [`ui/dr-ui/src/settings_ui.rs:237`](../ui/dr-ui/src/settings_ui.rs#L237), [`ui/dr-ui/src/settings_ui.rs:250`](../ui/dr-ui/src/settings_ui.rs#L250), [`ui/dr-ui/src/settings_ui.rs:265`](../ui/dr-ui/src/settings_ui.rs#L265), [`ui/dr-ui/src/settings_ui.rs:615`](../ui/dr-ui/src/settings_ui.rs#L615), [`ui/dr-ui/ui/settings.slint:735`](../ui/dr-ui/ui/settings.slint#L735), [`ui/dr-ui/ui/settings.slint:745`](../ui/dr-ui/ui/settings.slint#L745) | | 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:554`](../ui/dr-ui/src/lib.rs#L554), [`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:729`](../ui/dr-ui/src/settings_ui.rs#L729) | -| 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:992`](../ui/dr-ui/src/export.rs#L992), [`ui/dr-ui/src/lib.rs:232`](../ui/dr-ui/src/lib.rs#L232), [`ui/dr-ui/src/lib.rs:2555`](../ui/dr-ui/src/lib.rs#L2555), [`ui/dr-ui/src/lib.rs:554`](../ui/dr-ui/src/lib.rs#L554), [`ui/dr-ui/src/lib.rs:600`](../ui/dr-ui/src/lib.rs#L600), [`ui/dr-ui/src/lib.rs:627`](../ui/dr-ui/src/lib.rs#L627), [`ui/dr-ui/src/library_ui.rs:3982`](../ui/dr-ui/src/library_ui.rs#L3982), [`ui/dr-ui/src/library_ui.rs:645`](../ui/dr-ui/src/library_ui.rs#L645), [`ui/dr-ui/src/library_ui.rs:745`](../ui/dr-ui/src/library_ui.rs#L745), [`ui/dr-ui/src/library_ui.rs:7673`](../ui/dr-ui/src/library_ui.rs#L7673), [`ui/dr-ui/src/library_ui.rs:7750`](../ui/dr-ui/src/library_ui.rs#L7750), [`ui/dr-ui/src/library_ui.rs:7762`](../ui/dr-ui/src/library_ui.rs#L7762), [`ui/dr-ui/src/library_ui.rs:802`](../ui/dr-ui/src/library_ui.rs#L802), [`ui/dr-ui/ui/app.slint:1179`](../ui/dr-ui/ui/app.slint#L1179), [`ui/dr-ui/ui/app.slint:1669`](../ui/dr-ui/ui/app.slint#L1669), [`ui/dr-ui/ui/library.slint:1573`](../ui/dr-ui/ui/library.slint#L1573), [`ui/dr-ui/ui/library.slint:4157`](../ui/dr-ui/ui/library.slint#L4157) | -| 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:655`](../core/dr-types/src/lib.rs#L655), [`core/dr-types/src/settings.rs:474`](../core/dr-types/src/settings.rs#L474), [`ui/dr-ui/src/develop.rs:3551`](../ui/dr-ui/src/develop.rs#L3551), [`ui/dr-ui/src/develop.rs:3659`](../ui/dr-ui/src/develop.rs#L3659), [`ui/dr-ui/src/develop.rs:703`](../ui/dr-ui/src/develop.rs#L703), [`ui/dr-ui/src/export.rs:467`](../ui/dr-ui/src/export.rs#L467), [`ui/dr-ui/src/export.rs:634`](../ui/dr-ui/src/export.rs#L634), [`ui/dr-ui/src/export.rs:680`](../ui/dr-ui/src/export.rs#L680), [`ui/dr-ui/src/export.rs:702`](../ui/dr-ui/src/export.rs#L702), [`ui/dr-ui/src/export.rs:826`](../ui/dr-ui/src/export.rs#L826), [`ui/dr-ui/src/export.rs:844`](../ui/dr-ui/src/export.rs#L844), [`ui/dr-ui/src/lib.rs:232`](../ui/dr-ui/src/lib.rs#L232), [`ui/dr-ui/src/lib.rs:255`](../ui/dr-ui/src/lib.rs#L255), [`ui/dr-ui/src/lib.rs:586`](../ui/dr-ui/src/lib.rs#L586), [`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/examples/face_native.rs:1`](../ui/dr-ui/examples/face_native.rs#L1), [`ui/dr-ui/src/develop.rs:3680`](../ui/dr-ui/src/develop.rs#L3680), [`ui/dr-ui/src/develop.rs:3718`](../ui/dr-ui/src/develop.rs#L3718), [`ui/dr-ui/src/develop.rs:5545`](../ui/dr-ui/src/develop.rs#L5545), [`ui/dr-ui/src/lib.rs:554`](../ui/dr-ui/src/lib.rs#L554), [`ui/dr-ui/src/library.rs:3385`](../ui/dr-ui/src/library.rs#L3385), [`ui/dr-ui/src/library.rs:3742`](../ui/dr-ui/src/library.rs#L3742), [`ui/dr-ui/src/library.rs:3778`](../ui/dr-ui/src/library.rs#L3778), [`ui/dr-ui/tests/export_ignores_the_viewport.rs:1`](../ui/dr-ui/tests/export_ignores_the_viewport.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:559`](../ui/dr-ui/src/lib.rs#L559), [`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:729`](../ui/dr-ui/src/settings_ui.rs#L729) | +| 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:992`](../ui/dr-ui/src/export.rs#L992), [`ui/dr-ui/src/lib.rs:232`](../ui/dr-ui/src/lib.rs#L232), [`ui/dr-ui/src/lib.rs:2560`](../ui/dr-ui/src/lib.rs#L2560), [`ui/dr-ui/src/lib.rs:559`](../ui/dr-ui/src/lib.rs#L559), [`ui/dr-ui/src/lib.rs:605`](../ui/dr-ui/src/lib.rs#L605), [`ui/dr-ui/src/lib.rs:632`](../ui/dr-ui/src/lib.rs#L632), [`ui/dr-ui/src/library_ui.rs:3982`](../ui/dr-ui/src/library_ui.rs#L3982), [`ui/dr-ui/src/library_ui.rs:645`](../ui/dr-ui/src/library_ui.rs#L645), [`ui/dr-ui/src/library_ui.rs:745`](../ui/dr-ui/src/library_ui.rs#L745), [`ui/dr-ui/src/library_ui.rs:7673`](../ui/dr-ui/src/library_ui.rs#L7673), [`ui/dr-ui/src/library_ui.rs:7750`](../ui/dr-ui/src/library_ui.rs#L7750), [`ui/dr-ui/src/library_ui.rs:7762`](../ui/dr-ui/src/library_ui.rs#L7762), [`ui/dr-ui/src/library_ui.rs:802`](../ui/dr-ui/src/library_ui.rs#L802), [`ui/dr-ui/ui/app.slint:1203`](../ui/dr-ui/ui/app.slint#L1203), [`ui/dr-ui/ui/app.slint:1693`](../ui/dr-ui/ui/app.slint#L1693), [`ui/dr-ui/ui/library.slint:1573`](../ui/dr-ui/ui/library.slint#L1573), [`ui/dr-ui/ui/library.slint:4157`](../ui/dr-ui/ui/library.slint#L4157) | +| 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:655`](../core/dr-types/src/lib.rs#L655), [`core/dr-types/src/settings.rs:474`](../core/dr-types/src/settings.rs#L474), [`ui/dr-ui/src/develop.rs:3715`](../ui/dr-ui/src/develop.rs#L3715), [`ui/dr-ui/src/develop.rs:3823`](../ui/dr-ui/src/develop.rs#L3823), [`ui/dr-ui/src/develop.rs:703`](../ui/dr-ui/src/develop.rs#L703), [`ui/dr-ui/src/export.rs:467`](../ui/dr-ui/src/export.rs#L467), [`ui/dr-ui/src/export.rs:634`](../ui/dr-ui/src/export.rs#L634), [`ui/dr-ui/src/export.rs:680`](../ui/dr-ui/src/export.rs#L680), [`ui/dr-ui/src/export.rs:702`](../ui/dr-ui/src/export.rs#L702), [`ui/dr-ui/src/export.rs:826`](../ui/dr-ui/src/export.rs#L826), [`ui/dr-ui/src/export.rs:844`](../ui/dr-ui/src/export.rs#L844), [`ui/dr-ui/src/lib.rs:232`](../ui/dr-ui/src/lib.rs#L232), [`ui/dr-ui/src/lib.rs:255`](../ui/dr-ui/src/lib.rs#L255), [`ui/dr-ui/src/lib.rs:591`](../ui/dr-ui/src/lib.rs#L591), [`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/examples/face_native.rs:1`](../ui/dr-ui/examples/face_native.rs#L1), [`ui/dr-ui/src/develop.rs:3844`](../ui/dr-ui/src/develop.rs#L3844), [`ui/dr-ui/src/develop.rs:3882`](../ui/dr-ui/src/develop.rs#L3882), [`ui/dr-ui/src/develop.rs:5740`](../ui/dr-ui/src/develop.rs#L5740), [`ui/dr-ui/src/lib.rs:559`](../ui/dr-ui/src/lib.rs#L559), [`ui/dr-ui/src/library.rs:3385`](../ui/dr-ui/src/library.rs#L3385), [`ui/dr-ui/src/library.rs:3742`](../ui/dr-ui/src/library.rs#L3742), [`ui/dr-ui/src/library.rs:3778`](../ui/dr-ui/src/library.rs#L3778), [`ui/dr-ui/tests/export_ignores_the_viewport.rs:1`](../ui/dr-ui/tests/export_ignores_the_viewport.rs#L1) | | FR-NC-1 | [`core/dr-sync-nextcloud/src/auth.rs:132`](../core/dr-sync-nextcloud/src/auth.rs#L132), [`core/dr-sync-nextcloud/src/auth.rs:44`](../core/dr-sync-nextcloud/src/auth.rs#L44), [`core/dr-sync-nextcloud/src/provider.rs:1`](../core/dr-sync-nextcloud/src/provider.rs#L1), [`core/dr-sync/src/account.rs:355`](../core/dr-sync/src/account.rs#L355), [`ui/dr-ui/src/launch.rs:277`](../ui/dr-ui/src/launch.rs#L277), [`ui/dr-ui/src/launch.rs:61`](../ui/dr-ui/src/launch.rs#L61), [`ui/dr-ui/src/launch_ui.rs:417`](../ui/dr-ui/src/launch_ui.rs#L417) | -| FR-NC-10 | [`core/dr-sync/src/account.rs:220`](../core/dr-sync/src/account.rs#L220), [`ui/dr-ui/src/export.rs:1`](../ui/dr-ui/src/export.rs#L1), [`ui/dr-ui/src/lib.rs:627`](../ui/dr-ui/src/lib.rs#L627), [`ui/dr-ui/src/library.rs:1155`](../ui/dr-ui/src/library.rs#L1155), [`ui/dr-ui/src/library.rs:2255`](../ui/dr-ui/src/library.rs#L2255), [`ui/dr-ui/src/library.rs:584`](../ui/dr-ui/src/library.rs#L584), [`ui/dr-ui/src/library.rs:899`](../ui/dr-ui/src/library.rs#L899), [`ui/dr-ui/src/library_ui.rs:1983`](../ui/dr-ui/src/library_ui.rs#L1983), [`ui/dr-ui/src/library_ui.rs:3982`](../ui/dr-ui/src/library_ui.rs#L3982), [`ui/dr-ui/src/library_ui.rs:586`](../ui/dr-ui/src/library_ui.rs#L586), [`ui/dr-ui/src/sidecar_cache.rs:1`](../ui/dr-ui/src/sidecar_cache.rs#L1) | +| FR-NC-10 | [`core/dr-sync/src/account.rs:220`](../core/dr-sync/src/account.rs#L220), [`ui/dr-ui/src/export.rs:1`](../ui/dr-ui/src/export.rs#L1), [`ui/dr-ui/src/lib.rs:632`](../ui/dr-ui/src/lib.rs#L632), [`ui/dr-ui/src/library.rs:1155`](../ui/dr-ui/src/library.rs#L1155), [`ui/dr-ui/src/library.rs:2255`](../ui/dr-ui/src/library.rs#L2255), [`ui/dr-ui/src/library.rs:584`](../ui/dr-ui/src/library.rs#L584), [`ui/dr-ui/src/library.rs:899`](../ui/dr-ui/src/library.rs#L899), [`ui/dr-ui/src/library_ui.rs:1983`](../ui/dr-ui/src/library_ui.rs#L1983), [`ui/dr-ui/src/library_ui.rs:3982`](../ui/dr-ui/src/library_ui.rs#L3982), [`ui/dr-ui/src/library_ui.rs:586`](../ui/dr-ui/src/library_ui.rs#L586), [`ui/dr-ui/src/sidecar_cache.rs:1`](../ui/dr-ui/src/sidecar_cache.rs#L1) | | FR-NC-12 | [`core/dr-sync-folder/src/lib.rs:1`](../core/dr-sync-folder/src/lib.rs#L1), [`core/dr-sync-nextcloud/src/lib.rs:40`](../core/dr-sync-nextcloud/src/lib.rs#L40), [`core/dr-sync-nextcloud/src/lib.rs:914`](../core/dr-sync-nextcloud/src/lib.rs#L914), [`core/dr-sync-nextcloud/src/provider.rs:1`](../core/dr-sync-nextcloud/src/provider.rs#L1), [`core/dr-sync/src/account.rs:1`](../core/dr-sync/src/account.rs#L1), [`core/dr-sync/src/account.rs:81`](../core/dr-sync/src/account.rs#L81), [`core/dr-sync/src/lib.rs:218`](../core/dr-sync/src/lib.rs#L218), [`core/dr-sync/src/lib.rs:51`](../core/dr-sync/src/lib.rs#L51), [`core/dr-sync/src/provider.rs:106`](../core/dr-sync/src/provider.rs#L106), [`core/dr-sync/src/provider.rs:1`](../core/dr-sync/src/provider.rs#L1), [`core/dr-sync/src/provider.rs:53`](../core/dr-sync/src/provider.rs#L53), [`core/dr-sync/src/reachability.rs:1`](../core/dr-sync/src/reachability.rs#L1), [`ui/dr-ui/src/remote.rs:1`](../ui/dr-ui/src/remote.rs#L1) | | FR-NC-13 | [`core/dr-sync-folder/src/lib.rs:197`](../core/dr-sync-folder/src/lib.rs#L197), [`core/dr-sync-folder/src/lib.rs:1`](../core/dr-sync-folder/src/lib.rs#L1), [`core/dr-sync-folder/src/lib.rs:73`](../core/dr-sync-folder/src/lib.rs#L73), [`core/dr-sync/src/provider.rs:106`](../core/dr-sync/src/provider.rs#L106), [`ui/dr-ui/src/launch_ui.rs:316`](../ui/dr-ui/src/launch_ui.rs#L316), [`ui/dr-ui/src/remote.rs:1`](../ui/dr-ui/src/remote.rs#L1) | | FR-NC-2 | [`core/dr-sync/src/account.rs:1`](../core/dr-sync/src/account.rs#L1), [`core/dr-sync/src/account.rs:298`](../core/dr-sync/src/account.rs#L298), [`core/dr-sync/src/account.rs:355`](../core/dr-sync/src/account.rs#L355), [`core/dr-sync/src/account.rs:59`](../core/dr-sync/src/account.rs#L59), [`platform/dr-plat/src/secrets.rs:82`](../platform/dr-plat/src/secrets.rs#L82) | -| FR-NC-3 | [`core/dr-decode/src/locate.rs:1`](../core/dr-decode/src/locate.rs#L1), [`core/dr-decode/src/preview.rs:148`](../core/dr-decode/src/preview.rs#L148), [`core/dr-sync/src/capability.rs:85`](../core/dr-sync/src/capability.rs#L85), [`core/dr-thumbs/src/lib.rs:1`](../core/dr-thumbs/src/lib.rs#L1), [`core/dr-types/src/place.rs:1`](../core/dr-types/src/place.rs#L1), [`ui/dr-ui/src/library.rs:1`](../ui/dr-ui/src/library.rs#L1), [`ui/dr-ui/src/library.rs:3292`](../ui/dr-ui/src/library.rs#L3292), [`ui/dr-ui/src/library.rs:3883`](../ui/dr-ui/src/library.rs#L3883), [`ui/dr-ui/src/library_ui.rs:1`](../ui/dr-ui/src/library_ui.rs#L1), [`ui/dr-ui/src/library_ui.rs:4235`](../ui/dr-ui/src/library_ui.rs#L4235), [`ui/dr-ui/src/library_ui.rs:5734`](../ui/dr-ui/src/library_ui.rs#L5734), [`ui/dr-ui/ui/app.slint:466`](../ui/dr-ui/ui/app.slint#L466), [`ui/dr-ui/ui/settings.slint:395`](../ui/dr-ui/ui/settings.slint#L395), [`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), [`core/dr-types/src/place.rs:1`](../core/dr-types/src/place.rs#L1), [`ui/dr-ui/src/library.rs:1`](../ui/dr-ui/src/library.rs#L1), [`ui/dr-ui/src/library.rs:3292`](../ui/dr-ui/src/library.rs#L3292), [`ui/dr-ui/src/library.rs:3883`](../ui/dr-ui/src/library.rs#L3883), [`ui/dr-ui/src/library_ui.rs:1`](../ui/dr-ui/src/library_ui.rs#L1), [`ui/dr-ui/src/library_ui.rs:4235`](../ui/dr-ui/src/library_ui.rs#L4235), [`ui/dr-ui/src/library_ui.rs:5734`](../ui/dr-ui/src/library_ui.rs#L5734), [`ui/dr-ui/ui/app.slint:490`](../ui/dr-ui/ui/app.slint#L490), [`ui/dr-ui/ui/settings.slint:395`](../ui/dr-ui/ui/settings.slint#L395), [`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:118`](../core/dr-sync/src/scan.rs#L118), [`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:1186`](../core/dr-catalog/src/schema.rs#L1186), [`core/dr-catalog/src/schema.rs:785`](../core/dr-catalog/src/schema.rs#L785), [`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:3413`](../ui/dr-ui/src/collections_ui.rs#L3413), [`ui/dr-ui/src/collections_ui.rs:636`](../ui/dr-ui/src/collections_ui.rs#L636), [`ui/dr-ui/src/collections_ui.rs:704`](../ui/dr-ui/src/collections_ui.rs#L704), [`ui/dr-ui/src/lib.rs:2241`](../ui/dr-ui/src/lib.rs#L2241), [`ui/dr-ui/src/lib.rs:3443`](../ui/dr-ui/src/lib.rs#L3443), [`ui/dr-ui/src/library.rs:1881`](../ui/dr-ui/src/library.rs#L1881), [`ui/dr-ui/src/library.rs:1904`](../ui/dr-ui/src/library.rs#L1904), [`ui/dr-ui/src/library.rs:2179`](../ui/dr-ui/src/library.rs#L2179), [`ui/dr-ui/src/library_ui.rs:1408`](../ui/dr-ui/src/library_ui.rs#L1408), [`ui/dr-ui/src/library_ui.rs:1481`](../ui/dr-ui/src/library_ui.rs#L1481), [`ui/dr-ui/src/library_ui.rs:1582`](../ui/dr-ui/src/library_ui.rs#L1582), [`ui/dr-ui/src/library_ui.rs:1637`](../ui/dr-ui/src/library_ui.rs#L1637), [`ui/dr-ui/src/library_ui.rs:1772`](../ui/dr-ui/src/library_ui.rs#L1772), [`ui/dr-ui/src/library_ui.rs:1890`](../ui/dr-ui/src/library_ui.rs#L1890), [`ui/dr-ui/src/library_ui.rs:2657`](../ui/dr-ui/src/library_ui.rs#L2657), [`ui/dr-ui/src/library_ui.rs:341`](../ui/dr-ui/src/library_ui.rs#L341), [`ui/dr-ui/src/library_ui.rs:352`](../ui/dr-ui/src/library_ui.rs#L352), [`ui/dr-ui/src/library_ui.rs:360`](../ui/dr-ui/src/library_ui.rs#L360), [`ui/dr-ui/src/library_ui.rs:372`](../ui/dr-ui/src/library_ui.rs#L372), [`ui/dr-ui/src/library_ui.rs:381`](../ui/dr-ui/src/library_ui.rs#L381), [`ui/dr-ui/src/library_ui.rs:482`](../ui/dr-ui/src/library_ui.rs#L482), [`ui/dr-ui/src/library_ui.rs:492`](../ui/dr-ui/src/library_ui.rs#L492), [`ui/dr-ui/src/library_ui.rs:539`](../ui/dr-ui/src/library_ui.rs#L539), [`ui/dr-ui/src/library_ui.rs:602`](../ui/dr-ui/src/library_ui.rs#L602), [`ui/dr-ui/src/library_ui.rs:633`](../ui/dr-ui/src/library_ui.rs#L633), [`ui/dr-ui/src/library_ui.rs:645`](../ui/dr-ui/src/library_ui.rs#L645), [`ui/dr-ui/src/library_ui.rs:6536`](../ui/dr-ui/src/library_ui.rs#L6536), [`ui/dr-ui/src/library_ui.rs:6554`](../ui/dr-ui/src/library_ui.rs#L6554), [`ui/dr-ui/src/library_ui.rs:6566`](../ui/dr-ui/src/library_ui.rs#L6566), [`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:1567`](../ui/dr-ui/ui/app.slint#L1567), [`ui/dr-ui/ui/app.slint:2897`](../ui/dr-ui/ui/app.slint#L2897), [`ui/dr-ui/ui/app.slint:598`](../ui/dr-ui/ui/app.slint#L598), [`ui/dr-ui/ui/collections.slint:249`](../ui/dr-ui/ui/collections.slint#L249), [`ui/dr-ui/ui/collections.slint:360`](../ui/dr-ui/ui/collections.slint#L360), [`ui/dr-ui/ui/collections.slint:369`](../ui/dr-ui/ui/collections.slint#L369), [`ui/dr-ui/ui/collections.slint:372`](../ui/dr-ui/ui/collections.slint#L372), [`ui/dr-ui/ui/collections.slint:395`](../ui/dr-ui/ui/collections.slint#L395), [`ui/dr-ui/ui/collections.slint:52`](../ui/dr-ui/ui/collections.slint#L52), [`ui/dr-ui/ui/collections.slint:596`](../ui/dr-ui/ui/collections.slint#L596), [`ui/dr-ui/ui/collections.slint:747`](../ui/dr-ui/ui/collections.slint#L747), [`ui/dr-ui/ui/collections.slint:84`](../ui/dr-ui/ui/collections.slint#L84), [`ui/dr-ui/ui/icons.slint:261`](../ui/dr-ui/ui/icons.slint#L261) | +| 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:1186`](../core/dr-catalog/src/schema.rs#L1186), [`core/dr-catalog/src/schema.rs:785`](../core/dr-catalog/src/schema.rs#L785), [`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:3413`](../ui/dr-ui/src/collections_ui.rs#L3413), [`ui/dr-ui/src/collections_ui.rs:636`](../ui/dr-ui/src/collections_ui.rs#L636), [`ui/dr-ui/src/collections_ui.rs:704`](../ui/dr-ui/src/collections_ui.rs#L704), [`ui/dr-ui/src/lib.rs:2246`](../ui/dr-ui/src/lib.rs#L2246), [`ui/dr-ui/src/lib.rs:3481`](../ui/dr-ui/src/lib.rs#L3481), [`ui/dr-ui/src/library.rs:1881`](../ui/dr-ui/src/library.rs#L1881), [`ui/dr-ui/src/library.rs:1904`](../ui/dr-ui/src/library.rs#L1904), [`ui/dr-ui/src/library.rs:2179`](../ui/dr-ui/src/library.rs#L2179), [`ui/dr-ui/src/library_ui.rs:1408`](../ui/dr-ui/src/library_ui.rs#L1408), [`ui/dr-ui/src/library_ui.rs:1481`](../ui/dr-ui/src/library_ui.rs#L1481), [`ui/dr-ui/src/library_ui.rs:1582`](../ui/dr-ui/src/library_ui.rs#L1582), [`ui/dr-ui/src/library_ui.rs:1637`](../ui/dr-ui/src/library_ui.rs#L1637), [`ui/dr-ui/src/library_ui.rs:1772`](../ui/dr-ui/src/library_ui.rs#L1772), [`ui/dr-ui/src/library_ui.rs:1890`](../ui/dr-ui/src/library_ui.rs#L1890), [`ui/dr-ui/src/library_ui.rs:2657`](../ui/dr-ui/src/library_ui.rs#L2657), [`ui/dr-ui/src/library_ui.rs:341`](../ui/dr-ui/src/library_ui.rs#L341), [`ui/dr-ui/src/library_ui.rs:352`](../ui/dr-ui/src/library_ui.rs#L352), [`ui/dr-ui/src/library_ui.rs:360`](../ui/dr-ui/src/library_ui.rs#L360), [`ui/dr-ui/src/library_ui.rs:372`](../ui/dr-ui/src/library_ui.rs#L372), [`ui/dr-ui/src/library_ui.rs:381`](../ui/dr-ui/src/library_ui.rs#L381), [`ui/dr-ui/src/library_ui.rs:482`](../ui/dr-ui/src/library_ui.rs#L482), [`ui/dr-ui/src/library_ui.rs:492`](../ui/dr-ui/src/library_ui.rs#L492), [`ui/dr-ui/src/library_ui.rs:539`](../ui/dr-ui/src/library_ui.rs#L539), [`ui/dr-ui/src/library_ui.rs:602`](../ui/dr-ui/src/library_ui.rs#L602), [`ui/dr-ui/src/library_ui.rs:633`](../ui/dr-ui/src/library_ui.rs#L633), [`ui/dr-ui/src/library_ui.rs:645`](../ui/dr-ui/src/library_ui.rs#L645), [`ui/dr-ui/src/library_ui.rs:6536`](../ui/dr-ui/src/library_ui.rs#L6536), [`ui/dr-ui/src/library_ui.rs:6554`](../ui/dr-ui/src/library_ui.rs#L6554), [`ui/dr-ui/src/library_ui.rs:6566`](../ui/dr-ui/src/library_ui.rs#L6566), [`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:1591`](../ui/dr-ui/ui/app.slint#L1591), [`ui/dr-ui/ui/app.slint:2969`](../ui/dr-ui/ui/app.slint#L2969), [`ui/dr-ui/ui/app.slint:622`](../ui/dr-ui/ui/app.slint#L622), [`ui/dr-ui/ui/collections.slint:249`](../ui/dr-ui/ui/collections.slint#L249), [`ui/dr-ui/ui/collections.slint:360`](../ui/dr-ui/ui/collections.slint#L360), [`ui/dr-ui/ui/collections.slint:369`](../ui/dr-ui/ui/collections.slint#L369), [`ui/dr-ui/ui/collections.slint:372`](../ui/dr-ui/ui/collections.slint#L372), [`ui/dr-ui/ui/collections.slint:395`](../ui/dr-ui/ui/collections.slint#L395), [`ui/dr-ui/ui/collections.slint:52`](../ui/dr-ui/ui/collections.slint#L52), [`ui/dr-ui/ui/collections.slint:596`](../ui/dr-ui/ui/collections.slint#L596), [`ui/dr-ui/ui/collections.slint:747`](../ui/dr-ui/ui/collections.slint#L747), [`ui/dr-ui/ui/collections.slint:84`](../ui/dr-ui/ui/collections.slint#L84), [`ui/dr-ui/ui/icons.slint:261`](../ui/dr-ui/ui/icons.slint#L261) | | FR-NC-6b | [`ui/dr-ui/src/library_ui.rs:1637`](../ui/dr-ui/src/library_ui.rs#L1637), [`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:122`](../core/dr-types/src/lib.rs#L122), [`core/dr-types/src/lib.rs:204`](../core/dr-types/src/lib.rs#L204), [`ui/dr-ui/src/activity.rs:1`](../ui/dr-ui/src/activity.rs#L1), [`ui/dr-ui/src/collections_ui.rs:3413`](../ui/dr-ui/src/collections_ui.rs#L3413), [`ui/dr-ui/src/collections_ui.rs:636`](../ui/dr-ui/src/collections_ui.rs#L636), [`ui/dr-ui/src/collections_ui.rs:704`](../ui/dr-ui/src/collections_ui.rs#L704), [`ui/dr-ui/src/derived_sync.rs:585`](../ui/dr-ui/src/derived_sync.rs#L585), [`ui/dr-ui/src/derived_sync.rs:805`](../ui/dr-ui/src/derived_sync.rs#L805), [`ui/dr-ui/src/library.rs:1003`](../ui/dr-ui/src/library.rs#L1003), [`ui/dr-ui/src/library.rs:2001`](../ui/dr-ui/src/library.rs#L2001), [`ui/dr-ui/src/library.rs:2091`](../ui/dr-ui/src/library.rs#L2091), [`ui/dr-ui/src/library.rs:3569`](../ui/dr-ui/src/library.rs#L3569), [`ui/dr-ui/src/library.rs:4003`](../ui/dr-ui/src/library.rs#L4003), [`ui/dr-ui/src/library_ui.rs:1408`](../ui/dr-ui/src/library_ui.rs#L1408), [`ui/dr-ui/src/library_ui.rs:1481`](../ui/dr-ui/src/library_ui.rs#L1481), [`ui/dr-ui/src/library_ui.rs:1680`](../ui/dr-ui/src/library_ui.rs#L1680), [`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:747`](../ui/dr-ui/ui/collections.slint#L747), [`ui/dr-ui/ui/icons.slint:261`](../ui/dr-ui/ui/icons.slint#L261) | | FR-NC-6d | [`core/dr-sync-folder/src/borrow.rs:1`](../core/dr-sync-folder/src/borrow.rs#L1), [`core/dr-sync-folder/src/lib.rs:1`](../core/dr-sync-folder/src/lib.rs#L1), [`core/dr-sync-folder/src/vfs.rs:1`](../core/dr-sync-folder/src/vfs.rs#L1) | | FR-NC-7 | [`core/dr-catalog/src/face_shard.rs:1`](../core/dr-catalog/src/face_shard.rs#L1), [`core/dr-sync-nextcloud/src/lib.rs:105`](../core/dr-sync-nextcloud/src/lib.rs#L105), [`ui/dr-ui/src/derived_sync.rs:1`](../ui/dr-ui/src/derived_sync.rs#L1), [`ui/dr-ui/src/library.rs:3883`](../ui/dr-ui/src/library.rs#L3883), [`ui/dr-ui/src/library_ui.rs:4235`](../ui/dr-ui/src/library_ui.rs#L4235), [`ui/dr-ui/ui/settings.slint:395`](../ui/dr-ui/ui/settings.slint#L395) | -| 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:1374`](../ui/dr-ui/src/lib.rs#L1374), [`ui/dr-ui/ui/import.slint:5`](../ui/dr-ui/ui/import.slint#L5) | -| FR-NC-7b | [`core/dr-ingest/src/lib.rs:733`](../core/dr-ingest/src/lib.rs#L733), [`core/dr-sync/src/upload.rs:1`](../core/dr-sync/src/upload.rs#L1), [`ui/dr-ui/src/import.rs:122`](../ui/dr-ui/src/import.rs#L122), [`ui/dr-ui/src/import.rs:336`](../ui/dr-ui/src/import.rs#L336), [`ui/dr-ui/src/import.rs:584`](../ui/dr-ui/src/import.rs#L584), [`ui/dr-ui/src/import.rs:97`](../ui/dr-ui/src/import.rs#L97), [`ui/dr-ui/src/import_ui.rs:1`](../ui/dr-ui/src/import_ui.rs#L1), [`ui/dr-ui/src/lib.rs:1374`](../ui/dr-ui/src/lib.rs#L1374) | -| FR-NC-8 | [`core/dr-catalog/src/rating.rs:204`](../core/dr-catalog/src/rating.rs#L204), [`core/dr-catalog/src/rating.rs:66`](../core/dr-catalog/src/rating.rs#L66), [`core/dr-catalog/src/rating.rs:900`](../core/dr-catalog/src/rating.rs#L900), [`core/dr-catalog/src/schema.rs:155`](../core/dr-catalog/src/schema.rs#L155), [`core/dr-pipeline/src/sidecar.rs:120`](../core/dr-pipeline/src/sidecar.rs#L120), [`core/dr-pipeline/src/sidecar.rs:2487`](../core/dr-pipeline/src/sidecar.rs#L2487), [`core/dr-pipeline/src/sidecar.rs:619`](../core/dr-pipeline/src/sidecar.rs#L619), [`core/dr-pipeline/src/sidecar.rs:649`](../core/dr-pipeline/src/sidecar.rs#L649), [`core/dr-pipeline/src/sidecar.rs:94`](../core/dr-pipeline/src/sidecar.rs#L94), [`ui/dr-ui/src/lib.rs:2211`](../ui/dr-ui/src/lib.rs#L2211), [`ui/dr-ui/src/library.rs:1045`](../ui/dr-ui/src/library.rs#L1045), [`ui/dr-ui/src/library.rs:2310`](../ui/dr-ui/src/library.rs#L2310), [`ui/dr-ui/src/library.rs:500`](../ui/dr-ui/src/library.rs#L500), [`ui/dr-ui/src/library.rs:7312`](../ui/dr-ui/src/library.rs#L7312), [`ui/dr-ui/src/library.rs:755`](../ui/dr-ui/src/library.rs#L755), [`ui/dr-ui/src/library_ui.rs:554`](../ui/dr-ui/src/library_ui.rs#L554), [`ui/dr-ui/src/presets.rs:288`](../ui/dr-ui/src/presets.rs#L288), [`ui/dr-ui/src/presets.rs:335`](../ui/dr-ui/src/presets.rs#L335) | +| 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:1379`](../ui/dr-ui/src/lib.rs#L1379), [`ui/dr-ui/ui/import.slint:5`](../ui/dr-ui/ui/import.slint#L5) | +| FR-NC-7b | [`core/dr-ingest/src/lib.rs:733`](../core/dr-ingest/src/lib.rs#L733), [`core/dr-sync/src/upload.rs:1`](../core/dr-sync/src/upload.rs#L1), [`ui/dr-ui/src/import.rs:122`](../ui/dr-ui/src/import.rs#L122), [`ui/dr-ui/src/import.rs:336`](../ui/dr-ui/src/import.rs#L336), [`ui/dr-ui/src/import.rs:584`](../ui/dr-ui/src/import.rs#L584), [`ui/dr-ui/src/import.rs:97`](../ui/dr-ui/src/import.rs#L97), [`ui/dr-ui/src/import_ui.rs:1`](../ui/dr-ui/src/import_ui.rs#L1), [`ui/dr-ui/src/lib.rs:1379`](../ui/dr-ui/src/lib.rs#L1379) | +| FR-NC-8 | [`core/dr-catalog/src/rating.rs:204`](../core/dr-catalog/src/rating.rs#L204), [`core/dr-catalog/src/rating.rs:66`](../core/dr-catalog/src/rating.rs#L66), [`core/dr-catalog/src/rating.rs:900`](../core/dr-catalog/src/rating.rs#L900), [`core/dr-catalog/src/schema.rs:155`](../core/dr-catalog/src/schema.rs#L155), [`core/dr-pipeline/src/sidecar.rs:120`](../core/dr-pipeline/src/sidecar.rs#L120), [`core/dr-pipeline/src/sidecar.rs:2487`](../core/dr-pipeline/src/sidecar.rs#L2487), [`core/dr-pipeline/src/sidecar.rs:619`](../core/dr-pipeline/src/sidecar.rs#L619), [`core/dr-pipeline/src/sidecar.rs:649`](../core/dr-pipeline/src/sidecar.rs#L649), [`core/dr-pipeline/src/sidecar.rs:94`](../core/dr-pipeline/src/sidecar.rs#L94), [`ui/dr-ui/src/lib.rs:2216`](../ui/dr-ui/src/lib.rs#L2216), [`ui/dr-ui/src/library.rs:1045`](../ui/dr-ui/src/library.rs#L1045), [`ui/dr-ui/src/library.rs:2310`](../ui/dr-ui/src/library.rs#L2310), [`ui/dr-ui/src/library.rs:500`](../ui/dr-ui/src/library.rs#L500), [`ui/dr-ui/src/library.rs:7312`](../ui/dr-ui/src/library.rs#L7312), [`ui/dr-ui/src/library.rs:755`](../ui/dr-ui/src/library.rs#L755), [`ui/dr-ui/src/library_ui.rs:554`](../ui/dr-ui/src/library_ui.rs#L554), [`ui/dr-ui/src/presets.rs:288`](../ui/dr-ui/src/presets.rs#L288), [`ui/dr-ui/src/presets.rs:335`](../ui/dr-ui/src/presets.rs#L335) | | FR-NC-9 | [`core/dr-catalog/src/merge.rs:1`](../core/dr-catalog/src/merge.rs#L1), [`core/dr-catalog/src/rating.rs:204`](../core/dr-catalog/src/rating.rs#L204), [`core/dr-catalog/src/rating.rs:66`](../core/dr-catalog/src/rating.rs#L66), [`core/dr-catalog/src/rating.rs:900`](../core/dr-catalog/src/rating.rs#L900), [`core/dr-catalog/src/schema.rs:155`](../core/dr-catalog/src/schema.rs#L155), [`core/dr-catalog/src/schema.rs:532`](../core/dr-catalog/src/schema.rs#L532), [`core/dr-catalog/src/schema.rs:728`](../core/dr-catalog/src/schema.rs#L728), [`core/dr-catalog/src/sync.rs:1`](../core/dr-catalog/src/sync.rs#L1), [`core/dr-pipeline/src/sidecar.rs:158`](../core/dr-pipeline/src/sidecar.rs#L158), [`core/dr-pipeline/src/sidecar.rs:185`](../core/dr-pipeline/src/sidecar.rs#L185), [`core/dr-pipeline/src/sidecar.rs:2253`](../core/dr-pipeline/src/sidecar.rs#L2253), [`core/dr-pipeline/src/sidecar.rs:2487`](../core/dr-pipeline/src/sidecar.rs#L2487), [`core/dr-pipeline/src/sidecar.rs:354`](../core/dr-pipeline/src/sidecar.rs#L354), [`core/dr-pipeline/src/sidecar.rs:452`](../core/dr-pipeline/src/sidecar.rs#L452), [`core/dr-pipeline/src/sidecar.rs:619`](../core/dr-pipeline/src/sidecar.rs#L619), [`core/dr-pipeline/src/sidecar.rs:649`](../core/dr-pipeline/src/sidecar.rs#L649), [`core/dr-pipeline/src/spot.rs:245`](../core/dr-pipeline/src/spot.rs#L245), [`core/dr-pipeline/tests/mask_sidecar.rs:1055`](../core/dr-pipeline/tests/mask_sidecar.rs#L1055), [`core/dr-pipeline/tests/spot_sidecar.rs:1`](../core/dr-pipeline/tests/spot_sidecar.rs#L1), [`core/dr-sync/src/scan.rs:31`](../core/dr-sync/src/scan.rs#L31), [`core/dr-sync/src/scan.rs:45`](../core/dr-sync/src/scan.rs#L45), [`core/dr-sync/src/scan.rs:912`](../core/dr-sync/src/scan.rs#L912), [`ui/dr-ui/src/derived_sync.rs:585`](../ui/dr-ui/src/derived_sync.rs#L585), [`ui/dr-ui/src/library.rs:1045`](../ui/dr-ui/src/library.rs#L1045), [`ui/dr-ui/src/library.rs:1065`](../ui/dr-ui/src/library.rs#L1065), [`ui/dr-ui/src/library.rs:1376`](../ui/dr-ui/src/library.rs#L1376), [`ui/dr-ui/src/library.rs:1411`](../ui/dr-ui/src/library.rs#L1411), [`ui/dr-ui/src/library.rs:2310`](../ui/dr-ui/src/library.rs#L2310), [`ui/dr-ui/src/library.rs:7144`](../ui/dr-ui/src/library.rs#L7144), [`ui/dr-ui/src/library.rs:7312`](../ui/dr-ui/src/library.rs#L7312), [`ui/dr-ui/src/library.rs:73`](../ui/dr-ui/src/library.rs#L73), [`ui/dr-ui/src/library.rs:755`](../ui/dr-ui/src/library.rs#L755), [`ui/dr-ui/src/library.rs:899`](../ui/dr-ui/src/library.rs#L899), [`ui/dr-ui/src/library_ui.rs:1265`](../ui/dr-ui/src/library_ui.rs#L1265), [`ui/dr-ui/src/presets.rs:288`](../ui/dr-ui/src/presets.rs#L288), [`ui/dr-ui/src/presets.rs:335`](../ui/dr-ui/src/presets.rs#L335) | | FR-PLAT-AND-2 | [`core/dr-catalog/src/walk.rs:1022`](../core/dr-catalog/src/walk.rs#L1022), [`core/dr-catalog/src/walk.rs:435`](../core/dr-catalog/src/walk.rs#L435), [`core/dr-sync-folder/src/lib.rs:242`](../core/dr-sync-folder/src/lib.rs#L242), [`core/dr-sync-folder/src/tests.rs:51`](../core/dr-sync-folder/src/tests.rs#L51), [`core/dr-sync/src/error.rs:113`](../core/dr-sync/src/error.rs#L113), [`core/dr-sync/src/error.rs:195`](../core/dr-sync/src/error.rs#L195), [`core/dr-sync/src/scan.rs:200`](../core/dr-sync/src/scan.rs#L200), [`core/dr-sync/src/scan.rs:505`](../core/dr-sync/src/scan.rs#L505), [`core/dr-sync/src/scan.rs:531`](../core/dr-sync/src/scan.rs#L531), [`core/dr-sync/src/scan.rs:560`](../core/dr-sync/src/scan.rs#L560), [`ui/dr-ui/src/library.rs:1276`](../ui/dr-ui/src/library.rs#L1276), [`ui/dr-ui/src/library.rs:1329`](../ui/dr-ui/src/library.rs#L1329), [`ui/dr-ui/src/library.rs:1360`](../ui/dr-ui/src/library.rs#L1360), [`ui/dr-ui/src/library.rs:1727`](../ui/dr-ui/src/library.rs#L1727), [`ui/dr-ui/src/library_ui.rs:1241`](../ui/dr-ui/src/library_ui.rs#L1241), [`ui/dr-ui/src/library_ui.rs:1332`](../ui/dr-ui/src/library_ui.rs#L1332), [`ui/dr-ui/src/library_ui.rs:1931`](../ui/dr-ui/src/library_ui.rs#L1931), [`ui/dr-ui/src/library_ui.rs:325`](../ui/dr-ui/src/library_ui.rs#L325), [`ui/dr-ui/src/library_ui.rs:523`](../ui/dr-ui/src/library_ui.rs#L523) | | FR-PLAT-AND-3 | [`core/dr-catalog/src/jobs.rs:1`](../core/dr-catalog/src/jobs.rs#L1), [`core/dr-catalog/src/runner.rs:1`](../core/dr-catalog/src/runner.rs#L1) | | FR-PLAT-AND-4 | [`core/dr-catalog/src/runner.rs:1`](../core/dr-catalog/src/runner.rs#L1) | -| FR-PLAT-AND-5 | [`apps/darkroom-android/src/lib.rs:166`](../apps/darkroom-android/src/lib.rs#L166), [`core/dr-gpu/src/adjust.rs:1029`](../core/dr-gpu/src/adjust.rs#L1029), [`core/dr-gpu/src/detail.rs:161`](../core/dr-gpu/src/detail.rs#L161), [`core/dr-gpu/src/detail.rs:547`](../core/dr-gpu/src/detail.rs#L547), [`core/dr-gpu/tests/detail_stage.rs:417`](../core/dr-gpu/tests/detail_stage.rs#L417), [`ui/dr-ui/src/develop.rs:3524`](../ui/dr-ui/src/develop.rs#L3524), [`ui/dr-ui/src/identity_ui.rs:121`](../ui/dr-ui/src/identity_ui.rs#L121), [`ui/dr-ui/src/lib.rs:1193`](../ui/dr-ui/src/lib.rs#L1193), [`ui/dr-ui/src/lib.rs:1642`](../ui/dr-ui/src/lib.rs#L1642), [`ui/dr-ui/src/memory.rs:163`](../ui/dr-ui/src/memory.rs#L163), [`ui/dr-ui/src/memory.rs:1`](../ui/dr-ui/src/memory.rs#L1) | +| FR-PLAT-AND-5 | [`apps/darkroom-android/src/lib.rs:166`](../apps/darkroom-android/src/lib.rs#L166), [`core/dr-gpu/src/adjust.rs:1029`](../core/dr-gpu/src/adjust.rs#L1029), [`core/dr-gpu/src/detail.rs:161`](../core/dr-gpu/src/detail.rs#L161), [`core/dr-gpu/src/detail.rs:547`](../core/dr-gpu/src/detail.rs#L547), [`core/dr-gpu/tests/detail_stage.rs:417`](../core/dr-gpu/tests/detail_stage.rs#L417), [`ui/dr-ui/src/develop.rs:3688`](../ui/dr-ui/src/develop.rs#L3688), [`ui/dr-ui/src/identity_ui.rs:121`](../ui/dr-ui/src/identity_ui.rs#L121), [`ui/dr-ui/src/lib.rs:1198`](../ui/dr-ui/src/lib.rs#L1198), [`ui/dr-ui/src/lib.rs:1647`](../ui/dr-ui/src/lib.rs#L1647), [`ui/dr-ui/src/memory.rs:163`](../ui/dr-ui/src/memory.rs#L163), [`ui/dr-ui/src/memory.rs:1`](../ui/dr-ui/src/memory.rs#L1) | | FR-PLAT-AND-6 | [`apps/darkroom-android/src/lib.rs:388`](../apps/darkroom-android/src/lib.rs#L388) | -| FR-PLAT-LIN-1 | [`core/dr-types/src/settings.rs:1`](../core/dr-types/src/settings.rs#L1), [`platform/dr-plat/src/storage.rs:344`](../platform/dr-plat/src/storage.rs#L344), [`ui/dr-ui/src/lib.rs:1069`](../ui/dr-ui/src/lib.rs#L1069), [`ui/dr-ui/src/preset_store.rs:1`](../ui/dr-ui/src/preset_store.rs#L1), [`ui/dr-ui/src/settings_store.rs:1`](../ui/dr-ui/src/settings_store.rs#L1) | +| FR-PLAT-LIN-1 | [`core/dr-types/src/settings.rs:1`](../core/dr-types/src/settings.rs#L1), [`platform/dr-plat/src/storage.rs:344`](../platform/dr-plat/src/storage.rs#L344), [`ui/dr-ui/src/lib.rs:1074`](../ui/dr-ui/src/lib.rs#L1074), [`ui/dr-ui/src/preset_store.rs:1`](../ui/dr-ui/src/preset_store.rs#L1), [`ui/dr-ui/src/settings_store.rs:1`](../ui/dr-ui/src/settings_store.rs#L1) | | FR-PLAT-LIN-2 | [`platform/dr-plat/src/display.rs:1`](../platform/dr-plat/src/display.rs#L1), [`platform/dr-plat/src/display/wayland.rs:1`](../platform/dr-plat/src/display/wayland.rs#L1), [`platform/dr-plat/src/display/x11.rs:1`](../platform/dr-plat/src/display/x11.rs#L1) | -| FR-PLG-2 | [`core/dr-pipeline/src/declared/decl.rs:1`](../core/dr-pipeline/src/declared/decl.rs#L1), [`core/dr-pipeline/src/declared/expr.rs:152`](../core/dr-pipeline/src/declared/expr.rs#L152), [`core/dr-pipeline/src/declared/expr.rs:1`](../core/dr-pipeline/src/declared/expr.rs#L1), [`core/dr-pipeline/src/declared/mod.rs:1`](../core/dr-pipeline/src/declared/mod.rs#L1), [`core/dr-pipeline/src/declared/mod.rs:82`](../core/dr-pipeline/src/declared/mod.rs#L82), [`core/dr-pipeline/src/descriptor.rs:15`](../core/dr-pipeline/src/descriptor.rs#L15), [`core/dr-pipeline/src/descriptor.rs:674`](../core/dr-pipeline/src/descriptor.rs#L674), [`core/dr-pipeline/src/operation.rs:232`](../core/dr-pipeline/src/operation.rs#L232), [`core/dr-pipeline/tests/declared_parity.rs:1`](../core/dr-pipeline/tests/declared_parity.rs#L1), [`core/dr-pipeline/tests/declared_parity.rs:240`](../core/dr-pipeline/tests/declared_parity.rs#L240), [`core/dr-pipeline/tests/declared_parity.rs:305`](../core/dr-pipeline/tests/declared_parity.rs#L305), [`core/dr-pipeline/tests/declared_parity.rs:358`](../core/dr-pipeline/tests/declared_parity.rs#L358), [`core/dr-pipeline/tests/declared_parity.rs:417`](../core/dr-pipeline/tests/declared_parity.rs#L417) | +| FR-PLG-2 | [`core/dr-pipeline/src/declared/decl.rs:1`](../core/dr-pipeline/src/declared/decl.rs#L1), [`core/dr-pipeline/src/declared/expr.rs:152`](../core/dr-pipeline/src/declared/expr.rs#L152), [`core/dr-pipeline/src/declared/expr.rs:1`](../core/dr-pipeline/src/declared/expr.rs#L1), [`core/dr-pipeline/src/declared/mod.rs:1`](../core/dr-pipeline/src/declared/mod.rs#L1), [`core/dr-pipeline/src/declared/mod.rs:82`](../core/dr-pipeline/src/declared/mod.rs#L82), [`core/dr-pipeline/src/descriptor.rs:15`](../core/dr-pipeline/src/descriptor.rs#L15), [`core/dr-pipeline/src/descriptor.rs:692`](../core/dr-pipeline/src/descriptor.rs#L692), [`core/dr-pipeline/src/operation.rs:232`](../core/dr-pipeline/src/operation.rs#L232), [`core/dr-pipeline/tests/declared_parity.rs:1`](../core/dr-pipeline/tests/declared_parity.rs#L1), [`core/dr-pipeline/tests/declared_parity.rs:240`](../core/dr-pipeline/tests/declared_parity.rs#L240), [`core/dr-pipeline/tests/declared_parity.rs:305`](../core/dr-pipeline/tests/declared_parity.rs#L305), [`core/dr-pipeline/tests/declared_parity.rs:358`](../core/dr-pipeline/tests/declared_parity.rs#L358), [`core/dr-pipeline/tests/declared_parity.rs:417`](../core/dr-pipeline/tests/declared_parity.rs#L417) | | FR-PLG-2d | [`core/dr-pipeline/src/declared/decl.rs:112`](../core/dr-pipeline/src/declared/decl.rs#L112), [`core/dr-pipeline/src/declared/decl.rs:152`](../core/dr-pipeline/src/declared/decl.rs#L152), [`core/dr-pipeline/src/declared/decl.rs:1`](../core/dr-pipeline/src/declared/decl.rs#L1), [`core/dr-pipeline/src/declared/decl.rs:420`](../core/dr-pipeline/src/declared/decl.rs#L420), [`core/dr-pipeline/src/declared/decl.rs:67`](../core/dr-pipeline/src/declared/decl.rs#L67), [`core/dr-pipeline/src/declared/mod.rs:1`](../core/dr-pipeline/src/declared/mod.rs#L1), [`core/dr-pipeline/src/declared/mod.rs:384`](../core/dr-pipeline/src/declared/mod.rs#L384), [`core/dr-pipeline/src/declared/mod.rs:403`](../core/dr-pipeline/src/declared/mod.rs#L403) | | FR-PLG-8 | [`core/dr-pipeline/src/sidecar.rs:2011`](../core/dr-pipeline/src/sidecar.rs#L2011), [`core/dr-pipeline/src/sidecar.rs:2044`](../core/dr-pipeline/src/sidecar.rs#L2044) | | FR-RAW-1 | [`core/dr-decode/src/lib.rs:243`](../core/dr-decode/src/lib.rs#L243), [`core/dr-types/src/lib.rs:132`](../core/dr-types/src/lib.rs#L132), [`core/dr-types/src/lib.rs:203`](../core/dr-types/src/lib.rs#L203) | | 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:232`](../ui/dr-ui/src/lib.rs#L232) | | 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 | [`core/dr-types/src/settings.rs:1166`](../core/dr-types/src/settings.rs#L1166), [`core/dr-types/src/settings.rs:321`](../core/dr-types/src/settings.rs#L321), [`core/dr-types/src/settings.rs:341`](../core/dr-types/src/settings.rs#L341), [`ui/dr-ui/src/lib.rs:101`](../ui/dr-ui/src/lib.rs#L101), [`ui/dr-ui/src/lib.rs:108`](../ui/dr-ui/src/lib.rs#L108), [`ui/dr-ui/src/lib.rs:2455`](../ui/dr-ui/src/lib.rs#L2455), [`ui/dr-ui/src/lib.rs:3525`](../ui/dr-ui/src/lib.rs#L3525), [`ui/dr-ui/src/lib.rs:3544`](../ui/dr-ui/src/lib.rs#L3544), [`ui/dr-ui/src/masks_ui.rs:884`](../ui/dr-ui/src/masks_ui.rs#L884), [`ui/dr-ui/src/settings_ui.rs:160`](../ui/dr-ui/src/settings_ui.rs#L160), [`ui/dr-ui/ui/app.slint:2429`](../ui/dr-ui/ui/app.slint#L2429), [`ui/dr-ui/ui/app.slint:760`](../ui/dr-ui/ui/app.slint#L760), [`ui/dr-ui/ui/app.slint:929`](../ui/dr-ui/ui/app.slint#L929), [`ui/dr-ui/ui/identity.slint:188`](../ui/dr-ui/ui/identity.slint#L188), [`ui/dr-ui/ui/library.slint:1071`](../ui/dr-ui/ui/library.slint#L1071), [`ui/dr-ui/ui/settings.slint:104`](../ui/dr-ui/ui/settings.slint#L104), [`ui/dr-ui/ui/settings.slint:565`](../ui/dr-ui/ui/settings.slint#L565), [`ui/dr-ui/ui/toolrail.slint:156`](../ui/dr-ui/ui/toolrail.slint#L156), [`ui/dr-ui/ui/toolrail.slint:89`](../ui/dr-ui/ui/toolrail.slint#L89) | -| FR-UI-2 | [`ui/dr-ui/src/collections_ui.rs:1045`](../ui/dr-ui/src/collections_ui.rs#L1045), [`ui/dr-ui/src/collections_ui.rs:1055`](../ui/dr-ui/src/collections_ui.rs#L1055), [`ui/dr-ui/src/collections_ui.rs:116`](../ui/dr-ui/src/collections_ui.rs#L116), [`ui/dr-ui/src/collections_ui.rs:154`](../ui/dr-ui/src/collections_ui.rs#L154), [`ui/dr-ui/src/collections_ui.rs:1552`](../ui/dr-ui/src/collections_ui.rs#L1552), [`ui/dr-ui/src/collections_ui.rs:1569`](../ui/dr-ui/src/collections_ui.rs#L1569), [`ui/dr-ui/src/collections_ui.rs:1821`](../ui/dr-ui/src/collections_ui.rs#L1821), [`ui/dr-ui/src/collections_ui.rs:2926`](../ui/dr-ui/src/collections_ui.rs#L2926), [`ui/dr-ui/src/gestures.rs:1`](../ui/dr-ui/src/gestures.rs#L1), [`ui/dr-ui/src/lib.rs:101`](../ui/dr-ui/src/lib.rs#L101), [`ui/dr-ui/src/library_ui.rs:360`](../ui/dr-ui/src/library_ui.rs#L360), [`ui/dr-ui/src/library_ui.rs:6421`](../ui/dr-ui/src/library_ui.rs#L6421), [`ui/dr-ui/src/library_ui.rs:6566`](../ui/dr-ui/src/library_ui.rs#L6566), [`ui/dr-ui/src/library_ui.rs:7781`](../ui/dr-ui/src/library_ui.rs#L7781), [`ui/dr-ui/ui/app.slint:1011`](../ui/dr-ui/ui/app.slint#L1011), [`ui/dr-ui/ui/app.slint:60`](../ui/dr-ui/ui/app.slint#L60), [`ui/dr-ui/ui/app.slint:628`](../ui/dr-ui/ui/app.slint#L628), [`ui/dr-ui/ui/app.slint:642`](../ui/dr-ui/ui/app.slint#L642), [`ui/dr-ui/ui/controls.slint:593`](../ui/dr-ui/ui/controls.slint#L593), [`ui/dr-ui/ui/gestures.slint:1`](../ui/dr-ui/ui/gestures.slint#L1), [`ui/dr-ui/ui/library.slint:1277`](../ui/dr-ui/ui/library.slint#L1277), [`ui/dr-ui/ui/library.slint:1284`](../ui/dr-ui/ui/library.slint#L1284), [`ui/dr-ui/ui/library.slint:1381`](../ui/dr-ui/ui/library.slint#L1381), [`ui/dr-ui/ui/library.slint:2565`](../ui/dr-ui/ui/library.slint#L2565), [`ui/dr-ui/ui/library.slint:4195`](../ui/dr-ui/ui/library.slint#L4195), [`ui/dr-ui/ui/library.slint:960`](../ui/dr-ui/ui/library.slint#L960), [`ui/dr-ui/ui/library.slint:993`](../ui/dr-ui/ui/library.slint#L993), [`ui/dr-ui/ui/presets.slint:19`](../ui/dr-ui/ui/presets.slint#L19), [`ui/dr-ui/ui/settings.slint:118`](../ui/dr-ui/ui/settings.slint#L118) | -| FR-UI-3 | [`ui/dr-ui/src/develop.rs:2445`](../ui/dr-ui/src/develop.rs#L2445), [`ui/dr-ui/src/develop.rs:2554`](../ui/dr-ui/src/develop.rs#L2554), [`ui/dr-ui/src/library_ui.rs:5485`](../ui/dr-ui/src/library_ui.rs#L5485), [`ui/dr-ui/src/masks_ui.rs:249`](../ui/dr-ui/src/masks_ui.rs#L249), [`ui/dr-ui/src/masks_ui.rs:976`](../ui/dr-ui/src/masks_ui.rs#L976), [`ui/dr-ui/src/masks_ui.rs:998`](../ui/dr-ui/src/masks_ui.rs#L998), [`ui/dr-ui/src/spots_ui.rs:19`](../ui/dr-ui/src/spots_ui.rs#L19), [`ui/dr-ui/ui/app.slint:2134`](../ui/dr-ui/ui/app.slint#L2134), [`ui/dr-ui/ui/collections.slint:4`](../ui/dr-ui/ui/collections.slint#L4), [`ui/dr-ui/ui/collections.slint:747`](../ui/dr-ui/ui/collections.slint#L747), [`ui/dr-ui/ui/masks.slint:612`](../ui/dr-ui/ui/masks.slint#L612), [`ui/dr-ui/ui/widgets.slint:71`](../ui/dr-ui/ui/widgets.slint#L71) | -| FR-UI-4 | [`tools/traceability/src/gestures.rs:1`](../tools/traceability/src/gestures.rs#L1), [`ui/dr-ui/src/collections_ui.rs:1045`](../ui/dr-ui/src/collections_ui.rs#L1045), [`ui/dr-ui/src/collections_ui.rs:1055`](../ui/dr-ui/src/collections_ui.rs#L1055), [`ui/dr-ui/src/collections_ui.rs:116`](../ui/dr-ui/src/collections_ui.rs#L116), [`ui/dr-ui/src/collections_ui.rs:117`](../ui/dr-ui/src/collections_ui.rs#L117), [`ui/dr-ui/src/collections_ui.rs:126`](../ui/dr-ui/src/collections_ui.rs#L126), [`ui/dr-ui/src/collections_ui.rs:154`](../ui/dr-ui/src/collections_ui.rs#L154), [`ui/dr-ui/src/collections_ui.rs:1552`](../ui/dr-ui/src/collections_ui.rs#L1552), [`ui/dr-ui/src/collections_ui.rs:1569`](../ui/dr-ui/src/collections_ui.rs#L1569), [`ui/dr-ui/src/collections_ui.rs:1685`](../ui/dr-ui/src/collections_ui.rs#L1685), [`ui/dr-ui/src/collections_ui.rs:1821`](../ui/dr-ui/src/collections_ui.rs#L1821), [`ui/dr-ui/src/collections_ui.rs:1848`](../ui/dr-ui/src/collections_ui.rs#L1848), [`ui/dr-ui/src/collections_ui.rs:1964`](../ui/dr-ui/src/collections_ui.rs#L1964), [`ui/dr-ui/src/collections_ui.rs:2926`](../ui/dr-ui/src/collections_ui.rs#L2926), [`ui/dr-ui/src/collections_ui.rs:2963`](../ui/dr-ui/src/collections_ui.rs#L2963), [`ui/dr-ui/src/collections_ui.rs:365`](../ui/dr-ui/src/collections_ui.rs#L365), [`ui/dr-ui/src/collections_ui.rs:569`](../ui/dr-ui/src/collections_ui.rs#L569), [`ui/dr-ui/src/collections_ui.rs:589`](../ui/dr-ui/src/collections_ui.rs#L589), [`ui/dr-ui/src/develop.rs:4291`](../ui/dr-ui/src/develop.rs#L4291), [`ui/dr-ui/src/develop.rs:4316`](../ui/dr-ui/src/develop.rs#L4316), [`ui/dr-ui/src/develop.rs:4327`](../ui/dr-ui/src/develop.rs#L4327), [`ui/dr-ui/src/develop.rs:4341`](../ui/dr-ui/src/develop.rs#L4341), [`ui/dr-ui/src/develop.rs:5378`](../ui/dr-ui/src/develop.rs#L5378), [`ui/dr-ui/src/develop.rs:5409`](../ui/dr-ui/src/develop.rs#L5409), [`ui/dr-ui/src/develop.rs:5430`](../ui/dr-ui/src/develop.rs#L5430), [`ui/dr-ui/src/gesture_book.rs:3`](../ui/dr-ui/src/gesture_book.rs#L3), [`ui/dr-ui/src/gestures.rs:1`](../ui/dr-ui/src/gestures.rs#L1), [`ui/dr-ui/src/lib.rs:1719`](../ui/dr-ui/src/lib.rs#L1719), [`ui/dr-ui/src/lib.rs:2125`](../ui/dr-ui/src/lib.rs#L2125), [`ui/dr-ui/src/lib.rs:2362`](../ui/dr-ui/src/lib.rs#L2362), [`ui/dr-ui/src/lib.rs:2908`](../ui/dr-ui/src/lib.rs#L2908), [`ui/dr-ui/src/lib.rs:3631`](../ui/dr-ui/src/lib.rs#L3631), [`ui/dr-ui/src/lib.rs:409`](../ui/dr-ui/src/lib.rs#L409), [`ui/dr-ui/src/lib.rs:438`](../ui/dr-ui/src/lib.rs#L438), [`ui/dr-ui/src/library_ui.rs:5485`](../ui/dr-ui/src/library_ui.rs#L5485), [`ui/dr-ui/src/library_ui.rs:5497`](../ui/dr-ui/src/library_ui.rs#L5497), [`ui/dr-ui/src/library_ui.rs:5567`](../ui/dr-ui/src/library_ui.rs#L5567), [`ui/dr-ui/src/library_ui.rs:5677`](../ui/dr-ui/src/library_ui.rs#L5677), [`ui/dr-ui/src/library_ui.rs:5705`](../ui/dr-ui/src/library_ui.rs#L5705), [`ui/dr-ui/src/library_ui.rs:6554`](../ui/dr-ui/src/library_ui.rs#L6554), [`ui/dr-ui/src/library_ui.rs:6566`](../ui/dr-ui/src/library_ui.rs#L6566), [`ui/dr-ui/ui/app.slint:1957`](../ui/dr-ui/ui/app.slint#L1957), [`ui/dr-ui/ui/app.slint:2092`](../ui/dr-ui/ui/app.slint#L2092), [`ui/dr-ui/ui/app.slint:2243`](../ui/dr-ui/ui/app.slint#L2243), [`ui/dr-ui/ui/app.slint:2343`](../ui/dr-ui/ui/app.slint#L2343), [`ui/dr-ui/ui/app.slint:251`](../ui/dr-ui/ui/app.slint#L251), [`ui/dr-ui/ui/app.slint:604`](../ui/dr-ui/ui/app.slint#L604), [`ui/dr-ui/ui/app.slint:633`](../ui/dr-ui/ui/app.slint#L633), [`ui/dr-ui/ui/app.slint:642`](../ui/dr-ui/ui/app.slint#L642), [`ui/dr-ui/ui/app.slint:727`](../ui/dr-ui/ui/app.slint#L727), [`ui/dr-ui/ui/gestures.slint:1`](../ui/dr-ui/ui/gestures.slint#L1), [`ui/dr-ui/ui/library.slint:1048`](../ui/dr-ui/ui/library.slint#L1048), [`ui/dr-ui/ui/library.slint:1252`](../ui/dr-ui/ui/library.slint#L1252), [`ui/dr-ui/ui/library.slint:1277`](../ui/dr-ui/ui/library.slint#L1277), [`ui/dr-ui/ui/library.slint:1284`](../ui/dr-ui/ui/library.slint#L1284), [`ui/dr-ui/ui/library.slint:1317`](../ui/dr-ui/ui/library.slint#L1317), [`ui/dr-ui/ui/library.slint:1374`](../ui/dr-ui/ui/library.slint#L1374), [`ui/dr-ui/ui/library.slint:1381`](../ui/dr-ui/ui/library.slint#L1381), [`ui/dr-ui/ui/library.slint:2565`](../ui/dr-ui/ui/library.slint#L2565), [`ui/dr-ui/ui/library.slint:4079`](../ui/dr-ui/ui/library.slint#L4079), [`ui/dr-ui/ui/library.slint:4195`](../ui/dr-ui/ui/library.slint#L4195), [`ui/dr-ui/ui/library.slint:960`](../ui/dr-ui/ui/library.slint#L960), [`ui/dr-ui/ui/library.slint:987`](../ui/dr-ui/ui/library.slint#L987), [`ui/dr-ui/ui/library.slint:993`](../ui/dr-ui/ui/library.slint#L993) | -| 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:2953`](../ui/dr-ui/src/lib.rs#L2953), [`ui/dr-ui/src/lib.rs:3591`](../ui/dr-ui/src/lib.rs#L3591), [`ui/dr-ui/src/lib.rs:3782`](../ui/dr-ui/src/lib.rs#L3782), [`ui/dr-ui/src/masks_ui.rs:931`](../ui/dr-ui/src/masks_ui.rs#L931), [`ui/dr-ui/ui/app.slint:127`](../ui/dr-ui/ui/app.slint#L127), [`ui/dr-ui/ui/app.slint:2243`](../ui/dr-ui/ui/app.slint#L2243), [`ui/dr-ui/ui/collections.slint:4`](../ui/dr-ui/ui/collections.slint#L4) | +| FR-UI-1 | [`core/dr-types/src/settings.rs:1166`](../core/dr-types/src/settings.rs#L1166), [`core/dr-types/src/settings.rs:321`](../core/dr-types/src/settings.rs#L321), [`core/dr-types/src/settings.rs:341`](../core/dr-types/src/settings.rs#L341), [`ui/dr-ui/src/lib.rs:101`](../ui/dr-ui/src/lib.rs#L101), [`ui/dr-ui/src/lib.rs:108`](../ui/dr-ui/src/lib.rs#L108), [`ui/dr-ui/src/lib.rs:2460`](../ui/dr-ui/src/lib.rs#L2460), [`ui/dr-ui/src/lib.rs:3563`](../ui/dr-ui/src/lib.rs#L3563), [`ui/dr-ui/src/lib.rs:3582`](../ui/dr-ui/src/lib.rs#L3582), [`ui/dr-ui/src/masks_ui.rs:884`](../ui/dr-ui/src/masks_ui.rs#L884), [`ui/dr-ui/src/settings_ui.rs:160`](../ui/dr-ui/src/settings_ui.rs#L160), [`ui/dr-ui/ui/app.slint:2490`](../ui/dr-ui/ui/app.slint#L2490), [`ui/dr-ui/ui/app.slint:784`](../ui/dr-ui/ui/app.slint#L784), [`ui/dr-ui/ui/app.slint:953`](../ui/dr-ui/ui/app.slint#L953), [`ui/dr-ui/ui/identity.slint:188`](../ui/dr-ui/ui/identity.slint#L188), [`ui/dr-ui/ui/library.slint:1071`](../ui/dr-ui/ui/library.slint#L1071), [`ui/dr-ui/ui/settings.slint:104`](../ui/dr-ui/ui/settings.slint#L104), [`ui/dr-ui/ui/settings.slint:565`](../ui/dr-ui/ui/settings.slint#L565), [`ui/dr-ui/ui/toolrail.slint:156`](../ui/dr-ui/ui/toolrail.slint#L156), [`ui/dr-ui/ui/toolrail.slint:89`](../ui/dr-ui/ui/toolrail.slint#L89) | +| FR-UI-2 | [`ui/dr-ui/src/collections_ui.rs:1045`](../ui/dr-ui/src/collections_ui.rs#L1045), [`ui/dr-ui/src/collections_ui.rs:1055`](../ui/dr-ui/src/collections_ui.rs#L1055), [`ui/dr-ui/src/collections_ui.rs:116`](../ui/dr-ui/src/collections_ui.rs#L116), [`ui/dr-ui/src/collections_ui.rs:154`](../ui/dr-ui/src/collections_ui.rs#L154), [`ui/dr-ui/src/collections_ui.rs:1552`](../ui/dr-ui/src/collections_ui.rs#L1552), [`ui/dr-ui/src/collections_ui.rs:1569`](../ui/dr-ui/src/collections_ui.rs#L1569), [`ui/dr-ui/src/collections_ui.rs:1821`](../ui/dr-ui/src/collections_ui.rs#L1821), [`ui/dr-ui/src/collections_ui.rs:2926`](../ui/dr-ui/src/collections_ui.rs#L2926), [`ui/dr-ui/src/gestures.rs:1`](../ui/dr-ui/src/gestures.rs#L1), [`ui/dr-ui/src/lib.rs:101`](../ui/dr-ui/src/lib.rs#L101), [`ui/dr-ui/src/library_ui.rs:360`](../ui/dr-ui/src/library_ui.rs#L360), [`ui/dr-ui/src/library_ui.rs:6421`](../ui/dr-ui/src/library_ui.rs#L6421), [`ui/dr-ui/src/library_ui.rs:6566`](../ui/dr-ui/src/library_ui.rs#L6566), [`ui/dr-ui/src/library_ui.rs:7781`](../ui/dr-ui/src/library_ui.rs#L7781), [`ui/dr-ui/ui/app.slint:1035`](../ui/dr-ui/ui/app.slint#L1035), [`ui/dr-ui/ui/app.slint:60`](../ui/dr-ui/ui/app.slint#L60), [`ui/dr-ui/ui/app.slint:652`](../ui/dr-ui/ui/app.slint#L652), [`ui/dr-ui/ui/app.slint:666`](../ui/dr-ui/ui/app.slint#L666), [`ui/dr-ui/ui/controls.slint:593`](../ui/dr-ui/ui/controls.slint#L593), [`ui/dr-ui/ui/gestures.slint:1`](../ui/dr-ui/ui/gestures.slint#L1), [`ui/dr-ui/ui/library.slint:1277`](../ui/dr-ui/ui/library.slint#L1277), [`ui/dr-ui/ui/library.slint:1284`](../ui/dr-ui/ui/library.slint#L1284), [`ui/dr-ui/ui/library.slint:1381`](../ui/dr-ui/ui/library.slint#L1381), [`ui/dr-ui/ui/library.slint:2565`](../ui/dr-ui/ui/library.slint#L2565), [`ui/dr-ui/ui/library.slint:4195`](../ui/dr-ui/ui/library.slint#L4195), [`ui/dr-ui/ui/library.slint:960`](../ui/dr-ui/ui/library.slint#L960), [`ui/dr-ui/ui/library.slint:993`](../ui/dr-ui/ui/library.slint#L993), [`ui/dr-ui/ui/presets.slint:19`](../ui/dr-ui/ui/presets.slint#L19), [`ui/dr-ui/ui/settings.slint:118`](../ui/dr-ui/ui/settings.slint#L118) | +| FR-UI-3 | [`ui/dr-ui/src/develop.rs:2497`](../ui/dr-ui/src/develop.rs#L2497), [`ui/dr-ui/src/develop.rs:2606`](../ui/dr-ui/src/develop.rs#L2606), [`ui/dr-ui/src/library_ui.rs:5485`](../ui/dr-ui/src/library_ui.rs#L5485), [`ui/dr-ui/src/masks_ui.rs:249`](../ui/dr-ui/src/masks_ui.rs#L249), [`ui/dr-ui/src/masks_ui.rs:976`](../ui/dr-ui/src/masks_ui.rs#L976), [`ui/dr-ui/src/masks_ui.rs:998`](../ui/dr-ui/src/masks_ui.rs#L998), [`ui/dr-ui/src/spots_ui.rs:19`](../ui/dr-ui/src/spots_ui.rs#L19), [`ui/dr-ui/ui/app.slint:2195`](../ui/dr-ui/ui/app.slint#L2195), [`ui/dr-ui/ui/collections.slint:4`](../ui/dr-ui/ui/collections.slint#L4), [`ui/dr-ui/ui/collections.slint:747`](../ui/dr-ui/ui/collections.slint#L747), [`ui/dr-ui/ui/masks.slint:612`](../ui/dr-ui/ui/masks.slint#L612), [`ui/dr-ui/ui/widgets.slint:71`](../ui/dr-ui/ui/widgets.slint#L71) | +| FR-UI-4 | [`tools/traceability/src/gestures.rs:1`](../tools/traceability/src/gestures.rs#L1), [`ui/dr-ui/src/collections_ui.rs:1045`](../ui/dr-ui/src/collections_ui.rs#L1045), [`ui/dr-ui/src/collections_ui.rs:1055`](../ui/dr-ui/src/collections_ui.rs#L1055), [`ui/dr-ui/src/collections_ui.rs:116`](../ui/dr-ui/src/collections_ui.rs#L116), [`ui/dr-ui/src/collections_ui.rs:117`](../ui/dr-ui/src/collections_ui.rs#L117), [`ui/dr-ui/src/collections_ui.rs:126`](../ui/dr-ui/src/collections_ui.rs#L126), [`ui/dr-ui/src/collections_ui.rs:154`](../ui/dr-ui/src/collections_ui.rs#L154), [`ui/dr-ui/src/collections_ui.rs:1552`](../ui/dr-ui/src/collections_ui.rs#L1552), [`ui/dr-ui/src/collections_ui.rs:1569`](../ui/dr-ui/src/collections_ui.rs#L1569), [`ui/dr-ui/src/collections_ui.rs:1685`](../ui/dr-ui/src/collections_ui.rs#L1685), [`ui/dr-ui/src/collections_ui.rs:1821`](../ui/dr-ui/src/collections_ui.rs#L1821), [`ui/dr-ui/src/collections_ui.rs:1848`](../ui/dr-ui/src/collections_ui.rs#L1848), [`ui/dr-ui/src/collections_ui.rs:1964`](../ui/dr-ui/src/collections_ui.rs#L1964), [`ui/dr-ui/src/collections_ui.rs:2926`](../ui/dr-ui/src/collections_ui.rs#L2926), [`ui/dr-ui/src/collections_ui.rs:2963`](../ui/dr-ui/src/collections_ui.rs#L2963), [`ui/dr-ui/src/collections_ui.rs:365`](../ui/dr-ui/src/collections_ui.rs#L365), [`ui/dr-ui/src/collections_ui.rs:569`](../ui/dr-ui/src/collections_ui.rs#L569), [`ui/dr-ui/src/collections_ui.rs:589`](../ui/dr-ui/src/collections_ui.rs#L589), [`ui/dr-ui/src/develop.rs:4455`](../ui/dr-ui/src/develop.rs#L4455), [`ui/dr-ui/src/develop.rs:4480`](../ui/dr-ui/src/develop.rs#L4480), [`ui/dr-ui/src/develop.rs:4491`](../ui/dr-ui/src/develop.rs#L4491), [`ui/dr-ui/src/develop.rs:4505`](../ui/dr-ui/src/develop.rs#L4505), [`ui/dr-ui/src/develop.rs:5542`](../ui/dr-ui/src/develop.rs#L5542), [`ui/dr-ui/src/develop.rs:5573`](../ui/dr-ui/src/develop.rs#L5573), [`ui/dr-ui/src/develop.rs:5594`](../ui/dr-ui/src/develop.rs#L5594), [`ui/dr-ui/src/gesture_book.rs:3`](../ui/dr-ui/src/gesture_book.rs#L3), [`ui/dr-ui/src/gestures.rs:1`](../ui/dr-ui/src/gestures.rs#L1), [`ui/dr-ui/src/lib.rs:1724`](../ui/dr-ui/src/lib.rs#L1724), [`ui/dr-ui/src/lib.rs:2130`](../ui/dr-ui/src/lib.rs#L2130), [`ui/dr-ui/src/lib.rs:2367`](../ui/dr-ui/src/lib.rs#L2367), [`ui/dr-ui/src/lib.rs:2946`](../ui/dr-ui/src/lib.rs#L2946), [`ui/dr-ui/src/lib.rs:3669`](../ui/dr-ui/src/lib.rs#L3669), [`ui/dr-ui/src/lib.rs:414`](../ui/dr-ui/src/lib.rs#L414), [`ui/dr-ui/src/lib.rs:443`](../ui/dr-ui/src/lib.rs#L443), [`ui/dr-ui/src/library_ui.rs:5485`](../ui/dr-ui/src/library_ui.rs#L5485), [`ui/dr-ui/src/library_ui.rs:5497`](../ui/dr-ui/src/library_ui.rs#L5497), [`ui/dr-ui/src/library_ui.rs:5567`](../ui/dr-ui/src/library_ui.rs#L5567), [`ui/dr-ui/src/library_ui.rs:5677`](../ui/dr-ui/src/library_ui.rs#L5677), [`ui/dr-ui/src/library_ui.rs:5705`](../ui/dr-ui/src/library_ui.rs#L5705), [`ui/dr-ui/src/library_ui.rs:6554`](../ui/dr-ui/src/library_ui.rs#L6554), [`ui/dr-ui/src/library_ui.rs:6566`](../ui/dr-ui/src/library_ui.rs#L6566), [`ui/dr-ui/ui/app.slint:1981`](../ui/dr-ui/ui/app.slint#L1981), [`ui/dr-ui/ui/app.slint:2153`](../ui/dr-ui/ui/app.slint#L2153), [`ui/dr-ui/ui/app.slint:2304`](../ui/dr-ui/ui/app.slint#L2304), [`ui/dr-ui/ui/app.slint:2404`](../ui/dr-ui/ui/app.slint#L2404), [`ui/dr-ui/ui/app.slint:275`](../ui/dr-ui/ui/app.slint#L275), [`ui/dr-ui/ui/app.slint:628`](../ui/dr-ui/ui/app.slint#L628), [`ui/dr-ui/ui/app.slint:657`](../ui/dr-ui/ui/app.slint#L657), [`ui/dr-ui/ui/app.slint:666`](../ui/dr-ui/ui/app.slint#L666), [`ui/dr-ui/ui/app.slint:751`](../ui/dr-ui/ui/app.slint#L751), [`ui/dr-ui/ui/gestures.slint:1`](../ui/dr-ui/ui/gestures.slint#L1), [`ui/dr-ui/ui/library.slint:1048`](../ui/dr-ui/ui/library.slint#L1048), [`ui/dr-ui/ui/library.slint:1252`](../ui/dr-ui/ui/library.slint#L1252), [`ui/dr-ui/ui/library.slint:1277`](../ui/dr-ui/ui/library.slint#L1277), [`ui/dr-ui/ui/library.slint:1284`](../ui/dr-ui/ui/library.slint#L1284), [`ui/dr-ui/ui/library.slint:1317`](../ui/dr-ui/ui/library.slint#L1317), [`ui/dr-ui/ui/library.slint:1374`](../ui/dr-ui/ui/library.slint#L1374), [`ui/dr-ui/ui/library.slint:1381`](../ui/dr-ui/ui/library.slint#L1381), [`ui/dr-ui/ui/library.slint:2565`](../ui/dr-ui/ui/library.slint#L2565), [`ui/dr-ui/ui/library.slint:4079`](../ui/dr-ui/ui/library.slint#L4079), [`ui/dr-ui/ui/library.slint:4195`](../ui/dr-ui/ui/library.slint#L4195), [`ui/dr-ui/ui/library.slint:960`](../ui/dr-ui/ui/library.slint#L960), [`ui/dr-ui/ui/library.slint:987`](../ui/dr-ui/ui/library.slint#L987), [`ui/dr-ui/ui/library.slint:993`](../ui/dr-ui/ui/library.slint#L993) | +| 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:2991`](../ui/dr-ui/src/lib.rs#L2991), [`ui/dr-ui/src/lib.rs:3629`](../ui/dr-ui/src/lib.rs#L3629), [`ui/dr-ui/src/lib.rs:3820`](../ui/dr-ui/src/lib.rs#L3820), [`ui/dr-ui/src/masks_ui.rs:931`](../ui/dr-ui/src/masks_ui.rs#L931), [`ui/dr-ui/ui/app.slint:127`](../ui/dr-ui/ui/app.slint#L127), [`ui/dr-ui/ui/app.slint:2304`](../ui/dr-ui/ui/app.slint#L2304), [`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:395`](../core/dr-pipeline/src/framing.rs#L395), [`core/dr-types/src/settings.rs:321`](../core/dr-types/src/settings.rs#L321), [`ui/dr-ui/src/lib.rs:3544`](../ui/dr-ui/src/lib.rs#L3544), [`ui/dr-ui/ui/app.slint:760`](../ui/dr-ui/ui/app.slint#L760), [`ui/dr-ui/ui/settings.slint:565`](../ui/dr-ui/ui/settings.slint#L565), [`ui/dr-ui/ui/toolrail.slint:89`](../ui/dr-ui/ui/toolrail.slint#L89) | +| FR-UI-7 | [`core/dr-pipeline/src/descriptor.rs:195`](../core/dr-pipeline/src/descriptor.rs#L195), [`core/dr-pipeline/src/framing.rs:395`](../core/dr-pipeline/src/framing.rs#L395), [`core/dr-types/src/settings.rs:321`](../core/dr-types/src/settings.rs#L321), [`ui/dr-ui/src/develop.rs:1200`](../ui/dr-ui/src/develop.rs#L1200), [`ui/dr-ui/src/lib.rs:3582`](../ui/dr-ui/src/lib.rs#L3582), [`ui/dr-ui/ui/app.slint:2068`](../ui/dr-ui/ui/app.slint#L2068), [`ui/dr-ui/ui/app.slint:784`](../ui/dr-ui/ui/app.slint#L784), [`ui/dr-ui/ui/settings.slint:565`](../ui/dr-ui/ui/settings.slint#L565), [`ui/dr-ui/ui/toolrail.slint:89`](../ui/dr-ui/ui/toolrail.slint#L89) | | FR-UI-8 | [`core/dr-catalog/src/collections.rs:555`](../core/dr-catalog/src/collections.rs#L555), [`core/dr-catalog/src/collections.rs:576`](../core/dr-catalog/src/collections.rs#L576), [`core/dr-types/src/place.rs:1`](../core/dr-types/src/place.rs#L1), [`ui/dr-ui/src/derived_sync.rs:188`](../ui/dr-ui/src/derived_sync.rs#L188), [`ui/dr-ui/src/derived_sync.rs:657`](../ui/dr-ui/src/derived_sync.rs#L657), [`ui/dr-ui/src/derived_sync.rs:667`](../ui/dr-ui/src/derived_sync.rs#L667), [`ui/dr-ui/src/derived_sync.rs:749`](../ui/dr-ui/src/derived_sync.rs#L749), [`ui/dr-ui/src/derived_sync.rs:74`](../ui/dr-ui/src/derived_sync.rs#L74), [`ui/dr-ui/src/library.rs:1106`](../ui/dr-ui/src/library.rs#L1106), [`ui/dr-ui/src/library.rs:4556`](../ui/dr-ui/src/library.rs#L4556), [`ui/dr-ui/src/library.rs:5274`](../ui/dr-ui/src/library.rs#L5274), [`ui/dr-ui/src/library.rs:5340`](../ui/dr-ui/src/library.rs#L5340), [`ui/dr-ui/src/library_ui.rs:195`](../ui/dr-ui/src/library_ui.rs#L195), [`ui/dr-ui/src/library_ui.rs:2118`](../ui/dr-ui/src/library_ui.rs#L2118), [`ui/dr-ui/src/library_ui.rs:2307`](../ui/dr-ui/src/library_ui.rs#L2307), [`ui/dr-ui/src/library_ui.rs:2324`](../ui/dr-ui/src/library_ui.rs#L2324), [`ui/dr-ui/src/library_ui.rs:2422`](../ui/dr-ui/src/library_ui.rs#L2422), [`ui/dr-ui/src/library_ui.rs:5518`](../ui/dr-ui/src/library_ui.rs#L5518), [`ui/dr-ui/src/library_ui.rs:5558`](../ui/dr-ui/src/library_ui.rs#L5558), [`ui/dr-ui/src/library_ui.rs:5587`](../ui/dr-ui/src/library_ui.rs#L5587), [`ui/dr-ui/src/library_ui.rs:5850`](../ui/dr-ui/src/library_ui.rs#L5850), [`ui/dr-ui/src/library_ui.rs:6073`](../ui/dr-ui/src/library_ui.rs#L6073), [`ui/dr-ui/src/library_ui.rs:6795`](../ui/dr-ui/src/library_ui.rs#L6795), [`ui/dr-ui/src/library_ui.rs:859`](../ui/dr-ui/src/library_ui.rs#L859), [`ui/dr-ui/src/library_ui.rs:892`](../ui/dr-ui/src/library_ui.rs#L892), [`ui/dr-ui/src/library_ui.rs:938`](../ui/dr-ui/src/library_ui.rs#L938), [`ui/dr-ui/src/place.rs:1`](../ui/dr-ui/src/place.rs#L1) | -| NFR-A11Y-2 | [`ui/dr-ui/tests/ui_controls_are_accessible.rs:1`](../ui/dr-ui/tests/ui_controls_are_accessible.rs#L1), [`ui/dr-ui/ui/app.slint:2343`](../ui/dr-ui/ui/app.slint#L2343), [`ui/dr-ui/ui/app.slint:2367`](../ui/dr-ui/ui/app.slint#L2367) | +| NFR-A11Y-2 | [`ui/dr-ui/tests/ui_controls_are_accessible.rs:1`](../ui/dr-ui/tests/ui_controls_are_accessible.rs#L1), [`ui/dr-ui/ui/adjust.slint:157`](../ui/dr-ui/ui/adjust.slint#L157), [`ui/dr-ui/ui/app.slint:2404`](../ui/dr-ui/ui/app.slint#L2404), [`ui/dr-ui/ui/app.slint:2428`](../ui/dr-ui/ui/app.slint#L2428) | | NFR-A11Y-3 | [`ui/dr-ui/src/histogram.rs:356`](../ui/dr-ui/src/histogram.rs#L356), [`ui/dr-ui/ui/histogram.slint:137`](../ui/dr-ui/ui/histogram.slint#L137), [`ui/dr-ui/ui/library.slint:756`](../ui/dr-ui/ui/library.slint#L756), [`ui/dr-ui/ui/library.slint:904`](../ui/dr-ui/ui/library.slint#L904), [`ui/dr-ui/ui/peaking.slint:1`](../ui/dr-ui/ui/peaking.slint#L1) | | 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:3385`](../ui/dr-ui/src/library.rs#L3385) | -| NFR-ARCH-3 | [`ui/dr-ui/src/export.rs:1809`](../ui/dr-ui/src/export.rs#L1809), [`ui/dr-ui/src/export.rs:1836`](../ui/dr-ui/src/export.rs#L1836), [`ui/dr-ui/src/export.rs:412`](../ui/dr-ui/src/export.rs#L412), [`ui/dr-ui/src/export.rs:438`](../ui/dr-ui/src/export.rs#L438), [`ui/dr-ui/src/lib.rs:2589`](../ui/dr-ui/src/lib.rs#L2589), [`ui/dr-ui/ui/app.slint:1190`](../ui/dr-ui/ui/app.slint#L1190), [`ui/dr-ui/ui/library.slint:4157`](../ui/dr-ui/ui/library.slint#L4157) | +| NFR-ARCH-3 | [`ui/dr-ui/src/export.rs:1809`](../ui/dr-ui/src/export.rs#L1809), [`ui/dr-ui/src/export.rs:1836`](../ui/dr-ui/src/export.rs#L1836), [`ui/dr-ui/src/export.rs:412`](../ui/dr-ui/src/export.rs#L412), [`ui/dr-ui/src/export.rs:438`](../ui/dr-ui/src/export.rs#L438), [`ui/dr-ui/src/lib.rs:2594`](../ui/dr-ui/src/lib.rs#L2594), [`ui/dr-ui/ui/app.slint:1214`](../ui/dr-ui/ui/app.slint#L1214), [`ui/dr-ui/ui/library.slint:4157`](../ui/dr-ui/ui/library.slint#L4157) | | 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:514`](../ui/dr-ui/src/export.rs#L514) | | NFR-OPS-1 | [`platform/dr-plat/src/diagnostics.rs:1`](../platform/dr-plat/src/diagnostics.rs#L1), [`platform/dr-plat/src/state.rs:1`](../platform/dr-plat/src/state.rs#L1) | | NFR-OPS-2 | [`platform/dr-plat/src/crash.rs:1`](../platform/dr-plat/src/crash.rs#L1) | | 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/bench/src/catalog_open.rs:1`](../tools/bench/src/catalog_open.rs#L1) | | 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:3353`](../ui/dr-ui/src/develop.rs#L3353), [`ui/dr-ui/src/lib.rs:1911`](../ui/dr-ui/src/lib.rs#L1911) | +| 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:3405`](../ui/dr-ui/src/develop.rs#L3405), [`ui/dr-ui/src/lib.rs:1916`](../ui/dr-ui/src/lib.rs#L1916) | | NFR-P3 | [`tools/bench/src/thumbnails.rs:1`](../tools/bench/src/thumbnails.rs#L1) | | NFR-P5 | [`core/dr-catalog/src/schema.rs:356`](../core/dr-catalog/src/schema.rs#L356), [`ui/dr-ui/src/library.rs:4663`](../ui/dr-ui/src/library.rs#L4663), [`ui/dr-ui/src/library.rs:5776`](../ui/dr-ui/src/library.rs#L5776), [`ui/dr-ui/src/library_ui.rs:4726`](../ui/dr-ui/src/library_ui.rs#L4726), [`ui/dr-ui/src/library_ui.rs:64`](../ui/dr-ui/src/library_ui.rs#L64) | | NFR-P9 | [`ui/dr-ui/src/collections_ui.rs:1`](../ui/dr-ui/src/collections_ui.rs#L1), [`ui/dr-ui/src/export.rs:992`](../ui/dr-ui/src/export.rs#L992), [`ui/dr-ui/src/library.rs:1`](../ui/dr-ui/src/library.rs#L1), [`ui/dr-ui/src/library_ui.rs:1`](../ui/dr-ui/src/library_ui.rs#L1), [`ui/dr-ui/src/trash.rs:1`](../ui/dr-ui/src/trash.rs#L1) | @@ -154,7 +154,7 @@ _None._ | NFR-R6 | [`core/dr-catalog/src/error.rs:1`](../core/dr-catalog/src/error.rs#L1), [`core/dr-catalog/src/lib.rs:255`](../core/dr-catalog/src/lib.rs#L255), [`core/dr-catalog/src/recovery.rs:1`](../core/dr-catalog/src/recovery.rs#L1) | | NFR-R7 | [`core/dr-gpu/src/error.rs:1`](../core/dr-gpu/src/error.rs#L1) | | NFR-R8 | [`core/dr-gpu/src/error.rs:1`](../core/dr-gpu/src/error.rs#L1) | -| NFR-RES-1 | [`core/dr-gpu/src/adjust.rs:1029`](../core/dr-gpu/src/adjust.rs#L1029), [`core/dr-pipeline/src/history.rs:86`](../core/dr-pipeline/src/history.rs#L86), [`ui/dr-ui/src/develop.rs:3524`](../ui/dr-ui/src/develop.rs#L3524), [`ui/dr-ui/src/identity_ui.rs:121`](../ui/dr-ui/src/identity_ui.rs#L121), [`ui/dr-ui/src/lib.rs:93`](../ui/dr-ui/src/lib.rs#L93), [`ui/dr-ui/src/memory.rs:1`](../ui/dr-ui/src/memory.rs#L1) | +| NFR-RES-1 | [`core/dr-gpu/src/adjust.rs:1029`](../core/dr-gpu/src/adjust.rs#L1029), [`core/dr-pipeline/src/history.rs:86`](../core/dr-pipeline/src/history.rs#L86), [`ui/dr-ui/src/develop.rs:3688`](../ui/dr-ui/src/develop.rs#L3688), [`ui/dr-ui/src/identity_ui.rs:121`](../ui/dr-ui/src/identity_ui.rs#L121), [`ui/dr-ui/src/lib.rs:93`](../ui/dr-ui/src/lib.rs#L93), [`ui/dr-ui/src/memory.rs:1`](../ui/dr-ui/src/memory.rs#L1) | | NFR-RES-2 | [`ui/dr-ui/src/faces.rs:346`](../ui/dr-ui/src/faces.rs#L346), [`ui/dr-ui/src/library.rs:3385`](../ui/dr-ui/src/library.rs#L3385), [`ui/dr-ui/src/library.rs:3576`](../ui/dr-ui/src/library.rs#L3576) | | NFR-RES-4 | [`core/dr-catalog/src/cache.rs:1`](../core/dr-catalog/src/cache.rs#L1), [`core/dr-catalog/src/face_shard.rs:1`](../core/dr-catalog/src/face_shard.rs#L1), [`core/dr-catalog/src/schema.rs:785`](../core/dr-catalog/src/schema.rs#L785), [`core/dr-gpu/src/lib.rs:93`](../core/dr-gpu/src/lib.rs#L93), [`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), [`core/dr-thumbs/src/lib.rs:376`](../core/dr-thumbs/src/lib.rs#L376), [`ui/dr-ui/src/library.rs:3292`](../ui/dr-ui/src/library.rs#L3292) | | NFR-SEC-1 | [`core/dr-decode/src/error.rs:1`](../core/dr-decode/src/error.rs#L1) | diff --git a/ui/dr-ui/src/develop.rs b/ui/dr-ui/src/develop.rs index 1e1d565..ac061e2 100644 --- a/ui/dr-ui/src/develop.rs +++ b/ui/dr-ui/src/develop.rs @@ -1185,12 +1185,46 @@ pub(crate) fn supported(widget: WidgetKind) -> bool { // the panel contributes `ComposePanel`, the affordance that turns it // on. WidgetKind::CropOverlay => true, + // TRACES: FR-DEV-3 + // Hosted on the canvas too — a click on the photograph — with the + // affordance that arms it in the group's own heading. See + // `samples_the_canvas` for why this one leaves its sliders standing + // where the crop takes them away. + WidgetKind::WhitePoint => true, // Not implemented. Listed rather than caught by a wildcard so the next // kind added to the core surfaces here as a compile error. - WidgetKind::ColourWheel - | WidgetKind::GradientHandle - | WidgetKind::BrushMask - | WidgetKind::WhitePoint => false, + WidgetKind::ColourWheel | WidgetKind::GradientHandle | WidgetKind::BrushMask => false, + } +} + +/// TRACES: FR-DEV-3a | FR-UI-7 +/// Whether an on-canvas widget *reads* the photograph rather than replacing +/// its parameters with handles. +/// +/// **This is the distinction that stopped the picker eating its own sliders.** +/// [`WidgetKind::is_on_canvas`] says where a widget is manipulated, and the +/// panel had been treating that as also meaning "and so the panel draws +/// nothing for it". For a crop that is right: four edge fractions and an angle +/// are not controls anybody drags in a list, and the whole reason the crop is +/// on the photograph is that they are unusable anywhere else. +/// +/// An eyedropper is the other thing. It *writes* temperature and tint — they +/// remain exactly the controls a photographer reaches for afterwards, because +/// a sampled neutral is a starting point and warming a portrait past it is the +/// next move, not a mistake. Taking the sliders away to make room for the +/// picker would be trading a control for a control. +/// +/// So the panel draws the group as usual and puts the affordance that arms the +/// canvas in its heading. FR-DEV-3's "temperature/tint, **and** picker" is one +/// word doing a lot of work, and this is the word. +fn samples_the_canvas(widget: WidgetKind) -> bool { + match widget { + WidgetKind::WhitePoint => true, + // Dragged rather than sampled: the parameters *are* the handles. + WidgetKind::CropOverlay | WidgetKind::GradientHandle | WidgetKind::BrushMask => false, + // Not on the canvas at all, so nothing asks. Listed rather than + // wildcarded for the reason `supported` lists its own. + WidgetKind::ToneCurve | WidgetKind::ColourWheel => false, } } @@ -1240,6 +1274,11 @@ pub(crate) fn rows_filtered( // Where this operation's rows begin. The panel groups by walking // back to it, so it has to be taken before any row is pushed. let group_head = rows.len(); + // TRACES: FR-DEV-3 + // Whether this group's heading carries the affordance that arms an + // on-canvas sampler. Set below, from what the operation asked for and + // nothing else — the panel never learns which operation it is. + let mut group_samples = false; // An operation may ask for one widget spanning several // parameters. Honouring it is optional — dropping this block // renders the same parameters as ordinary sliders, and the edit @@ -1270,7 +1309,15 @@ pub(crate) fn rows_filtered( // build (ARCH §4.3a draws the line at the *generated* panel // naming stages, not at the interface having hand-made // widgets). - if widget.is_on_canvas() { + // + // TRACES: FR-DEV-3 + // **Unless the canvas is *reading* rather than driving.** An + // eyedropper writes temperature and tint and leaves them as + // the controls they were, so its group is drawn in full and + // only the affordance moves to the heading. See + // `samples_the_canvas` for the whole of that argument. + group_samples = samples_the_canvas(widget); + if widget.is_on_canvas() && !group_samples { continue; } @@ -1281,8 +1328,10 @@ pub(crate) fn rows_filtered( WidgetKind::ToneCurve => { curve_row(op_index, group_head, op, presentation, curve_channel) } - // Canvas-hosted kinds returned above; the rest are not - // implemented and reached sliders via `choose`. + // Canvas-hosted kinds returned above, except a + // sampler, which falls through to its own sliders; the + // rest are not implemented and reached sliders via + // `choose`. WidgetKind::ColourWheel | WidgetKind::CropOverlay | WidgetKind::GradientHandle @@ -1371,6 +1420,7 @@ pub(crate) fn rows_filtered( group_head: group_head as i32, group_len, group_modified, + group_samples, kind: kind.into(), value: p.value, default_value: p.default, @@ -1498,6 +1548,8 @@ fn curve_row( // the group it heads is itself and nothing else. group_len: 1, group_modified: op.params.iter().any(|p| p.value != p.default), + // A curve is drawn, not sampled. Its own affordance is the plot. + group_samples: false, kind: "curve".into(), value: 0.0, default_value: 0.0, @@ -3671,6 +3723,118 @@ impl DevelopSession { self.set_film(None); } + /// TRACES: FR-DEV-3 | FR-DEV-5 + /// Set the white balance from a point on the photograph. + /// + /// `x` and `y` are fractions of the *visible* image — the coordinates a + /// click on the canvas arrives in — so a photographer inspecting a + /// highlight at 4× samples the pixel they are actually looking at. + /// + /// **Nothing here knows it is white balance.** The colour goes to + /// [`dr_pipeline::neutral`], which finds the operation that asked to be + /// driven by a pixel and inverts its declared response; this side supplies + /// the pixel and the undo step and nothing else. That is FR-DEV-3a's line + /// in its awkward case: a picker genuinely needs to know how far a hundred + /// units of temperature move red against blue, and that number is declared + /// in the node's own file, so the interface must not be the thing that + /// holds a second copy of it. + /// + /// **One step per sample**, and no step at all for a sample that could not + /// be used — a point in the deep shadows has no balance in it to correct. + /// `Edit::Action` never coalesces, so two clicks are two decisions + /// however quickly they follow each other, which is what a photographer + /// trying a wall and then a cloud expects to be able to undo one at a + /// time. + /// + /// Returns whether the photograph moved. + pub fn sample_neutral(&mut self, x: f32, y: f32) -> bool { + let Some(sample) = self.sample_as_shot(x, y) else { + return false; + }; + if !dr_pipeline::neutral::neutralise(&mut self.graph, sample) { + return false; + } + self.history + .record(&self.graph, Edit::Action(labels::step::SAMPLED_NEUTRAL)); + true + } + + /// The colour at a point with every adjustment taken off, in linear RGB. + /// + /// **Measured before the chain rather than off the screen**, and that is + /// the difference between a picker that converges and one that chases + /// itself. The frame on the canvas has already been through the white + /// balance being solved for, the tone curve, the contrast and whatever + /// else is on; neutralising *that* pixel would be correcting a correction, + /// and the second sample of the same wall would land somewhere else. With + /// the adjustments stripped the value read is the colour as the file has + /// it, which is the domain `neutralise` is defined over. + /// + /// The framing stays on, exactly as it does for [`Self::render_original`] + /// and for the same reason: `x` and `y` are fractions of what is on + /// screen, and a probe rendered without the crop and the zoom would be + /// answering about a different part of the photograph. + /// + /// **Rendered small on purpose.** A 192px probe of the visible region + /// averages a small neighbourhood into each of its pixels, which is what + /// every eyedropper does deliberately: a single photosite off a noisy + /// shadow is a worse answer than the patch around it, and the photographer + /// is pointing at a grey card rather than at a pixel. It is also two + /// dispatches' worth of work on a click. + /// + /// This overwrites the frame the adjust pass is holding, so the caller + /// must redraw — which the callback that samples does anyway, since the + /// picture has just changed. + fn sample_as_shot(&mut self, x: f32, y: f32) -> Option<[f32; 3]> { + /// Long edge of the probe render. See the note above on why it is + /// small rather than large. + const PROBE_EDGE: u32 = 192; + + // sRGB regardless of the display: this is a measurement, not something + // anybody looks at, and decoding it needs a transfer function known + // here. Composing for a wide-gamut panel would put the reading in a + // space the arithmetic below does not undo. + let space = dr_types::ColourSpace::Srgb; + + let saved = self.graph.state(); + self.strip_adjustments(); + + let (sw, sh) = self.demosaiced.size(); + let (fw, fh) = self.graph.output_size(sw, sh); + let (w, h) = fit(fw, fh, PROBE_EDGE, PROBE_EDGE); + let shader = self.graph.compose_for(space); + let probe = self + .render_with_masks(&shader, w, h, space) + .and_then(|()| self.adjust.export_pixels().map_err(|e| e.to_string())); + + // Restored whatever happened, for the reason every other suspension + // here restores: leaving the graph stripped after a failed probe would + // discard the edit silently. + let debt = self.graph.set_state(&saved); + self.pay_film_debt(&debt); + + let (rgba, pw, ph) = probe + .inspect_err(|e| log::warn!("could not read a neutral off the frame: {e}")) + .ok()?; + + let (pw, ph) = (pw as usize, ph as usize); + let px = ((x.clamp(0.0, 1.0) * pw as f32) as usize).min(pw.saturating_sub(1)); + let py = ((y.clamp(0.0, 1.0) * ph as f32) as usize).min(ph.saturating_sub(1)); + let at = (py * pw + px) * 4; + let pixel = rgba.get(at..at + 3)?; + + // The probe was encoded for the screen; the solve is multiplicative + // and only means anything in linear light (ARCH §5.2). Undone with + // the space's own transfer function rather than a second copy of the + // curve written out here. + let transfer = space.transfer(); + Some([ + transfer.decode(f32::from(pixel[0]) / 255.0), + transfer.decode(f32::from(pixel[1]) / 255.0), + transfer.decode(f32::from(pixel[2]) / 255.0), + ]) + } + /// TRACES: FR-PLAT-AND-5 | NFR-RES-1 /// Give back the GPU memory this session is holding only to be fast. /// @@ -5597,6 +5761,37 @@ mod tests { assert!(!session.framing_edits_image()); } + /// TRACES: FR-DEV-3 | FR-DEV-5 + /// Sampling something that is already neutral corrects nothing, and says + /// so by leaving the stack alone. + /// + /// The failure this guards is a picker that lands a ten-thousandth off + /// zero: the photograph would come back marked modified, an undo step + /// would appear for a correction of nothing, and the sidecar would gain a + /// temperature the photographer never chose. The solve rounds to the + /// precision the control is drawn at, which is what makes "no correction" + /// representable at all. + #[test] + fn sampling_a_grey_that_is_already_grey_leaves_the_photograph_alone() { + let Some(ctx) = headless() else { return }; + let (mut session, _) = grey_session(&ctx); + let steps = session.history_rows().len(); + + assert!( + session.sample_neutral(0.5, 0.5), + "a flat grey frame is a usable sample" + ); + assert!( + session.is_neutral(), + "there was nothing to correct, so nothing was corrected" + ); + assert_eq!( + session.history_rows().len(), + steps, + "and a correction of nothing is not a step" + ); + } + /// TRACES: FR-DEV-7 | FR-DEV-5 /// A held comparison hands the edit straight back. /// @@ -6449,6 +6644,50 @@ mod tests { ); } + /// TRACES: FR-DEV-3 | FR-DEV-3a + /// A canvas *sampler* adds an affordance; it does not take the sliders. + /// + /// The distinction the panel had been missing. `is_on_canvas` was read as + /// "and so the panel draws nothing", which is right for a crop and wrong + /// for an eyedropper — FR-DEV-3 asks for "temperature/tint, **and** + /// picker", and a picker that ate the two sliders would have traded one + /// control for another. Asserted against the chain rather than a literal, + /// so it keeps testing the property when the declaration moves. + #[test] + fn a_sampled_operation_keeps_the_sliders_it_writes() { + let graph = EditGraph::default_chain(); + let caps = graph.capabilities(); + + let (index, cap) = caps + .iter() + .enumerate() + .find(|(_, c)| { + c.presentation + .as_ref() + .is_some_and(|p| p.widgets.contains(&WidgetKind::WhitePoint)) + }) + .expect("some operation asks to be driven by a pixel"); + + let rows = rows_from(&caps); + let mine: Vec<_> = rows.iter().filter(|r| r.op_index == index as i32).collect(); + + assert_eq!( + mine.len(), + cap.params.len(), + "every parameter of a sampled operation still has its own control" + ); + assert!( + mine.iter().all(|r| r.group_samples), + "and the group's heading carries the picker" + ); + assert!( + rows.iter() + .filter(|r| r.op_index != index as i32) + .all(|r| !r.group_samples), + "no other group claims one" + ); + } + #[test] fn framing_is_not_generated_as_sliders() { // `ComposePanel` presents crop, rotation, flips and straightening as diff --git a/ui/dr-ui/src/labels.rs b/ui/dr-ui/src/labels.rs index c60644c..3d567fd 100644 --- a/ui/dr-ui/src/labels.rs +++ b/ui/dr-ui/src/labels.rs @@ -29,6 +29,14 @@ pub mod step { pub const PASTE: LocalizedKey = LocalizedKey("history.paste"); pub const FILM: LocalizedKey = LocalizedKey("history.film"); + /// TRACES: FR-DEV-3 + /// A neutral was picked off the photograph, setting the white balance. + /// + /// Named for what the photographer did rather than for the parameters it + /// moved: two of them changed, and "Temperature" beside "Tint" in the list + /// would describe the mechanism rather than the decision. + pub const SAMPLED_NEUTRAL: LocalizedKey = LocalizedKey("history.sampled_neutral"); + pub const RESET_ALL: LocalizedKey = LocalizedKey("history.reset_all"); pub const RESET_OP: LocalizedKey = LocalizedKey("history.reset_op"); pub const RESET_PARAM: LocalizedKey = LocalizedKey("history.reset_param"); @@ -77,6 +85,7 @@ pub mod step { dr_pipeline::history::UNNAMED, PASTE, FILM, + SAMPLED_NEUTRAL, RESET_ALL, RESET_OP, RESET_PARAM, @@ -253,6 +262,7 @@ fn catalogued(key: &str) -> Option<&'static str> { "history.edit" => "Edit", "history.paste" => "Paste Settings", "history.film" => "Film Stock", + "history.sampled_neutral" => "Sample Neutral", "history.reset_all" => "Reset Everything", "history.reset_op" => "Reset Group", diff --git a/ui/dr-ui/src/lib.rs b/ui/dr-ui/src/lib.rs index 83f4502..3296268 100644 --- a/ui/dr-ui/src/lib.rs +++ b/ui/dr-ui/src/lib.rs @@ -378,6 +378,11 @@ fn reset_view_state(window: &AppWindow) { // back anyway, but a press that opens the next photograph — the roll is a // tap away — must not carry a held original onto it. window.set_showing_original(false); + // TRACES: FR-DEV-3 + // And an armed sampler goes down with it: a picker left waiting would make + // the first click on the *next* photograph sample it, which is a click + // nobody meant to spend. + window.set_sampling_op(-1); // TRACES: FR-DSP-7 // Emptied rather than left standing: the previous photograph's histogram // beside the next one's filename is a confident, precise lie, and the gap @@ -2833,6 +2838,39 @@ pub fn run(paths: Vec) -> Result<()> { render_now(&w, false); }); } + { + // TRACES: FR-DEV-3 + // A neutral picked off the photograph. + // + // The operation is not named here and is not passed in: the click + // carries a point, the session turns it into a colour, and + // `dr_pipeline::neutral` finds the operation that asked to be driven + // by one. This callback's whole contribution is that a click on the + // canvas is a click on the canvas. + // + // The rows are re-synced because the sample moved parameters the panel + // is showing — two of them, from one press, which is exactly the case + // a paste and an undo already go through this path for. + let weak = window.as_weak(); + let session = session.clone(); + let redraw = redraw.clone(); + let rows = rows.clone(); + window.on_neutral_picked(move |x, y| { + let Some(w) = weak.upgrade() else { return }; + let sampled = session + .borrow_mut() + .as_mut() + .is_some_and(|s| s.sample_neutral(x, y)); + if sampled { + sync_rows(&w, &rows, &session); + } + // Redrawn either way. A sample that found nothing usable still + // overwrote the frame the adjust pass was holding, and leaving the + // canvas showing a probe of the unedited image would look like the + // edit had been thrown away. + redraw(&w); + }); + } // TRACES: FR-DEV-5 | FR-DEV-7 // Clicking a row. Arriving six steps away costs what arriving from one diff --git a/ui/dr-ui/ui/adjust.slint b/ui/dr-ui/ui/adjust.slint index 417aa4c..de5cbe0 100644 --- a/ui/dr-ui/ui/adjust.slint +++ b/ui/dr-ui/ui/adjust.slint @@ -42,6 +42,17 @@ export struct ParamRow { // cannot see the others. group-modified: bool, + // TRACES: FR-DEV-3 + // This operation is driven by pointing at the photograph as well as by + // its sliders, so the group's heading carries the control that arms the + // canvas. Identical on every row of the group, for the reason + // `group-modified` above is: the heading is one of those rows. + // + // Set in Rust from the widget the operation asked for, never from which + // operation it is (ARCH §4.3a) — the panel still does not know that white + // balance exists, only that something here can be sampled. + group-samples: bool, + // Which control to build. Mirrors ParamKind, plus the widget kinds an // operation can request through its presentation. kind: string, // "scalar" | "bool" | "enum" | "curve" @@ -111,8 +122,15 @@ component GroupHeading inherits Rectangle { in property modified: false; /// Whether this group has anything to reset. in property has-reset: true; + /// TRACES: FR-DEV-3 + /// Whether this group can be set by pointing at the photograph. + in property has-sampler: false; + /// Whether the canvas is currently waiting for that point. + in property sampling: false; callback reset(); + /// Arm the sampler, or put it away if it is already armed. + callback sample(); height: Theme.control-height; @@ -136,6 +154,52 @@ component GroupHeading inherits Rectangle { visible: root.modified; } + // TRACES: FR-DEV-3 | NFR-A11Y-2 + // The eyedropper, built exactly as the reset beside it is: a word, a + // hit target grown to a thumb, and a role so it is announced as + // something that can be pressed rather than read as a caption. + // + // A word rather than a drawn pipette, because this heading has no + // icons in it and one would be the only glyph in a column of text — + // and because "pick" says what happens next, which a pipette only + // says to somebody who already knows. + // + // It stays lit while armed. Arming changes what a click on the + // photograph *does*, and a mode with nothing saying it is on is the + // fault the develop view's own mode strip exists to prevent. + Rectangle { + width: 30px; + visible: root.has-sampler; + + accessible-role: button; + accessible-label: "Set from a neutral in the photograph"; + accessible-enabled: root.has-sampler; + accessible-checkable: true; + accessible-checked: root.sampling; + accessible-action-default => { + if (root.has-sampler) { + root.sample(); + } + } + + sample-touch := TouchArea { + width: 100%; + height: max(parent.height, Theme.touch-target); + y: (parent.height - self.height) / 2; + enabled: root.has-sampler; + mouse-cursor: pointer; + clicked => { root.sample(); } + } + + Caption { + text: "pick"; + emphasised: root.sampling || sample-touch.has-hover; + horizontal-alignment: right; + width: 100%; + height: 100%; + } + } + Rectangle { width: 34px; visible: root.has-reset; @@ -993,6 +1057,19 @@ export component AdjustPanel inherits Rectangle { callback op-reset(int); callback reset-all(); + // TRACES: FR-DEV-3 + // The on-canvas sampler: which group has armed it, and the request to arm + // one. + // + // The op index rather than a bool, because arming is a question about a + // *group* — two operations could ask for a sampler and only one of them + // can be waiting for the click. -1 is none armed, the sentinel this file + // already uses for "no swatch" and "everything" and for the same reason: + // a Slint struct or property cannot carry an optional. + in property sampling-op: -1; + /// The heading's picker was pressed, for the operation at this index. + callback sampler-armed(int); + // TRACES: FR-DEV-3f // The film stock, which is not a parameter and so is not a `ParamRow`. // @@ -1276,6 +1353,15 @@ export component AdjustPanel inherits Rectangle { GroupHeading { title: row.op-label; modified: row.group-modified; + // TRACES: FR-DEV-3 + // And, where the operation asked for one, the + // control that arms the canvas. The heading knows + // only that it has a sampler; which group is + // waiting is the panel's business, because only + // the panel can see the others. + has-sampler: row.group-samples; + sampling: root.sampling-op == row.op-index; + sample => { root.sampler-armed(row.op-index); } // Resetting is what *this* panel's groups do; the // heading itself has no opinion about it. reset => { root.op-reset(row.op-index); } diff --git a/ui/dr-ui/ui/app.slint b/ui/dr-ui/ui/app.slint index d91fc99..44a12a3 100644 --- a/ui/dr-ui/ui/app.slint +++ b/ui/dr-ui/ui/app.slint @@ -237,6 +237,30 @@ export component AppWindow inherits Window { /// the two cannot get out of step and strand the view on the original. callback compare-original(bool); + // --- sampling a neutral off the photograph (FR-DEV-3) --- + + /// TRACES: FR-DEV-3 + /// Which operation's on-canvas sampler is armed, or -1 for none. + /// + /// Held here rather than in Rust, unlike the view mode beside it, and the + /// difference is real: entering a mode has side effects on the session and + /// this has none. Arming changes what the next click on the photograph + /// means and nothing else — no parameter moves, no history step is taken, + /// and the session has nothing to hear about until a point is picked. It + /// is one-shot: the click that samples disarms it. + /// + /// An index rather than a bool because arming belongs to a *group*. Two + /// operations could offer a sampler and only one of them can be waiting. + in-out property sampling-op: -1; + /// Shorthand for the condition the canvas tests, written once. + property sampling: root.sampling-op >= 0; + /// A neutral was picked, in fractions of the visible image. + /// + /// The operation is not passed: which one a sampled colour belongs to is + /// settled by what the chain declared, and this file has no business + /// knowing. See `dr_pipeline::neutral`. + callback neutral-picked(float, float); + /// Every step, newest first. Rust owns the order and stamps each row with /// its own position in the stack, so nothing here does arithmetic to turn /// a row back into a step. @@ -2050,6 +2074,43 @@ in property panel-visible: true; } } + // TRACES: FR-DEV-3 | FR-UI-7 + // Sampling a neutral, beside the repair placer above and + // built exactly like it: a click on the fitted image, over + // the pan area so the click reaches it first, and a + // separate handler rather than a branch inside the pan — + // panning wants press-drag-release and this wants a click, + // and interleaving the two is how a drag ends up sampling + // whatever it happened to travel over. + // + // **One click, one sample, one history step.** There is no + // hover preview: previewing would mean a render and a + // solve per pixel the pointer crossed, and if any of them + // were recorded the stack would fill with a hundred + // temperatures nobody chose. The arming state is what says + // the next click will do something instead. + if root.sampling && root.total > 0 && root.load-error == "": TouchArea { + x: parent.shown-x; + y: parent.shown-y; + width: parent.shown-w; + height: parent.shown-h; + mouse-cursor: MouseCursor.crosshair; + enabled: !root.cropping; + + clicked => { + root.neutral-picked( + self.mouse-x / max(self.width, 1px), + self.mouse-y / max(self.height, 1px), + ); + // One shot. Leaving it armed would make the next + // click on the photograph — to place a mask, to + // pan — a second sample, and the photographer + // would have to remember to put a tool away that + // has already done its job. + root.sampling-op = -1; + } + } + if root.total > 0 && root.load-error == "": TouchArea { x: 0; y: 0; width: 100%; @@ -2831,6 +2892,17 @@ in property panel-visible: true; // kept in step with it. op-reset(op) => { root.curve-reset(op); } reset-all => { root.reset-all(); } + // TRACES: FR-DEV-3 + // Arming is a toggle and it is resolved here, + // not in Rust: it changes what a click on the + // photograph does and nothing about the edit, + // so there is nothing for the session to hear + // about until a point is actually picked. + sampling-op: root.sampling-op; + sampler-armed(op) => { + root.sampling-op = + root.sampling-op == op ? -1 : op; + } // TRACES: FR-DEV-3f film-stocks: root.film-stocks; film-selected: root.film-selected;