Roslyn Bridge flagged these as copy-paste clusters; each pair now shares
one implementation so a fix lands everywhere at once:
- Shape.OffsetInward/OffsetOutward differed only in the target winding.
- BestFitFinder kept its own copy of SpatialQuery's arc-extreme points.
- SplitDrawingForm rebuilt DrawingSplitter's clip-region grid for preview.
- GeometryOptimizer's collinear/coradial finders (one misspelled
GetCoradialArs) become one generic FindRelated.
- Five settings files repeated the write-with-retry loop, and two also
repeated the unit parser and unreadable-file filter (SettingsFile).
- ClampsForm and SupportGridForm repeated their row/box builders.
- Vertical/HorizontalRemnantComparer share a RemnantComparer base.
Behavior is unchanged except that Engine/NestStorage settings loads now
also tolerate NotSupported/Security exceptions, matching the other
settings files' never-throw contract.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
New installs now start with a generic fiber laser: mild steel, 304
stainless and 5052 aluminum, gauge-named thicknesses, fiber-sized
kerfs and arc lead-ins, and no lead-out. It has its own id, so
uploading local machines never replaces an existing CL-980. A test
checks that the shipped values grow sensibly with thickness.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Schema v13 adds shared_settings and shared_setting_revisions behind
/api/settings: one revision-guarded JSON document per kind and key, with
every revision (deletions included) kept with who saved it. Recreating a
deleted document continues its revision count.
OpenNest.Data gains the client (RemoteSharedSettings), a synchronous store
that keeps the last copy read for offline use and refuses writes while the
server is unreachable (SharedSettingsStore), a machine provider over it, and
JSON parse/serialize entry points for clamp settings and nest defaults.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Repo-wide sweep with the pinned CSharpier 1.3.0 tool. Whitespace and
line-wrapping only; OpenNest.Engine.Tests (109) and OpenNest.IO.Tests
pass after reformat, full solution builds 0 errors.
Added .csharpierignore so csproj/config XML keeps its existing layout
(CSharpier's XML wrapping churns attributes with zero benefit).
Formatting is now enforceable: dotnet csharpier check . passes.
Embeds CL-980.json as a resource in OpenNest.Data and adds EnsureDefaults()
to LocalJsonProvider, which seeds the machines directory on first run when empty.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
One JSON file per machine named by GUID, stored in a configurable directory.
Supports save, load, list (as summaries), and delete with IO-error retry.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>