more towards parsing vps
This commit is contained in:
parent
3221bb1e89
commit
4893ef0d70
|
@ -20,6 +20,7 @@
|
||||||
"@types/react": "^17.0.3",
|
"@types/react": "^17.0.3",
|
||||||
"@types/react-dom": "^17.0.2",
|
"@types/react-dom": "^17.0.2",
|
||||||
"bootstrap": "^4.6.0",
|
"bootstrap": "^4.6.0",
|
||||||
|
"jest-extended": "^4.0.1",
|
||||||
"node-fetch": "^3.2.10",
|
"node-fetch": "^3.2.10",
|
||||||
"node-fetch-commonjs": "^3.2.4",
|
"node-fetch-commonjs": "^3.2.4",
|
||||||
"pbf": "^3.2.1",
|
"pbf": "^3.2.1",
|
||||||
|
|
|
@ -31,10 +31,32 @@ export function lookup(s: Partial<T.DictionaryEntry>): T.DictionaryEntry[] {
|
||||||
return nounsAdjs.filter((e) => e[key] === value) as T.DictionaryEntry[];
|
return nounsAdjs.filter((e) => e[key] === value) as T.DictionaryEntry[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export function verbLookup(
|
export function verbLookup(input: string): T.VerbEntry[] {
|
||||||
s: (e: T.VerbDictionaryEntry) => boolean
|
const s = input.slice(0, -1);
|
||||||
): T.VerbEntry[] {
|
if (s.endsWith("ېږ")) {
|
||||||
return verbs.filter(({ entry }) => s(entry));
|
return verbs.filter(
|
||||||
|
({ entry }) =>
|
||||||
|
entry.p.slice(0, -1) === s ||
|
||||||
|
entry.p === s.slice(0, -1) + "دل" ||
|
||||||
|
entry.p === s ||
|
||||||
|
entry.psp === s ||
|
||||||
|
entry.prp === s ||
|
||||||
|
entry.ssp === s
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return verbs.filter(
|
||||||
|
({ entry }) =>
|
||||||
|
entry.p.slice(0, -1) === s ||
|
||||||
|
// for short intransitive forms
|
||||||
|
entry.p.slice(0, -3) === s ||
|
||||||
|
entry.p === s ||
|
||||||
|
entry.psp === s ||
|
||||||
|
entry.prp === s ||
|
||||||
|
entry.ssp === s ||
|
||||||
|
(entry.separationAtP &&
|
||||||
|
(entry.p.slice(entry.separationAtP) === s ||
|
||||||
|
entry.psp?.slice(entry.separationAtP) === s))
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function wordQuery(word: string, type: "adj"): T.AdjectiveEntry;
|
export function wordQuery(word: string, type: "adj"): T.AdjectiveEntry;
|
||||||
|
|
|
@ -0,0 +1,413 @@
|
||||||
|
/* eslint-disable jest/valid-title */
|
||||||
|
import * as T from "../../../types";
|
||||||
|
import { verbLookup, wordQuery } from "./lookup";
|
||||||
|
import { parseVerb } from "./parse-verb";
|
||||||
|
import { tokenizer } from "./tokenizer";
|
||||||
|
|
||||||
|
const wahul = wordQuery("وهل", "verb");
|
||||||
|
const leekul = wordQuery("لیکل", "verb");
|
||||||
|
const manul = wordQuery("منل", "verb");
|
||||||
|
const rasedul = wordQuery("رسېدل", "verb");
|
||||||
|
const leedul = wordQuery("لیدل", "verb");
|
||||||
|
const khorul = wordQuery("خوړل", "verb");
|
||||||
|
const kenaastul = wordQuery("کېناستل", "verb");
|
||||||
|
const prexodul = wordQuery("پرېښودل", "verb");
|
||||||
|
const xodul = wordQuery("ښودل", "verb");
|
||||||
|
const kexodul = wordQuery("کېښودل", "verb");
|
||||||
|
|
||||||
|
const tests: {
|
||||||
|
label: string;
|
||||||
|
cases: {
|
||||||
|
input: string;
|
||||||
|
output: {
|
||||||
|
root?: {
|
||||||
|
persons: T.Person[];
|
||||||
|
aspects: T.Aspect[];
|
||||||
|
};
|
||||||
|
stem?: {
|
||||||
|
persons: T.Person[];
|
||||||
|
aspects: T.Aspect[];
|
||||||
|
};
|
||||||
|
verb: T.VerbEntry;
|
||||||
|
}[];
|
||||||
|
}[];
|
||||||
|
}[] = [
|
||||||
|
{
|
||||||
|
label: "with regular simple verbs",
|
||||||
|
cases: [
|
||||||
|
{
|
||||||
|
input: "وهلم",
|
||||||
|
output: [
|
||||||
|
{
|
||||||
|
root: {
|
||||||
|
persons: [T.Person.FirstSingMale, T.Person.FirstSingFemale],
|
||||||
|
aspects: ["imperfective", "perfective"],
|
||||||
|
},
|
||||||
|
verb: wahul,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
input: "وهم",
|
||||||
|
output: [
|
||||||
|
{
|
||||||
|
root: {
|
||||||
|
persons: [T.Person.FirstSingMale, T.Person.FirstSingFemale],
|
||||||
|
aspects: ["imperfective", "perfective"],
|
||||||
|
},
|
||||||
|
stem: {
|
||||||
|
persons: [T.Person.FirstSingMale, T.Person.FirstSingFemale],
|
||||||
|
aspects: ["imperfective", "perfective"],
|
||||||
|
},
|
||||||
|
verb: wahul,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
input: "وهې",
|
||||||
|
output: [
|
||||||
|
{
|
||||||
|
root: {
|
||||||
|
persons: [
|
||||||
|
T.Person.SecondSingMale,
|
||||||
|
T.Person.SecondSingFemale,
|
||||||
|
T.Person.ThirdPlurFemale,
|
||||||
|
],
|
||||||
|
aspects: ["imperfective", "perfective"],
|
||||||
|
},
|
||||||
|
stem: {
|
||||||
|
persons: [T.Person.SecondSingMale, T.Person.SecondSingFemale],
|
||||||
|
aspects: ["imperfective", "perfective"],
|
||||||
|
},
|
||||||
|
verb: wahul,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
input: "لیکم",
|
||||||
|
output: [
|
||||||
|
{
|
||||||
|
root: {
|
||||||
|
persons: [T.Person.FirstSingMale, T.Person.FirstSingFemale],
|
||||||
|
aspects: ["imperfective", "perfective"],
|
||||||
|
},
|
||||||
|
stem: {
|
||||||
|
persons: [T.Person.FirstSingMale, T.Person.FirstSingFemale],
|
||||||
|
aspects: ["imperfective", "perfective"],
|
||||||
|
},
|
||||||
|
verb: leekul,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
input: "لیکلو",
|
||||||
|
output: [
|
||||||
|
{
|
||||||
|
root: {
|
||||||
|
persons: [T.Person.FirstPlurMale, T.Person.FirstPlurFemale],
|
||||||
|
aspects: ["imperfective", "perfective"],
|
||||||
|
},
|
||||||
|
verb: leekul,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
input: "لیکل",
|
||||||
|
output: [
|
||||||
|
{
|
||||||
|
root: {
|
||||||
|
persons: [T.Person.ThirdPlurMale],
|
||||||
|
aspects: ["imperfective", "perfective"],
|
||||||
|
},
|
||||||
|
verb: leekul,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
input: "لیکلل",
|
||||||
|
output: [],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
input: "منله",
|
||||||
|
output: [
|
||||||
|
{
|
||||||
|
root: {
|
||||||
|
persons: [T.Person.ThirdSingFemale],
|
||||||
|
aspects: ["imperfective", "perfective"],
|
||||||
|
},
|
||||||
|
verb: manul,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
input: "مني",
|
||||||
|
output: [
|
||||||
|
{
|
||||||
|
stem: {
|
||||||
|
persons: [
|
||||||
|
T.Person.ThirdSingMale,
|
||||||
|
T.Person.ThirdSingFemale,
|
||||||
|
T.Person.ThirdPlurMale,
|
||||||
|
T.Person.ThirdPlurFemale,
|
||||||
|
],
|
||||||
|
aspects: ["imperfective", "perfective"],
|
||||||
|
},
|
||||||
|
verb: manul,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
input: "منئ",
|
||||||
|
output: [
|
||||||
|
{
|
||||||
|
stem: {
|
||||||
|
persons: [T.Person.SecondPlurMale, T.Person.SecondPlurFemale],
|
||||||
|
aspects: ["imperfective", "perfective"],
|
||||||
|
},
|
||||||
|
root: {
|
||||||
|
persons: [T.Person.SecondPlurMale, T.Person.SecondPlurFemale],
|
||||||
|
aspects: ["imperfective", "perfective"],
|
||||||
|
},
|
||||||
|
verb: manul,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "with regular intransitive verbs",
|
||||||
|
cases: [
|
||||||
|
{
|
||||||
|
input: "رسېدلم",
|
||||||
|
output: [
|
||||||
|
{
|
||||||
|
root: {
|
||||||
|
persons: [T.Person.FirstSingMale, T.Person.FirstSingFemale],
|
||||||
|
aspects: ["imperfective", "perfective"],
|
||||||
|
},
|
||||||
|
verb: rasedul,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
input: "رسېدم",
|
||||||
|
output: [
|
||||||
|
{
|
||||||
|
root: {
|
||||||
|
persons: [T.Person.FirstSingMale, T.Person.FirstSingFemale],
|
||||||
|
aspects: ["imperfective", "perfective"],
|
||||||
|
},
|
||||||
|
verb: rasedul,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
input: "رسېږې",
|
||||||
|
output: [
|
||||||
|
{
|
||||||
|
stem: {
|
||||||
|
persons: [T.Person.SecondSingMale, T.Person.SecondSingFemale],
|
||||||
|
aspects: ["imperfective", "perfective"],
|
||||||
|
},
|
||||||
|
verb: rasedul,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
// short version of intransitive as well
|
||||||
|
{
|
||||||
|
input: "رسئ",
|
||||||
|
output: [
|
||||||
|
{
|
||||||
|
stem: {
|
||||||
|
persons: [T.Person.SecondPlurMale, T.Person.SecondPlurFemale],
|
||||||
|
aspects: ["imperfective", "perfective"],
|
||||||
|
},
|
||||||
|
verb: rasedul,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "verbs with irregular stems",
|
||||||
|
cases: [
|
||||||
|
{
|
||||||
|
input: "وینم",
|
||||||
|
output: [
|
||||||
|
{
|
||||||
|
stem: {
|
||||||
|
persons: [T.Person.FirstSingMale, T.Person.FirstSingFemale],
|
||||||
|
aspects: ["imperfective", "perfective"],
|
||||||
|
},
|
||||||
|
verb: leedul,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
input: "وینم",
|
||||||
|
output: [
|
||||||
|
{
|
||||||
|
stem: {
|
||||||
|
persons: [T.Person.FirstSingMale, T.Person.FirstSingFemale],
|
||||||
|
aspects: ["imperfective", "perfective"],
|
||||||
|
},
|
||||||
|
verb: leedul,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
input: "لیده",
|
||||||
|
output: [
|
||||||
|
{
|
||||||
|
root: {
|
||||||
|
persons: [T.Person.ThirdSingFemale],
|
||||||
|
aspects: ["imperfective", "perfective"],
|
||||||
|
},
|
||||||
|
verb: leedul,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
input: "خورې",
|
||||||
|
output: [
|
||||||
|
{
|
||||||
|
stem: {
|
||||||
|
persons: [T.Person.SecondSingMale, T.Person.SecondSingFemale],
|
||||||
|
aspects: ["imperfective", "perfective"],
|
||||||
|
},
|
||||||
|
verb: khorul,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
input: "خوړي",
|
||||||
|
output: [],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
input: "خوړم",
|
||||||
|
output: [
|
||||||
|
{
|
||||||
|
root: {
|
||||||
|
persons: [T.Person.FirstSingMale, T.Person.FirstSingFemale],
|
||||||
|
aspects: ["imperfective", "perfective"],
|
||||||
|
},
|
||||||
|
verb: khorul,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "verbs with seperating prefix",
|
||||||
|
cases: [
|
||||||
|
{
|
||||||
|
input: "کېني",
|
||||||
|
output: [
|
||||||
|
{
|
||||||
|
stem: {
|
||||||
|
persons: [
|
||||||
|
T.Person.ThirdSingMale,
|
||||||
|
T.Person.ThirdSingFemale,
|
||||||
|
T.Person.ThirdPlurMale,
|
||||||
|
T.Person.ThirdPlurFemale,
|
||||||
|
],
|
||||||
|
aspects: ["imperfective", "perfective"],
|
||||||
|
},
|
||||||
|
verb: kenaastul,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
input: "نم",
|
||||||
|
output: [
|
||||||
|
{
|
||||||
|
stem: {
|
||||||
|
persons: [T.Person.FirstSingMale, T.Person.FirstSingFemale],
|
||||||
|
aspects: ["perfective"],
|
||||||
|
},
|
||||||
|
verb: kenaastul,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
input: "پرېږدو",
|
||||||
|
output: [
|
||||||
|
{
|
||||||
|
stem: {
|
||||||
|
persons: [T.Person.FirstPlurMale, T.Person.FirstPlurFemale],
|
||||||
|
aspects: ["imperfective", "perfective"],
|
||||||
|
},
|
||||||
|
verb: prexodul,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
input: "پرېښوده",
|
||||||
|
output: [
|
||||||
|
{
|
||||||
|
root: {
|
||||||
|
persons: [T.Person.ThirdSingFemale],
|
||||||
|
aspects: ["imperfective", "perfective"],
|
||||||
|
},
|
||||||
|
verb: prexodul,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
input: "ښودله",
|
||||||
|
output: [
|
||||||
|
{
|
||||||
|
root: {
|
||||||
|
persons: [T.Person.ThirdSingFemale],
|
||||||
|
aspects: ["imperfective", "perfective"],
|
||||||
|
},
|
||||||
|
verb: xodul,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
root: {
|
||||||
|
persons: [T.Person.ThirdSingFemale],
|
||||||
|
aspects: ["perfective"],
|
||||||
|
},
|
||||||
|
verb: prexodul,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
root: {
|
||||||
|
persons: [T.Person.ThirdSingFemale],
|
||||||
|
aspects: ["perfective"],
|
||||||
|
},
|
||||||
|
verb: kexodul,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
tests.forEach(({ label, cases }) => {
|
||||||
|
test(label, () => {
|
||||||
|
cases.forEach(({ input, output }) => {
|
||||||
|
const tokens = tokenizer(input);
|
||||||
|
const vbs = parseVerb(tokens, verbLookup).map((r) => r.body);
|
||||||
|
const madeVbsS = output.reduce<Omit<T.VBE, "ps">[]>((acc, o) => {
|
||||||
|
return [
|
||||||
|
...acc,
|
||||||
|
...(["root", "stem"] as const).flatMap((base) =>
|
||||||
|
(o[base]?.aspects || []).flatMap((aspect) =>
|
||||||
|
(o[base]?.persons || []).flatMap((person) => ({
|
||||||
|
type: "VB" as const,
|
||||||
|
person,
|
||||||
|
info: {
|
||||||
|
type: "verb" as const,
|
||||||
|
aspect,
|
||||||
|
base,
|
||||||
|
verb: o.verb,
|
||||||
|
},
|
||||||
|
}))
|
||||||
|
)
|
||||||
|
),
|
||||||
|
];
|
||||||
|
}, []);
|
||||||
|
expect(vbs).toIncludeSameMembers(madeVbsS);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
|
@ -2,63 +2,183 @@ import * as T from "../../../types";
|
||||||
|
|
||||||
export function parseVerb(
|
export function parseVerb(
|
||||||
tokens: Readonly<T.Token[]>,
|
tokens: Readonly<T.Token[]>,
|
||||||
verbLookup: (s: (e: T.VerbDictionaryEntry) => boolean) => T.VerbEntry[]
|
verbLookup: (s: string) => T.VerbEntry[]
|
||||||
): T.ParseResult<Omit<T.VBE, "ps">>[] {
|
): T.ParseResult<Omit<T.VBE, "ps">>[] {
|
||||||
if (tokens.length === 0) {
|
if (tokens.length === 0) {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
const [first, ...rest] = tokens;
|
const [first, ...rest] = tokens;
|
||||||
const people = getVerbEnding(first.s);
|
const people = getVerbEnding(first.s);
|
||||||
if (people.length === 0) {
|
// TODO: can optimize this to not have to look for possible stems/roots if none
|
||||||
return [];
|
const verbs = verbLookup(first.s);
|
||||||
}
|
return matchVerbs(first.s, verbs, people).map((body) => ({
|
||||||
const verbs = findByStem(first.s.slice(0, -1), verbLookup);
|
tokens: rest,
|
||||||
|
body,
|
||||||
return people.flatMap((person) =>
|
errors: [],
|
||||||
verbs.map((verb) => ({
|
}));
|
||||||
tokens: rest,
|
|
||||||
body: {
|
|
||||||
type: "VB",
|
|
||||||
person,
|
|
||||||
info: {
|
|
||||||
type: "verb",
|
|
||||||
aspect: "imperfective",
|
|
||||||
base: "stem",
|
|
||||||
verb,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
errors: [],
|
|
||||||
}))
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function getVerbEnding(p: string): T.Person[] {
|
function matchVerbs(
|
||||||
|
s: string,
|
||||||
|
entries: T.VerbEntry[],
|
||||||
|
people: {
|
||||||
|
root: T.Person[];
|
||||||
|
stem: T.Person[];
|
||||||
|
}
|
||||||
|
): Omit<T.VBE, "ps">[] {
|
||||||
|
const w: Omit<T.VBE, "ps">[] = [];
|
||||||
|
const base = s.endsWith("ل") ? s : s.slice(0, -1);
|
||||||
|
if (people.stem.length) {
|
||||||
|
const stemMatches = {
|
||||||
|
imperfective: entries.filter(({ entry: e }) => {
|
||||||
|
if (e.c.includes("comp")) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (e.psp) {
|
||||||
|
return e.psp === base;
|
||||||
|
}
|
||||||
|
if (e.c.includes("intrans.")) {
|
||||||
|
const miniRoot = e.p.slice(0, -3);
|
||||||
|
return miniRoot + "ېږ" === base || miniRoot === base;
|
||||||
|
} else {
|
||||||
|
return e.p.slice(0, -1) === base;
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
perfective: entries.filter(({ entry: e }) => {
|
||||||
|
if (e.c.includes("comp")) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (e.ssp) {
|
||||||
|
const bSep = e.separationAtP ? e.ssp.slice(e.separationAtP) : "";
|
||||||
|
return bSep === base || e.ssp === base;
|
||||||
|
}
|
||||||
|
if (e.psp) {
|
||||||
|
const bSep = e.separationAtP ? e.psp.slice(e.separationAtP) : "";
|
||||||
|
return bSep === base || e.psp === base;
|
||||||
|
}
|
||||||
|
if (e.c.includes("intrans.")) {
|
||||||
|
const miniRoot = e.p.slice(0, -3);
|
||||||
|
return miniRoot + "ېږ" === base || miniRoot === base;
|
||||||
|
} else {
|
||||||
|
return e.p.slice(0, -1) === base;
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
};
|
||||||
|
Object.entries(stemMatches).forEach(([aspect, entries]) => {
|
||||||
|
entries.forEach((verb) => {
|
||||||
|
people.stem.forEach((person) => {
|
||||||
|
w.push({
|
||||||
|
type: "VB",
|
||||||
|
person,
|
||||||
|
info: {
|
||||||
|
type: "verb",
|
||||||
|
aspect: aspect as T.Aspect,
|
||||||
|
base: "stem",
|
||||||
|
verb: verb,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (people.root.length) {
|
||||||
|
const rootMatches = {
|
||||||
|
imperfective: entries.filter(
|
||||||
|
({ entry: e }) =>
|
||||||
|
!e.c.includes("comp") &&
|
||||||
|
(base === e.p || (!s.endsWith("ل") && base === e.p.slice(0, -1)))
|
||||||
|
),
|
||||||
|
perfective: entries.filter(({ entry: e }) => {
|
||||||
|
if (e.c.includes("comp")) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (e.separationAtP) {
|
||||||
|
const bSep = e.p.slice(e.separationAtP);
|
||||||
|
return (
|
||||||
|
base === bSep ||
|
||||||
|
base === e.p ||
|
||||||
|
(!s.endsWith("ل") &&
|
||||||
|
(base === e.p.slice(0, -1) || base === bSep.slice(0, -1)))
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
// TODO: perfective roots are so rare could optimize this with a couple of checks?
|
||||||
|
return e.prp
|
||||||
|
? e.prp === base || e.prp.slice(0, -1) === base
|
||||||
|
: base === e.p || (!s.endsWith("ل") && base === e.p.slice(0, -1));
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
};
|
||||||
|
Object.entries(rootMatches).forEach(([aspect, entries]) => {
|
||||||
|
entries.forEach((verb) => {
|
||||||
|
people.root.forEach((person) => {
|
||||||
|
w.push({
|
||||||
|
type: "VB",
|
||||||
|
person,
|
||||||
|
info: {
|
||||||
|
type: "verb",
|
||||||
|
aspect: aspect as T.Aspect,
|
||||||
|
base: "root",
|
||||||
|
verb: verb,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return w;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getVerbEnding(p: string): {
|
||||||
|
root: T.Person[];
|
||||||
|
stem: T.Person[];
|
||||||
|
} {
|
||||||
if (p.endsWith("م")) {
|
if (p.endsWith("م")) {
|
||||||
return [T.Person.FirstSingMale, T.Person.FirstSingFemale];
|
return {
|
||||||
|
root: [T.Person.FirstSingMale, T.Person.FirstSingFemale],
|
||||||
|
stem: [T.Person.FirstSingMale, T.Person.FirstSingFemale],
|
||||||
|
};
|
||||||
} else if (p.endsWith("ې")) {
|
} else if (p.endsWith("ې")) {
|
||||||
return [T.Person.SecondSingMale, T.Person.SecondSingFemale];
|
return {
|
||||||
|
root: [
|
||||||
|
T.Person.SecondSingMale,
|
||||||
|
T.Person.SecondSingFemale,
|
||||||
|
T.Person.ThirdPlurFemale,
|
||||||
|
],
|
||||||
|
stem: [T.Person.SecondSingMale, T.Person.SecondSingFemale],
|
||||||
|
};
|
||||||
} else if (p.endsWith("ي")) {
|
} else if (p.endsWith("ي")) {
|
||||||
return [
|
return {
|
||||||
T.Person.ThirdSingMale,
|
stem: [
|
||||||
T.Person.ThirdSingFemale,
|
T.Person.ThirdSingMale,
|
||||||
T.Person.ThirdPlurMale,
|
T.Person.ThirdSingFemale,
|
||||||
T.Person.ThirdPlurFemale,
|
T.Person.ThirdPlurMale,
|
||||||
];
|
T.Person.ThirdPlurFemale,
|
||||||
|
],
|
||||||
|
root: [],
|
||||||
|
};
|
||||||
} else if (p.endsWith("و")) {
|
} else if (p.endsWith("و")) {
|
||||||
return [T.Person.FirstPlurMale, T.Person.FirstPlurFemale];
|
return {
|
||||||
|
root: [T.Person.FirstPlurMale, T.Person.FirstPlurFemale],
|
||||||
|
stem: [T.Person.FirstPlurMale, T.Person.FirstPlurFemale],
|
||||||
|
};
|
||||||
} else if (p.endsWith("ئ")) {
|
} else if (p.endsWith("ئ")) {
|
||||||
return [T.Person.SecondPlurMale, T.Person.SecondPlurFemale];
|
return {
|
||||||
|
root: [T.Person.SecondPlurMale, T.Person.SecondPlurFemale],
|
||||||
|
stem: [T.Person.SecondPlurMale, T.Person.SecondPlurFemale],
|
||||||
|
};
|
||||||
|
} else if (p.endsWith("ه")) {
|
||||||
|
return {
|
||||||
|
root: [T.Person.ThirdSingFemale],
|
||||||
|
stem: [],
|
||||||
|
};
|
||||||
|
} else if (p.endsWith("ل")) {
|
||||||
|
return {
|
||||||
|
root: [T.Person.ThirdPlurMale],
|
||||||
|
stem: [],
|
||||||
|
};
|
||||||
}
|
}
|
||||||
return [];
|
return {
|
||||||
}
|
root: [],
|
||||||
|
stem: [],
|
||||||
function findByStem(
|
};
|
||||||
stem: string,
|
|
||||||
verbLookup: (s: (e: T.VerbDictionaryEntry) => boolean) => T.VerbEntry[]
|
|
||||||
): T.VerbEntry[] {
|
|
||||||
return verbLookup(
|
|
||||||
(e) =>
|
|
||||||
e.psp === stem ||
|
|
||||||
(!e.psp && !e.c.includes("comp") && e.p.slice(0, -1) === stem)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,42 +28,167 @@ const kedulStat = vEntry({
|
||||||
ec: "become",
|
ec: "become",
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// cool examples: زه خوږې ماشومې وهم
|
||||||
|
|
||||||
export function parseVP(
|
export function parseVP(
|
||||||
tokens: Readonly<T.Token[]>,
|
tokens: Readonly<T.Token[]>,
|
||||||
lookup: (s: Partial<T.DictionaryEntry>) => T.DictionaryEntry[],
|
lookup: (s: Partial<T.DictionaryEntry>) => T.DictionaryEntry[],
|
||||||
verbLookup: (s: (e: T.VerbDictionaryEntry) => boolean) => T.VerbEntry[]
|
verbLookup: (s: string) => T.VerbEntry[]
|
||||||
): T.ParseResult<T.VPSelectionComplete>[] {
|
): T.ParseResult<T.VPSelectionComplete>[] {
|
||||||
if (tokens.length === 0) {
|
if (tokens.length === 0) {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
// how to make this into a nice pipeline... 🤔
|
// how to make this into a nice pipeline... 🤔
|
||||||
const NP1 = parseNP(tokens, lookup).filter(({ errors }) => !errors.length);
|
const NP1 = parseNP(tokens, lookup).filter(({ errors }) => !errors.length);
|
||||||
const NP2 = bindParseResult(
|
const NP2 = bindParseResult<
|
||||||
NP1,
|
{
|
||||||
(tokens) => parseNP(tokens, lookup),
|
inflected: boolean;
|
||||||
true
|
selection: T.NPSelection;
|
||||||
).filter(({ errors }) => !errors.length);
|
},
|
||||||
const vb = bindParseResult(
|
{
|
||||||
NP2,
|
np1: {
|
||||||
(tokens) => parseVerb(tokens, verbLookup),
|
inflected: boolean;
|
||||||
true
|
selection: T.NPSelection;
|
||||||
).filter(({ errors }) => !errors.length);
|
};
|
||||||
|
np2:
|
||||||
|
| {
|
||||||
|
inflected: boolean;
|
||||||
|
selection: T.NPSelection;
|
||||||
|
}
|
||||||
|
| undefined;
|
||||||
|
}
|
||||||
|
>(NP1, (tokens, np1) => {
|
||||||
|
const np2s = parseNP(tokens, lookup);
|
||||||
|
if (!np2s.length) {
|
||||||
|
const r: T.ParseResult<{
|
||||||
|
np1: {
|
||||||
|
inflected: boolean;
|
||||||
|
selection: T.NPSelection;
|
||||||
|
};
|
||||||
|
np2: undefined;
|
||||||
|
}>[] = [
|
||||||
|
{
|
||||||
|
tokens,
|
||||||
|
body: {
|
||||||
|
np1,
|
||||||
|
np2: undefined,
|
||||||
|
},
|
||||||
|
errors: [],
|
||||||
|
},
|
||||||
|
];
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
return np2s.map((p) => ({
|
||||||
|
tokens: p.tokens,
|
||||||
|
body: {
|
||||||
|
np1,
|
||||||
|
np2: p.body,
|
||||||
|
},
|
||||||
|
errors: p.errors,
|
||||||
|
}));
|
||||||
|
}).filter(({ errors }) => !errors.length);
|
||||||
|
const vb = bindParseResult(NP2, (tokens, nps) => {
|
||||||
|
const vb = parseVerb(tokens, verbLookup);
|
||||||
|
// TODO make a nice functor that just maps or adds in the body
|
||||||
|
return vb.map((p) => ({
|
||||||
|
tokens: p.tokens,
|
||||||
|
body: {
|
||||||
|
np2: nps.np2,
|
||||||
|
v: p.body,
|
||||||
|
np1: nps.np1,
|
||||||
|
},
|
||||||
|
errors: p.errors,
|
||||||
|
}));
|
||||||
|
}).filter(({ errors }) => !errors.length);
|
||||||
// TODO: be able to bind mulitple vals
|
// TODO: be able to bind mulitple vals
|
||||||
return bindParseResult<Omit<T.VBE, "ps">, T.VPSelectionComplete>(
|
return bindParseResult(vb, (tokens, { np1, np2, v }) => {
|
||||||
vb,
|
const w: T.ParseResult<T.VPSelectionComplete>[] = [];
|
||||||
(tokens, v) => {
|
const isPast = v.info.type === "verb" && v.info.base === "root";
|
||||||
const w: T.ParseResult<T.VPSelectionComplete>[] = [];
|
const intransitive =
|
||||||
NP1.forEach(({ body: np1 }) => {
|
v.info.type === "verb" && v.info.verb.entry.c.includes("intrans.");
|
||||||
NP2.forEach(({ body: np2 }) => {
|
|
||||||
// NICE TODO: IF there's an error in any of the NPS, don't try
|
if (!np2) {
|
||||||
// to make the VPS - just show them that error
|
const errors: T.ParseError[] = [];
|
||||||
// for that we probably need a different type of
|
const s = np1;
|
||||||
[
|
if (!intransitive) {
|
||||||
[np1, np2],
|
return [];
|
||||||
[np2, np1],
|
}
|
||||||
].forEach(([s, o]) => {
|
if (s.inflected) {
|
||||||
const errors: T.ParseError[] = [];
|
errors.push({
|
||||||
const subjPerson = getPersonFromNP(s.selection);
|
message: "subject of intransitive verb should not be inflected",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (getPersonFromNP(s.selection) !== v.person) {
|
||||||
|
errors.push({
|
||||||
|
message: "subject should agree with intransitive verb",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
const blocks: T.VPSBlockComplete[] = [
|
||||||
|
{
|
||||||
|
key: 1,
|
||||||
|
block: makeSubjectSelectionComplete(s.selection),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 2,
|
||||||
|
block: {
|
||||||
|
type: "objectSelection",
|
||||||
|
selection: "none",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
];
|
||||||
|
const verb: T.VerbSelectionComplete = {
|
||||||
|
type: "verb",
|
||||||
|
verb: v.info.type === "verb" ? v.info.verb : kedulStat,
|
||||||
|
transitivity: "intransitive",
|
||||||
|
canChangeTransitivity: false,
|
||||||
|
canChangeStatDyn: false,
|
||||||
|
negative: false,
|
||||||
|
tense: isPast ? "imperfectivePast" : "presentVerb",
|
||||||
|
canChangeVoice: true,
|
||||||
|
isCompound: false,
|
||||||
|
voice: "active",
|
||||||
|
};
|
||||||
|
w.push({
|
||||||
|
tokens,
|
||||||
|
body: {
|
||||||
|
blocks,
|
||||||
|
verb,
|
||||||
|
externalComplement: undefined,
|
||||||
|
form: {
|
||||||
|
removeKing: false,
|
||||||
|
shrinkServant: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
errors,
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
[[np1, np2, false] as const, [np2, np1, true] as const].forEach(
|
||||||
|
([s, o, reversed]) => {
|
||||||
|
const subjPerson = getPersonFromNP(s.selection);
|
||||||
|
const errors: T.ParseError[] = [];
|
||||||
|
if (intransitive) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isPast) {
|
||||||
|
if (getPersonFromNP(o.selection) !== v.person) {
|
||||||
|
errors.push({
|
||||||
|
message: "transitive past tense verb does not match object",
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
if (!s.inflected) {
|
||||||
|
errors.push({
|
||||||
|
message: "transitive past tense subject should be inflected",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (o.inflected) {
|
||||||
|
errors.push({
|
||||||
|
message:
|
||||||
|
"transitive past tense object should not be inflected",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
if (getPersonFromNP(s.selection) !== v.person) {
|
if (getPersonFromNP(s.selection) !== v.person) {
|
||||||
errors.push({
|
errors.push({
|
||||||
message: "verb does not match subject",
|
message: "verb does not match subject",
|
||||||
|
@ -83,46 +208,49 @@ export function parseVP(
|
||||||
errors.push({ message: "object should not be inflected" });
|
errors.push({ message: "object should not be inflected" });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const blocks: T.VPSBlockComplete[] = [
|
const blocks: T.VPSBlockComplete[] = [
|
||||||
{
|
{
|
||||||
key: 1,
|
key: 1,
|
||||||
block: makeSubjectSelectionComplete(s.selection),
|
block: makeSubjectSelectionComplete(s.selection),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 2,
|
||||||
|
block: makeObjectSelectionComplete(o.selection),
|
||||||
|
},
|
||||||
|
];
|
||||||
|
if (reversed) {
|
||||||
|
blocks.reverse();
|
||||||
|
}
|
||||||
|
const verb: T.VerbSelectionComplete = {
|
||||||
|
type: "verb",
|
||||||
|
verb: v.info.type === "verb" ? v.info.verb : kedulStat,
|
||||||
|
transitivity: "transitive",
|
||||||
|
canChangeTransitivity: false,
|
||||||
|
canChangeStatDyn: false,
|
||||||
|
negative: false,
|
||||||
|
tense: isPast ? "imperfectivePast" : "presentVerb",
|
||||||
|
canChangeVoice: true,
|
||||||
|
isCompound: false,
|
||||||
|
voice: "active",
|
||||||
|
};
|
||||||
|
w.push({
|
||||||
|
tokens,
|
||||||
|
body: {
|
||||||
|
blocks,
|
||||||
|
verb,
|
||||||
|
externalComplement: undefined,
|
||||||
|
form: {
|
||||||
|
removeKing: false,
|
||||||
|
shrinkServant: false,
|
||||||
},
|
},
|
||||||
{
|
},
|
||||||
key: 2,
|
errors,
|
||||||
block: makeObjectSelectionComplete(o.selection),
|
|
||||||
},
|
|
||||||
];
|
|
||||||
const verb: T.VerbSelectionComplete = {
|
|
||||||
type: "verb",
|
|
||||||
verb: v.info.type === "verb" ? v.info.verb : kedulStat,
|
|
||||||
transitivity: "transitive",
|
|
||||||
canChangeTransitivity: false,
|
|
||||||
canChangeStatDyn: false,
|
|
||||||
negative: false,
|
|
||||||
tense: "presentVerb",
|
|
||||||
canChangeVoice: true,
|
|
||||||
isCompound: false,
|
|
||||||
voice: "active",
|
|
||||||
};
|
|
||||||
w.push({
|
|
||||||
tokens,
|
|
||||||
body: {
|
|
||||||
blocks,
|
|
||||||
verb,
|
|
||||||
externalComplement: undefined,
|
|
||||||
form: {
|
|
||||||
removeKing: false,
|
|
||||||
shrinkServant: false,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
errors,
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
});
|
}
|
||||||
});
|
);
|
||||||
return w;
|
|
||||||
}
|
}
|
||||||
);
|
return w;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,4 +2,8 @@
|
||||||
// allows you to do things like:
|
// allows you to do things like:
|
||||||
// expect(element).toHaveTextContent(/react/i)
|
// expect(element).toHaveTextContent(/react/i)
|
||||||
// learn more: https://github.com/testing-library/jest-dom
|
// learn more: https://github.com/testing-library/jest-dom
|
||||||
import '@testing-library/jest-dom';
|
import "@testing-library/jest-dom";
|
||||||
|
|
||||||
|
// add all jest-extended matchers
|
||||||
|
import * as matchers from "jest-extended";
|
||||||
|
expect.extend(matchers);
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
"jsx": "react-jsx"
|
"jsx": "react-jsx"
|
||||||
},
|
},
|
||||||
"include": [
|
"include": [
|
||||||
"src"
|
"src",
|
||||||
|
"testSetup.js"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
54
yarn.lock
54
yarn.lock
|
@ -1433,6 +1433,13 @@
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
node-notifier "^8.0.0"
|
node-notifier "^8.0.0"
|
||||||
|
|
||||||
|
"@jest/schemas@^29.6.0":
|
||||||
|
version "29.6.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@jest/schemas/-/schemas-29.6.0.tgz#0f4cb2c8e3dca80c135507ba5635a4fd755b0040"
|
||||||
|
integrity sha512-rxLjXyJBTL4LQeJW3aKo0M/+GkCOXsO+8i9Iu7eDb6KwtP65ayoDsitrdPBtujxQ88k4wI2FNYfa6TOGwSn6cQ==
|
||||||
|
dependencies:
|
||||||
|
"@sinclair/typebox" "^0.27.8"
|
||||||
|
|
||||||
"@jest/source-map@^26.6.2":
|
"@jest/source-map@^26.6.2":
|
||||||
version "26.6.2"
|
version "26.6.2"
|
||||||
resolved "https://registry.npmjs.org/@jest/source-map/-/source-map-26.6.2.tgz"
|
resolved "https://registry.npmjs.org/@jest/source-map/-/source-map-26.6.2.tgz"
|
||||||
|
@ -1640,6 +1647,11 @@
|
||||||
estree-walker "^1.0.1"
|
estree-walker "^1.0.1"
|
||||||
picomatch "^2.2.2"
|
picomatch "^2.2.2"
|
||||||
|
|
||||||
|
"@sinclair/typebox@^0.27.8":
|
||||||
|
version "0.27.8"
|
||||||
|
resolved "https://registry.yarnpkg.com/@sinclair/typebox/-/typebox-0.27.8.tgz#6667fac16c436b5434a387a34dedb013198f6e6e"
|
||||||
|
integrity sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==
|
||||||
|
|
||||||
"@sinonjs/commons@^1.7.0":
|
"@sinonjs/commons@^1.7.0":
|
||||||
version "1.8.3"
|
version "1.8.3"
|
||||||
resolved "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.3.tgz"
|
resolved "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.3.tgz"
|
||||||
|
@ -4283,6 +4295,11 @@ diff-sequences@^27.0.6:
|
||||||
resolved "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.0.6.tgz"
|
resolved "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.0.6.tgz"
|
||||||
integrity sha512-ag6wfpBFyNXZ0p8pcuIDS//D8H062ZQJ3fzYxjpmeKjnz8W4pekL3AI8VohmyZmsWW2PWaHgjsmqR6L13101VQ==
|
integrity sha512-ag6wfpBFyNXZ0p8pcuIDS//D8H062ZQJ3fzYxjpmeKjnz8W4pekL3AI8VohmyZmsWW2PWaHgjsmqR6L13101VQ==
|
||||||
|
|
||||||
|
diff-sequences@^29.4.3:
|
||||||
|
version "29.4.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-29.4.3.tgz#9314bc1fabe09267ffeca9cbafc457d8499a13f2"
|
||||||
|
integrity sha512-ofrBgwpPhCD85kMKtE9RYFFq6OC1A89oW2vvgWZNCwxrUpRUILopY7lsYyMDSjc8g6U6aiO0Qubg6r4Wgt5ZnA==
|
||||||
|
|
||||||
diffie-hellman@^5.0.0:
|
diffie-hellman@^5.0.0:
|
||||||
version "5.0.3"
|
version "5.0.3"
|
||||||
resolved "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz"
|
resolved "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz"
|
||||||
|
@ -6555,6 +6572,16 @@ jest-diff@^27.0.0:
|
||||||
jest-get-type "^27.0.6"
|
jest-get-type "^27.0.6"
|
||||||
pretty-format "^27.2.4"
|
pretty-format "^27.2.4"
|
||||||
|
|
||||||
|
jest-diff@^29.0.0:
|
||||||
|
version "29.6.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-29.6.2.tgz#c36001e5543e82a0805051d3ceac32e6825c1c46"
|
||||||
|
integrity sha512-t+ST7CB9GX5F2xKwhwCf0TAR17uNDiaPTZnVymP9lw0lssa9vG+AFyDZoeIHStU3WowFFwT+ky+er0WVl2yGhA==
|
||||||
|
dependencies:
|
||||||
|
chalk "^4.0.0"
|
||||||
|
diff-sequences "^29.4.3"
|
||||||
|
jest-get-type "^29.4.3"
|
||||||
|
pretty-format "^29.6.2"
|
||||||
|
|
||||||
jest-docblock@^26.0.0:
|
jest-docblock@^26.0.0:
|
||||||
version "26.0.0"
|
version "26.0.0"
|
||||||
resolved "https://registry.npmjs.org/jest-docblock/-/jest-docblock-26.0.0.tgz"
|
resolved "https://registry.npmjs.org/jest-docblock/-/jest-docblock-26.0.0.tgz"
|
||||||
|
@ -6598,6 +6625,14 @@ jest-environment-node@^26.6.2:
|
||||||
jest-mock "^26.6.2"
|
jest-mock "^26.6.2"
|
||||||
jest-util "^26.6.2"
|
jest-util "^26.6.2"
|
||||||
|
|
||||||
|
jest-extended@^4.0.1:
|
||||||
|
version "4.0.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/jest-extended/-/jest-extended-4.0.1.tgz#2315cb5914fc132e5acd07945bfaa01aac3947c2"
|
||||||
|
integrity sha512-KM6dwuBUAgy6QONuR19CGubZB9Hkjqvl/d5Yc/FXsdB8+gsGxB2VQ+NEdOrr95J4GMPeLnDoPOKyi6+mKCCnZQ==
|
||||||
|
dependencies:
|
||||||
|
jest-diff "^29.0.0"
|
||||||
|
jest-get-type "^29.0.0"
|
||||||
|
|
||||||
jest-get-type@^26.3.0:
|
jest-get-type@^26.3.0:
|
||||||
version "26.3.0"
|
version "26.3.0"
|
||||||
resolved "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz"
|
resolved "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz"
|
||||||
|
@ -6608,6 +6643,11 @@ jest-get-type@^27.0.6:
|
||||||
resolved "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.0.6.tgz"
|
resolved "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.0.6.tgz"
|
||||||
integrity sha512-XTkK5exIeUbbveehcSR8w0bhH+c0yloW/Wpl+9vZrjzztCPWrxhHwkIFpZzCt71oRBsgxmuUfxEqOYoZI2macg==
|
integrity sha512-XTkK5exIeUbbveehcSR8w0bhH+c0yloW/Wpl+9vZrjzztCPWrxhHwkIFpZzCt71oRBsgxmuUfxEqOYoZI2macg==
|
||||||
|
|
||||||
|
jest-get-type@^29.0.0, jest-get-type@^29.4.3:
|
||||||
|
version "29.4.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-29.4.3.tgz#1ab7a5207c995161100b5187159ca82dd48b3dd5"
|
||||||
|
integrity sha512-J5Xez4nRRMjk8emnTpWrlkyb9pfRQQanDrvWHhsR1+VUfbwxi30eVcZFlcdGInRibU4G5LwHXpI7IRHU0CY+gg==
|
||||||
|
|
||||||
jest-haste-map@^26.6.2:
|
jest-haste-map@^26.6.2:
|
||||||
version "26.6.2"
|
version "26.6.2"
|
||||||
resolved "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-26.6.2.tgz"
|
resolved "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-26.6.2.tgz"
|
||||||
|
@ -9092,6 +9132,15 @@ pretty-format@^27.0.0, pretty-format@^27.2.4:
|
||||||
ansi-styles "^5.0.0"
|
ansi-styles "^5.0.0"
|
||||||
react-is "^17.0.1"
|
react-is "^17.0.1"
|
||||||
|
|
||||||
|
pretty-format@^29.6.2:
|
||||||
|
version "29.6.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-29.6.2.tgz#3d5829261a8a4d89d8b9769064b29c50ed486a47"
|
||||||
|
integrity sha512-1q0oC8eRveTg5nnBEWMXAU2qpv65Gnuf2eCQzSjxpWFkPaPARwqZZDGuNE0zPAZfTCHzIk3A8dIjwlQKKLphyg==
|
||||||
|
dependencies:
|
||||||
|
"@jest/schemas" "^29.6.0"
|
||||||
|
ansi-styles "^5.0.0"
|
||||||
|
react-is "^18.0.0"
|
||||||
|
|
||||||
process-nextick-args@~2.0.0:
|
process-nextick-args@~2.0.0:
|
||||||
version "2.0.1"
|
version "2.0.1"
|
||||||
resolved "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz"
|
resolved "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz"
|
||||||
|
@ -9396,6 +9445,11 @@ react-is@^17.0.1:
|
||||||
resolved "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz"
|
resolved "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz"
|
||||||
integrity sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==
|
integrity sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==
|
||||||
|
|
||||||
|
react-is@^18.0.0:
|
||||||
|
version "18.2.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/react-is/-/react-is-18.2.0.tgz#199431eeaaa2e09f86427efbb4f1473edb47609b"
|
||||||
|
integrity sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==
|
||||||
|
|
||||||
react-lifecycles-compat@^3.0.4:
|
react-lifecycles-compat@^3.0.4:
|
||||||
version "3.0.4"
|
version "3.0.4"
|
||||||
resolved "https://registry.npmjs.org/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz"
|
resolved "https://registry.npmjs.org/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz"
|
||||||
|
|
Loading…
Reference in New Issue