Šķîþ ţö ḿàîñ çöñţéñţ

Çöñţéñţ ƃüñđļé (.kbf.json)

Ţĥé çöñţéñţ ƃüñđļé îš ţĥé ĴŠÖÑ šéŕîàļîžàţîöñ öƒ neokapi'š çöñţéñţ ḿöđéļ: à šéţ öƒ Documentš, éàçĥ ĥöļđîñĝ Blockš ŵĥöšé çöñţéñţ îš à ƒļàţ šéǫüéñçé öƒ Runš, ŵîţĥ öþţîöñàļ þéŕ-ļöçàļé targets. Îţš ḿàŕķéŕ šéĝḿéñţ àñđ Ĝö þàçķàĝé àŕé ƃöţĥ kbf, ƒöŕ Kapi Ƃüñđļé Ƒöŕḿàţ.

Ţĥîš þàĝé îš ţĥé ñöŕḿàţîṽé šçĥéḿà, ƒöļļöŵéđ ƃý ŵöŕķéđ éẋàḿþļéš öƒ éṽéŕý ŕüñ ķîñđ. Ƒöŕ ŵĥéŕé ţĥé ƃüñđļé šîţš àḿöñĝ kapi'š öţĥéŕ ƒöŕḿàţš, šţàŕţ ŵîţĥ ţĥé öṽéŕṽîéŵ.

Ŵĥàţ îţ îš ñöţ ƒöŕ

À çöñţéñţ ƃüñđļé îš àñ àüţĥöŕîñĝ àñđ éẋçĥàñĝé ƒöŕḿàţ, ñöţ à ŕüñţîḿé çàţàļöĝ. Îţ îš îñţéñţîöñàļļý ĥéàṽý: îţ çàŕŕîéš ţĥé đàţà šĥàþé ţĥàţ ļéţš ţŕàñšļàţöŕš ŵöŕķ, ţĥàţ ţööļš ŕöüñđ-ţŕîþ, àñđ ţĥàţ à ŕéṽîéŵ þļàţƒöŕḿ çàñ þéŕšîšţ. Ţĥàţ ŕîçĥñéšš îš ŵàšţé àţ ŕüñţîḿé, ŵĥéŕé ţĥé öñļý öþéŕàţîöñ îš (scope, source) → translated. Çöḿþîļé îţ đöŵñ ţö àñ éšţàƃļîšĥéđ ŕüñţîḿé çàţàļöĝ ƒöŕḿàţ (ĝéţţéẋţ ḾÖ, çöḿþàçţ þéŕ-ļöçàļé ĴŠÖÑ, ÎÇÜ) ƒöŕ ţĥé ŕüññîñĝ àþþļîçàţîöñ, àñđ ķééþ ţĥé ƃüñđļé öñ ţĥé þîþéļîñé šîđé.

Ţŵö îḿþļéḿéñţàţîöñš, öñé ƒöŕḿàţ

Ţĥé ƃüñđļé ĥàš ţŵö ŕéƒéŕéñçé îḿþļéḿéñţàţîöñš ķéþţ ƃýţé-ƒöŕ-ƃýţé éǫüîṽàļéñţ ƃý šĥàŕéđ ĝöļđéñ ƒîẋţüŕéš:

  • Ĝö, çàñöñîçàļ. core/kbf îñ ţĥé ƒŕàḿéŵöŕķ ḿöđüļé. Ŵĥéŕé ţĥé ţŵö đéŕ, ţĥé Ĝö šöüŕçé ĝöṽéŕñš.
  • ŢýþéŠçŕîþţ, ḿîŕŕöŕ. @neokapi/kapi-format, üšéđ ƃý ţĥé Ŕéàçţ éẋţŕàçţöŕ àñđ ţĥé îñ-ƃŕöŵšéŕ ţööļîñĝ.

Ýöü çàñ ŵàţçĥ ţĥé ţŵö éñĝîñéš àĝŕéé, ļîṽé, öñ ţĥé çöñƒöŕḿàñçé þàĝé, ŵĥîçĥ ŕüñš ţĥé šþéç çöñƒöŕḿàñçé šüîţé àĝàîñšţ ƃöţĥ îḿþļéḿéñţàţîöñš îñ ýöüŕ ƃŕöŵšéŕ.

Đéţéçţîöñ àñđ đéţéŕḿîñîšḿ

À .kbf.json ƒîļé îš àüţö-đéţéçţéđ ƃý îţš éẋţéñšîöñ àñđ ƃý šñîñĝ ţĥé đöçüḿéñţ ƒöŕ ţĥé ḿàĝîç šţŕîñĝ "kapi-bundle". Ţĥé çöḿþöüñđ šüƒƒîẋ îš đéļîƃéŕàţé: ţĥé ƒîļé îš ĴŠÖÑ, šö ţĥé .json ţàîļ ļéţš jq, ĜîţĤüƃ, àñđ àñ éđîţöŕ ţŕéàţ îţ àš ĴŠÖÑ, ŵĥîļé ţĥé .kbf šéĝḿéñţ šţîļļ šàýš ŵĥîçĥ ĴŠÖÑ îţ îš. Ţĥé öṽéŕṽîéŵ çöṽéŕš ţĥé çöñṽéñţîöñ, àñđ ţĥé filepath.Ext çàṽéàţ îţ çŕéàţéš.

Ţĥé šéŕîàļîžéŕ îš đéţéŕḿîñîšţîç: 2-šþàçé îñđéñţ, ñö ĤŢḾĻ éšçàþîñĝ, à ţŕàîļîñĝ ñéŵļîñé, ƒîéļđš éḿîţţéđ îñ ţĥé šţŕüçţ-đéƒîñîţîöñ öŕđéŕ þîññéđ ƃéļöŵ, àñđ àļļ ḿàþ ķéýš šöŕţéđ (ţàŕĝéţ ļöçàļéš, þļüŕàļ ƒöŕḿš, àñđ šéļéçţ çàšéš). Đéţéŕḿîñîšţîç öüţþüţ îš ŵĥàţ ķééþš ţĥé çöñţéñţ ĥàšĥ šţàƃļé àçŕöšš ŕüñš, ḿàçĥîñéš, àñđ ţĥé ţŵö îḿþļéḿéñţàţîöñš.

Ṽéŕšîöñîñĝ

Ţĥé çüŕŕéñţ šçĥéḿà ṽéŕšîöñ îš 1.0, çàŕŕîéđ îñ ţĥé schemaVersion ƒîéļđ öƒ éṽéŕý ƒîļé. Ṽéŕšîöñš ƒöļļöŵ à MAJOR.MINOR çöñţŕàçţ:

  • Ḿàĵöŕ ḿéàñš à ƃŕéàķîñĝ çĥàñĝé. À çöñšüḿéŕ ḿüšţ ŕéĵéçţ à ƒîļé ŵĥöšé ḿàĵöŕ ṽéŕšîöñ îţ đöéš ñöţ ŕéçöĝñîžé.
  • Ḿîñöŕ ḿéàñš à ƒöŕŵàŕđ-çöḿþàţîƃļé àđđîţîöñ. À çöñšüḿéŕ šĥöüļđ àççéþţ üñķñöŵñ ḿîñöŕ ṽéŕšîöñš ŵîţĥîñ à ḿàĵöŕ îţ üñđéŕšţàñđš, îĝñöŕîñĝ ƒîéļđš îţ đöéš ñöţ ŕéçöĝñîžé.

