crates/engine/src/cmd/library.rs: kept main's split; the PR's parse_gps changes and tests are ported to crates/engine/src/cmd/library/gps.rs.
docs/gaps.md, docs/parity-checklist.md: both sides kept (header items, rows, LR-META-LOCATION note).
crates/ui-egui/tests/it/main.rs: both mod lines kept. docs/whats-new.md, docs/parity-checklist.md: both sides' entries, header and LR-BEHAV-ACCESS row combined.
docs/parity-checklist.md, docs/ui-parity.md: headers, the KEYC-METADATA and LRC-LIB-KEYWORDS rows carry both sides' changes; revision rows kept from both.
Setting a colour label is photo.label with the colour as a parameter, and the
keyboard shortcuts editor binds a key to a command, not to a parameter, so
only 6-9 had keys and clearing a label could not be given one. photo.clearLabel
is the same as photo.label with none, as a command of its own. The Photo >
Set Color Label > None row runs it and shows its key.
A person's page (and every face confirmed there) compares each unnamed
face with each of the person's named faces on the UI thread, on one core:
92 000 unnamed faces against 4 100 named ones is some 400 million
512-long dot products, about 2 min 40 s on an Apple M1 Pro with the
window frozen.
- matching::cosine sums in eight lanes, which the compiler vectorizes
(about 4x faster on 512-long embeddings; same result to the last bits).
- matching::person_score: one person's score as rank gives it, with no
names to group by and nothing allocated (same score, tested).
- similar() scores the candidates with rayon: about 3 s in the same case
(benchmark at that scale: 163 s before, 3 s after).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Follows main's split of menus.rs into menus/ and of the keyword tests into
keywords/tests.rs: Set Keyword Shortcut moves to menus/ui_commands.rs and
menus/run.rs, its catalog test to keywords/tests.rs, and the docs name the
moved test files.
The restore actions use the recorded folder without checking that it still
exists, so an upgrade creates it again rather than using the default folder.
Keep Enable Painting in the extracted menu modules and share the painter
box text with the keyword panel. Open the folded Keywords section when
the shortcut is pressed with an empty painter box.
Lightroom Classic's keyboard shortcut page lists Command+Option+Shift+K
(Ctrl+Alt+Shift+K on Windows) for Set a keyword shortcut and Shift+K
for adding or removing the keyword shortcut on the selected photos.
LightCraft had no keyword shortcut.
Set Keyword Shortcut... (dialog.keywordShortcut, Cmd+Alt+Shift+K) asks
for one or more keywords with commas between them and shows the ones
set before. A new name goes inside the default parent, as in the
Keywording box. A keyword's Use This as Keyword Shortcut in the Keyword
List sets that keyword alone, and the list shows a + after each keyword
of the keyword shortcut. Shift+K (keyword.toggleShortcut) adds the
keywords to the selected photos, or removes them when every selected
photo has them all. The help pages do not say what Shift+K does when
only some selected photos have the keywords; adding them unless every
photo has them all is LightCraft's own rule. A photo's context menu
offers Add Keyword with the keyword shortcut's keywords.
The keyword shortcut is a mark on its keywords in the catalog's keyword
list (KeywordInfo::keyword_shortcut), as Put New Keywords Inside This
Keyword is: a new name is listed, the mark moves with a renamed, moved
or merged keyword and goes with a deleted one, and setting it
(keyword.setShortcut) is one undo step.
The new labels have rows in every catalog. The KEYC-METADATA and
LRC-LIB-KEYWORDS rows, docs/ui-parity.md and docs/library-shortcuts.md
list the keys.