Repository navigation
Commit ceee88f
Part of #20822
Clause-②: no (narrowing)
#5930 step 4, **group 2**: `driver-sql` F1, `driver-turso` remote F2,
and the `plugin-security` `rlsLowering` absent-guard twin (the seat's
answer 5918373748, A). Ruled by 5902355785 (D4 (b)) and ADR-0053 D-D1
items 5, 7 and 9 as amended. The order follows group 1b's pattern: make
the seam type-blind first, then delete. Seven commits on `main` at
`5f6b63a6fd`:
| # | Commit | What it does |
|:--|:--|:--|
| 1 | `e20e17e929` fix(plugin-security) | `rlsLowering` hands the
lowering no reader when the guard carries no `datetime` set (no guard,
or a guard built without types). The RLS compile seam is now type-blind
there (item 7). The typed branch is byte-identical. The pin "a guard
with no types reads no column as datetime" is rewritten to the new
reading. A new pin file covers the no-guard compile for both clauses,
and a `using` policy through `SecurityPlugin.getReadFilter` handed to
`SqlDriver.find`. |
| 2 | `a9b1f79282` refactor(driver-sql, driver-turso) | Deletes the
whole-day copies. F1: `calendarDayExclusiveUpperBound`,
`calendarDayUpperBoundRewrite` and `calendarDayBetweenRewrite`, plus
their two call blocks in the emitter. F2: `toRemoteFilter`'s whole-day
arms (`toRemoteUpperBound` and the `$lte` / `$between`-max rewrites).
The direct-call temporal suites are routed through
`lowerFilterCondition` with each fixture's declared-datetime reader. New
item-5 pins on both drivers. |
| 3 | `d5277f98e6` refactor(driver-sql, driver-turso) | Deletes the
NULL-safe `$not` copies: F1 `nullSafeNegationOperand` and its three
polarity tables, and F2 `RemoteTransport`'s copy of the same. The `$not`
direct-call suites are routed, including two `service-analytics`
`find()` faces that stand for the engine. Refusal pins stay direct
calls. New pins on both drivers. |
| 4 | `4658e72939` docs(changeset) |
`.changeset/20822-driver-sql-turso-copies.md`, first draft. |
| 5 | `6ec47a8770` docs(changeset, spec) | Patch round (the seat's
answers 5922273550 and 5922490848): `driver-sql` `minor`, `Clause-②: no
(narrowing)`, a BREAKING paragraph with a FROM → TO line, both step-2
sentences superseded, and `@objectstack/spec` `patch` for the ledger
entry `18.driver-sql-calendar-day-methods-removed.ts` with the
regenerated `registry.ts`. The other three packages stay `patch`. |
| 6 | `d8b8f9095a` fix(spec) | The ledger entry's printed reason states
the decision in words instead of citing tracker ids. CI's
`migrate-meta-engine-guidance` test was red on commit 5 for this. |
| 7 | `0e8378cf54` docs(objectql) |
`content/docs/protocol/objectql/query-syntax.mdx` states the whole-day
rule as the shared lowering's (the engine's `where` seam and the RLS
compile seam), and a direct call to `SqlDriver` or a driver built on it
as compared as written (contract review 5923464846, FAIL 1). |
49 files, +1501 / -977 against `5f6b63a6fd` at `0e8378cf54`, under the
5000-line human-merge threshold. No governed path.
## The answers that move, named
All rows were measured on SQLite (better-sqlite3 `:memory:`, and the
libsql stub for Turso remote).
| Path | Filter | Before | After | Ruled by |
|:--|:--|:--|:--|:--|
| Any seamed read: engine `where` positions, `aggregations[i].filter`,
RLS compile seam with a typed guard | any | — | **no move** (ablations
below) | item 9 |
| RLS `using` / `check` compiled with **no guard**, or with a guard
without a `datetime` set | `record.signed_on` before-or-on
`'2026-01-05'` | `{ signed_on: { $lte: '2026-01-05' } }`, as written |
`{ signed_on: { $lt: '2026-01-06' } }`; SQLite keeps every row of the
day (pin §B); `InMemoryDriver` keeps the whole day too | item 7 (seat
answer A) |
| Direct `SqlDriver` / `SqliteWasmDriver` / `TursoDriver` call (both
faces), `datetime` column | `$lte` a bare day | the whole day | that
day's midnight, as written | item 5 |
| same | `$between` with a bare-day max | the whole max day | inclusive
at both ends, as written | item 5 |
| same | `$lte '9999-12-31'` | every row with a value | that midnight,
as written | item 5 |
| Direct call, both faces | `$not` over `=`, an ordering operator,
`$in`, `$contains`, a `$or` | a row with a NULL column was returned
(#5146) | SQL's three-valued `NOT`: that row is not returned | item 5 |
| same | `$not` over `$ne` / `$nin` / `$notContains`, and `$ne` / `$nin`
/ `$notContains` without a `$not` | NULL-safe | **unchanged**: each
emitter spells these NULL-safe itself (`applyNullSafeNegative` /
`nullSafeNegative`, #5298); they are not copies of the `$not` rewrite |
— |
| Direct `RemoteTransport` call with an **author**-marked filter | a
refusal raised inside a `$not` operand (for example `$or: [null]`) |
withheld even for the author, because the rewrite's nodes carried no
provenance mark | resolves against the author's own mark and names the
branch, as it does outside a `$not` | #8220 contract (a refusal message,
not an answer) |
Nothing moved beyond item 5 or item 7, so no site stopped on that
clause.
## Two stops, measured (H3, and the `$between` split)
- **`assertDefinedComparands` is kept in both faces.**
- *Seamed positions:* the engine's comparand door refuses an `undefined`
comparand on `find`, `findOne`, `count`, `update`, `delete`,
`aggregations[i].filter`, `having` and `$not` positions
(`engine-comparand-type-door.test.ts`,
`engine-aggregate-filter.test.ts`,
`engine-aggregate-having-comparand-shape.test.ts`, all green). The RLS
compile seam refuses through `normalizeFilterComparandTypes` in
`judgeCompiledComparands`.
- *F1, a direct caller after deletion* (both call sites disabled,
`sql-driver-undefined-comparand-refusal.test.ts`, 22 positions):
- 5 positions move from `INVALID_FILTER` / 400 to **an answer**:
`$contains`, `$notContains`, `$startsWith` and `$endsWith` with
`undefined`, and `undefined` beside the TRUE identity `{}`. The LIKE
family binds `String(undefined)`.
- The other 17 move to a bare `DATABASE_ERROR`.
- That is H3's stop. F1's copy is kept.
- *F2:* with its pre-walk removed, all 19 positions still refuse with
`INVALID_FILTER` / 400, through `serializeComparand`'s
unbindable-comparand refusal. No answer moved. But
`turso-local-remote-null-parity.test.ts`, which the dispatch names as a
suite to keep green, holds both faces to driver-sql's one sentence
(#6050, #5240): 13 parity cases (the #6050 block), 14 refusal-seam rows
(13 `undefinedComparand` rows plus the closed-class enumeration) and 20
`undefined`-refusal pins went red. F2's copy is kept with F1's. Its
comment now says why.
- **`toRemoteFilter` keeps its structural `$between` split.** The remote
transport has no `$between` arm, and it refuses an unsplit range. The
typed lowering leaves a `$between` on a non-`datetime` column whole. So
removing the split moves seamed answers from rows to a refusal. Measured
by ablation (S1): 6 red. They are the numeric `$between` control, two
`Field.time` `$between` conformance cells, `$not` over a numeric
`$between`, and the two `$between` item-5 cells. Only the whole-day half
of those arms is deleted.
## Hypotheses
- **H1 (sites): held**, at `75519e1c0a`, the first base. `sql-driver.ts`
is unchanged by the rebase onto `5f6b63a6fd`.
- F1:
- the quartet is lines 5054 to 5298: `NullGuard` 5064,
`nullValueSatisfiesOperator` 5077, `operatorIsNullTotal` 5141,
`nullGuardForFieldSpec` 5180, `nullSafeNegationOperand` 5265;
- it is called from the `$not` branch at 16943;
- `assertDefinedComparands` is at 4707, called at 4929 and 16588;
- `calendarDayExclusiveUpperBound` is at 15476,
`calendarDayUpperBoundRewrite` at 15498 and `calendarDayBetweenRewrite`
at 15521, called at 17036 and 17053.
- F2:
- `toRemoteFilter` is at 2567 (the dispatch said about 2566);
- the `$between` arm is at 2610 and the `$lte` arm at 2638;
- `toRemoteUpperBound` is at 2685, and it calls
`calendarDayUpperBoundRewrite` at 2691;
- `remote-transport.ts` has its quartet at 379 to 614, called at 3116,
and `assertDefinedComparands` at 4364, called at 2961.
- **H2 (deleting moves no seamed answer): held for every deleted copy.**
The ablations restored each copy on the committed head. Every routed
suite stayed green with the copy back, and only the new direct-call pins
turned red. The `$between` split is the exception above: it is
structural, not a copy.
- **H3: held as a stop for both faces.** See above.
- **H4 (direct callers): no caller to route.** Grep over production
`src` (`driver.find` / `count` / `aggregate` / `updateMany` /
`deleteMany` / `distinct`, `getDriverForObject`, `_find` / `_count`):
- `metadata` `DatabaseLoader` in driver mode builds equality filters
only (`baseFilter`, `nextEventSeq`). `queryHistory` is already lowered
(group 1b), and its §A pin stays green on SQLite with F1 gone.
- `metadata` `history-cleanup` uses `recorded_at $lt` an instant, and
`type $nin`.
- `objectql` `LifecycleService`'s archive pass uses `hot.find` /
`cold.deleteMany`, through `getDriverForObject` / `datasource`. Its
filters are `$lt` an ISO instant, an `organization_id` equality, and
`$or: [organization_id $nin, organization_id null]`.
- The CLI's `secret-reference-union` / `secret orphans` use `{ type:
'datasource' }` or no `where`.
- `metadata-protocol`'s migrations run raw SQL.
- None of these builds a bare-day `$lte`, a `$between`, a `$not` or an
`undefined` comparand. `$lt` an instant is never widened. `$nin` outside
a `$not` keeps the emitter's own NULL-safe form.
- **H5 (the RLS twin): held.** `rlsLowering(undefined)` and a guard
without `datetime` both return `{}`. The existing pin flipped as
predicted. The new pin goes through a `using` policy: SQLite keeps the
whole day. The memory half is the filter shape (driver-agnostic) plus
`driver-memory`'s own §C pin of a type-blind lowered filter. A
plugin-security test that imports `@objectstack/driver-memory` is an
arrival outside the driver-memory census ledger.
- **H6: NOT MEASURED here.** A live PostgreSQL / MySQL matrix and a live
remote Turso server were not measured. The live matrix is `Temporal
Conformance (live PG + MySQL)` in CI. Remote Turso was measured against
the libsql stub only.
## For the review
- **`packages/spec` is touched for the ledger only:** one semantic entry
in `src/migrations/entries/semantic/` and the regenerated `registry.ts`.
`spec-changes` and the upgrade guide stay byte-identical, because the
generators stop at protocol 17. It is a declared cross-lane surface (the
seat's answer 5922490848).
- **`SqlDriver`'s published class surface shrinks.**
`calendarDayExclusiveUpperBound`, `calendarDayUpperBoundRewrite` and
`calendarDayBetweenRewrite` were `protected` members of the exported
class, so they are declared in `dist/index.d.ts`. Measured against the
published `.d.ts` (tsc 6.0.3): a call gets TS2339, and an `override`
re-declaration gets TS4113. A plain re-declaration still compiles, but
the driver never calls it. The replacement is `lowerFilterCondition`
from `@objectstack/spec/data`. The changeset carries it as BREAKING
(`minor`), with the ADR-0087 ledger entry
`driver-sql-calendar-day-methods-removed`.
- In-repo, `TursoDriver` was the one caller, and it is updated. The test
probe subclass is rewritten.
- `objectui` / `cloud` at their pins: NOT MEASURED (no sibling checkout
in this container).
- The changeset states the removal.
- **One sentence of this release's step-2 changeset is superseded.**
`.changeset/5930-shared-filter-lowering.md` says "A guard without that
set treats no column as `datetime`" and "Each driver keeps its own copy
of these rules". The new changeset has a Supersedes paragraph naming
both sentences. The step-2 file is not edited here, because the
foreign-changeset rule in `check-empty-changeset` (#17712) forbids it.
- **Expected values changed in three places; all other edits wrap
arguments.**
1. The H5 flip in `rls-shared-lowering-seam.test.ts`.
2. The `$not` refusal-provenance flip in
`remote-transport-not-operator.test.ts` (e).
3. `sql-driver-calendar-day-upper-bound.test.ts`'s probe matrix. It
called the deleted methods. It now pins the lowered bound's physical
form per dialect, with the same values as before:
`2026-07-29T00:00:00.000Z`, and `2026-07-29 00:00:00.000` on MySQL. The
calendar arithmetic and the scope rows are the lowering's (`spec`'s
`filter-lowering.test.ts`).
Every other changed `expect(` line wraps its filter in `seamed(...)`,
and its expected value is unchanged.
## Verification at head `4658e72939` (driver code; unchanged since. The
patch round's gates at `d8b8f9095a`: 94 derived, 94 run, every one exit
0, under a stale-tree warning for 5 files `main` changed outside this
diff)
**Suites**, each with `vitest run --maxWorkers=2`. Package baselines are
from `75519e1c0a`.
| Package | Files | Tests | Baseline |
|:--|:--|:--|:--|
| `driver-sql` | 203 passed, 11 skipped | 3281 passed, 188 skipped |
3266 passed / 188 skipped |
| `driver-turso` | 81 | 2210 passed, 33 skipped | 2195 / 33 |
| `driver-sqlite-wasm` | 36 | 675 | 675 |
| `plugin-security` | 151 | 3272 passed, 23 skipped | 3227 / 23 |
| `service-analytics` | 148 | 3425 | — |
| `metadata` | 56 | 836 | — |
| `objectql`, `--project local` | 348 | 6821 | — |
| `objectql`, `--project repo` | 1 | 5 | — |
| `rest` | 249 | 4964 passed, 114 skipped | — |
The typechecks for `driver-sql`, `driver-turso`, `driver-sqlite-wasm`,
`plugin-security` (including `check:test-typecheck`) and
`service-analytics` all exit 0. `driver-sql`'s tsc program lists all 214
of its test files.
**Ablations.** Each restores the deleted copy on the committed head
through `scripts/ablation-replace.mjs`. Each is restored with blob equal
to HEAD and `git diff HEAD` empty.
| # | Restored | Red (expected direction) | Everything else |
|:--|:--|:--|:--|
| A1 | F1 whole-day | 8 of 3281: exactly the 8 §A cells (4 canonical, 4
legacy-normalised) | green |
| A2 | F1 `$not` rewrite | 6: the 4 §B direct cells, plus 2 SQL-text
pins that compile the lowered operand. The restored copy guards it a
second time: diagnostics grow, same rows. | green, including every
row-result suite |
| A3 | F1 + F2 whole-day | 8: the turso §A cells, 4 per face | green |
| A4 | F2 transport `$not` rewrite | 17: the 4 §B remote cells, 12
transport SQL-text pins (the double guard again), and the (e) provenance
pin (the rewrite's new nodes withhold again) | green, including
filter-logic remote and local/remote NULL parity |
| A5 | the RLS twin reverted | 8: 4 §A compile cells, both §B cells (the
SQLite rows fall to midnight-only), and the 2 flipped seam pins | green
|
| S1 | the `$between` split removed | the 6 cells named above | green |
A3 rebuilt `driver-sql`, and `ablation-dist-preflight` showed the marker
present in `dist/`. The restore leg rebuilt it again, and `--absent`
showed the marker gone from all 6 built files with the tree clean.
**Gates.**
- `node scripts/pm/dispatch-gates.mjs --commands` derives 67 families:
46 paths against merge base `5f6b63a6f`, with no stale-tree warning
after the rebase.
- All 67 were run, and every one exits 0. That includes
`check:driver-conformance` (OK, 50 covered cells, 0 DEBT),
`check:driver-memory-census`, `check:engine-double-contract`,
`check:query-options-erasure`, `check:nul-bytes`,
`check:dual-build-cjs-loads` and `check:i18n`. The last two first exited
3 (`PREREQUISITE NOT MET`) and were rerun after a full workspace build
(72 tasks).
- `dispatch-gates --ran`: 67 derived, 67 run, 0 NOT-MEASURED, 0 UNRUN.
**Lint (narrowed).**
- `eslint --no-inline-config --format json` over the 45 changed `.ts`
files: 45 files, 0 errors, 0 warnings.
- Every file resolves under `--print-config`.
- `eslint.config.mjs` never enables type-aware linting (no
`parserOptions.project`), so no untouched file's verdict can move.
- The full `pnpm lint` is CI's.
## Acceptance notes
- **Stale pointers outside this file surface,** for the last group PR,
which per landing record 5920439482 corrects the stale pointers outside
`driver-memory`:
- `objectql` `having-filter.ts` around line 1365, and `spec`
`filter.zod.ts` around lines 434, 734 and 750, still name
`calendarDayUpperBoundRewrite` / `calendarDayBetweenRewrite`.
- `service-analytics` `read-scope-shared-lowering-seam.test.ts` has a
case titled "RLS using, as written (a guard without types)". Its rows
still hold, but the RLS seam no longer emits that shape.
- **One copy is left in F1 on purpose: the `undefined` refusal.** The
seat answered A (5922273550): it stays in both faces as a door, not a
copy of the lowering's meaning, because without it 5 of F1's 22
direct-call positions move from 400 to an answer.
- `applyNullSafeNegative` (F1) and `nullSafeNegative` (F2) are not in
the design's census quartet. They are the emitters' own NULL-safe
spelling of `$ne` / `$nin` / `$notContains`, and they stay.
---
_Generated by [Claude
Code](https://claude.ai/code/session_01DEvba2nBuD4tWzfq8r8NFY)_
---------
Co-authored-by: Claude <noreply@anthropic.com>
1 parent b8191f7 commit ceee88f
49 files changed
Lines changed: 1501 additions & 977 deletions
File tree
- .changeset
- content/docs/protocol/objectql
- packages
- drivers
- driver-sqlite-wasm/src
- driver-sql/src
- driver-turso/src
- plugins/plugin-security/src
- services/service-analytics/src/__tests__
- spec/src/migrations
- entries/semantic
Some content is hidden
Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
568 | 568 | | |
569 | 569 | | |
570 | 570 | | |
571 | | - | |
572 | | - | |
573 | | - | |
574 | | - | |
| 571 | + | |
| 572 | + | |
| 573 | + | |
| 574 | + | |
| 575 | + | |
| 576 | + | |
| 577 | + | |
| 578 | + | |
| 579 | + | |
| 580 | + | |
| 581 | + | |
575 | 582 | | |
576 | 583 | | |
577 | 584 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
56 | 56 | | |
57 | 57 | | |
58 | 58 | | |
59 | | - | |
| 59 | + | |
60 | 60 | | |
61 | 61 | | |
62 | 62 | | |
63 | 63 | | |
64 | 64 | | |
65 | 65 | | |
66 | 66 | | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
67 | 77 | | |
68 | 78 | | |
69 | 79 | | |
| |||
263 | 273 | | |
264 | 274 | | |
265 | 275 | | |
266 | | - | |
| 276 | + | |
267 | 277 | | |
268 | 278 | | |
269 | | - | |
| 279 | + | |
270 | 280 | | |
271 | 281 | | |
272 | 282 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
85 | 85 | | |
86 | 86 | | |
87 | 87 | | |
88 | | - | |
| 88 | + | |
89 | 89 | | |
90 | 90 | | |
91 | 91 | | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
92 | 106 | | |
93 | 107 | | |
94 | 108 | | |
| |||
158 | 172 | | |
159 | 173 | | |
160 | 174 | | |
161 | | - | |
| 175 | + | |
| 176 | + | |
| 177 | + | |
162 | 178 | | |
163 | 179 | | |
164 | 180 | | |
| |||
207 | 223 | | |
208 | 224 | | |
209 | 225 | | |
210 | | - | |
| 226 | + | |
211 | 227 | | |
212 | 228 | | |
213 | 229 | | |
| |||
317 | 333 | | |
318 | 334 | | |
319 | 335 | | |
320 | | - | |
| 336 | + | |
321 | 337 | | |
322 | 338 | | |
323 | 339 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
35 | 35 | | |
36 | 36 | | |
37 | 37 | | |
38 | | - | |
| 38 | + | |
39 | 39 | | |
40 | 40 | | |
41 | 41 | | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
42 | 53 | | |
43 | 54 | | |
44 | 55 | | |
| |||
151 | 162 | | |
152 | 163 | | |
153 | 164 | | |
154 | | - | |
| 165 | + | |
155 | 166 | | |
156 | 167 | | |
157 | 168 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
32 | 32 | | |
33 | 33 | | |
34 | 34 | | |
35 | | - | |
| 35 | + | |
36 | 36 | | |
37 | 37 | | |
38 | 38 | | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
39 | 50 | | |
40 | 51 | | |
41 | 52 | | |
| |||
197 | 208 | | |
198 | 209 | | |
199 | 210 | | |
200 | | - | |
| 211 | + | |
201 | 212 | | |
202 | 213 | | |
203 | 214 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
29 | 29 | | |
30 | 30 | | |
31 | 31 | | |
32 | | - | |
| 32 | + | |
33 | 33 | | |
34 | 34 | | |
35 | 35 | | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
36 | 47 | | |
37 | 48 | | |
38 | 49 | | |
| |||
168 | 179 | | |
169 | 180 | | |
170 | 181 | | |
171 | | - | |
| 182 | + | |
172 | 183 | | |
173 | 184 | | |
174 | 185 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
36 | 36 | | |
37 | 37 | | |
38 | 38 | | |
39 | | - | |
| 39 | + | |
40 | 40 | | |
41 | 41 | | |
42 | 42 | | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
43 | 54 | | |
44 | 55 | | |
45 | 56 | | |
| |||
120 | 131 | | |
121 | 132 | | |
122 | 133 | | |
123 | | - | |
| 134 | + | |
124 | 135 | | |
125 | 136 | | |
126 | 137 | | |
| |||
0 commit comments