À ŕéàđéŕ ṽàļîđàţéš ţĥé éñṽéļöþé öñ ļöàđ: îţ ŕéĵéçţš àñý đöçüḿéñţ ŵĥöšé kind îš ñöţ kapi-bundle àñđ àñý schemaVersion ŵĥöšé ḿàĵöŕ đöéš ñöţ ḿàţçĥ ţĥé ṽéŕšîöñ ţĥé ƃüîļđ šþéàķš.

Ƒîļé éñṽéļöþé

Ţĥé ţöþ-ļéṽéļ File öƃĵéçţ îš ţĥé .kbf.json đöçüḿéñţ. Ƒîéļđ öŕđéŕ àñđ šĥàþé àŕé ñöŕḿàţîṽé, ƃéçàüšé đéţéŕḿîñîšţîç šéŕîàļîžàţîöñ îš ŵĥàţ ķééþš ţĥé çöñţéñţ ĥàšĥ šţàƃļé àçŕöšš ţĥé Ĝö àñđ ŢýþéŠçŕîþţ îḿþļéḿéñţàţîöñš.

ƑîéļđŢýþéŔéǫüîŕéđĐéšçŕîþţîöñ
schemaVersionšţŕîñĝýéšŴîŕé ƒöŕḿàţ ṽéŕšîöñ, é.ĝ. "1.0". Šüƃĵéçţ ţö ţĥé ṽéŕšîöñîñĝ çöñţŕàçţ àƃöṽé.
kindšţŕîñĝýéšḾàĝîç šţŕîñĝ; ḿüšţ ƃé "kapi-bundle".
createdšţŕîñĝñöÇŕéàţîöñ ţîḿéšţàḿþ (ŔƑÇ 3339). Öḿîţţéđ ŵĥéñ éḿþţý.
generatorĜéñéŕàţöŕÎñƒöýéšŢĥé éẋţŕàçţöŕ ţĥàţ þŕöđüçéđ ţĥé ƒîļé.
projectÞŕöĵéçţÎñƒöýéšŢĥé þŕöĵéçţ ţĥé ƒîļé ƃéļöñĝš ţö.
vocabularyṼöçàƃüļàŕýñöṼöçàƃüļàŕý þàçķš ţĥîš ƒîļé'š ŕüñš đéþéñđ öñ. Öḿîţţéđ ŵĥéñ àƃšéñţ.
documentsĐöçüḿéñţ[]ýéšÖñé éñţŕý þéŕ éẋţŕàçţéđ šöüŕçé ƒîļé.

ĜéñéŕàţöŕÎñƒö

Îđéñţîƒîéš ţĥé éẋţŕàçţöŕ ţĥàţ þŕöđüçéđ ţĥé ƒîļé.

ƑîéļđŢýþéŔéǫüîŕéđĐéšçŕîþţîöñ
idšţŕîñĝýéšÉẋţŕàçţöŕ îđéñţîƒîéŕ, é.ĝ. "@neokapi/kapi-format-examples".
versionšţŕîñĝýéšÉẋţŕàçţöŕ ṽéŕšîöñ.
capabilitiesšţŕîñĝ[]ñöĐéçļàŕéđ çàþàƃîļîţîéš, é.ĝ. ["extract", "preview"]. Öḿîţţéđ ŵĥéñ éḿþţý.

ÞŕöĵéçţÎñƒö

Îđéñţîƒîéš ţĥé þŕöĵéçţ ţĥé ƒîļé ƃéļöñĝš ţö.

ƑîéļđŢýþéŔéǫüîŕéđĐéšçŕîþţîöñ
idšţŕîñĝýéšÞŕöĵéçţ îđéñţîƒîéŕ.
sourceLocalešţŕîñĝýéšƂÇÞ-47 ļöçàļé öƒ ţĥé source ŕüñš.

Ṽöçàƃüļàŕý

Ļîšţš ţĥé ṽöçàƃüļàŕý þàçķš ŵĥöšé šþàñ-ţýþé éñţŕîéš ţĥé ƒîļé'š ŕüñš éẋþéçţ à çöñšüḿéŕ ţö ĥàṽé ļöàđéđ.

ƑîéļđŢýþéŔéǫüîŕéđĐéšçŕîþţîöñ
extendsšţŕîñĝ[]ñöÑàḿéš öƒ ṽöçàƃüļàŕý þàçķš, é.ĝ. ["common-formatting", "rich-jsx"].

Đöçüḿéñţ

À Document îš öñé šöüŕçé ƒîļé'š ŵöŕţĥ öƒ éẋţŕàçţéđ çöñţéñţ.

ƑîéļđŢýþéŔéǫüîŕéđĐéšçŕîþţîöñ
idšţŕîñĝý隊ţàƃļé îđéñţîƒîéŕ ƒöŕ ţĥé đöçüḿéñţ ŵîţĥîñ ţĥé ƒîļé.
documentTypešţŕîñĝý隊öüŕçé ƒöŕḿàţ đîšçŕîḿîñàţöŕ. Ţĥé Ĝö îḿþļéḿéñţàţîöñ đéƒîñéš "jsx".
pathšţŕîñĝýéšÞàţĥ öƒ ţĥé šöüŕçé ƒîļé ţĥé çöñţéñţ ŵàš éẋţŕàçţéđ ƒŕöḿ.
sourceHashšţŕîñĝñöÇöñţéñţ ĥàšĥ öƒ ţĥé öŕîĝîñàļ šöüŕçé ƒîļé. Öḿîţţéđ ŵĥéñ éḿþţý.
skeletonŠķéļéţöññöŔéƒéŕéñçé ţö ţĥé öþàǫüé šķéļéţöñ üšéđ ţö ŕéçöñšţŕüçţ ţĥé šöüŕçé öñ ḿéŕĝé.
blocksƂļöçķ[]ýéšŢĥé ţŕàñšļàţàƃļé üñîţš éẋţŕàçţéđ ƒŕöḿ ţĥîš đöçüḿéñţ.

Šķéļéţöñ

À ŕéƒéŕéñçé ţö ţĥé öþàǫüé šķéļéţöñ þàýļöàđ à ḿéŕĝé šţéþ çöñšüḿéš ţö ŕéçöñšţŕüçţ ţĥé öŕîĝîñàļ šöüŕçé ƒîļé ŵîţĥ ţŕàñšļàţéđ çöñţéñţ šþļîçéđ ƃàçķ îñ. Àţ ļéàšţ öñé öƒ ţĥé ƒîéļđš îš þŕéšéñţ.

ƑîéļđŢýþéŔéǫüîŕéđĐéšçŕîþţîöñ
refšţŕîñĝñöŔéƒéŕéñçé ţö àñ éẋţéŕñàļ šķéļéţöñ þàýļöàđ. Öḿîţţéđ ŵĥéñ éḿþţý.
inlinešţŕîñĝñöÎñļîñé šķéļéţöñ þàýļöàđ. Öḿîţţéđ ŵĥéñ éḿþţý.

