an.timing.contract#
The timing kernel’s cross-language contract: five JSON files, generated from the registries.
The contract lives in an/data/timing/ (shipped in the wheel) and is what any
other implementation of the kernel — the TypeScript one, a package that copies
an’s track format — copies and asserts:
|
every registered easing (name, version, family, solver) with sample values, plus parametrised examples |
|
every field kind with sample interpolations, and the seeded property spaces |
|
the authored flat timeline |
|
tracks, placed clips, loop modes, channels — the
compiled form |
|
compiled documents and the state at listed times |
Numbers agree within 1e-9 * max(1, |x|, |y|); strings, booleans,
null, list lengths and object keys agree exactly. A state is SPARSE: an
address no clip has started writing is absent (at rest).
The files are regenerated by python -m an.timing.contract write and checked
by python -m an.timing.contract check (a test runs the check). Regenerating
is a deliberate act: a change to a committed sample is a change of the contract.
>>> doc = {"timeline": {"duration": 1.0, "tracks": [{"clips": [
... {"animation_id": "m", "start_time": 0.0}]}]},
... "animations": {"m": {"duration": 1.0, "channels": [{"target": "cam",
... "property": "yaw", "keyframes": [{"time": 0.0, "value": 350.0},
... {"time": 1.0, "value": 10.0}]}]}}}
>>> space = {"fields": [{"pattern": "yaw", "spec": {"kind": "angle"}}]}
>>> state_at(doc, 0.5, space=space)
{'cam:yaw': 360.0}
Module Attributes
Where the committed contract files live (inside the package, so they ship). |
|
The cases whose space is the value-typed rule's write-group space are ALSO evaluated with |
|
a uniform grid, plus points that reach the solvers' fallbacks (near the ends, and around the middle of a curve whose slope vanishes there, e.g. cubic-bezier(1, 0, 0, 1)). |
|
Parametrised specs the easing file samples, beside the named entries. |
|
How a CSS-named document's names map onto this registry where the name means something else here. |
|
The address grammar as a regular expression (the parser is |
Functions
|
|
Every contract file's content, by file name, generated from the registries. |
|
|
|
|
|
|
|
|
|
|
Every sample of |
|
How the committed files differ from what the registries generate today. |
|
The committed text of a contract file (stable, diffable). |
|
|
|
|
|
A vector case's |
|
The sparse state of compiled document |
|
The contract's comparison (see the module docstring). |
|
Regenerate every contract file under |
- an.timing.contract.ADDRESS_PATTERN: str = '^[^:/@\\s](?:[^:/@]*[^:/@\\s])?(?:/[^:/@\\s](?:[^:/@]*[^:/@\\s])?)*:[^:/@.\\s](?:[^:/@.]*[^:/@.\\s])?(?:\\.[^:/@.\\s](?:[^:/@.]*[^:/@.\\s])?)*(?:@[^:/@\\s](?:[^:/@]*[^:/@\\s])?)?$'#
The address grammar as a regular expression (the parser is
an.timing.address).
- an.timing.contract.CONTRACT_DIR: Path = PosixPath('/home/runner/work/an/an/an/data/timing')#
Where the committed contract files live (inside the package, so they ship).
- an.timing.contract.CSS_IMPORT_ALIASES: dict[str, str] = {'ease': 'cubic-bezier(0.25, 0.1, 0.25, 1)'}#
How a CSS-named document’s names map onto this registry where the name means something else here.
easeisan’s quadratic (ADR 0001 decision 10, amended 2026-10-01); a CSS document’seaseis this spec.
- an.timing.contract.PARAMETRIC_EXAMPLES: tuple[Any, ...] = ('cubic-bezier(0.25, 0.1, 0.25, 1)', 'cubic-bezier(0.5, -0.8, 0.5, 1.8)', 'cubic-bezier(0.3, 1.8, 0.7, -0.8)', 'steps(4)', 'steps(4, jump-start)', 'steps(3, jump-none)', 'steps(2, jump-both)', 'steps(2, start)', 'cubic-bezier(1, 0, 0, 1)', [0.42, 0.0, 0.58, 1.0], [0.5, 2.0, 0.5, 2.0], [0.3, 3.0, 0.7, 0.0], [1.0, 0.0, 0.0, 1.0], [0.42, 0.0, 1.0, 1.0], [0.0, 0.0, 0.58, 1.0])#
Parametrised specs the easing file samples, beside the named entries.
- an.timing.contract.REL_TOL: float = 1e-09#
|x - y| <= REL_TOL * max(1, |x|, |y|).
- Type:
The contract’s tolerance
- an.timing.contract.SOLVER_PROBE_U: tuple[float, ...] = (1e-06, 0.4, 0.501, 0.999999)#
a uniform grid, plus points that reach the solvers’ fallbacks (near the ends, and around the middle of a curve whose slope vanishes there, e.g. cubic-bezier(1, 0, 0, 1)).
- Type:
Where every easing is sampled
- an.timing.contract.VALUE_TYPED_CASE_SPACE: str = 'stage.node'#
The cases whose space is the value-typed rule’s write-group space are ALSO evaluated with
space=VALUE_TYPED— the ruleruntime.jsimplements — so both rules are held to the same numbers (the default,space=None, is the declared rule since an#239 item 2).
- an.timing.contract.build_contract()[source]#
Every contract file’s content, by file name, generated from the registries.
- an.timing.contract.check_vectors(vectors=None)[source]#
Every sample of
vectors(default: the committed file) thatan.timingdoes not reproduce, as one line each. Empty means the kernel meets the contract.Both evaluation rules are held: every case under its declared space, and every
stage.nodecase also under the value-typed rule (space=VALUE_TYPED).
- an.timing.contract.contract_drift(directory=PosixPath('/home/runner/work/an/an/an/data/timing'))[source]#
How the committed files differ from what the registries generate today.
Numbers compare with the contract’s tolerance, because a transcendental function (
exp,sin,pow) may differ in its last bit across platforms’ maths libraries; anything else must match exactly.
- an.timing.contract.dumps(obj)[source]#
The committed text of a contract file (stable, diffable).
- Return type:
- an.timing.contract.main(argv=None)[source]#
python -m an.timing.contract [write|check].- Return type:
- an.timing.contract.resolve_space(space)[source]#
A vector case’s
space: a registered space’s name, or its JSON form.- Return type:
- an.timing.contract.state_at(doc, t, *, space)[source]#
The sparse state of compiled document
docatt, keyed by address.