Repository navigation
Commit 72eeabd
fix(platform-objects): decide the dataset panel en-echoes per leaf, and derive the panel pin (#19460)
Part of #19403
Clause-②: no
## What this is
Round 3 of this card. One panel family, decided **leaf by leaf**. The
card's deliverable is a per-leaf judgement with its reason recorded, not
24 translations; every leaf below was decided on its own evidence, and
the verdicts with their reasons live in a ledger the suite reads
(`dataset-panel-echo-decisions.test.ts`), not only in this body.
**The family: the whole `dataset` metadata form** — the ADR-0021
analytics semantic-layer editor. Its type display pair, its four section
headings, and both string leaves of its seven non-repeater fields. It is
the largest family the round-2 table left (12 of the 50 keys), and round
2's stated rule was to take that one.
Not `Fixes` — this is one family of the card's population, and the card
outlives this round. **Six families remain** (38 label keys), tabled at
the foot of this body.
## The reading, re-taken on this base — the numbers are NOT inherited
Census instrument: flatten every `*.metadata-forms.generated.ts` bundle
and compare `.label` leaves against the `en` bundle. Population fixed
here: the `.label` leaves of the metadata-form catalogs (the card's
population, 538 leaves), **plus the sibling `helpText` leaf of every key
this round decides, plus the `label` + `description` pair of every
section heading this family sits under, plus the type's own display
pair** — a panel whose field name is Chinese and whose tooltip is
English is the same defect half fixed.
Measured on worktree base `2951c0f8f`:
| reading | result |
|:--|:--|
| `en` string leaves in the metadata-form catalogs | 893 |
| of which `.label` leaves | 538 |
| POSITIVE CONTROL — labels genuinely translated | **488** (`zh-CN`) ·
**472** (`ja-JP`) · **472** (`es-ES`) |
| labels echoing the `en` source, per locale | 50 · 66 · 66 |
| label keys echoing in ALL THREE locales | **50** ⇒ 150 leaves |
The control is what makes the echo count mean something: 488 translated
against 50 echoing is a discrimination, not a parser that matches
everything.
**This is 50 / 150, the same reading round 2's LANDED comment recorded
on the trunk and the same the round-3 claim re-took at 23:01Z** — but
that is a *measurement here*, not an inheritance: four commits landed on
`origin/main` between my base and my first push (`04d639c65`,
`fc1a79067`, `be488cef3`, `8e368dc3b`) and `git diff
2951c0f..origin/main --
packages/platform-objects/src/apps/translations/` is **empty**, so
nothing moved this population under me. The card's own banner exists
because a sibling PR once did exactly that; the way to know is to look.
**After this change**: 38 keys / 114 leaves echo in all three locales;
control **500** · **484** · **484** — echoes down 12 and the control up
12, same population, same run.
## The re-derived family table — the round-2 table is NOT stale
The claim said to treat PR #19428's seven-family breakdown as a starting
hypothesis and re-derive it. Re-derived from the census output on base
`2951c0f8f`, grouping the 50 keys by metadata type: the two tables agree
**key for key**, including its decision to collect the six bare
`type.label` keys with no panel (`seed` · `mapping` · `api` · `doc` ·
`book` · `capability`) into one row. So the table is a live reading, not
a stale one, and the largest family it leaves is this one.
One thing the re-derivation exposes that a `.label` census cannot: **12
label keys is 24 decidable leaves here**, because every one of them has
a sibling `helpText` or `description` that echoes with it and that no
`.label` census counts. That ratio is what the remaining-count table at
the foot is worth reading against.
## The verdicts — 12 keys × 2 string leaves × 3 locales = 72 decisions
Every one is `translate`, and **not one of them is "translate because it
is English"**. The echo direction was tested per leaf by asking what
this catalog's own authored corpus answers for that term.
- **The authored twin INSIDE the same key.** `dataset.fields.measures`
was already authored in all three locales (度量 / メジャー / Medidas, helpText
included) while `dataset.sections.measures` — the heading directly over
it — read English; `dataset.fields.dimensions` read English while its
own five row properties were authored; `dataset.fields.measures.filter`
was 筛选 / フィルター / Filtro while `dataset.fields.filter` echoed;
`dataset.fields.measures.name` / `.label` were authored while
`dataset.fields.name` / `.label` echoed. The identical string, on the
same panel, rendered one way and echoed the other. An echo cannot be the
deliberate rendering when the same word is rendered beside it.
- **The sibling editor.** `datasetForm`'s own docblock says it "Mirrors
`reportForm` — the sibling analytics editor", and `report` is authored
in all three locales for the same identity fields (`snake_case unique
identifier` is an exact-string precedent, byte for byte), the same
section shape, and the same semantic-layer vocabulary (`semantic layer`,
`measures/dimensions`).
- **Decided AGAINST its precedents, per locale** —
`dataset.sections.source.label`. This catalog answers the bare word
`Source` in three directions: `hook.fields.body.source` is 源码 / ソース /
Código fuente (source CODE), `sys_metadata.fields.source` is 来源 / ソース /
Origen (provenance), and `page.fields.interfaceConfig.source` is 数据来源 /
ソース / Origen de datos (a data binding — decided one round earlier on
this same card). This section holds the base object, the joins and the
intrinsic scope, so it is the third sense and neither of the first two.
`zh-CN` and `es-ES` depart from two of the three precedents; `ja-JP`
keeps ソース, which all three precedents already use and which carries the
data-source sense unambiguously in Japanese. Per locale, not per string.
- **The one leaf with NO precedent at all** —
`dataset.fields.include.label`. Nothing in either catalog answers the
bare word `Include`, so it is decided from its own helpText and the
decision is recorded **as an expansion**: 包含关联 / 含める関係 / Relaciones a
incluir, using this catalog's own authored words for the concept
(`report.sections.joined_blocks.label` is 关联对象 / 結合ブロック / Bloques
unidos; `field.fields.summaryOperations.helpText` renders parent-child
relationships as 父子关系 / 親子関係 / `relaciones padre-hijo`). A bare 包含 / 含める
/ Incluir answers "include what?" with nothing on a panel whose other
labels all name their content.
- **Strict-enum values kept English, schema checked BEFORE translating**
— `dataset.sections.measures.description` names `sum/avg/count/…` and
`ratio/sum/difference/product`. Those are `AggregationFunction`
(`packages/spec/src/data/query.zod.ts:159`) and `DerivedMeasureOp`
(`packages/spec/src/ui/dataset.zod.ts:136`), both `z.enum` inside a
`strictObject`. Rendering them as words would tell an author in their
own language to write a token the schema refuses — the inverse defect
round 2 found on `view.fields.userFilters.helpText` and recorded as
#19430. Kept English on this catalog's own authored precedent for the
shape: `report.fields.type.helpText` keeps
`tabular/summary/matrix/joined` verbatim in all three locales.
- **Machine tokens and SQL keywords kept English inside translated
prose** — `lookup` / `master_detail` (FieldType enum values),
`relationship.field` and its worked example `account.region`, the
literal example value `account`, and the `FROM` / `ON` clauses the prose
names. Precedents: `object.fields.fields.reference.helpText` keeps
`tree` and `lookup` verbatim in all three locales,
`field.fields.multiple.helpText` keeps `select/lookup`, and
`view.fields.appearance.helpText` keeps `allowedVisualizations`.
- **A house style measured rather than assumed** — of the 67
genuinely-translated section descriptions in this catalog, `zh-CN` drops
the trailing full stop in 56 while `ja-JP` and `es-ES` keep it in all
67. The four new section descriptions follow that.
- **Panel-internal control** for every prose leaf: each of the 24
carried an entry in this package's per-locale
`source-hashes.generated.ts` provenance table in all three locales —
exactly 24 rows under `metadataForms.dataset` per locale, no more and no
fewer — while all 15 authored neighbours in the same `dataset` block
(`measures.label`, `measures.helpText` and the thirteen repeater row
properties) carried none in any of them. That is what an unauthored
extractor fill looks like here.
Per-leaf reasons for all 24 leaves are in the ledger; this list is the
summary, not the record.
## The instrument, extended not reinvented
`dataset-panel-echo-decisions.test.ts` is the #19355 shape as rounds 1
and 2 left it: one row per leaf, verdict per locale, reason, and the
`en` source pinned EQUAL to the live bundle so rewording the English
reds the row instead of leaving a decision standing over text nobody
judged. All three of round 2's deliberate properties are carried over:
1. **The echo-reason rule is a predicate with a dark control.** Every
verdict here is `translate`, so asserting the rule over the ledger alone
evaluates nothing — the suite feeds it a synthetic `echo` row, asserts
it is refused, then asserts it is accepted once a departure reason is
added.
2. **The panel population is DERIVED from the `en` catalog**, not
hand-listed, so the pin cannot drift into a maintained list. It reaches
all 39 string leaves of the `dataset` entry (the 24 decided plus the 15
already authored), and the dark control feeds it the `en` catalog and
requires every leaf to come back flagged.
3. **A SECOND, independent witness: the provenance table.** The ledger
asserts that no decided leaf is still recorded as an extractor fill in
any of the three `source-hashes.generated.ts` companions. It fires on a
different trigger than the catalog assertion (a re-fill followed by an
extract, rather than the re-fill itself) and it is per-locale, so it is
not blind in the case `check:i18n-stale-fill`'s cross-locale witness is
blind. Its own dark control proves the lookup finds a key the table
*does* hold, matched by pattern rather than pinned to a family, so a
later round cannot red it by repairing one — and it additionally pins
both spellings the composer builds, since this family is the first to
need a type-level key (`metadataForms.dataset.label`) beside the
`fields`/`sections` form.
**The blind spot this family adds — a third shape, measured from both
sides.** Round 1 measured the `record` blind spot and round 2 the
`composite` one. Here `dataset` *is* one of the types
`repeater-row-properties.test.ts` already derives: its two enumerated
repeaters yield **13** row properties (`dimensions.*` ×5, `measures.*`
×8), and **every one of those 13 was already translated in all three
locales**. None of the 24 leaves decided here is inside that derivation,
because the pin walks a repeater's CHILDREN and never the repeater
itself — so `dataset.fields.dimensions.label` and `.helpText` sat
directly above thirteen covered row properties and no pin saw them. The
suite asserts both halves: what the existing pin covers (and that it was
fine), and what it structurally cannot.
## Regeneration — the silent-loss hazard on this path
Translated-locale values are hand-written; the provenance tables are
not. Regenerated with **`pnpm i18n:extract`** (the command this
package's extract config documents), never by hand, and **no key was
added or removed** — so the `merge=os-regen` gap on
`*.metadata-forms.generated.ts` (`git check-attr merge` reads
`unspecified` on these paths) has nothing to lose even in principle.
Measured rather than asserted: the bundle diff is **24 insertions / 24
deletions** in each of the three translated bundles — a pure value
replacement — and the key lines of all four bundles are byte-identical
lists before and after (**1465** in each, same order, `diff` clean). The
extract's own diff is **0 insertions / 24 deletions** per provenance
table: the 24 rows per locale that now record these leaves as authored
(table sizes 455 → 431, 509 → 485, 518 → 494, exactly −24 each; **0**
rows remain under `metadataForms.dataset` in any locale, while the
tables still hold rows for other families). The `en` bundle and all four
`*.objects.generated.ts` bundles are untouched.
`pnpm check:i18n` green is the proof that the hand-written values are
byte-identical to what a fresh extract writes, across all nine bundle
sets.
## Reverse verification — the new pin can fail, in three independent
places
Committed first, then ablated through `scripts/ablation-replace.mjs`,
which makes the anchor count and the blob hash its own verdict and
performs the mutation, the run and the restore **inside one process** —
so no restore can be lost to a shell that exited between the two. No
rebuild is needed for these: the ledger imports the bundles by relative
path inside its own package, so the ablated files do not resolve through
a package `exports` to `dist/`; this package's one vitest alias is for
`@objectstack/lint` and touches none of it. (The ledger's one
cross-package import, `datasetForm` from `@objectstack/spec/ui`, does
resolve to `spec/dist` — it is not an ablation subject, and that dist
was rebuilt on this base before any reading was taken.)
**Ablation A — one decided leaf reverted to its English source in
`zh-CN`** (`dataset.fields.include.label`):
- anchor `label: "包含关联",` x1 → x0 · replacement `label: "Include",` x0 →
x1 · blob `6cadd2c0231a` → `a0f356e5270f`
- suite under the mutation: **2 failed | 17 passed** — the enumerated
verdict (`zh-CN: every decided leaf matches its verdict`) AND the
derived panel pin (`no leaf on this panel reads its en source unless the
ledger decided it is an echo`), independently
- restored: blob back to `6cadd2c0231a` == HEAD, `git diff HEAD` empty
**Ablation B — one provenance row re-pointed at a decided leaf** (a
row's key swapped in `zh-CN.source-hashes.generated.ts`, so the table
claims the leaf is still a byte copy of its source):
- anchor x1 → x0 · replacement x0 → x1 · blob `d279b182827b` →
`bbe9b563ba54`
- suite under the mutation: **1 failed | 18 passed** — and it is a
**different** assertion than A's two (`zh-CN: no decided leaf is still
recorded as an extractor fill`), so the second witness is not a
restatement of the first
- restored: blob back to `d279b182827b` == HEAD, `git diff HEAD` empty
Suite restored and re-run: **19 passed**, working tree clean.
## Verification
- `pnpm --filter @objectstack/platform-objects test` — 46 files, **647
passed** (628 before; +19 from the new ledger)
- `pnpm --filter @objectstack/platform-objects typecheck` — **exit 0**.
Its `tsconfig.test.json` program reaches the new file (`--listFiles`
names it; 46 of 46 of this package's test files are in that program) and
it contributes **0** errors — the only test-layer errors are the three
pre-existing signatures `test-typecheck-debt.json` already records for
`src/feature-gate-guard.test.ts`. The build config `tsconfig.json`
excludes `*.test.ts` by design, so it names the new file 0 times; that
is the shape, not a gap
- `pnpm check:i18n` — **green**, 9 packages in sync. Its first run
exited **3** (PREREQUISITE NOT MET), which is not a reading; cleared by
building the closure the gate itself names, then re-run green
- `pnpm lint` — repo-wide, `eslint . --no-inline-config`, **exit 0**, at
`edfef935d` (the head of this branch; no commit has landed on it since
that run)
- Gate families derived with `scripts/pm/dispatch-gates.mjs --repo
objectstack-ai/objectstack` and reconciled with `--ran` carrying every
exit code, each captured BEFORE any pipe: **60 derived · 59 run green ·
0 unrun · 1 NOT MEASURED** — `pnpm check:dual-build-cjs-loads` exits 3
(PREREQUISITE NOT MET: it reads built output for every package in the
repo and names twelve with no `dist/`). That prerequisite is a
whole-repo build, which is CI's `Build Core`, and this diff adds no
package and changes no export
- The first two derivations printed **STALE TREE** (4 commits behind
`origin/main`, 2 of the files the families are derived from changed
across that range). Discharged by merging `origin/main` and re-deriving
from the merged tree, not by waving it off; the re-derived list is
identical and the merge brought no change to
`packages/platform-objects/src/apps/translations/` and no lockfile
movement
## Changeset, measured
`@objectstack/platform-objects` declares no `private` and ships `files:
["dist", …]`, and `src/metadata-translations/index.ts` imports all three
translated bundles. Probed on the built output: four new leaves are
present in `dist/metadata-translations/index.js`, `dist/index.js`
**and** `dist/plugin.js` — 数据集 as `数据集`, 含める関係 as `含める関係`, `Capa
sem\xE1ntica de anal\xEDtica`, and the plain-ASCII `Relaciones a
incluir` — with two pre-existing translated leaves as positive controls
(度量, メジャー, 15 hits each) and two negative controls: an invented string
(**0**) and the **raw un-escaped** spelling of the same CJK strings
(**0**, including for the positive controls). ⇒ the diff publishes,
`skip-changeset` would be wrong, and a **`patch`** changeset is
included.
That probe is written to round 2's sharpened lesson and confirms both
halves of it in one run: esbuild emits **UPPER-CASE** hex in `\uXXXX`,
and `\xNN` for U+0080–U+00FF — `Capa semántica de analítica` is only
findable as `Capa sem\xE1ntica de anal\xEDtica`. The raw negative
control is in the probe so the next reader can see that a zero means
"escaped", not "absent".
## The six families that remain (38 label keys, all-three-locale echoes,
this base)
| family | keys |
|:--|--:|
| `object.fields.enable.*` (+ `validations`) — the object capabilities
panel | 9 |
| `field.fields.*` — the standalone field panel (several keys have a
precedent from round 1) | 9 |
| `action.fields.body.*` + `action.fields.ai` | 6 |
| metadata-type display names with no panel: `seed` · `mapping` · `api`
· `doc` · `book` · `capability` | 6 |
| `hook.fields.retryPolicy.*` + `hook.fields.body.memoryMb` +
`hook.fields.timeoutMs` | 5 |
| `report.fields.drilldown` + `report.fields.runtimeFilter` +
`report.sections.dataset_binding` | 3 |
The `dataset` type is now absent from the echo census **and** from the
`metadataForms.dataset.*` half of all three provenance tables — 0 rows
remain there, where 24 per locale stood on this base.
1 parent 22ca89f commit 72eeabd
8 files changed
Lines changed: 807 additions & 144 deletions
File tree
- .changeset
- packages/platform-objects/src/apps/translations
| 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 | + | |
Large diffs are not rendered by default.
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1475 | 1475 | | |
1476 | 1476 | | |
1477 | 1477 | | |
1478 | | - | |
1479 | | - | |
| 1478 | + | |
| 1479 | + | |
1480 | 1480 | | |
1481 | 1481 | | |
1482 | | - | |
1483 | | - | |
| 1482 | + | |
| 1483 | + | |
1484 | 1484 | | |
1485 | 1485 | | |
1486 | | - | |
1487 | | - | |
| 1486 | + | |
| 1487 | + | |
1488 | 1488 | | |
1489 | 1489 | | |
1490 | | - | |
1491 | | - | |
| 1490 | + | |
| 1491 | + | |
1492 | 1492 | | |
1493 | 1493 | | |
1494 | | - | |
1495 | | - | |
| 1494 | + | |
| 1495 | + | |
1496 | 1496 | | |
1497 | 1497 | | |
1498 | 1498 | | |
1499 | 1499 | | |
1500 | | - | |
1501 | | - | |
| 1500 | + | |
| 1501 | + | |
1502 | 1502 | | |
1503 | 1503 | | |
1504 | | - | |
1505 | | - | |
| 1504 | + | |
| 1505 | + | |
1506 | 1506 | | |
1507 | 1507 | | |
1508 | | - | |
1509 | | - | |
| 1508 | + | |
| 1509 | + | |
1510 | 1510 | | |
1511 | 1511 | | |
1512 | | - | |
1513 | | - | |
| 1512 | + | |
| 1513 | + | |
1514 | 1514 | | |
1515 | 1515 | | |
1516 | | - | |
1517 | | - | |
| 1516 | + | |
| 1517 | + | |
1518 | 1518 | | |
1519 | 1519 | | |
1520 | | - | |
1521 | | - | |
| 1520 | + | |
| 1521 | + | |
1522 | 1522 | | |
1523 | 1523 | | |
1524 | | - | |
1525 | | - | |
| 1524 | + | |
| 1525 | + | |
1526 | 1526 | | |
1527 | 1527 | | |
1528 | 1528 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
36 | 36 | | |
37 | 37 | | |
38 | 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 | 39 | | |
64 | 40 | | |
65 | 41 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1475 | 1475 | | |
1476 | 1476 | | |
1477 | 1477 | | |
1478 | | - | |
1479 | | - | |
| 1478 | + | |
| 1479 | + | |
1480 | 1480 | | |
1481 | 1481 | | |
1482 | | - | |
1483 | | - | |
| 1482 | + | |
| 1483 | + | |
1484 | 1484 | | |
1485 | 1485 | | |
1486 | | - | |
1487 | | - | |
| 1486 | + | |
| 1487 | + | |
1488 | 1488 | | |
1489 | 1489 | | |
1490 | | - | |
1491 | | - | |
| 1490 | + | |
| 1491 | + | |
1492 | 1492 | | |
1493 | 1493 | | |
1494 | | - | |
1495 | | - | |
| 1494 | + | |
| 1495 | + | |
1496 | 1496 | | |
1497 | 1497 | | |
1498 | 1498 | | |
1499 | 1499 | | |
1500 | | - | |
1501 | | - | |
| 1500 | + | |
| 1501 | + | |
1502 | 1502 | | |
1503 | 1503 | | |
1504 | | - | |
1505 | | - | |
| 1504 | + | |
| 1505 | + | |
1506 | 1506 | | |
1507 | 1507 | | |
1508 | | - | |
1509 | | - | |
| 1508 | + | |
| 1509 | + | |
1510 | 1510 | | |
1511 | 1511 | | |
1512 | | - | |
1513 | | - | |
| 1512 | + | |
| 1513 | + | |
1514 | 1514 | | |
1515 | 1515 | | |
1516 | | - | |
1517 | | - | |
| 1516 | + | |
| 1517 | + | |
1518 | 1518 | | |
1519 | 1519 | | |
1520 | | - | |
1521 | | - | |
| 1520 | + | |
| 1521 | + | |
1522 | 1522 | | |
1523 | 1523 | | |
1524 | | - | |
1525 | | - | |
| 1524 | + | |
| 1525 | + | |
1526 | 1526 | | |
1527 | 1527 | | |
1528 | 1528 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
36 | 36 | | |
37 | 37 | | |
38 | 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 | 39 | | |
64 | 40 | | |
65 | 41 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1475 | 1475 | | |
1476 | 1476 | | |
1477 | 1477 | | |
1478 | | - | |
1479 | | - | |
| 1478 | + | |
| 1479 | + | |
1480 | 1480 | | |
1481 | 1481 | | |
1482 | | - | |
1483 | | - | |
| 1482 | + | |
| 1483 | + | |
1484 | 1484 | | |
1485 | 1485 | | |
1486 | | - | |
1487 | | - | |
| 1486 | + | |
| 1487 | + | |
1488 | 1488 | | |
1489 | 1489 | | |
1490 | | - | |
1491 | | - | |
| 1490 | + | |
| 1491 | + | |
1492 | 1492 | | |
1493 | 1493 | | |
1494 | | - | |
1495 | | - | |
| 1494 | + | |
| 1495 | + | |
1496 | 1496 | | |
1497 | 1497 | | |
1498 | 1498 | | |
1499 | 1499 | | |
1500 | | - | |
1501 | | - | |
| 1500 | + | |
| 1501 | + | |
1502 | 1502 | | |
1503 | 1503 | | |
1504 | | - | |
1505 | | - | |
| 1504 | + | |
| 1505 | + | |
1506 | 1506 | | |
1507 | 1507 | | |
1508 | | - | |
1509 | | - | |
| 1508 | + | |
| 1509 | + | |
1510 | 1510 | | |
1511 | 1511 | | |
1512 | | - | |
1513 | | - | |
| 1512 | + | |
| 1513 | + | |
1514 | 1514 | | |
1515 | 1515 | | |
1516 | | - | |
1517 | | - | |
| 1516 | + | |
| 1517 | + | |
1518 | 1518 | | |
1519 | 1519 | | |
1520 | | - | |
1521 | | - | |
| 1520 | + | |
| 1521 | + | |
1522 | 1522 | | |
1523 | 1523 | | |
1524 | | - | |
1525 | | - | |
| 1524 | + | |
| 1525 | + | |
1526 | 1526 | | |
1527 | 1527 | | |
1528 | 1528 | | |
| |||
0 commit comments