Commit Graph
281 Commits
Author SHA1 Message Date
bflatastic 2af11131ef Merge main into merge/xfa2
# Conflicts:
#	crates/automation/src/tools.rs
#	crates/automation/tests/it/automation.rs
#	crates/forms/src/tests.rs
#	crates/ui-egui/src/tools/forms_ui.rs
#	parity/acrobat-features.toml
2026-11-09 20:57:05 +07:00
bflatastic c1d9dd1db1 Merge #4791: M12: a dynamic XFA form runs all its opening scripts and is laid out once, so a save no longer keeps a half-initialized form (#4790)
# Conflicts:
#	crates/engine/src/xfa.rs
#	crates/forms/src/tests.rs
#	crates/xfa/src/data.rs
#	crates/xfa/src/lib.rs
#	crates/xfa/src/tests.rs
#	parity/acrobat-features.toml
2026-11-09 18:26:29 +07:00
bflatastic a0b791853c Merge #4784: M6: a radio option whose export value is a number selects its own button, and its XFA data holds the item (form.fill-checkbox-radio) 2026-11-09 18:24:54 +07:00
bflatastic e917cc2cc6 Fit the landed changes together 2026-11-09 18:24:27 +07:00
bflatastic de333340a5 Merge #4532: M6: list boxes show and pick the option /I names, and a single-select list shows one value (#4531)
# Conflicts:
#	crates/automation/src/tools.rs
#	crates/forms/src/lib.rs
#	crates/forms/src/tests.rs
#	crates/forms/src/values.rs
#	crates/ui-egui/src/tools/forms_ui.rs
#	crates/ui-egui/tests/it/forms.rs
2026-11-09 18:17:35 +07:00
BFlat 9ee213eff7 Fix main's build and tests after the latest merges (#6706) 2026-11-09 19:12:07 +08:00
mtlcl410 4f71f96058 Merge remote-tracking branch 'upstream/main' into lane9-4784b
# Conflicts:
#	crates/automation/src/tools.rs
#	crates/automation/tests/it/automation.rs
#	crates/xfa/src/tests.rs
#	parity/acrobat-features.toml
2026-11-09 18:57:44 +08:00
mtlcl410 7096266c48 M6: give the custom-validation test's ScriptResult its value_set field 2026-11-09 18:41:47 +08:00
mtlcl410 7917ecb83f Merge remote-tracking branch 'upstream/main' into lane7-4496b
# Conflicts:
#	crates/automation/src/tools.rs
#	crates/automation/tests/it/automation.rs
#	crates/forms/src/lib.rs
#	crates/forms/src/tests.rs
#	crates/forms/src/values.rs
#	crates/ui-egui/src/tools/forms_ui.rs
#	crates/ui-egui/tests/it/forms.rs
#	parity/acrobat-features.toml
2026-11-09 18:23:59 +08:00
Dylan M. Taylor f64c853a3a fix(forms): comb detection ignores repeated boxes (#6077) 2026-11-09 18:19:30 +08:00
jonathanwxh-cell 0e199bb602 fix(forms): harden tab order, AF script parsing, and null/inherited tree entries (#5614) 2026-11-09 18:15:28 +08:00
Eric Kaden 7fa6f10720 M12: an XFA date field keeps what its patterns don't read as typed, and reads its own patterns first (#4511) 2026-11-09 18:13:08 +08:00
mtlcl410 7a19802a77 M6: radio buttons sharing an on state are exclusive unless RadiosInUnison (form.fill-checkbox-radio) (#4489) 2026-11-09 18:12:29 +08:00
mtlcl410 d920c8bdf3 Merge main into fix/listbox-selected-indices
crates/forms/src/values.rs: the read imports take both listed_indices and
selected_options (list selection) and main's listing_fields_named (radio
fields sharing a name).
2026-11-09 12:20:42 +08:00
mtlcl410 9619cc2e1e Merge upstream/main into fix/xfa-open-scripts-complete 2026-11-09 12:00:34 +08:00
mtlcl410 4e2235cf1b Merge upstream/main into fix/checkbox-kid-on-states 2026-11-09 11:57:54 +08:00
mtlcl410andClaude Opus 5.5 ea541c6076 Merge upstream/main into fix/radio-numeric-export
xfa data.rs: keep main's fields_with_ids re-export and the PR's radio
value re-exports.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Pq7HyCHD1R3rywQBPCHXZA
2026-11-09 11:34:06 +08:00
mtlcl410andClaude Opus 5.5 a60d78240c Merge upstream/main into fix/listbox-selected-indices
values.rs: keep the position-tracking choice matching and match each value
with main's option_named (export value first, then display text).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Pq7HyCHD1R3rywQBPCHXZA
2026-11-09 11:24:32 +08:00
bflatastic 02fbca9fd3 Name a kid from its /Parent as written, and draw a referenced CMYK entry as the reference gives it 2026-11-09 09:59:06 +07:00
mtlcl410andClaude Opus 5.5 2d8b7048a2 Merge upstream/main into fix/checkbox-kid-on-states
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Pq7HyCHD1R3rywQBPCHXZA
2026-11-09 10:57:10 +08:00
bflatastic 08c0a59212 Merge main into merge/redact-forms-misc
# Conflicts:
#	ROADMAP.md
#	crates/render/src/text/tests.rs
2026-11-09 09:56:59 +07:00
mtlcl410andClaude Opus 5.5 f996aef12f Merge upstream/main into fix/xfa-open-scripts-complete
Main's DataOp::Value now replaces a multi-select list's value-group picks in the
packet and in the data copy, so the reset writes through it and the separate
DataOp::Reset (and Want::picks) is dropped. The reset keeps the PR's indexed
targets and its pass over fields without widgets, beside main's floating-field
pass (which the unshown pass leaves embedded fields to), and finish() lays out
again for either an owed relayout or a changed embedded value. Parity notes and
evidence take both sides.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Pq7HyCHD1R3rywQBPCHXZA
2026-11-09 10:39:06 +08:00
Unhumanje ab7af72347 fix(forms): name tree nodes sharing one long /Kids array no longer exhaust memory (#5121) 2026-11-09 10:11:18 +08:00
jonathanwxh-cell a22bede984 fix(forms): resolve field and widget references in ResetForm and Hide actions (#5364) 2026-11-09 10:05:03 +08:00
bflatastic eb47b57b4f Merge #6610: M6: a field whose normal appearance gives no stream is drawn from its value, /MK and /BS (view.render-annotation-appearances)
# Conflicts:
#	parity/acrobat-features.toml
2026-11-09 08:19:52 +07:00
bflatastic 5e1d511216 Merge #6570: M6: a named kid is named up its own /Parent chain, and a radio option of any same-named field is chosen by the name (form.field-list)
# Conflicts:
#	crates/forms/src/read.rs
#	crates/render/src/inspect/annotations.rs
#	crates/render/src/inspect/tests.rs
#	parity/acrobat-features.toml
2026-11-09 08:19:22 +07:00
mtlcl410 d65ae4268e M6: a calculate script that sets its own field through the field object keeps that value (form.custom-scripts) (#6616) 2026-11-09 08:59:19 +08:00
mtlcl410 b9ffb68b12 M6: a product of empty fields is 0, not 1 (form.af-simple-calculate) (#6567) 2026-11-09 08:57:28 +08:00
mtlcl410 e83c200598 M6: a field whose /Kids loop back or name a root field keeps its other kids (form.field-list) (#6446) 2026-11-09 08:50:11 +08:00
mtlcl410 608ff62dae M6: a widget whose /Parent names a missing object is a field of its own (form.field-list) (#6445) 2026-11-09 08:49:56 +08:00
Harrison Booth 3b731f9458 Expose widget rectangles to field scripts (#6093) 2026-11-09 08:42:39 +08:00
b07a84f003 M5: a comment whose colour is written [r g b null] is drawn, as CMYK with the null read as 0 (view.render-annotation-appearances) (#6503)
* M5: a comment whose colour is written [r g b null] is drawn, as CMYK with the null read as 0 (view.render-annotation-appearances)

ISO 32000-2 Table 166 /C (and /IC, Tables 178, 180, 181; /MK /BC and /BG,
Table 192) is an array of 0, 1, 3 or 4 numbers whose length picks the
colour space. A four-entry array with a non-number in it, such as
[1 0 0 null] (PDFBOX-2699), made the /C parser give up, so a shape
without an appearance stream was not drawn at all. PDFium, MuPDF and
Poppler all read such an array as CMYK with the non-number as 0.

- annot: a four-entry /C or /IC reads non-numbers as 0; other lengths
  still need every entry to be a number.
- annot: the properties' fill uses the same parser (it read
  [r g b null] as RGB before), and /C no longer drops a non-number
  to make three numbers.
- forms: /MK /BC and /BG read a four-entry array the same way instead
  of dropping the non-number and drawing RGB.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Pq7HyDBXygTf7jcqdsjcfn

* M5: comment properties report the stroke colour as drawn; a reference among four colour entries is not read as 0 (view.render-annotation-appearances)

props() reads a non-FreeText /C through the appearance parser, so a
[1 0 0 null] stroke reports CMYK cyan as drawn, and grey and CMYK
strokes report their converted colour. A reference among the four
entries of a /C array (ISO 32000-2 7.3.10) is left unreadable instead
of standing in as 0, so /C [1 0 0 6 0 R] is never drawn cyan.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Pq7HyDBXygTf7jcqdsjcfn

* M5: re-run CI (fill_sign Escape test depends on the clock's second, passes locally)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Pq7HyDBXygTf7jcqdsjcfn

* M5: the comment list reports a comment's colour as drawn (view.render-annotation-appearances)

summaries() accepted only a three-entry /C, so a Square with /C [1 0 0 null],
drawn cyan and reported cyan by props(), had no colour in the comment list;
grey and CMYK colours were dropped the same way. Non-FreeText comments now
read /C through drawn_color (the array itself followed when it is given by
reference), keeping the three-number fallback and the FreeText /DA handling.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Pq7HyDBXygTf7jcqdsjcfn

* M5: the render inspector lists a comment's colour as drawn (view.render-annotation-appearances)

The inspector accepted only a three-entry /C, with a referenced entry read
as 0, so a /C [1 0 0 null], a grey or a CMYK colour listed none, unlike the
comment list and the drawing. Non-FreeText comments now read /C by the
appearance builder's rule (one entry grey, four CMYK with a non-number as 0
and a reference unreadable, finite and clamped), with the three-number
fallback reading referenced entries.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Pq7HyDBXygTf7jcqdsjcfn

---------

Co-authored-by: mtlcl410 <chuanlin@niar.org.tw>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-09 08:29:31 +08:00
mtlcl410 91b0933933 Merge remote-tracking branch 'upstream/main' into fix/radio-numeric-export
# Conflicts:
#	crates/automation/src/tools.rs
2026-11-09 03:43:46 +08:00
mtlcl410 850f6f8e04 Merge remote-tracking branch 'upstream/main' into fix/checkbox-kid-on-states
# Conflicts:
#	crates/automation/src/tools.rs
2026-11-09 03:34:49 +08:00
BFlat 43f24aa169 Draw Thai in Fill & Sign, text boxes, form fields, headers, footers and watermarks (#6632)
Refs #2354. Thai typed into these tools is shaped and drawn from the Thai face through Add text's writer (now pdfcraft_fonts::shaped_text), searchable and copyable, instead of being written as ?????; a build without a Thai face refuses it with a message.
2026-11-09 02:56:34 +08:00
mtlcl410andClaude Opus 5.5 ccc2cd0dee M6: a field whose normal appearance gives no stream is drawn from its value, /MK and /BS (view.render-annotation-appearances)
A widget's /AP /N that is neither a stream nor a state subdictionary with
a stream for /AS draws nothing (ISO 32000-2 12.5.5, Table 170), yet the
display copy treated any /N as the file's own appearance. Text, choice and
push-button widgets whose /N is null, a form XObject dictionary without its
stream data, or a subdictionary without /AS now get the drawn appearance a
widget without /N gets, and check boxes and radio buttons whose state entry
is not a stream are drawn from /MK. The test is the same one the renderer
uses to pick the stream.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Pq7HyCHD1R3rywQBPCHXZA
2026-11-08 17:29:41 +08:00
mtlcl410andClaude Opus 5.5 8bb2d920a0 M6: a /Parent given through an object that is only a reference is followed in the field name (form.field-list)
qualified_name reads each ancestor through Document::resolve, which follows an object that is
nothing but a reference to another, as document inspection does, so both name the kid the same.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Pq7HyCHD1R3rywQBPCHXZA
2026-11-08 12:49:40 +08:00
mtlcl410andClaude Opus 5.5 eee81da38b M6: a radio choice by the name is refused when any radio field of it is read-only, a claimed widget is read once, and inspection lists widgets beside named kids (form.field-list)
- fill: the first same-named field's read-only flag still applies when a later one draws the
  choice, and no radio field of the name is written when any of them is read-only.
- enumerate: a nameless /Fields widget its parent already claimed is not read again as a nameless
  field; one its parent's /Kids omits is still read on its own.
- walk: only kids whose /Subtype is /Widget replace a merged field's own widget.
- inspection: a kid whose /Parent is another field is named from that chain even under a direct
  listing field, and widget annotations beside named kids are listed as a field of the parent's
  name (ISO 32000-2 §12.7.4), as the form reader lists them.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Pq7HyCHD1R3rywQBPCHXZA
2026-11-08 11:21:59 +08:00
mtlcl410andClaude Opus 5.5 916ca60e80 M6: a field merged with a widget reads its widget kids as its buttons, and nameless widgets of an unlisted field are options of its name (form.field-list)
A field dictionary that also carries a zero-area widget and lists widget
kids now has the kids as its buttons (ISO 32000-2 §12.7.4: field and
widget merge only for a single widget). Widget annotations listed beside
named kids, and nameless /Fields entries whose /Parent /Fields doesn't
list, are read as buttons of that parent's name.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Pq7HyCHD1R3rywQBPCHXZA
2026-11-08 06:33:46 +08:00
mtlcl410andClaude Opus 5.5 0ddcc60015 M6: every field sharing a radio group's name takes the chosen /V (form.field-list)
ISO 32000-2 §12.7.4.2: fields with the same fully qualified name have
the same value. Choosing a radio option by the name now writes the
choice as /V of a same-named twin that draws no button for it (its
buttons stay off), and of a field whose /Kids lists them without being
their /Parent, so it shares their name (issue15096.pdf's group, whose
/V was a stale Choice2). Exactly one button stays drawn on.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Pq7HyCHD1R3rywQBPCHXZA
2026-11-08 01:52:28 +08:00
mtlcl410andClaude Opus 5.5 401a64fd60 M6: a radio choice by the name leaves one button on in kids without /P saved both on (form.field-list)
Adds the layout issue15096.pdf's last revision has: the two same-named
radio kids carry no /P (their page comes from /Annots), and both are
drawn on with /V that disagree (Off with /AS /Choice1, Choice2 with
/AS /Choice2). Choosing Choice1, Choice2 and Choice1 again by the name
leaves exactly the chosen button on after each save and reopen.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Pq7HyCHD1R3rywQBPCHXZA
2026-11-08 01:43:01 +08:00
mtlcl410andClaude Opus 5.5 68dff686fe M6: a named kid is named up its own /Parent chain, and a radio option of any same-named field is chosen by the name (form.field-list)
A field's fully qualified name is built from the partial names of the field
and its ancestors, and a child names its parent with /Parent (ISO 32000-2
§12.7.4.2, Table 226). A /Kids entry with /T whose /Parent does not name the
field listing it is now named up its own /Parent chain, in the form reader
and in document inspection, as PDFium and MuPDF name it: pdf.js's
issue15096.pdf lists its two radio fields as Group1, not Group1.Group1.

Fields with the same fully qualified name are one field (§12.7.4.2), so a
radio option that a later one of them draws is now chosen by the name: it is
written through the first field that draws it and the others turn off.
Before, only the first field's options were accepted.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Pq7HyCHD1R3rywQBPCHXZA
2026-11-07 23:54:22 +08:00
mtlcl410andClaude Opus 5.5 928c082e6b M6: a radio number at or past 2^53 matches an export value only by its text (form.fill-checkbox-radio)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Pq7HyDBXygTf7jcqdsjcfn
2026-11-07 09:28:03 +08:00
mtlcl410 8fefffc011 Merge remote-tracking branch 'upstream/main' into HEAD 2026-11-07 09:16:38 +08:00
mtlcl410 bf56dfe7af Merge remote-tracking branch 'upstream/main' into fix/checkbox-kid-on-states-l4
# Conflicts:
#	crates/xfdf/src/tests.rs
2026-11-06 01:04:02 +08:00
6427357fcb Forms: date fields name months in the date language, not always English (#5303) (#5464)
* Forms: date fields name months in the date language, not always English (#5303)

`AFDate_FormatEx("dd-mmm-yy")` wrote "18-Oct-26" in an Italian interface,
where a localized Acrobat writes "18-ott-26". Form date formats,
`util.printd` and `util.scand` now take their month and weekday names
from the date language (Preferences > Date format > Language, which
follows the interface language until one is picked), and still read
English names typed in. The names are process-wide, so their test runs
in its own binary.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Forms: dates read back in every date language (#5303)

Trying every date language showed what a field wrote not always reading
back: names holding digits ("10月"), spaces ("tháng 10"), dots ("ม.ค.")
or combining vowel signs (Thai, Hindi, Telugu) fell apart word by word,
and Italian, Spanish, Romanian and Albanian share some short weekday and
month names ("mar"). The language's names are now found whole in the
text first, the longest at each place, and read as their English names;
the format's order of `mmm` and `ddd` settles a shared name. Both
AFDate parsing and util.scand do this, on text up to 1 KB. A test reads
back every language, each name format, and hostile text.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Forms: date names no field font can draw are drawn in English (#5303)

With the names in the date language, a Russian dd-mmm-yy field drawn in
Helvetica showed "18-????.-26": no /DR font held "окт." and the WinAnsi
stand-in drew each letter as ?. The same held for Japanese, Chinese,
Greek, Arabic, Thai and others, and for Latin names outside WinAnsi
(Czech "říj"). Before, the names were English and always drew. An
AFDate/AFTime field now formats its value again with English names for
a widget whose fonts can't draw the localized text; a custom Format
script is run again with util.printd writing English names for such a
widget, and its result kept only when it draws whole. A field whose
font holds the names keeps them, and scripts otherwise still print the
date language.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Forms: an English weekday before the month keeps the month (#5303)

With Italian dates, "Tue 17 Mar 2026" in a "ddd d mmm yyyy" field read
as no date: the language's names were found in the text, but not
English ones, so "Tue" left the format's weekday unfilled and "Mar",
which Italian shares between Tuesday and March, was taken as the
weekday. Both AFDate parsing and util.scand lost the month, and
Spanish, Romanian and Albanian ("mar") did the same. English names are
now found too and fill their field of the format as localized ones do.
A test reads English and mixed weekdays before the month in those
languages.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Forms: an English date run is drawn even when it prints the value (#5303)

A Helvetica field storing "18-Oct-26" whose Format script prints it
again as dd-mmm-yy still showed "18-???.-26" in Russian. The English
run printed "18-Oct-26", but it was dropped for equalling the stored
value, which was how a failed run was told apart: a failing script
handed back the value unchanged. The English run now says whether it
ran (`None` when the script failed or the runner can't write English
dates), and what it made is drawn whenever it draws whole. A test
reprints the stored value under Russian, and checks that a failing
script keeps its text and is reported undrawn.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Forms: a short weekday typed without its dot is the weekday (#5303)

With French dates, "mar 6 janv 2026" in a "ddd d mmm yyyy" field read
as no date through util.scand, and "mar 06/01/2026" in "ddd dd/mm/yyyy"
through AFDate too. French writes Tuesday as "mar.", which a name
search only found with its dot; since English names are found as well,
the English "Mar" (March) was the only name of that length, so the
weekday became a month. Romanian "mar" did the same. A short name
ending in a dot is now also found typed without it, as the same kind of
name, so the format's order of name fields decides between it and an
equal name of the other kind. Both copies of the name search change. A
test reads French and Romanian weekdays typed without their dot.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Forms: a shared name is the month when no weekday is typed (#5303)

With Italian dates, "17 mar 2026" in a "ddd d mmm yyyy" field read as
no date, nor did "mar 17, 2026" in "dddd, mmmm d, yyyy". AFDate leaves
weekdays out of what it reads (they are shown, not typed), but the name
search still expected the format's weekday first, so "mar", which
Italian shares between Tuesday and March, filled it and left no month.
Spanish and Albanian "mar" and Albanian "sht" (Saturday, September) did
the same, and the keystroke check refused those dates. Where such a
read finds no date, the names are now read again with no weekday
expected, so the shared name is the month; a typed weekday still comes
first ("mar 17 mar 2026"). util.scand reads its fields in order and
needs the weekday, so it is unchanged. A test types those dates with the
weekday left out.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Forms: Turkish names typed in capitals are read (#5303)

With Turkish dates, "1 MAYIS 2026" and "1 EKİM 2026" in a d mmmm yyyy
field read as no date through AFDate and util.scand, and "SALI 6 OCAK
2026" through util.scand. Names were compared lower-cased, which turns
I into i, not the dotless ı of "Mayıs" and "Salı", and İ into i with a
combining dot above, which "Ekim" doesn't have. Names and typed text
are now folded alike, the capital I and the dotted and dotless i all as
i and the combining dot dropped, one piece for each char so positions
in the text stay aligned: in both copies of the name search, the AFDate
month reader and util.scand's name matcher. English reads as before. A
test types Turkish names in capitals and English ones as a check.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Forms: Greek names typed in capitals are read again (#5303)

Folding names char by char turned a capital Σ into σ, so "ΙΑΝΟΥΆΡΙΟΣ"
no longer matched "Ιανουάριος", whose last letter is the final ς. The
fold now makes ς a σ on both sides, in the forms and JS parsers alike.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: FredApps <153173854+FredApps@users.noreply.github.com>
2026-11-05 16:12:04 +01:00
mtlcl410 05692274c4 Merge remote-tracking branch 'upstream/main' into fix/radio-numeric-export-l1 2026-11-05 21:01:06 +08:00
mtlcl410andClaude Opus 5.5 9e51a1f4a6 M6: a radio number is compared with decimal export values as a number first
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Pq7HyDBXygTf7jcqdsjcfn
2026-11-05 20:58:42 +08:00
mtlcl410 29a56a5703 Merge remote-tracking branch 'upstream/main' into HEAD
# Conflicts:
#	crates/automation/tests/it/main.rs
2026-11-05 06:25:42 +08:00
mtlcl410 fd4d2df058 Merge remote-tracking branch 'upstream/main' into HEAD 2026-11-05 02:35:07 +08:00