CORE-8 pre v1.16.0 fixes #251 - #253
craig-o-curtis merged 55 commits into
Conversation
…es and site links (CORE-8, #251) api-surface.mjs derives the public surface from the reference corpus and fails validate on an unreachable public file, a wrong @example result, a wrong documented result on a doc page, an unresolvable documented import, or a broken reference or site link. Clock-dependent calls are skipped only when the function reads Temporal.Now and the call does not pin a reference. build-reference.ts now treats a rest parameter and the documented elements of a trailing rest tuple as optional, so their playground forms are generated.
…w harness over every export (CORE-8, #251) Moves the startOrEndOf and resolveUnixIntervalPair helpers into internal, adds isObject, maxPieces, unixEpochInstant, resolveManualRoundingOptions, resolveMinimalDaysInFirstWeek, plainFormatOptions, rfc5322DateTime and httpDateFields, and tightens leap-second and calendar-id guards. test/noThrow feeds garbage to every exported function and asserts no throw and the declared sentinel.
…-8, #251) No-throw guards, plural smallestUnit in round*, startOfDate day, rejected invalid roundingMode, equal-by bucket comparison, maxPieces caps on splits, divides and mapDatesInRange, ToParts and formatCalendar without leaked zone names, isLeapYear and getWeekNumber validate first, cycle amounts validated, documented examples corrected.
…-8, #251) RFC 2822 parser accepts the receiver grammar and obsolete syntax, rejects a mismatched weekday; RFC 2822 and RFC 3339 formatters stop emitting out-of-grammar years and sub-minute offsets; leap seconds rejected in every spelling; IANA single-component zone names accepted; isValidZonedRange calendar gate; getLocaleZonedEndOfWeek nanosecond default; maxPieces caps; no-throw guards.
…#251) parseHttp accepts rfc850-date and asctime-date and rejects a mismatched weekday; formatHttp rejects years outside IMF-fixdate; areUtcEqualBy compares bucket floors; plural smallestUnit in roundUtc; week parsing for expanded years; maxPieces caps; no-throw guards.
#251) Exports parseMillisecondFromUnix and parseMinuteFromUnix; validates epochUnit everywhere; blank epoch strings no longer read as 1970; sort, min and max drop non-instants and no longer overflow the stack; FormatCalendarUnixOptions drops four options it never read; interval JSDoc states milliseconds; invalid-input examples; maxPieces caps; plural smallestUnit in roundUnix; no-throw guards.
…ections (CORE-8, #251) formatDuration renders sub-second parts exactly; FILETIME values at or above 2^63 are out of range; businessDaysBetween never returns -0; toOffsetInstant returns IANA-cased zone ids; timeZoneLike accepts every IANA name; date regexes reject -000000 and RFC 3339 offsets are range-checked; modifiedPreceding cited to FpML, not ISDA 4.12(a); JSDoc corrections for NTP zero, .NET Kind, ignored zone annotations, relativeTo resolution and rounding increments.
…READMEs and skills (CORE-8, #251) Every documented import resolves, every documented result is what the function returns, and every internal link resolves; api-surface now enforces all three. Also corrects the swapped fiscal-year figures in CORE-5 and the ISDA citation for modifiedPreceding in CORE-7.
…ention citation (CORE-8, #251) Minor for the newly exported unix parse functions, the three signature types and the minimalDays option; patch for the endOf and ToParts defaults and the corrected @example results. The roll-convention changeset now cites FpML for modifiedPreceding. These will be extended as the remaining review rounds land.
…FC 5322 comments, stricter example gate (CORE-8, #251) The polyfill adds and differences non-ISO months one at a time, so a large month span in persian, hebrew, islamic, ethiopic or japanese aborted the process with a heap OOM. temporalCompat/largeMonthSpan.ts jumps whole years using only Temporal calendar reads, is dormant below 1,200 months, and has a canary in pnpm compat. Adds divisionBoundary (exact bigint division), measureNearRangeEnd, zonedLocalDates, instantFormatOptions and a spec-exact time format path, and folds RFC 5322 comments in one linear scan. api-surface now runs invalid-input examples of clock accessors and examples whose aside contains a dash.
…edges and time spans are exact (CORE-8, #251) formatDate, formatDateTime, formatTime and the range formatters keep requested field widths, give era alone its defaults, ignore timeZoneName on plain values, and reject a style that does not apply. roundDate and roundDateTime return representable floors in the last year; the week functions work at both range limits; intervalDivideEqually is exact; mapDatesInRange keeps dates at the maximum; intervalFromDurationTime rejects spans of 24 hours or more and negative wraps; diff units arrays, sunday week numbering, areDatesEqualBy and calendar-id compatibility are documented.
…mporal across DST (CORE-8, #251) addZoned, subtractZoned and intervalFromDurationZoned add the time portion in exact time and apply disambiguation only to the date step; diffZoned, diffZonedAsDuration and intervalLengthZoned measure calendar units on the zone wall clock and return the sentinel across two zones; intervalOverlappingDaysZoned counts the local dates actually touched; formatZonedDateTime keeps requested widths and formatZonedToParts and formatZonedRange reject a timeZone option; exact division, range-edge splits and counts; corrected compatibility notes.
… and five (CORE-8, #251) formatUtc and formatUnix follow the Temporal Intl spec; intervalOverlappingDaysUnix counts local dates touched; exact division; range-edge splits and counts; unix functions document their time zone defaults; FormatCalendarUnixOptions keeps its four never-read members as deprecated so existing calls still type-check; bucketRange returns the representable bucket at the maximum and refuses over-cap ranges without walking them.
… in the READMEs, guides and agent skills (CORE-8, #251)
… (CORE-8, #251) Adds eight changesets: piece-limits (minor, the maxPieces option) and seven patches covering invalid input, internet date grammars, leap seconds and zone names, zoned arithmetic across DST, Intl formatting, range edges and exactness, and unix validation and rounding options. Updates two earlier CORE-8 changesets. The CORE-8 findings ledger covers every review wave, and the tracker marks CORE-8 Done.
…s section; major is never used (CORE-8, #251) Owner decision 2026-09-17: GMT users are internal, so there is no 2.0.0. AGENTS.md core rule 11, PUBLISHING.md, the finalizer and the changelog, tanstack-intent and update-readme skills drop major and describe the Breaking changes migration section. dox-builder states that package exports declare only the root, namespace and category barrels.
… RFC 9557 strings, with contract tests over every export (CORE-8, #251) Adds internal helpers for GetOptionsObject checks, required locales, half-open interval relations, instant interval text and the diff weeks carry, and removes the closed-interval and calendar-suffix helpers. New contract tests pass null, strings and numbers as options to every options-taking export and cover the 17 required-locale functions. Package exports close undeclared nested subpaths, add typesVersions and sideEffects false, and set engines to node 22.16.0 or later. The api-surface and temporal-compat checkers and the fallow config follow.
…ls and RFC 9557 calendar strings (CORE-8, #251) Positional intervals are half-open. Calendar strings are ISO digits plus [u-ca=id]. Non-object options return the sentinel, units are singular or plural, diff unit arrays fold unlisted amounts into the next smaller listed unit including weeks, and inert overflow options are removed from addTime, subtractTime, intervalFromDurationTime and cycleTime. isLeapSecond detects every second-60 spelling.
… half-open intervals (CORE-8, #251) setZoned and cycleZoned default offset to prefer, disambiguation applies to a date step into a DST gap, and inert offset options are removed from addZoned, subtractZoned, intervalFromDurationZoned and convertPlainDateTimeToZoned. diffZoned accepts singular units, non-object options and an invalid reference return the sentinel, and zoned calendar strings are zone then [u-ca=id].
Review — CORE-8Reviewed by dimension (internal helpers, Independently reproduced: 33,432 / 2,594 / 97 tests green (exact claimed counts) · Two honest caveats on that list, since it reads stronger than it is. The oracle compares calendar fields and arithmetic only — it has no I also checked the new gate isn't vacuous: corrupting one Blocking1. Also This predates the PR, but
2. Three exports throw instead of returning their sentinel.
Missed because 3.
One root cause, 23 functions
Docs and tooling
Questions
Coverage gaps, so none of the above reads as exhaustive: |
Addendum — one more defect, and a correction to my coverage claim
.with({ month: quarterStartMonth, day: 1, hour: 0, minute: 0, second: 0 })No It contradicts its own JSDoc line 8 ("the first day of the quarter with time set to 00:00:00"), and it's the lone outlier among the applicable siblings — Two scoping points, stated plainly:
Correction to my own review. I listed Same caveat applies to my differential runs against 1.15.0: this function is byte-identical to 1.15.0, so "identical to 1.15.0" was never going to surface a bug that has been present in both. |
…ions as Temporal does, and fix a month total the polyfill gets wrong (CORE-8, #251) Six exports threw instead of returning their sentinel when an argument did not stringify, and the garbage set in noThrow.ts had nothing that triggered a ToString, so nothing caught them; it now carries a throwing toString, a null-prototype object and a symbol, and all 556 exports pass. A null option member took the `??` default where Temporal treats it as present-but-invalid: 62 exports over 90 member pairs in 46 files now compare against undefined, five tests that had pinned the defect are corrected, and optionsObject.test.ts pins the rule for every documented member. patternToken treats an empty locale array as omitted, so a pattern parse no longer follows the machine LANG. startOfQuarterForDateTime resets its millisecond, microsecond and nanosecond fields like its siblings. Closing the review gap on interval lengths found a polyfill defect: Duration#total divides a calendar remainder by the month that ends at the whole-month mark, where TC39 and Chromium 153 divide by the month that starts there, so any length in months from the 29th, 30th or 31st was wrong in the fraction. A 2,016-case scan in both engines found 16 mismatches, all months. Compat defect D11 sends month and year totals past the 28th through the nudgeToCalendarUnit path GMT already owns, and intervalLengthDate, intervalLengthDateTime, formatRelativeDate and formatRelativeDateTime now go through durationTotal instead of calling the polyfill. Every scanned case matches Chromium; the workaround is probe-gated and retires by canary. New suites close the coverage the review called out: a brute-force oracle for merge and xor over lists of three to eight, reconstruction of difference records over deliberately gappy unit lists, diff rounding values across all nine Temporal modes in both directions, the RFC 9557 annotation grammar per parser against a Chromium table, and interval lengths against a longhand oracle. The round functions document how many fractional digits each unit prints. The docs text surfaces render mistake and scenario cards to Markdown and evaluate the splash pages figures at build time, so llms-full.txt no longer ships 73 raw JSX blocks and 80 unevaluated expressions, and fenced code keeps its import lines.
|
Thanks — this is the review that earned its keep. Everything is fixed on the branch; nothing is deferred and there is no follow-up story. One finding is refuted with primary sources, and one of your coverage gaps turned out to be hiding a real bug. Blocking 1 — refuted: the spec does require a TypeError
The reasoning traces
Base ECMA-402 §11.1.2 has no null path — it only fills in defaults — which is why the constructor-shaped reading comes out the other way. The null return is added by the Temporal amendment's Checked rather than argued: Chromium 153.0.8010.12 throws You were right about the mirror case for a different reason, and we kept your warning: Blocking 2 and 3 — confirmed, and both were bigger than filedThrowing exports: 6, not 3. Adding your three values to the garbage set found
"One root cause, 23 functions" — it was 62 exports and 90 pairsThe
Docs and tooling — all confirmed and fixedEvery item on the list is fixed. Three were larger than filed:
The rest as filed: the stray The addendum — fixed here, not as its own change
You offered to let it land separately. We don't ship a known defect, so it's fixed here, test-first: four rows covering milliseconds, microseconds, nanoseconds and a bare Your point that no Coverage gaps — all closed, and one was hiding a real bugWe took the gap list as a work list rather than a caveat. 1. Writing an oracle from intervalLengthDateTime("2024-01-31T00:00:00", "2024-02-29T12:00:00", "month");
// GMT was 1.0172413793103448 (12h over February's 29 days)
// Chromium 153: 1.0161290322580645 (12h over the following month's 31 days)
Scanned every day-of-month across all twelve months of 2024, ending at several offsets past 0, 1, 2 and 13 units, for Fixed as compat defect D11: 2. 3. 4. 5. On your parenthesis — yes, deliberate. 6. Annotation sweeps per parser — a 22-shape grammar table applied to six validators, 132 assertions. Shapes include a repeated elective key, a repeated Your three questions
Two decisions from the owner, for the record
Where it stands
Thanks again — the two blocking findings we accepted were both wider than they looked, and the gap list found a bug that eleven review units and a 409,552-comparison oracle had all walked past. |
…s too, not just totals (CORE-8, #251) The polyfill bounds a duration between relativeTo plus r1 units and relativeTo plus r2 units and never rechecks that the target falls inside that window, where TC39 recomputes it one unit further along. The previous commit routed only Duration#total around it. The same gap reaches Duration#round and until or since with a calendar smallestUnit, and there it loses a whole unit rather than a fraction: normalizeDuration of P30DT12H floored to months from 2024-01-30 gave PT0S instead of P1M, and diffDateTime from 2024-01-31 to 2024-02-29T12:00 gave 0 months instead of 1. Five seams now take the spec path GMT already owns — monthTotalBySpec, monthRoundBySpec, the zonedUntil gate that covers diffUtc, diffUnix and diffZoned, the new plainUntilWithRounding for diffDateTime, and a D11 term in plainDateUntil for diffDate. All 12,960 round rows, 9,940 until rows and 2,016 total rows now match Chromium 153, and Duration.compare needs no gate because it reaches no nudge window. The round scan also found a defect in GMT own mirror of the algorithm: a target landing exactly on the window lower bound is already rounded, which TC39 states inside ApplyUnsignedRoundingMode, but GMT compares rather than reading the value, so ceil expanded an exact boundary — P60D from 2024-01-31 gave P3M instead of P2M. That was live for the non-ISO calendars before this branch. Fixed by the missing zero-progress branch, pinned in ISO and hebrew, and kept when D11 retires. Corrects the upstream record: this is tc39 proposal-temporal issue 3168, fixed there by PR 3172 (commit 5dd0b0d97ee1, merged 2025-11-19) and not ported by js-temporal on 0.5.1 or main. The ask is a port and release request against js-temporal only, not a new patch and not a tc39 filing. The bug doc section H, the compat README, the canary group, the defect-4 header and the changeset now say so, and three more canary probes cover round and until.
Correction on D11 — I claimed too much and reported too littleTwo corrections to my previous comment, both found while writing the upstream filing it promised. 1. It is not a new defect. It is a known one, already fixed upstreamD11 is tc39/proposal-temporal #3168, I called it a newly discovered polyfill bug and said it needed filings in both repositories. Neither My root-cause wording was also the symptom rather than the mechanism. It is not that the fraction is The polyfill has not ported it on 0.5.1 or on 2. I fixed a third of itThis is the part that matters, and you had already pointed at the reason I missed it: the oracle normalizeDuration("P30DT12H", { smallestUnit: "month", roundingMode: "floor", relativeTo: "2024-01-30" })
// was "PT0S" Chromium 153 and the spec: "P1M"
diffDateTime("2024-01-31T00:00:00", "2024-02-29T12:00:00", ["months"], { smallestUnit: "months", roundingMode: "floor" })
// was { months: 0 } Chromium 153 and the spec: { months: 1 }A whole month, not a fraction. Scans against Chromium 153:
Every mismatch is Now fixed at five seams: And a third defect, this one oursThe normalizeDuration("P60D", { smallestUnit: "month", roundingMode: "ceil", relativeTo: "2024-01-31" })
// was "P3M" Chromium 153: "P2M"It was live for the non-ISO calendars before any of this, since they already took that path — Where that leaves the numbers
You were right that the coverage gaps were the interesting part of your review. Closing one found a |
…R that already carries the port (CORE-8, #251) The port we were about to file already existed: commit 50d66d2 in ptomato open js-temporal PR 361, opened in April and unreviewed since. Our earlier reasoning checked only our own filings 367 to 372 for NudgeToCalendarUnit and never looked at the maintainer own open PRs. What 361 was missing was evidence that the normative commit inside it fixes a user-visible wrong answer today, so that is what we added as a comment, with the reproducer, the Chromium 153 scan and before and after measurements of the commit applied to main. Nothing of ours was filed and no tc39 filing is needed, since tc39 3168 is already fixed there by 3172. The upstream tracker gains that as a twelfth entry, marked as someone else pull request: a role field distinguishes a filing we opened from one we only contributed to, and contributionUrl links our comment, because sync rewrites url from the repo, kind and number every run. The page headline now reads 11 reports and fixes sent, 6 of them as ready-to-merge code changes, and the evidence added to one more the maintainers had already written, so a maintainer PR is never counted among fixes we sent. Its live state is worth tracking because it is what retires D11. Two bugs found while doing it. upstream:sync had never worked past the first repository: REPOS.flatMap(discover) passes the array index as the discover timeout, so the second repo got a one millisecond cap and the command always died there. And buildFiling enumerates its output fields, so a hand-written field it does not name is dropped on the next sync, which for the new role field would silently turn a maintainer PR into one of ours; both are fixed, with the row pinned in a test that reads the committed file rather than the live refresh. D11 itself is unchanged: 50d66d2 is not on main and in no release, so every workaround stays and the removal trigger is now two gates, the commit landing on main and then shipping in a release. Section H of the polyfill bug doc records the measured main versus 50d66d2 table, the suite results, and three traps: Node bundled Temporal is not a valid oracle here, nudgedEpochNs is intentionally left alone upstream, and the 3168 reproducer does not expose this.
…t (CORE-8, #251) The suite ran on Vitest's 5s default, which was never chosen for it. Several tests here are import-bound rather than slow: they await an import of a GMT namespace, which pulls in the polyfill and costs about 3.9s in a fresh worker on an idle machine. Under Scope: 5 of 6 workspace projects packages/gmt-oxlint test$ vitest run --config vitest.config.ts packages/gmt-oxlint test: �[1m�[30m�[46m RUN �[49m�[39m�[22m �[36mv4.1.4 �[39m�[90m/Users/craigcurtis/workbench/northguild/gmt.worktrees/chore/251-core-8-final-review-with-gmt-reviewer-of-entire-api-pre-v1160/packages/gmt-oxlint�[39m packages/gmt-oxlint test: �[32m✓�[39m src/utils/isBannedDateLibrary.test.ts �[2m(�[22m�[2m13 tests�[22m�[2m)�[22m�[32m 2�[2mms�[22m�[39m packages/gmt-oxlint test: �[32m✓�[39m src/rules/no-date-getTimezoneOffset.test.ts �[2m(�[22m�[2m5 tests�[22m�[2m)�[22m�[32m 3�[2mms�[22m�[39m packages/gmt-oxlint test: �[32m✓�[39m src/rules/no-date-library-imports.test.ts �[2m(�[22m�[2m19 tests�[22m�[2m)�[22m�[32m 4�[2mms�[22m�[39m packages/gmt-oxlint test: �[32m✓�[39m src/utils/hasDateStaticMemberCall.test.ts �[2m(�[22m�[2m5 tests�[22m�[2m)�[22m�[32m 2�[2mms�[22m�[39m packages/gmt-oxlint test: �[32m✓�[39m src/rules/no-date-parse.test.ts �[2m(�[22m�[2m8 tests�[22m�[2m)�[22m�[32m 4�[2mms�[22m�[39m packages/gmt-oxlint test: �[32m✓�[39m src/rules/no-date-global.test.ts �[2m(�[22m�[2m6 tests�[22m�[2m)�[22m�[32m 6�[2mms�[22m�[39m packages/gmt-oxlint test: �[32m✓�[39m src/rules/no-date-now.test.ts �[2m(�[22m�[2m7 tests�[22m�[2m)�[22m�[32m 7�[2mms�[22m�[39m packages/gmt-oxlint test: �[32m✓�[39m src/rules/no-date-utc.test.ts �[2m(�[22m�[2m8 tests�[22m�[2m)�[22m�[32m 4�[2mms�[22m�[39m packages/gmt-oxlint test: �[32m✓�[39m src/rules/no-new-date.test.ts �[2m(�[22m�[2m6 tests�[22m�[2m)�[22m�[32m 4�[2mms�[22m�[39m packages/gmt-oxlint test: �[32m✓�[39m src/recommended-config.test.ts �[2m(�[22m�[2m1 test�[22m�[2m)�[22m�[32m 2�[2mms�[22m�[39m packages/gmt-oxlint test: �[32m✓�[39m src/index.test.ts �[2m(�[22m�[2m6 tests�[22m�[2m)�[22m�[32m 3�[2mms�[22m�[39m packages/gmt-oxlint test: �[32m✓�[39m src/utils/isIdentifier.test.ts �[2m(�[22m�[2m4 tests�[22m�[2m)�[22m�[32m 2�[2mms�[22m�[39m packages/gmt-oxlint test: �[32m✓�[39m src/utils/isMemberExpression.test.ts �[2m(�[22m�[2m3 tests�[22m�[2m)�[22m�[32m 2�[2mms�[22m�[39m packages/gmt-oxlint test: �[32m✓�[39m src/utils/isChainExpression.test.ts �[2m(�[22m�[2m3 tests�[22m�[2m)�[22m�[32m 2�[2mms�[22m�[39m packages/gmt-oxlint test: �[32m✓�[39m src/utils/getMemberExpressionFromCall.test.ts �[2m(�[22m�[2m3 tests�[22m�[2m)�[22m�[32m 2�[2mms�[22m�[39m packages/gmt-oxlint test: �[2m Test Files �[22m �[1m�[32m15 passed�[39m�[22m�[90m (15)�[39m packages/gmt-oxlint test: �[2m Tests �[22m �[1m�[32m97 passed�[39m�[22m�[90m (97)�[39m packages/gmt-oxlint test: �[2m Start at �[22m 08:08:41 packages/gmt-oxlint test: �[2m Duration �[22m 571ms�[2m (transform 447ms, setup 0ms, import 1.08s, tests 48ms, environment 1ms)�[22m packages/gmt-oxlint test: Done packages/gmt test$ vitest run packages/gmt test: �[1m�[30m�[46m RUN �[49m�[39m�[22m �[36mv4.1.4 �[39m�[90m/Users/craigcurtis/workbench/northguild/gmt.worktrees/chore/251-core-8-final-review-with-gmt-reviewer-of-entire-api-pre-v1160/packages/gmt�[39m packages/gmt test: �[32m✓�[39m src/calendar/calculate/floorToZone.test.ts �[2m(�[22m�[2m194 tests�[22m�[2m)�[22m�[33m 805�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/plain/calculate/diffDateAsDuration.grid.lunar.test.ts �[2m(�[22m�[2m774 tests�[22m�[2m)�[22m�[33m 977�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/zoned/interval/intervalAlgebraZoned.test.ts �[2m(�[22m�[2m8 tests�[22m�[2m)�[22m�[33m 802�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/zoned/interval/intervalCountZoned.test.ts �[2m(�[22m�[2m111 tests�[22m�[2m)�[22m�[33m 1242�[2mms�[22m�[39m packages/gmt test: �[33m�[2m✓�[22m�[39m returns null for '2024-01-01T00:00:00+00:00[UTC]' to '2024-01-08T00:00:00+00:00[UTC]' by 'hour' with a transition every minute �[33m 694�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/plain/calculate/diffDateAsDuration.grid.solar.test.ts �[2m(�[22m�[2m1801 tests�[22m�[2m)�[22m�[33m 1268�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/zoned/interval/intervalOverlappingDaysZoned.test.ts �[2m(�[22m�[2m43 tests�[22m�[2m)�[22m�[33m 1483�[2mms�[22m�[39m packages/gmt test: �[33m�[2m✓�[22m�[39m returns null when the intersection crosses more than 10,000 zone transitions (America/New_York, 1970 to 7000) �[33m 1439�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/internal/zonedBucket.test.ts �[2m(�[22m�[2m68 tests�[22m�[2m)�[22m�[33m 1672�[2mms�[22m�[39m packages/gmt test: �[33m�[2m✓�[22m�[39m always advances, and lands on a real bucket start, in 'GMT' �[33m 309�[2mms�[22m�[39m packages/gmt test: �[33m�[2m✓�[22m�[39m always advances, and lands on a real bucket start, in 'Etc/GMT' �[33m 417�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/plain/calculate/diffDateAsDuration.edges.test.ts �[2m(�[22m�[2m328 tests�[22m�[2m)�[22m�[33m 433�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/plain/calculate/diffDateAsDuration.umalqura.test.ts �[2m(�[22m�[2m259 tests�[22m�[2m)�[22m�[33m 310�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/plain/calculate/diffDateAsDuration.test.ts �[2m(�[22m�[2m376 tests�[22m�[2m)�[22m�[33m 316�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/unix/interval/intervalCountUnix.test.ts �[2m(�[22m�[2m75 tests�[22m�[2m)�[22m�[32m 210�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/plain/parse/parseDateTimeWithPattern.test.ts �[2m(�[22m�[2m49 tests�[22m�[2m)�[22m�[32m 260�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/utc/interval/intervalAlgebraUtc.test.ts �[2m(�[22m�[2m8 tests�[22m�[2m)�[22m�[32m 251�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/zoned/calculate/startOfZoned.test.ts �[2m(�[22m�[2m111 tests�[22m�[2m)�[22m�[33m 2434�[2mms�[22m�[39m packages/gmt test: �[33m�[2m✓�[22m�[39m agree with floorToZone and contain the input for hour/day/week/month in 'GMT' �[33m 617�[2mms�[22m�[39m packages/gmt test: �[33m�[2m✓�[22m�[39m agree with floorToZone and contain the input for hour/day/week/month in 'Etc/GMT' �[33m 508�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/plain/parse/parseDateWithPattern.test.ts �[2m(�[22m�[2m99 tests�[22m�[2m)�[22m�[32m 152�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/unix/interval/intervalAlgebraUnix.test.ts �[2m(�[22m�[2m8 tests�[22m�[2m)�[22m�[32m 207�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/plain/locale/getLocaleMonthNames.test.ts �[2m(�[22m�[2m24 tests�[22m�[2m)�[22m�[32m 133�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/zoned/compare/areZonedEqualBy.test.ts �[2m(�[22m�[2m90 tests�[22m�[2m)�[22m�[32m 144�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/plain/calculate/subtractDate.edges.test.ts �[2m(�[22m�[2m336 tests�[22m�[2m)�[22m�[32m 118�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/internal/zonedWallClock.test.ts �[2m(�[22m�[2m67 tests�[22m�[2m)�[22m�[32m 110�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/plain/locale/getLocaleWeekdayNames.test.ts �[2m(�[22m�[2m24 tests�[22m�[2m)�[22m�[32m 88�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/zoned/calculate/getLocaleZonedStartOfWeek.test.ts �[2m(�[22m�[2m83 tests�[22m�[2m)�[22m�[32m 101�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/zoned/calculate/roundZoned.test.ts �[2m(�[22m�[2m812 tests�[22m�[2m)�[22m�[32m 84�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/plain/calculate/addDate.edges.test.ts �[2m(�[22m�[2m414 tests�[22m�[2m)�[22m�[32m 82�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/plain/calculate/addDate.test.ts �[2m(�[22m�[2m251 tests�[22m�[2m)�[22m�[32m 72�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/zoned/get/getDstTransitions.test.ts �[2m(�[22m�[2m53 tests�[22m�[2m)�[22m�[32m 63�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/internal/zonedWallClockOperations.test.ts �[2m(�[22m�[2m128 tests�[22m�[2m)�[22m�[32m 71�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/unix/unixContract.test.ts �[2m(�[22m�[2m1048 tests�[22m�[2m)�[22m�[32m 121�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/zoned/calculate/subtractZoned.test.ts �[2m(�[22m�[2m191 tests�[22m�[2m)�[22m�[32m 62�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/zoned/interval/intervalDifferenceZoned.test.ts �[2m(�[22m�[2m34 tests�[22m�[2m)�[22m�[32m 66�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/internal/businessCalendar.test.ts �[2m(�[22m�[2m90 tests�[22m�[2m)�[22m�[32m 65�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/internal/calendarZonedString.test.ts �[2m(�[22m�[2m329 tests�[22m�[2m)�[22m�[32m 81�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/internal/temporalCompat/nonIsoArithmetic.test.ts �[2m(�[22m�[2m36 tests�[22m�[2m)�[22m�[32m 54�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/zoned/calculate/diffZonedAsDuration.test.ts �[2m(�[22m�[2m91 tests�[22m�[2m)�[22m�[32m 52�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/zoned/interval/splitIntervalByUnitZoned.test.ts �[2m(�[22m�[2m69 tests�[22m�[2m)�[22m�[32m 59�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/calendar/calculate/bucketRange.test.ts �[2m(�[22m�[2m129 tests�[22m�[2m)�[22m�[33m 6501�[2mms�[22m�[39m packages/gmt test: �[33m�[2m✓�[22m�[39m returns only genuine bucket starts, strictly increasing, in 'GMT' �[33m 820�[2mms�[22m�[39m packages/gmt test: �[33m�[2m✓�[22m�[39m returns only genuine bucket starts, strictly increasing, in 'Etc/GMT' �[33m 680�[2mms�[22m�[39m packages/gmt test: �[33m�[2m✓�[22m�[39m returns only genuine bucket starts, strictly increasing, in 'Asia/Kolkata' �[33m 330�[2mms�[22m�[39m packages/gmt test: �[33m�[2m✓�[22m�[39m returns 10000 buckets when a range needs 'exactly the maximum number of buckets' �[33m 350�[2mms�[22m�[39m packages/gmt test: �[33m�[2m✓�[22m�[39m returns 9999 buckets when a range needs 'one under it' �[33m 328�[2mms�[22m�[39m packages/gmt test: �[33m�[2m✓�[22m�[39m returns an empty array when a range needs 'one bucket over the maximum' �[33m 331�[2mms�[22m�[39m packages/gmt test: �[33m�[2m✓�[22m�[39m returns [] for 'day' buckets from '1900-01-01T00:00:00Z' to '1960-01-01T00:00:00Z' in 'Etc/GMT+12' within a second ('60 years of days') �[33m 315�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/zoned/calculate/addZoned.test.ts �[2m(�[22m�[2m216 tests�[22m�[2m)�[22m�[32m 69�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/test/differenceCarry.test.ts �[2m(�[22m�[2m312 tests�[22m�[2m)�[22m�[32m 106�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/test/diffRoundingValues.test.ts �[2m(�[22m�[2m1368 tests�[22m�[2m)�[22m�[32m 144�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/test/intervalSetAlgebra.test.ts �[2m(�[22m�[2m720 tests�[22m�[2m)�[22m�[32m 226�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/zoned/calculate/endOfZoned.test.ts �[2m(�[22m�[2m95 tests�[22m�[2m)�[22m�[32m 56�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/plain/format/formatDateTime.test.ts �[2m(�[22m�[2m190 tests�[22m�[2m)�[22m�[32m 38�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/zoned/format/formatZonedRange.test.ts �[2m(�[22m�[2m71 tests�[22m�[2m)�[22m�[32m 71�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/zoned/interval/intervalXorAllZoned.test.ts �[2m(�[22m�[2m26 tests�[22m�[2m)�[22m�[32m 56�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/zoned/interval/intervalXorZoned.test.ts �[2m(�[22m�[2m32 tests�[22m�[2m)�[22m�[32m 56�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/zoned/map/mapZonedHoursInDay.test.ts �[2m(�[22m�[2m64 tests�[22m�[2m)�[22m�[32m 50�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/span/calculate/spanWallClock.test.ts �[2m(�[22m�[2m236 tests�[22m�[2m)�[22m�[32m 42�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/test/intervalLengthOracle.test.ts �[2m(�[22m�[2m108 tests�[22m�[2m)�[22m�[33m 987�[2mms�[22m�[39m packages/gmt test: �[33m�[2m✓�[22m�[39m day from 1970-01-01T00:00:00 to 2024-07-04T09:15:00 (Zoned, America/New_York) �[33m 383�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/duration/calculate/durationAs.test.ts �[2m(�[22m�[2m135 tests�[22m�[2m)�[22m�[32m 41�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/zoned/interval/intervalLengthZoned.test.ts �[2m(�[22m�[2m48 tests�[22m�[2m)�[22m�[32m 46�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/plain/format/formatDateTimeRange.test.ts �[2m(�[22m�[2m76 tests�[22m�[2m)�[22m�[32m 44�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/plain/format/formatRelativeDateTime.test.ts �[2m(�[22m�[2m265 tests�[22m�[2m)�[22m�[32m 36�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/zoned/interval/intervalFromDurationZoned.test.ts �[2m(�[22m�[2m125 tests�[22m�[2m)�[22m�[32m 48�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/unix/calculate/startOfUnix.test.ts �[2m(�[22m�[2m61 tests�[22m�[2m)�[22m�[32m 46�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/plain/format/formatTime.test.ts �[2m(�[22m�[2m192 tests�[22m�[2m)�[22m�[32m 40�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/unix/compare/areUnixEqualBy.test.ts �[2m(�[22m�[2m47 tests�[22m�[2m)�[22m�[32m 41�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/zoned/format/formatZonedDateTime.test.ts �[2m(�[22m�[2m223 tests�[22m�[2m)�[22m�[32m 42�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/plain/calculate/subtractDate.test.ts �[2m(�[22m�[2m57 tests�[22m�[2m)�[22m�[32m 38�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/plain/format/formatRelativeTime.test.ts �[2m(�[22m�[2m250 tests�[22m�[2m)�[22m�[32m 41�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/plain/format/formatRelativeDate.test.ts �[2m(�[22m�[2m274 tests�[22m�[2m)�[22m�[32m 37�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/instant/convert/resolveLocal.test.ts �[2m(�[22m�[2m138 tests�[22m�[2m)�[22m�[32m 41�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/test/nudgeWindowRetry.test.ts �[2m(�[22m�[2m81 tests�[22m�[2m)�[22m�[32m 46�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/zoned/calculate/diffZoned.test.ts �[2m(�[22m�[2m91 tests�[22m�[2m)�[22m�[32m 38�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/zoned/interval/intervalEngulfsZoned.test.ts �[2m(�[22m�[2m32 tests�[22m�[2m)�[22m�[32m 39�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/zoned/interval/intervalAbutsZoned.test.ts �[2m(�[22m�[2m36 tests�[22m�[2m)�[22m�[32m 38�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/zoned/get/getTimeZones.test.ts �[2m(�[22m�[2m4 tests�[22m�[2m)�[22m�[32m 35�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/unix/interval/intervalOverlappingDaysUnix.test.ts �[2m(�[22m�[2m60 tests�[22m�[2m)�[22m�[32m 37�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/plain/format/formatDate.test.ts �[2m(�[22m�[2m195 tests�[22m�[2m)�[22m�[32m 37�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/zoned/format/formatRelativeZoned.test.ts �[2m(�[22m�[2m129 tests�[22m�[2m)�[22m�[32m 33�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/plain/convert/convertDateToCalendar.test.ts �[2m(�[22m�[2m329 tests�[22m�[2m)�[22m�[32m 37�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/unix/format/formatRelativeUnix.test.ts �[2m(�[22m�[2m153 tests�[22m�[2m)�[22m�[32m 33�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/zoned/calculate/getLocaleZonedEndOfWeek.test.ts �[2m(�[22m�[2m82 tests�[22m�[2m)�[22m�[32m 35�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/plain/calculate/addBusinessDays.test.ts �[2m(�[22m�[2m92 tests�[22m�[2m)�[22m�[32m 36�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/utc/format/formatRelativeUtc.test.ts �[2m(�[22m�[2m132 tests�[22m�[2m)�[22m�[32m 32�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/zoned/interval/intervalContainsZoned.test.ts �[2m(�[22m�[2m57 tests�[22m�[2m)�[22m�[32m 35�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/test/noThrow.test.ts �[2m(�[22m�[2m556 tests�[22m�[2m)�[22m�[32m 246�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/plain/calculate/diffDate.test.ts �[2m(�[22m�[2m89 tests�[22m�[2m)�[22m�[32m 30�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/instant/convert/fromOffsetInstant.test.ts �[2m(�[22m�[2m134 tests�[22m�[2m)�[22m�[32m 38�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/internal/zonedWallClockDifference.test.ts �[2m(�[22m�[2m56 tests�[22m�[2m)�[22m�[32m 31�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/plain/interval/intervalCountDate.test.ts �[2m(�[22m�[2m79 tests�[22m�[2m)�[22m�[32m 31�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/plain/interval/splitIntervalByUnitDate.test.ts �[2m(�[22m�[2m62 tests�[22m�[2m)�[22m�[32m 34�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/plain/calculate/addDate.grid.test.ts �[2m(�[22m�[2m150 tests�[22m�[2m)�[22m�[32m 34�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/test/optionsObject.test.ts �[2m(�[22m�[2m544 tests�[22m�[2m)�[22m�[32m 107�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/plain/convert/convertDateToCalendar.umalqura.test.ts �[2m(�[22m�[2m528 tests�[22m�[2m)�[22m�[32m 34�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/test/requiredLocale.test.ts �[2m(�[22m�[2m21 tests�[22m�[2m)�[22m�[32m 34�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/instant/convert/toOffsetInstant.test.ts �[2m(�[22m�[2m158 tests�[22m�[2m)�[22m�[32m 25�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/interval/calculate/intersectIntervals.test.ts �[2m(�[22m�[2m58 tests�[22m�[2m)�[22m�[32m 32�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/zoned/compare/isZonedThisUnit.test.ts �[2m(�[22m�[2m89 tests�[22m�[2m)�[22m�[32m 31�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/duration/normalize/normalizeDuration.test.ts �[2m(�[22m�[2m74 tests�[22m�[2m)�[22m�[32m 32�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/zoned/interval/intervalIntersectionZoned.test.ts �[2m(�[22m�[2m36 tests�[22m�[2m)�[22m�[32m 30�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/zoned/interval/intervalUnionZoned.test.ts �[2m(�[22m�[2m100 tests�[22m�[2m)�[22m�[32m 30�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/zoned/interval/calendarZonedIntervalPolicy.test.ts �[2m(�[22m�[2m27 tests�[22m�[2m)�[22m�[32m 32�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/zoned/calculate/startOfQuarterForZoned.test.ts �[2m(�[22m�[2m35 tests�[22m�[2m)�[22m�[32m 26�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/zoned/calculate/addZonedBusinessDays.test.ts �[2m(�[22m�[2m59 tests�[22m�[2m)�[22m�[32m 28�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/zoned/calculate/getHoursInZonedDay.test.ts �[2m(�[22m�[2m70 tests�[22m�[2m)�[22m�[32m 28�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/zoned/format/formatCalendarZoned.test.ts �[2m(�[22m�[2m64 tests�[22m�[2m)�[22m�[32m 30�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/plain/format/formatCalendar.test.ts �[2m(�[22m�[2m71 tests�[22m�[2m)�[22m�[32m 23�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/internal/temporalCompat/fieldSearch.test.ts �[2m(�[22m�[2m19 tests�[22m�[2m)�[22m�[32m 23�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/plain/interval/intervalLengthDate.test.ts �[2m(�[22m�[2m30 tests�[22m�[2m)�[22m�[32m 25�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/utc/format/formatCalendarUtc.test.ts �[2m(�[22m�[2m62 tests�[22m�[2m)�[22m�[32m 26�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/zoned/interval/intervalSplitAtZoned.test.ts �[2m(�[22m�[2m24 tests�[22m�[2m)�[22m�[32m 24�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/internal/temporalCompat/largeMonthArithmetic.test.ts �[2m(�[22m�[2m37 tests�[22m�[2m)�[22m�[33m 12340�[2mms�[22m�[39m packages/gmt test: �[33m�[2m✓�[22m�[39m 'gmt.addDate("2024-01-15[u-ca=persian]…' → '+252023-12-27[u-ca=persian]' ('persian 3,000,000 months = 250,000 ye…') �[33m 467�[2mms�[22m�[39m packages/gmt test: �[33m�[2m✓�[22m�[39m 'gmt.subtractDate("2024-01-14[u-ca=isl…' → '-240532-04-17[u-ca=islamic-civil]' ('islamic-civil back 250,000 years') �[33m 639�[2mms�[22m�[39m packages/gmt test: �[33m�[2m✓�[22m�[39m 'gmt.addDate("2024-01-15[u-ca=japanese…' → '+252024-01-15[u-ca=japanese]' ('japanese 250,000 years, still reiwa') �[33m 396�[2mms�[22m�[39m packages/gmt test: �[33m�[2m✓�[22m�[39m 'gmt.addDate("2024-01-15[u-ca=gregory]…' → '+252024-01-15[u-ca=gregory]' ('gregory 250,000 years (Chromium 153)') �[33m 365�[2mms�[22m�[39m packages/gmt test: �[33m�[2m✓�[22m�[39m 'gmt.addDate("2024-03-15[u-ca=ethiopic…' → '+232798-03-10[u-ca=ethiopic]' ('ethiopic 13-month years: 230,769 year…') �[33m 430�[2mms�[22m�[39m packages/gmt test: �[33m�[2m✓�[22m�[39m 'gmt.addDate("2024-03-15[u-ca=coptic]"…' → '+232798-03-10[u-ca=coptic]' ('coptic 13-month years: 230,769 years …') �[33m 370�[2mms�[22m�[39m packages/gmt test: �[33m�[2m✓�[22m�[39m 'gmt.addDate("2024-01-15[u-ca=hebrew]"…' → '+244580-02-07[u-ca=hebrew]' ('hebrew leap-month years (D–R month co…') �[33m 339�[2mms�[22m�[39m packages/gmt test: �[33m�[2m✓�[22m�[39m 'gmt.addDate("2024-01-15[u-ca=persian]…' → '' ('persian year 334735 is past the maxim…') �[33m 337�[2mms�[22m�[39m packages/gmt test: �[33m�[2m✓�[22m�[39m 'gmt.addDate("2024-01-15[u-ca=persian]…' → '' ('the largest valid Duration months fie…') �[33m 302�[2mms�[22m�[39m packages/gmt test: �[33m�[2m✓�[22m�[39m 'gmt.diffDate("-247976-02-03[u-ca=pers…' → 6000000 ('persian 500,000 years of months, acro…') �[33m 325�[2mms�[22m�[39m packages/gmt test: �[33m�[2m✓�[22m�[39m 'gmt.intervalLengthDate("2024-01-15[u-…' → 3000000 ('interval length in months') �[33m 458�[2mms�[22m�[39m packages/gmt test: �[33m�[2m✓�[22m�[39m 'gmt.durationAs("P3000000M", "days", {…' → 91310606 ('ISO 2024-01-15 → +252023-12-27') �[33m 403�[2mms�[22m�[39m packages/gmt test: �[33m�[2m✓�[22m�[39m 'gmt.durationAs("P3000000M", "days", {…' → 88591783 ('hebrew 5784-05-05 → 248337-07-05 in I…') �[33m 361�[2mms�[22m�[39m packages/gmt test: �[33m�[2m✓�[22m�[39m 'gmt.durationAs("P3000000M", "days", {…' → 84288467 ('coptic 1740-07-06 → 232509-10-06 in I…') �[33m 376�[2mms�[22m�[39m packages/gmt test: �[33m�[2m✓�[22m�[39m 'gmt.normalizeDuration("P90000000D", {…' → 'P2956940M5D' ('target persian 247814-06-30: 246,412 …') �[33m 343�[2mms�[22m�[39m packages/gmt test: �[33m�[2m✓�[22m�[39m 'gmt.normalizeDuration("P90000000D", {…' → 'P3203285M24D' ('target ethioaa 253923-01-30, 13-month…') �[33m 342�[2mms�[22m�[39m packages/gmt test: �[33m�[2m✓�[22m�[39m 'gmt.compareDurations("P3000000M", "P1…' → 1 ('3,000,000 months is longer than a day') �[33m 348�[2mms�[22m�[39m packages/gmt test: �[33m�[2m✓�[22m�[39m 'gmt.compareDurations("P4000000M", "P1…' → null ('relativeTo + 4,000,000 months is past…') �[33m 338�[2mms�[22m�[39m packages/gmt test: �[33m�[2m✓�[22m�[39m 'gmt.addZoned("2024-01-15T12:00:00+03:…' → '+252023-12-27T12:00:00+03:30[Asia/Teh…' ('Tehran has kept +03:30 without DST si…') �[33m 406�[2mms�[22m�[39m packages/gmt test: �[33m�[2m✓�[22m�[39m 'gmt.subtractZoned("+252023-12-27T12:0…' → '2024-01-15T12:00:00+03:30[Asia/Tehran…' ('inverse of the addZoned row') �[33m 396�[2mms�[22m�[39m packages/gmt test: �[33m�[2m✓�[22m�[39m 'gmt.addZoned("2025-09-05T00:30:00-04:…' → '' ('far past the maximum') �[33m 391�[2mms�[22m�[39m packages/gmt test: �[33m�[2m✓�[22m�[39m 'gmt.diffDate("2024-01-15[u-ca=hebrew]…' → 242553 ('years stay cheap: M07 follows M05') �[33m 385�[2mms�[22m�[39m packages/gmt test: �[33m�[2m✓�[22m�[39m 'gmt.diffZoned("2024-01-15T12:00:00+03…' → 3000000 ('zoned difference in months') �[33m 415�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/zoned/convert/convertZonedToCalendar.test.ts �[2m(�[22m�[2m119 tests�[22m�[2m)�[22m�[32m 30�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/duration/compare/compareDurations.test.ts �[2m(�[22m�[2m77 tests�[22m�[2m)�[22m�[32m 26�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/zoned/calculate/cycleZoned.test.ts �[2m(�[22m�[2m97 tests�[22m�[2m)�[22m�[32m 22�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/unix/format/formatCalendarUnix.test.ts �[2m(�[22m�[2m70 tests�[22m�[2m)�[22m�[32m 27�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/plain/format/formatDateRange.test.ts �[2m(�[22m�[2m55 tests�[22m�[2m)�[22m�[32m 22�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/zoned/calculate/endOfQuarterForZoned.test.ts �[2m(�[22m�[2m35 tests�[22m�[2m)�[22m�[32m 22�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/plain/interval/intervalFromDurationDate.test.ts �[2m(�[22m�[2m31 tests�[22m�[2m)�[22m�[32m 19�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/zoned/interval/mergeIntervalsZoned.test.ts �[2m(�[22m�[2m43 tests�[22m�[2m)�[22m�[32m 21�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/plain/interval/intervalAnnotationPolicy.test.ts �[2m(�[22m�[2m98 tests�[22m�[2m)�[22m�[32m 23�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/zoned/format/formatTimeZoneName.test.ts �[2m(�[22m�[2m31 tests�[22m�[2m)�[22m�[32m 38�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/instant/convert/classifyLocal.test.ts �[2m(�[22m�[2m102 tests�[22m�[2m)�[22m�[32m 22�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/plain/convert/convertDateToCalendar.edges.test.ts �[2m(�[22m�[2m358 tests�[22m�[2m)�[22m�[32m 25�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/internal/resolveLocale.test.ts �[2m(�[22m�[2m25 tests�[22m�[2m)�[22m�[32m 19�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/zoned/calculate/subtractZonedBusinessDays.test.ts �[2m(�[22m�[2m47 tests�[22m�[2m)�[22m�[32m 22�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/zoned/compare/isZonedBusinessDay.test.ts �[2m(�[22m�[2m42 tests�[22m�[2m)�[22m�[32m 21�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/zoned/calculate/setZoned.test.ts �[2m(�[22m�[2m81 tests�[22m�[2m)�[22m�[32m 20�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/unix/interval/intervalLengthUnix.test.ts �[2m(�[22m�[2m64 tests�[22m�[2m)�[22m�[32m 21�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/plain/locale/getLocaleEraNames.test.ts �[2m(�[22m�[2m25 tests�[22m�[2m)�[22m�[32m 19�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/zoned/calculate/clampZoned.test.ts �[2m(�[22m�[2m79 tests�[22m�[2m)�[22m�[32m 20�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/unix/format/formatUnix.test.ts �[2m(�[22m�[2m53 tests�[22m�[2m)�[22m�[32m 19�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/zoned/get/getZonedNow.test.ts �[2m(�[22m�[2m48 tests�[22m�[2m)�[22m�[32m 17�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/zoned/calculate/closestZonedTo.test.ts �[2m(�[22m�[2m84 tests�[22m�[2m)�[22m�[32m 21�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/unix/calculate/endOfUnix.test.ts �[2m(�[22m�[2m56 tests�[22m�[2m)�[22m�[32m 18�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/calendar/calculate/getFiscalPeriod.test.ts �[2m(�[22m�[2m102 tests�[22m�[2m)�[22m�[32m 24�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/zoned/convert/convertPlainDateTimeToZoned.test.ts �[2m(�[22m�[2m89 tests�[22m�[2m)�[22m�[32m 17�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/unix/calculate/diffUnixAsDuration.test.ts �[2m(�[22m�[2m70 tests�[22m�[2m)�[22m�[32m 22�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/interval/calculate/intervalAlgebra.test.ts �[2m(�[22m�[2m3 tests�[22m�[2m)�[22m�[32m 21�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/zoned/compare/isZonedRelativeDay.test.ts �[2m(�[22m�[2m49 tests�[22m�[2m)�[22m�[32m 18�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/plain/calculate/roundDate.test.ts �[2m(�[22m�[2m91 tests�[22m�[2m)�[22m�[32m 18�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/zoned/format/formatZonedToParts.test.ts �[2m(�[22m�[2m50 tests�[22m�[2m)�[22m�[32m 17�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/unix/calculate/diffUnix.test.ts �[2m(�[22m�[2m55 tests�[22m�[2m)�[22m�[32m 18�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/zoned/map/mapZonedDatesInRange.test.ts �[2m(�[22m�[2m73 tests�[22m�[2m)�[22m�[32m 18�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/zoned/get/getZonedNowUnit.test.ts �[2m(�[22m�[2m63 tests�[22m�[2m)�[22m�[32m 18�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/zoned/compare/isZonedWeekend.test.ts �[2m(�[22m�[2m111 tests�[22m�[2m)�[22m�[32m 18�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/zoned/compare/isZonedPast.test.ts �[2m(�[22m�[2m46 tests�[22m�[2m)�[22m�[32m 15�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/zoned/validate/isValidCalendarZonedDateTime.test.ts �[2m(�[22m�[2m98 tests�[22m�[2m)�[22m�[32m 20�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/plain/calculate/roundDateTime.test.ts �[2m(�[22m�[2m93 tests�[22m�[2m)�[22m�[32m 18�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/unix/calculate/roundUnix.test.ts �[2m(�[22m�[2m63 tests�[22m�[2m)�[22m�[32m 19�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/zoned/interval/intervalDivideEquallyZoned.test.ts �[2m(�[22m�[2m36 tests�[22m�[2m)�[22m�[32m 16�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/plain/compare/areDateTimesEqualBy.test.ts �[2m(�[22m�[2m69 tests�[22m�[2m)�[22m�[32m 12�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/plain/format/formatDateTimeToParts.test.ts �[2m(�[22m�[2m49 tests�[22m�[2m)�[22m�[32m 21�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/zoned/validate/isValidTimeZone.test.ts �[2m(�[22m�[2m91 tests�[22m�[2m)�[22m�[32m 16�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/zoned/validate/isValidZonedDateTime.test.ts �[2m(�[22m�[2m176 tests�[22m�[2m)�[22m�[32m 19�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/calendar/business/rollDate.test.ts �[2m(�[22m�[2m79 tests�[22m�[2m)�[22m�[32m 17�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/plain/calculate/diffTime.test.ts �[2m(�[22m�[2m61 tests�[22m�[2m)�[22m�[32m 17�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/utc/compare/areUtcEqualBy.test.ts �[2m(�[22m�[2m59 tests�[22m�[2m)�[22m�[32m 20�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/unix/calculate/minUnix.test.ts �[2m(�[22m�[2m14 tests�[22m�[2m)�[22m�[32m 16�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/plain/format/formatDateToParts.test.ts �[2m(�[22m�[2m49 tests�[22m�[2m)�[22m�[32m 17�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/plain/parse/parseTimeWithPattern.test.ts �[2m(�[22m�[2m60 tests�[22m�[2m)�[22m�[32m 16�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/utc/interval/intervalCountUtc.test.ts �[2m(�[22m�[2m50 tests�[22m�[2m)�[22m�[32m 16�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/utc/calculate/diffUtc.test.ts �[2m(�[22m�[2m47 tests�[22m�[2m)�[22m�[32m 15�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/plain/compare/isThisUnit.test.ts �[2m(�[22m�[2m60 tests�[22m�[2m)�[22m�[32m 16�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/zoned/convert/convertZonedToUnix.test.ts �[2m(�[22m�[2m94 tests�[22m�[2m)�[22m�[32m 15�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/unix/calculate/maxUnix.test.ts �[2m(�[22m�[2m16 tests�[22m�[2m)�[22m�[32m 16�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/utc/calculate/endOfUtc.test.ts �[2m(�[22m�[2m60 tests�[22m�[2m)�[22m�[32m 14�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/zoned/chop/chopZonedDateTime.test.ts �[2m(�[22m�[2m99 tests�[22m�[2m)�[22m�[32m 15�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/calendar/business/businessDaysBetween.test.ts �[2m(�[22m�[2m70 tests�[22m�[2m)�[22m�[32m 15�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/utc/interval/splitIntervalByUnitUtc.test.ts �[2m(�[22m�[2m53 tests�[22m�[2m)�[22m�[32m 15�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/calendar/business/mergeCalendars.test.ts �[2m(�[22m�[2m49 tests�[22m�[2m)�[22m�[32m 15�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/zoned/compare/isZonedFuture.test.ts �[2m(�[22m�[2m46 tests�[22m�[2m)�[22m�[32m 16�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/utc/interval/intervalAnnotationPolicy.test.ts �[2m(�[22m�[2m38 tests�[22m�[2m)�[22m�[32m 15�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/unix/calculate/setUnix.test.ts �[2m(�[22m�[2m46 tests�[22m�[2m)�[22m�[32m 16�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/zoned/compare/areZonedEqual.test.ts �[2m(�[22m�[2m44 tests�[22m�[2m)�[22m�[32m 14�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/zoned/get/getZonedToday.test.ts �[2m(�[22m�[2m48 tests�[22m�[2m)�[22m�[32m 13�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/unix/interval/intervalFromDurationUnix.test.ts �[2m(�[22m�[2m43 tests�[22m�[2m)�[22m�[32m 17�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/plain/calculate/diffDateTime.test.ts �[2m(�[22m�[2m68 tests�[22m�[2m)�[22m�[32m 12�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/duration/format/formatDuration.test.ts �[2m(�[22m�[2m55 tests�[22m�[2m)�[22m�[32m 21�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/unix/convert/convertUnixToZoned.test.ts �[2m(�[22m�[2m122 tests�[22m�[2m)�[22m�[32m 17�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/plain/calculate/subtractBusinessDays.test.ts �[2m(�[22m�[2m85 tests�[22m�[2m)�[22m�[32m 12�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/plain/interval/splitIntervalByUnitDateTime.test.ts �[2m(�[22m�[2m51 tests�[22m�[2m)�[22m�[32m 14�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/zoned/compare/isInDaylightSaving.test.ts �[2m(�[22m�[2m40 tests�[22m�[2m)�[22m�[32m 15�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/zoned/interval/validate/isValidZonedInterval.test.ts �[2m(�[22m�[2m57 tests�[22m�[2m)�[22m�[32m 14�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/plain/compare/isBusinessDay.test.ts �[2m(�[22m�[2m75 tests�[22m�[2m)�[22m�[32m 10�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/zoned/parse/parseRfc2822.test.ts �[2m(�[22m�[2m73 tests�[22m�[2m)�[22m�[32m 14�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/plain/compare/isRelativeDay.test.ts �[2m(�[22m�[2m19 tests�[22m�[2m)�[22m�[32m 13�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/unix/interval/splitIntervalByUnitUnix.test.ts �[2m(�[22m�[2m84 tests�[22m�[2m)�[22m�[32m 14�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/unix/calculate/startOfQuarterForUnix.test.ts �[2m(�[22m�[2m18 tests�[22m�[2m)�[22m�[32m 12�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/internal/fiscalCalendar.test.ts �[2m(�[22m�[2m47 tests�[22m�[2m)�[22m�[32m 13�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/plain/calculate/endOfDateTime.test.ts �[2m(�[22m�[2m74 tests�[22m�[2m)�[22m�[32m 12�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/zoned/interval/intervalsOverlapZoned.test.ts �[2m(�[22m�[2m32 tests�[22m�[2m)�[22m�[32m 13�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/internal/durationUntilString.test.ts �[2m(�[22m�[2m27 tests�[22m�[2m)�[22m�[32m 10�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/utc/interval/intervalLengthUtc.test.ts �[2m(�[22m�[2m17 tests�[22m�[2m)�[22m�[32m 12�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/utc/calculate/diffUtcAsDuration.test.ts �[2m(�[22m�[2m39 tests�[22m�[2m)�[22m�[32m 14�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/plain/calculate/getWeeksInLocaleWeekYear.test.ts �[2m(�[22m�[2m50 tests�[22m�[2m)�[22m�[32m 14�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/zoned/convert/convertZonedToZoned.test.ts �[2m(�[22m�[2m70 tests�[22m�[2m)�[22m�[32m 11�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/precision/convert/fromExcelSerial.test.ts �[2m(�[22m�[2m67 tests�[22m�[2m)�[22m�[32m 12�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/zoned/calculate/getLocaleZonedDayOfWeek.test.ts �[2m(�[22m�[2m75 tests�[22m�[2m)�[22m�[32m 14�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/zoned/chop/chopZonedMilliseconds.test.ts �[2m(�[22m�[2m56 tests�[22m�[2m)�[22m�[32m 13�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/utc/parse/parseHttp.test.ts �[2m(�[22m�[2m44 tests�[22m�[2m)�[22m�[32m 14�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/zoned/chop/chopZonedSeconds.test.ts �[2m(�[22m�[2m56 tests�[22m�[2m)�[22m�[32m 13�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/precision/convert/fromNtpTimestamp.test.ts �[2m(�[22m�[2m58 tests�[22m�[2m)�[22m�[32m 12�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/zoned/parse/parseUnitFromZoned.test.ts �[2m(�[22m�[2m71 tests�[22m�[2m)�[22m�[32m 12�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/zoned/parse/parseDateFromZoned.test.ts �[2m(�[22m�[2m46 tests�[22m�[2m)�[22m�[32m 12�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/zoned/format/formatRfc2822.test.ts �[2m(�[22m�[2m36 tests�[22m�[2m)�[22m�[32m 13�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/plain/interval/splitIntervalByUnitTime.test.ts �[2m(�[22m�[2m45 tests�[22m�[2m)�[22m�[32m 12�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/zoned/compare/isBeforeZoned.test.ts �[2m(�[22m�[2m42 tests�[22m�[2m)�[22m�[32m 11�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/zoned/parse/getZonedOffsetAs.test.ts �[2m(�[22m�[2m41 tests�[22m�[2m)�[22m�[32m 11�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/plain/locale/getLocaleMeridiems.test.ts �[2m(�[22m�[2m25 tests�[22m�[2m)�[22m�[32m 11�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/plain/interval/intervalCountDateTime.test.ts �[2m(�[22m�[2m63 tests�[22m�[2m)�[22m�[32m 11�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/zoned/compare/isAfterZoned.test.ts �[2m(�[22m�[2m42 tests�[22m�[2m)�[22m�[32m 10�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/plain/interval/mergeIntervalsDate.test.ts �[2m(�[22m�[2m18 tests�[22m�[2m)�[22m�[32m 8�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/zoned/parse/parseTimeFromZoned.test.ts �[2m(�[22m�[2m47 tests�[22m�[2m)�[22m�[32m 11�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/span/calculate/spanMs.test.ts �[2m(�[22m�[2m73 tests�[22m�[2m)�[22m�[32m 12�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/plain/interval/intervalDivideEquallyTime.test.ts �[2m(�[22m�[2m34 tests�[22m�[2m)�[22m�[32m 11�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/unix/parse/parseDateFromUnix.test.ts �[2m(�[22m�[2m37 tests�[22m�[2m)�[22m�[32m 12�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/zoned/convert/convertZonedToUtc.test.ts �[2m(�[22m�[2m66 tests�[22m�[2m)�[22m�[32m 13�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/internal/resolveDurationRelativeTo.test.ts �[2m(�[22m�[2m45 tests�[22m�[2m)�[22m�[32m 13�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/plain/calculate/diffDateTimeAsDuration.test.ts �[2m(�[22m�[2m52 tests�[22m�[2m)�[22m�[32m 10�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/unix/calculate/addUnix.test.ts �[2m(�[22m�[2m28 tests�[22m�[2m)�[22m�[32m 14�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/utc/convert/convertUtcToZoned.test.ts �[2m(�[22m�[2m49 tests�[22m�[2m)�[22m�[32m 10�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/utc/parse/parseUnitFromUtc.test.ts �[2m(�[22m�[2m55 tests�[22m�[2m)�[22m�[32m 12�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/unix/parse/parseTimeFromUnix.test.ts �[2m(�[22m�[2m31 tests�[22m�[2m)�[22m�[32m 10�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/interval/calculate/sumIntervals.test.ts �[2m(�[22m�[2m38 tests�[22m�[2m)�[22m�[32m 10�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/plain/validate/isValidCalendarDate.test.ts �[2m(�[22m�[2m87 tests�[22m�[2m)�[22m�[32m 11�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/precision/convert/fromNanoseconds.test.ts �[2m(�[22m�[2m54 tests�[22m�[2m)�[22m�[32m 8�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/plain/interval/intervalUnionDate.test.ts �[2m(�[22m�[2m36 tests�[22m�[2m)�[22m�[32m 10�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/utc/calculate/startOfUtc.test.ts �[2m(�[22m�[2m42 tests�[22m�[2m)�[22m�[32m 11�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/zoned/chop/chopZonedDate.test.ts �[2m(�[22m�[2m56 tests�[22m�[2m)�[22m�[32m 9�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/plain/map/mapDatesInRange.test.ts �[2m(�[22m�[2m42 tests�[22m�[2m)�[22m�[32m 8�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/unix/parse/parseWeekFromUnix.test.ts �[2m(�[22m�[2m30 tests�[22m�[2m)�[22m�[32m 11�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/unix/parse/parseUnitFromUnix.test.ts �[2m(�[22m�[2m76 tests�[22m�[2m)�[22m�[32m 10�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/plain/calculate/startOfDateTime.test.ts �[2m(�[22m�[2m57 tests�[22m�[2m)�[22m�[32m 10�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/internal/utcOffsetString.test.ts �[2m(�[22m�[2m159 tests�[22m�[2m)�[22m�[32m 11�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/interval/calculate/mergeIntervals.test.ts �[2m(�[22m�[2m61 tests�[22m�[2m)�[22m�[32m 12�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/precision/convert/toExcelSerial.test.ts �[2m(�[22m�[2m80 tests�[22m�[2m)�[22m�[32m 8�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/zoned/get/getTimeZoneOffset.test.ts �[2m(�[22m�[2m56 tests�[22m�[2m)�[22m�[32m 13�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/plain/interval/intervalDivideEquallyDate.test.ts �[2m(�[22m�[2m35 tests�[22m�[2m)�[22m�[32m 10�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/utc/interval/intervalUnionUtc.test.ts �[2m(�[22m�[2m39 tests�[22m�[2m)�[22m�[32m 11�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/plain/get/getNow.test.ts �[2m(�[22m�[2m25 tests�[22m�[2m)�[22m�[32m 9�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/interval/calculate/clampInterval.test.ts �[2m(�[22m�[2m28 tests�[22m�[2m)�[22m�[32m 10�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/test/annotationGrammar.test.ts �[2m(�[22m�[2m132 tests�[22m�[2m)�[22m�[32m 13�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/utc/format/formatUtc.test.ts �[2m(�[22m�[2m33 tests�[22m�[2m)�[22m�[32m 10�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/zoned/parse/parseWeekFromZoned.test.ts �[2m(�[22m�[2m33 tests�[22m�[2m)�[22m�[32m 9�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/precision/convert/fromFileTime.test.ts �[2m(�[22m�[2m37 tests�[22m�[2m)�[22m�[32m 8�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/internal/unixEpochValue.test.ts �[2m(�[22m�[2m101 tests�[22m�[2m)�[22m�[32m 10�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/plain/calculate/roundTime.test.ts �[2m(�[22m�[2m71 tests�[22m�[2m)�[22m�[32m 9�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/utc/interval/intervalSplitAtUtc.test.ts �[2m(�[22m�[2m16 tests�[22m�[2m)�[22m�[32m 7�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/plain/interval/intervalDifferenceDate.test.ts �[2m(�[22m�[2m33 tests�[22m�[2m)�[22m�[32m 8�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/utc/interval/mergeIntervalsUtc.test.ts �[2m(�[22m�[2m19 tests�[22m�[2m)�[22m�[32m 9�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/interval/compare/intervalsOverlap.test.ts �[2m(�[22m�[2m51 tests�[22m�[2m)�[22m�[32m 10�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/plain/calculate/closestDateTo.test.ts �[2m(�[22m�[2m38 tests�[22m�[2m)�[22m�[32m 9�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/interval/calculate/subtractIntervals.test.ts �[2m(�[22m�[2m48 tests�[22m�[2m)�[22m�[32m 10�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/zoned/format/formatRfc3339.test.ts �[2m(�[22m�[2m36 tests�[22m�[2m)�[22m�[32m 9�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/utc/calculate/roundUtc.test.ts �[2m(�[22m�[2m57 tests�[22m�[2m)�[22m�[32m 10�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/plain/get/getNowUnit.test.ts �[2m(�[22m�[2m26 tests�[22m�[2m)�[22m�[32m 11�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/calendar/validate/isValidBusinessCalendar.test.ts �[2m(�[22m�[2m66 tests�[22m�[2m)�[22m�[32m 9�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/utc/parse/parseWeekFromUtc.test.ts �[2m(�[22m�[2m39 tests�[22m�[2m)�[22m�[32m 12�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/plain/interval/intervalDivideEquallyDateTime.test.ts �[2m(�[22m�[2m34 tests�[22m�[2m)�[22m�[32m 9�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/utc/interval/intervalDivideEquallyUtc.test.ts �[2m(�[22m�[2m36 tests�[22m�[2m)�[22m�[32m 10�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/utc/interval/intervalDifferenceUtc.test.ts �[2m(�[22m�[2m30 tests�[22m�[2m)�[22m�[32m 12�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/utc/interval/intervalContainsUtc.test.ts �[2m(�[22m�[2m42 tests�[22m�[2m)�[22m�[32m 8�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/zoned/interval/intervalAnnotationPolicy.test.ts �[2m(�[22m�[2m14 tests�[22m�[2m)�[22m�[32m 10�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/plain/calculate/getLocaleDayOfWeek.test.ts �[2m(�[22m�[2m55 tests�[22m�[2m)�[22m�[32m 7�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/utc/calculate/subtractUtc.test.ts �[2m(�[22m�[2m33 tests�[22m�[2m)�[22m�[32m 11�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/utc/parse/parseDateFromUtc.test.ts �[2m(�[22m�[2m19 tests�[22m�[2m)�[22m�[32m 8�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/plain/interval/intervalFromDurationTime.test.ts �[2m(�[22m�[2m45 tests�[22m�[2m)�[22m�[32m 10�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/unix/calculate/endOfQuarterForUnix.test.ts �[2m(�[22m�[2m16 tests�[22m�[2m)�[22m�[32m 9�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/utc/interval/intervalIntersectionUtc.test.ts �[2m(�[22m�[2m31 tests�[22m�[2m)�[22m�[32m 10�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/zoned/chop/chopZonedTimezone.test.ts �[2m(�[22m�[2m56 tests�[22m�[2m)�[22m�[32m 11�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/precision/validate/isValidInstant.test.ts �[2m(�[22m�[2m64 tests�[22m�[2m)�[22m�[32m 9�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/internal/calendarDateString.test.ts �[2m(�[22m�[2m74 tests�[22m�[2m)�[22m�[32m 9�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/plain/interval/intervalCountTime.test.ts �[2m(�[22m�[2m52 tests�[22m�[2m)�[22m�[32m 11�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/utc/calculate/endOfQuarterForUtc.test.ts �[2m(�[22m�[2m13 tests�[22m�[2m)�[22m�[32m 10�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/calendar/business/nextBusinessDay.test.ts �[2m(�[22m�[2m53 tests�[22m�[2m)�[22m�[32m 9�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/plain/interval/intervalsOverlapDate.test.ts �[2m(�[22m�[2m30 tests�[22m�[2m)�[22m�[32m 8�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/utc/calculate/setUtc.test.ts �[2m(�[22m�[2m20 tests�[22m�[2m)�[22m�[32m 8�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/duration/calculate/getDurationUnit.test.ts �[2m(�[22m�[2m76 tests�[22m�[2m)�[22m�[32m 8�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/internal/calendarZonedPairPolicy.test.ts �[2m(�[22m�[2m6 tests�[22m�[2m)�[22m�[32m 8�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/zoned/chop/chopZonedTime.test.ts �[2m(�[22m�[2m56 tests�[22m�[2m)�[22m�[32m 9�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/plain/interval/intervalXorAllDate.test.ts �[2m(�[22m�[2m16 tests�[22m�[2m)�[22m�[32m 9�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/utc/interval/intervalFromDurationUtc.test.ts �[2m(�[22m�[2m25 tests�[22m�[2m)�[22m�[32m 9�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/span/calculate/spanNs.test.ts �[2m(�[22m�[2m62 tests�[22m�[2m)�[22m�[32m 8�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/plain/interval/intervalXorDate.test.ts �[2m(�[22m�[2m28 tests�[22m�[2m)�[22m�[32m 8�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/plain/calculate/getLocaleWeekYear.test.ts �[2m(�[22m�[2m54 tests�[22m�[2m)�[22m�[32m 11�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/plain/interval/intervalLengthDateTime.test.ts �[2m(�[22m�[2m14 tests�[22m�[2m)�[22m�[32m 9�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/utc/calculate/addUtc.test.ts �[2m(�[22m�[2m33 tests�[22m�[2m)�[22m�[32m 9�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/utc/parse/parseDayFromUtc.test.ts �[2m(�[22m�[2m13 tests�[22m�[2m)�[22m�[32m 7�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/calendar/business/previousBusinessDay.test.ts �[2m(�[22m�[2m53 tests�[22m�[2m)�[22m�[32m 9�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/utc/calculate/startOfQuarterForUtc.test.ts �[2m(�[22m�[2m15 tests�[22m�[2m)�[22m�[32m 8�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/plain/interval/intervalXorAllTime.test.ts �[2m(�[22m�[2m19 tests�[22m�[2m)�[22m�[32m 9�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/plain/interval/intervalLengthTime.test.ts �[2m(�[22m�[2m12 tests�[22m�[2m)�[22m�[32m 7�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/utc/get/getUtcNowUnit.test.ts �[2m(�[22m�[2m26 tests�[22m�[2m)�[22m�[32m 9�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/plain/interval/intervalIntersectionDate.test.ts �[2m(�[22m�[2m31 tests�[22m�[2m)�[22m�[32m 8�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/plain/interval/intervalAbutsDate.test.ts �[2m(�[22m�[2m35 tests�[22m�[2m)�[22m�[32m 12�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/span/validate/isValidSpan.test.ts �[2m(�[22m�[2m56 tests�[22m�[2m)�[22m�[32m 8�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/interval/calculate/splitIntervalAt.test.ts �[2m(�[22m�[2m42 tests�[22m�[2m)�[22m�[32m 10�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/internal/splitStep.test.ts �[2m(�[22m�[2m39 tests�[22m�[2m)�[22m�[32m 11�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/internal/rfc5322DateTime.test.ts �[2m(�[22m�[2m9 tests�[22m�[2m)�[22m�[32m 8�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/utc/interval/intervalXorAllUtc.test.ts �[2m(�[22m�[2m15 tests�[22m�[2m)�[22m�[32m 9�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/plain/interval/intervalOverlappingDaysDate.test.ts �[2m(�[22m�[2m32 tests�[22m�[2m)�[22m�[32m 10�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/zoned/parse/getZonedOffset.test.ts �[2m(�[22m�[2m32 tests�[22m�[2m)�[22m�[32m 8�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/plain/calculate/addDate.umalqura.test.ts �[2m(�[22m�[2m17 tests�[22m�[2m)�[22m�[32m 9�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/zoned/convert/convertZonedToPlainDateTime.test.ts �[2m(�[22m�[2m15 tests�[22m�[2m)�[22m�[32m 8�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/utc/format/formatHttp.test.ts �[2m(�[22m�[2m32 tests�[22m�[2m)�[22m�[32m 10�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/plain/calculate/addDateTime.test.ts �[2m(�[22m�[2m44 tests�[22m�[2m)�[22m�[32m 8�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/plain/calculate/cycleDateTime.test.ts �[2m(�[22m�[2m39 tests�[22m�[2m)�[22m�[32m 7�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/plain/interval/mergeIntervalsTime.test.ts �[2m(�[22m�[2m16 tests�[22m�[2m)�[22m�[32m 8�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/utc/interval/intervalXorUtc.test.ts �[2m(�[22m�[2m27 tests�[22m�[2m)�[22m�[32m 8�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/plain/calculate/endOfTime.test.ts �[2m(�[22m�[2m41 tests�[22m�[2m)�[22m�[32m 8�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/plain/interval/intervalContainsTime.test.ts �[2m(�[22m�[2m41 tests�[22m�[2m)�[22m�[32m 8�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/plain/interval/intervalUnionTime.test.ts �[2m(�[22m�[2m29 tests�[22m�[2m)�[22m�[32m 8�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/plain/interval/intervalUnionDateTime.test.ts �[2m(�[22m�[2m29 tests�[22m�[2m)�[22m�[32m 8�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/duration/parse/parseDuration.test.ts �[2m(�[22m�[2m59 tests�[22m�[2m)�[22m�[32m 8�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/unix/calculate/subtractUnix.test.ts �[2m(�[22m�[2m28 tests�[22m�[2m)�[22m�[32m 8�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/zoned/validate/isValidZonedRange.test.ts �[2m(�[22m�[2m64 tests�[22m�[2m)�[22m�[32m 8�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/plain/interval/intervalContainsDate.test.ts �[2m(�[22m�[2m41 tests�[22m�[2m)�[22m�[32m 10�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/plain/calculate/cycleTime.test.ts �[2m(�[22m�[2m40 tests�[22m�[2m)�[22m�[32m 7�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/internal/dateTimeUnitHelpers.test.ts �[2m(�[22m�[2m25 tests�[22m�[2m)�[22m�[32m 8�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/interval/compare/intervalContains.test.ts �[2m(�[22m�[2m54 tests�[22m�[2m)�[22m�[32m 9�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/plain/calculate/subtractDateTime.test.ts �[2m(�[22m�[2m41 tests�[22m�[2m)�[22m�[32m 10�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/utc/interval/intervalOverlappingDaysUtc.test.ts �[2m(�[22m�[2m23 tests�[22m�[2m)�[22m�[32m 8�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/unix/get/getUnixNowUnit.test.ts �[2m(�[22m�[2m22 tests�[22m�[2m)�[22m�[32m 8�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/plain/interval/intervalDifferenceTime.test.ts �[2m(�[22m�[2m25 tests�[22m�[2m)�[22m�[32m 7�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/plain/interval/intervalIntersectionTime.test.ts �[2m(�[22m�[2m24 tests�[22m�[2m)�[22m�[32m 8�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/plain/compare/isPast.test.ts �[2m(�[22m�[2m12 tests�[22m�[2m)�[22m�[32m 8�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/internal/normalizeTimeZone.test.ts �[2m(�[22m�[2m42 tests�[22m�[2m)�[22m�[32m 7�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/plain/calculate/startOfTime.test.ts �[2m(�[22m�[2m38 tests�[22m�[2m)�[22m�[32m 7�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/plain/compare/isFuture.test.ts �[2m(�[22m�[2m12 tests�[22m�[2m)�[22m�[32m 8�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/utc/parse/parseSecondFromUtc.test.ts �[2m(�[22m�[2m12 tests�[22m�[2m)�[22m�[32m 7�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/plain/parse/parseUnitFromDateTime.test.ts �[2m(�[22m�[2m50 tests�[22m�[2m)�[22m�[32m 7�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/zoned/parse/parseTimeZoneFromZoned.test.ts �[2m(�[22m�[2m29 tests�[22m�[2m)�[22m�[32m 7�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/unix/parse/parseMonthFromUnix.test.ts �[2m(�[22m�[2m18 tests�[22m�[2m)�[22m�[32m 7�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/plain/interval/intervalFromDurationDateTime.test.ts �[2m(�[22m�[2m24 tests�[22m�[2m)�[22m�[32m 8�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/plain/calculate/subtractTime.test.ts �[2m(�[22m�[2m31 tests�[22m�[2m)�[22m�[32m 7�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/precision/convert/fromPgMicroseconds.test.ts �[2m(�[22m�[2m31 tests�[22m�[2m)�[22m�[32m 8�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/plain/calculate/endOfQuarterForDateTime.test.ts �[2m(�[22m�[2m21 tests�[22m�[2m)�[22m�[32m 9�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/plain/calculate/subtractDate.umalqura.test.ts �[2m(�[22m�[2m6 tests�[22m�[2m)�[22m�[32m 7�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/plain/compare/areDatesEqualBy.test.ts �[2m(�[22m�[2m40 tests�[22m�[2m)�[22m�[32m 8�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/utc/parse/parseMicrosecondFromUtc.test.ts �[2m(�[22m�[2m10 tests�[22m�[2m)�[22m�[32m 7�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/zoned/validate/hasDaylightSaving.test.ts �[2m(�[22m�[2m33 tests�[22m�[2m)�[22m�[32m 8�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/unix/parse/parseYearFromUnix.test.ts �[2m(�[22m�[2m18 tests�[22m�[2m)�[22m�[32m 7�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/precision/convert/fromDotNetTicks.test.ts �[2m(�[22m�[2m31 tests�[22m�[2m)�[22m�[32m 12�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/calendar/calculate/getQuarter.test.ts �[2m(�[22m�[2m62 tests�[22m�[2m)�[22m�[32m 8�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/zoned/parse/parseMonthFromZoned.test.ts �[2m(�[22m�[2m6 tests�[22m�[2m)�[22m�[32m 5�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/utc/interval/intervalsOverlapUtc.test.ts �[2m(�[22m�[2m29 tests�[22m�[2m)�[22m�[32m 7�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/plain/interval/intervalXorAllDateTime.test.ts �[2m(�[22m�[2m14 tests�[22m�[2m)�[22m�[32m 7�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/utc/parse/parseHourFromUtc.test.ts �[2m(�[22m�[2m13 tests�[22m�[2m)�[22m�[32m 7�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/plain/interval/intervalContainsDateTime.test.ts �[2m(�[22m�[2m41 tests�[22m�[2m)�[22m�[32m 8�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/plain/interval/intervalAbutsTime.test.ts �[2m(�[22m�[2m30 tests�[22m�[2m)�[22m�[32m 7�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/internal/calendarDatePairPolicy.test.ts �[2m(�[22m�[2m9 tests�[22m�[2m)�[22m�[32m 7�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/precision/convert/toNanoseconds.test.ts �[2m(�[22m�[2m68 tests�[22m�[2m)�[22m�[32m 8�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/plain/interval/intervalSplitAtDate.test.ts �[2m(�[22m�[2m16 tests�[22m�[2m)�[22m�[32m 8�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/plain/interval/intervalEngulfsDate.test.ts �[2m(�[22m�[2m29 tests�[22m�[2m)�[22m�[32m 8�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/plain/interval/intervalsOverlapTime.test.ts �[2m(�[22m�[2m31 tests�[22m�[2m)�[22m�[32m 8�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/internal/instantNanoseconds.test.ts �[2m(�[22m�[2m50 tests�[22m�[2m)�[22m�[32m 7�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/plain/interval/intervalOverlappingDaysDateTime.test.ts �[2m(�[22m�[2m24 tests�[22m�[2m)�[22m�[32m 7�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/zoned/calculate/sortZoned.test.ts �[2m(�[22m�[2m4 tests�[22m�[2m)�[22m�[32m 8�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/plain/calculate/cycleDate.test.ts �[2m(�[22m�[2m48 tests�[22m�[2m)�[22m�[32m 7�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/internal/temporalCompat/capabilities.test.ts �[2m(�[22m�[2m115 tests�[22m�[2m)�[22m�[32m 9�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/plain/interval/mergeIntervalsDateTime.test.ts �[2m(�[22m�[2m15 tests�[22m�[2m)�[22m�[32m 7�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/utc/calculate/minUtc.test.ts �[2m(�[22m�[2m6 tests�[22m�[2m)�[22m�[32m 5�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/utc/convert/convertUtcToPlainDateTime.test.ts �[2m(�[22m�[2m9 tests�[22m�[2m)�[22m�[32m 7�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/plain/calculate/getWeekOfMonth.test.ts �[2m(�[22m�[2m60 tests�[22m�[2m)�[22m�[32m 8�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/utc/parse/parseNanosecondFromUtc.test.ts �[2m(�[22m�[2m13 tests�[22m�[2m)�[22m�[32m 7�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/plain/interval/intervalXorTime.test.ts �[2m(�[22m�[2m22 tests�[22m�[2m)�[22m�[32m 7�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/internal/intervalNanoseconds.test.ts �[2m(�[22m�[2m33 tests�[22m�[2m)�[22m�[32m 6�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/plain/chop/chopSeconds.test.ts �[2m(�[22m�[2m22 tests�[22m�[2m)�[22m�[32m 6�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/plain/calculate/getLocaleEndOfWeek.test.ts �[2m(�[22m�[2m50 tests�[22m�[2m)�[22m�[32m 7�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/plain/calculate/endOfDate.test.ts �[2m(�[22m�[2m48 tests�[22m�[2m)�[22m�[32m 8�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/zoned/compare/isBetweenZoned.test.ts �[2m(�[22m�[2m17 tests�[22m�[2m)�[22m�[32m 6�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/plain/calculate/getLocaleStartOfWeek.test.ts �[2m(�[22m�[2m50 tests�[22m�[2m)�[22m�[32m 9�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/interval/validate/isValidInterval.test.ts �[2m(�[22m�[2m48 tests�[22m�[2m)�[22m�[32m 7�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/utc/parse/parseMonthFromUtc.test.ts �[2m(�[22m�[2m12 tests�[22m�[2m)�[22m�[32m 7�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/plain/calculate/addTime.test.ts �[2m(�[22m�[2m27 tests�[22m�[2m)�[22m�[32m 7�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/unix/parse/parseSecondFromUnix.test.ts �[2m(�[22m�[2m18 tests�[22m�[2m)�[22m�[32m 6�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/internal/dateUnitHelpers.test.ts �[2m(�[22m�[2m34 tests�[22m�[2m)�[22m�[32m 7�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/plain/interval/intervalDifferenceDateTime.test.ts �[2m(�[22m�[2m23 tests�[22m�[2m)�[22m�[32m 6�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/zoned/parse/parseRfc3339.test.ts �[2m(�[22m�[2m14 tests�[22m�[2m)�[22m�[32m 6�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/plain/parse/parseUnitFromTime.test.ts �[2m(�[22m�[2m29 tests�[22m�[2m)�[22m�[32m 6�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/utc/parse/parseMillisecondFromUtc.test.ts �[2m(�[22m�[2m12 tests�[22m�[2m)�[22m�[32m 7�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/utc/parse/parseDayOfWeekFromUtc.test.ts �[2m(�[22m�[2m12 tests�[22m�[2m)�[22m�[32m 7�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/precision/convert/toDotNetTicks.test.ts �[2m(�[22m�[2m54 tests�[22m�[2m)�[22m�[32m 6�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/plain/interval/intervalIntersectionDateTime.test.ts �[2m(�[22m�[2m24 tests�[22m�[2m)�[22m�[32m 7�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/utc/parse/parseYearFromUtc.test.ts �[2m(�[22m�[2m13 tests�[22m�[2m)�[22m�[32m 7�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/utc/parse/parseMinuteFromUtc.test.ts �[2m(�[22m�[2m12 tests�[22m�[2m)�[22m�[32m 8�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/calendar/calculate/getIsoWeekDate.test.ts �[2m(�[22m�[2m38 tests�[22m�[2m)�[22m�[32m 7�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/precision/convert/toPgMicroseconds.test.ts �[2m(�[22m�[2m53 tests�[22m�[2m)�[22m�[32m 6�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/precision/convert/toNtpTimestamp.test.ts �[2m(�[22m�[2m50 tests�[22m�[2m)�[22m�[32m 6�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/zoned/get/getSystemTimeZone.test.ts �[2m(�[22m�[2m21 tests�[22m�[2m)�[22m�[32m 7�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/unix/parse/parseNanosecondFromUnix.test.ts �[2m(�[22m�[2m18 tests�[22m�[2m)�[22m�[32m 6�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/precision/convert/toFileTime.test.ts �[2m(�[22m�[2m58 tests�[22m�[2m)�[22m�[32m 7�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/plain/calculate/previousWeekday.test.ts �[2m(�[22m�[2m26 tests�[22m�[2m)�[22m�[32m 7�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/zoned/parse/parseMicrosecondFromZoned.test.ts �[2m(�[22m�[2m4 tests�[22m�[2m)�[22m�[32m 5�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/utc/interval/intervalAbutsUtc.test.ts �[2m(�[22m�[2m34 tests�[22m�[2m)�[22m�[32m 6�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/plain/calculate/endOfQuarterForDate.test.ts �[2m(�[22m�[2m22 tests�[22m�[2m)�[22m�[32m 7�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/internal/measureNearRangeEnd.test.ts �[2m(�[22m�[2m6 tests�[22m�[2m)�[22m�[32m 6�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/zoned/parse/parseDateTimeFromZoned.test.ts �[2m(�[22m�[2m28 tests�[22m�[2m)�[22m�[32m 7�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/plain/interval/intervalXorDateTime.test.ts �[2m(�[22m�[2m21 tests�[22m�[2m)�[22m�[32m 7�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/duration/validate/isValidDuration.test.ts �[2m(�[22m�[2m56 tests�[22m�[2m)�[22m�[32m 5�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/plain/parse/parseNanosecondFromTime.test.ts �[2m(�[22m�[2m7 tests�[22m�[2m)�[22m�[32m 5�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/plain/calculate/startOfDate.test.ts �[2m(�[22m�[2m42 tests�[22m�[2m)�[22m�[32m 7�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/plain/interval/intervalEngulfsTime.test.ts �[2m(�[22m�[2m25 tests�[22m�[2m)�[22m�[32m 7�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/internal/joinDateTimeConnector.test.ts �[2m(�[22m�[2m11 tests�[22m�[2m)�[22m�[32m 7�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/plain/calculate/nextWeekday.test.ts �[2m(�[22m�[2m26 tests�[22m�[2m)�[22m�[32m 6�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/regex/calendar-zoned-date-time.test.ts �[2m(�[22m�[2m38 tests�[22m�[2m)�[22m�[32m 6�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/plain/parse/parseMicrosecondFromTime.test.ts �[2m(�[22m�[2m6 tests�[22m�[2m)�[22m�[32m 5�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/plain/calculate/setTime.test.ts �[2m(�[22m�[2m22 tests�[22m�[2m)�[22m�[32m 6�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/plain/interval/intervalAbutsDateTime.test.ts �[2m(�[22m�[2m29 tests�[22m�[2m)�[22m�[32m 7�[2mms�[22m�[39m packages/gmt test: �[32m✓�[39m src/plain/c…
…251) It held four stale validate logs, about 400 KB of build output, one of them a run that never finished. The directory was untracked but not ignored, so `git add -A` would have swept all of it into a commit.
`@fontsource/michroma` supplied one woff2 that has been committed under apps/dox/public/fonts/ since #161, and no script installs from the package; its provenance moves into the @font-face comment in gmt-tokens.css, which is where anyone changing the font will look. `@open-wc/testing` is imported nowhere at all. The lockfile is regenerated with them, which prunes 1,404 lines of transitive entries. That regeneration is not optional: `pnpm install --frozen-lockfile` runs in five CI jobs and fails on any manifest and lockfile mismatch.
…es (CORE-8, #251) Re-queried all twelve filings on 2026-09-23: nothing has moved since the 21st. The B and E adaptations were marked drafted but unverified. They are now checked against tc39's current polyfill/lib/ecmascript.mjs rather than assumed to match: the loop B patches is verbatim at line 2444, MathMin is imported at 52, MS_MAX at 129, and the BEFORE_FIRST_DST line E replaces at 143. Both drafts state plainly that neither has been run against tc39's own test suite.
…ish (CORE-8, #251) The six polyfill PRs closed on 2026-09-21 made the old `/upstream/` page read as six rejections. None was a rejection: every one was routed to the standard first, to keep the polyfill's rebase manageable. A tracker whose spine is our filings cannot say that, so the page is rebuilt on the defect instead. What the page now says, and how it knows: - One row per canary group, with `Still needed?` read from `temporal-compat.json`. That file is written by `pnpm compat:snapshot` from the same probes `pnpm compat` runs, and `validate` fails when the committed copy drifts, so no figure on the page is typed by a human. 14 groups, 81 probes, 13 still needed. - The filings table stays, demoted to what we sent and what happened to it, where a closed row carries the maintainer's own reason. `upstream.mjs check` now fails on a closed and unmerged filing with no `outcome`, because a bare `Closed` is the misleading case. - No pipeline stage is asserted anywhere. Commit presence is unreliable (tc39 squash-merges, so `5dd0b0d97ee1` reports diverged against `main` although its code is there) and a hand-written stage rots silently, so the page carries only what regenerates itself. Written to ISO 24495-1: the opening answers the reader's own question instead of burying it four sections down, `rebase` and `routed` are gone, and the twelve filing descriptions are split so the symptom comes before the cause. Average prose sentence is 12.6 words. Bugs fixed on the way: - The defect table was unreadable. Starlight sets `display: block` on content tables so wide ones scroll, and a block box is not a table box, so `table-layout: fixed` and `width: 100%` never reached the columns; with `gmt-content.css` also setting `white-space: nowrap` on every first cell, column one grew to 862px inside a 612px page. The styles move to `gmt-upstream.css` because an Astro scoped style compiles to `:where(.astro-hash)`, which carries no specificity and therefore cannot override a site rule at all. - `apps/dox` had no `testTimeout`, so it ran on Vitest's 5s default while several of its tests are import-bound at ~3.9s. Under `pnpm -r run test` those crossed 5s and failed `validate`. Now 20s, five times the measured cost. - `@fontsource/michroma` was a dependency nothing imported; its one `.woff2` has been committed since #161. Removed, with the provenance kept in `gmt-tokens.css`. Also reduces the complexity fallow reports on the files this branch touches: every function over 60 lines is split, including `runTwin` (271 lines) into one function per scan. Verified by oracle against Chromium 153 before and after, 409,552 comparisons, 0 mismatches.
…them actually run (CORE-8, #251)
Two corrections, and the three questions I never answered1. The D11 filing story in my last comment is wrongI wrote that The port already existed. ptomato's own open PR js-temporal/temporal-polyfill#361 carries it as commit So nothing of ours was filed, and no tc39 filing is needed either — tc39 #3168 is already fixed there by #3172. What #361 lacked was evidence that the normative commit inside it fixes a wrong answer users hit today. That is what we added, as a comment on #361: the reproducer, the Chromium 153 scan, and before/after measurements of the commit applied to The upstream tracker records this as a twelfth entry with a D11 itself is unchanged. 2. Your three questions were answered in the code, but never back to youAll three landed in
You were also right about the half of the first question I had missed. The migration note explained the clash, but Closing that gap found another instance of the class you flagged. The migration bullet told readers to call Two test-row labels still used the "not a calendar id" phrasing you objected to. 3. Current numbersThe branch has moved since my last comment, so the count I gave is stale. That came out of a sweep removing every native The sweep also found that none of the four lint plugins had ever linted this repo. |
…p a changeset line that recommends a function we never exported (CORE-8, #251) The CORE-8 review asked whether `mapDatesInRange` staying end-inclusive while `interval*` went half-open deserved a line in the migration notes. It got one, and that answered half the question: the changeset explains the clash, but the JSDoc on `mapDatesInRange` and `mapZonedDatesInRange` said only inclusive and never named the `interval*` convention, so a caller reading the generated reference alone could not see it. Both now carry the rule, the direction it differs in, and the one-day bridge between the two conventions. The reference regenerates two pages from it. Writing that bridge exposed a defect in the migration bullet it came from. The bullet told readers to call `subDate(end, { days: 1 })`; the export is `subtractDate` and `subDate` has never existed. It is the same failure mode the review caught in `tall-moons-tickle.md`, and it fails the same way: changesets ship verbatim into `CHANGELOG.md` and `api-surface` does not read `.changeset/*.md`, so nothing in `validate` was ever going to see it. All 37 pending changesets were swept for names that look like GMT API but resolve to nothing in the built `dist`. `subDate` was the only real hit. The other candidates were Temporal and JavaScript built-ins quoted legitimately, or, in `lint-messages-name-real-functions.md`, the wrong name quoted as the thing being corrected. Two test-row labels still called a CLDR alias not a calendar id, which the review pointed out is not what it is. `taiwan` and `islamic-tabular` now say they are CLDR aliases absent from ECMA-402's `AvailableCanonicalCalendars`, which is the actual reason and keeps them distinct from `gregorian`, whose nine letters fail the eight-character limit on a Unicode locale-extension type subtag. `convertZonedToCalendar.test.ts` takes the wording its siblings already use. `stats check` then failed: published 36,349 tests against 36,348 derived. Removing a redundant `formatRfc3339` test in the previous commit moved the count, and the rule that catches that drift is one this review asked for. `stats sync` brings both READMEs and `gmt-stats.json` back in line, and the competitor multipliers recompute with it. `packages/gmt` 36,348 tests and `apps/dox` 4,268 pass, lint and typecheck are clean in all three scopes, and `stats`, `api-surface`, `test-markers`, `upstream` and `deps` all pass. The `api-surface` skip budget is unchanged at 164 examples and 64 documented results, so the new prose added no skipped rows.
Route changes painted the new page in pieces. Three causes, all fixed: - The theme script set innerHTML on an SVG while the page was still parsing. In Chrome that cancels the rel=expect render block, so the page painted before it had finished loading. The icon is now built with DOM calls. - Expressive Code linked its stylesheet inside the body. Everything after the first code block stayed blank until it loaded. Its styles are now inlined. - Pages now use cross-document view transitions. The header and sidebar swap in place, and only the content fades. Firefox and reduced-motion users get a plain cut. React goes to 19.3. On /dox, the widget rail slides in and out, and the first message fades the empty state into the transcript, using the new ViewTransition component. From 72rem up, the layout now follows react.dev. The content column is 50rem wide and centred, the On this page sidebar has a fixed width instead of taking half the spare space, and the search box lines up with the content column at the same width.
…te links (CORE-8, #251)
Review — CORE-8, second pass (
|
…render the defect table, lint the vendored tree, drop a dead D11 seam (CORE-8, #251) The review filed four findings and named the shape behind two of them: an enumerated list standing in for a general rule, where what slipped through is what was not on the list. All four are real. Two are larger than reported, and a third hole turned up while closing the first. **Hostile input returns the sentinel, not an exception.** 221 of the 551 exports threw when an argument resisted inspection. A revoked Proxy throws on get, ownKeys and Array.isArray; an object with a throwing getter throws when a rest-spread enumerates it. Those operations sit in the guards above each function's try, so the guard written to reject invalid input raised instead. Every affected export now evaluates its body inside the try whose catch already returned its sentinel. The reported cause covers part of it: the four spread-before-try sites and about 126 options-slot cases, but roughly 95 fail at non-options positions in functions that take no options at all. The count is 221 of 551 rather than 556, and it is carried by the revoked Proxy alone — the throwing getter accounts for four, all already inside that set. The harness now also feeds a proxy that throws on every trap, so the garbage set stops being a list of remembered shapes. **The upstream defect table reached no text surface.** A raw UpstreamDefects tag shipped into dist/upstream.md, llms-full.txt and the retrieval chunks, so all seven upstream chunks carried zero defect rows while the HTML carried eleven, and the prose around it spoke of each row and the middle column over nothing. The gate that should have caught it matched nine component names — exactly the nine the renderer handles — so it mirrored the handler list instead of checking it. It now matches any capitalised tag, excluding TypeScript generics, across the same three surfaces its sibling scans. That general form found eight more unhandled components, including the home page's own case against Date, whose faults table had never reached the text surfaces either. A second tally was missing too: the sentence counting what we sent upstream moved into a component last round to escape the expression problem, which put it out of reach entirely. **The vendored carve-out's premise was false.** Four unmarked Date calls lived under ai-elements, one of them a calendar value formatted into a user-visible filename on the site that argues Date is the wrong tool. The exemption called that tree vendored and unmodified. All fifteen oxlint pragmas naming this repo's own plugins were present in the vendoring commit itself, prompt-input.tsx was edited again afterwards with a LOCAL MODIFICATION marker, and the directory's own README says we re-theme every component there. The tree is now linted for Date while staying exempt from the style rules, the stopwatch takes a monotonic clock, and a test pins the three carve-out lists against each other. Only components/ui stays exempt; it is genuinely untouched. **A D11 seam that corrected nothing is gone.** plainDateUntil routed ISO date differences through the nudge-window workaround whenever the start day was past the 28th. The defect cannot reach there: the window only misses its target when the target sits strictly between its bounds by a sub-day amount, and two PlainDates have no time component. Measured over about 1.96 million rows against the raw polyfill, in both directions and across every rounding mode and increment, the two paths never disagreed. Removing it costs no answer and withdraws GMT's own exact-boundary behaviour from ISO date differences. The changeset and the bug doc no longer claim a diffDate fix that was never scanned. **And the gates that check any of this had never run in CI.** All three text-surface checks early-return when apps/dox/dist is absent, and the Tests job builds only @northguild/gmt — the site is built in a different job on a different runner. A skip reports as a pass, which is how the raw tag shipped green. Story consistency now builds the site and runs those checks, and outside a local run a missing dist fails loudly rather than passing silently. packages/gmt 36,348 tests and apps/dox 4,283 pass, the no-throw harness is 556 of 556 with the widened set, api-surface reports 0 failing with the skip budget unchanged, and every script gate and all three lint scopes are clean.
All four confirmed and fixed — two were larger, and the gates behind them were not runningThank you for the third-engine D11 scan. Running GMT's You named the shape yourself: an enumerated list standing in for a general rule, and what slipped through is what wasn't on the list. That turned out to describe a third case too. 1. The defect table — confirmed, and there is a second dropped tableFixed, and the gate is now general: any capitalised tag, across the same three surfaces the expression test scans, with a lookbehind so Two things you did not have. The nine names in that regex are exactly the nine The second dropped table is the tally: "we have sent 11 reports and fixes…" appeared in the HTML and nowhere else. That is a regression from last round — 2. Never-throw — 221 confirmed, attribution corrected221 reproduces exactly. Three corrections:
All 221 fixed by moving each function's whole body inside the 3. The carve-out — confirmed, and false three waysAll four calls fixed. Your evidence understates it. Beyond the 15 pragmas, all 15 were present in the vendoring commit itself (
4. The
|
…(CORE-8, #251) The guard added in the previous commit failed whenever apps/dox/dist was absent under CI, which is every job. The Tests job runs the dox suite on three Node versions and has no reason to build the site, so all three failed while Story consistency — the one job that does build it — passed. The flag is now set only on that step. Also folds in pnpm format: the try/catch wrap indented 221 files by two spaces, pushing some lines past the print width.
Title:
chore(gmt): final whole-API standards review before 1.16.0 (CORE-8, #251)Summary
CORE-8 reviews the whole public API of
@northguild/gmtbefore 1.16.0 ships. That is about 550 functions in ten namespaces, 90% of which predate the 1.16.0 epic, checked against TC39 Temporal, ECMA-402, the RFCs and the domain standards each area cites. Sixteengmt-reviewerunits swept the library by dimension and by namespace, and an external review then re-ran every claim on a rebuilt branch. Every finding was reproduced, then fixed test-first, together with its whole defect class.Phase 2 follows the owner's decision of 2026-09-17: there is no 2.0.0, and GMT's users are internal. So every inconsistency and every breaking fix also ships in 1.16.0. That covers half-open positional intervals, RFC 9557 calendar strings, a unified
unix/namespace, Temporal option handling, and removing options that did nothing. Each breaking change is aminorchangeset with a Breaking changes migration section, and there are no deprecation shims. Three re-review units then checked everything phase 2 touched, and those findings are fixed here too.What Changed
1. New gates
scripts/api-surface.mjs(new, run invalidate) fails on any of these:@exampleresult (2,797 of 2,961 run);src/test/noThrow.test.tsfeeds garbage to every argument of every export. It asserts no throw and the declared sentinel.src/test/optionsObject.test.tspassesnull,"x"and1as options to all 174 options-taking functions.src/test/requiredLocale.test.tscovers the 17 functions that require a locale.scripts/temporal-compat.mjsgains a canary for the new calendar month-arithmetic workaround.scripts/stats.mjswritesgmt-stats.jsonin the formatter's layout, so astats:syncthat changes a figure no longer fails the CI format check.2. Half-open positional intervals (breaking)
plain/,utc/,zoned/andunix/are half-open[start, end)(SQL:2011 PERIOD, RFC 5545 §3.6.1), matchinginterval/. The ±1-unit steps are gone.intervalOverlappingDays*returns 0 for an empty intersection.[].3. RFC 9557 calendar strings (breaking)
[u-ca=<id>], and zoned strings are…[zone][u-ca=…]. Calendar ids are the BCP 47 / Temporal ids (gregory,roc,islamic-tbla,ethioaa).;era=is gone, and the critical flag is accepted.4.
unix/unified (breaking)timeZonedefaults to UTC everywhere.{ epochUnit }options everywhere, including the converters andgetUnixNow.epochUnitandtimeZone.""for an unknown zone, and nanosecond fields are three digits.5. Options follow Temporal (breaking)
optionsargument, includingnull, returns the sentinel (GetOptionsObject). TheIntl.DateTimeFormatformatters keep CoerceOptionsToObject.undefinedmeans omitted.setZoned,setUnixandcycleZoneddefaultoffsetto"prefer".disambiguationapplies to a date step into a DST gap.referenceorweekStartsOnreturns the sentinel. The 17 required-locale functions reject[].string | string[].formatRelative*picks units up to year.disambiguation/offsetmembers;offsetonaddZoned,subtractZoned,intervalFromDurationZonedandconvertPlainDateTimeToZoned;offsetanddisambiguationonsetUtc;overflowonaddTime,subtractTime,intervalFromDurationTimeandcycleTime;FormatCalendarUnixOptionsmembers;fractionalSecondDigitsonareUtcEqualBy/areDateTimesEqualBy.6. Differences, parsing and string grammars (breaking)
diff*unit array, amounts of unlisted units fold into the next smaller listed unit, including weeks listed below months or years.units = []returnsnull.diffUnixkeys are plural.parseUnitFrom*reads microseconds and nanoseconds.[key=value]annotations are accepted and ignored. Unknown critical annotations are rejected (RFC 9557 §3.3).isLeapSeconddetects every second-60 spelling, and every validator still rejects them.7. Invalid input, bounded work, internet grammars, DST and formatting
maxPiecesoption (default 1,000,000) bounds splits, divides and mapped ranges.splitIntervalByUnitTimeno longer loops forever.internal/temporalCompat/largeMonthSpan.tsdoes the arithmetic instead.parseRfc2822andparseHttpaccept the full RFC 5322 and RFC 9110 receiver grammars and check the weekday. The formatters stay inside their grammars.…ToParts). Answers at the range limits are exact, andintervalDivideEqually*is exact.8. Packaging
./regex/*entry is removed.Temporal,IntlandtoTemporalInstantare re-exported from every namespace subpath.UnixUnitis exported from/types.typesVersionsandsideEffects: falseare added.enginesis>=22.16.0. CI stays on Node 22, 24 and 26.9. Lint plugins
The
gmt-oxlint,gmt-eslintandgmt-biomemessages namedconvertUtcDateTimeToUnix, which doesn't exist, and the old positionalgetUnixNow. They now nameconvertUtcToUnix(…, { epochUnit })andgetUnixNow({ epochUnit }).10. Docs site
±HH:MMoffsets.| nullin signatures (the generator now runs withstrictNullChecks) and no longer truncates long signatures.11. GMT covers every Temporal bug it reported upstream
While testing against the spec, GMT found defects in
@js-temporal/polyfilland in the proposal's own reference implementation, and filed them upstream: 11 issues and PRs acrossjs-temporal/temporal-polyfillandtc39/proposal-temporal, most with a verified patch, plus a twelfth tracker entry that is not a filing of ours — our comment on the maintainer's PR #361, which already carried the D11 port.Outcome as of 2026-09-23 (re-checked; nothing has moved since 2026-09-21). All six polyfill PRs were closed unmerged, and none was rejected: ports must land "in order" so the maintainer's rebase stays manageable (#367–#369), and new fixes should be applied "in proposal-temporal and pull[ed] in here after" (#370–#372). #373 (release) is open and answered — one release once the rebase has caught up. #361 merged on 2026-09-21, landing
50d66d2(D11) plus D3, D5 and D7 on the polyfill'smain. Nothing is released, so every GMT workaround stays andpnpm compatis unchanged at 13 of 14 groups needed.zoned.Eworkaround: the polyfill starts its time zone transition search in 1847, so the 1844-12-31 date-line crossing in Asia/Manila, Pacific/Guam, Pacific/Saipan, Pacific/Kosrae and Pacific/Palau was never found. GMT now finds it from offsets alone, for instants before 1847 only (zero cost after). Fixed:getDstTransitions(missed the crossing),getHoursInZonedDay(returned 479,340 hours),roundZoned/roundUnixby day (""),startOfZoned/floorToZone/areZonedEqualByby week (a day off),intervalCountZoned(counted the missing day) andaddZonedBusinessDays(jumped to 1899). Its canary retires it once a release contains Start the time zone transition search before the first transition in 1844 js-temporal/temporal-polyfill#372.D10canary: Polyfill: calendarToIsoDate overshoot assertion from #3292 is reachable in coptic/ethiopic/ethioaa month 13 tc39/proposal-temporal#3329 (coptic/ethiopic month 13 in far years) can't reach GMT, which computes those calendars throughethioaaand finds dates from fields by bisection. The canary and 40 far-year test rows pin that; a polyfill failure that is not aRangeErrornow falls back to GMT's own algorithms instead of an empty result.D10still needed on polyfill 0.5.1, as expected.12. Docs site: "Helping fix Temporal", and a faster dev start
/upstream/("Helping fix Temporal", under Start here), built around the defect rather than the filing. It leads with what GMT works around and whether it still has to — one row per canary group, with the "still needed" column read fromtemporal-compat.json, whichpnpm compat:snapshotwrites from the same probespnpm compatruns andvalidategates. 14 groups, 81 probes, 13 still needed. The filings table follows as "what we sent, and what happened to it", where a closed row carries the maintainer's own reason;upstream checknow fails on a closed-unmerged filing with no explanation, because a bare "Closed" is the misleading case. Status refreshes from GitHub duringgenerate(cached for 6 hours, falls back to the committed snapshot offline). The page asserts no upstream pipeline stage: commit presence proved unreliable (tc39 squash-merges, so a fix's original sha reports as absent frommainwhile its code is there), so it carries only what regenerates itself.rebaseandroutedare gone, and the twelve filing descriptions are split so the symptom comes before the cause. Average prose sentence is 12.6 words.llms.txt,llms-full.txtand the site chat now include every top-level page (they skipped Why GMT, Core rules, Install and the home page).pnpm dox:dev: the generator writes only files whose content changed (it used to rewrite about 1,300 on every start), an incremental gmt build replaces the full one before dev, a dev-only watcher regenerates the reference when gmt source changes, and VS Code no longer watches generated output.13. Story, tracker and changesets
context/domination/issues/CORE-8.mdholds the review units, triage, the findings ledger for every wave, and Phase 2 with its decisions of record.context/coding-standards.mdgains § "Intervals are half-open" and the RFC 9557 calendar-string rules. The changeset policy is now: a breaking change isminorwith a Breaking changes section, andmajoris never used.context/domination/tracker.mdmarks CORE-8 Done.14. Review response (baldurpan, 2026-09-20)
The review rebuilt the branch and re-ran every headline claim rather than reading it, then filed 3 blocking
findings, one root cause, 16 docs/tooling items, 3 questions, a coverage-gap list and an addendum. All of it is
answered on this branch: 19 findings fixed, 1 refuted from the primary source, every coverage gap closed — and
one of those gaps was hiding a real bug.
Refuted —
formatDate/formatTimereturning"". The review readtoLocaleStringas constructing with~any~. The Temporal amendment constructs[[TemporalPlainDateFormat]]with(date, date, relevant)(§15.4.1),
GetDateTimeFormatreturns null for a lone time field underinherit = relevant(§15.6.1),and
HandleDateTimeTemporalDatethen throws aTypeError(§15.6.15). Chromium 153 and the polyfill boththrow for every listed row, so
""is the correct sentinel and the JSDoc is right. The~any~rules belongto
new Intl.DateTimeFormat(…).format(plainDate), which is whatformatDateToPartsuses. No change.A polyfill defect, found by closing a coverage gap (D11). The review noted that
intervalLength*in calendar units had only ever been compared against the sameuntil/totalprimitives the implementation calls. An oracle built from
addand instant subtraction alonedisagreed, and Chromium 153 sided with the oracle. The cause is
tc39/proposal-temporal#3168, fixed
upstream by #3172 (
5dd0b0d97ee1, merged2025-11-19) and not ported by
@js-temporal/polyfillon 0.5.1 ormain: TC39 recomputes thenudge window one unit further along when the target falls outside it, and the polyfill computes it
once. It reaches three operations, all only from a
relativeTopast the 28th, where adding a monthconstrains the day:
Duration#totalDuration#rounduntil/sincewith a calendarsmallestUnitDuration.compareintervalLengthDateTime("2024-01-31T00:00:00", "2024-02-29T12:00:00", "month")was1.0172413793103448and is now1.0161290322580645; worse,normalizeDuration("P30DT12H", { smallestUnit: "month", roundingMode: "floor", relativeTo: "2024-01-30" })was
"PT0S"and is now"P1M"— a whole month. Fixed at five seams (monthTotalBySpec,monthRoundBySpec, thezonedUntilgate,plainUntilWithRounding, and a D11 term inplainDateUntil), all routed to thenudgeToCalendarUnitGMT already owns. Probe-gated, retiresby canary, written up as section H of the polyfill bug doc.
Nothing was filed, and nothing should be. The port into
@js-temporal/polyfillwas alreadywritten by the maintainer —
50d66d2in open PR#361 — so instead of a duplicate we
added the evidence that PR was missing: a reproducer, the Chromium-153 scan, and before/after
measurements of the commit applied to
main(comment).
50d66d2is not onmainand in no release, so every D11 workaround stays, and the removaltrigger is now two gates: the commit lands on
main, then ships in a release.A second, GMT-side defect found by the same scan. Rounding a span that lands exactly on a whole
month expanded it:
ceilonP60Dfrom2024-01-31gaveP3Mwhere Chromium givesP2M. TC39handles it inside
ApplyUnsignedRoundingMode("if x is equal to r1, return r1"); GMT's form takes acomparison rather than the value and could not see it. It was live for the non-ISO calendars before
this PR. Fixed, pinned in ISO and
hebrew, and it stays when D11 retires.Six exports threw on ToString-hostile input (the review found 3):
isLeapSecond,getNowUnit,getUtcNowUnit,getZonedNowUnit,getTimeZoneOffset,spanWallClock. Each guards the type and returns itssentinel; the no-throw gate's garbage set gains a throwing
toString, a null-prototype object and a symbol.locale: []followed the hostLANGin the three pattern parsers. An empty list is now the same as anomitted one (
"en-US"), pinned by a table that fails underLANG=fr_FR/ja_JPbefore the fix.nulloption members: 90 pairs across 62 exports (the review estimated 23). Temporal treats anullmember as present-and-invalid; GMT returned the default. Every site now reads the member with an explicit
undefinedcheck.optionsObject.test.tsgains a generic pin:{ m: null }must equal{ m: "zzbogus" }for every documented member, which covers the class.
startOfQuarterForDateTimekept its sub-second fields (the addendum's finding) — pre-existing, fixed hererather than deferred, and the new rows use fractional inputs so the gate can see it.
Every coverage gap closed with tests, not caveats. A brute-force oracle for
mergeIntervals*andintervalXorAll*over lists of three to eight (720 cases, all six families); reconstruction of differencerecords over deliberately gappy unit lists (312 cases, including through DST);
diff*rounding valuesacross all nine Temporal modes in both directions (1,368 cases, expected values from bigint longhand); the
RFC 9557 annotation grammar swept shape by shape across six parsers against a Chromium-sourced table (132);
and interval lengths against the longhand oracle that found D11. The
round*family now documents how manyfractional digits each unit prints.
maxPiecesstays offmergeIntervals*/intervalXorAll*deliberately:a boundary sweep emits at most as many spans as it was given, so there is no enumeration to bound.
Docs, changesets and gates: a third stale clock example (
formatRelativeTime),stripMdxbeing twodefects rather than one, and
diffUtccarrying the same wrongInstant.until()claim as thediffUnixpair.api-surface checkandupstream checkrun in CI'sconsistencyjob, and the skip budget is pinned(164 examples / 64 documented results), so a silent increase fails.
The text surfaces render the whole page, not the JSX. Following the review's wider
stripMdxnote, the.md,llms.txt,llms-full.txtand retrieval surfaces now render<Mistake>and<Scenario>to Markdown(73 cards that shipped as raw JSX), unwrap the layout components, and evaluate the splash pages'
{gmtStats…}expressions at build time from the same modulespnpm stats:syncwrites.llms-full.txtwentfrom 80 unevaluated expressions to 4, and those four are prose (
{yyyy},{MM},{dd},{RelativeUnit}).Stripping now leaves fenced code alone, so a sample keeps the
importline that names its function. Fourtests fail the build if any of it returns.
Decisions of record:
parseHttpkeeps rejecting a mismatched weekday in all three HTTP-date forms,asctimeincluded, and says so; thegregorian/ethiopic-amete-alemalias asymmetry stays as it is and isrecorded as a divergence.
15. No native
Dateanywhere, and the lint that forbids it now runsThe repo ships four lint plugins whose whole purpose is banning
Date, and none of them had ever linted this repo. Rootoxlint.config.jsfailed to load on five separate counts: oxlint auto-discovers only.oxlintrc.json,.oxlintrc.jsonc,oxlint.config.tsandoxlint.config.mts, so the filename was never read;defineConfig([...])returns an array where an object is required; the plugin was registered asplugins: [plugin]rather thanjsPlugins: [specifier];files: { include, ignore }is not a field,ignorePatternsis; and the two rule names were Biome's camelCase.packages/gmtandapps/doxeach run their ownoxlintfrom their own directory, where a root config never applies, so both now carry one — andpackages/gmtresolvedoxlint@^1.0.0to 1.59.0, which predates JS-config discovery, so it is pinned to^1.78.0. All three scopes now flag all fourDateAPIs, verified by linting a deliberate violation rather than by trusting a green exit.That left
date-ban.test.tsas the only live enforcement, and it did not scanapps/dox/worker— which is where all eight production calls had collected. It now scans the Worker,packages/gmt/src,.tsxand test files, and covers 1,705 files.The sweep exposed a real bug.
allowanceSpentpicked the soonest quota reset with a bare.sort(), which is chronological only becausetoISOStringis fixed width.nextMidnightMsreturnsnowMsunchanged when its zone lookup fails, so a stray subsecond can reach that list, and…T00:00:00.500Zsorts ahead of…T00:00:00Zbecause.precedesZ— putting the later instant first. It now usessortUtc, which compares instants.convertUnixToUtcemits2026-06-16T07:00:00ZwheretoISOStringemitted the same instant with a.000fraction, sovisitor.resetsAtand eachproviders[].resetsAtchange shape. Every client parses them through GMT, whoseutcDateTimegrammar makes the fraction optional, and no type, schema or doc commits to millisecond precision.Fixtures now say what they mean:
Date.UTC(2026, 5, 16)reads as May and means June. The 27 inapps/doxcallconvertUtcToUnixdirectly. GMT's own 11 go through aTemporalhelper, because a fixture built by the library cannot catch the library being wrong —setUnix.test.tsfeeds a converted instant in and compares against a converted instant out, so an hour of drift would cancel on both sides and still pass. OneDatecall remains in the repo: elapsed time against a file'smtimeMs.16. Review follow-ups, the plain-English skill, and CI
The three Questions from the review were answered in
44447b7but never said back to the reviewer; a follow-up comment now points at where each landed. Closing the one genuinely open half —mapDatesInRangeandmapZonedDatesInRangenever naming theinterval*half-open convention in their JSDoc — turned up another instance of a class the review had flagged: the migration bullet recommendedsubDate, which has never been exported. All 37 pending changesets were swept for names that resolve to nothing in the builtdist; that was the only real hit.A
plain-englishskill now carries ISO 24495-1 for every surface a person reads rather than runs — commit messages, changesets, PR text, review comments and upstream filings — wired into AGENTS.md as Core Rule 13 and into the four skills that emit that prose.A CI fix that matters for this PR.
Story consistencywas failing on seven broken site links to/guides/concepts/dst-disambiguation/. The page is generated, not committed:docs/dst-disambiguation.mdis the canonical source andbuild-guides.mjscopies it in. The job built@northguild/gmtbut never generated the dox content, so those pages did not exist on a fresh checkout and seven pages linking to them came back broken. Reproduced locally by deleting the generated files, then fixed by generating them before the check. All eight steps of that job now pass from a clean state.17. Second review response (baldurpan, 2026-09-23)
A second pass reproduced the D11 work against Chrome 153's native Temporal — 58,968 rows, 0 mismatches, where the raw polyfill gives 68 — then filed four findings. All four were real. Two were larger than reported, and closing the first exposed a third hole. The reviewer named the shape himself: an enumerated list standing in for a general rule, where what slipped through is what was not on the list.
Hostile input now returns the sentinel. 221 of the 551 exports threw when an argument resisted inspection: a revoked
Proxythrows onget,ownKeysandArray.isArray, and an object with a throwing getter throws when a rest-spread enumerates it. Those operations sat in the guards above each function'stry, so the guard written to reject invalid input raised instead. Every affected export now evaluates its body inside thetrywhosecatchalready returned its sentinel. Three corrections to the report: it is 221 of 551, not 556; the revoked Proxy carries all of it (the throwing getter accounts for 4, all already in that set); and while "options destructured outside the try" explains those 4 and ~126 options-slot cases, roughly 95 fail at non-options positions in functions that take no options at all, dying inArray.isArrayand string coercion.GARBAGEnow also carries a proxy that throws on every trap — 153/551 on its own, and hostile to any access rather than to one named operation.The
/upstream/defect table reached no text surface. A raw<UpstreamDefects />shipped intodist/upstream.md,llms-full.txtand the retrieval chunks, so all seven upstream chunks carried zero defect rows while the HTML carried eleven — and the prose around it spoke of "each row" and "the middle column" over nothing. The gate that should have caught it matched nine component names: exactly the ninerenderMdxComponentshandles, so it mirrored the handler list rather than checking it. It now matches any capitalised tag, excluding TypeScript generics, across the same three surfaces its sibling scans. That general form found eight more unhandled components, includingWhyDateBug— the home page's own case againstDate, whose faults table had never reached the text surfaces either. A second tally was missing too: the "we have sent 11 reports and fixes" sentence moved into a component last round to escape the{expr}problem, which put it out of reach entirely.upstream.mdis 8,357 bytes against 5,368.The vendored carve-out's premise was false. Four unmarked
Datecalls lived underai-elements/, one a calendar value formatted into a user-visible filename on the site that arguesDateis the wrong tool. The exemption called that tree "vendored, unmodified". All 15 oxlint pragmas naming this repo's own plugins were present in the vendoring commit itself,prompt-input.tsxwas edited again afterwards with aLOCAL MODIFICATION (GMT)marker, and the directory's own README says "we own and re-theme every component here". The tree is now linted forDatewhile staying exempt from the style rules, the stopwatch takes a monotonic clock, and a test pins the three carve-out lists against each other.ui/**stays exempt — 18 files, no pragmas, noDate.A D11 seam that corrected nothing is gone.
plainDateUntilrouted ISO date differences through the nudge-window workaround whenever the start day was past the 28th. The defect cannot reach there: the window only misses its target when the target sits strictly between its bounds by a sub-day amount, and twoPlainDates have no time component. Measured over ~1.96M rows against the raw polyfill, both directions, every rounding mode and increment 1–12: zero divergence. Removing it costs no answer and withdraws GMT's own exact-boundary behaviour from ISO date differences. The changeset and the bug doc no longer claim adiffDatefix that was never scanned.And the gates behind all of this had never run in CI. All three text-surface checks early-return when
apps/dox/distis absent, and the Tests job builds only@northguild/gmt— the site is built in a different job, on a different runner. A skip reports as a pass, which is how the raw tag shipped green, and the generalised gate would have rotted the same way.Story consistencynow builds the site and runs those checks, and outside a local run a missingdistfails loudly rather than passing silently.18. Discord
A Discord link sits beside GitHub in the site header, generated from Starlight's
socialconfig like its neighbour, plus thediscordglyph in the localIcon.astro(which carries only 22 of Starlight's icons, so the config entry alone would have rendered an empty<svg>). Also in both READMEs —packages/gmt/README.mdships in the npm tarball, so it is user-facing there.Why
Validation
daebdde, all 38 jobs passing, includingStory consistency, which had been failing on seven broken site links to a page that is generated rather than committed.pnpm run validate(all steps): passed on the final tree:deps check✅,test-markers check✅, build ✅,stats check✅api-surface check✅ (2,797 of 2,961 examples and 554 of 618 documented results run, 0 failing),upstream check✅ (12 filings),compat snapshot --check✅ (14 groups, 13 still needed)astro check)@northguild/gmt: 36,348 tests ✅ (27,334 at the start of the story)apps/dox: 4,283 tests ✅gmt-oxlint: 97 tests ✅pnpm compat✅: 14 workaround groups;zoned.Estill needed (5 of 5 probes), the newD11still needed (6 of 6),D10removable on 0.5.1 (pinned against regression)pnpm compat:oracle✅: 409,552 comparisons against Chromium 153 native Temporal, 0 mismatches, including after phase 2npx fallow auditclears every finding this branch introduced except eleven tool artefacts, recorded here rather than suppressed. Every function over 60 lines is split — includingrunTwin(271 lines) into one function per scan — the clone group is gone, and two unused devDependencies are removed. The eleven that remain: nine are CRAP-only, and with no coverage data CRAP is cyclomatic² + cyclomatic, so clearing them means cyclomatic ≤ 4 in every function of a CLI script — the trap.fallowrc.jsoncalready documents forapi-surface.mjs; two are fallow not resolving Astro'scustomCss, which it demonstrates by also flagginggmt-tokens.css, the file defining every token on the site. NothresholdOverrideswere added for any of it.runTwinwas verified, not assumed. It is untested comparison code, so the refactor was checked by capturing an oracle baseline from the committed version and re-running after: 409,552 comparisons against Chromium 153 across every calendar, 0 mismatches, identical.compat checkoutput diffs byte-for-byte againstHEAD./upstream/leads with what GMT works around and whether it still has to, generated bypnpm compat:snapshotfrom the same probespnpm compatruns and gated byvalidate. The filings table follows as "what we sent, and what happened to it", where a closed row carries the maintainer's own reason —upstream checknow fails on a closed-unmerged filing with no explanation. The page asserts no upstream pipeline stage: commit presence proved unreliable (tc39 squash-merges, so a fix's original sha reports as absent frommainwhile its code is there), so it carries only what regenerates itself.UpstreamTracker.astro,upstream.mjsandtemporal-compat.mjsformatted and compared timestamps withnew Date; they now usegetUtcNow,parseDateFromUtc,isValidUtcandisValidDate. The remainingDate.now()calls are elapsed-time budgets, nowperformance.now()where a monotonic clock is the correct primitive.pnpm upstream:synchad never worked past the first repository (REPOS.flatMap(discover)passes the array index asdiscover'stimeout);buildFilingsilently dropped hand-written fields it did not name, and a dropped "whose PR is this" flag reads as ours; a merged filing broke the state enum, which no filing of ours had ever exercised until #361; the site usednew Date;apps/doxhad notestTimeout, so import-bound tests at ~3.9 s failed against Vitest's 5 s default wheneverpnpm -r run testshared a CPU withpackages/gmt's 36k tests (now 20 s, and this would have failed CI on a slower runner); and two devDependencies were declared that nothing imports —@fontsource/michroma(its one.woff2has been committed since DOX-A3: JSDoc-driven MDX reference generator and site shell (132) #161) and@open-wc/testing. Removing them pruned 1,404 lines of transitive lockfile entries. The lockfile is regenerated with them, becausepnpm install --frozen-lockfileruns in five CI jobs and fails on a manifest/lockfile mismatch.display: blockon content tables so wide ones scroll; a block box is not a table box, sotable-layout: fixedandwidth: 100%never reached the columns, and withgmt-content.csssettingwhite-space: nowrapon every first cell, column one grew to 862px inside a 612px page. Fixing it from a scoped<style>is impossible: Astro compiles scoped styles to:where(.astro-hash), which carries no specificity, so a component rule can never outrank a site rule. The styles now live insrc/styles/gmt-upstream.css.apps/dox/tsconfig.jsonsetsjsx: react-jsxfor its React islands, which disables Astro'sPropsinference, soAstro.propsisRecord<string, any>in every.astrofile in the app. The new components assert theirProps; changing the compiler option site-wide is its own piece of work.pnpm install --frozen-lockfileverified after the dependency removals, so the five CI jobs that use it will install cleanly.scratchpad/is now gitignored. It held four stalevalidate-*.logfiles (~400 KB of build output, one of them a truncated run) and was untracked but not ignored, sogit add -Awould have committed them.@northguild/gmt@1.15.0, and every "after" value against this branch.Risk / Impact
High (intentional). 1.16.0 carries breaking changes for any caller that:
nulloptions tounix/functions;diff*unit arrays.Every breaking change is listed with old → new calls in its changeset's Breaking changes section. Stored calendar strings must be regenerated from their ISO dates, not parsed. All known users are internal. The native-Temporal oracle shows no drift.
Release
minorfor@northguild/gmt, rolling into 1.16.0 with the other pending changesets.patchfor@northguild/gmt-oxlint,@northguild/gmt-eslintand@northguild/gmt-biome. Merging publishes nothing.Breaking (minor) changesets:
half-open-positional-intervals.mdrfc9557-calendar-strings.mdunix-unified.mdoptions-follow-temporal.mddiff-records-and-parsing.mdstring-grammars-follow-temporal.mdpackage-exports-and-engines.mdsteady-zones-floor.mdunix-validation-and-rounding-options.mdAdditive (minor):
piece-limits.md(maxPieces) andunix-parse-exports-week-rule.md.Patch:
boundary-and-parts-defaults.md,documented-examples-execute.md,invalid-input-never-throws.mdinternet-date-grammars.md,leap-seconds-zone-names-calendar-ids.md,zoned-arithmetic-across-dst.mdintl-formatting-follows-temporal.md,range-edges-and-exact-results.md,roll-convention-provenance.mdlint-messages-name-real-functions.md(the three lint plugins)date-line-crossings-1844.md(thezoned.Efix)Checklist