Ƃļöçķ

À Block îš ţĥé üñîţ öƒ ţŕàñšļàţîöñ ţŕàçķîñĝ. Îţš source îš à ƒļàţ šéǫüéñçé öƒ Runš îñ ţĥé þŕöĵéçţ'š šöüŕçé ļöçàļé; çöḿḿîţţéđ ţŕàñšļàţîöñš ļîṽé îñ ţĥé öþţîöñàļ þéŕ-ļöçàļé targets ḿàþ (šéé Ţàŕĝéţš).

ƑîéļđŢýþéŔéǫüîŕéđĐéšçŕîþţîöñ
idšţŕîñĝý隊ţàƃļé îđéñţîƒîéŕ ŵîţĥîñ ţĥé đöçüḿéñţ.
hashšţŕîñĝýéšÇöñţéñţ ĥàšĥ öƒ ţĥé ƃļöçķ, üšéđ ƒöŕ đéđüþļîçàţîöñ àñđ çĥàñĝé đéţéçţîöñ.
translatableƃööļýéšŴĥéţĥéŕ ţĥé ƃļöçķ šĥöüļđ ƃé öƒƒéŕéđ ƒöŕ ţŕàñšļàţîöñ.
typešţŕîñĝýéšÇöàŕšé ƃļöçķ çļàššîƒîçàţîöñ: "jsx:element", "jsx:attribute", öŕ "js:t".
sourceŔüñ[]ý隊öüŕçé-ļöçàļé çöñţéñţ àš à ŕüñ šéǫüéñçé.
targetsḿàþ<ļöçàļé, Ŕüñ[]>ñöÇöḿḿîţţéđ ţŕàñšļàţîöñš, ķéýéđ ƃý ƂÇÞ-47 ļöçàļé. Öḿîţţéđ ŵĥéñ ţĥéŕé àŕé ñöñé.
placeholdersÞļàçéĥöļđéŕ[]ýéšḾéţàđàţà ƒöŕ éṽéŕý þļàçéĥöļđéŕ, þàîŕéđ çöđé, àñđ ÎÇÜ þîṽöţ ŕéƒéŕéñçéđ ƃý ţĥé ŕüñš.
propertiesƂļöçķÞŕöþéŕţîéšýéšÞŕöṽéñàñçé ḿéţàđàţà (šöüŕçé ļöçàţîöñ, çöḿþöñéñţ, ĴŠẊ þàţĥ).
previewƂļöçķÞŕéṽîéŵĤîñţšñöÖþţîöñàļ ĥîñţš ƒöŕ ŕéñđéŕîñĝ à þŕéṽîéŵ öƒ ţĥé ƃļöçķ. Öḿîţţéđ ŵĥéñ àƃšéñţ.

ƂļöçķÞŕöþéŕţîéš

Þŕöṽéñàñçé ḿéţàđàţà đéšçŕîƃîñĝ ŵĥéŕé ţĥé ƃļöçķ ŵàš éẋţŕàçţéđ ƒŕöḿ.

ƑîéļđŢýþéĐéšçŕîþţîöñ
filešţŕîñĝŠöüŕçé ƒîļé þàţĥ.
lineîñţĻîñé ñüḿƃéŕ îñ ţĥé šöüŕçé ƒîļé.
componentšţŕîñĝÉñçļöšîñĝ çöḿþöñéñţ ñàḿé.
jsxPathšţŕîñĝÞàţĥ ţö ţĥé éļéḿéñţ ŵîţĥîñ ţĥé çöḿþöñéñţ ţŕéé.
elementšţŕîñĝŢĥé éļéḿéñţ ţàĝ ţĥé çöñţéñţ ŵàš éẋţŕàçţéđ ƒŕöḿ.
locNotešţŕîñĝŢŕàñšļàţöŕ ñöţé (ÎŢŠ locNote). Öḿîţţéđ ŵĥéñ éḿþţý.

ƂļöçķÞŕéṽîéŵĤîñţš

Ĥîñţš üšéđ ţö ŕéñđéŕ à ŕéþŕéšéñţàţîṽé þŕéṽîéŵ öƒ à ƃļöçķ.

ƑîéļđŢýþéĐéšçŕîþţîöñ
storyIdšţŕîñĝŠţöŕýƃööķ šţöŕý îđéñţîƒîéŕ. Öḿîţţéđ ŵĥéñ éḿþţý.
snapshotPathšţŕîñĝÞàţĥ ţö à ŕéñđéŕéđ šñàþšĥöţ. Öḿîţţéđ ŵĥéñ éḿþţý.
sampleValuesḿàþ<šţŕîñĝ, àñý>Šàḿþļé ṽàļüéš ƒöŕ þļàçéĥöļđéŕš, ķéýéđ ƃý þļàçéĥöļđéŕ ñàḿé. Öḿîţţéđ ŵĥéñ àƃšéñţ.

Þļàçéĥöļđéŕ

À Placeholder îš ḿéţàđàţà àƃöüţ à ṽàŕîàƃļé, éļéḿéñţ, ñöđé, öŕ ÎÇÜ þîṽöţ ţĥàţ ţĥé ƃļöçķ'š ŕüñš ŕéƒéŕéñçé. Ṽàļîđàţöŕš üšé ţĥîš ļîšţ ţö àššéŕţ ţĥàţ ţàŕĝéţš þŕéšéŕṽé éṽéŕý ŕéǫüîŕéđ þļàçéĥöļđéŕ.

ƑîéļđŢýþéŔéǫüîŕéđĐéšçŕîþţîöñ
namešţŕîñĝýéšÞļàçéĥöļđéŕ ñàḿé. Ḿàţçĥéš ţĥé equiv öƒ ţĥé çöŕŕéšþöñđîñĝ ŕüñ, öŕ ţĥé pivot öƒ à þļüŕàļ/šéļéçţ çöñšţŕüçţ.
kindšţŕîñĝýéšÖñé öƒ "variable", "element", "node", öŕ "icu-pivot".
jsTypešţŕîñĝñöŢĥé ĴàṽàŠçŕîþţ/ŢýþéŠçŕîþţ ţýþé öƒ ţĥé ṽàļüé, é.ĝ. "number", "string", "ReactNode". Öḿîţţéđ ŵĥéñ éḿþţý.
sourceExpršţŕîñĝýéšŢĥé šöüŕçé éẋþŕéššîöñ ţĥé þļàçéĥöļđéŕ ŵàš éẋţŕàçţéđ ƒŕöḿ.
optionalƃööļñöŴĥéñ true, ţĥé þļàçéĥöļđéŕ ḿàý ƃé đŕöþþéđ îñ à ţàŕĝéţ (é.ĝ. à çöñđîţîöñàļ ĴŠẊ ñöđé). Öḿîţţéđ ŵĥéñ false.

Ţĥé Ŕüñ ḿöđéļ

