3553 Commits
Author SHA1 Message Date
aiongg 53ce89fc11 Integration: #1616 move the overcast-scene doc comment back to its test 2026-10-22 02:37:51 +00:00
aiongg 73c61cf655 Merge PR #2400: Crop: the spiral guide is complete at every aspect ratio 2026-10-22 02:37:50 +00:00
aiongg eee3b799fe Merge PR #2371: #2365: centre the search field on the window, not inside the bar's margins 2026-10-22 02:37:49 +00:00
aiongg fbc927f0b1 Merge PR #2347: feat(guided): Guided Upright guides select, start on the press and drag their endpoints
docs/parity-checklist.md: both revision rows.
2026-10-22 02:37:49 +00:00
aiongg 8bd9a3af1e Merge PR #1616: LR-PROF-CAMERACOLOR: near-black frames get a tone curve when no colour look fits (#1587)
crates/engine/src/camera_preview.rs: LOOK_VERSION keeps the higher value; fit_tone_only_pairs (from #1616) takes the HighlightCheck of #699 from fit_tone_only_on, and fit_dark_tone passes its frame's (empty, as no JPEG pixel reaches 0.85) check.
crates/engine/src/media.rs: RENDER_CACHE_VERSION keeps the higher value.
docs/parity-checklist.md: LR-PROF-CAMERACOLOR row keeps both sides' changes.
2026-10-22 02:37:46 +00:00
aiongg feaf1aa5bb Merge PR #2317: #2267: the Before label stays in view when zoomed in (stacked on #2274)
crates/ui-egui/src/tests_zoom.rs: both new Before-label tests, with #1968's comment wording on the crop test

docs/whats-new.md: both entries under 2026-10-19
2026-10-22 02:37:40 +00:00
aiongg 4de80f3ef9 Merge PR #2306: LR-CROP-RECT: a moved crop slides along a straightened photo's tilted edges (#2299) 2026-10-22 02:37:36 +00:00
aiongg cb8115b239 Merge PR #2217: LR-EDIT-OPTICS-PROFILE: look up Nikon DSLR lenses by their lens specification
docs/parity-checklist.md: newer header (2026-10-21); both revision rows.
2026-10-22 02:37:35 +00:00
aiongg 2aae31ecb4 Merge PR #2404: Keep file name when a redirect Location is query-only 2026-10-22 02:37:33 +00:00
aiongg 551defa04e Merge PR #2336: Treat Unicode minus and dash characters as negative in parse_gps
crates/engine/src/cmd/library.rs: gps_tests keeps both PRs' asserts
2026-10-22 02:37:33 +00:00
aiongg d8b2eb60d3 Merge PR #2172: i18n: add Finnish (fi) interface language
Conflicts:
- README.md, docs/localization.md: language lists keep every language, Finnish appended
- assets/ATTRIBUTION.md: union of rows
- crates/ui-egui/src/i18n.rs, crates/ui-egui/src/menus.rs: language table and commands keep sv and fi
- crates/ui-egui/src/panels/keyword_list.rs: code list gains fi; Locale::ALL.len() is 16
- docs/localization-parity.md: header keeps the newer date and both changes; revision rows are the union
2026-10-22 02:37:29 +00:00
aiongg 2965161505 Merge PR #1997: KEY-CROP-SWAP: X in the crop tool swaps the aspect once (#1866) 2026-10-22 02:37:24 +00:00
aiongg 590c17a8f3 Merge PR #1977: GUM-3203: Stress-test previews against full-size renders 2026-10-22 02:37:23 +00:00
aiongg b242cd6bfc Merge PR #1972: Tone: neutral display tone map is the identity up to white (#1945) 2026-10-22 02:37:23 +00:00
aiongg f8f68fa8b2 Merge PR #2341: Fix parse_gps for hemisphere-letter-first coordinates without comma 2026-10-22 02:37:22 +00:00
aiongg bb18036420 Merge PR #1909: docs(support): explain the Remove tool workflow (#1756) 2026-10-22 02:37:22 +00:00
aiongg b1c4cb7df9 Merge PR #1258: Ignore hidden and empty masks when choosing develop planes. 2026-10-22 02:37:22 +00:00
aiongg fb316ee5ea Merge PR #1402: Fix slider wheel edits after leaving and returning to the Edit panel
crates/ui-egui/src/widgets/tests_numeric_entry.rs: keep both sides' tests.
docs/parity-checklist.md: newer header (2026-10-21); KEY-SLIDER-NUDGE from #1402, KEY-SLIDER-TYPE from #1687; both revision rows.
2026-10-22 02:37:21 +00:00
aiongg 51bf538f27 Merge PR #1968: crop.set refuses a crop smaller than the crop tool allows, instead of exporting 1×1 2026-10-22 02:37:19 +00:00
aiongg 166380630b Merge PR #2366: LRC-LIB-LIBFOLDERS: Synchronize Folder says a folder is up to date, with one Close
docs/parity-checklist.md: header and revision rows from both sides; LRC-LIB-LIBFOLDERS row takes both wording changes
2026-10-22 02:37:19 +00:00
aiongg 67d6e1879f Merge PR #1991: Control port: don't clone the connection's socket (Windows: launched programs kept it open)
apps/lightcraft/src/control_server.rs: serve() keeps #2027's idle read timeout and #1991's single-stream serve_lines (no try_clone); #1991's Windows test passes IDLE_TIMEOUT
2026-10-22 02:37:18 +00:00
aiongg cf804ee9f6 Merge PR #699: LR-PROF-CAMERACOLOR: fit the tone curve of low-contrast scenes (range limit 1.5 to 1.2)
crates/engine/src/camera_preview.rs: LOOK_VERSION keeps both history lines and the higher value.
crates/engine/src/media.rs: RENDER_CACHE_VERSION keeps the higher value.
2026-10-22 02:37:09 +00:00
aiongg 4764767694 Merge PR #1855: i18n: Swedish (sv) interface translation
Conflicts:
- README.md, docs/localization.md: language lists keep every language, Swedish appended
- assets/ATTRIBUTION.md: union of rows
- crates/ui-egui/src/i18n.rs: language table and command test list keep it, ka and sv; both tests kept
- crates/ui-egui/src/menus.rs: language commands keep it, ka and sv
- crates/ui-egui/src/panels/keyword_list.rs: code list gains sv; Locale::ALL.len() is 15
2026-10-22 02:37:05 +00:00
aiongg 92c90ad743 Merge PR #1687: KEY-SLIDER-TYPE: a long click keeps the value field open; drag the value to scrub 2026-10-22 02:36:59 +00:00
aiongg 08f9334457 Merge PR #2452: LR-PRE-PANEL: the applied preset stays marked on returning to the pho… 2026-10-22 02:36:59 +00:00
aiongg a22f447523 Merge PR #1921: Context menus: a right-click elsewhere on the same widget moves its o… 2026-10-22 02:36:58 +00:00
aiongg f4dd312eac Merge PR #2177: LRC-DEV-AUTOSYNC: sync HDR state while retaining per-photo tuning
crates/engine/src/lib.rs: keep both explicit comparison leaves (camera_local_tone and hdr).
crates/engine/src/tests.rs: keep both sides' tests.
2026-10-22 02:36:58 +00:00
aiongg 04e20de345 Merge PR #2027: #1952: expire idle control connections
contributors/people.toml: union of new people entries
2026-10-22 02:36:51 +00:00
aiongg 81f304a867 Merge PR #2208: LRC-DEV-AUTOSYNC: sync camera local tone Off 2026-10-22 02:36:40 +00:00
aiongg 214c595794 Merge PR #2049: LRC-LIB-LIBFOLDERS: Synchronize Folder says it is listing the folder instead of sitting at "0 of N" 2026-10-22 02:36:15 +00:00
helgehelge123andClaude Opus 5.5 e07c2bd44e LRC-LIB-LIBFOLDERS: the deep-folder tests put a photo in every level (ready for #1243)
The two deep-chain tests now build their library with `deep_folders_app`, as #1243 does: every
level holds a photo, so it has a row of its own and starts closed, and the test opens it. They
pass the same whether or not the sidebar passes over folders that only lead on.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-22 04:31:08 +02:00
Nathaniel Ledford 0e08318bad LR-VIEW-ZOOM: a pinch holds the loupe's fit size, so it no longer renders at every zoom step 2026-10-21 19:50:28 -04:00
Dylan M. Taylor bfb23db2ca Use chrono instead of hand-rolled UTC conversion (#2457)
* Use chrono for UTC/calendar conversion instead of hand-rolled copies

Replaces the hand-rolled Howard Hinnant civil/days-from-civil copies and the
leap-year/days-in-month table with chrono as a workspace dependency:
- apps/lightcraft/src/logging.rs: timestamp (log line time)
- crates/catalog/src/dates.rs: civil + weekday
- crates/catalog/src/stacks.rs: iso_seconds (date -> seconds)
- crates/engine/src/cmd/face_recognize.rs: capture_secs (native only)
- crates/meta/src/datetime.rs: DateTime::unix_seconds and the valid() day check
Output formats and semantics are unchanged (pre-epoch clamp, day rollover that
normalize_iso relies on, leap-second tolerance, EXIF/XMP parsing). chrono uses
only std, so wasm stays safe. AGENTS.md/CLAUDE.md now say time goes through chrono.

Follow-up to storytold/cadcraft#1785

* Never panic on a clock outside chrono's range; keep 5-digit years unprefixed

chrono's From<SystemTime> unwraps, so a clock past year 262143 panicked
inside the logger. timestamp now uses the fallible DateTime::from_timestamp
and reads such a clock as the epoch, keeping the old pre-epoch clamp.

timestamp and catalog's civil write years past 9999 with {:04} like the old
{y:04} did, because %Y would add a '+'. Tests cover the out-of-range and
5-digit-year cases.

* Don't build an unrepresentable SystemTime in the far-future test

UNIX_EPOCH + Duration::from_secs(u64::MAX / 2) overflows Windows'
SystemTime and panicked before timestamp() ran, failing the Windows
test job. Build it with checked_add and only assert where it exists.

* time: preserve old out-of-range date conversion (no epoch fallback)

`DateTime::from_timestamp(...).unwrap_or_default()` silently reset any instant
past chrono's year range to 1970-01-01, changing output the old hand-rolled
Howard-Hinnant code converted exactly (e.g. 10_000_000_000_000 s was
318857-05-20 17:46:40, not the epoch). Restore the old conversion domain with a
cycle-based helper that routes the calendar through chrono (the calendar
repeats every 400 years = 146_097 days, so month/day/time come from chrono and
only the year is carried in i128, keeping every i64 exact).

- apps/lightcraft/src/logging.rs: `timestamp` via `utc_parts`; keep the
  pre-1970 epoch clamp; u64 secs past i64::MAX saturate, not epoch.
- crates/catalog/src/dates.rs: `civil` cycle-based (the callers stay inside
  0000-9999, but a far clock no longer resets to the epoch).

Pinned old outputs in tests:
  logging u64::MAX/2 s -> 292277026596-12-04T15:30:07.000Z (was epoch),
          10_000_000_000_000 s -> 318857-05-20T17:46:40.000Z
  civil 10_000_000_000_000 -> 318857-05-20T17:46:40,
        -10_000_000_000_000 -> -314918-08-13T06:13:20, i64 extremes

* Don't build a year-318857 SystemTime unchecked in the logging test

Windows' SystemTime only reaches about year 30828, so
UNIX_EPOCH + Duration::from_secs(10_000_000_000_000) panicked before
timestamp() ran and failed the Windows test job. Build it with
checked_add and assert where the platform can hold it. The year-10000
case fits everywhere and stays unconditional.

* Name the 400-year range extension as the one exception to the time rule

The rule said never to hand-roll calendar math, but the range fix
(shifting by whole 400-year Gregorian cycles so dates past chrono's year
range keep their old output) is cycle arithmetic, so the rule and the code
disagreed. The rule now names that exception: the library still computes
month, day and time, and only whole cycles are carried in the year.

* Say the library computes month and day; time-of-day is plain arithmetic

Narrows the range-extension wording: the date library computes the
calendar fields, and splitting seconds into hours, minutes and seconds
is ordinary arithmetic, which is what the code does.
2026-10-21 19:36:36 -04:00
Dylan M. Taylor d79b1f33e3 security: enforce HTTPS on curl downloads (SonarCloud S6506) (#2493)
Add --proto '=https' to curl invocations so redirects cannot downgrade to
plaintext HTTP. Resolves SonarCloud S6506 (shell/docker/githubactions).
2026-10-21 19:35:59 -04:00
Bruno-Alumn f32116bee1 Merge remote-tracking branch 'upstream/main' into fix/strict-ids-params
# Conflicts:
#	crates/engine/src/cmd/mask_effects.rs
#	crates/engine/src/cmd/masks.rs
#	crates/ui-egui/src/control.rs
2026-10-21 22:48:03 +00:00
Bruno-Alumn d15fc0a6ce Merge remote-tracking branch 'upstream/main' into fix/f8-right-panel
# Conflicts:
#	docs/parity-checklist.md
2026-10-21 22:42:18 +00:00
Bruno-Alumn c96af686a1 Merge remote-tracking branch 'upstream/main' into fix/preset-mark-per-photo
# Conflicts:
#	docs/parity-checklist.md
2026-10-21 22:42:18 +00:00
Bruno-Alumn c733daf1c2 Merge remote-tracking branch 'upstream/main' into fix/cull-color-label
# Conflicts:
#	docs/parity-checklist.md
2026-10-21 22:42:17 +00:00
Bruno-Alumn 731b461d7d Merge remote-tracking branch 'upstream/main' into fix/mask-overlay-reshow
# Conflicts:
#	docs/parity-checklist.md
2026-10-21 22:42:17 +00:00
chordpli c28a537a15 LR-CROP-RECT: a crop a handle drag filled to the tilted edges still moves (#2299)
The E2E showed the previous fix missed the common case: enlarging a locked
crop until it stops leaves a frame that fills the photo's height, with its
top and bottom both at the edge of is_within_image's 1e-6 tolerance. No
translation keeps both there with room to spare, so the move stayed stuck.

When the frame can't move as it is, solve again with it shrunk about its
centre by the least that puts it strictly inside (at most 1e-5 of its size,
aspect unchanged). This also covers a frame at the edge on one side, so the
half-tolerance first pass is dropped and a click moves nothing again.
2026-10-22 07:34:48 +09:00
chordpli 89a35ded91 LR-CROP-RECT: a crop a handle drag left at a tilted edge still moves (#2299)
A handle drag stops where is_within_image's 1e-6 tolerance ends, so a
corner can sit right at it. The move solve then let that corner go 1e-9
further, the result failed the check, and the across-then-down fallback
left the frame stuck. Solve first with every corner kept within half the
tolerance, and only then where it is.
2026-10-22 07:34:48 +09:00
chordpli f443bed56f LR-CROP-RECT: trim the crop move comments (#2299) 2026-10-22 07:34:48 +09:00
chordpli 4bd40cda60 LR-CROP-RECT: a crop just past a tilted edge still moves, and a click leaves it be (#2299)
A handle drag can leave the frame up to is_within_image's tolerance past a
tilted edge. The move's bounds were tighter than that, so such a frame was
stuck again, and a click inside it moved it. The bounds are now never tighter
than where the frame is. A test pins how a smaller frame pushed past a tilted
edge slides along it, and the parity checklist's revision history notes the fix.
2026-10-22 07:34:48 +09:00
tylerphotosandCodex 4245d50f2f LR-IMP-ADD-DIALOG: reconcile album picker with integrated main (#2425)
Retain both sets of parity revision notes after the upstream integration.
Keep the hierarchical picker and deleted-destination guard unchanged.

Co-Authored-By: Codex <noreply@openai.com>
2026-10-21 17:34:40 -05:00
chordpli d63ce8e5f8 LR-CROP-RECT: a moved crop slides along a straightened photo's tilted edges (#2299)
On a straightened photo, a crop that fills the photo's height could not be
moved sideways: the move went across and then down, and no straight sideways
step stays inside the turned photo. The frame now goes to the place nearest
the pointer's that keeps it inside, so it slides along the tilted edges to the
photo's side. Unstraightened, that place is the old across-then-down clamp.
2026-10-22 07:34:28 +09:00
JackalCOBandClaude Opus 5.5 4771ae0ea5 LR-EDIT-OPTICS-PROFILE: read Fujifilm's nine-knot lens tables at the plain radius
Fujifilm's nine-knot distortion and vignetting tables (knots at sqrt(k/8))
end at the corner on the eighth knot; the ninth, sqrt(9/8), lies past it
with the eighth's value repeated. Reading them at rho = knot_last * r took
every value from 6 % further out. On the X-T4 the warp polynomial then
failed its fit checks on 253 of 425 zoom-lens raws, which got no
distortion correction at all, and corners came out up to 6.5 % brighter
than the camera's. Read at rho = r, the tables match the camera's measured
geometry and corner gain (docs/fuji-lens-corrections.md, "Knot radius").
Nothing changes for the 11-knot and 8-knot tables, whose last knot is 1.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-22 11:27:49 +13:00
Dylan M. Taylor 3a9b35c687 ci: exclude dev tool scripts from SonarCloud coverage gate
tools/ and docs/ scripts aren't unit-tested; exclude them from coverage so the
new-code coverage gate doesn't block hardening-only changes.
2026-10-21 17:31:18 -04:00
Dylan M. Taylor 68d5118a9d security: validate CLI paths/args in dev tools (SonarCloud S2083/S8707/S8705/S7044)
Resolve and validate command-line path arguments before use, enforce HTTPS at
download sinks, and confirm path containment. Hardens local codegen/fetch tools
against path-traversal and command-argument-injection findings.
2026-10-21 17:13:05 -04:00
Claude 55a094475d Merge main into fix/dx12-nn-denoise
The only conflict was the 2026-10-19 whats-new entries; both are kept.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01K93HTyCiwYvbRGaAkjPvXn
2026-10-21 13:01:31 -07:00
Dylan M. Taylor 3dc3b955df ci: add sonar-project.properties for CI-based analysis
Marks the project ineligible for SonarCloud Automatic Analysis, resolving the
CI-vs-automatic-analysis conflict so the SonarCloud workflow succeeds.
2026-10-21 16:00:43 -04:00