diff --git a/Kuli/index.html b/Kuli/index.html
new file mode 100644
index 0000000..819dd41
--- /dev/null
+++ b/Kuli/index.html
@@ -0,0 +1,54 @@
+
+
+
+
+
+
+ Enjoy your Kuli
+
+
+ N
+
+
+

+
+

+
+
+
+
+
+
+
+ |
+
+
+ |
+ |
+
+
+ |
+ |
+
+
+
+
+

+
+

+
+
+
Perfect!
+
+
+ Replay
+ Go Spell It
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Kuli/script.js b/Kuli/script.js
new file mode 100644
index 0000000..719f426
--- /dev/null
+++ b/Kuli/script.js
@@ -0,0 +1,255 @@
+let wordClass = "noun";
+let target = words(wordClass);
+let targetLen = target.length;
+console.log(targetLen);
+
+let body = document.getElementsByTagName("body")[0];
+let clsChg = document.getElementById("clsChg");
+let display = document.getElementById("display");
+let word = document.getElementById("word");
+let pronunc = document.getElementById("pronunc");
+let ans = [document.getElementById("ans_0"), document.getElementById("ans_1"), document.getElementById("ans_2"), document.getElementById("ans_3")]
+let result = document.getElementById("result");
+let scoreElemA = document.getElementById("scoreA");
+let scoreElemB = document.getElementById("scoreB");
+let corrCntElemA = document.getElementById("corrCntA");
+let wrongCntElemA = document.getElementById("wrongCntA");
+let corrCntElemB = document.getElementById("corrCntB");
+let wrongCntElemB = document.getElementById("wrongCntB");
+let perfect = document.getElementById("perfect");
+let imperfect = document.getElementById("imperfect");
+let replay = document.getElementById("replay");
+let playAnother = document.getElementsByClassName("playAnother")[0];
+let footer = document.getElementsByTagName("footer")[0];
+let startSound = document.getElementById("startSound");
+let corrSound = document.getElementById("corrSound");
+let corrSound2 = document.getElementById("corrSound2");
+let wrongSound = document.getElementById("wrongSound");
+
+let curWordIdx;
+let curCorrIdx;
+let isClicked = [false, false, false, false];
+let wordIdx;
+let tmpWordIdx;
+let wordTxt;
+let corrDict;
+let corrIdx;
+let wrongIdx = [];
+let tmpWrongIdx;
+let cnt = 0;
+let corrCnt = 0;
+let wrongCnt = 0;
+let wrongs = [];
+let wrongsLen;
+let mistakenWordIdx;
+let mistakenWordMeaning;
+let mistakenWordMeaningLen;
+let mistakenWordMeaningTxt;
+let wrongsTxt;
+function randElem(arr) {
+ return arr[Math.floor(Math.random() * arr.length)];
+}
+function setQuiz() {
+ scoreElemA.style.display = "block";
+ display.style.display = "table";
+ result.style.display = "none";
+ replay.style.display = "none";
+ playAnother.style.display = "none";
+ footer.style.display = "inline";
+}
+function removeQuiz() {
+ display.style.display = "none";
+ result.style.display = "block";
+ replay.style.display = "block";
+ playAnother.style.display = "block";
+ footer.style.display = "none";
+}
+function quiz() {
+ if (cnt == 20) {
+ removeQuiz();
+ cnt = 0;
+ wrongsLen = wrongs.length;
+ if (wrongsLen == 0) {
+ perfect.style.display = "block";
+ imperfect.style.display = "none";
+ scoreElemA.style.display = "none";
+ scoreElemB.style.display = "none";
+ body.style.animation = "gaming 2s linear infinite";
+ result.style.animation = "gaming 2s linear infinite";
+ perfect.style.animation = "gaming 2s linear infinite";
+ return [null, null];
+ } else {
+ perfect.style.display = "none";
+ imperfect.style.display = "block";
+ scoreElemA.style.display = "none";
+ scoreElemB.style.display = "block";
+ corrCntElemB.innerText = corrCnt;
+ wrongCntElemB.innerText = wrongCnt;
+ wrongsTxt = "";
+ for (let i = 0; i < wrongsLen; ++i) {
+ mistakenWordIdx = wrongs[i][0];
+ mistakenWordMeaning = target[mistakenWordIdx]["meaning"];
+ mistakenWordMeaningLen = mistakenWordMeaning.length;
+ mistakenWordMeaningTxt = "'" + mistakenWordMeaning[0] + "'";
+ if (mistakenWordMeaningLen != 0) {
+ for (let i = 1; i < mistakenWordMeaningLen; ++i) {
+ if (i == mistakenWordMeaningLen - 1) {
+ mistakenWordMeaningTxt += " or '" + mistakenWordMeaning[i] + "'";
+ } else {
+ mistakenWordMeaningTxt += ", '" + mistakenWordMeaning[i] + "'";
+ }
+ }
+ }
+ wrongsTxt += "'" + target[mistakenWordIdx]["word"] + "'"
+ + " is "
+ + mistakenWordMeaningTxt + ", not '" + wrongs[i][1] + "'.
"
+ }
+ imperfect.innerHTML = wrongsTxt.slice(0, -4);
+ return [null, null];
+ }
+ } else {
+ setQuiz();
+ tmpWordIdx = Math.floor(Math.random() * targetLen);
+ while (tmpWordIdx == wordIdx) {
+ tmpWordIdx = Math.floor(Math.random() * targetLen);
+ }
+ wordIdx = tmpWordIdx;
+ corrIdx = Math.floor(Math.random() * 4);
+ console.log(corrIdx);
+ for (let i = 0; i < 4; ++i) {
+ if (i == corrIdx) continue;
+ tmpWrongIdx = Math.floor(Math.random() * targetLen);
+ while (wrongIdx.includes(tmpWrongIdx) || tmpWrongIdx == wordIdx) {
+ tmpWrongIdx = Math.floor(Math.random() * targetLen);
+ }
+ wrongIdx.push(tmpWrongIdx);
+ ans[i].innerText = randElem(target[tmpWrongIdx]["meaning"]);
+ }
+ wrongIdx = [];
+ corrDict = target[wordIdx]
+ wordTxt = corrDict["word"];
+ if (corrDict["gender_is_distinctive"]) wordTxt += " (" + corrDict["gender"] + ")";
+ word.innerText = wordTxt;
+ pronunc.innerText = "[" + corrDict["pronunc"] + "]";
+ ans[corrIdx].innerText = randElem(corrDict["meaning"]);
+ cnt++;
+ return [wordIdx, corrIdx]
+ }
+}
+function start() {
+ [curWordIdx, curCorrIdx] = quiz();
+ startSound.currentTime = 0;
+ startSound.play();
+ corrCnt = 0;
+ wrongCnt = 0;
+ wrongs = [];
+ isClicked = [false, false, false, false];
+ corrCntElemA.innerText = 0;
+ wrongCntElemA.innerText = 0;
+ body.style.animation = "";
+ result.style.animation = "";
+}
+start();
+ans[0].addEventListener("click", () => {
+ if (curCorrIdx == 0) {
+ if (cnt == 20) {
+ corrSound2.play();
+ } else {
+ corrSound.currentTime = 0;
+ corrSound.play();
+ }
+ corrCnt++;
+ corrCntElemA.innerText = corrCnt;
+ [curWordIdx, curCorrIdx] = quiz();
+ isClicked = [false, false, false, false];
+ } else {
+ wrongSound.currentTime = 0;
+ wrongSound.play();
+ if (isClicked[0]) return;
+ wrongCnt++;
+ wrongCntElemA.innerText = wrongCnt;
+ isClicked[0] = true;
+ wrongs.push([curWordIdx, ans[0].textContent]);
+ }
+})
+ans[1].addEventListener("click", () => {
+ if (curCorrIdx == 1) {
+ if (cnt == 20) {
+ corrSound2.play();
+ } else {
+ corrSound.currentTime = 0;
+ corrSound.play();
+ }
+ corrCnt++;
+ corrCntElemA.innerText = corrCnt;
+ [curWordIdx, curCorrIdx] = quiz();
+ isClicked = [false, false, false, false];
+ } else {
+ wrongSound.currentTime = 0;
+ wrongSound.play();
+ if (isClicked[1]) return;
+ wrongCnt++;
+ wrongCntElemA.innerText = wrongCnt;
+ isClicked[1] = true;
+ wrongs.push([curWordIdx, ans[1].textContent]);
+ }
+})
+ans[2].addEventListener("click", () => {
+ if (curCorrIdx == 2) {
+ if (cnt == 20) {
+ corrSound2.play();
+ } else {
+ corrSound.currentTime = 0;
+ corrSound.play();
+ }
+ corrCnt++;
+ corrCntElemA.innerText = corrCnt;
+ [curWordIdx, curCorrIdx] = quiz();
+ isClicked = [false, false, false, false];
+ } else {
+ wrongSound.currentTime = 0;
+ wrongSound.play();
+ if (isClicked[2]) return;
+ wrongCnt++;
+ wrongCntElemA.innerText = wrongCnt;
+ isClicked[2] = true;
+ wrongs.push([curWordIdx, ans[2].textContent]);
+ }
+})
+ans[3].addEventListener("click", () => {
+ if (curCorrIdx == 3) {
+ if (cnt == 20) {
+ corrSound2.play();
+ } else {
+ corrSound.currentTime = 0;
+ corrSound.play();
+ }
+ corrCnt++;
+ corrCntElemA.innerText = corrCnt;
+ [curWordIdx, curCorrIdx] = quiz();
+ isClicked = [false, false, false, false];
+ } else {
+ wrongSound.currentTime = 0;
+ wrongSound.play();
+ if (isClicked[3]) return;
+ wrongCnt++;
+ wrongCntElemA.innerText = wrongCnt;
+ isClicked[3] = true;
+ wrongs.push([curWordIdx, ans[3].textContent]);
+ }
+})
+replay.addEventListener("click", start)
+clsChg.addEventListener("click", () => {
+ if (wordClass == "noun") {
+ wordClass = "verb";
+ clsChg.innerText = "V";
+ } else {
+ wordClass = "noun";
+ clsChg.innerText = "N";
+ }
+ target = words(wordClass);
+ targetLen = target.length;
+ console.log(targetLen);
+ cnt = 0;
+ start();
+})
\ No newline at end of file
diff --git a/Kuli/src/words_list.js b/Kuli/src/words_list.js
new file mode 100644
index 0000000..acb60a8
--- /dev/null
+++ b/Kuli/src/words_list.js
@@ -0,0 +1,3 @@
+function words() {
+
+}
\ No newline at end of file
diff --git a/Kuli/style.css b/Kuli/style.css
new file mode 100644
index 0000000..fae08a3
--- /dev/null
+++ b/Kuli/style.css
@@ -0,0 +1,179 @@
+ody {
+ text-align: center;
+ vertical-align: middle;
+ font-weight: bold;
+}
+
+#clsChg {
+ position: absolute;
+ display: block;
+ width: 16vh;
+ height: 8vh;
+ text-align: center;
+ border-radius: 2rem;
+ background-color: darkgreen;
+ color: white;
+ font-size: 6vh;
+ cursor: pointer;
+ user-select: none;
+ transition: all 0.3s;
+ box-shadow: 0 3px 5px rgba(0, 0, 0, .3);
+}
+
+#clsChg:hover {
+ background-color: green;
+}
+
+#hamburger {
+ background-color: green;
+}
+
+#scoreA {
+ position: absolute;
+ right: 0px;
+ width: fit-content;
+ text-align: center;
+ font-size: 45px;
+}
+
+#display {
+ width: 100%;
+ height: 100vh;
+ font-size: 8vh;
+ color: white;
+}
+
+#question {
+ height: 20%;
+}
+
+#word {
+ font-size: 8vh;
+ color: black;
+}
+
+#pronunc {
+ font-size: 4vh;
+ font-family: "Times New Roman", "Arial", "Courier New", "Segoe UI";
+ color: gray;
+}
+
+#ans_0 {
+ width: 50%;
+ height: 40%;
+ background-color: #d14d28;
+}
+
+#ans_0:hover {
+ opacity: 0.6;
+ cursor: pointer;
+}
+
+#ans_1 {
+ width: 50%;
+ background-color: #59c8ef;
+}
+
+#ans_1:hover {
+ opacity: 0.6;
+ cursor: pointer;
+}
+
+#ans_2 {
+ height: 40%;
+ background-color: #2b9464;
+}
+
+#ans_2:hover {
+ opacity: 0.6;
+ cursor: pointer;
+}
+
+#ans_3 {
+ background-color: #f5df65;
+}
+
+#ans_3:hover {
+ opacity: 0.6;
+ cursor: pointer;
+}
+
+#result {
+ width: fit-content;
+ min-width: 26vw;
+ padding: 0.5em 1em;
+ margin: 0 auto;
+ text-align: left;
+ background-color: white;
+ box-shadow: 0 3px 6px rgba(0, 0, 0, .4);
+}
+
+#scoreB {
+ padding: 5px;
+ margin-bottom: 10px;
+ border-bottom: 1px solid black;
+ text-align: center;
+ font-size: 25px;
+}
+
+#perfect {
+ display: block;
+ width: 100%;
+ text-align: "center";
+ font-size: 14vw;
+ background-color: black;
+ color: white;
+}
+
+#replay,
+.playAnother {
+ position: relative;
+ display: block;
+ width: 24vw;
+ padding: auto;
+ margin: 10px auto;
+ border-radius: 1rem;
+ background-color: red;
+ color: white !important;
+ font-size: 4vw;
+ cursor: pointer;
+ transition: all 0.3s;
+ box-shadow: 0 3px 5px rgba(0, 0, 0, .3);
+}
+
+#replay:hover,
+.playAnother:hover {
+ background-color: orange;
+}
+
+footer {
+ font-size: 4vh;
+ float: right;
+}
+
+a {
+ color: blue;
+ text-decoration: none;
+}
+
+footer a:hover {
+ text-decoration: underline;
+}
+
+@keyframes gaming {
+ 0% {
+ background-color: magenta;
+ }
+
+ 33% {
+ background-color: yellow;
+ }
+
+ 66% {
+ background-color: Cyan;
+ }
+
+ 100% {
+ background-color: magenta;
+ }
+}
\ No newline at end of file