Choose the export folder by walking the server, not by typing it
The destination for a Nextcloud export was a text field. Nobody recalls the exact spelling of a path three levels down, and getting it wrong does not fail — `create_dir` makes whatever was typed, so a misremembered folder becomes a new one at the root and the exports are somewhere nobody looks. So it is picked the way the library root is picked, using the same `FolderBrowser` model the launch screen drives: up, into, and "use this folder", confirming the folder currently *shown* rather than one selected in the list. Same rule in both places, so the phrase means one thing. The model is shared; the worker is not. `settings_ui::spawn_folder_list` is a near-twin of the launch screen's, because that one reaches into the `LaunchController` for its session and reports onto the launch screen's error line, while this one is handed credentials and writes to the settings page. Factoring them together needs a function taking both controllers or a trait implemented twice to abstract two call sites — more machinery than the twenty lines it saves. What matters is shared already: navigation behaves identically because both drive the same model. The callbacks are wired in `lib.rs` rather than in `settings_ui::wire`, because listing a remote folder needs credentials and the settings page holds no session on purpose — it is reachable before a library is opened and must not depend on one existing. With no account the picker says to sign in first, rather than showing an empty list that reads as a server with no folders. Details that are decisions rather than accidents: the picker opens at the library root rather than at whatever half-typed path is in the field, which would list nothing and look broken. The listing area is a fixed 180px, since a folder with sixty children would otherwise push the rest of the settings page off the bottom. "Up" is disabled at the root rather than hidden, so the row does not jump as the user navigates. A failed listing leaves the picker open on the folder it was showing — where the user had got to is not something to discard over a dropped request. And the chosen folder saves immediately like every other setting on a page that has no Save button. The poll timer lives on the controller for the reason `LaunchController` keeps its own there: a `slint::Timer` stops when dropped, so one local to the function that starts it would be collected before the listing arrived. Carries in-flight work from a parallel session — a segmentation pass in dr-gpu, a sidecar cache, and the develop panel's continuing changes. 1020 tests pass, fmt clean. One clippy warning remains and is not mine: `sidecar_cache::dir` is unused while that work is in progress. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,334 @@
|
||||
# Region segmentation for local masking
|
||||
|
||||
Spec for **S15**, the spike that decides how DarkRoom finds the boundaries a local mask snaps to.
|
||||
|
||||
Local adjustments (FR-DEV-3, "linear gradient, radial gradient, and brush masks") need more than
|
||||
placement handles to be competitive. The interactions that matter — click to select a region, drag a
|
||||
contour that clings to an edge, paint without crossing a boundary — all need the same thing
|
||||
underneath: **a map of where the image's regions are.**
|
||||
|
||||
There are two credible ways to produce that map and they are not obviously ordered. This document
|
||||
specifies both, specifies the third option of combining them, and fixes the measurements that decide
|
||||
between them *before* any of them is built.
|
||||
|
||||
---
|
||||
|
||||
## 1. Why this is a spike and not a build
|
||||
|
||||
Three properties make the choice expensive to get wrong.
|
||||
|
||||
**It sets the mask representation.** If regions exist, a mask is a *set of region ids* — integers,
|
||||
diffable, mergeable at node level under FR-NC-9, cheap in a sidecar. If they don't, a mask is a
|
||||
raster, and rasters are none of those things. This is the decision that is expensive to retrofit;
|
||||
everything else in local masking sits on top of it.
|
||||
|
||||
**One arm collides with a settled policy.** D13 records that every dependency choice in this project
|
||||
has gone the same way — rustls over aws-lc-rs, bundled SQLite, a Rust Lensfun port, zune-jpeg — to
|
||||
avoid a C dependency under the Android NDK, and names `ort` as the largest exception that policy
|
||||
would tolerate. Arm B needs exactly that exception. Arm A needs no new dependency at all. That
|
||||
asymmetry is not a tiebreak, it is most of the cost difference, and it should be priced honestly
|
||||
rather than discovered at packaging time.
|
||||
|
||||
**Model licensing is a distribution blocker.** D13 already establishes this for the face pipeline,
|
||||
and the same reading applies here — see §7. It is a licence-reading exercise, not a research
|
||||
question, and it comes first.
|
||||
|
||||
---
|
||||
|
||||
## 2. The common interface
|
||||
|
||||
Both arms produce the same thing. This is what makes them comparable, and what lets the choice be
|
||||
deferred behind a seam rather than baked into every consumer.
|
||||
|
||||
```rust
|
||||
/// A partition of the image into labelled regions.
|
||||
pub struct RegionField {
|
||||
/// Per-pixel region id at proxy resolution. R32Uint on the GPU.
|
||||
labels: Texture,
|
||||
/// Per-region summary: pixel count, bounding box, mean colour,
|
||||
/// and (arm B only) a semantic class id.
|
||||
regions: Vec<Region>,
|
||||
/// Boundary strength per adjacent region pair — the edge weight
|
||||
/// the merge tree is built from and the cost field reads.
|
||||
adjacency: Vec<(RegionId, RegionId, f32)>,
|
||||
}
|
||||
```
|
||||
|
||||
Two consumers sit on it, and neither knows which arm produced it:
|
||||
|
||||
**A cost field, for contour snapping.** Live-wire — Dijkstra from the last anchor to the cursor over
|
||||
a per-pixel cost that is *low* on boundaries. The cost is a **sum of terms**, which is the property
|
||||
that matters: image gradient is always available, region boundary strength is added when a
|
||||
`RegionField` exists, and a semantic boundary term is added when a model is present. Each source
|
||||
improves the snap without changing the interface, so the arms are not exclusive here even in
|
||||
principle.
|
||||
|
||||
**A region set, for click selection.** Click reads the label under the cursor; the mask is
|
||||
`label(px) ∈ selected`. Add and subtract are set operations on ids. No flood fill, no readback, no
|
||||
iteration — the whole reason the precomputed map is worth having.
|
||||
|
||||
Both consumers are built once, in the spike, and shared by both arms. A comparison in which each arm
|
||||
gets its own consumer measures the consumers.
|
||||
|
||||
---
|
||||
|
||||
## 3. Arm A — multiscale watershed
|
||||
|
||||
No model, no new dependency, deterministic, works on any image.
|
||||
|
||||
**Gradient.** Sobel magnitude over a perceptual luma plus chroma distance, not camera-space RGB —
|
||||
channel-weighted RGB gradient reads a saturated red edge as weaker than it looks. Computed after
|
||||
demosaic and denoise, before the edit graph, so an exposure change does not invalidate it.
|
||||
|
||||
**Pre-smoothing is not optional.** Raw watershed on a noisy file makes every grain its own basin.
|
||||
A guided or bilateral pre-filter, with strength tied to the file's ISO, is part of the arm rather
|
||||
than a refinement of it.
|
||||
|
||||
**Basins.** Each pixel points downhill to its steepest neighbour; pointer-jumping resolves every
|
||||
pixel to its basin root in log passes. Two compute shaders and a dispatch loop.
|
||||
|
||||
**The hierarchy is the cheap part.** Build the region adjacency graph, sort edges by boundary
|
||||
strength, union-find over them, and *record the merge order*. That recording is the merge tree — a
|
||||
click selects a leaf, and a scroll walks up through progressively coarser merges. Textbook Kruskal on
|
||||
a graph of a few thousand nodes.
|
||||
|
||||
That node count is why the tree build is a legitimate CPU operation: it runs on the adjacency graph,
|
||||
not on pixels. Pixels stay on the GPU, the graph is CPU-side — the same split ARCH §3.4 and §6.1
|
||||
already draw for the edit graph, so no exception to the no-readback rule is needed.
|
||||
|
||||
**Known weaknesses, to be measured rather than argued about:** over-segmentation on noise and
|
||||
texture, weak boundaries where contrast is low but semantics are obvious (a pale sky meeting a pale
|
||||
wall), and a granularity ladder that is geometric rather than meaningful — level 7 is *a* coarser
|
||||
partition, not necessarily *the* object.
|
||||
|
||||
---
|
||||
|
||||
## 4. Arm B — semantic segmentation
|
||||
|
||||
YOLO26-seg pretrained on ADE20K, run through `ort`.
|
||||
|
||||
ADE20K's 150 classes include stuff — sky, vegetation, water, wall, road — which is a far better
|
||||
vocabulary for photography than COCO's 80 thing-classes. "That patch of sky" is a class here. The
|
||||
nano variant is ~1.6M parameters, which is genuinely mobile-viable in a way SAM never was.
|
||||
|
||||
**It produces a flat partition with class ids**, so it populates `RegionField` directly: connected
|
||||
components of the class map become regions, class boundaries become adjacency edges.
|
||||
|
||||
**What it does not produce is a hierarchy.** One partition at one semantic granularity. Click "sky"
|
||||
and you get all the sky; there is no level at which you get *this part* of the sky. Adjacent
|
||||
same-class regions merge whether or not you wanted them to — two different walls are one wall.
|
||||
|
||||
**Boundaries are semantically right and geometrically soft.** Internal stride is 4–8, upsampled to
|
||||
H×W, so the class map is confident about *which* side of the boundary a pixel is on and vague about
|
||||
*where* the boundary is to the pixel. Acceptable for biasing a contour. Not acceptable as a mask
|
||||
edge at 100% zoom.
|
||||
|
||||
**Costs it brings that arm A does not:** a C dependency on the Android NDK against D13's policy, a
|
||||
model to distribute and cache, an AGPL question (§7), an inference runtime per platform, and output
|
||||
whose determinism across drivers is unproven (§6).
|
||||
|
||||
---
|
||||
|
||||
## 5. Arm C — semantic as a merge prior
|
||||
|
||||
The arms are not alternatives, and a comparison that omits their combination is a false dichotomy.
|
||||
|
||||
Weight each region-adjacency edge in arm A's union-find by boundary strength **and** by whether the
|
||||
two regions share a semantic class. Regions that agree semantically merge earlier.
|
||||
|
||||
The result is a hierarchy whose coarse levels align with semantic objects and whose fine levels stay
|
||||
pixel-accurate — the model doing what models are good at, which is knowing what things *are*, and
|
||||
watershed doing what it is good at, which is knowing where boundaries are, exactly, at every scale.
|
||||
It also repairs arm B's two weaknesses at once: the soft boundary is replaced by the watershed
|
||||
boundary underneath it, and the missing granularity ladder is arm A's.
|
||||
|
||||
Arm C is the expected winner on quality. The question the spike actually has to answer is therefore
|
||||
not "which is better" but **how much better than arm A alone, and is that increment worth D13's
|
||||
cost.** §8 fixes that threshold in advance.
|
||||
|
||||
---
|
||||
|
||||
## 6. What gets measured
|
||||
|
||||
Per arm, over the corpus in §9, using the shared consumers from §2.
|
||||
|
||||
| # | Measure | Method | Why it decides anything |
|
||||
|---|---|---|---|
|
||||
| **M1** | **Interactions to target mask** | Clicks plus scroll steps to reach ≥95% IoU against a hand-traced mask | The real UX metric. "How many actions to get the mask I meant" is what a user experiences |
|
||||
| **M2** | **Boundary accuracy** | Precision/recall of snapped-contour pixels within a 2px slack of the hand trace | Whether the edge survives 100% zoom, where masks are actually judged |
|
||||
| **M3** | **Granularity coverage** | Per case, yes/no: does *any* hierarchy level produce the target region? | A hard failure mode. Arm B is expected to fail this wherever the target is not a class |
|
||||
| **M4** | **Out-of-vocabulary behaviour** | M1 and M3 restricted to the OOV subset | Whether the arm degrades gracefully or produces nothing usable off-distribution |
|
||||
| **M5** | **Determinism** | Same input twice on one machine; then across Mesa/AMD, NVIDIA, and Adreno | Gates whether a label field can be a cache key at all — see below |
|
||||
| **M6** | **Precompute cost** | ms at proxy resolution and peak memory, on the reference desktop and one Android device | Whether it fits a background prefetch alongside the proxy |
|
||||
| **M7** | **Distribution cost** | Added binary size, model size, new native dependencies, licence | D13's axis. Priced, not assumed |
|
||||
|
||||
**M5 deserves its own note, and it is a risk for arm A too.** ARCH §6.13 holds that cache keys are
|
||||
computed over CPU-side *integer* state because GPU float results diverge across vendors. A label
|
||||
field is integer state — but it is *derived from* float gradient arithmetic, so a boundary sitting
|
||||
exactly between two basins could resolve differently on Adreno than on Mesa. If either arm proves
|
||||
non-deterministic across vendors, its output cannot be a cache key and cannot round-trip through a
|
||||
sidecar as region ids, which would push masks back toward rasters and undo most of §1's argument.
|
||||
This is the measurement most likely to invalidate the whole approach, and it should be run early
|
||||
rather than last.
|
||||
|
||||
---
|
||||
|
||||
## 7. Licence reading — before any code
|
||||
|
||||
D13's position applies unchanged: discovering at packaging time that a feature cannot ship is the
|
||||
expensive failure, and it is entirely avoidable.
|
||||
|
||||
**Ultralytics ships YOLO under AGPL-3.0** — confirmed 2026-08-17 by reading `LICENSE` at the head of
|
||||
`github.com/ultralytics/ultralytics`, which is the GNU Affero General Public License v3 verbatim.
|
||||
That is deliberate on their part; the commercial licence is their business model.
|
||||
|
||||
GPLv3 §13 explicitly permits the combination, so this is *not* the blocker the InsightFace
|
||||
non-commercial weights were: it is redistributable. But the combined work becomes effectively AGPL,
|
||||
which is a change to DarkRoom's licensing posture rather than a dependency detail, and it needs to be
|
||||
a decision made on purpose.
|
||||
|
||||
Still to verify before writing any of arm B:
|
||||
|
||||
- The licence on YOLO26 specifically, and on the ADE20K-pretrained weights *separately* from the
|
||||
framework code — they are not necessarily the same grant.
|
||||
- Whether ADE20K's own terms permit redistribution of weights derived from it.
|
||||
- Whether AGPL is acceptable for DarkRoom, given Flatpak, F-Droid and Play distribution
|
||||
(NFR-COMPAT-2).
|
||||
|
||||
**Arm A raises none of these questions**, which is worth stating plainly as part of its cost.
|
||||
|
||||
---
|
||||
|
||||
## 8. Decision criteria, fixed in advance
|
||||
|
||||
Stated now so the result cannot be rationalised afterwards.
|
||||
|
||||
- **Arm A ships alone** if it reaches within **one interaction** (M1) of arm C on the scene subset
|
||||
*and* dominates arm C on the OOV subset (M4). The semantic increment does not then justify a C
|
||||
dependency, an AGPL conversion, and a per-platform inference runtime.
|
||||
- **Arm C ships** if it beats arm A by **two or more interactions** on the scene subset without
|
||||
regressing OOV. That is a large enough difference to be felt in ordinary use, and it is what would
|
||||
justify reopening D13.
|
||||
- **Arm B never ships alone.** M3 is expected to fail on anything that is not an ADE20K class, and an
|
||||
arm with a hard failure mode and no fallback is not a selection tool. If it surprises us and passes
|
||||
M3 broadly, that is a genuine finding and this criterion is revisited on the evidence.
|
||||
- **If M5 fails for an arm across vendors**, that arm cannot carry region ids into the sidecar
|
||||
regardless of how it scored elsewhere.
|
||||
|
||||
---
|
||||
|
||||
## 9. Corpus
|
||||
|
||||
Roughly 24 images from a real library — three per category — hand-traced once and reused across all
|
||||
arms. Categories chosen for the failure modes they provoke, not for coverage:
|
||||
|
||||
| Category | Provokes |
|
||||
|---|---|
|
||||
| Gradient sky | Low-contrast boundary; watershed banding |
|
||||
| Foliage against sky | High-frequency boundary — arm A over-segments, arm B blurs |
|
||||
| Hair against a busy background | The classic hard mask edge |
|
||||
| Out-of-focus background | No edges at all; tests graceful failure in both |
|
||||
| High-ISO noise | Arm A's known weakness; tests whether pre-smoothing is sufficient |
|
||||
| Backlit silhouette | Strong unambiguous edge — the control case |
|
||||
| Macro, abstract, still life | **OOV for ADE20K.** Arm B expected to fail M3 here |
|
||||
| Architectural detail | Repeated structure; arm B merges distinct walls into one class |
|
||||
|
||||
Hand-tracing 24 masks is a couple of hours and it is what makes M1 and M2 mean anything. Without
|
||||
ground truth this comparison is two demos and a preference.
|
||||
|
||||
---
|
||||
|
||||
## 10. Deliverables
|
||||
|
||||
Nothing in the UI, nothing in the graph, nothing in the sidecar.
|
||||
|
||||
- `core/dr-gpu/src/shaders/watershed.wgsl` — gradient and basin propagation.
|
||||
- `core/dr-gpu/src/segment.rs` — the passes, producing a `RegionField`.
|
||||
- RAG construction and the union-find merge tree as a pure-CPU module with unit tests and no device,
|
||||
so the hierarchy is testable headless the way `dr-pipeline` is (ARCH §6.5a).
|
||||
- The two shared consumers from §2 — live-wire over a summable cost field, and region-set selection.
|
||||
- `core/dr-gpu/examples/segment.rs` — false-coloured PNGs at four or five hierarchy levels, plus the
|
||||
M1/M2 numbers against the traced corpus.
|
||||
|
||||
It graduates to `core/dr-segment` if it ships; that is not a spike decision.
|
||||
|
||||
---
|
||||
|
||||
## 11. Order
|
||||
|
||||
1. **Licence reading (§7).** Hours, and it can eliminate arm B before anything is built.
|
||||
2. **Arm A, and the shared consumers.** About a day. Look at the false-coloured PNGs — if the
|
||||
granularity ladder does not feel right, nothing downstream matters and that is worth knowing
|
||||
immediately.
|
||||
3. **M5 across vendors, early.** It is the measurement that can invalidate the region-id
|
||||
representation entirely, and it wants knowing before the corpus work is invested.
|
||||
4. **The traced corpus, then M1–M4 on arm A.** Establishes the baseline every other arm is judged
|
||||
against.
|
||||
5. **Arms B and C**, only if §7 cleared and arm A's baseline leaves room worth closing.
|
||||
|
||||
Arm A is a day and needs no model, no runtime, no licence and no new dependency. It is also the
|
||||
substrate every model-based arm writes into — so it is first regardless of how the comparison
|
||||
eventually lands.
|
||||
|
||||
---
|
||||
|
||||
## 12. Arm A results
|
||||
|
||||
Built 2026-08-17. `core/dr-gpu/src/{segment.rs,hierarchy.rs}`,
|
||||
`shaders/watershed.wgsl`, `examples/segment.rs`. 15 tests, 11 of them device-free.
|
||||
|
||||
**It works, and the hierarchy is not the expensive part.** On a 1200×800 synthetic at blur radius 2,
|
||||
release build, RTX 3050 laptop: 6,730 basins and 19,223 boundaries found in **67 ms including the
|
||||
readback**, and the merge tree built from them in **0.2 ms**. The tree is ~0.3% of the cost. The
|
||||
estimate that priced it as a week's work was wrong by about two orders of magnitude, and the reason
|
||||
is worth recording: it is Kruskal over a few thousand nodes, not a segmentation algorithm.
|
||||
|
||||
**The granularity ladder behaves.** At the fine end the background fragments badly — a smooth tonal
|
||||
ramp bands into horizontal strips, and flat areas break into diagonal chains (see below). By
|
||||
`cut_to(300)` all of that is gone: the hard-edged disc is exactly one region, the whole gradient
|
||||
background is one region, and only genuine noise still fragments. The over-segmentation is absorbed
|
||||
by the merge order rather than needing to be prevented, which is the property the whole design rests
|
||||
on.
|
||||
|
||||
**Pre-smoothing is the knob it was claimed to be.** Radius 2 leaves the noisy corner fragmented at
|
||||
300 regions; radius 5 largely clears it. Tying it to ISO is the right control.
|
||||
|
||||
Three findings that change what comes next:
|
||||
|
||||
**F1 — plateaux fragment into diagonal chains.** In an exactly flat region every pixel's steepest
|
||||
descent is a tie, and the (value, index) tie-break sends them all up-left, so a plateau resolves into
|
||||
diagonal streaks rather than one basin. Harmless here because those saddles are ~0 and the tree
|
||||
merges them first — but a real sky or wall is a large plateau, and relying on the hierarchy to clean
|
||||
up an artefact of the flow pass is fragile. The principled fix is a **lower-complete transform**: one
|
||||
extra pass giving plateau pixels a gradient toward their nearest descending exit. Standard, cheap,
|
||||
and worth doing before the corpus work.
|
||||
|
||||
**F2 — `cut_to(N)` is a visualisation, not the interaction.** A global cut by region count spends its
|
||||
budget wherever the saddles happen to be densest: at blur 5 the soft-edged disc's interior held a
|
||||
cluster of near-equal saddles and ate the budget, fragmenting at a level where everything else was
|
||||
clean. The real interaction walks up locally from the clicked region and has no such coupling. The
|
||||
ladder in the example should not be read as what a user would experience.
|
||||
|
||||
**F3 — the RAG build still needs a readback.** `Segmentation::read_field` copies labels and gradient
|
||||
to the CPU, gated behind the `readback` feature exactly as `read_pixels` is. Fine for a spike and
|
||||
off the frame path, but a shipping build cannot take it (ARCH §6.1, AC-8), so the adjacency
|
||||
accumulation has to move GPU-side with atomics. That is the largest known gap between this and
|
||||
something shippable.
|
||||
|
||||
**M5 partially answered.** Run-to-run on one device is bit-identical, and the CPU half contributes no
|
||||
nondeterminism of its own — both asserted by tests. Cross-vendor is untouched and remains the
|
||||
measurement that can invalidate the region-id representation.
|
||||
|
||||
---
|
||||
|
||||
## 13. Register entries
|
||||
|
||||
To be added when this is accepted:
|
||||
|
||||
**S15** — *Region segmentation for local masking:* implement arm A and the shared consumers, trace a
|
||||
24-image corpus, measure M1–M7 across arms. **Resolve the licence question before writing arm B.**
|
||||
Answers: which segmentation source local masking snaps to, and whether a mask can be stored as region
|
||||
ids at all. Relates to: D13, D14, FR-DEV-3, ARCH §5.4, §6.13.
|
||||
|
||||
**D14** — *Segmentation source for local masking* · **OPEN**. Decided by S15 against the criteria in
|
||||
§8. Reopens D13's dependency-policy question if arm C wins.
|
||||
+25
-25
@@ -9,8 +9,8 @@ Denominators are parsed from [`requirements.md`](requirements.md) at run time, n
|
||||
|
||||
| Metric | Value |
|
||||
|---|---|
|
||||
| Source files scanned | 113 |
|
||||
| TRACES tags found | 186 |
|
||||
| Source files scanned | 118 |
|
||||
| TRACES tags found | 199 |
|
||||
| Requirements defined | 151 |
|
||||
| Requirements covered | 77 |
|
||||
| **Coverage** | **51.0%** (77/151) |
|
||||
@@ -34,53 +34,53 @@ _None._
|
||||
| ID | Tagged in |
|
||||
|---|---|
|
||||
| FR-CAT-1 | [`core/dr-catalog/src/scan.rs:1`](../core/dr-catalog/src/scan.rs#L1), [`core/dr-sync/src/scan.rs:93`](../core/dr-sync/src/scan.rs#L93), [`core/dr-types/src/lib.rs:185`](../core/dr-types/src/lib.rs#L185), [`tools/traceability/src/lib.rs:479`](../tools/traceability/src/lib.rs#L479), [`tools/traceability/src/lib.rs:511`](../tools/traceability/src/lib.rs#L511), [`ui/dr-ui/src/activity.rs:1`](../ui/dr-ui/src/activity.rs#L1), [`ui/dr-ui/src/library.rs:1`](../ui/dr-ui/src/library.rs#L1) |
|
||||
| FR-CAT-11 | [`ui/dr-ui/src/library.rs:150`](../ui/dr-ui/src/library.rs#L150) |
|
||||
| FR-CAT-11 | [`ui/dr-ui/src/library.rs:152`](../ui/dr-ui/src/library.rs#L152) |
|
||||
| FR-CAT-12 | [`core/dr-pipeline/src/sidecar.rs:108`](../core/dr-pipeline/src/sidecar.rs#L108) |
|
||||
| FR-CAT-15 | [`core/dr-catalog/src/schema.rs:258`](../core/dr-catalog/src/schema.rs#L258), [`core/dr-catalog/src/trash.rs:1`](../core/dr-catalog/src/trash.rs#L1), [`core/dr-sync-nextcloud/src/lib.rs:366`](../core/dr-sync-nextcloud/src/lib.rs#L366), [`core/dr-sync/src/lib.rs:122`](../core/dr-sync/src/lib.rs#L122), [`core/dr-sync/src/scan.rs:426`](../core/dr-sync/src/scan.rs#L426), [`core/dr-sync/src/scan.rs:57`](../core/dr-sync/src/scan.rs#L57), [`core/dr-thumbs/src/lib.rs:376`](../core/dr-thumbs/src/lib.rs#L376), [`ui/dr-ui/src/collections_ui.rs:1299`](../ui/dr-ui/src/collections_ui.rs#L1299), [`ui/dr-ui/src/collections_ui.rs:817`](../ui/dr-ui/src/collections_ui.rs#L817), [`ui/dr-ui/src/library.rs:150`](../ui/dr-ui/src/library.rs#L150), [`ui/dr-ui/src/library.rs:167`](../ui/dr-ui/src/library.rs#L167), [`ui/dr-ui/src/library.rs:2135`](../ui/dr-ui/src/library.rs#L2135), [`ui/dr-ui/src/library.rs:2167`](../ui/dr-ui/src/library.rs#L2167), [`ui/dr-ui/src/library_ui.rs:112`](../ui/dr-ui/src/library_ui.rs#L112), [`ui/dr-ui/src/library_ui.rs:476`](../ui/dr-ui/src/library_ui.rs#L476), [`ui/dr-ui/src/trash.rs:1`](../ui/dr-ui/src/trash.rs#L1), [`ui/dr-ui/ui/collections.slint:458`](../ui/dr-ui/ui/collections.slint#L458) |
|
||||
| FR-CAT-15 | [`core/dr-catalog/src/schema.rs:258`](../core/dr-catalog/src/schema.rs#L258), [`core/dr-catalog/src/trash.rs:1`](../core/dr-catalog/src/trash.rs#L1), [`core/dr-sync-nextcloud/src/lib.rs:366`](../core/dr-sync-nextcloud/src/lib.rs#L366), [`core/dr-sync/src/lib.rs:122`](../core/dr-sync/src/lib.rs#L122), [`core/dr-sync/src/scan.rs:426`](../core/dr-sync/src/scan.rs#L426), [`core/dr-sync/src/scan.rs:57`](../core/dr-sync/src/scan.rs#L57), [`core/dr-thumbs/src/lib.rs:376`](../core/dr-thumbs/src/lib.rs#L376), [`ui/dr-ui/src/collections_ui.rs:1299`](../ui/dr-ui/src/collections_ui.rs#L1299), [`ui/dr-ui/src/collections_ui.rs:817`](../ui/dr-ui/src/collections_ui.rs#L817), [`ui/dr-ui/src/library.rs:152`](../ui/dr-ui/src/library.rs#L152), [`ui/dr-ui/src/library.rs:169`](../ui/dr-ui/src/library.rs#L169), [`ui/dr-ui/src/library.rs:2430`](../ui/dr-ui/src/library.rs#L2430), [`ui/dr-ui/src/library.rs:2462`](../ui/dr-ui/src/library.rs#L2462), [`ui/dr-ui/src/library_ui.rs:112`](../ui/dr-ui/src/library_ui.rs#L112), [`ui/dr-ui/src/library_ui.rs:508`](../ui/dr-ui/src/library_ui.rs#L508), [`ui/dr-ui/src/trash.rs:1`](../ui/dr-ui/src/trash.rs#L1), [`ui/dr-ui/ui/collections.slint:458`](../ui/dr-ui/ui/collections.slint#L458) |
|
||||
| FR-CAT-1a | [`core/dr-types/src/lib.rs:47`](../core/dr-types/src/lib.rs#L47) |
|
||||
| FR-CAT-2 | [`core/dr-catalog/src/lib.rs:1`](../core/dr-catalog/src/lib.rs#L1), [`core/dr-catalog/src/schema.rs:1`](../core/dr-catalog/src/schema.rs#L1), [`tools/traceability/src/lib.rs:479`](../tools/traceability/src/lib.rs#L479) |
|
||||
| FR-CAT-3 | [`core/dr-catalog/src/jobs.rs:1`](../core/dr-catalog/src/jobs.rs#L1), [`core/dr-sync/src/scan.rs:69`](../core/dr-sync/src/scan.rs#L69), [`core/dr-thumbs/src/codec.rs:1`](../core/dr-thumbs/src/codec.rs#L1), [`core/dr-thumbs/src/lib.rs:1`](../core/dr-thumbs/src/lib.rs#L1), [`ui/dr-ui/src/derived_sync.rs:1`](../ui/dr-ui/src/derived_sync.rs#L1) |
|
||||
| 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), [`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) |
|
||||
| FR-CAT-5 | [`core/dr-catalog/src/rating.rs:1`](../core/dr-catalog/src/rating.rs#L1), [`core/dr-decode/src/lib.rs:240`](../core/dr-decode/src/lib.rs#L240), [`core/dr-decode/src/lib.rs:307`](../core/dr-decode/src/lib.rs#L307), [`core/dr-pipeline/src/sidecar.rs:125`](../core/dr-pipeline/src/sidecar.rs#L125) |
|
||||
| FR-CAT-6 | [`core/dr-catalog/src/collections.rs:1`](../core/dr-catalog/src/collections.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-types/src/selector.rs:1`](../core/dr-types/src/selector.rs#L1), [`ui/dr-ui/src/library.rs:177`](../ui/dr-ui/src/library.rs#L177) |
|
||||
| FR-CAT-6 | [`core/dr-catalog/src/collections.rs:1`](../core/dr-catalog/src/collections.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-types/src/selector.rs:1`](../core/dr-types/src/selector.rs#L1), [`ui/dr-ui/src/library.rs:179`](../ui/dr-ui/src/library.rs#L179) |
|
||||
| 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:1`](../ui/dr-ui/src/collections_ui.rs#L1), [`ui/dr-ui/src/derived_sync.rs:1`](../ui/dr-ui/src/derived_sync.rs#L1), [`ui/dr-ui/ui/collections.slint:4`](../ui/dr-ui/ui/collections.slint#L4) |
|
||||
| FR-CAT-8 | [`core/dr-pipeline/src/sidecar.rs:89`](../core/dr-pipeline/src/sidecar.rs#L89), [`ui/dr-ui/src/develop.rs:820`](../ui/dr-ui/src/develop.rs#L820), [`ui/dr-ui/src/lib.rs:1114`](../ui/dr-ui/src/lib.rs#L1114), [`ui/dr-ui/src/lib.rs:1214`](../ui/dr-ui/src/lib.rs#L1214), [`ui/dr-ui/src/lib.rs:405`](../ui/dr-ui/src/lib.rs#L405), [`ui/dr-ui/src/lib.rs:607`](../ui/dr-ui/src/lib.rs#L607), [`ui/dr-ui/src/lib.rs:815`](../ui/dr-ui/src/lib.rs#L815), [`ui/dr-ui/src/library.rs:1075`](../ui/dr-ui/src/library.rs#L1075), [`ui/dr-ui/src/library.rs:289`](../ui/dr-ui/src/library.rs#L289), [`ui/dr-ui/src/library_ui.rs:2995`](../ui/dr-ui/src/library_ui.rs#L2995) |
|
||||
| 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:230`](../core/dr-catalog/src/schema.rs#L230), [`core/dr-sync-nextcloud/src/desktop_client.rs:30`](../core/dr-sync-nextcloud/src/desktop_client.rs#L30), [`core/dr-sync/src/reachability.rs:1`](../core/dr-sync/src/reachability.rs#L1), [`core/dr-types/src/lib.rs:104`](../core/dr-types/src/lib.rs#L104), [`ui/dr-ui/src/library.rs:1035`](../ui/dr-ui/src/library.rs#L1035), [`ui/dr-ui/src/library.rs:136`](../ui/dr-ui/src/library.rs#L136), [`ui/dr-ui/src/library.rs:194`](../ui/dr-ui/src/library.rs#L194), [`ui/dr-ui/src/library.rs:2255`](../ui/dr-ui/src/library.rs#L2255), [`ui/dr-ui/src/library_ui.rs:1014`](../ui/dr-ui/src/library_ui.rs#L1014), [`ui/dr-ui/src/library_ui.rs:1056`](../ui/dr-ui/src/library_ui.rs#L1056), [`ui/dr-ui/src/library_ui.rs:1318`](../ui/dr-ui/src/library_ui.rs#L1318), [`ui/dr-ui/src/library_ui.rs:1583`](../ui/dr-ui/src/library_ui.rs#L1583), [`ui/dr-ui/src/library_ui.rs:165`](../ui/dr-ui/src/library_ui.rs#L165), [`ui/dr-ui/src/library_ui.rs:1902`](../ui/dr-ui/src/library_ui.rs#L1902), [`ui/dr-ui/src/library_ui.rs:1974`](../ui/dr-ui/src/library_ui.rs#L1974), [`ui/dr-ui/src/library_ui.rs:2139`](../ui/dr-ui/src/library_ui.rs#L2139), [`ui/dr-ui/src/library_ui.rs:291`](../ui/dr-ui/src/library_ui.rs#L291), [`ui/dr-ui/src/library_ui.rs:3147`](../ui/dr-ui/src/library_ui.rs#L3147), [`ui/dr-ui/src/library_ui.rs:3175`](../ui/dr-ui/src/library_ui.rs#L3175) |
|
||||
| FR-CAT-8 | [`core/dr-pipeline/src/sidecar.rs:89`](../core/dr-pipeline/src/sidecar.rs#L89), [`ui/dr-ui/src/develop.rs:852`](../ui/dr-ui/src/develop.rs#L852), [`ui/dr-ui/src/lib.rs:1236`](../ui/dr-ui/src/lib.rs#L1236), [`ui/dr-ui/src/lib.rs:1341`](../ui/dr-ui/src/lib.rs#L1341), [`ui/dr-ui/src/lib.rs:406`](../ui/dr-ui/src/lib.rs#L406), [`ui/dr-ui/src/lib.rs:608`](../ui/dr-ui/src/lib.rs#L608), [`ui/dr-ui/src/lib.rs:937`](../ui/dr-ui/src/lib.rs#L937), [`ui/dr-ui/src/library.rs:1329`](../ui/dr-ui/src/library.rs#L1329), [`ui/dr-ui/src/library.rs:291`](../ui/dr-ui/src/library.rs#L291), [`ui/dr-ui/src/library.rs:349`](../ui/dr-ui/src/library.rs#L349), [`ui/dr-ui/src/library.rs:567`](../ui/dr-ui/src/library.rs#L567), [`ui/dr-ui/src/library_ui.rs:3136`](../ui/dr-ui/src/library_ui.rs#L3136), [`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:230`](../core/dr-catalog/src/schema.rs#L230), [`core/dr-sync-nextcloud/src/desktop_client.rs:30`](../core/dr-sync-nextcloud/src/desktop_client.rs#L30), [`core/dr-sync/src/reachability.rs:1`](../core/dr-sync/src/reachability.rs#L1), [`core/dr-types/src/lib.rs:104`](../core/dr-types/src/lib.rs#L104), [`ui/dr-ui/src/library.rs:1289`](../ui/dr-ui/src/library.rs#L1289), [`ui/dr-ui/src/library.rs:1366`](../ui/dr-ui/src/library.rs#L1366), [`ui/dr-ui/src/library.rs:138`](../ui/dr-ui/src/library.rs#L138), [`ui/dr-ui/src/library.rs:196`](../ui/dr-ui/src/library.rs#L196), [`ui/dr-ui/src/library.rs:2550`](../ui/dr-ui/src/library.rs#L2550), [`ui/dr-ui/src/library.rs:349`](../ui/dr-ui/src/library.rs#L349), [`ui/dr-ui/src/library.rs:547`](../ui/dr-ui/src/library.rs#L547), [`ui/dr-ui/src/library.rs:567`](../ui/dr-ui/src/library.rs#L567), [`ui/dr-ui/src/library.rs:621`](../ui/dr-ui/src/library.rs#L621), [`ui/dr-ui/src/library_ui.rs:1046`](../ui/dr-ui/src/library_ui.rs#L1046), [`ui/dr-ui/src/library_ui.rs:1072`](../ui/dr-ui/src/library_ui.rs#L1072), [`ui/dr-ui/src/library_ui.rs:1088`](../ui/dr-ui/src/library_ui.rs#L1088), [`ui/dr-ui/src/library_ui.rs:1182`](../ui/dr-ui/src/library_ui.rs#L1182), [`ui/dr-ui/src/library_ui.rs:1444`](../ui/dr-ui/src/library_ui.rs#L1444), [`ui/dr-ui/src/library_ui.rs:146`](../ui/dr-ui/src/library_ui.rs#L146), [`ui/dr-ui/src/library_ui.rs:1709`](../ui/dr-ui/src/library_ui.rs#L1709), [`ui/dr-ui/src/library_ui.rs:179`](../ui/dr-ui/src/library_ui.rs#L179), [`ui/dr-ui/src/library_ui.rs:2043`](../ui/dr-ui/src/library_ui.rs#L2043), [`ui/dr-ui/src/library_ui.rs:2115`](../ui/dr-ui/src/library_ui.rs#L2115), [`ui/dr-ui/src/library_ui.rs:2280`](../ui/dr-ui/src/library_ui.rs#L2280), [`ui/dr-ui/src/library_ui.rs:307`](../ui/dr-ui/src/library_ui.rs#L307), [`ui/dr-ui/src/library_ui.rs:3288`](../ui/dr-ui/src/library_ui.rs#L3288), [`ui/dr-ui/src/library_ui.rs:3316`](../ui/dr-ui/src/library_ui.rs#L3316), [`ui/dr-ui/src/library_ui.rs:365`](../ui/dr-ui/src/library_ui.rs#L365), [`ui/dr-ui/src/sidecar_cache.rs:1`](../ui/dr-ui/src/sidecar_cache.rs#L1) |
|
||||
| FR-CULL-1 | [`core/dr-decode/src/preview.rs:134`](../core/dr-decode/src/preview.rs#L134) |
|
||||
| FR-CULL-2 | [`core/dr-decode/src/locate.rs:1`](../core/dr-decode/src/locate.rs#L1), [`core/dr-decode/src/preview.rs:161`](../core/dr-decode/src/preview.rs#L161) |
|
||||
| FR-CULL-4 | [`core/dr-catalog/src/rating.rs:1`](../core/dr-catalog/src/rating.rs#L1), [`core/dr-pipeline/src/sidecar.rs:125`](../core/dr-pipeline/src/sidecar.rs#L125), [`ui/dr-ui/src/library.rs:177`](../ui/dr-ui/src/library.rs#L177), [`ui/dr-ui/src/library.rs:289`](../ui/dr-ui/src/library.rs#L289) |
|
||||
| FR-CULL-4 | [`core/dr-catalog/src/rating.rs:1`](../core/dr-catalog/src/rating.rs#L1), [`core/dr-pipeline/src/sidecar.rs:125`](../core/dr-pipeline/src/sidecar.rs#L125), [`ui/dr-ui/src/library.rs:179`](../ui/dr-ui/src/library.rs#L179), [`ui/dr-ui/src/library.rs:291`](../ui/dr-ui/src/library.rs#L291) |
|
||||
| FR-DEV-3 | [`core/dr-pipeline/src/framing.rs:185`](../core/dr-pipeline/src/framing.rs#L185) |
|
||||
| FR-DEV-3a | [`core/dr-pipeline/build.rs:1734`](../core/dr-pipeline/build.rs#L1734), [`core/dr-pipeline/ops/exposure.yaml:1`](../core/dr-pipeline/ops/exposure.yaml#L1), [`core/dr-pipeline/src/descriptor.rs:117`](../core/dr-pipeline/src/descriptor.rs#L117), [`core/dr-pipeline/src/descriptor.rs:157`](../core/dr-pipeline/src/descriptor.rs#L157), [`core/dr-pipeline/src/descriptor.rs:177`](../core/dr-pipeline/src/descriptor.rs#L177), [`core/dr-pipeline/src/descriptor.rs:232`](../core/dr-pipeline/src/descriptor.rs#L232), [`core/dr-pipeline/src/framing.rs:256`](../core/dr-pipeline/src/framing.rs#L256), [`core/dr-pipeline/src/graph.rs:133`](../core/dr-pipeline/src/graph.rs#L133), [`core/dr-pipeline/src/graph.rs:17`](../core/dr-pipeline/src/graph.rs#L17), [`core/dr-pipeline/src/graph.rs:41`](../core/dr-pipeline/src/graph.rs#L41), [`core/dr-pipeline/src/operation.rs:104`](../core/dr-pipeline/src/operation.rs#L104) |
|
||||
| FR-DEV-3b | [`core/dr-pipeline/src/descriptor.rs:177`](../core/dr-pipeline/src/descriptor.rs#L177), [`core/dr-pipeline/src/framing.rs:256`](../core/dr-pipeline/src/framing.rs#L256), [`core/dr-pipeline/src/graph.rs:41`](../core/dr-pipeline/src/graph.rs#L41), [`core/dr-pipeline/src/operation.rs:104`](../core/dr-pipeline/src/operation.rs#L104) |
|
||||
| FR-DEV-3c | [`core/dr-pipeline/build.rs:1734`](../core/dr-pipeline/build.rs#L1734), [`core/dr-pipeline/ops/exposure.yaml:1`](../core/dr-pipeline/ops/exposure.yaml#L1), [`core/dr-pipeline/src/graph.rs:133`](../core/dr-pipeline/src/graph.rs#L133), [`ui/dr-ui/src/develop.rs:1258`](../ui/dr-ui/src/develop.rs#L1258) |
|
||||
| FR-DEV-3c | [`core/dr-pipeline/build.rs:1734`](../core/dr-pipeline/build.rs#L1734), [`core/dr-pipeline/ops/exposure.yaml:1`](../core/dr-pipeline/ops/exposure.yaml#L1), [`core/dr-pipeline/src/graph.rs:133`](../core/dr-pipeline/src/graph.rs#L133), [`ui/dr-ui/src/develop.rs:1290`](../ui/dr-ui/src/develop.rs#L1290) |
|
||||
| FR-DEV-3d | [`core/dr-pipeline/src/framing.rs:185`](../core/dr-pipeline/src/framing.rs#L185) |
|
||||
| FR-DEV-3e | [`core/dr-decode/src/lib.rs:492`](../core/dr-decode/src/lib.rs#L492), [`core/dr-decode/src/lib.rs:612`](../core/dr-decode/src/lib.rs#L612) |
|
||||
| FR-DEV-3h | [`core/dr-decode/src/lib.rs:307`](../core/dr-decode/src/lib.rs#L307), [`core/dr-decode/src/preview.rs:29`](../core/dr-decode/src/preview.rs#L29), [`core/dr-pipeline/src/framing.rs:199`](../core/dr-pipeline/src/framing.rs#L199), [`core/dr-types/src/lib.rs:272`](../core/dr-types/src/lib.rs#L272) |
|
||||
| FR-DEV-4 | [`core/dr-gpu/src/lib.rs:132`](../core/dr-gpu/src/lib.rs#L132) |
|
||||
| FR-DEV-6 | [`core/dr-pipeline/src/preset.rs:1`](../core/dr-pipeline/src/preset.rs#L1), [`core/dr-types/src/settings.rs:61`](../core/dr-types/src/settings.rs#L61), [`ui/dr-ui/src/develop.rs:801`](../ui/dr-ui/src/develop.rs#L801), [`ui/dr-ui/src/develop.rs:811`](../ui/dr-ui/src/develop.rs#L811), [`ui/dr-ui/src/lib.rs:815`](../ui/dr-ui/src/lib.rs#L815), [`ui/dr-ui/src/library.rs:1075`](../ui/dr-ui/src/library.rs#L1075), [`ui/dr-ui/src/library.rs:289`](../ui/dr-ui/src/library.rs#L289), [`ui/dr-ui/src/library.rs:317`](../ui/dr-ui/src/library.rs#L317), [`ui/dr-ui/src/library_ui.rs:1414`](../ui/dr-ui/src/library_ui.rs#L1414), [`ui/dr-ui/src/library_ui.rs:317`](../ui/dr-ui/src/library_ui.rs#L317), [`ui/dr-ui/src/presets.rs:1`](../ui/dr-ui/src/presets.rs#L1), [`ui/dr-ui/src/settings_ui.rs:434`](../ui/dr-ui/src/settings_ui.rs#L434), [`ui/dr-ui/ui/adjust.slint:569`](../ui/dr-ui/ui/adjust.slint#L569), [`ui/dr-ui/ui/library.slint:455`](../ui/dr-ui/ui/library.slint#L455), [`ui/dr-ui/ui/library.slint:474`](../ui/dr-ui/ui/library.slint#L474), [`ui/dr-ui/ui/library.slint:748`](../ui/dr-ui/ui/library.slint#L748), [`ui/dr-ui/ui/settings.slint:79`](../ui/dr-ui/ui/settings.slint#L79) |
|
||||
| FR-DSP-1 | [`ui/dr-ui/src/lib.rs:47`](../ui/dr-ui/src/lib.rs#L47) |
|
||||
| FR-DEV-4 | [`core/dr-gpu/src/lib.rs:135`](../core/dr-gpu/src/lib.rs#L135) |
|
||||
| FR-DEV-6 | [`core/dr-pipeline/src/preset.rs:1`](../core/dr-pipeline/src/preset.rs#L1), [`core/dr-types/src/settings.rs:61`](../core/dr-types/src/settings.rs#L61), [`ui/dr-ui/src/develop.rs:833`](../ui/dr-ui/src/develop.rs#L833), [`ui/dr-ui/src/develop.rs:843`](../ui/dr-ui/src/develop.rs#L843), [`ui/dr-ui/src/lib.rs:937`](../ui/dr-ui/src/lib.rs#L937), [`ui/dr-ui/src/library.rs:1329`](../ui/dr-ui/src/library.rs#L1329), [`ui/dr-ui/src/library.rs:291`](../ui/dr-ui/src/library.rs#L291), [`ui/dr-ui/src/library.rs:319`](../ui/dr-ui/src/library.rs#L319), [`ui/dr-ui/src/library_ui.rs:1540`](../ui/dr-ui/src/library_ui.rs#L1540), [`ui/dr-ui/src/library_ui.rs:333`](../ui/dr-ui/src/library_ui.rs#L333), [`ui/dr-ui/src/presets.rs:1`](../ui/dr-ui/src/presets.rs#L1), [`ui/dr-ui/src/settings_ui.rs:502`](../ui/dr-ui/src/settings_ui.rs#L502), [`ui/dr-ui/ui/adjust.slint:569`](../ui/dr-ui/ui/adjust.slint#L569), [`ui/dr-ui/ui/library.slint:455`](../ui/dr-ui/ui/library.slint#L455), [`ui/dr-ui/ui/library.slint:474`](../ui/dr-ui/ui/library.slint#L474), [`ui/dr-ui/ui/library.slint:748`](../ui/dr-ui/ui/library.slint#L748), [`ui/dr-ui/ui/settings.slint:79`](../ui/dr-ui/ui/settings.slint#L79) |
|
||||
| FR-DSP-1 | [`ui/dr-ui/src/lib.rs:48`](../ui/dr-ui/src/lib.rs#L48) |
|
||||
| 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-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-3 | [`core/dr-export/src/lib.rs:1`](../core/dr-export/src/lib.rs#L1), [`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-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-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:291`](../ui/dr-ui/src/lib.rs#L291), [`ui/dr-ui/src/settings_ui.rs:1`](../ui/dr-ui/src/settings_ui.rs#L1) |
|
||||
| FR-EXP-7 | [`ui/dr-ui/src/export.rs:1`](../ui/dr-ui/src/export.rs#L1), [`ui/dr-ui/src/library_ui.rs:1991`](../ui/dr-ui/src/library_ui.rs#L1991) |
|
||||
| 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:292`](../ui/dr-ui/src/lib.rs#L292), [`ui/dr-ui/src/settings_ui.rs:1`](../ui/dr-ui/src/settings_ui.rs#L1), [`ui/dr-ui/src/settings_ui.rs:48`](../ui/dr-ui/src/settings_ui.rs#L48), [`ui/dr-ui/src/settings_ui.rs:561`](../ui/dr-ui/src/settings_ui.rs#L561) |
|
||||
| FR-EXP-7 | [`ui/dr-ui/src/export.rs:1`](../ui/dr-ui/src/export.rs#L1), [`ui/dr-ui/src/library_ui.rs:2132`](../ui/dr-ui/src/library_ui.rs#L2132) |
|
||||
| FR-EXP-8 | [`core/dr-export/src/encode.rs:1`](../core/dr-export/src/encode.rs#L1), [`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:409`](../core/dr-decode/src/lib.rs#L409), [`core/dr-export/src/lib.rs:1`](../core/dr-export/src/lib.rs#L1), [`core/dr-export/src/lib.rs:91`](../core/dr-export/src/lib.rs#L91), [`core/dr-gpu/src/adjust.rs:332`](../core/dr-gpu/src/adjust.rs#L332), [`ui/dr-ui/src/develop.rs:542`](../ui/dr-ui/src/develop.rs#L542), [`ui/dr-ui/src/lib.rs:291`](../ui/dr-ui/src/lib.rs#L291) |
|
||||
| FR-EXP-9 | [`core/dr-decode/src/lib.rs:409`](../core/dr-decode/src/lib.rs#L409), [`core/dr-export/src/lib.rs:1`](../core/dr-export/src/lib.rs#L1), [`core/dr-export/src/lib.rs:91`](../core/dr-export/src/lib.rs#L91), [`core/dr-gpu/src/adjust.rs:332`](../core/dr-gpu/src/adjust.rs#L332), [`ui/dr-ui/src/develop.rs:574`](../ui/dr-ui/src/develop.rs#L574), [`ui/dr-ui/src/lib.rs:292`](../ui/dr-ui/src/lib.rs#L292) |
|
||||
| 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/session.rs:128`](../core/dr-sync-nextcloud/src/session.rs#L128), [`ui/dr-ui/src/launch.rs:256`](../ui/dr-ui/src/launch.rs#L256), [`ui/dr-ui/src/launch.rs:49`](../ui/dr-ui/src/launch.rs#L49), [`ui/dr-ui/src/launch_ui.rs:344`](../ui/dr-ui/src/launch_ui.rs#L344) |
|
||||
| FR-NC-10 | [`ui/dr-ui/src/export.rs:1`](../ui/dr-ui/src/export.rs#L1), [`ui/dr-ui/src/library_ui.rs:1991`](../ui/dr-ui/src/library_ui.rs#L1991) |
|
||||
| FR-NC-10 | [`ui/dr-ui/src/export.rs:1`](../ui/dr-ui/src/export.rs#L1), [`ui/dr-ui/src/library.rs:1366`](../ui/dr-ui/src/library.rs#L1366), [`ui/dr-ui/src/library.rs:349`](../ui/dr-ui/src/library.rs#L349), [`ui/dr-ui/src/library.rs:621`](../ui/dr-ui/src/library.rs#L621), [`ui/dr-ui/src/library_ui.rs:1088`](../ui/dr-ui/src/library_ui.rs#L1088), [`ui/dr-ui/src/library_ui.rs:2132`](../ui/dr-ui/src/library_ui.rs#L2132), [`ui/dr-ui/src/library_ui.rs:365`](../ui/dr-ui/src/library_ui.rs#L365), [`ui/dr-ui/src/sidecar_cache.rs:1`](../ui/dr-ui/src/sidecar_cache.rs#L1) |
|
||||
| FR-NC-12 | [`core/dr-sync-nextcloud/src/lib.rs:34`](../core/dr-sync-nextcloud/src/lib.rs#L34), [`core/dr-sync-nextcloud/src/lib.rs:811`](../core/dr-sync-nextcloud/src/lib.rs#L811), [`core/dr-sync/src/lib.rs:155`](../core/dr-sync/src/lib.rs#L155), [`core/dr-sync/src/lib.rs:38`](../core/dr-sync/src/lib.rs#L38), [`core/dr-sync/src/reachability.rs:1`](../core/dr-sync/src/reachability.rs#L1) |
|
||||
| FR-NC-2 | [`core/dr-sync-nextcloud/src/session.rs:128`](../core/dr-sync-nextcloud/src/session.rs#L128), [`core/dr-sync-nextcloud/src/session.rs:34`](../core/dr-sync-nextcloud/src/session.rs#L34) |
|
||||
| FR-NC-3 | [`core/dr-decode/src/locate.rs:1`](../core/dr-decode/src/locate.rs#L1), [`core/dr-decode/src/preview.rs:161`](../core/dr-decode/src/preview.rs#L161), [`core/dr-sync/src/capability.rs:41`](../core/dr-sync/src/capability.rs#L41), [`core/dr-thumbs/src/lib.rs:1`](../core/dr-thumbs/src/lib.rs#L1), [`ui/dr-ui/src/library.rs:1`](../ui/dr-ui/src/library.rs#L1), [`ui/dr-ui/src/library_ui.rs:1`](../ui/dr-ui/src/library_ui.rs#L1) |
|
||||
| FR-NC-4 | [`core/dr-sync-nextcloud/src/propfind.rs:100`](../core/dr-sync-nextcloud/src/propfind.rs#L100), [`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:155`](../core/dr-sync/src/lib.rs#L155), [`core/dr-sync/src/scan.rs:93`](../core/dr-sync/src/scan.rs#L93), [`ui/dr-ui/src/launch.rs:49`](../ui/dr-ui/src/launch.rs#L49) |
|
||||
| FR-NC-5 | [`core/dr-sync-nextcloud/src/propfind.rs:51`](../core/dr-sync-nextcloud/src/propfind.rs#L51) |
|
||||
| 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/schema.rs:230`](../core/dr-catalog/src/schema.rs#L230), [`core/dr-catalog/src/schema.rs:631`](../core/dr-catalog/src/schema.rs#L631), [`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/lib.rs:1140`](../ui/dr-ui/src/lib.rs#L1140), [`ui/dr-ui/src/lib.rs:1668`](../ui/dr-ui/src/lib.rs#L1668), [`ui/dr-ui/src/library.rs:1035`](../ui/dr-ui/src/library.rs#L1035), [`ui/dr-ui/src/library.rs:854`](../ui/dr-ui/src/library.rs#L854), [`ui/dr-ui/src/library.rs:877`](../ui/dr-ui/src/library.rs#L877), [`ui/dr-ui/src/library_ui.rs:1119`](../ui/dr-ui/src/library_ui.rs#L1119), [`ui/dr-ui/src/library_ui.rs:173`](../ui/dr-ui/src/library_ui.rs#L173), [`ui/dr-ui/src/library_ui.rs:184`](../ui/dr-ui/src/library_ui.rs#L184), [`ui/dr-ui/src/library_ui.rs:193`](../ui/dr-ui/src/library_ui.rs#L193), [`ui/dr-ui/src/library_ui.rs:250`](../ui/dr-ui/src/library_ui.rs#L250), [`ui/dr-ui/src/library_ui.rs:260`](../ui/dr-ui/src/library_ui.rs#L260), [`ui/dr-ui/src/library_ui.rs:302`](../ui/dr-ui/src/library_ui.rs#L302), [`ui/dr-ui/src/library_ui.rs:3164`](../ui/dr-ui/src/library_ui.rs#L3164), [`ui/dr-ui/src/library_ui.rs:349`](../ui/dr-ui/src/library_ui.rs#L349), [`ui/dr-ui/src/library_ui.rs:380`](../ui/dr-ui/src/library_ui.rs#L380), [`ui/dr-ui/src/library_ui.rs:761`](../ui/dr-ui/src/library_ui.rs#L761), [`ui/dr-ui/src/library_ui.rs:862`](../ui/dr-ui/src/library_ui.rs#L862), [`ui/dr-ui/src/library_ui.rs:981`](../ui/dr-ui/src/library_ui.rs#L981), [`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/library.slint:504`](../ui/dr-ui/ui/library.slint#L504) |
|
||||
| FR-NC-6a | [`core/dr-catalog/src/cache.rs:1`](../core/dr-catalog/src/cache.rs#L1), [`core/dr-catalog/src/schema.rs:230`](../core/dr-catalog/src/schema.rs#L230), [`core/dr-catalog/src/schema.rs:631`](../core/dr-catalog/src/schema.rs#L631), [`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/lib.rs:1267`](../ui/dr-ui/src/lib.rs#L1267), [`ui/dr-ui/src/lib.rs:1795`](../ui/dr-ui/src/lib.rs#L1795), [`ui/dr-ui/src/library.rs:1108`](../ui/dr-ui/src/library.rs#L1108), [`ui/dr-ui/src/library.rs:1131`](../ui/dr-ui/src/library.rs#L1131), [`ui/dr-ui/src/library.rs:1289`](../ui/dr-ui/src/library.rs#L1289), [`ui/dr-ui/src/library_ui.rs:1013`](../ui/dr-ui/src/library_ui.rs#L1013), [`ui/dr-ui/src/library_ui.rs:1245`](../ui/dr-ui/src/library_ui.rs#L1245), [`ui/dr-ui/src/library_ui.rs:187`](../ui/dr-ui/src/library_ui.rs#L187), [`ui/dr-ui/src/library_ui.rs:198`](../ui/dr-ui/src/library_ui.rs#L198), [`ui/dr-ui/src/library_ui.rs:207`](../ui/dr-ui/src/library_ui.rs#L207), [`ui/dr-ui/src/library_ui.rs:266`](../ui/dr-ui/src/library_ui.rs#L266), [`ui/dr-ui/src/library_ui.rs:276`](../ui/dr-ui/src/library_ui.rs#L276), [`ui/dr-ui/src/library_ui.rs:318`](../ui/dr-ui/src/library_ui.rs#L318), [`ui/dr-ui/src/library_ui.rs:3305`](../ui/dr-ui/src/library_ui.rs#L3305), [`ui/dr-ui/src/library_ui.rs:381`](../ui/dr-ui/src/library_ui.rs#L381), [`ui/dr-ui/src/library_ui.rs:412`](../ui/dr-ui/src/library_ui.rs#L412), [`ui/dr-ui/src/library_ui.rs:793`](../ui/dr-ui/src/library_ui.rs#L793), [`ui/dr-ui/src/library_ui.rs:894`](../ui/dr-ui/src/library_ui.rs#L894), [`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/library.slint:504`](../ui/dr-ui/ui/library.slint#L504) |
|
||||
| FR-NC-6c | [`core/dr-sync-nextcloud/src/desktop_client.rs:30`](../core/dr-sync-nextcloud/src/desktop_client.rs#L30), [`core/dr-types/src/lib.rs:104`](../core/dr-types/src/lib.rs#L104), [`core/dr-types/src/lib.rs:186`](../core/dr-types/src/lib.rs#L186), [`ui/dr-ui/src/activity.rs:1`](../ui/dr-ui/src/activity.rs#L1) |
|
||||
| FR-NC-7 | [`core/dr-sync-nextcloud/src/lib.rs:95`](../core/dr-sync-nextcloud/src/lib.rs#L95), [`ui/dr-ui/src/derived_sync.rs:1`](../ui/dr-ui/src/derived_sync.rs#L1) |
|
||||
| FR-NC-8 | [`core/dr-pipeline/src/sidecar.rs:108`](../core/dr-pipeline/src/sidecar.rs#L108), [`core/dr-pipeline/src/sidecar.rs:89`](../core/dr-pipeline/src/sidecar.rs#L89), [`ui/dr-ui/src/lib.rs:1114`](../ui/dr-ui/src/lib.rs#L1114), [`ui/dr-ui/src/library.rs:289`](../ui/dr-ui/src/library.rs#L289), [`ui/dr-ui/src/library_ui.rs:317`](../ui/dr-ui/src/library_ui.rs#L317) |
|
||||
| FR-NC-9 | [`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-pipeline/src/sidecar.rs:212`](../core/dr-pipeline/src/sidecar.rs#L212) |
|
||||
| FR-NC-8 | [`core/dr-pipeline/src/sidecar.rs:108`](../core/dr-pipeline/src/sidecar.rs#L108), [`core/dr-pipeline/src/sidecar.rs:89`](../core/dr-pipeline/src/sidecar.rs#L89), [`ui/dr-ui/src/lib.rs:1236`](../ui/dr-ui/src/lib.rs#L1236), [`ui/dr-ui/src/library.rs:291`](../ui/dr-ui/src/library.rs#L291), [`ui/dr-ui/src/library_ui.rs:333`](../ui/dr-ui/src/library_ui.rs#L333) |
|
||||
| FR-NC-9 | [`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-pipeline/src/sidecar.rs:212`](../core/dr-pipeline/src/sidecar.rs#L212), [`ui/dr-ui/src/library.rs:621`](../ui/dr-ui/src/library.rs#L621), [`ui/dr-ui/src/library.rs:748`](../ui/dr-ui/src/library.rs#L748) |
|
||||
| FR-PLAT-AND-1 | [`core/dr-types/src/lib.rs:47`](../core/dr-types/src/lib.rs#L47) |
|
||||
| FR-PLAT-AND-3 | [`core/dr-catalog/src/jobs.rs:1`](../core/dr-catalog/src/jobs.rs#L1) |
|
||||
| FR-PLAT-LIN-1 | [`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) |
|
||||
@@ -88,11 +88,11 @@ _None._
|
||||
| FR-RAW-3 | [`core/dr-decode/src/lib.rs:409`](../core/dr-decode/src/lib.rs#L409), [`core/dr-decode/src/lib.rs:94`](../core/dr-decode/src/lib.rs#L94) |
|
||||
| FR-RAW-4 | [`core/dr-decode/src/error.rs:1`](../core/dr-decode/src/error.rs#L1) |
|
||||
| FR-RAW-5 | [`core/dr-decode/src/lib.rs:122`](../core/dr-decode/src/lib.rs#L122) |
|
||||
| FR-UI-1 | [`ui/dr-ui/src/lib.rs:1750`](../ui/dr-ui/src/lib.rs#L1750), [`ui/dr-ui/src/lib.rs:55`](../ui/dr-ui/src/lib.rs#L55), [`ui/dr-ui/ui/library.slint:546`](../ui/dr-ui/ui/library.slint#L546) |
|
||||
| FR-UI-2 | [`ui/dr-ui/src/lib.rs:55`](../ui/dr-ui/src/lib.rs#L55) |
|
||||
| FR-UI-1 | [`ui/dr-ui/src/lib.rs:1877`](../ui/dr-ui/src/lib.rs#L1877), [`ui/dr-ui/src/lib.rs:56`](../ui/dr-ui/src/lib.rs#L56), [`ui/dr-ui/ui/library.slint:546`](../ui/dr-ui/ui/library.slint#L546) |
|
||||
| FR-UI-2 | [`ui/dr-ui/src/lib.rs:56`](../ui/dr-ui/src/lib.rs#L56) |
|
||||
| FR-UI-3 | [`ui/dr-ui/ui/collections.slint:4`](../ui/dr-ui/ui/collections.slint#L4) |
|
||||
| FR-UI-4 | [`ui/dr-ui/ui/app.slint:1064`](../ui/dr-ui/ui/app.slint#L1064) |
|
||||
| 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:1784`](../ui/dr-ui/src/lib.rs#L1784), [`ui/dr-ui/ui/collections.slint:4`](../ui/dr-ui/ui/collections.slint#L4) |
|
||||
| FR-UI-4 | [`ui/dr-ui/ui/app.slint:1084`](../ui/dr-ui/ui/app.slint#L1084) |
|
||||
| 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:1911`](../ui/dr-ui/src/lib.rs#L1911), [`ui/dr-ui/ui/collections.slint:4`](../ui/dr-ui/ui/collections.slint#L4) |
|
||||
| FR-UI-7 | [`core/dr-pipeline/src/descriptor.rs:100`](../core/dr-pipeline/src/descriptor.rs#L100), [`core/dr-pipeline/src/framing.rs:256`](../core/dr-pipeline/src/framing.rs#L256) |
|
||||
| NFR-ARCH-2 | [`core/dr-catalog/src/jobs.rs:1`](../core/dr-catalog/src/jobs.rs#L1) |
|
||||
| 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) |
|
||||
@@ -105,11 +105,11 @@ _None._
|
||||
| NFR-R5 | [`core/dr-catalog/src/collections.rs:1`](../core/dr-catalog/src/collections.rs#L1), [`core/dr-catalog/src/error.rs:1`](../core/dr-catalog/src/error.rs#L1), [`core/dr-catalog/src/schema.rs:1`](../core/dr-catalog/src/schema.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 | [`ui/dr-ui/src/lib.rs:47`](../ui/dr-ui/src/lib.rs#L47) |
|
||||
| NFR-RES-1 | [`ui/dr-ui/src/lib.rs:48`](../ui/dr-ui/src/lib.rs#L48) |
|
||||
| NFR-RES-4 | [`core/dr-catalog/src/cache.rs:1`](../core/dr-catalog/src/cache.rs#L1), [`core/dr-catalog/src/schema.rs:230`](../core/dr-catalog/src/schema.rs#L230), [`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) |
|
||||
| NFR-SEC-1 | [`core/dr-decode/src/error.rs:1`](../core/dr-decode/src/error.rs#L1) |
|
||||
| R1 | [`tools/traceability/src/lib.rs:495`](../tools/traceability/src/lib.rs#L495), [`tools/traceability/src/lib.rs:499`](../tools/traceability/src/lib.rs#L499) |
|
||||
| R4 | [`core/dr-gpu/src/lib.rs:132`](../core/dr-gpu/src/lib.rs#L132) |
|
||||
| R4 | [`core/dr-gpu/src/lib.rs:135`](../core/dr-gpu/src/lib.rs#L135) |
|
||||
|
||||
## Not yet tagged
|
||||
|
||||
|
||||
Reference in New Issue
Block a user