Compare commits

...

2 Commits

Author SHA1 Message Date
adueck b0ed40fb07 fixing progress bar on game sections 2024-07-08 15:34:50 -04:00
adueck 9a6cd29af6 added plural noun game 2024-07-08 14:42:10 -04:00
12 changed files with 888 additions and 583 deletions

View File

@ -17,7 +17,7 @@
"@formkit/auto-animate": "^1.0.0-beta.6",
"@fortawesome/fontawesome-free": "5.15.4",
"@lingdocs/lingdocs-main": "^0.3.3",
"@lingdocs/ps-react": "^7.1.6",
"@lingdocs/ps-react": "^7.1.7",
"@mdx-js/rollup": "^2.2.1",
"@stefanprobst/rehype-extract-toc": "^2.2.0",
"@types/mdx": "^2.0.3",

View File

@ -173,6 +173,20 @@ export const contentTree: (ChapterSection | ChaptersSection)[] =
"slug": "other-equatives"
}
]
},
{
"heading": "Inflection 🔘",
"subdirectory": "inflection",
"chapters": [
{
"import": inflectionIntro,
"slug": "inflection-intro"
},
{
"import": inflectionPatterns,
"slug": "inflection-patterns"
}
]
},
{
"heading": "Nouns",
@ -358,20 +372,6 @@ export const contentTree: (ChapterSection | ChaptersSection)[] =
}
]
},
{
"heading": "Inflection 🔘",
"subdirectory": "inflection",
"chapters": [
{
"import": inflectionIntro,
"slug": "inflection-intro"
},
{
"import": inflectionPatterns,
"slug": "inflection-patterns"
}
]
},
{
"heading": "Sandwiches 🥪",
"subdirectory": "sandwiches",

View File

@ -42,7 +42,7 @@ These words always end in:
- **Feminine:** - <InlinePs opts={opts} ps={{ p: "ـه", f: "-a" }} />
<InflectionCarousel
items={startingWord(words.filter(tp.isPattern1Entry), "غټ")}
items={startingWord(words.filter(n => tp.isPattern1Entry(n) && !n.c.includes("adv.")), "غټ")}
/>
**Note:** See exceptions below.

View File

@ -12,6 +12,10 @@ import mascEndingChart from "./masc-plural-ending-decision-chart.excalidraw.svg"
import femEndingChart from "./fem-plural-ending-decision-chart.excalidraw.svg";
import PluralTable from "./PluralTable";
import VideoPlayer from "../../components/VideoPlayer";
import {
pluralNounGame,
} from "../../games/games";
import GameDisplay from "../../games/GameDisplay";
export const Pattern1 = () => <Link to="/nouns/nouns-unisex/#1-basic">Pattern #1</Link>;
export const Pattern2 = () => <Link to="/inflection/inflection-patterns/#2-words-ending-in-an-unstressed-%DB%8C---ay">Pattern #2</Link>;
@ -561,3 +565,5 @@ The <InlinePs opts={opts} ps={{ p: "انې", f: "áane" }} /> can be added to fe
/>
</div>
<GameDisplay record={pluralNounGame} />

View File

@ -4,17 +4,16 @@ import { useUser } from "../user-context";
import Link from "../components/Link";
// @ts-ignore
import SmoothCollapse from "react-smooth-collapse";
import {
AT,
} from "@lingdocs/lingdocs-main";
import { AT } from "@lingdocs/lingdocs-main";
function GamesBrowser() {
const { user } = useUser();
const [opened, setOpened] = useState<string | undefined>(undefined);
function handleChapterClick(id: string) {
setOpened(prev => prev === id ? undefined : id);
setOpened((prev) => (prev === id ? undefined : id));
}
return <div>
return (
<div>
{games.map((chapter) => (
<div key={chapter.chapter}>
<ChapterDisplay
@ -26,59 +25,83 @@ function GamesBrowser() {
</div>
))}
</div>
);
}
function ChapterDisplay({ chapter, user, handleClick, expanded }: {
chapter: { chapter: string, items: GameRecord[] },
user: AT.LingdocsUser | undefined,
handleClick: (chapter: string) => void,
expanded: boolean,
function ChapterDisplay({
chapter,
user,
handleClick,
expanded,
}: {
chapter: { chapter: string; items: GameRecord[] };
user: AT.LingdocsUser | undefined;
handleClick: (chapter: string) => void;
expanded: boolean;
}) {
const [opened, setOpened] = useState<string | undefined>(undefined);
const progress = getPercentageComplete(chapter, user?.tests);
function handleTitleClick(id: string) {
setOpened(prev => prev === id ? undefined : id);
setOpened((prev) => (prev === id ? undefined : id));
}
return <div className="mb-3">
<div className="card clickable" onClick={() => handleClick(chapter.chapter)}>
<div className="card-body" style={{
return (
<div className="mb-3">
<div
className="card clickable"
onClick={() => handleClick(chapter.chapter)}
>
<div
className="card-body"
style={{
backgroundColor: expanded ? "#e6e6e6" : "inherit",
}}>
}}
>
<h4>{chapter.chapter}</h4>
<ChapterProgress progress={progress} />
</div>
</div>
<SmoothCollapse expanded={expanded}>
{chapter.items.map(({ id, title, Game }) => {
const done = user?.tests.some(t => t.done && t.id === id);
const done = user?.tests.some((t) => t.done && t.id === id);
const open = opened === id;
return <div key={id}>
return (
<div key={id}>
<div className="d-flex flex-row justify-content-between align-items-center">
<div>
<h5 className="my-3 clickable" onClick={() => handleTitleClick(id)}>
<i className={`fas fa-caret-${open ? "down" : "right"}`}></i> {title}
<h5
className="my-3 clickable"
onClick={() => handleTitleClick(id)}
>
<i
className={`fas fa-caret-${open ? "down" : "right"}`}
></i>{" "}
{title}
{` `}
</h5>
</div>
<div>
{done && <h4></h4>}
</div>
<div>{done && <h4></h4>}</div>
</div>
<SmoothCollapse expanded={open}>
{open && <Game inChapter={false} />}
</SmoothCollapse>
</div>
);
})}
</SmoothCollapse>
</div>
);
}
function ChapterProgress({ progress }: { progress: "not logged in" | number }) {
if (progress === "not logged in") {
return <div className="small text-muted"><Link to="/account">Log in</Link> to see progress</div>;
return (
<div className="small text-muted">
<Link to="/account">Log in</Link> to see progress
</div>
);
}
return <div>
return (
<div>
<div className="small text-muted">{progress}% mastered</div>
<div className="progress my-1" style={{ height: "5px" }}>
<div
@ -87,25 +110,24 @@ function ChapterProgress({ progress }: { progress: "not logged in" | number }) {
style={{ width: `${progress}%` }}
/>
</div>
</div>;
}
function getPercentageComplete(
chapter: { chapter: string, items: GameRecord[] },
tests: undefined | AT.TestResult[],
): "not logged in" | number {
if (!tests) return "not logged in";
const chapterTestIds = chapter.items.map(gr => gr.id);
const userCompletedIds = tests.filter(t => t.done).map(t => t.id);
const required = chapterTestIds.length;
const completed = chapterTestIds
.filter(x => userCompletedIds.includes(x))
.length;
return Math.round(
(completed / (required + 1)) * 100
</div>
);
}
function getPercentageComplete(
chapter: { chapter: string; items: GameRecord[] },
tests: undefined | AT.TestResult[]
): "not logged in" | number {
if (!tests) return "not logged in";
const chapterTestIds = chapter.items.map((gr) => gr.id);
const userCompletedIds = tests.filter((t) => t.done).map((t) => t.id);
const required = chapterTestIds.length;
const completed = chapterTestIds.filter((x) =>
userCompletedIds.includes(x)
).length;
return Math.round((completed / required) * 100);
}
export default GamesBrowser;

View File

@ -1,6 +1,7 @@
import EquativeGame from "./sub-cores/EquativeGame";
import VerbGame from "./sub-cores/VerbGame";
import GenderGame from "./sub-cores/GenderGame";
import PluralNounGame from "./sub-cores/PluralNounGame";
import UnisexNounGame from "./sub-cores/UnisexNounGame";
import EquativeSituations from "./sub-cores/EquativeSituations";
import VerbSituations from "./sub-cores/VerbSituations";
@ -12,7 +13,6 @@ import PerfectVerbsIntransitive from "./sub-cores/PerfectGame";
import NPAdjWriting from "./sub-cores/NPAdjGame";
import EPAdjGame from "./sub-cores/EPAdjGame";
// NOUNS
export const nounGenderGame1 = makeGameRecord({
title: "Identify Noun Genders - Level 1",
@ -35,6 +35,13 @@ export const unisexNounGame = makeGameRecord({
level: undefined,
SubCore: UnisexNounGame,
});
export const pluralNounGame = makeGameRecord({
title: "Making nouns plural",
id: "plural-nouns-1",
link: "/nouns/nouns-plural/",
level: undefined,
SubCore: PluralNounGame,
});
// INFLECTIONS
export const inflectionTableGame1 = makeGameRecord({
@ -138,7 +145,7 @@ export const equativeGameWouldBe = makeGameRecord({
SubCore: EquativeGame,
});
export const equativeGamePastSubjunctive = makeGameRecord({
title: 'Write the past subjunctive equative',
title: "Write the past subjunctive equative",
id: "equative-past-subjunctive",
link: "/equatives/other-equatives/#past-subjunctive",
level: "pastSubjunctive",
@ -178,119 +185,119 @@ export const presentVerbGame1 = makeGameRecord({
title: "Write the present verb (one)",
id: "present-verbs-write-1",
link: "/verbs/present-verbs/",
level: { level: 1, type :"presentVerb" },
level: { level: 1, type: "presentVerb" },
SubCore: VerbGame,
});
export const presentVerbGame2 = makeGameRecord({
title: "Write the present verb (mix)",
id: "present-verbs-write-2",
link: "/verbs/present-verbs/",
level: { level: 2, type :"presentVerb" },
level: { level: 2, type: "presentVerb" },
SubCore: VerbGame,
});
export const subjunctiveVerbGame1 = makeGameRecord({
title: "Write the subjunctive verb (one)",
id: "subjunctive-verbs-write-1",
link: "/verbs/subjunctive-verbs/",
level: { level: 1, type :"subjunctiveVerb" },
level: { level: 1, type: "subjunctiveVerb" },
SubCore: VerbGame,
});
export const subjunctiveVerbGame2 = makeGameRecord({
title: "Write the subjunctive verb (mix)",
id: "subjunctive-verbs-write-2",
link: "/verbs/subjunctive-verbs/",
level: { level: 2, type :"subjunctiveVerb" },
level: { level: 2, type: "subjunctiveVerb" },
SubCore: VerbGame,
});
export const futureVerbGame1 = makeGameRecord({
title: "Write the future verb (one)",
id: "future-verbs-write-1",
link: "/verbs/future-verbs/",
level: { level: 1, type :"futureVerb" },
level: { level: 1, type: "futureVerb" },
SubCore: VerbGame,
});
export const futureVerbGame2 = makeGameRecord({
title: "Write the future verb (mix)",
id: "future-verbs-write-2",
link: "/verbs/future-verbs/",
level: { level: 2, type :"futureVerb" },
level: { level: 2, type: "futureVerb" },
SubCore: VerbGame,
});
export const imperativeVerbGame1 = makeGameRecord({
title: "Write the imperative verb (one)",
id: "imperative-verbs-write-1",
link: "/verbs/imperative-verbs/",
level: { level: 1, type :"imperative" },
level: { level: 1, type: "imperative" },
SubCore: VerbGame,
});
export const imperativeVerbGame2 = makeGameRecord({
title: "Write the imperative verb (mix)",
id: "imperative-verbs-write-2",
link: "/verbs/imperative-verbs/",
level: { level: 2, type :"imperative" },
level: { level: 2, type: "imperative" },
SubCore: VerbGame,
});
export const intransitivePerfectivePastVerbGame1 = makeGameRecord({
title: "Write the intransitive simple past verb (one)",
id: "intransitive-perfective-past-verbs-write-1",
link: "/verbs/past-verbs/#past-tense-with-intransitive-verbs-",
level: { level: 1, type :"intransitivePerfectivePast" },
level: { level: 1, type: "intransitivePerfectivePast" },
SubCore: VerbGame,
});
export const intransitivePerfectivePastVerbGame2 = makeGameRecord({
title: "Write the intransitive simple past verb (mix)",
id: "intransitive-perfective-past-verbs-write-2",
link: "/verbs/past-verbs/#past-tense-with-intransitive-verbs-",
level: { level: 2, type :"intransitivePerfectivePast" },
level: { level: 2, type: "intransitivePerfectivePast" },
SubCore: VerbGame,
});
export const intransitiveImperfectivePastVerbGame1 = makeGameRecord({
title: "Write the intransitive continuous past verb (one)",
id: "intransitive-imperfective-past-verbs-write-1",
link: "/verbs/past-verbs/#past-tense-with-intransitive-verbs-",
level: { level: 1, type :"intransitiveImperfectivePast" },
level: { level: 1, type: "intransitiveImperfectivePast" },
SubCore: VerbGame,
});
export const intransitiveImperfectivePastVerbGame2 = makeGameRecord({
title: "Write the intransitive continuous past verb (mix)",
id: "intransitive-imperfective-past-verbs-write-2",
link: "/verbs/past-verbs/#past-tense-with-intransitive-verbs-",
level: { level: 2, type :"intransitiveImperfectivePast" },
level: { level: 2, type: "intransitiveImperfectivePast" },
SubCore: VerbGame,
});
export const transitivePerfectivePastVerbGame1 = makeGameRecord({
title: "Write the transitive simple past verb (one)",
id: "transitive-perfective-past-verbs-write-1",
link: "/verbs/past-verbs/#past-tense-with-transitive-verbs-",
level: { level: 1, type :"transitivePerfectivePast" },
level: { level: 1, type: "transitivePerfectivePast" },
SubCore: VerbGame,
});
export const transitivePerfectivePastVerbGame2 = makeGameRecord({
title: "Write the transitive simple past verb (mix)",
id: "transitive-perfective-past-verbs-write-2",
link: "/verbs/past-verbs/#past-tense-with-transitive-verbs-",
level: { level: 2, type :"transitivePerfectivePast" },
level: { level: 2, type: "transitivePerfectivePast" },
SubCore: VerbGame,
});
export const transitiveImperfectivePastVerbGame1 = makeGameRecord({
title: "Write the transitive continuous past verb (one)",
id: "transitive-imperfective-past-verbs-write-1",
link: "/verbs/past-verbs/#past-tense-with-transitive-verbs-",
level: { level: 1, type :"transitiveImperfectivePast" },
level: { level: 1, type: "transitiveImperfectivePast" },
SubCore: VerbGame,
});
export const transitiveImperfectivePastVerbGame2 = makeGameRecord({
title: "Write the transitive continuous past verb (mix)",
id: "transitive-imperfective-past-verbs-write-2",
link: "/verbs/past-verbs/#past-tense-with-transitive-verbs-",
level: { level: 2, type :"transitiveImperfectivePast" },
level: { level: 2, type: "transitiveImperfectivePast" },
SubCore: VerbGame,
});
export const habitualPastVerbGame1 = makeGameRecord({
title: "Write the habitual past verb (one)",
id: "habitual-past-verbs-write-1",
link: "/verbs/past-verbs/#habitual-past-tenses",
level: { level: 1, type : "habitualPast" },
level: { level: 1, type: "habitualPast" },
SubCore: VerbGame,
});
export const habitualPastVerbGame2 = makeGameRecord({
@ -304,7 +311,7 @@ export const allPastVerbGame1 = makeGameRecord({
title: "Write the past verb - all past tenses (one)",
id: "all-past-verbs-write-1",
link: "/verbs/past-verbs/",
level: { level: 1, type : "allPast" },
level: { level: 1, type: "allPast" },
SubCore: VerbGame,
});
export const allPastVerbGame2 = makeGameRecord({
@ -318,7 +325,7 @@ export const allVerbGame1 = makeGameRecord({
title: "Write verb - all tenses (one)",
id: "all-verbs-write-1",
link: "/verbs/master-chart/",
level: { level: 1, type : "allPast" },
level: { level: 1, type: "allPast" },
SubCore: VerbGame,
});
export const allVerbGame2 = makeGameRecord({
@ -435,14 +442,10 @@ export const npWithAdjectivesInSandwiches = makeGameRecord({
SubCore: NPAdjWriting,
});
const games: { chapter: string, items: GameRecord[] }[] = [
const games: { chapter: string; items: GameRecord[] }[] = [
{
chapter: "Nouns",
items: [
nounGenderGame1,
nounGenderGame2,
unisexNounGame,
],
items: [nounGenderGame1, nounGenderGame2, unisexNounGame, pluralNounGame],
},
{
chapter: "Inflection",
@ -527,20 +530,26 @@ const games: { chapter: string, items: GameRecord[] }[] = [
// check to make sure we have no duplicate game keys
games.forEach(({ items }) => {
const allAreUnique = (arr: unknown[]) => arr.length === new Set(arr).size;
const ids = items.map(x => x.id);
const titles = items.map(x => x.title);
const ids = items.map((x) => x.id);
const titles = items.map((x) => x.title);
if (!allAreUnique(titles)) throw new Error("duplicate game title");
if (!allAreUnique(ids)) throw new Error("duplicate game key");
})
});
export default games;
function makeGameRecord<T>({ title, id, link, level, SubCore }:{
title: string,
id: string,
link: string,
level: T,
SubCore: GameSubCore<T>,
function makeGameRecord<T>({
title,
id,
link,
level,
SubCore,
}: {
title: string;
id: string;
link: string;
level: T;
SubCore: GameSubCore<T>;
}): GameRecord {
return {
title,
@ -548,5 +557,5 @@ function makeGameRecord<T>({ title, id, link, level, SubCore }:{
Game: ({ inChapter }: { inChapter: boolean }) => (
<SubCore inChapter={inChapter} id={id} level={level} link={link} />
),
}
};
}

View File

@ -0,0 +1,288 @@
import { useState } from "react";
import { comparePs } from "../../lib/game-utils";
import genderColors from "../../lib/gender-colors";
import GameCore from "../GameCore";
import {
Types as T,
Examples,
defaultTextOptions as opts,
inflectWord,
firstVariation,
typePredicates as tp,
randFromArray,
removeFVarients,
psStringFromEntry,
} from "@lingdocs/ps-react";
import { wordQuery } from "../../words/words";
import { makePool } from "../../lib/pool";
export const nouns = wordQuery("nouns", [
"dUaa",
"idaa",
"raNaa",
"angrez",
"xudza",
"ihtiyaaj",
"safar",
"khob",
"gUl",
"wakht",
"watan",
"qaazee",
"bachay",
"spay",
"nmasay",
"atal",
"puxtoon",
"wayaand",
"dzaay",
"kitaab",
"peesho",
"ghul",
"shpoon",
"xUwoonkay",
"gaawanDay",
"sakhtee",
"dostee",
"aRtiyaa",
"DaakTar",
"laas",
"waadu",
"dost",
"maar",
"lewu",
"چرګ",
"zmaray",
"zalmay",
"paakistaanay",
"baaNoo",
"maamaa",
"kaakaa",
"qaazuy",
"نرس",
"ghwaa",
"gwaax",
"gaam",
"andzoor",
"ghlaa",
"mlaa",
"khabura",
"andexna",
"برقه",
"پښه",
"پوښتنه",
"تمه",
"shpa",
"kurxa",
"amsaa",
"tsaa",
"مېلمستیا",
"وینا",
"plaan",
"bayragh",
"ghaax",
"فلم",
"marg",
"kaal",
"noom",
"paachaa",
"laalaa",
"بوټی",
"پېټی",
"توری",
"غړی",
"کاڼی",
"کلی",
"مړی",
"چېلی",
"کوچی",
"eeraanay",
"lmasay",
"baazoo",
"chaaqoo",
"paaroo",
"weeDiyo",
]);
// type NType =
// | "pattern1"
// | "pattern2"
// | "pattern3"
// | "pattern4"
// | "pattern5"
// | "other";
// // TODO: make pattern types as overlay types
// const types = intoPatterns(nouns);
const genders: T.Gender[] = ["masc", "fem"];
const amount = 25;
type Question = {
entry: T.DictionaryEntry;
singular: T.PsString;
plural: T.PsString[];
gender: T.Gender;
};
export default function PluralNounGame({
id,
link,
inChapter,
}: {
inChapter: boolean;
id: string;
link: string;
}) {
const getFromNounPool = makePool(nouns);
// let pool = { ...types };
function getQuestion(): Question {
const entry = getFromNounPool();
const gender: T.Gender = tp.isUnisexNounEntry(entry)
? randFromArray(genders)
: tp.isFemNounEntry(entry)
? "fem"
: "masc";
const [singular, plural] = getSingAndPlural({ entry, gender });
if (!singular || plural.length === 0) {
console.log({ singular, plural });
throw new Error("unable to generate plurals for " + entry.p);
}
return {
entry,
gender,
singular,
plural,
};
}
function getSingAndPlural({
entry,
gender,
}: {
entry: T.DictionaryEntry;
gender: T.Gender;
}): [T.PsString, T.PsString[]] {
const infs = inflectWord(entry);
if (!infs) {
throw new Error("Unable to inflect word for plural");
}
const inflections: T.InflectionSet =
infs.inflections && gender in infs.inflections
? // @ts-ignore
infs.inflections[gender]
: undefined;
const plural: T.PluralInflectionSet =
// @ts-ignore
"plural" in infs && infs.plural ? infs.plural[gender] : undefined;
const singular = inflections
? inflections[0][0]
: psStringFromEntry(removeFVarients(entry));
const allPlurals = [
...(inflections ? inflections[1] : []),
...(plural ? plural[0] : []),
];
return [singular, allPlurals];
}
function Display({ question, callback }: QuestionDisplayProps<Question>) {
const [answer, setAnswer] = useState<string>("");
const handleInput = ({
target: { value },
}: React.ChangeEvent<HTMLInputElement>) => {
setAnswer(value);
};
const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => {
e.preventDefault();
const a = answer.replace(" ګ", "ګ").replace(" گ", "گ");
const correct = comparePs(a, question.plural);
if (correct) {
setAnswer("");
}
callback(correct);
};
function makePartOfSpeechInfo(q: Question) {
return `(n. ${q.gender === "masc" ? "m" : "f"}. ${
q.entry.c?.includes("anim.") ? "anim." : ""
})`;
}
return (
<div>
<div
className="pt-2 pb-1 mb-2"
style={{
maxWidth: "300px",
margin: "0 auto",
backgroundColor:
genderColors[question.gender === "masc" ? "m" : "f"],
}}
>
<Examples opts={opts}>
{[
{
...question.singular,
e: `${firstVariation(question.entry.e)} ${makePartOfSpeechInfo(
question
)}`,
},
]}
</Examples>
</div>
<div>is a singular noun. Make it plural.</div>
<form onSubmit={handleSubmit}>
<div className="my-3" style={{ maxWidth: "200px", margin: "0 auto" }}>
<input
type="text"
className="form-control"
autoComplete="off"
autoCapitalize="off"
spellCheck="false"
dir="auto"
value={answer}
onChange={handleInput}
/>
<div className="text-muted small mt-3">
Type <kbd>Enter</kbd> to check
</div>
</div>
</form>
</div>
);
}
function Instructions() {
return (
<div>
<h5>Make the given noun plural</h5>
</div>
);
}
function DisplayCorrectAnswer({ question }: { question: Question }) {
return (
<div>
{question.plural.length > 1 && (
<div className="text-muted">One of the following:</div>
)}
{question.plural.map((ps: any) => (
<Examples opts={opts}>{ps}</Examples>
))}
</div>
);
}
return (
<GameCore
inChapter={inChapter}
studyLink={link}
getQuestion={getQuestion}
id={id}
Display={Display}
DisplayCorrectAnswer={DisplayCorrectAnswer}
amount={amount}
timeLimit={175}
Instructions={Instructions}
/>
);
}

View File

@ -13,7 +13,7 @@ export function makePool<P>(poolBase: P[], removalLaxity = 0): () => P {
let pool = [...poolBase];
function shouldStillKeepIt() {
if (!removalLaxity) return false;
return Math.random() < (removalLaxity / 100);
return Math.random() < removalLaxity / 100;
}
function pickRandomFromPool(): P {
// Pick an item from the pool;
@ -23,7 +23,7 @@ export function makePool<P>(poolBase: P[], removalLaxity = 0): () => P {
if (shouldStillKeepIt()) {
return pick;
}
const index = pool.findIndex(v => equal(v, pick))
const index = pool.findIndex((v) => equal(v, pick));
if (index === -1) throw new Error("could not find pick from pool");
pool.splice(index, 1);
// If the pool is empty, reset it
@ -34,4 +34,3 @@ export function makePool<P>(poolBase: P[], removalLaxity = 0): () => P {
}
return pickRandomFromPool;
}

View File

@ -1,13 +1,11 @@
import React from 'react'
import ReactDOM from 'react-dom/client'
import App from './App'
import React from "react";
import ReactDOM from "react-dom/client";
import App from "./App";
import "bootstrap/dist/css/bootstrap.min.css";
import "@fortawesome/fontawesome-free/css/all.css";
import { registerSW } from "virtual:pwa-register";
import {
BrowserRouter,
} from "react-router-dom";
import { UserProvider} from "./user-context";
import { BrowserRouter } from "react-router-dom";
import { UserProvider } from "./user-context";
const updateSW = registerSW({
onNeedRefresh() {
@ -20,12 +18,12 @@ const updateSW = registerSW({
},
});
ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render(
ReactDOM.createRoot(document.getElementById("root") as HTMLElement).render(
<React.StrictMode>
<BrowserRouter>
<UserProvider>
<App />
</UserProvider>
</BrowserRouter>
</React.StrictMode>,
</React.StrictMode>
);

View File

@ -1,8 +1,6 @@
export default [
1527812449, // هلته - hálta, álta
1527813043, // بې له ټاله - be la Taala
1527823145, // بېرون - beróon
1527811735, // هنرمندانه - hUnarmandaana
1527813516, // څنګه - tsanga, tsunga
1578014249199, // پکښې - pukxe
1527821618, // احمقانه - ahmaqaana
@ -18,10 +16,7 @@ export default [
1527811221, // پورته - porta
1611401028364, // جسماً - jismán
1527815099, // نا وخته - naa wakhta
1527823029, // برالا - baraalaa
1527817154, // پسې - pase
1527818325, // اېله - elá
1610796256372, // مخ په وړاندې - mukh pu wRaande
1527819870, // په ناحقه - pu naahaqa
1527815228, // رو - roo
1575236274891, // دوري - dóoree
@ -54,7 +49,6 @@ export default [
1527823231, // په جڼه جڼه - pu jaNa jaNa
1527812890, // معمولاً - mamoolan
1586363985796, // روزانه - rozaaná
1527819008, // مطلق العنان - mUtlaq-Ul-'ináan
1527822660, // خود به خود - khoodbakhood
1527823364, // باوجود - baawujood
1527820143, // پسته - pasta
@ -71,7 +65,6 @@ export default [
1527821224, // فقط - faqát
1527817302, // یوځای - yodzaay
1527820499, // عاریتاً - aariyatan
1527815959, // دم درحال - dam dărhaal
1527821253, // نزدې - nizde, nazde
1527815997, // بدبختانه - badbakhtaana
1584688791272, // په لوی لاس - pu looy laas
@ -147,10 +140,8 @@ export default [
1527814710, // نژدې پر نژدې - najzde par najzde
1527821743, // ابتداً - ibtidán
1527817155, // پرله پسې - parlapase
1527818323, // ایله - eelá
1527822464, // تقلیداً - taqleedan
1527813650, // لکه - lăka
1527811618, // منحیث - minheys
1527822465, // تقلیفاً - taqleefan
1527817294, // پاس - paas
1527819016, // مستقیماً - mUstaqeeman
@ -197,7 +188,6 @@ export default [
1527820087, // وخت ناوخت - wakhtnaawakht
1527814163, // اخوا - akhwaa
1527822165, // سیده - seeda
1527814912, // رانږدې - raanaGde
1593176318060, // ډانګ پېیلی - Daang pe`yúley
1527819455, // د دې له کبله - du de la kabala
1578330078760, // بدبد - badbad, budbud
@ -222,7 +212,6 @@ export default [
1527811327, // صمیمانه - sameemaana
1577390207734, // پرې - pre
1527818716, // تدریجاً - tadreejan
1527822285, // کل - kUl
1527822183, // شرعاً - sharan
1527818276, // پرمهال - purmahaal
1527814270, // له بده مرغه - la buda margha, la buda murgha
@ -248,10 +237,8 @@ export default [
1527813595, // چندان - chandaan
1527811222, // په څېر - pu tser
1527813692, // په خاطر - pu khaatir
1623688507454, // ګنګوړ - gangóR, gangwÚR
1527820344, // په داوطلب ډول - pu daawtaláb Dawul
1527811360, // هم مهاله - hammahaala
1527812498, // بلې - băle
1586262008294, // پېټ - peT
1527818646, // یو په دوه - yawpudwá
1527812762, // خالي - khaalee
@ -305,7 +292,6 @@ export default [
1578080952673, // دباندې - dubaande
1527813323, // خوشبختانه - khoshbakhtaana
1527819156, // ظالمانه - zaalimaana
1527818313, // پنځلس ورځنی - pindzúlaswradzanéy
1527812670, // هسې - hase
1527818324, // په مټې - pumúTe
1527820205, // کله ناکله - kalanaakala
@ -313,7 +299,6 @@ export default [
1527813688, // کوز - kooz
1527821666, // آمرانه - aamuraana
1527817845, // کټ مټ - kaTmaT, kuTmuT
1527822351, // تېر و بېر - ter-U-ber
1527813618, // طبعاً - taban
1527821531, // تل - tul
1527817255, // لیرې - leere
@ -373,8 +358,6 @@ export default [
1527820289, // واقعاً - waaqi'an, waaqiyan
1588786919406, // زر تر زره - zur tur zura
1575642923868, // حتیٰ - hattaa
1527813261, // هله - hala
1593173287113, // مجمل - mUjmál
1527815224, // رښتیا - rixtiyaa
1594909066356, // خوا و شا - khwaa-U-shaa
1527819344, // پسه - pása
@ -387,9 +370,7 @@ export default [
1527821125, // په منطقي ډول - pu mantiqee Dawul
1527812137, // تل تر تله - tulturtula
1527812375, // واپس - waapus
1527821736, // په موقت ډول - pu mUwaqqat Dawul
1527816129, // خواره واره - khwaarawaara
1527812572, // د ... په شان - du … pu shaan
1527811423, // لاندې - laande
1527820416, // حاکمانه - haakimaana
1527812866, // لږترلږه - luG tur luGa
@ -407,7 +388,6 @@ export default [
1527813061, // بې درنګه - bediranga
1527818056, // فی الحال - filháal
1527818654, // عین - ayn
1527818669, // ماشومانه - maashoomaana
1527822765, // له واره - la waara
1527814913, // ورنږدې - warnaGde
1527816312, // تخمیناً - takhmeenan
@ -419,8 +399,6 @@ export default [
1527811244, // آن - aan
1527816949, // هومره - hoomra
1527821995, // اخر - akhúr, akhír
1527817078, // خود - khood, khwud
1527823176, // آخود - aakhwad
1586626956539, // درست - drust, drast
1527818644, // برحال - barháal
1527815340, // تکرار - tăkraar
@ -442,21 +420,14 @@ export default [
1527820921, // علیحده - aleyhida, alaeyda
1527817376, // درڅخه - dărtsukha
1527822852, // دېخوا هاخوا - dekhwaa haakhwaa
1527820103, // یوموټ - yawmóoT
1527820737, // هغسې - haghase
1527823338, // هاغومره - haaghoomra
1527814318, // مخکښې - mukhkxe
1584689070748, // نامستقیم - naamUstaqeem
1527821752, // ماسوا - maasiwáa
1591382269266, // قابو - qaaboo
1527818586, // بلا استثنیٰ - bilaaistisnaa
1527820750, // چوټ انداز - choT andaaz, chooT andaaz ??
1527812504, // بېرته - berta
1571526377164, // کډن - kaDún
1527819764, // ماهانه - maahaaná
1527822366, // حق ناحق - haqnaaháq
1527819438, // لېرې - lere
1527819392, // برسېره - barséra
1527822184, // اخلاقاً - akhlaaqan
1527813260, // تماماً - tamaaman
1588758935200, // وراخوا - wăraakhwaa
@ -489,7 +460,6 @@ export default [
1527812415, // سم دلاسه - samdulaasa
1527823339, // هغومره - haghoomra
1527821616, // مظلومانه - mazloomaana
1584691547040, // مودبانه - mUaddabaana
1527812324, // هاسې په هاسې - haase pu haase
1527815420, // وروسته - wroosta
1527818595, // قدرتاً - qUdratan

View File

@ -9,9 +9,8 @@ export default [
1527817146, // استوګن - astogan
1527813713, // امیدوار - Umeedwaar
1527819451, // انګرېز - angréz
1527820346, // انلاین - anlaayn
1527813667, // اهم - aham
1598724912198, // اوچ - ooch
1527815130, // اوچ - wuch
1586452587974, // اوزګار - oozgáar
1527816489, // ایماندار - eemaandaar
1527820433, // باتور - baatóor
@ -23,14 +22,12 @@ export default [
1527812515, // بل - bul
1527815725, // بلد - balad
1577301753727, // بند - band
1527812490, // بې کار - be kaar
1527812031, // بېل - bel
1527815144, // پاک - paak
1527815201, // پټ - puT
1527815179, // پلن - plun
1527819059, // پنډ - punD
1611767359178, // ترسناک - tarsnáak
1527813270, // تروش - troosh
1527813817, // تنګ - tang
1527816354, // تیار - tayaar
1527817056, // تېز - tez
@ -38,7 +35,6 @@ export default [
1527819864, // ټیټ - TeeT
1527811894, // ټینګ - Teeng
1527812943, // ثابت - saabit
1527813085, // ثقیل - saqeel
1527820479, // جاهل - jaahíl
1588160800930, // جراح - jarráah
1527812707, // جګ - jig, jug
@ -215,7 +211,6 @@ export default [
1527813115, // ادعا - idaa
1527818119, // امسا - amsaa
1527815043, // جزا - jazaa
1527819022, // څا - tsaa
1527814225, // خطا - khataa
1610797589510, // خلا - khaláa
@ -240,6 +235,16 @@ export default [
1610443988250, // وېشلتیا - weshiltyaa, weshiltiyaa
1527816806, // وینا - waynaa
1527815163, // پیشو - peesho
1527822272, // باڼو - baaNoo
1527823587, // بازو - baazoo
1527813463, // چاقو - chaaqóo
1527821599, // پارو - paaróo
1596290955751, // تالو - taalóo
1674934574643, // ویډیو - weeDiyo
1566468038374, // بیزو - beezo
1527815197, // پښتون
1527813148, // پروت
1574867531681, // پوخ
@ -278,6 +283,7 @@ export default [
1576113803291, // ووړ
1527819244, // کوربه
1527812908, // مېلمه
1527813270, // تروش - troosh
1527814150, // لار - laar
1527815417, // ورځ - wradz
@ -400,6 +406,12 @@ export default [
1527822208, // وطواط - watwáat
1527819571, // وهم - wáhum, wahm
1527816332, // ویاړ - wyaaR
1527816747, // ډاکټر - DaakTár
1527812849, // لاس - laas
1527814158, // دوست - dost
1527815711, // مار - maar
1527820043, // چرګ - charg
1527815127, // نرس - nurs
1568926976497, // اکسرې - iksre
1602179757779, // الف بې - alif be
@ -446,6 +458,7 @@ export default [
1527813462, // کیلي - keelee
1527814492, // ګاوداري - gaawdaaree
1610013679820, // ورورولي - wrorwalée
1527816247, // سختي - sakhtee
1527821971, // بن - bun
1527816397, // ترور - tror
@ -492,6 +505,7 @@ export default [
1579041957559, // ندا - nadáa
1527816253, // نواسه - nawaasa
1527819971, // والي - waalée
1527812456, // اړتیا - aRtyaa
1573659054031, // ارتوالی - artwaaley, aratwaaley
1527811890, // ازغی - azghey
@ -629,7 +643,6 @@ export default [
1527820130, // پلوی - palawéy
1582390092514, // پورتنی - portinéy
1610617741649, // ځنډنی - dzanDanéy, dzanDunéy
1610793723568, // چېلی - cheléy
1527819362, // خوسی - khooséy
1590052667427, // درستی - drustéy, drastéy
1527822854, // ړومبی - Roombéy
@ -654,6 +667,7 @@ export default [
1527821373, // هوسی - hoséy
1527813636, // وروستی - wroostéy
1527815430, // یوازنی - yawaazunéy
1714029848228, // ایرانی - eeraanáy
1527817036, // astáazey
1582853867682, // اوسېدونکی
@ -815,7 +829,6 @@ export default [
1527818255, // لېوه - lewú
1527821522, // مریه - mrayú
1527812911, // مېړه - meRu
1527811626, // نکېده - nukedu
1527816410, // نیکه - neekú
1527822420, // واګه - waagu
1527816357, // وراره - wraaru
@ -823,6 +836,7 @@ export default [
1527814789, // وېښته - wextu
1527815394, // واده - waadú
1527823526, // قاضۍ - qaazúy
1527818017, // اټۍ - aTuy
1527812694, // انجنۍ - injUnuy
1527815140, // اونۍ - onuy, ownuy, owunuy
@ -852,7 +866,6 @@ export default [
1527812594, // ځای - dzaay
1527812525, // چای - chaay
1527812783, // خدای - khUdaay
1527819514, // دای - daay
1610797797756, // سای - saay
1527822345, // سرای - saráay
1586598425514, // بوی - booy

View File

@ -1597,10 +1597,10 @@
rambda "^6.7.0"
react-select "^5.2.2"
"@lingdocs/ps-react@^7.1.6":
version "7.1.6"
resolved "https://npm.lingdocs.com/@lingdocs/ps-react/-/ps-react-7.1.6.tgz#610f543e5a82acbdb346026ea0bceb4a78febf21"
integrity sha512-IQf3X5uBvBbuhE2Q3/66rU7bVOeSg81rdPvvYgNCWDFk0fAM5VqV7mJSpRkMBM3foV9rlNk6F0WkNqG/ngp6IQ==
"@lingdocs/ps-react@^7.1.7":
version "7.1.7"
resolved "https://npm.lingdocs.com/@lingdocs/ps-react/-/ps-react-7.1.7.tgz#69c552322919d16afb5f1635e2b928e38761fc5f"
integrity sha512-yMKzcKnBQUgOsMZLAVKhBjpG5QzGC5nBEixtpj4PRVtjIs34HqwdxDxWPA0/OYZVNUvFhFui4UM3oZ+T568k9Q==
dependencies:
"@formkit/auto-animate" "^1.0.0-beta.3"
classnames "^2.2.6"