À Run îš öñé éļéḿéñţ îñ à ƃļöçķ'š ƒļàţ îñļîñé çöñţéñţ šéǫüéñçé. Ŕüñš àŕé à đîšçŕîḿîñàţéđ üñîöñ: éàçĥ ŕüñ îš à ĴŠÖÑ öƃĵéçţ ŵîţĥ éẋàçţļý öñé đîšçŕîḿîñàţöŕ ķéý. À ŕüñ öƃĵéçţ ŵîţĥ žéŕö öŕ ḿöŕé ţĥàñ öñé đîšçŕîḿîñàţöŕ îš ŕéĵéçţéđ öñ đéçöđé. Ţĥé šéṽéñ ķîñđš àŕé text, ph, pcOpen, pcClose, sub, plural, àñđ select.

Ţéẋţ îš ţĥé öñé ķîñđ šéŕîàļîžéđ ƒļàţ, àš {"text": "..."}, ŵĥéŕé ţĥé đîšçŕîḿîñàţöŕ'š ṽàļüé îš ţĥé šţŕîñĝ îţšéļƒ. Éṽéŕý öţĥéŕ ķîñđ ñéšţš îţš öƃĵéçţ üñđéŕ ţĥé đîšçŕîḿîñàţöŕ ķéý.

ţéẋţ: à þļàîñ ţéẋţ çĥüñķ

{ "text": "Files " }

þĥ: à šéļƒ-çļöšîñĝ þļàçéĥöļđéŕ

À ph ŕüñ îš à šéļƒ-çöñţàîñéđ îñļîñé ţöķéñ: à ṽàŕîàƃļé îñţéŕþöļàţîöñ, à çöñđîţîöñàļ ĴŠẊ éẋþŕéššîöñ, à <br/>, àñ îçöñ, à ŕéđàçţîöñ, àñđ šö öñ.

ƑîéļđŢýþéŔéǫüîŕéđĐéšçŕîþţîöñ
idšţŕîñĝýéšŔüñ îđéñţîƒîéŕ, üñîǫüé ŵîţĥîñ ţĥé ƃļöçķ.
typešţŕîñĝýéšÞŕöđüçéŕ-šþéçîƒîç ŕüñ ţýþé, é.ĝ. "jsx:var", "jsx:node".
subTypešţŕîñĝñöƑîñéŕ çļàššîƒîçàţîöñ, é.ĝ. "number", "string". Öḿîţţéđ ŵĥéñ éḿþţý.
datašţŕîñĝýéšŢĥé öŕîĝîñàļ ţöķéñ ţĥé ŕéàđéŕ çàþţüŕéđ, é.ĝ. "{count}".
equivšţŕîñĝýéšÉǫüîṽàļéñçé ñàḿé; ţĥé þļàçéĥöļđéŕ ţĥîš ŕüñ šţàñđš ƒöŕ.
dispšţŕîñĝñöŠĥöŕţ đîšþļàý ļàƃéļ ƒöŕ çĥîþš. Ƒàļļš ƃàçķ ţö equiv. Öḿîţţéđ ŵĥéñ éḿþţý.
constraintsŔüñÇöñšţŕàîñţšñöÞéŕ-ŕüñ éđîţîñĝ çöñšţŕàîñţš (šéé ŔüñÇöñšţŕàîñţš). Öḿîţţéđ ŵĥéñ àƃšéñţ.
{
"ph": {
"id": "2",
"type": "jsx:var",
"subType": "number",
"data": "{count}",
"equiv": "count",
"disp": "count"
}
}

þçÖþéñ / þçÇļöšé: þàîŕéđ çöđéš

À þàîŕéđ çöđé îš šþļîţ îñţö àñ öþéñîñĝ ŕüñ (pcOpen) àñđ à çļöšîñĝ ŕüñ (pcClose) ţĥàţ šĥàŕé ţĥé šàḿé id ŵîţĥîñ à ŕüñš šçöþé. Ţĥéý ŵŕàþ ţĥé çöñţéñţ ƃéţŵééñ ţĥéḿ, ţĥé àñàļöĝüé öƒ àñ öþéñîñĝ àñđ çļöšîñĝ ĤŢḾĻ/ĴŠẊ ţàĝ.

pcOpen çàŕŕîéš ţĥé šàḿé ƒîéļđš àš ph (id, type, subType, data, equiv, disp, constraints). pcClose çàŕŕîéš id, type, subType, data, àñđ àñ öþţîöñàļ equiv (ŕéþéàţéđ ƒöŕ ļöçàļîţý šö à ŕéñđéŕéŕ çàñ ŕéñđéŕ ţĥé çļöšîñĝ ĥàļƒ öñ îţš öŵñ).

{
"pcOpen": {
"id": "1",
"type": "jsx:element",
"subType": "span",
"data": "<span className=\"muted\">",
"equiv": "muted",
"disp": "span"
}
}
{
"pcClose": {
"id": "1",
"type": "jsx:element",
"subType": "span",
"data": "</span>",
"equiv": "muted"
}
}

šüƃ: à ŕéƒéŕéñçé ţö à šüƃƃļöçķ

À sub ŕüñ ŕéƒéŕéñçéš àñöţĥéŕ Block ƃý îđ. Îţ îš éḿîţţéđ ŵĥéñ àñ öüţéŕ ƒöŕḿàţ éẋţŕàçţš à ƒîéļđ ŵĥöšé ṽàļüé îš îţšéļƒ à ḿîñî-đöçüḿéñţ îñ àñöţĥéŕ ƒöŕḿàţ: à šüƃƒîļţéŕ þŕöđüçéš à šéþàŕàţé ƃļöçķ, àñđ ţĥé öüţéŕ ƃļöçķ þöîñţš àţ îţ.

ƑîéļđŢýþéŔéǫüîŕéđĐéšçŕîþţîöñ
idšţŕîñĝýéšŔüñ îđéñţîƒîéŕ ŵîţĥîñ ţĥé ƃļöçķ.
refšţŕîñĝýéšŢĥé îđ öƒ ţĥé ŕéƒéŕéñçéđ šüƃƃļöçķ.
equivšţŕîñĝýéšÉǫüîṽàļéñçé ñàḿé ƒöŕ ţĥé šüƃƃļöçķ ţöķéñ.
{ "sub": { "id": "1", "ref": "subblock-7", "equiv": "body" } }

þļüŕàļ: à šţŕüçţüŕéđ þļüŕàļ çöñšţŕüçţ

À plural ŕüñ çàŕŕîéš àñ ÎÇÜ þļüŕàļ çöñšţŕüçţ àš ƒîŕšţ-çļàšš šţŕüçţüŕé: à pivot ṽàŕîàƃļé ţĥàţ đŕîṽéš šéļéçţîöñ, àñđ à forms ḿàþ ķéýéđ ƃý þļüŕàļ ƒöŕḿ. Éàçĥ ƒöŕḿ'š ṽàļüé îš îţšéļƒ à Run[], šö îñļîñé ḿàŕķüþ àñđ þļàçéĥöļđéŕš îñšîđé à þļüŕàļ çļàüšé šţàý ƒîŕšţ-çļàšš.

ƑîéļđŢýþéŔéǫüîŕéđĐéšçŕîþţîöñ
pivotšţŕîñĝýéšŢĥé ṽàŕîàƃļé đŕîṽîñĝ þļüŕàļ šéļéçţîöñ. Đéçļàŕéđ îñ placeholders ŵîţĥ ķîñđ icu-pivot.
formsḿàþ<ƒöŕḿ, Ŕüñ[]>ýéšÖñé ŕüñ šéǫüéñçé þéŕ þļüŕàļ ƒöŕḿ.

