From b4a84645eafd4edf2a1d5219e40cecf0a80db4a8 Mon Sep 17 00:00:00 2001 From: lingdocs <71590811+lingdocs@users.noreply.github.com> Date: Tue, 26 Apr 2022 13:08:32 +0500 Subject: [PATCH] up --- package.json | 2 +- scripts/misc-query.js | 8 +- src/components/VPBuilder.tsx | 11 +- .../equative-explorer/EquativeDisplay.tsx | 155 ------------ .../equative-explorer/EquativeExplorer.tsx | 70 ------ .../equative-explorer/explorer-inputs.ts | 37 --- .../equative-explorer/explorer-reducer.ts | 110 --------- .../equative-explorer/explorer-selectors.tsx | 233 ------------------ .../equative-explorer/explorer-types.ts | 52 ---- src/content/equatives/equative-explorer.mdx | 20 +- src/lib/entry-feeder.ts | 16 ++ src/types/gramm-types.d.ts | 9 + src/words/words.ts | 19 +- tsconfig.json | 5 + yarn.lock | 8 +- 15 files changed, 65 insertions(+), 690 deletions(-) delete mode 100644 src/components/equative-explorer/EquativeDisplay.tsx delete mode 100644 src/components/equative-explorer/EquativeExplorer.tsx delete mode 100644 src/components/equative-explorer/explorer-inputs.ts delete mode 100644 src/components/equative-explorer/explorer-reducer.ts delete mode 100644 src/components/equative-explorer/explorer-selectors.tsx delete mode 100644 src/components/equative-explorer/explorer-types.ts create mode 100644 src/lib/entry-feeder.ts diff --git a/package.json b/package.json index 1c322d0..bd78a14 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,7 @@ "dependencies": { "@fortawesome/fontawesome-free": "^5.15.4", "@lingdocs/lingdocs-main": "^0.2.0", - "@lingdocs/pashto-inflector": "^2.0.5", + "@lingdocs/pashto-inflector": "^2.3.2", "@testing-library/jest-dom": "^5.11.4", "@testing-library/react": "^11.1.0", "@testing-library/user-event": "^12.1.10", diff --git a/scripts/misc-query.js b/scripts/misc-query.js index 98888d8..c578966 100644 --- a/scripts/misc-query.js +++ b/scripts/misc-query.js @@ -1,7 +1,6 @@ const fs = require("fs"); const fetch = require("node-fetch"); const path = require("path"); -const { readDictionary } = require("@lingdocs/pashto-inflector"); const verbsPath = path.join(".", "src", "words"); const pChars = [ "آ", @@ -51,10 +50,11 @@ const pChars = [ 'ږ', ]; -fetch(process.env.LINGDOCS_DICTIONARY_URL).then(res => res.arrayBuffer()).then(data => { - const { entries } = readDictionary(data); + +fetch(process.env.LINGDOCS_DICTIONARY_URL + ".json").then(res => res.json()).then(data => { + const { entries } = data; const filtered = shuffle(entries.filter(e => ( - e.c?.includes("n. f.") && e.p.endsWith("ي") + e.c?.includes("loc. adv.") ))); const content = `module.exports = [ ${filtered.reduce((text, entry) => ( diff --git a/src/components/VPBuilder.tsx b/src/components/VPBuilder.tsx index 2af3b53..7f5e557 100644 --- a/src/components/VPBuilder.tsx +++ b/src/components/VPBuilder.tsx @@ -4,11 +4,8 @@ import { EntrySelect, Types as T, } from "@lingdocs/pashto-inflector"; -import { - nouns, - verbs, -} from "../words/words"; import { useStickyState } from "@lingdocs/pashto-inflector"; +import entryFeeder from "../lib/entry-feeder"; function VPBuilder() { const [entry, setEntry] = useStickyState(undefined, "vEntrySelect"); @@ -18,7 +15,7 @@ function VPBuilder() { :
Choose a verb to start building diff --git a/src/components/equative-explorer/EquativeDisplay.tsx b/src/components/equative-explorer/EquativeDisplay.tsx deleted file mode 100644 index 8828882..0000000 --- a/src/components/equative-explorer/EquativeDisplay.tsx +++ /dev/null @@ -1,155 +0,0 @@ -import { - VerbTable, - defaultTextOptions as opts, - ButtonSelect, - Types as T, - personGender, - personIsPlural, - typePredicates, -} from "@lingdocs/pashto-inflector"; -import { - ExplorerState, - ExplorerReducerAction, -} from "./explorer-types"; -import { - equativeMachine, - assembleEquativeOutput, -} from "../../lib/equative-machine"; -const { - isUnisexNounEntry, - isAdjectiveEntry, - isVerbEntry, - isLocativeAdverbEntry, - isNounEntry, -} = typePredicates; - -function chooseLength(o: T.SingleOrLengthOpts, length: "short" | "long"): O { - return ("long" in o) ? o[length] : o; -} - -function SingleItemDisplay({ state }: { state: ExplorerState }) { - if (state.subject.type === "pronouns") { - return
ERROR: Wrong display being used
; - } - try { - const se = state.subject[state.subject.type]; - const pe = state.predicate[state.predicate.type]; - const subject = makeNounPhrase(se, state, "subject"); - const predicate = (isAdjectiveEntry(pe) || isLocativeAdverbEntry(pe)) - ? makeComplement(pe) - : makeNounPhrase(pe, state, "predicate"); - const block = assembleEquativeOutput( - equativeMachine({ - subject, - predicate, - tense: state.tense, - negative: state.negative, - }) - ); - return
- -
; - } catch (e) { - console.error(e); - return
Error making equative sentence
- } -} - -function makeComplement(entry: T.AdjectiveEntry | T.LocativeAdverbEntry): Compliment { - return { - type: "compliment", - entry, - }; -} - -function makeNounPhrase(entry: T.NounEntry | T.UnisexNounEntry | T.VerbEntry, state: ExplorerState, entity: "subject" | "predicate"): NounPhrase { - if (isVerbEntry(entry)) { - return { - type: "participle", - entry, - }; - } - return { - type: "noun", - number: state[entity].info.number, - gender: state[entity].info.gender, - entry, - }; -} - -export function makeBlockWPronouns(e: T.AdjectiveEntry | T.UnisexNounEntry | T.LocativeAdverbEntry, tense: EquativeTense, negative: boolean, length?: "short" | "long"): T.SingleOrLengthOpts { - // if the output's gonna have long / short forms (if it's past or wouldBe) then recursive call to make the long and short versions - if (!length && "long" in assembleEquativeOutput(equativeMachine({ - subject: { type: "pronoun", pronounType: "near", person: 0 }, - predicate: (isAdjectiveEntry(e) || isLocativeAdverbEntry(e)) - ? { type: "compliment", entry: e } - : { type: "noun", gender: "masc", number: "singular", entry: e }, - tense, - negative, - }))) { - return { - short: makeBlockWPronouns(e, tense, negative, "short") as T.VerbBlock, - long: makeBlockWPronouns(e, tense, negative, "long") as T.VerbBlock, - }; - } - const makeP = (p: T.Person): T.ArrayOneOrMore => { - const b = assembleEquativeOutput(equativeMachine({ - subject: { type: "pronoun", pronounType: "far", person: p }, - predicate: (isAdjectiveEntry(e) || isLocativeAdverbEntry(e)) - ? { type: "compliment", entry: e } - : { type: "noun", gender: personGender(p), number: personIsPlural(p) ? "plural" : "singular", entry: e }, - tense, - negative, - })); - if ("long" in b) { - if (!length) throw new Error("bad length processing"); - return b[length]; - } - return b; - }; - return [ - [makeP(0), makeP(6)], - [makeP(1), makeP(7)], - [makeP(2), makeP(8)], - [makeP(3), makeP(9)], - [makeP(4), makeP(10)], - [makeP(5), makeP(11)], - ]; -} - -function PronounBlockDisplay({ state }: { state: ExplorerState }) { - const pred = state.predicate[state.predicate.type]; - if (!isVerbEntry(pred) && (isAdjectiveEntry(pred) || isLocativeAdverbEntry(pred) || (isNounEntry(pred) && isUnisexNounEntry(pred)))) { - const block = makeBlockWPronouns(pred, state.tense, state.negative); - return ; - } - return
Invalid combination
-} - -function EquativeDisplay({ state, dispatch }: { state: ExplorerState, dispatch: (action: ExplorerReducerAction) => void }) { - return <> - {(state.tense === "past" || state.tense === "wouldBe") &&
- dispatch({ type: "setLength", payload: p as "long" | "short" })} - /> -
} - {state.subject.type === "pronouns" - ? - : - } - {state.predicate.type === "participle" &&
- Note: This means that the subject is the act of the participle/verb, not that the subject is currently doing the verb! -
} - ; -} - -export default EquativeDisplay; diff --git a/src/components/equative-explorer/EquativeExplorer.tsx b/src/components/equative-explorer/EquativeExplorer.tsx deleted file mode 100644 index 24e6e66..0000000 --- a/src/components/equative-explorer/EquativeExplorer.tsx +++ /dev/null @@ -1,70 +0,0 @@ -import { useState } from "react"; -import { - reducer, -} from "./explorer-reducer"; -import { - InputSelector, - TenseSelector, -} from "./explorer-selectors"; -import { - ExplorerState, - ExplorerReducerAction, -} from "./explorer-types"; -import { - defaultUnisexNoun, - defaultAdjective, - defaultNoun, - defaultParticiple, - defaultAdverb, -} from "./explorer-inputs"; -import EquativeDisplay from "./EquativeDisplay"; - -const defaultState: ExplorerState = { - tense: "present", - length: "short", - negative: false, - predicate: { - type: "adjective", - adjective: defaultAdjective, - adverb: defaultAdverb, - unisexNoun: defaultUnisexNoun, - participle: defaultParticiple, - noun: defaultNoun, - info: { - number: "singular", - gender: "masc", - }, - }, - subject: { - type: "pronouns", - noun: defaultNoun, - participle: defaultParticiple, - unisexNoun: defaultUnisexNoun, - info: { - number: "singular", - gender: "masc", - }, - }, -}; - -function EquativeExplorer() { - const [state, unsafeSetState] = useState(defaultState); - function dispatch(action: ExplorerReducerAction) { - const newState = reducer(state, action); - unsafeSetState(newState); - } - return <> - -
-
- -
-
- -
-
- - ; -} - -export default EquativeExplorer; \ No newline at end of file diff --git a/src/components/equative-explorer/explorer-inputs.ts b/src/components/equative-explorer/explorer-inputs.ts deleted file mode 100644 index 48dab49..0000000 --- a/src/components/equative-explorer/explorer-inputs.ts +++ /dev/null @@ -1,37 +0,0 @@ -import { nouns, adjectives, verbs, adverbs } from "../../words/words"; -import { - Types as T, - typePredicates as tp, -} from "@lingdocs/pashto-inflector"; - -function sort(arr: Readonly): T[] { - if ("entry" in arr[0]) { - return [...arr].sort((a, b) => ( - // @ts-ignore - a.entry.p.localeCompare(b.entry.p) - )); - } - return [...arr].sort((a, b) => ( - // @ts-ignore - a.p.localeCompare(b.p) - )); -} - -const unisexNouns = sort(nouns.filter(x => tp.isUnisexNounEntry(x)) as T.UnisexNounEntry[]); -const nonUnisexNouns = sort(nouns.filter(x => !tp.isUnisexNounEntry(x)) as (T.MascNounEntry | T.FemNounEntry)[]); - -const inputs = { - adjective: sort(adjectives), - unisexNoun: unisexNouns, - noun: nonUnisexNouns, - participle: sort(verbs), - adverb: sort(adverbs.filter(tp.isLocativeAdverbEntry)), -}; - -export const defaultAdjective = inputs.adjective.find(ps => ps.p === "زوړ") || inputs.adjective[0]; -export const defaultAdverb = inputs.adverb.find(ps => ps.p === "دلته") || inputs.adverb[0]; -export const defaultUnisexNoun = inputs.unisexNoun.find(ps => ps.p === "پښتون") || inputs.unisexNoun[0]; -export const defaultNoun = inputs.noun.find(ps => ps.p === "کتاب") || inputs.noun[0]; -export const defaultParticiple = inputs.participle.find(ps => ps.entry.p === "لیکل") || inputs.participle[0]; - -export default inputs; \ No newline at end of file diff --git a/src/components/equative-explorer/explorer-reducer.ts b/src/components/equative-explorer/explorer-reducer.ts deleted file mode 100644 index 086f39f..0000000 --- a/src/components/equative-explorer/explorer-reducer.ts +++ /dev/null @@ -1,110 +0,0 @@ -import inputs from "./explorer-inputs"; -import { ExplorerState, ExplorerReducerAction } from "./explorer-types"; -import { - Types as T, -} from "@lingdocs/pashto-inflector"; - -export function reducer(state: ExplorerState, action: ExplorerReducerAction): ExplorerState { - if (action.type === "setPredicate") { - const pile = inputs[state.predicate.type] as (T.UnisexNounEntry | T.AdjectiveEntry)[]; - const predicate = (pile.find(p => p.ts === action.payload) || pile[0]); - return { - ...state, - predicate: { - ...state.predicate, - [state.predicate.type]: predicate, - }, - }; - } - if (action.type === "setPredicateType") { - const predicateType = action.payload; - return { - ...state, - predicate: { - ...state.predicate, - type: predicateType, - }, - }; - } - if (action.type === "setSubjectType") { - const subjectType = action.payload; - return { - ...state, - subject: { - ...state.subject, - type: subjectType, - }, - predicate: { - ...state.predicate, - type: ( - subjectType === "pronouns" && - !["adjective", "adverb", "unisexNoun"].includes(state.predicate.type) - ) ? "adjective" : state.predicate.type, - }, - }; - } - if (action.type === "setSubject") { - if (state.subject.type === "pronouns") return state; - const pile = inputs[state.subject.type]; - // @ts-ignore - const subject = (pile.find(p => p.ts === action.payload) || pile[0]); - return { - ...state, - subject: { - ...state.subject, - [state.subject.type]: subject, - }, - }; - } - if (action.type === "setNumber") { - const entity = action.payload.entity; - return { - ...state, - [entity]: { - ...state[entity], - info: { - ...state[entity].info, - number: action.payload.number, - }, - }, - }; - } - if (action.type === "setGender") { - const entity = action.payload.entity; - return { - ...state, - [entity]: { - ...state[entity], - info: { - ...state[entity].info, - gender: action.payload.gender, - }, - }, - }; - } - if (action.type === "setTense") { - return { - ...state, - tense: action.payload, - }; - } - // if (action.type === "setPredicateEntity") { - // return { - // ...state, - // predicate: { - // ...state.predicate, - // entity: action.payload, - // }, - // }; - // } - if (action.type === "setNegative") { - return { - ...state, - negative: action.payload, - }; - } - return { - ...state, - length: action.payload, - }; -} \ No newline at end of file diff --git a/src/components/equative-explorer/explorer-selectors.tsx b/src/components/equative-explorer/explorer-selectors.tsx deleted file mode 100644 index 49622ed..0000000 --- a/src/components/equative-explorer/explorer-selectors.tsx +++ /dev/null @@ -1,233 +0,0 @@ -// import { makeOptionLabel } from "./explorer-helpers"; -import inputs from "./explorer-inputs"; -import { - ExplorerReducerAction, - ExplorerState, - SubjectType, - PredicateType, -} from "./explorer-types"; -import { - getEnglishParticiple, -} from "../../lib/np-tools"; -import { - ButtonSelect, - getEnglishWord, - Types as T, - removeFVarients, - typePredicates, -} from "@lingdocs/pashto-inflector"; -import Select from "react-select"; -const { - isAdjectiveEntry, - isAdverbEntry, - isFemNounEntry, - isMascNounEntry, - isNounEntry, - isPluralNounEntry, -} = typePredicates; - -const zIndexProps = { - menuPortalTarget: document.body, - styles: { menuPortal: (base: any) => ({ ...base, zIndex: 9999 }) }, -}; - -const npTypeOptions: { type: SubjectType, label: string }[] = [ - { type: "unisexNoun", label: "Unisex Noun"}, - { type: "noun", label: "Noun" }, - { type: "participle", label: "Participle" }, -]; -const subjectTypeOptions: { type: SubjectType, label: string }[] = [ - { type: "pronouns" as SubjectType, label: "Pronouns" } -]; -const compTypeOptions: { type: PredicateType, label: string }[] = [ - { type: "adjective", label: "Adjective" }, - { type: "adverb", label: "Loc. Adverb" }, -]; - -export function InputSelector({ state, dispatch, entity }: { - state: ExplorerState, - dispatch: (action: ExplorerReducerAction) => void, - entity: "subject" | "predicate", -}) { - const typeOptions = [ - ...entity === "subject" - ? subjectTypeOptions - : compTypeOptions, - ...npTypeOptions.filter(o => !(entity === "predicate" && ( - (state.subject.type === "pronouns" && ["noun", "participle"].includes(o.type)) - // || (state.subject.type === "unisexNoun" && o.type === "unisexNoun") - ))), - ]; - - function onTypeSelect(e: React.ChangeEvent) { - if (entity === "subject") { - const t = e.target.value as SubjectType; - dispatch({ type: "setSubjectType", payload: t }); - } else { - const t = e.target.value as PredicateType; - dispatch({ type: "setPredicateType", payload: t }); - } - } - - function onEntrySelect({ value }: any) { - dispatch({ type: entity === "subject" ? "setSubject" : "setPredicate", payload: parseInt(value) }); - } - - function CheckboxItem({ type, label }: { type: string, label: string }) { - const id = `${entity}-${type}-radio`; - return
- - -
- } - - const type = state[entity].type; - const entry: T.NounEntry | T.VerbEntry | T.AdjectiveEntry | T.LocativeAdverbEntry | undefined = type === "pronouns" - ? undefined - // @ts-ignore - : state[entity][type]; - const options = type === "pronouns" - ? [] - : inputs[type].map(makeOption); - - return
-
{entity === "subject" ? "Subject:" : "Predicate:"}
-
- {typeOptions.map(({ type, label }) => ( - - ))} -
- {type !== "pronouns" && <> - o.value === state.tense)?.label} - {...zIndexProps} - /> -
- dispatch({ type: "setNegative", payload: p === "neg" })} - /> -
-
-} diff --git a/src/components/equative-explorer/explorer-types.ts b/src/components/equative-explorer/explorer-types.ts deleted file mode 100644 index 8b864ee..0000000 --- a/src/components/equative-explorer/explorer-types.ts +++ /dev/null @@ -1,52 +0,0 @@ -import { Types as T } from "@lingdocs/pashto-inflector"; - -export type PredicateNPType = "noun" | "unisexNoun" | "participle"; -export type PredicateCompType = "adjective" | "adverb"; -export type PredicateType = PredicateNPType | PredicateCompType; -export type SubjectType = "pronouns" | "noun" | "unisexNoun" | "participle"; - -export type ExplorerState = { - tense: EquativeTense, - length: "short" | "long", - subject: SubjectEntityInfo, - predicate: PredicateEntityInfo, - negative: boolean, -}; - -export type SubjectEntityInfo = EntitiyInfo & { type: SubjectType }; - -export type PredicateEntityInfo = EntitiyInfo & { - type: PredicateType, - adjective: import("@lingdocs/pashto-inflector").Types.AdjectiveEntry, - adverb: import("@lingdocs/pashto-inflector").Types.LocativeAdverbEntry, -} - -type EntitiyInfo = { - noun: import("@lingdocs/pashto-inflector").Types.NounEntry, - participle: import("@lingdocs/pashto-inflector").Types.VerbEntry, - unisexNoun: import("@lingdocs/pashto-inflector").Types.UnisexNounEntry, - info: { - number: NounNumber, - gender: T.Gender, - }, -}; - -export type ExplorerReducerAction = { - type: "setPredicateType", payload: PredicateType, -} | { - type: "setPredicate", payload: number, -} | { - type: "setSubjectType", payload: SubjectType, -} | { - type: "setSubject", payload: number, -} | { - type: "setNumber", payload: { entity: "subject" | "predicate", number: NounNumber }, -} | { - type: "setGender", payload: { entity: "subject" | "predicate", gender: T.Gender }, -} | { - type: "setTense", payload: EquativeTense, -} | { - type: "setLength", payload: "short" | "long", -} | { - type: "setNegative", payload: boolean, -}; \ No newline at end of file diff --git a/src/content/equatives/equative-explorer.mdx b/src/content/equatives/equative-explorer.mdx index ae02e6c..4da33a7 100644 --- a/src/content/equatives/equative-explorer.mdx +++ b/src/content/equatives/equative-explorer.mdx @@ -2,17 +2,15 @@ title: Equative Explorer 🌎 --- -import EquativeExplorer from "../../components/equative-explorer/EquativeExplorer"; -import { useState } from "react"; - -You can use this tool to explore how to make different equative sentences. Everything that comes out of this will be **gramatically correct**, but the sentences might not always make sense! 🤪 +import { + EPExplorer, + defaultTextOptions, +} from "@lingdocs/pashto-inflector"; +import entryFeeder from "../../lib/entry-feeder";
- +
- -### Equative Rules: 👨‍🏫 - -- The **subject** has to be a **noun phrase** -- The **predicate** can be a **noun phrase** or **compliment** -- In Pashto, if the predicate is a noun phrase, the equative agrees with the predicate. Otherwise, if the predicate is a compliment, the equative agrees with the subject. In English, the equative always agrees with the subject. diff --git a/src/lib/entry-feeder.ts b/src/lib/entry-feeder.ts new file mode 100644 index 0000000..d5d7b50 --- /dev/null +++ b/src/lib/entry-feeder.ts @@ -0,0 +1,16 @@ +import { Types as T } from "@lingdocs/pashto-inflector"; +import { + nouns, + verbs, + adjectives, + locativeAdverbs, +} from "../words/words"; + +const entryFeeder: T.EntryFeeder = { + nouns, + verbs, + adjectives, + locativeAdverbs, +} + +export default entryFeeder; \ No newline at end of file diff --git a/src/types/gramm-types.d.ts b/src/types/gramm-types.d.ts index d57bc7a..eb6b6bd 100644 --- a/src/types/gramm-types.d.ts +++ b/src/types/gramm-types.d.ts @@ -1,6 +1,15 @@ // TODO: I think this is just used for the old equative explorer // build a new better equative explorer using NP Pickers etc and deprecate all this +type EPSelection = { + subject: NPSelection, + predicate: NPSelection | EComplementSelection, + equative: { + tense: EquativeTense, + negative: boolean, + }, +}; + type EquativeTense = "present" | "subjunctive" | "habitual" | "past" | "future" | "wouldBe" | "pastSubjunctive"; type NounNumber = "singular" | "plural"; diff --git a/src/words/words.ts b/src/words/words.ts index c937a00..f6dee8e 100644 --- a/src/words/words.ts +++ b/src/words/words.ts @@ -5,16 +5,23 @@ import { } from "@lingdocs/pashto-inflector"; import { categorize } from "../lib/categorize"; -const words = categorize(rawWords, { - "nouns": tp.isNounEntry, - "adjectives": tp.isAdjectiveEntry, - "verbs": tp.isVerbEntry, - "adverbs": tp.isAdverbEntry, +const words = categorize(rawWords, { + nouns: tp.isNounEntry, + adjectives: tp.isAdjectiveEntry, + verbs: tp.isVerbEntry, + adverbs: tp.isAdverbEntry, + locativeAdverbs: tp.isLocativeAdverbEntry, }); export default words; -export const { nouns, adjectives, verbs, adverbs } = words; +export const { nouns, adjectives, verbs, adverbs, locativeAdverbs } = words; // console.log( // Object.entries( diff --git a/tsconfig.json b/tsconfig.json index b625491..06f8f21 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -21,6 +21,11 @@ "jsx": "react-jsx", "noFallthroughCasesInSwitch": true }, + "ts-node": { + "compilerOptions": { + "module": "commonjs" + } + }, "include": [ "src" ] diff --git a/yarn.lock b/yarn.lock index c1263bb..e7b0a72 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1684,10 +1684,10 @@ pbf "^3.2.1" rambda "^6.7.0" -"@lingdocs/pashto-inflector@^2.0.5": - version "2.0.5" - resolved "https://npm.lingdocs.com/@lingdocs%2fpashto-inflector/-/pashto-inflector-2.0.5.tgz#b917428e81395206d78f8f72122dddc4432364b3" - integrity sha512-WdkunOYqj3045Too4PioDIh9ljYXrbGiV+CVZtbF8s8Bnw/L+6Y7ShgYFb2DQalkwtis+5BJzzcKMMUE4ZtTYQ== +"@lingdocs/pashto-inflector@^2.3.2": + version "2.3.2" + resolved "https://npm.lingdocs.com/@lingdocs%2fpashto-inflector/-/pashto-inflector-2.3.2.tgz#59c42d5bbe4e2befc467cd506b12a11632545eaf" + integrity sha512-EGWHwe8RdRD7NcZtE4CVUQGSvfXCcVyTrNmmqv1kJeRLZIn2MN2UMCbGRMZcz3681mCQvvfkRpsAD8xJSSjyNw== dependencies: classnames "^2.2.6" pbf "^3.2.1"