fix(soma): decisión 12 — las fuentes de segmento se registran, la mano muere y chronos deja de esconder su contrato

RECONCILIAR (bloque L3): los dos instrumentos decían cosas contrarias sobre
el MISMO (parte, attr) y ambos tenían razón sobre elementos distintos — el
segmento de CANAL llevaba los attrs escritos a mano, y el segmento `literal`
(el #, la coma, el paréntesis del valor formateado) es un separador inerte
que no los lleva; la cosecha, midiendo instancia a instancia, los contaba
ausentes. No era defecto de emisión: era defecto de DECLARACIÓN.

Ejecutado en el ORDEN firmado, que no es negociable: (1) registrar las
fuentes en la parte `segment` de color-field, date-field y time-field; (2)
sólo entonces la condición prop-defined significa lo que dice y distingue el
separador del canal; (3) hecho eso, morir la mano (getAriaProps) y emitir la
bolsa (ley P0). Al revés, la condición habría quedado como guarda
permanentemente falsa silenciando el síntoma.

UNCERTAIN (chronos): de las 6 filas estampadas, 4 se habían disuelto ya con
la retirada de espejos (216ac0116). Las 3 supervivientes tenían fuentes que
EXISTEN pero que ningún AST podía ver, porque llegaban por un spread dinámico
(`Object.fromEntries(Object.keys(sources())...)`) — la misma enfermedad que
el strip del attr identificador que cerró la fila cero: maquinaria que
esconde el contrato al instrumento. Ahora registra ESTÁTICAMENTE.

ATRIBUCIÓN DECLARADA (precedente 8ac23047f / 1cb07c1e1): este commit lleva
`src/uix/morfo/source-census.test.ts`, que es del eje de vicen-e1. Viaja aquí
porque sus cifras SÓLO son verdad con este lote dentro (firmarlas en un
commit ajeno dejaría su instrumento mintiendo por un desfase), y porque el
registro estático de chronos MATA la premisa de uno de sus asertos — el que
exigía que la bolsa objetivo fuera opaca. La adaptación (inyectar un opaco
sintético y comprobar que el CONTADOR se mueve, en relativo `+1` para no
convertir una cifra honesta en un gate que nadie firmó) la revisó línea a
línea y la FIRMÓ POR ESCRITO vicen-e1, dueño del fichero, que además la
prefiere a la que tenía prescrita. Lo que se pierde y se acepta: el aserto
viejo era además un canario de fixture; se pierde el canario, no el guard.
Declarado por ellos y por mí: un ±1 en las cifras de cabecera que PRECEDE a
este lote queda anotado en el fichero para que lo midan sobre árbol limpio.

Gate entero VERDE con la ola dentro: 443 ficheros / 5224 tests.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
alpha-0.1-background
dev 1 month ago
parent c1f5b49253
commit cb70927e92

@ -53,6 +53,18 @@ import type { Morfo, MorfoCondition, MorfoPart, MorfoValueSource } from './types
* (749→763 — 9 rows, 11 registrations, because `treeView` feeds the pair on
* `branch` AND on `item`).
*
* AND WHAT IT MEASURES AFTER decision 12(a) (2026-08-27, the L3 block + the
* chronos lane): 789 keys (75 / 653 / 61), 0 unreadable ⇒ the same 20 orphans
* and 0 dead per-part, advisory cube 34 = 3 (c1a) / 15 (c1b) / 16 (c2). The
* key count moved once more, +25 (764→789): +20 for the 15 L3 rows registered
* across color-field / date-field / time-field (five registrations feed
* `segment`, one per occurrence) and +5 for chronos' Region keys, which the
* AST could not see while they arrived through a spread. Two figures inherited
* from the paragraph above did not reconcile when this lot opened, and saying
* so is cheaper than a silent correction: a run printed 764 keys (628 props)
* against the 763 (627) documented, and (c1a) 5 against the 6 — a ±1 that
* predates this lot and belongs to a movement it did not make.
*
* The two lanes moved DIFFERENT halves of the cube, and only one of them is
* pinned by a key count. FUENTES took (c1b) 55 → 37 and lifted `tooltip.disabled`
* out of (c1a) — every one of those 19 rows is a registered source, so the +20
@ -83,14 +95,19 @@ import type { Morfo, MorfoCondition, MorfoPart, MorfoValueSource } from './types
* `types.ts` is the file under declared contention.
* 2. The flip to a BIDIRECTIONAL gate — also REQUIRING the source, the shape
* `SomaRuntimeDirSource<M>` already uses for `dir` — happens after the
* author adjudicates the harvest below, never before. Today the (c) cube
* is 53 rows: demanding a source would be a migration, not a gate. And
* THREE of those rows are stamped UNCERTAIN — a cube that still hides an
* opaque bag is not an adjudicable harvest yet. All three are chronos',
* all three ride the SAME opaque registration, and the cube prints them as
* `chronosMorfo.props.value` (`components/chronos.ts:464`),
* author adjudicates the harvest below, never before. The cube was 53 rows
* when this was written and is 34 today: demanding a source would still be
* a migration, not a gate. THE UNCERTAIN STAMP IS GONE, and with it the
* blocker this paragraph named — a cube that still hides an opaque bag is
* not an adjudicable harvest yet. The three rows that carried it were all
* chronos', all riding the SAME opaque registration, and the cube printed
* them as `chronosMorfo.props.value` (`components/chronos.ts:464`),
* `chronosMorfo.props.minute` (`:680`) and `chronosMorfo.props.slotLabel`
* (`:684`). This line read SIX until 2026-08-27, when it was measured
* (`:684`). Decision 12(a) (2026-08-27) cured the CAUSE, not the rows:
* `soma/components/chronos/chronos-provider.svelte.ts:1519` names the
* Region's five source keys one by one instead of spreading them, the AST
* reads them, and all three left the cube REGISTERED — the DOM did not
* move. This line read SIX until 2026-08-27, when it was measured
* again: a header contradicted by its own output is the instrument lying
* first, so the figure here is the one a run prints — never the one the
* last note remembered. THE SIX WAS HONEST WHEN IT WAS WRITTEN, and the
@ -506,9 +523,13 @@ interface Census {
* suspiciously round one: it read 0 until 2026-08-27 not because the corpus
* was transparent but because the only opaque bag in the tree sat behind a
* `part(K, …)` the scan refused to enter — the counter certified a coverage
* the blind spot had already voided. It counts 1 today: chronos' `Region`
* spreads `Object.fromEntries(Object.keys(sources())…)`. Every (c) row of a
* morfo with an opaque registration is stamped UNCERTAIN for that reason.
* the blind spot had already voided. Then it read 1: chronos' `Region`
* spreading `Object.fromEntries(Object.keys(sources())…)`. It reads 0 again
* since decision 12(a) named that bag's five keys one by one — and THIS zero
* is earned, not certified: the blind spot that made the first one false is
* closed (the scan enters `part(K, …)`), and the negative below proves the
* counter still bites by injecting an opaque bag in memory. Every (c) row of
* a morfo with an opaque registration is stamped UNCERTAIN for that reason.
*/
readonly unreadable: number;
}
@ -886,10 +907,24 @@ describe('source census — every registered source has a reader, and every read
target,
'chronos registers on a part whose kebab is a variable — the fixture this negative needs'
).toBeDefined();
// The assertion that used to stand here — «and its bag is opaque» — read a
// LIVE spread on this very registration. Decision 12(a) (2026-08-27) named
// chronos' five Region keys one by one, so the fixture is gone and the tree
// answers `unreadable=0`. The counter it guarded is pinned SYNTHETICALLY
// instead, exactly the way the 7(a) negative below pins a law no live entry
// carries: inject the unreadable key in memory and watch the counter move.
// Relative, not absolute — the mutation is the only difference, and pinning
// the tree's own figure would turn an honest number into a gate nobody
// signed.
const opaque = classify(
registrations.map((reg) =>
reg === target ? { ...reg, props: [...reg.props, `${UNREADABLE}spread`] } : reg
)
);
expect(
target?.props,
'and its bag is opaque — the coverage counter must have something to count'
).toContain(`${UNREADABLE}spread`);
opaque.unreadable,
'the coverage counter must still count an opaque bag when one lands'
).toBe(census.unreadable + 1);
const bitten = classify(
registrations.map((reg) =>
reg === target ? { ...reg, props: [...reg.props, 'redonly'] } : reg

@ -1512,17 +1512,31 @@ export class ChronosRegionProvider {
// DOES declare makes the attr vanish silently, which is how the
// time-grid lost its accessible name in this very pass.
//
// `sources` carries the PER-INSTANCE values a repeated part needs
// (`day-number`'s value, `agenda-group`'s date + label). A thunk,
// not a snapshot: the runtime re-reads it, so the attrs stay
// `sources` carries the PER-INSTANCE values a repeated part needs. A
// thunk, not a snapshot: the runtime re-reads it, so the attrs stay
// reactive as the month changes underneath.
//
// NAMED ONE BY ONE, never spread (decision 12(a), 2026-08-27). This bag
// used to be `...Object.fromEntries(Object.keys(sources())…)`, which no
// AST can read: the source census counted it as ONE unreadable key and
// stamped every chronos row UNCERTAIN — «a suspicion, not a finding» —
// because a spread may or may not already feed the ref the cube is
// complaining about. It is the same illness as the stripped identifier
// attr that closed row zero: machinery that hides the contract from the
// instrument. The five keys below are the closed set the morfo reads
// off a Region (`morfo/components/chronos.ts:434` `date`, `:444`/`:736`
// `dateLabel`, `:464` `value`, `:680` `minute`, `:684` `slotLabel`); a
// Region whose caller passes none of them resolves them to `undefined`
// and the attrs drop, exactly as the absent key did.
props: {
readonly: () => this.provider.opts.readonly.current,
disabled: () => this.provider.opts.disabled.current,
ariaLabel: () => this.provider.effectiveAriaLabel,
...Object.fromEntries(
Object.keys(sources()).map((key) => [key, () => sources()[key]])
)
date: () => sources().date,
dateLabel: () => sources().dateLabel,
value: () => sources().value,
minute: () => sources().minute,
slotLabel: () => sources().slotLabel
}
});
// The grid's `aria-labelledby` points HERE by partRef, so the id has to

@ -593,12 +593,17 @@ abstract class BaseColorSegmentProvider {
ref: opts.ref,
owner: this,
// Per-part sources for the morfo's aria-disabled (ariaBoolean) +
// aria-invalid (literal gated on `invalid`). aria-readonly stays a soma
// override (per-segment readonly the propRef can't model); the value/min/
// max/label aria are computed in getAriaProps and override the morfo too.
// aria-invalid (literal gated on `invalid`), and for the three
// value-bearing refs whose `prop-defined` condition separates a CHANNEL
// from the `literal` separator (which registers none of them).
// aria-readonly stays a soma override (per-segment readonly the propRef
// can't model); `value` stays hand-written — see `getAriaProps`.
props: {
disabled: () => this.provider.isDisabled,
invalid: () => this.provider.isInvalid
invalid: () => this.provider.isInvalid,
segmentLabel: () => `${this.provider.getSegmentLabel(this.part)}, `,
min: () => this.config.min,
max: () => this.config.max
}
});
}
@ -737,10 +742,26 @@ abstract class BaseColorSegmentProvider {
this.provider.states[this.part].hasLeftFocus = true;
};
/**
* What the render bag CANNOT emit yet, and why it is still a hand.
*
* `aria-valuenow` and `aria-valuetext` are declared over the SAME ref —
* `v.propRef('value')` twice (`morfo/components/color-field.ts:171` and
* `:176`) — while the two attrs need different values: the parsed NUMBER vs
* the formatted string (`#aabbcc`, `50%`, or the "empty" label, which the
* number does not have at all). One source could only lie in one direction
* or the other. It is the shape `c0c03818c` cured for css-field by splitting
* the ref (`aria-valuenow ← propRef('valueNumber')`); until color-field's
* declaration gets the same split, registering `value` would be a
* regression, so the pair stays here.
*
* `aria-labelledby` is the Label part's id — parity with date-field /
* time-field segments, so a screen reader announces the group name
* ("Color") alongside the per-segment label ("Red").
*/
protected getAriaProps() {
const value = this.provider.segmentValues[this.part];
const isEmpty = value === null || value === undefined;
const cfg = this.config;
const valueNow = isEmpty ? undefined : (this.parse(value as string) ?? undefined);
const valueText = isEmpty
? this.provider.langs(COLOR_FIELD_LANGS.EMPTY)
@ -750,13 +771,7 @@ abstract class BaseColorSegmentProvider {
? `${valueNow ?? ''}%`
: `${valueNow ?? ''}`;
return {
'aria-label': `${this.provider.getSegmentLabel(this.part)}, `,
// Reference the Label part's id when present, for parity with
// date-field / time-field segments. Screen readers announce the
// group name ("Color") alongside the per-segment label ("Red").
'aria-labelledby': this.provider.labelNode?.id || undefined,
'aria-valuemin': cfg.min,
'aria-valuemax': cfg.max,
'aria-valuenow': valueNow,
'aria-valuetext': valueText
};
@ -767,9 +782,10 @@ abstract class BaseColorSegmentProvider {
const isReadonly = this.provider.isReadonly || this.provider.readonlySegmentsSet.has(this.part);
return this.runtimePart.assert({
// Morfo supplies role=spinbutton + aria-disabled (ariaBoolean) +
// aria-invalid (resolved against the registered flags). The computed
// aria below (value/min/max/label/labelledby) overrides the morfo's raw
// propRef defaults; aria-readonly is a per-segment soma override.
// aria-invalid + aria-label / aria-valuemin / aria-valuemax, resolved
// against the sources registered above. The computed aria below
// (valuenow/valuetext/labelledby) overrides the morfo's raw propRef
// defaults; aria-readonly is a per-segment soma override.
...this.runtimePart.props,
...this.provider.sharedSegmentAttrs,
// Soma-owned data-* — the morfo declares these without a value source.

@ -1095,13 +1095,26 @@ abstract class BaseNumericSegmentProvider {
) {
this.opts = opts;
this.provider = DateFieldProvider.require();
// Assigned BEFORE the registration: the sources below close over both.
this.part = part;
this.config = config;
this.runtimePart = this.provider.runtime.part('segment', {
id: opts.id,
ref: opts.ref,
owner: this
owner: this,
// Per-part sources for the morfo's value-bearing aria. Registering them
// is what gives the `prop-defined` conditions something to distinguish:
// this occurrence is a CHANNEL, the `literal` separator below registers
// only `segment` and so publishes none of these.
props: {
segment: () => part,
segmentLabel: () => `${this.provider.getSegmentLabel(this.part)}, `,
min: () => this.getMin(),
max: () => this.getMax(),
value: () => this.segmentValue().now,
valueText: () => this.segmentValue().text
}
});
this.part = part;
this.config = config;
}
get announcer(): Announcer {
@ -1333,7 +1346,14 @@ abstract class BaseNumericSegmentProvider {
}
};
getSegmentProps() {
/**
* The two values the morfo's `value` / `valueText` refs NAME — computed here
* and registered as sources, the `aria-rowindex` precedent: the ref names
* what the provider computes, and the render bag stamps it. `now` never goes
* undefined (an empty segment still publishes the placeholder's number);
* only the TEXT says "empty".
*/
private segmentValue(): { now: number; text: string } {
const segmentValues = this.provider.segmentValues;
const placeholder = this.provider.opts.placeholder.current;
const value = (segmentValues as Record<string, unknown>)[this.part];
@ -1344,31 +1364,20 @@ abstract class BaseNumericSegmentProvider {
date = placeholder.set({ [this.part]: Number.parseInt(value as string) });
}
const valueNow = (date as unknown as Record<string, number>)[this.part];
const valueMin = this.getMin();
const valueMax = this.getMax();
let valueText = isEmpty ? this.provider.getEmptyLabel() : `${valueNow}`;
const now = (date as unknown as Record<string, number>)[this.part];
let text = isEmpty ? this.provider.getEmptyLabel() : `${now}`;
if (this.part === 'hour' && 'dayPeriod' in segmentValues && segmentValues.dayPeriod) {
valueText = isEmpty
? this.provider.getEmptyLabel()
: `${valueNow} ${segmentValues.dayPeriod}`;
text = isEmpty ? this.provider.getEmptyLabel() : `${now} ${segmentValues.dayPeriod}`;
}
return {
'aria-label': `${this.provider.getSegmentLabel(this.part)}, `,
'aria-valuemin': valueMin,
'aria-valuemax': valueMax,
'aria-valuenow': valueNow,
'aria-valuetext': valueText
};
return { now, text };
}
readonly props = $derived.by(() =>
this.runtimePart.assert({
...this.provider.sharedSegmentAttrs,
...this.runtimePart.props,
...this.getSegmentProps(),
...this.provider.getBaseSegmentAttrs(
this.part as SegmentPart,
this.opts.id.current,
@ -1582,7 +1591,12 @@ class DateFieldDayPeriodSegmentProvider {
owner: this,
onRefChange: (v) => {
this.provider.dayPeriodNode = v;
}
},
// The discriminator the `aria-hidden` condition reads. Declared on EVERY
// segment occurrence on purpose: an unregistered key and a channel that
// simply is not the separator resolve the same way, so leaving it out
// would make a typo indistinguishable from a legitimately false branch.
props: { segment: () => 'dayPeriod' }
});
}
@ -1680,14 +1694,18 @@ class DateFieldLiteralSegmentProvider {
this.runtimePart = this.provider.runtime.part('segment', {
id: opts.id,
ref: opts.ref,
owner: this
owner: this,
// The ONE source the morfo's `aria-hidden` condition reads
// (`prop-equals segment: 'literal'`). Registering it is what turns that
// condition from a permanently-false guard into the discriminator it
// declares itself to be — and it retires the hand-written stamp.
props: { segment: () => 'literal' }
});
}
readonly props = $derived.by(() =>
this.runtimePart.assert({
...this.runtimePart.props,
'aria-hidden': 'true' as const,
...this.provider.getBaseSegmentAttrs(
'literal',
this.opts.id.current,
@ -1708,7 +1726,10 @@ class DateFieldTimeZoneSegmentProvider {
this.runtimePart = this.provider.runtime.part('segment', {
id: opts.id,
ref: opts.ref,
owner: this
owner: this,
// See the day-period registration: the discriminator is declared on
// every occurrence, never left to absence.
props: { segment: () => 'timeZoneName' }
});
}

@ -699,7 +699,19 @@ export abstract class BaseTimeNumericSegmentProvider {
this.runtimePart = this.provider.runtime.part('segment', {
id: opts.id,
ref: opts.ref,
owner: this
owner: this,
// Per-part sources for the morfo's value-bearing aria. Registering them
// is what gives the `prop-defined` conditions something to distinguish:
// this occurrence is a CHANNEL, the `literal` separator registers only
// `segment` and so publishes none of these.
props: {
segment: () => part,
segmentLabel: () => `${this.provider.getSegmentLabel(this.part)}, `,
min: () => this.getMin(),
max: () => this.getMax(),
value: () => this.segmentValue().now,
valueText: () => this.segmentValue().text
}
});
}
@ -878,44 +890,41 @@ export abstract class BaseTimeNumericSegmentProvider {
}
};
getSegmentProps() {
/**
* The two values the morfo's `value` / `valueText` refs NAME — computed here
* and registered as sources, the `aria-rowindex` precedent: the ref names
* what the provider computes, and the render bag stamps it. `now` goes
* undefined on an empty segment (the attr drops); only the TEXT says "empty".
*/
private segmentValue(): { now: number | undefined; text: string } {
const value = this.provider.segmentValues[this.part];
const isEmpty = value === null || value === undefined;
const valueNow = isEmpty ? undefined : Number.parseInt(value as string);
const valueMin = this.getMin();
const valueMax = this.getMax();
let valueText = isEmpty ? this.provider.getEmptyLabel() : `${valueNow}`;
const now = isEmpty ? undefined : Number.parseInt(value as string);
let text = isEmpty ? this.provider.getEmptyLabel() : `${now}`;
if (this.part === 'hour' && this.provider.resolvedHourCycle === 12) {
const dp = (this.provider.segmentValues as TimeSegmentObj).dayPeriod;
valueText = isEmpty ? this.provider.getEmptyLabel() : `${valueNow} ${dp ?? 'AM'}`;
text = isEmpty ? this.provider.getEmptyLabel() : `${now} ${dp ?? 'AM'}`;
}
return {
'aria-label': `${this.provider.getSegmentLabel(this.part)}, `,
'aria-valuemin': valueMin,
'aria-valuemax': valueMax,
'aria-valuenow': valueNow,
'aria-valuetext': valueText
};
return { now, text };
}
readonly props = $derived.by(() => {
const p = this.getSegmentProps();
const isReadonly = this.provider.isReadonly || this.provider.readonlySegmentsSet.has(this.part);
return this.runtimePart.assert({
// Morfo-declared attrs (role=spinbutton, aria-disabled, aria-invalid),
// resolved against the component-level sources — no longer re-declared.
// Morfo-declared attrs (role=spinbutton, aria-disabled, aria-invalid and
// the value-bearing aria), resolved against the sources registered above
// — no longer re-declared here.
...this.runtimePart.props,
...this.provider.sharedSegmentAttrs,
// Soma-only: data-* are morfo-declared WITHOUT a value; the value-aria
// (`...p`), per-segment aria-readonly and aria-labelledby are computed
// here and override the morfo's raw declaration.
// Soma-only: data-* are morfo-declared WITHOUT a value; per-segment
// aria-readonly and aria-labelledby are computed here and override the
// morfo's raw declaration.
'data-segment': this.part,
'data-placeholder': boolToEmptyStrOrUndef(this.provider.segmentValues[this.part] === null),
'data-invalid': boolToEmptyStrOrUndef(this.provider.isInvalid),
'data-disabled': boolToEmptyStrOrUndef(this.provider.isDisabled),
'data-readonly': boolToEmptyStrOrUndef(isReadonly),
'aria-readonly': boolToStr(isReadonly),
...p,
'aria-labelledby': this.provider.getLabelledBy(this.opts.id.current),
onkeydown: this.onkeydown,
onfocusout: this.onfocusout
@ -959,7 +968,12 @@ export class TimeFieldDayPeriodSegmentProvider {
owner: this,
onRefChange: (v) => {
this.provider.dayPeriodNode = v;
}
},
// The discriminator the `aria-hidden` condition reads. Declared on EVERY
// segment occurrence on purpose: an unregistered key and a channel that
// simply is not the separator resolve the same way, so leaving it out
// would make a typo indistinguishable from a legitimately false branch.
props: { segment: () => 'dayPeriod' }
});
}
@ -1050,14 +1064,18 @@ export class TimeFieldLiteralSegmentProvider {
this.runtimePart = provider.runtime.part('segment', {
id: opts.id,
ref: opts.ref,
owner: this
owner: this,
// The ONE source the morfo's `aria-hidden` condition reads
// (`prop-equals segment: 'literal'`). Registering it is what turns that
// condition from a permanently-false guard into the discriminator it
// declares itself to be — and it retires the hand-written stamp.
props: { segment: () => 'literal' }
});
}
readonly props = $derived.by(() =>
this.runtimePart.assert({
...this.runtimePart.props,
'aria-hidden': 'true' as const,
'data-segment': 'literal' as const
} as const)
);
@ -1080,7 +1098,10 @@ export class TimeFieldTimeZoneSegmentProvider {
this.runtimePart = this.provider.runtime.part('segment', {
id: opts.id,
ref: opts.ref,
owner: this
owner: this,
// See the day-period registration: the discriminator is declared on
// every occurrence, never left to absence.
props: { segment: () => 'timeZoneName' }
});
}

@ -61,8 +61,23 @@ const MIGRATED_CEILINGS: Record<string, number> = {
// trio it already shared this ceiling with. No new hardcoded attr — the write
// predates the wave and stays for the reason above; only the morfo's blindness
// to it was retired.
'date-field': 10, // input composites + segment (multi-archetype, deferred)
'time-field': 13, // input composites + segment (multi-archetype, deferred)
//
// −1 each on 2026-08-27 (decision 12(a), the L3 block): that same
// `aria-hidden` is now EMITTED by the bag. Its condition
// (`prop-equals segment: 'literal'`) had no source at all, so it was a
// permanently-false guard next to a hand-written stamp; the literal segment
// provider registers `segment` and the stamp is retired. Measured before and
// after — 10 → 9 and 13 → 12, the only ceilings this lot moved. Re-pinned in
// the same movement because the guard fails by EXCESS only: leaving 10/13
// over 9/12 hits would pass in green while permitting the stamp straight
// back. The value trio the numeric segments wrote (`aria-label` /
// `aria-valuemin` / `aria-valuemax` / `aria-valuenow` / `aria-valuetext`)
// also moved to the bag in this lot and moved NOTHING here: those writes sat
// in a helper OUTSIDE `.assert({…})`, which the auditor does not read. The
// hits still listed under `segment` are the day-period / time-zone
// occurrences, whose own writes this lot did not touch.
'date-field': 9, // input composites + segment (multi-archetype, deferred)
'time-field': 12, // input composites + segment (multi-archetype, deferred)
'color-picker': 4, // computed aria-labels (trigger/thumb/swatch/eyedropper)
'date-picker': 0,
'date-range-picker': 0,

Loading…
Cancel
Save

Powered by TurnKey Linux.