Ţĥé ƒöŕḿ ķéýš àŕé ţĥé ÇĻĐŔ þļüŕàļ çàţéĝöŕîéš: zero, one, two, few, many, other. Öñ ţĥé ŵîŕé ţĥé đéţéŕḿîñîšţîç šéŕîàļîžéŕ éḿîţš ţĥéḿ îñ šöŕţéđ öŕđéŕ (šö one, other, zero ƃéļöŵ); à ŕéñđéŕéŕ îš ƒŕéé ţö ŕé-öŕđéŕ ţĥéḿ îñţö ÇĻĐŔ öŕđéŕ ƒöŕ đîšþļàý.

{
"plural": {
"pivot": "count",
"forms": {
"one": [{ "text": "1 item in your cart" }],
"other": [
{
"ph": {
"id": "1",
"type": "jsx:var",
"subType": "number",
"data": "{count}",
"equiv": "count",
"disp": "count"
}
},
{ "text": " items in your cart" }
],
"zero": [{ "text": "Your cart is empty" }]
}
}
}

šéļéçţ: à šţŕüçţüŕéđ šéļéçţ çöñšţŕüçţ

À select ŕüñ îš šýḿḿéţŕîç ţö plural, ƃüţ îţš cases ḿàþ îš ķéýéđ ƃý àŕƃîţŕàŕý šţŕîñĝ ṽàļüéš (šüçĥ àš male / female / other) ŕàţĥéŕ ţĥàñ ƒîẋéđ þļüŕàļ çàţéĝöŕîéš. Çàšé ķéýš àŕé ļîķéŵîšé éḿîţţéđ îñ šöŕţéđ öŕđéŕ öñ ţĥé ŵîŕé.

ƑîéļđŢýþéŔéǫüîŕéđĐéšçŕîþţîöñ
pivotšţŕîñĝýéšŢĥé ṽàŕîàƃļé đŕîṽîñĝ šéļéçţîöñ. Đéçļàŕéđ îñ placeholders.
casesḿàþ<šţŕîñĝ, Ŕüñ[]>ýéšÖñé ŕüñ šéǫüéñçé þéŕ šéļéçţ çàšé.
{
"select": {
"pivot": "gender",
"cases": {
"female": [{ "text": "She liked your post" }],
"male": [{ "text": "He liked your post" }],
"other": [{ "text": "They liked your post" }]
}
}
}

ŔüñÇöñšţŕàîñţš

Öþţîöñàļ þéŕ-ŕüñ éđîţîñĝ çöñšţŕàîñţš, þŕéšéñţ öñ ph àñđ pcOpen ŕüñš ŵĥéñ à ŕüñ öṽéŕŕîđéš îţš ṽöçàƃüļàŕý đéƒàüļţš.

ƑîéļđŢýþéĐéšçŕîþţîöñ
deletableƃööļŴĥéţĥéŕ ţĥé ŕüñ ḿàý ƃé đéļéţéđ îñ à ţàŕĝéţ.
cloneableƃööļŴĥéţĥéŕ ţĥé ŕüñ ḿàý ƃé đüþļîçàţéđ îñ à ţàŕĝéţ.
reorderableƃööļŴĥéţĥéŕ ţĥé ŕüñ ḿàý ƃé ḿöṽéđ ŵîţĥîñ à ţàŕĝéţ.

Ţàŕĝéţš

À ƃļöçķ'š çöḿḿîţţéđ ţŕàñšļàţîöñš ļîṽé îñ targets, à ḿàþ ķéýéđ ƃý ƂÇÞ-47 ļöçàļé ŵĥöšé ṽàļüé îš à Run[], ţĥé ţŕàñšļàţéđ çöñţéñţ ƒöŕ ţĥàţ ļöçàļé, üšîñĝ éẋàçţļý ţĥé šàḿé ŕüñ þŕîḿîţîṽéš àš source. Ţĥé ƒîéļđ îš öḿîţţéđ éñţîŕéļý ŵĥéñ à ƃļöçķ ĥàš ñö ţàŕĝéţš. Ļöçàļé ķéýš àŕé šöŕţéđ öñ ţĥé ŵîŕé.

{
"id": "files-heading",
"hash": "2xykvb",
"translatable": true,
"type": "jsx:element",
"source": [{ "text": "Files matched" }],
"targets": {
"de": [{ "text": "Gefundene Dateien" }],
"fr": [{ "text": "Fichiers trouvés" }]
},
"placeholders": [],
"properties": {
"file": "src/FilesHeading.tsx",
"line": 4,
"component": "FilesHeading",
"jsxPath": "FilesHeading > h2",
"element": "h2"
}
}

À ţàŕĝéţ ḿàý àđđ çöñţéñţ, ŕéšţŕüçţüŕé ţéẋţ, öŕ ŕé-ŵŕàþ þàîŕéđ çöđéš, ƃüţ îţ ḿüšţ þŕéšéŕṽé éṽéŕý ŕéǫüîŕéđ þļàçéĥöļđéŕ ƒŕöḿ ţĥé šöüŕçé.

Ṽàļîđàţîöñ

Ţĥé ṽàļîđàţöŕ ŕéþöŕţš þŕöƃļéḿš àš ţýþéđ éŕŕöŕš, éàçĥ çàŕŕýîñĝ à ḿàçĥîñé-ŕéàđàƃļé kind. Ţŵö çĥéçķš àŕé éẋþöšéđ: à šţŕüçţüŕàļ ŵéļļ-ƒöŕḿéđñéšš çĥéçķ öṽéŕ à ƃļöçķ'š ŕüñš (ValidateBlock), àñđ à þļàçéĥöļđéŕ-þŕéšéŕṽàţîöñ çĥéçķ öƒ à ţàŕĝéţ àĝàîñšţ îţš šöüŕçé (ValidateTargetAgainstSource). Ṽàļîđàţîöñ ŵàļķš îñţö ñéšţéđ þļüŕàļ ƒöŕḿš àñđ šéļéçţ çàšéš àš ţĥéîŕ öŵñ šçöþéš.

ĶîñđḾéàñîñĝ
missing-placeholderÀ ţàŕĝéţ đŕöþþéđ à ŕéǫüîŕéđ (ñöñ-öþţîöñàļ) šöüŕçé þļàçéĥöļđéŕ.
extra-placeholderÀ ţàŕĝéţ îñţŕöđüçéđ à þļàçéĥöļđéŕ ñöţ þŕéšéñţ îñ ţĥé šöüŕçé.
malformed-runsÀ ŕüñ îš ñöţ à ŵéļļ-ƒöŕḿéđ đîšçŕîḿîñàţéđ üñîöñ: îţ ĥàš žéŕö öŕ ḿöŕé ţĥàñ öñé đîšçŕîḿîñàţöŕ ķéý šéţ.
unknown-placeholderÀ šöüŕçé ŕüñ ŕéƒéŕéñçéš à þļàçéĥöļđéŕ (öŕ þļüŕàļ/šéļéçţ þîṽöţ) ñöţ đéçļàŕéđ îñ ţĥé ƃļöçķ'š placeholders ļîšţ.
unclosed-paired-codeÀ pcOpen ĥàš ñö ḿàţçĥîñĝ pcClose îñ ţĥé šàḿé ŕüñš šçöþé.
unmatched-close-codeÀ pcClose ĥàš ñö ḿàţçĥîñĝ pcOpen.
duplicate-paired-codeŢŵö pcOpen ŕüñš šĥàŕé ţĥé šàḿé îđ ŵîţĥîñ à šîñĝļé ŕüñš šçöþé.

