Repository navigation
Commit d6a5fa3
fix(driver-sql): a SQLite database whose header SQLite cannot read, and a dangling-link directory on the boot that writes, fail connect() naming the file (#25080)
Part of #25019
The card keyword above is the seat's: member 3 (the wasm quarantine)
stays on #25019 under the seat's ruling 6311031589 (route A, inherited
from #24960), dispatched on the card after this PR lands, so this merge
does not close the card.
Clause-②: no (narrowing)
**Narrowing face:** three answers that read success now refuse, each
naming the file. `SqlDriver.connect()` rejects a SQLite database whose
header or schema SQLite cannot read (`SQLITE_CORRUPT` at the first
statement), and a path whose directory is a dangling symbolic link
(`ENOENT`), where both used to resolve. The read-only boot
(`sqliteAbsentFile: 'empty-in-memory'`) rejects a dangling symbolic link
as the file itself when the directory its chain of links ends in does
not exist, where it opened an empty in-memory database and read
`connected`. Nothing exported changes shape. It owes a
`CONTRACT_REVIEW_TIER` review before the queue (the claim's line).
Dev session `session_01QK6pdbxKZiHdFApL8RYVh9` (a `mode:subagent` run),
dispatched by the `domain:engine` seat 2 under claim 6307297304. This is
the SQLite file-failure family's closing card. It builds on PR #25006
(`SQLITE_NOTADB`) and PR #25007 (the read-only boot's unopenable path),
both on `main`.
## What changed
- **Member 1, `SQLITE_CORRUPT`.**
`packages/drivers/driver-sql/src/sql-driver.ts`, only the
`applyAutoVacuumIncremental` comment and `SQLITE_FILE_REFUSALS`: one
more row, `SQLITE_CORRUPT` with the words "is damaged (SQLite cannot
read its header or its schema), and was left as it is".
`packages/services/service-datasource/src/sqlite-driver-fallback.ts`:
`isSqliteFileOpenFailure` adds the same code, with its doc list and the
module note (the cross-lane line declared to `domain:services` on the
claim).
- **Member 2, a dangling-link directory on the boot that writes.**
`packages/drivers/driver-sql/src/sqlite-database-file.ts`,
`makeDatabaseDirectory`: the walk now asks the read-only twin's own
`isDanglingLink` at each level `stat` answers `ENOENT` for, and refuses
that level with `stat`'s error as `code` and the link named. Before, the
level went on the "missing" list, `mkdir` answered `EEXIST`, and the
creating loop accepted that as a concurrent creator. Both twins now
print the link through one helper (`danglingLinkWords`), so their words
cannot drift. `ensureDatabaseExists` in `sql-driver.ts` is untouched: it
wraps what the walk throws, as it already did.
- **The dangling link as the file itself (family note 6305577138):
pinned, not left out.** Measured below: the read-only boot read it
absent when the directory the link points into does not exist, while the
writing boot refuses it with `SQLITE_CANTOPEN`.
`probeAbsentSqliteDatabaseFile` now follows a dangling link that is the
file to the end of its chain (`danglingLinkEnd`, reading each relative
target from the real directory of the link that holds it, as the kernel
does) and judges that directory without making it: it must exist, and
allow write and search. Otherwise `'absent'`, as before.
- **Member 3, the wasm quarantine: measured, not changed.** Closing it
means changing what `driver-sqlite-wasm`'s quarantine does, so it is the
card's fork, reported to the seat with the four-axis analysis. No line
of `packages/drivers/driver-sqlite-wasm` changed.
- Changeset `.changeset/25019-sqlite-file-failure-family.md`:
`@objectstack/driver-sql` and `@objectstack/service-datasource` `minor`,
with the `Clause-②` line, the BREAKING banner (Before, Now, Fix) and the
ADR-0087 disposition `not-required (no-migration-prescription)`, as PR
#25006's changeset does.
- Pin files:
`packages/drivers/driver-sql/src/sql-driver-25019-sqlite-damaged-file-and-dangling-link.test.ts`
(relative `src` import) and
`packages/services/service-datasource/src/__tests__/sqlite-driver-fallback-damaged-file-and-dangling-link.test.ts`
(resolves `@objectstack/driver-sql` through `dist/`, an existing
`KNOWN_UNALIASED_TEST_IMPORTS` pair).
## Premise, measured on base `d68aab6fd` (better-sqlite3 13.0.3, SQLite
3.53.4, Node v22.22.0)
**H1 holds, and both shapes were measured.** Statement by statement,
through better-sqlite3 directly, on a database written and then damaged:
| shape | first statement (`PRAGMA auto_vacuum`) | `SELECT 1` |
`connect()` on base |
|---|---|---|---|
| truncated to 10 or 16 bytes (inside the magic string) |
`SQLITE_NOTADB` | `SQLITE_NOTADB` | refused (PR #25006) |
| truncated to 50, 99, 100, 101, 512 or 4095 bytes | `SQLITE_CORRUPT` |
`SQLITE_CORRUPT` | **resolved** |
| truncated to its first page, or to half its pages | `SQLITE_CORRUPT` |
`SQLITE_CORRUPT` | **resolved** |
| page 1's b-tree (the schema) overwritten past the header |
`SQLITE_CORRUPT` | `SQLITE_CORRUPT` | **resolved** |
| in-header page count larger than the file | `SQLITE_CORRUPT` |
`SQLITE_CORRUPT` | **resolved** |
| one table's page overwritten (damage deeper inside) | answers |
answers | resolved; only a read of that table answers `SQLITE_CORRUPT` |
So `SQLITE_CORRUPT` at the FIRST statement is a verdict on the whole
file: every statement answers the same code, `SELECT 1` included, and
nothing can be read. A database damaged deeper inside answers the first
statement and connects, and its damage surfaces on the read that reaches
it. The refusal is worded for the first kind ("SQLite cannot read its
header or its schema"), and a control pins the second (it still
connects). No extended code (`SQLITE_CORRUPT_*`) appeared at the first
statement. Nothing in the tree reads `SQLITE_CORRUPT` or "disk image is
malformed" outside `driver-sqlite-wasm` and two unrelated REST and
runtime fixtures.
**H2 holds.** On base, the writing boot over `link/archive.db` (a
dangling link) resolved `connect()`, then the first statement failed
with a code-less `TypeError` ("Cannot open database because the
directory does not exist"). Over `link/sub/archive.db` it already
refused (`ENOENT` from `mkdir`), without naming the link. The read-only
boot refused both naming the link. After the change, both boots answer
`SqliteDatabaseFileError`, `code: 'ENOENT'`, naming the file and the
link, at both depths. Their words differ by one verb ("could not be
made" on the writing boot, "cannot be made" on the read-only one), as
they already did for every other shape. A directory that is a link to an
existing directory still connects and creates the file in it.
**The dangling link as the file.** Base and after, both boots:
| file `archive.db` is a link to | writing boot (base and after) |
read-only boot, base | read-only boot, after |
|---|---|---|---|
| `target.db` in a directory that exists (absolute or relative target,
direct or through a second link) | connects; creates `target.db` |
absent, in memory | absent, in memory (unchanged) |
| `missing/target.db` (direct, or through a second link) | refused,
`SQLITE_CANTOPEN` | **absent, in memory, `connected`** | refused,
`ENOENT`, naming the target |
| itself, through a loop | refused, `SQLITE_CANTOPEN` | refused, `ELOOP`
| refused, `ELOOP` (unchanged) |
Nothing on disk changed in any read-only run.
**H3, member 3.** With the #24950 suite's load-failure seam
(`acquireRawConnection` answering a real `ERR_DLOPEN_FAILED`),
development `resolveSqliteDriver` over a plain-text file and over a
header-truncated database, after this change:
- the addon loads: both refused (`SQLITE_NOTADB`, `SQLITE_CORRUPT`), the
file untouched;
- the addon cannot load: both resolve to `sqlite-wasm`, and `data/`
holds `archive.db` (an empty database) and
`archive.db.corrupt-TIMESTAMP`;
- controls: a real database with the addon unable to load steps down to
wasm and reads its rows, not renamed; an absent file does the same.
The rename happens in `driver-sqlite-wasm`,
`WasmSqliteConnection.open()` (`wasm-connection.ts`), which calls
`quarantineCorruptFile` when `new SQL.Database(bytes)` or `PRAGMA
quick_check(1)` fails. The wasm driver takes no option that could say
"refuse"; `resolveSqliteDriver`'s wasm rung also catches every wasm
failure and goes on to the in-memory rung. A second door reaches the
same quarantine with no step-down at all: a datasource declared `driver:
'sqlite-wasm'` over a plain-text file, through
`DatasourceConnectionService.connectDeclared` on the built `dist/`, was
renamed and read `available` in development AND in production. Every
in-tree construction that reaches the quarantine is a declared
datasource: the `default` datasource is one since #3826 (the CLI and the
standalone stack hand it to `DefaultDatasourcePlugin`), so "the dev
server's own self-heal" and "a declared datasource" are one population.
The self-heal was written for torn images, which wasm's atomic flush
(`atomicWriteFile`, write then `rename`) has since closed. The fork and
its options are in the report to the seat.
## Evidence
**Public door, the card's own** (`bin/run-dev.js migrate apply --yes`
through `tsx`, a throwaway project whose `objectstack.config.ts`
declares `archive` (`driver: 'sqlite'`) and binds `door_note` to it),
after `turbo run build --filter='@objectstack/cli^...'` (60 of 60) on
the merge head `cc15060f7`:
- **Header-truncated `archive.db`** (a database this driver wrote, cut
to 50 bytes): `datasource 'archive': connect failed — SQLite database
file 'PROJECT/data/archive.db' is damaged (SQLite cannot read its header
or its schema), and was left as it is: PRAGMA auto_vacuum - database
disk image is malformed. (1 object(s) bind to it explicitly (door_note)
…)`, exit 1. The md5 is unchanged (`dc1e7bea…` before and after), and
`data/` holds `archive.db` alone. No step-down warning printed.
- **Dangling-link directory** (`data/link` pointing at a path that does
not exist): `connect failed — SQLite database file
'PROJECT/data/link/archive.db' cannot be created: its directory
'PROJECT/data/link' could not be made: 'PROJECT/data/link' is a symbolic
link to a path that does not exist: ENOENT …`, exit 1. No "native
better-sqlite3 unavailable" line, no wasm line; the link still dangles
and its target was not created.
- **Control, a real database:** `datasource 'archive': connected
(driver=sqlite, schemaMode=managed)`, exit 0, not renamed.
- The card measured the base on the same door: the truncated file was
renamed to `archive.db.corrupt-1792539192447` with an empty database in
its place and read `connected`; the dangling-link directory read
`connected` under the false native-addon warning.
**Pins** (both files run inside the whole-package suites on the final
head `cc15060f7`, under `os-verify-lock`):
- driver-sql, 10 cases: the header-truncated database refused with
`SqliteDatabaseFileError`, `code` `SQLITE_CORRUPT`, `filename`, a
message naming the file and carrying the cause, under
`NODE_ENV=development` and `production`; a database cut to its first
page, the same. Each asserts no `.corrupt-*` sibling while the refused
connection is open, then, closed, the same bytes and a directory holding
only that file. The header still says WAL, so SQLite keeps its `-shm`
and an empty `-wal` while that connection is open, and removes both when
it closes. CONTROL: a database damaged deeper inside connects, and the
read of the damaged table fails with `SQLITE_CORRUPT` as its cause. The
dangling-link directory refused on the writing boot (`ENOENT`, file and
link named) with the read-only boot's answer for the same path asserted
beside it (class, `code`, `filename`, the link words), at both depths,
the link still dangling and nothing created. CONTROLS: a linked
directory that exists connects; an absent file under makeable
directories connects. The dangling file link: refused by the read-only
boot (`ENOENT`, the target named), direct and through a second link,
with the writing boot's `SQLITE_CANTOPEN` asserted beside it and nothing
written; CONTROL: with the target's directory present, the read-only
boot reads it absent (`:memory:`) and writes nothing, and the writing
boot creates the target through the link (absolute and relative
targets).
- service-datasource, 10 cases: development `resolveSqliteDriver` over
the header-truncated database rejects with the driver's refusal, warns
nothing, and leaves the file and its directory as they were; production
returns native unprobed and its `connect()` refuses;
`DatasourceConnectionService.connectDeclared` reports `availability:
'failed'` with a reason naming the file and registers no driver, in
development and production, and moves nothing aside. The dangling-link
directory: development `resolveSqliteDriver` rejects (`ENOENT`, file and
link named) with no warning, and the read-only resolve over the same
path gives the same class, code, file and words; `connectDeclared`
reports `failed` naming the file and the link, on the writing and the
read-only factory, in development and production; nothing created.
CONTROLS: a real database opens native and answers; an absent file in a
makeable directory opens native and is created; a native addon that
cannot load over a real database still steps down to wasm SQLite, with
`NATIVE_SQLITE_WASM_FALLBACK_WARNING`, and reads the same rows, not
renamed.
- Whole packages on the final head `cc15060f7` (re-run after the worker
restart, on a full `turbo run build`, 77 of 77): driver-sql "Test Files
227 passed | 12 skipped (239) · Tests 3712 passed | 210 skipped (3922)"
(the skips are the live PG/MySQL cells, not provisioned here);
service-datasource "Test Files 53 passed (53) · Tests 930 passed (930)".
`tsc --noEmit` exit 0 for both; `tsc --listFiles` includes each new test
file (1 hit each).
**Ablation** (`scripts/ablation-replace.mjs` WRAP, each leg under
`os-verify-lock`; every restore proven by blob equality with `HEAD`, an
empty `git diff HEAD`, and an empty `git status --porcelain`; at
`281d27bdf`; the only later change to these files is `f7ea1c503`, a type
annotation on two rows the damaged-page control reads):
- **Leg 1, the driver row.** `['SQLITE_CORRUPT', 'is damaged` became
`['ABLATION_25019_CORRUPT', 'is damaged`: anchor 1 to 0, blob
`778b08f36ba6` to `7048da65440a`. driver-sql rebuilt;
`ablation-dist-preflight.mjs` found the marker in 2 built files.
Predicted and observed: driver-sql "3 failed | 7 passed" (the two
header-truncated cases and the first-page case; the controls and both
link blocks green); service-datasource "4 failed | 6 passed"
(development resolved to `sqlite-wasm`; the production refusal was
`undefined`; both `connectDeclared` cases read `available`). Restored,
rebuilt; preflight `--absent` found the marker in none of the 6 built
files, tree clean; both pin files 10/10.
- **Leg 2, the step-down code.** `|| code === 'SQLITE_CORRUPT'` became
`|| code === 'ABLATION_25019_SD'`: blob `6e42085d4512` to
`4e4570fda7a2`. A relative `src` subject, so no dist step. Predicted and
observed: service-datasource "2 failed | 8 passed" (the two development
cases; production, which the driver alone carries, green).
- **Leg 3, the dangling-link directory guard.** The line `if
(isDanglingLink(level)) throw danglingLinkRefusal(level, e);` was
deleted: blob `adf3e6b62148` to `8c7be7a55c8d`. driver-sql rebuilt;
preflight `--absent` on `danglingLinkRefusal(level, e)` found it in none
of the built files (the same marker read present in 2 on the pristine
build first). Predicted and observed: driver-sql "2 failed | 8 passed"
(both depths: the first resolved, the second refused without the link's
words); service-datasource "3 failed | 7 passed" (development resolve,
and `connectDeclared` in both modes). Restored, rebuilt; preflight found
the guard back in 2 built files, tree clean; both pin files 10/10.
- **Leg 4, the dangling file link.** `const linkEnd =
danglingLinkEnd(filename);` became `const linkEnd = undefined as string
| undefined; // ABLATION_25019_FILELINK`: blob `adf3e6b62148` to
`ad84f6bf25a0`. Relative `src` subject. Predicted and observed:
driver-sql "1 failed | 9 passed" (the refusal; its control green).
**Driver ledger** (`pnpm check:driver-conformance`): before, at
`d68aab6fd`: "55 covered cell(s), 0 in the DEBT ledger, 0 exempt";
dialect axis 9 suites, 8 matrix and 1 named, 0 in the DIALECT ledger.
After, at `cc15060f7`: the same counts. The ledger did not move.
**Gates.** `node scripts/pm/dispatch-gates.mjs --commands --repo
objectstack-ai/objectstack` (no paths) at `cc15060f7` derived 72
commands. I ran each one once, sequentially, with its exit captured
before any pipe. 70 exited 0 on the first pass. Two answered exit 3
(`PREREQUISITE NOT MET`) and were re-run on the same head after their
prerequisite: `check:dual-build-cjs-loads` needed every package's
`dist/` (a full `turbo run build`, 77 of 77), and
`check:type-check-debt` needed a turn on the verify lock for its closure
build ("1 ledger entr(ies) re-measured … none above its recorded
number"). Both then exited 0. `--ran` reconciliation: "72 derived, 72
run, 0 NOT-MEASURED, 0 UNRUN". No exported symbol was renamed or
removed, so `check-platform-checklist.mjs --changed-from` was not owed.
CI owns the full farm and `test:repo`.
**Dogfood battery** (owed: the `Clause-②` line carries the `(narrowing)`
arm): running on `cc15060f7` under `os-verify-lock` as this PR opens;
its verdict line and counts are in the dev report on the card.
## Acceptance notes
- **Member 3 is the seat's fork, not this PR's.** Measured above: with a
native addon that cannot load, a declared file that is not a database or
whose header SQLite cannot read is still renamed by wasm SQLite on a
development boot; and a datasource declared `driver: 'sqlite-wasm'` over
such a file is renamed and reads `available` in development and
production. Both live in `WasmSqliteConnection.open()`'s quarantine. The
options and their four-axis analysis are in this PR's dev report on the
card; this PR changes nothing there.
- **A refused connect's connection is never released on the production
path.** `DatasourceConnectionService` does not disconnect a handle whose
`connect()` rejected, and `connect()` does not close its own pool when
it refuses the file. For a damaged file whose header says WAL, SQLite
therefore keeps `-shm` and an empty `-wal` beside the file for as long
as the process lives (measured at the unit level; the development path
closes the probe and leaves nothing). The operator's bytes are not
touched. It predates this PR (a `SQLITE_NOTADB` file holds the same open
handle, without visible siblings) and is outside this claim's file
surface. Observation, not filed; carrier: none.
- **The development telemetry sibling**
(`packages/cli/src/utils/telemetry-datasource.ts`) still catches every
throw, so a damaged telemetry sibling is now neither renamed nor
reported. That is its pre-existing best-effort shape (family note
6305864303); out of the claim's scope.
- The writing boot answers the dangling file link whose target's
directory is missing with SQLite's own `SQLITE_CANTOPEN` ("unable to
open database file"), which names the file but not the link. The
read-only boot names the target. Both refuse; the words were left as
SQLite gives them.
- `main` was merged at `157ebd008` (merge head `cc15060f7`). It brought
eight commits touching spec, objectql, plugin-security, core, rest,
lint, cli and docs, none of this diff's packages; the closure was
rebuilt and both whole packages and the pins re-run on the merge head.
The worker restarted during the first full build; that run's readings
were discarded and the build, both suites and the two prerequisite gates
re-run on the same head.
- CI owns the full farm and `test:repo`; this diff touches no
`repo`-project test.
---
_Generated by [Claude
Code](https://claude.ai/code/session_01QK6pdbxKZiHdFApL8RYVh9)_
---------
Co-authored-by: Claude <noreply@anthropic.com>1 parent 5d2c5a1 commit d6a5fa3
6 files changed
Lines changed: 644 additions & 13 deletions
File tree
- .changeset
- packages
- drivers/driver-sql/src
- services/service-datasource/src
- __tests__
| 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 | + | |
| 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 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
| 134 | + | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
| 144 | + | |
| 145 | + | |
| 146 | + | |
| 147 | + | |
| 148 | + | |
| 149 | + | |
| 150 | + | |
| 151 | + | |
| 152 | + | |
| 153 | + | |
| 154 | + | |
| 155 | + | |
| 156 | + | |
| 157 | + | |
| 158 | + | |
| 159 | + | |
| 160 | + | |
| 161 | + | |
| 162 | + | |
| 163 | + | |
| 164 | + | |
| 165 | + | |
| 166 | + | |
| 167 | + | |
| 168 | + | |
| 169 | + | |
| 170 | + | |
| 171 | + | |
| 172 | + | |
| 173 | + | |
| 174 | + | |
| 175 | + | |
| 176 | + | |
| 177 | + | |
| 178 | + | |
| 179 | + | |
| 180 | + | |
| 181 | + | |
| 182 | + | |
| 183 | + | |
| 184 | + | |
| 185 | + | |
| 186 | + | |
| 187 | + | |
| 188 | + | |
| 189 | + | |
| 190 | + | |
| 191 | + | |
| 192 | + | |
| 193 | + | |
| 194 | + | |
| 195 | + | |
| 196 | + | |
| 197 | + | |
| 198 | + | |
| 199 | + | |
| 200 | + | |
| 201 | + | |
| 202 | + | |
| 203 | + | |
| 204 | + | |
| 205 | + | |
| 206 | + | |
| 207 | + | |
| 208 | + | |
| 209 | + | |
| 210 | + | |
| 211 | + | |
| 212 | + | |
| 213 | + | |
| 214 | + | |
| 215 | + | |
| 216 | + | |
| 217 | + | |
| 218 | + | |
| 219 | + | |
| 220 | + | |
| 221 | + | |
| 222 | + | |
| 223 | + | |
| 224 | + | |
| 225 | + | |
| 226 | + | |
| 227 | + | |
| 228 | + | |
| 229 | + | |
| 230 | + | |
| 231 | + | |
| 232 | + | |
| 233 | + | |
| 234 | + | |
| 235 | + | |
| 236 | + | |
| 237 | + | |
| 238 | + | |
| 239 | + | |
| 240 | + | |
| 241 | + | |
| 242 | + | |
| 243 | + | |
| 244 | + | |
| 245 | + | |
| 246 | + | |
| 247 | + | |
| 248 | + | |
| 249 | + | |
| 250 | + | |
| 251 | + | |
| 252 | + | |
| 253 | + | |
| 254 | + | |
| 255 | + | |
| 256 | + | |
| 257 | + | |
| 258 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
7061 | 7061 | | |
7062 | 7062 | | |
7063 | 7063 | | |
7064 | | - | |
| 7064 | + | |
7065 | 7065 | | |
7066 | 7066 | | |
7067 | 7067 | | |
| |||
7097 | 7097 | | |
7098 | 7098 | | |
7099 | 7099 | | |
7100 | | - | |
| 7100 | + | |
| 7101 | + | |
| 7102 | + | |
| 7103 | + | |
| 7104 | + | |
| 7105 | + | |
| 7106 | + | |
| 7107 | + | |
| 7108 | + | |
| 7109 | + | |
| 7110 | + | |
7101 | 7111 | | |
7102 | 7112 | | |
7103 | 7113 | | |
| |||
7132 | 7142 | | |
7133 | 7143 | | |
7134 | 7144 | | |
| 7145 | + | |
7135 | 7146 | | |
7136 | 7147 | | |
7137 | 7148 | | |
| |||
0 commit comments