Repository navigation
Commit 958cfe2
Part of #21464
Clause-②: yes (narrowing)
## What this does
Stage 3 (S-form) of the `ComponentPropsMap` `z.unknown()` close-out, per
triage `5961300594`, the seat answers `5963787404` (staging A) and
`5966636964` (the writer test: a writer is a value the renderer draws),
and the claim `5967737487`. Of the form family's nine `z.unknown()`
members, **four are typed**. **Four are held** because the form draws a
value each typed shape would refuse, and **one** (`customFields`) is
re-recorded with the objectui-held contracts, because its entries are
objectui's runtime form field, which the spec has not declared. Read
points are at the `.objectui-sha` pin `89cad75d55`, under
`packages/plugin-form/src/` unless named.
| row · member | was | now | read point |
|:--|:--|:--|:--|
| `object-form` · `contentLayout` | `z.unknown()` | `'simple' \|
'tabbed'`, the measured shape | `ModalForm.tsx:854` tests `=== 'tabbed'`
(declared `'simple' \| 'tabbed'` at `:151`); the only reader |
| `object-form` · `submitBehavior` | `z.unknown()` |
`FormViewSchema.shape.submitBehavior`, by reference |
`ObjectForm.tsx:1312-1370` and `WizardForm.tsx:1005-1065` switch on
`kind`, read `url` / `delayMs` / `title` / `message`;
`submitRedirect.ts:202` judges a redirect `url` by parsing a form view
through this same schema |
| `object-form` · `navigateOnSuccess` | `z.unknown()` | `z.string()`,
the measured shape | `successBehavior.ts:118-131` (`template.replace`),
from `ObjectForm.tsx:1373` and `WizardForm.tsx:1071` |
| `object-form` · `mobile` | `z.unknown()` | strict `{ stickyActions?,
stepper?, stepperMinFields?, stepperFieldsPerStep?, fullscreenLongText?
}` (module-private `ObjectFormMobileSchema`), the measured shape |
`ObjectForm.tsx:1857-1942` (flat arm only) |
| `object-form` · `fields` | `z.array(z.unknown())` | **held**,
unchanged | `ObjectForm.tsx:961-981` and `flatFields.ts:71-79` draw a `{
name }` entry by that name |
| `object-form` · `sections` | `z.array(z.unknown())` | **held**,
unchanged | `sectionFields.ts:367-369` draws an inline runtime field `{
name, type, … }` inside a section as it stands ("shape 3") |
| `object-form` · `customFields` | `z.unknown()` | unchanged; ledger
stage `object-form` → `objectui-held` | `customFieldsMerge.ts:59-108`
matches members by `name` and draws them whole |
| `object-master-detail-form` · `sections`, `fields` |
`z.array(z.unknown())` | **held**, unchanged |
`MasterDetailForm.tsx:1692-1693` hands both to the parent `object-form`
verbatim |
The four typed members carry no default and no transform, so
`ObjectFormProps` stays input-equals-output. `ObjectFormProps` carries
the four types instead of `unknown`.
## The census (A1), whole
A writer is a page-component node: an object literal naming the type, a
literal annotated with the block's type, a `schema={{…}}` on
`ObjectForm` / `MasterDetailForm`, a call into a local helper that
builds the node (each call site counted, the helper's parameters bound
to that call's arguments and defaults), or a direct parse through the
row. Values resolve through same-file constants and single-expression
local helpers. The control is `objectName` on the same nodes. The
instrument is a TypeScript-AST walk over every `.ts`, `.tsx`, `.js`,
`.jsx`, `.mjs`, `.json`, `.md`, `.mdx` and `.yaml` file, with fenced
code in the documents parsed too.
| corpus | `object-form` nodes | `object-master-detail-form` nodes |
control `objectName` |
|:--|--:|--:|:--|
| objectstack `e909aa0a23` (`examples/`, `packages/` with
`packages/apps/`, `content/`, `skills/`, `apps/`) | 16 | 125 | 13 / 125
|
| objectui `89cad75d55` (whole tree) | 539 | 131 | 522 / 120 |
Re-checked at the final merge base `cc645f2385`: the `.objectui-sha` pin
is unchanged, and the commits `main` brought since `e909aa0a23` add or
remove no line naming either block (`object-form`,
`object-master-detail-form`, `ObjectForm`, `MasterDetailForm`) or
`submitBehavior`, `navigateOnSuccess`, `contentLayout` or `customFields`
(0 hits in 2947 moved lines), so the census stands.
Every renderer path that reads each member, and the keys it reads from
an entry:
| row · member | readers at the pin | keys read | referenced schema |
objectstack values (parse) | objectui values · static (distinct) · parse
· refused · not static |
|:--|:--|:--|:--|:--|:--|
| form `contentLayout` | `ModalForm.tsx:854` only | `=== 'tabbed'` |
none (form view has none) | 0 | 5 · 5 (1) · 5 · 0 · 0 |
| form `submitBehavior` | `ObjectForm.tsx:1312-1370`, `:1926-1928`;
`WizardForm.tsx:1005-1065`; `submitRedirect.ts:202` | `kind`; `url`,
`delayMs`; `title`, `message` | `FormViewSchema.submitBehavior` | 3 (3)
| 49 · 36 (20) · 32 · 4 · 13 |
| form `navigateOnSuccess` | `successBehavior.ts:118-131` via
`ObjectForm.tsx:1373`, `:1412-1429`; `WizardForm.tsx:1071`, `:1085-1092`
| a string template | none | 0 | 5 · 5 (1) · 5 · 0 · 0 |
| form `mobile` | `ObjectForm.tsx:1857-1942` | `stickyActions`,
`stepper`, `stepperMinFields`, `stepperFieldsPerStep`,
`fullscreenLongText`; presence (`data-mobile-form`) | none | 0 | 14 · 14
(8) · 14 · 0 · 0 |
| form `fields` (held) | `ObjectForm.tsx:961-981` (pool), `:323` (field
security), `:387` (master-detail hand-off), `:1665-1683` (section
intersection); `flatFields.ts:71-79` (drawer / modal,
`DrawerForm.tsx:473`, `:877`, `ModalForm.tsx:562`, `:1037`);
`sectionFields.ts:203` (the warning) | a string, or an entry's `name` |
none; objectui declares `string[]` | 0 | 33 · 25 (20) · 17 · 8 · 8 —
candidate `z.array(z.string())` |
| form `sections` (held) | `ObjectForm.tsx:244-314` (`group`,
`sectionGroups.ts:139`), `:288-298`, `:324-327`, `:364-367`, `:386`,
`:406-608` (tabbed / wizard / split / drawer / modal maps), `:1511-1742`
(simple); `sectionFields.ts:319-485`; `submitTarget.ts:101-135`;
`TabbedForm`, `WizardForm`, `SplitForm`, `DrawerForm`, `ModalForm` |
section: `name`, `label`, `description`, `columns`, `fields`, `group`,
`pane`, `collapsible`, `collapsed`, `visibleWhen`; field entry: a
string, a spec field keyed by `field` (and its 26 override keys), or a
runtime field keyed by `name`, drawn whole | `FormViewSchema.sections` |
3 (3) | 252 · 218 (90) · 203 · 15 · 34 — candidate
`FormViewSchema.shape.sections` |
| form `customFields` (objectui-held) | `ObjectForm.tsx:755`, `:1180`,
`:1625`, `:1675`; `customFieldsMerge.ts:59-108`; `sectionFields.ts`
(`findCustomFieldMember`); `DrawerForm.tsx:433`, `:465`, `:480`;
`ModalForm.tsx:523`, `:555`, `:569`; `SplitForm.tsx:323`;
`TabbedForm.tsx:424`; `WizardForm.tsx:688`; `submitTarget.ts:131-135`;
`index.tsx:215` | `name`, then the whole runtime field | none in the
spec | 0 | 32 · 29 (17) · — · — · 3 (every static entry is a runtime
field keyed by `name`) |
| master-detail `fields` (held) | `MasterDetailForm.tsx:1693` into the
parent form (read as the form's) | as the form's | as the form's | 4 (4)
| 85 · 82 (13) · 80 · 2 · 3 — candidate `z.array(z.string())` |
| master-detail `sections` (held) | `MasterDetailForm.tsx:1692` into the
parent form | as the form's | as the form's | 0 | 18 · 15 (9) · 15 · 0 ·
3 — candidate `FormViewSchema.shape.sections` |
The objectui values were parsed through the built row on this branch
(typed members) and through the candidate shape (held members). The
not-static values are run-time hand-offs (`ObjectView.tsx:2585`,
`AppContent.tsx:1152`, `RecordFormPage.tsx:368`,
`useActionModal.tsx:254`, `ViewPreview.tsx:258`,
`StudioDesignSurface.tsx:4139`, `EmbeddableForm.tsx:562`,
`MasterDetailForm.tsx:1682`, the drawer / modal / form master-detail
routes, the designer's `ObjectManager` / `FieldDesigner`), test-loop
variables, and helper results the instrument does not evaluate.
## Writer parse results (A3)
**Typed members — no refused value is one the form draws.**
- `submitBehavior`: 4 static values are refused, each `{ kind:
'redirect', url: '//example.com/thanks' }`
(`ObjectForm.submitRedirect.test.tsx:264`, `:276`;
`WizardForm.submitRedirect.test.tsx:204`, `:220`), and each test asserts
the form refuses it and navigates nowhere. Of the 13 not-static values,
read by hand: 9 are relative redirects that parse
(`submitRedirect.injectedNavigation.test.tsx:164`, `:176`, `:193`,
`:225`, `:232`, `:275`, `:281`, `:296`, `:303`), and 4 are redirect
fixtures the form refuses (the same-origin absolute
`${window.location.origin}/thanks` at
`ObjectForm.submitRedirect.test.tsx:233`,
`WizardForm.submitRedirect.test.tsx:179`,
`submitRedirect.injectedNavigation.test.tsx:208`, and
`//example.com/thanks` at `:309`). All 3 objectstack values (the
showcase's new-project wizard and its two copies in the lint and spec
tests) parse.
- `contentLayout`, `navigateOnSuccess`, `mobile`: every value parses.
**Held members — the candidate shape refuses values the form draws.**
- form `fields` (candidate `z.array(z.string())`), 8 refused. **Drawn —
working writers:** objectui's published page-builder guide
(`skills/objectui/guides/page-builder.md:263`, an `os:check` example:
`fields: [{ name, label, type, required }, …]`), the field-security
payload pin (`fieldSecurityPayload.test.tsx:214`, `:222`, `:230`, `{
name, label }` entries on all three containers), the system-managed
payload pin (`systemManagedPayload.test.tsx:209`), and the `{ name }`
row objectui pins as behaviour
(`__tests__/objectFormFieldsMembers-8071.test.tsx:165-167`, "recorded as
drift, not a second contract"). **Probes:** `{ field: 'note' }` and `{
field: 'sent_at' }` (`objectFormFieldsMembers-8071.test.tsx:132`,
`:183`), which the form warns about and skips.
- master-detail `fields`, 2 refused: `[{ name: 'note' }, 'status']`
(`__tests__/topLevelFieldsWarnCoverage-8847.test.tsx:254-257`, "`{ name
}` is tolerated as the same member as the bare name") is **drawn**; `{
field: 'note' }` (`:104`) is a probe of the warning.
- form `sections` (candidate `FormViewSchema.shape.sections`), 15
refused. **Drawn — working writers:** objectui's README wizard example
with inline runtime fields (`packages/plugin-form/README.md:764`), and
its submit-target pins that assert that shape renders and submits
(`submitTargetRefusal.test.tsx:345`, and `:374`, where the inline field
is drawn and only the submit is refused for the bare name beside it).
**Probes:** `submitTargetRefusal.test.tsx:422` (the simple arm resolves
zero fields from inline sections), 8 `className` / `gridClassName`
sections (`__tests__/sectionStyleKeysRetired-13626.test.tsx`, the
retired reads), a section with neither `fields` nor `group` and a
`group` beside a `label` / `collapsible`
(`__tests__/formSectionGroupReference-7051.test.tsx:270`, `:307`,
rendered as nothing and as ignored-and-reported), and a blank view-level
`visibleWhen` (`wizardVisibleWhenFault-8069.test.tsx:134`, diagnosed).
- master-detail `sections`: no measured value is refused; held with the
form's member because it is the same read (A4).
Under the triage caveat ("a narrowing that would refuse a measured
writer is reported, not shipped silently") and the seat's test, this
list is the report: the four held members are not narrowed, and each
stays in the enumeration pin's ledger as `held-for-decision` with the
read it rests on. The renderer side is the seat's to card.
## A2, per member
- **Typed by reference (1):** `submitBehavior` →
`FormViewSchema.shape.submitBehavior` (the discriminated union on
`kind`, its four strict arms and the redirect `url` rule). It states the
member and accepts every drawn value.
- **Typed to the renderer's read (3):** `contentLayout` (`'simple' |
'tabbed'`), `navigateOnSuccess` (`z.string()`), `mobile` (the five
members objectui's own `ObjectFormSchema.mobile` declares; the two
counts positive integers — the read clamps `stepperFieldsPerStep` below
1 to 1, and no writer authors a count below 1).
- **Held (4):** form `fields` (no by-reference schema; the renderer's
declared type `string[]` refuses the `{ name }` entry it draws), form
`sections` (`FormViewSchema.sections` states every section key the form
reads but refuses the shape-3 field entry it draws), master-detail
`fields` and `sections`.
- **Recorded with a reason, not typed (1):** `customFields` — its
entries are objectui's runtime form field (`FormField`, identity key
`name`, about forty members drawn whole). The spec declares no such
field, and its own `FormFieldSchema` is keyed by `field`, which the
merge never matches. Typing it means declaring that contract in the spec
first, which is the `objectui-held` stage's definition, so its ledger
line moves there (the `objectui-held` text now names `FormField`). See
the open question in the dev report.
- **Runner-forwarded:** none.
## A4: one read, two rows
`MasterDetailForm` builds its parent form with `sections:
schema.sections, fields: schema.fields`
(`MasterDetailForm.tsx:1692-1693`), so each master-detail member is read
by exactly the form's read. Both rows take one disposition per member:
held. The master-detail `fields` hold also rests on its own drawn `{
name }` writer; the master-detail `sections` hold rests on the shared
read — typing it alone would give one read two accept sets.
## The pin (A5)
- `component-props-unknown-members.pin.test.ts`: four
`staged('object-form', …)` lines leave (`contentLayout`,
`submitBehavior`, `navigateOnSuccess`, `mobile`); form `fields[]` and
`sections[]` and master-detail `sections[]` / `fields[]` become
`held-for-decision`, each with its read and writers in the comment;
`customFields` becomes `objectui-held`. The `object-form` stage leaves
`STAGES` with no line using it. The `held-for-decision` text now reads
"a typed shape exists (by reference, or the renderer's own declared
type)", because form `fields` has no by-reference schema.
- `component-form-family-typed-members.pin.test.ts`, the companion pin
in stage 2's pattern: §1 every shape a measured writer authors parses
byte-identical (16 cases, plus absence); §2 17 refusals by code and
path, the `heading` → `title` prescription, and a lit control; §3
`submitBehavior`'s def identity with the form view's, and the measured
vocabularies of `contentLayout` and `mobile`; §4 the D3 registration.
- Red then green, and the ablation: see "Gates".
## The rest of the kit (A6)
- ADR-0087 D3 entry `ui-object-form-members-typed` (D3 only, no
conversion, reason recorded) and its step-18 rationale fragment at order
67 (one more than the highest, 66).
- `dropped-refinements.baseline.json` gains `ui/ObjectFormProps` →
`submitBehavior.options[1].url`: the form view's redirect `url`
refinement reaches this second published schema by reference and does
not project into JSON Schema; the build refused until the line was
added, as #21445's by-reference `bulkActionDefs` did.
- Regenerated by `check:generated --fix` (only what it proved stale):
the step-18 semantic region of `migrations/registry.ts`,
`content/docs/references/ui/component.mdx`, and the `ui/` strictness
counts (191 → 192 sites, +1 strict for the `mobile` block).
- Changeset: `@objectstack/spec` `minor`, a **BREAKING** banner,
`Clause-②: yes (narrowing)`, a FROM → TO table, the measured census, and
the ADR-0087 marker `registered`.
## objectui fixtures (A7)
None needs respelling at objectui's next `@objectstack/spec` bump. The 8
refused `submitBehavior` values are render-only tests that mount
`ObjectForm` / `WizardForm` directly; none parses through
`ObjectFormBlockSchema`. objectui's parse-through tests
(`types/src/__tests__/object-form-properties-bag-10859-b4.test.ts`,
`p1-spec-alignment.test.ts`) author only values that parse, or members
this PR does not narrow. objectui's source indexes
`SpecObjectFormProps['layout']` only, which is not narrowed.
## Gates
All readings are at `ee6a556ad8`, the fourth merge of `origin/main`
(`cc645f2385`, docs only), unless one says otherwise. Every exit code
was written to disk before any pipe. This run resumed after a container
restart at `f63c7849b6`: the third gate round there had recorded 87 of
114 exit codes when it was cut off, so after the fourth merge every
gate, build, test and the ablation below re-ran at `ee6a556ad8`. The
branch's own added and removed lines are byte-identical to the second
round's (only context lines moved). After the fourth merge, `main`
advanced by `a7ab047cf6` and `901e7cf13a` (`packages/rest`,
`packages/cloud-connection`, the dogfood suite and two changesets): none
of this branch's 9 paths and nothing under `packages/spec`. They are not
merged here, so every reading below stays at the head it cites; the
merge queue rebuilds onto current `main`.
- **Derived set:** `node scripts/pm/dispatch-gates.mjs --repo
objectstack-ai/objectstack --commands` derived 114 commands (9 paths,
549 changed lines, +521 / -28, merge base `cc645f238`), all run;
`--ran`: **114 derived, 114 run, 0 NOT-MEASURED, 0 UNRUN**, every one
exit 0.
- **`@objectstack/spec`:** `build` exit 0 (the package's own build,
after a turbo run that replayed 72 of 72 tasks from cache), and the tree
stayed clean; `check:generated` exit 0 — "All 15 generated artifacts are
up to date"; `check:migration-registry` — "src/migrations/registry.ts is
current (357 semantic, 246 retired-key, 218 retired-def)";
`check:liveness` — "packages/spec/liveness/state-counts/ is current";
`check:strictness-ledger` — "463 triaged site(s) measured";
`check:authorable-surface` (the base trails its anchor, an information
line); `check:api-surface` — "public API surface + factory signatures
unchanged"; `check:docs` — "226 generated files in sync with
packages/spec": each exit 0. `check:generated` and `check:api-surface`
re-ran after the package build, exit 0.
- **Tests and types:** `pnpm --filter @objectstack/spec test` — **Test
Files 607 passed (607), Tests 17992 passed, 1 todo**, exit 0;
`typecheck` exit 0 with "check:test-typecheck: OK"; `pnpm --filter
@objectstack/lint test` (the import side of `ComponentPropsMap`) — **119
files, 5620 tests passed**, exit 0; the three `ComponentPropsMap` pins —
**3 files, 139 tests passed**.
- `pnpm check:doc-authoring` and `pnpm check:nul-bytes` ("scanned 9949
text file(s) … no raw ASCII control bytes"): exit 0.
- **`check-widening-tells`** on the branch diff: `--declaration no` exit
4 with six tells. Five are T1 tells at the new `mobile` block's keys
inside the former `z.unknown()` member — the shape the gate's own text
rules a true refusal, so declare `yes`. The sixth is a T2 at
`component.zod.ts:41`, the `FormViewSchema` specifier in the multi-line
import list from `./view.zod`, read as a new member of a closed set; it
is a false tell (an import specifier widens no accept set).
`--declaration yes` exit 0.
- **Changeset gates, with this body as the `--event` payload:**
`check-changeset-no-major` exit 0 — "LEVEL AXIS: this PR declares
clause-② `yes (narrowing)`, and no package whose `packages/**/src/**` it
moves is graded `patch`" · "direction arm: `narrowing` — a BREAKING
change; during the launch window it ships `minor`";
`check-adr-0087-registration` exit 0 — "1 declared-breaking
changeset(s), each carrying an ADR-0087 disposition" (`registered
ui-object-form-members-typed`); `check-empty-changeset` exit 0 — "No
empty-frontmatter changeset introduced by this diff (1 declaring
changeset(s) added)".
- **Red then green, and the ablation** (through `node
scripts/ablation-replace.mjs` in wrap mode, inside a script with its own
`EXIT INT TERM` restore trap): `object-form` `contentLayout` reverted to
`z.unknown().optional()`, with no ledger line. It landed: anchor x1 to
x0, replacement x0 to x1, blob `2594178cfc` to `82b2f86644`. Red:
**Tests 5 failed | 86 passed (91)** — the enumeration pin's §1 received
exactly `[ 'object-form contentLayout' ]` and its census-equals-ledger
control read 96 against 95, and the companion pin failed its two
`contentLayout` refusals and its vocabulary case. Restored: blob after
restore `2594178cfc` == blob at HEAD, `git diff HEAD` empty (the tool's
check and the trap's both). Green rerun: **Tests 91 passed (91)**. The
pins import `./component.zod` from source, so no build sits between
mutation and run.
- **Lint, narrowed:** eslint over the 5 changed TypeScript files (each
resolves a config by `--print-config`; the other 4 changed files resolve
none), `--no-inline-config --format json`: 5 files, 0 errors, 0
warnings, exit 0. `eslint.config.mjs` never enables type-aware linting
(lines 326-328), so this diff cannot move the verdict on an untouched
file.
- **NOT MEASURED:** the Console Pin Gate, Dogfood and the full `pnpm
lint`; reason: CI-owned.
## Acceptance notes
- **The holds.** Form `fields`: objectui's declared type and its zod
twin are `string[]`, its registration calls `{ name }` "tolerated", and
its own pin calls it "drift, not a second contract" — the arguments for
a ruling, not a licence to ship past the caveat. Form `sections`: the
shape-3 entry is how objectui's sectioned variants run with no data
source (`submitTarget.ts:36-61`), shipped in its README. Both are the
seat's to card on the renderer side; this PR changes neither accept set.
- **For the `sections` ruling, observed:** the form view's section
accepts the deprecated `visibleOn` and string `columns` (`'2'`), which
the form view's own parse normalizes. A page component's `properties` is
never parsed, so on this door the renderer would read them raw: no arm
reads a section `visibleOn`, and the simple arm's column clamp takes
numbers only (`ObjectForm.tsx:1599-1600`). Typing `sections` by
reference would accept both on a door where they render nothing.
- **objectui's page-builder guide**
(`skills/objectui/guides/page-builder.md:263`) teaches `object-form`
`fields` entries with `label`, `type` and `required`; the form draws
each entry by `name` and drops the other three. It belongs with the
`fields` hold's ruling; noted, not filed here.
- No objectui edit and no renderer change.
#21464 remains open for S-metric and S-objectui-held. object-kanban
`conditionalFormatting` stays held on objectstack-ai/objectui#11522,
object-grid `columns` on objectstack-ai/objectui#11544, and the four
form members here await the seat's carrier.
---
_Generated by [Claude
Code](https://claude.ai/code/session_01YDt3PzwfrkuFzUBF89WPmM)_
---------
Co-authored-by: Claude <noreply@anthropic.com>
1 parent 901e7cf commit 958cfe2
9 files changed
Lines changed: 521 additions & 28 deletions
File tree
- .changeset
- content/docs/references/ui
- docs/audits/2026-07-unknown-key-strictness-ledger.counts
- packages/spec
- src
- migrations
- entries/semantic
- ui
| 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 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
539 | 539 | | |
540 | 540 | | |
541 | 541 | | |
542 | | - | |
| 542 | + | |
543 | 543 | | |
544 | 544 | | |
545 | 545 | | |
| |||
548 | 548 | | |
549 | 549 | | |
550 | 550 | | |
551 | | - | |
| 551 | + | |
552 | 552 | | |
553 | 553 | | |
554 | | - | |
| 554 | + | |
555 | 555 | | |
556 | 556 | | |
557 | 557 | | |
558 | | - | |
| 558 | + | |
| 559 | + | |
| 560 | + | |
| 561 | + | |
| 562 | + | |
| 563 | + | |
| 564 | + | |
| 565 | + | |
| 566 | + | |
| 567 | + | |
| 568 | + | |
| 569 | + | |
| 570 | + | |
| 571 | + | |
| 572 | + | |
| 573 | + | |
| 574 | + | |
| 575 | + | |
| 576 | + | |
559 | 577 | | |
560 | 578 | | |
561 | 579 | | |
| |||
Lines changed: 5 additions & 5 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
21 | 21 | | |
22 | 22 | | |
23 | 23 | | |
24 | | - | |
| 24 | + | |
25 | 25 | | |
26 | 26 | | |
27 | 27 | | |
| |||
36 | 36 | | |
37 | 37 | | |
38 | 38 | | |
39 | | - | |
| 39 | + | |
40 | 40 | | |
41 | 41 | | |
42 | 42 | | |
| |||
46 | 46 | | |
47 | 47 | | |
48 | 48 | | |
49 | | - | |
| 49 | + | |
50 | 50 | | |
51 | 51 | | |
52 | 52 | | |
53 | 53 | | |
54 | 54 | | |
55 | 55 | | |
56 | 56 | | |
57 | | - | |
| 57 | + | |
58 | 58 | | |
59 | 59 | | |
60 | 60 | | |
61 | 61 | | |
62 | 62 | | |
63 | 63 | | |
64 | 64 | | |
65 | | - | |
| 65 | + | |
66 | 66 | | |
67 | 67 | | |
68 | 68 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
2 | 2 | | |
3 | 3 | | |
4 | 4 | | |
5 | | - | |
6 | | - | |
| 5 | + | |
| 6 | + | |
7 | 7 | | |
8 | 8 | | |
9 | 9 | | |
| |||
1364 | 1364 | | |
1365 | 1365 | | |
1366 | 1366 | | |
| 1367 | + | |
| 1368 | + | |
| 1369 | + | |
| 1370 | + | |
| 1371 | + | |
1367 | 1372 | | |
1368 | 1373 | | |
1369 | 1374 | | |
| |||
Lines changed: 53 additions & 0 deletions
| 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 | + | |
0 commit comments