Ýöü çàñ éẋéŕçîšé éṽéŕý öñé öƒ ţĥéšé ŕüļéš àĝàîñšţ ƃöţĥ ŕéƒéŕéñçé îḿþļéḿéñţàţîöñš öñ ţĥé KBF Ţéšţš þàĝé.

Çöḿþàñîöñ àññöţàţîöñ ƒîļé (.overlays.jsonl)

Šţàñđ-öƒƒ àññöţàţîöñš (ŕéṽîéŵ šţàţüš, þŕöţéçţéđ ţéŕḿš, ḾŢ çöñƒîđéñçé, ţéŕḿîñöļöĝý ḿàţçĥéš) ļîṽé îñ à çöḿþàñîöñ .overlays.jsonl ƒîļé ŕàţĥéŕ ţĥàñ îñšîđé ţĥé .kbf.json îţšéļƒ. À .overlays.jsonl ƒîļé îš ĴŠÖÑ-Ļîñéš: éàçĥ ļîñé îš öñé çöḿþàçţ ĴŠÖÑ ŕéçöŕđ (ñö îñđéñţàţîöñ, ĻƑ-ţéŕḿîñàţéđ), ŵĥîçĥ ķééþš îţ ĝŕéþ- àñđ đ-ƒŕîéñđļý. Ţĥé ƒîŕšţ ñöñ-éḿþţý ļîñé îš à ĥéàđéŕ ŕéçöŕđ ("type": "header"); éṽéŕý šüƃšéǫüéñţ ñöñ-éḿþţý ļîñé îš àñ àññöţàţîöñ ŕéçöŕđ ("type": "annotation").

Ţĥé ĥéàđéŕ çàŕŕîéš annotationType, annotationVersion, à producer (id + version), à created ţîḿéšţàḿþ, àñđ targetArchive, ţĥé àŕçĥîṽé šţàţé ţĥé àññöţàţîöñš ŵéŕé þŕöđüçéđ àĝàîñšţ. Éàçĥ àññöţàţîöñ ŕéçöŕđ çàŕŕîéš à type, àñ id, ţĥé block îţ îš àƃöüţ, àñ anchor šàýîñĝ ŵĥéŕé îñšîđé ţĥàţ ƃļöçķ, àñđ à þŕöđüçéŕ-šþéçîƒîç data þàýļöàđ (ţĥé ƒŕàḿéŵöŕķ îḿþöšéš ñö šçĥéḿà öñ data).

Àñ àñçĥöŕ îš ţĥé šàḿé Anchor ţĥé éñĝîñé üšéš éṽéŕýŵĥéŕé éļšé îţ ŕéçöŕđš à þöšîţîöñ, šö à ţéŕḿ ḿàţçĥ ŵŕîţţéñ ĥéŕé ḿéàñš ŵĥàţ îţ ḿéàñš îñ àñ öṽéŕļàý öŕ à çĥéçķ ƒîñđîñĝ. Îţš kind đîšçŕîḿîñàţéš ƒöüŕ šĥàþéš:

Àñçĥöŕ ķîñđḾéàñîñĝƒüļ ƒîéļđšŢàŕĝéţš
blockñ/àƂļöçķ-ļéṽéļ ḿéţàđàţà.
runpath, runIdÀ šþéçîƒîç ŕüñ, îđéñţîƒîéđ ƃý þàţĥ àñđ ḿàţçĥéđ àĝàîñšţ runId.
rangepath, start, endÀ ĥàļƒ-öþéñ šþàñ öƒ ţĥé ŕüñ šéǫüéñçé àţ path.
formpath, keyÀ šþéçîƒîç þļüŕàļ ƒöŕḿ öŕ šéļéçţ çàšé, šéļéçţéđ ƃý key.

Ţĥé path îš à ļîšţ öƒ šţéþš îñţö à ƃļöçķ'š ñéšţéđ ŕüñ šţŕüçţüŕé: à ƃàŕé ñüḿƃéŕ îñđéẋéš îñţö à Run[], àñ öƃĵéçţ {"plural": "<form>"} đéšçéñđš îñţö à þļüŕàļ ƒöŕḿ, àñđ {"select": "<value>"} đéšçéñđš îñţö à šéļéçţ çàšé. Àñ éḿþţý þàţĥ ŕéƒéŕš ţö ţĥé ƃļöçķ'š ţöþ-ļéṽéļ šöüŕçé ŕüñš.

start àñđ end àŕé éàçĥ à ŕüñ þöšîţîöñ: {"run": <index>, "offset": <runes>}, ŵĥéŕé offset îš à ŕüñé öƒƒšéţ îñţö ţĥàţ ŕüñ'š ţéẋţ àñđ đéƒàüļţš ţö 0. Ƃöüñđîñĝ à ŕàñĝé ƃý ŕüñ þöšîţîöñš ŕàţĥéŕ ţĥàñ ƃý à ƒļàţ çĥàŕàçţéŕ öƒƒšéţ îš ŵĥàţ ļéţš à šþàñ çŕöšš ŕüñ ƃöüñđàŕîéš, šö à þĥŕàšé ŕüññîñĝ ţĥŕöüĝĥ à ƃöļđ šéĝḿéñţ îš öñé ŕàñĝé ŕàţĥéŕ ţĥàñ ţĥŕéé, àñđ ļéţš à ƃöüñđàŕý šîţ éîţĥéŕ šîđé öƒ à þļàçéĥöļđéŕ, ŵĥîçĥ çàŕŕîéš ñö ţéẋţ öƒ îţš öŵñ.

Ŕéšöļṽîñĝ àñ àñçĥöŕ àĝàîñšţ à ƃļöçķ éîţĥéŕ šüççééđš öŕ ŕéţüŕñš öñé öƒ šîẋ ḿàçĥîñé-ŕéàđàƃļé ƒàîļüŕé ŕéàšöñš:

ŔéàšöñḾéàñîñĝ
block-not-foundŢĥé àñçĥöŕéđ ƃļöçķ îđ đöéš ñöţ ḿàţçĥ.
path-out-of-boundsÀ þàţĥ šţéþ îñđéẋéš þàšţ ţĥé éñđ öƒ à ŕüñ šéǫüéñçé.
path-wrong-kindŢĥé þàţĥ ļàñđš öñ à ŕüñ öƒ ţĥé ŵŕöñĝ ķîñđ ƒöŕ ţĥé àñçĥöŕ.
run-id-mismatchŢĥé ŕéšöļṽéđ ŕüñ'š îđ đéŕš ƒŕöḿ ţĥé ŕéçöŕđéđ runId (à ļîķéļý öŕþĥàñ).
range-out-of-boundsŢĥé ŕàñĝé àđđŕéššéš þöšîţîöñš öüţšîđé ţĥé ŕüñ šéǫüéñçé îţ ñàḿéš.
form-not-foundŢĥé àñçĥöŕéđ þļüŕàļ ƒöŕḿ öŕ šéļéçţ çàšé đöéš ñöţ éẋîšţ öñ ţĥé ƃļöçķ.

Àñ éẋàḿþļé ĥéàđéŕ àñđ ŕüñ-ļéṽéļ àññöţàţîöñ ŕéçöŕđ:

{"type":"header","annotationType":"@neokapi/example","annotationVersion":"1.0.0","producer":{"id":"@neokapi/kapi-format-examples","version":"0.0.1"},"created":"2026-04-15T12:00:00Z","targetArchive":"sha256:deadbeef"}
{"type":"annotation","id":"term-1","block":"tag-chip","anchor":{"kind":"run","path":[2],"runId":"2"},"data":{"kind":"protected-term","term":"label","action":"preserve-placeholder","confidence":1.0}}

Ţĥé KBF àñàţöḿý þàĝé ļéţš ýöü éđîţ à .overlays.jsonl öṽéŕļàý àñđ ŵàţçĥ éàçĥ àñçĥöŕ ŕéšöļṽé àĝàîñšţ à ļîṽé đöçüḿéñţ, öŕ ƒàîļ ŵîţĥ öñé öƒ ţĥé ŕéàšöñš àƃöṽé.

Ŵöŕķéđ éẋàḿþļéš

Ţĥéšé éẋàḿþļéš ŵàļķ ţĥŕöüĝĥ ţĥé ŕüñ ḿöđéļ öñé ķîñđ àţ à ţîḿé, ţĥéñ šĥöŵ à çöḿþļéţé đöçüḿéñţ àñđ îţš àññöţàţîöñ öṽéŕļàý. Ţĥé šçĥéḿà àƃöṽé îš ţĥé ñöŕḿàţîṽé ŕéƒéŕéñçé; ţĥîš ĥàļƒ îš ţĥé ŕéàđàƃļé çöḿþàñîöñ. Éṽéŕý éẋàḿþļé îš ŕéàļ: ţĥéý àŕé ţĥé ĝöļđéñ ƒîẋţüŕéš šĥàŕéđ ƃéţŵééñ ţĥé Ĝö àñđ ŢýþéŠçŕîþţ îḿþļéḿéñţàţîöñš.

À ƃļöçķ îš à ƒļàţ ŕüñ šéǫüéñçé

Ţĥé üñîţ öƒ ţŕàñšļàţîöñ îš à Block. Îţš source îš à ƒļàţ Run[]: îñļîñé ḿàŕķüþ, ṽàŕîàƃļéš, àñđ ÎÇÜ çöñšţŕüçţš àļļ ļîṽé îñ ţĥé šéǫüéñçé, ñöţ îñ ţĥé ţéẋţ. Ţĥîš îš ŵĥàţ ļéţš à ţŕàñšļàţîöñ šţéþ ŕéŵŕîţé ţĥé ŕéàđàƃļé ţéẋţ ŵĥîļé éṽéŕý þļàçéĥöļđéŕ àñđ ţàĝ šţàýš ƒîŕšţ-çļàšš àñđ àççöüñţéđ ƒöŕ.

Þàîŕéđ çöđé ŵŕàþþîñĝ à ṽàŕîàƃļé

files-heading éẋţŕàçţš Files <span className="muted">({count} matched)</span>. Ţĥé <span> ƃéçöḿéš à þàîŕéđ çöđé, àñ öþéñîñĝ pcOpen àñđ à çļöšîñĝ pcClose ţĥàţ šĥàŕé àñ id, àñđ {count} ƃéçöḿéš à ph þļàçéĥöļđéŕ ƃéţŵééñ ţĥéḿ:

{
"id": "files-heading",
"hash": "2xykvb",
"translatable": true,
"type": "jsx:element",
"source": [
{ "text": "Files " },
{
"pcOpen": {
"id": "1",
"type": "jsx:element",
"subType": "span",
"data": "<span className=\"muted\">",
"equiv": "muted",
"disp": "span"
}
},
{ "text": "(" },
{
"ph": {
"id": "2",
"type": "jsx:var",
"subType": "number",
"data": "{count}",
"equiv": "count",
"disp": "count"
}
},
{ "text": " matched)" },
{
"pcClose": {
"id": "1",
"type": "jsx:element",
"subType": "span",
"data": "</span>",
"equiv": "muted"
}
}
],
"placeholders": [
{
"name": "muted",
"kind": "element",
"jsType": "ReactNode",
"sourceExpr": "<span className=\"muted\">...</span>"
},
{
"name": "count",
"kind": "variable",
"jsType": "number",
"sourceExpr": "count"
}
],
"properties": {
"file": "src/FilesHeading.tsx",
"line": 4,
"component": "FilesHeading",
"jsxPath": "FilesHeading > h2",
"element": "h2"
}
}

À Ƒŕéñçĥ ţàŕĝéţ ŕé-öŕđéŕš ţĥé ŕéàđàƃļé ţéẋţ ƃüţ ķééþš ƃöţĥ ţĥé muted þàîŕéđ çöđé àñđ ţĥé count ṽàŕîàƃļé, šö îţ ṽàļîđàţéš çļéàñ:

{
"fr": [
{
"pcOpen": {
"id": "1",
"type": "jsx:element",
"subType": "span",
"data": "<span className=\"muted\">",
"equiv": "muted"
}
},
{ "text": "(" },
{
"ph": {
"id": "2",
"type": "jsx:var",
"subType": "number",
"data": "{count}",
"equiv": "count"
}
},
{ "text": " trouvés)" },
{
"pcClose": {
"id": "1",
"type": "jsx:element",
"subType": "span",
"data": "</span>",
"equiv": "muted"
}
}
]
}

Öþţîöñàļ ñöđéš

tag-chip çàŕŕîéš ţŵö öþţîöñàļ jsx:node þļàçéĥöļđéŕš (çöñđîţîöñàļ ĴŠẊ éẋþŕéššîöñš ţĥàţ ḿàý öŕ ḿàý ñöţ ŕéñđéŕ) àŕöüñđ à ŕéǫüîŕéđ {label} ṽàŕîàƃļé. Ƃéçàüšé badge àñđ required àŕé đéçļàŕéđ "optional": true, à ţàŕĝéţ ḿàý đŕöþ ţĥéḿ; îţ ḿàý ñöţ đŕöþ label:

{
"source": [
{
"ph": {
"id": "1",
"type": "jsx:node",
"subType": "logical-and",
"data": "index !== undefined && <span className=\"badge\">{index}</span>",
"equiv": "badge",
"disp": "⟨badge⟩"
}
},
{ "text": " " },
{
"ph": {
"id": "2",
"type": "jsx:var",
"subType": "string",
"data": "{label}",
"equiv": "label",
"disp": "label"
}
},
{ "text": " " },
{
"ph": {
"id": "3",
"type": "jsx:node",
"subType": "logical-and",
"data": "!deletable && <span className=\"required\">*</span>",
"equiv": "required",
"disp": "⟨required⟩"
}
}
],
"placeholders": [
{
"name": "badge",
"kind": "node",
"jsType": "ReactNode",
"sourceExpr": "index !== undefined && <span className=\"badge\">{index}</span>",
"optional": true
},
{
"name": "label",
"kind": "variable",
"jsType": "string",
"sourceExpr": "label"
},
{
"name": "required",
"kind": "node",
"jsType": "ReactNode",
"sourceExpr": "!deletable && <span className=\"required\">*</span>",
"optional": true
}
]
}

Þļüŕàļ

À plural ŕüñ çàŕŕîéš àñ ÎÇÜ þļüŕàļ çöñšţŕüçţ àš šţŕüçţüŕé: à pivot àñđ à forms ḿàþ, ŵĥéŕé éàçĥ ƒöŕḿ îš îţš öŵñ Run[], šö ḿàŕķüþ àñđ þļàçéĥöļđéŕš îñšîđé à çļàüšé šţàý ƒîŕšţ-çļàšš. Ƒöŕḿ ķéýš àŕé éḿîţţéđ îñ šöŕţéđ öŕđéŕ öñ ţĥé ŵîŕé (one, other, zero):

{
"plural": {
"pivot": "count",
"forms": {
"one": [{ "text": "1 item in your cart" }],
"other": [
{
"ph": {
"id": "1",
"type": "jsx:var",
"subType": "number",
"data": "{count}",
"equiv": "count",
"disp": "count"
}
},
{ "text": " items in your cart" }
],
"zero": [{ "text": "Your cart is empty" }]
}
}
}

Ţĥé count þîṽöţ îš đéçļàŕéđ îñ placeholders ŵîţĥ ķîñđ icu-pivot.

Šéļéçţ

À select ŕüñ îš šýḿḿéţŕîç ţö plural, ƃüţ îţš cases ḿàþ îš ķéýéđ ƃý àŕƃîţŕàŕý ṽàļüéš ŕàţĥéŕ ţĥàñ ÇĻĐŔ þļüŕàļ çàţéĝöŕîéš:

{
"select": {
"pivot": "gender",
"cases": {
"female": [{ "text": "She liked your post" }],
"male": [{ "text": "He liked your post" }],
"other": [{ "text": "They liked your post" }]
}
}
}

Šüƃƃļöçķ

Ŵĥéñ àñ öüţéŕ ƒöŕḿàţ éẋţŕàçţš à ƒîéļđ ŵĥöšé ṽàļüé îš îţšéļƒ à ḿîñî-đöçüḿéñţ îñ àñöţĥéŕ ƒöŕḿàţ, ţĥé šüƃƒîļţéŕ þŕöđüçéš à šéþàŕàţé Block àñđ ţĥé öüţéŕ ƃļöçķ þöîñţš àţ îţ ŵîţĥ à sub ŕüñ:

{
"id": "email-body",
"source": [
{ "text": "Thanks for signing up. " },
{ "sub": { "id": "1", "ref": "email-cta", "equiv": "cta" } }
],
"placeholders": [
{
"name": "cta",
"kind": "node",
"jsType": "ReactNode",
"sourceExpr": "<CallToAction/>"
}
]
}

À çöḿþļéţé đöçüḿéñţ ŵîţĥ àñ àññöţàţîöñ öṽéŕļàý

À ƒüļļ .kbf.json ƃüñđļéš đöçüḿéñţš àñđ ƃļöçķš üñđéŕ ţĥé éñṽéļöþé; à çöḿþàñîöñ .overlays.jsonl öṽéŕļàý àţţàçĥéš šţàñđ-öƒƒ àññöţàţîöñš ƃý àñçĥöŕ. Ţĥé ĥéàđéŕ ƃéļöŵ îš öñé ļîñé; éàçĥ àññöţàţîöñ îš öñé ļîñé. Ţĥé term-1 ŕéçöŕđ àñçĥöŕš ţö ţĥé label ŕüñ öƒ tag-chip; entity-1 àñçĥöŕš ţö à çĥàŕàçţéŕ ŕàñĝé; check-1 àñçĥöŕš ţö ţĥé one þļüŕàļ ƒöŕḿ; orphan-1 çàŕŕîéš à šţàļé runId àñđ ŵîļļ ñöţ ŕéšöļṽé:

{"type":"header","annotationType":"@neokapi/example","annotationVersion":"1.0.0","producer":{"id":"@neokapi/kapi-format-examples","version":"0.0.1"},"created":"2026-04-15T12:00:00Z","targetArchive":"sha256:deadbeef"}
{"type":"annotation","id":"review-1","block":"files-heading","anchor":{"kind":"block"},"data":{"kind":"review-status","status":"approved"}}
{"type":"annotation","id":"term-1","block":"tag-chip","anchor":{"kind":"run","path":[2],"runId":"2"},"data":{"kind":"protected-term","term":"label"}}
{"type":"annotation","id":"entity-1","block":"files-heading","anchor":{"kind":"range","path":[],"start":{"run":4,"offset":1},"end":{"run":4,"offset":8}},"data":{"kind":"named-entity","entity":"matched"}}
{"type":"annotation","id":"check-1","block":"shopping-cart-plural","anchor":{"kind":"form","path":[0],"key":"one"},"data":{"kind":"qa","note":"singular form reviewed"}}
{"type":"annotation","id":"orphan-1","block":"tag-chip","anchor":{"kind":"run","path":[2],"runId":"99"},"data":{"kind":"protected-term","term":"label"}}

Ţŕý îţ ļîṽé

Ţĥé ļàƃ ƃéļöŵ ŕüñš ţĥé ŕéàļ core/kbf éñĝîñé îñ ýöüŕ ƃŕöŵšéŕ. Þîçķ à šàḿþļé öŕ éđîţ ţĥé .kbf.json đîŕéçţļý. Îţ ŕé-þàŕšéš, çàñöñîçàļîžéš, ŕéñđéŕš éàçĥ ƃļöçķ, àñđ ṽàļîđàţéš ţĥé ŕüñ šţŕüçţüŕé àš ýöü ţýþé. Éđîţ ţĥé .overlays.jsonl öṽéŕļàý àñđ çļîçķ àñ àññöţàţîöñ ţö ŕéšöļṽé îţ àĝàîñšţ ţĥé ļîṽé đöçüḿéñţ àñđ šéé éẋàçţļý ŵĥàţ îţ þöîñţš àţ (öŕ ŵĥý îţ đöéš ñöţ ŕéšöļṽé).

Ļöàđîñĝ ţĥé îñţéŕàçţîṽé KBF ļàƃ…

Ƒöŕ ţĥé çŕöšš-éñĝîñé çöñƒöŕḿàñçé šüîţé, ŵĥéŕé ţĥéšé šàḿé öþéŕàţîöñš ŕüñ àĝàîñšţ ƃöţĥ ţĥé Ĝö éñĝîñé àñđ ţĥé ŢýþéŠçŕîþţ ḿîŕŕöŕ, šéé ţĥé KBF Ţéšţš þàĝé.

Šéé àļšö