Compare commits
33 Commits
08b5f6daf6
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| ef9aed3126 | |||
| b6b3655142 | |||
| 38376225c8 | |||
| 00032f9cc0 | |||
| c35d27198c | |||
| 82e4d36b14 | |||
| a6542fbe60 | |||
| 30b3cf0d0a | |||
| 132e49b589 | |||
| 19b1c73dca | |||
| b8ae68eff8 | |||
| 05623222c8 | |||
| 9fb89f31d5 | |||
| 2c1164a6bc | |||
| 65aec63e12 | |||
| 56f524df38 | |||
| 0e8ac06e26 | |||
|
|
ce1c8c7bbb | ||
|
|
2e235e575f | ||
| 4d56328ceb | |||
| 1d4caa5f2b | |||
| e153143a7a | |||
| 04058a3be3 | |||
|
|
926bbf927b | ||
| 285c707290 | |||
| 03d6ad19f3 | |||
| 8cbb971c40 | |||
| f88202b792 | |||
| baa691fa03 | |||
| 980ab5b84c | |||
|
|
b2ef344949 | ||
|
|
b19dc38898 | ||
|
|
9b5f272cd5 |
1
.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
update.php
|
||||||
1
.gitignore_global
Normal file
@@ -0,0 +1 @@
|
|||||||
|
.DS_Store
|
||||||
3
.gitmodules
vendored
@@ -1,3 +1,6 @@
|
|||||||
[submodule "heonian-ime"]
|
[submodule "heonian-ime"]
|
||||||
path = heonian-ime
|
path = heonian-ime
|
||||||
url = https://git.succubi.services/heonian.org/heonian-ime
|
url = https://git.succubi.services/heonian.org/heonian-ime
|
||||||
|
[submodule "heonian-resources"]
|
||||||
|
path = heonian-resources
|
||||||
|
url = https://git.succubi.services/heonian.org/heonian-resources
|
||||||
|
|||||||
5
README.md
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
# heonian web dictionary
|
||||||
|
|
||||||
|
your beloved heonian dictionary, now in .html form
|
||||||
|
|
||||||
|
[live-ish here](https://dreamnotes.space/hw/)
|
||||||
1
heonian-resources
Submodule
BIN
icons/icon-128x128.png
Normal file
|
After Width: | Height: | Size: 5.6 KiB |
BIN
icons/icon-144x144.png
Normal file
|
After Width: | Height: | Size: 6.3 KiB |
BIN
icons/icon-152x152.png
Normal file
|
After Width: | Height: | Size: 6.9 KiB |
BIN
icons/icon-192x192.png
Normal file
|
After Width: | Height: | Size: 9.9 KiB |
BIN
icons/icon-384x384.png
Normal file
|
After Width: | Height: | Size: 32 KiB |
BIN
icons/icon-512x512.png
Normal file
|
After Width: | Height: | Size: 38 KiB |
BIN
icons/icon-72x72.png
Normal file
|
After Width: | Height: | Size: 2.7 KiB |
BIN
icons/icon-96x96.png
Normal file
|
After Width: | Height: | Size: 3.7 KiB |
BIN
icons/maskable_icon.png
Normal file
|
After Width: | Height: | Size: 69 KiB |
13
index.html
@@ -6,7 +6,15 @@
|
|||||||
<meta name="description" content="now with 50% less unix requirement">
|
<meta name="description" content="now with 50% less unix requirement">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
<link rel="stylesheet" href="./main.css">
|
<link rel="stylesheet" href="./main.css">
|
||||||
<link rel="preload" href="./wordlist.json" as="fetch">
|
<link rel="manifest" href="./manifest.json">
|
||||||
|
<meta name="apple-mobile-web-app-title" content="hisho">
|
||||||
|
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||||
|
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
|
||||||
|
<link rel="apple-touch-icon" href="./icons/icon-512x512.png" />
|
||||||
|
<link rel="apple-touch-icon" sizes="72x72" href="./icons/icon-72x72.png" />
|
||||||
|
<link rel="apple-touch-icon" sizes="144x144" href="./icons/icon-144x144.png" />
|
||||||
|
<link rel="apple-touch-icon" sizes="152x152" href="./icons/icon-152x152.png" />
|
||||||
|
<!-- <link rel="preload" href="./heonian-resources/wordlist.json" as="fetch"> this doesnt seem to do shit so /shrug -->
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<!--
|
<!--
|
||||||
@@ -29,9 +37,10 @@
|
|||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<a href="#">show all words</a> <a href="#">uh. something else</a>
|
<a id="showAllWords">show all words</a> <a id="randomWord">random word</a> <a href="https://heonian.dreamnotes.space">wiki</a>
|
||||||
</div>
|
</div>
|
||||||
<noscript>turn on js doofus</noscript>
|
<noscript>turn on js doofus</noscript>
|
||||||
|
<span id="update">update available! close all open hisho tabs and reopen hisho to update.</span>
|
||||||
</header>
|
</header>
|
||||||
<main>
|
<main>
|
||||||
|
|
||||||
|
|||||||
10
main.css
@@ -67,6 +67,10 @@ a:hover {
|
|||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.clickable {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
.heonian {
|
.heonian {
|
||||||
font-family: "heonian";
|
font-family: "heonian";
|
||||||
}
|
}
|
||||||
@@ -156,6 +160,10 @@ header.fullscreen #search {
|
|||||||
max-width: 500px;
|
max-width: 500px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
header #update {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
.header-animation {
|
.header-animation {
|
||||||
animation: clearly-cheating 1s ease-in-out;
|
animation: clearly-cheating 1s ease-in-out;
|
||||||
}
|
}
|
||||||
@@ -232,6 +240,7 @@ main {
|
|||||||
margin-bottom: 6px;
|
margin-bottom: 6px;
|
||||||
border-left: 3px solid var(--darkgrey);
|
border-left: 3px solid var(--darkgrey);
|
||||||
padding-left: 4px;
|
padding-left: 4px;
|
||||||
|
font-family: var(--font-h);
|
||||||
}
|
}
|
||||||
|
|
||||||
.result-translation {
|
.result-translation {
|
||||||
@@ -252,6 +261,7 @@ main {
|
|||||||
|
|
||||||
.result details.result-meta p {
|
.result details.result-meta p {
|
||||||
font-size: 1rem;
|
font-size: 1rem;
|
||||||
|
font-family: var(--font-h);
|
||||||
}
|
}
|
||||||
|
|
||||||
.results-header-count::after {
|
.results-header-count::after {
|
||||||
|
|||||||
295
main.js
@@ -20,6 +20,7 @@ function toggleIME() {
|
|||||||
|
|
||||||
function animateHeader(inout = false) {
|
function animateHeader(inout = false) {
|
||||||
//todo: debounce this
|
//todo: debounce this
|
||||||
|
// const mediaQuery = window.matchMedia("(prefers-reduced-motion: reduce)"); //do shit
|
||||||
if (inout) {
|
if (inout) {
|
||||||
header.classList.add("header-animation-reverse");
|
header.classList.add("header-animation-reverse");
|
||||||
header.classList.remove("header-animation");
|
header.classList.remove("header-animation");
|
||||||
@@ -28,6 +29,7 @@ function animateHeader(inout = false) {
|
|||||||
header.classList.add("fullscreen");
|
header.classList.add("fullscreen");
|
||||||
main.style.opacity = "0";
|
main.style.opacity = "0";
|
||||||
main.classList.remove("main-animation-reverse");
|
main.classList.remove("main-animation-reverse");
|
||||||
|
main.innerHTML = "";
|
||||||
}, 500);
|
}, 500);
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
header.classList.remove("header-animation-reverse");
|
header.classList.remove("header-animation-reverse");
|
||||||
@@ -59,7 +61,7 @@ document.addEventListener("keydown", (e) => {
|
|||||||
//if search box not focused, and if we're not on the home page, go back to home page
|
//if search box not focused, and if we're not on the home page, go back to home page
|
||||||
if (!header.querySelector("input").matches(":focus") && !header.classList.contains("fullscreen")) {
|
if (!header.querySelector("input").matches(":focus") && !header.classList.contains("fullscreen")) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
animateHeader(true);
|
goHome();
|
||||||
} else if (header.querySelector("input").matches(":focus") && ime != null) {
|
} else if (header.querySelector("input").matches(":focus") && ime != null) {
|
||||||
toggleIME();
|
toggleIME();
|
||||||
} else if (header.querySelector("input").matches(":focus")) {
|
} else if (header.querySelector("input").matches(":focus")) {
|
||||||
@@ -80,7 +82,7 @@ document.addEventListener("keydown", (e) => {
|
|||||||
|
|
||||||
function stripWord(word, space = false) {
|
function stripWord(word, space = false) {
|
||||||
return space == false ? word.replace(/[^a-zA-Z-]/gu, "").toLowerCase() :
|
return space == false ? word.replace(/[^a-zA-Z-]/gu, "").toLowerCase() :
|
||||||
word.replace(/[^a-zA-Z-\s]/gu, "").toLowerCase();
|
word.replace(/[^a-zA-Z-\s]/gu, "").toLowerCase();
|
||||||
}
|
}
|
||||||
|
|
||||||
heonianVowels = {
|
heonianVowels = {
|
||||||
@@ -161,17 +163,50 @@ function processVerb(word) {
|
|||||||
//but ... not yet uwu
|
//but ... not yet uwu
|
||||||
}
|
}
|
||||||
|
|
||||||
function generateRuby(word) {
|
function isHeonian(word) {
|
||||||
letters = word.split("");
|
letters = word.split("");
|
||||||
ruby = "";
|
|
||||||
for (let i = 0; i < letters.length; i++) {
|
for (let i = 0; i < letters.length; i++) {
|
||||||
ruby += `<ruby>${letters[i]}<rt>${heonianToRoman(letters[i])}</rt></ruby>`;
|
if (letters[i].codePointAt(0) < 57344 || letters[i].codePointAt(0) > 57606) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function generateRuby(word, addLinks = false) {
|
||||||
|
ruby = "";
|
||||||
|
if (addLinks == true) {
|
||||||
|
//split by space
|
||||||
|
let split = word.split(" ");
|
||||||
|
for (let i = 0; i < split.length; i++) {
|
||||||
|
letters = word.split("");
|
||||||
|
for (let i = 0; i < letters.length; i++) {
|
||||||
|
if (letters[i] == " ") {
|
||||||
|
ruby += " ";
|
||||||
|
} else if (json[letters[i]] != undefined) {
|
||||||
|
ruby += `<ruby class="clickable" onclick='clickSearch(\"${letters[i]}\")'>${letters[i]}<rt>${heonianToRoman(letters[i])}</rt></ruby>`;
|
||||||
|
} else {
|
||||||
|
ruby += `<ruby>${letters[i]}<rt>${heonianToRoman(letters[i])}</rt></ruby>`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//somehow figure out how to get links in
|
||||||
|
} else {
|
||||||
|
letters = word.split("");
|
||||||
|
for (let i = 0; i < letters.length; i++) {
|
||||||
|
if (letters[i] == " ") {
|
||||||
|
ruby += " ";
|
||||||
|
} else {
|
||||||
|
ruby += `<ruby>${letters[i]}<rt>${heonianToRoman(letters[i])}</rt></ruby>`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return ruby;
|
return ruby;
|
||||||
}
|
}
|
||||||
|
|
||||||
function loadDictionary() {
|
function loadDictionary() {
|
||||||
fetch("./wordlist.json").then((e) => {
|
fetch("./heonian-resources/wordlist.json").then((e) => {
|
||||||
if (e.status === 200) {
|
if (e.status === 200) {
|
||||||
//convert to json lmao
|
//convert to json lmao
|
||||||
e.json().then((e) => {
|
e.json().then((e) => {
|
||||||
@@ -182,6 +217,7 @@ function loadDictionary() {
|
|||||||
//prepare search. maybe async this if we're loading a specific word?
|
//prepare search. maybe async this if we're loading a specific word?
|
||||||
for (let i = 0; i < keys.length; i++) {
|
for (let i = 0; i < keys.length; i++) {
|
||||||
try {
|
try {
|
||||||
|
if (keys[i] == "") continue;
|
||||||
//create array
|
//create array
|
||||||
searchDictionary[keys[i]] = [];
|
searchDictionary[keys[i]] = [];
|
||||||
|
|
||||||
@@ -191,11 +227,13 @@ function loadDictionary() {
|
|||||||
//add: romanized word
|
//add: romanized word
|
||||||
searchDictionary[keys[i]].push(stripWord(heonianToRoman(keys[i])));
|
searchDictionary[keys[i]].push(stripWord(heonianToRoman(keys[i])));
|
||||||
//what if i add it here.
|
//what if i add it here.
|
||||||
searchDictionary[keys[i]].push(stripWord(heonianToRoman(keys[i]).replace("dsh","z")));
|
searchDictionary[keys[i]].push(stripWord(heonianToRoman(keys[i]).replace("dsh", "z")));
|
||||||
|
|
||||||
//add: translations, meanings
|
//add: translations, meanings
|
||||||
for (let o = 0; o < values[i].length; o++) {
|
for (let o = 0; o < values[i].length; o++) {
|
||||||
if (values[i][o].hasOwnProperty("translation")) searchDictionary[keys[i]].push(stripWord(values[i][o]["translation"], true));
|
if (values[i][o].hasOwnProperty("translation")) {
|
||||||
|
searchDictionary[keys[i]].push(stripWord(values[i][o]["translation"], true))
|
||||||
|
};
|
||||||
if (values[i][o].hasOwnProperty("meaning")) searchDictionary[keys[i]].push(stripWord(values[i][o]["meaning"], true));
|
if (values[i][o].hasOwnProperty("meaning")) searchDictionary[keys[i]].push(stripWord(values[i][o]["meaning"], true));
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
@@ -205,6 +243,13 @@ function loadDictionary() {
|
|||||||
|
|
||||||
//ok, we're all ready!
|
//ok, we're all ready!
|
||||||
document.querySelector("header input").placeholder = "search";
|
document.querySelector("header input").placeholder = "search";
|
||||||
|
const url = new URL(window.location);
|
||||||
|
const val = url.searchParams.get('s');
|
||||||
|
if (val != null) {
|
||||||
|
header.querySelector("input").value = val;
|
||||||
|
doSearch(false);
|
||||||
|
animateHeader(false);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
alert("yeah something went horribly wrong loading the wordlist so uh,,, certified ike moment");
|
alert("yeah something went horribly wrong loading the wordlist so uh,,, certified ike moment");
|
||||||
@@ -213,7 +258,12 @@ function loadDictionary() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function search(word) {
|
function search(word, type) {
|
||||||
|
if (type == "all") { word = "" };
|
||||||
|
if (type == "random") {
|
||||||
|
let random = Math.floor(Math.random() * Object.keys(json).length);
|
||||||
|
return [Object.keys(json)[random]];
|
||||||
|
}
|
||||||
let words = word.split(" ");
|
let words = word.split(" ");
|
||||||
for (let i = 0; i < words.length; i++) {
|
for (let i = 0; i < words.length; i++) {
|
||||||
words[i] = stripWord(words[i]);
|
words[i] = stripWord(words[i]);
|
||||||
@@ -226,19 +276,66 @@ function search(word) {
|
|||||||
for (let key in searchDictionary) {
|
for (let key in searchDictionary) {
|
||||||
for (let value in searchDictionary[key]) {
|
for (let value in searchDictionary[key]) {
|
||||||
if (searchDictionary[key][value].includes(word)) {
|
if (searchDictionary[key][value].includes(word)) {
|
||||||
|
if (value == 0) {
|
||||||
|
result.push(key);
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
//if its a description (i.e: includes a space)
|
||||||
|
//do startsWith or something instead to prevent
|
||||||
|
//false positive search results
|
||||||
|
let t = false;
|
||||||
|
let d = searchDictionary[key][value].split(" ")
|
||||||
|
for (let w in d) {
|
||||||
|
if (d[w].startsWith(word)) {
|
||||||
|
t = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (t) {
|
||||||
|
result.push(key);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (words.length > 1 && stripWord(searchDictionary[key][value]).includes(word)) {
|
||||||
result.push(key);
|
result.push(key);
|
||||||
break; //????
|
break;
|
||||||
|
//can still produce false positives, but... very low chance
|
||||||
|
//i'll fix it once it starts happening...
|
||||||
|
//(just... re-creating the search tems to actually have spaces should do the trick, right?)
|
||||||
|
//(yeah, i'll wanna . strip spaces to not be more than one in a row and all that but. H)
|
||||||
|
//idk. this should be fine for now, and possibly, ever
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function doSearch() {
|
function clickSearch(word) {
|
||||||
|
header.querySelector("input").value = word;
|
||||||
|
doSearch();
|
||||||
|
//TODO: scroll to top of page or w/e.
|
||||||
|
//maybe dosearch should do that instead
|
||||||
|
//minds too hazy for this rn though...
|
||||||
|
}
|
||||||
|
|
||||||
|
function doSearch(state = true) {
|
||||||
let val = header.querySelector("input").value;
|
let val = header.querySelector("input").value;
|
||||||
let results = search(val);
|
if (val == "") {
|
||||||
|
main.innerHTML = "enter some search terms...";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Manage search methods
|
||||||
|
let type = "normal";
|
||||||
|
if (val.includes("show:random")) {
|
||||||
|
type = "random";
|
||||||
|
} else if (val.includes("show:all")) {
|
||||||
|
type = "all";
|
||||||
|
}
|
||||||
|
|
||||||
|
//Results
|
||||||
|
let results = search(val, type);
|
||||||
if (results.length == 0) {
|
if (results.length == 0) {
|
||||||
main.innerHTML = "no results lulw";
|
main.innerHTML = "no results (todo: cool form)";
|
||||||
} else {
|
} else {
|
||||||
main.innerHTML = "";
|
main.innerHTML = "";
|
||||||
/*
|
/*
|
||||||
@@ -275,39 +372,80 @@ function doSearch() {
|
|||||||
let meaning = document.createElement("div");
|
let meaning = document.createElement("div");
|
||||||
meaning.classList.add("result-meaning");
|
meaning.classList.add("result-meaning");
|
||||||
//ripping off jisho: Bold, word type (*required)
|
//ripping off jisho: Bold, word type (*required)
|
||||||
if (last != json[results[i]][o]["type"]) meaning.innerHTML += "<b class='capitalize'>"+json[results[i]][o]["type"]+"</b><br>";
|
if (last != json[results[i]][o]["type"]) meaning.innerHTML += "<b class='capitalize'>" + json[results[i]][o]["type"] + "</b><br>";
|
||||||
last = json[results[i]][o]["type"];
|
last = json[results[i]][o]["type"];
|
||||||
if (types[json[results[i]][o]["type"]] == undefined) {
|
if (types[json[results[i]][o]["type"]] == undefined) {
|
||||||
types[json[results[i]][o]["type"]] = 1;
|
types[json[results[i]][o]["type"]] = 1;
|
||||||
} else {
|
} else {
|
||||||
types[json[results[i]][o]["type"]]++;
|
types[json[results[i]][o]["type"]]++;
|
||||||
}
|
}
|
||||||
//number, meaning (*required)
|
//meaning, tl, etc
|
||||||
meaning.innerHTML += "<span class='result-number'>"+(o+1)+"</span><span class='result-big'>"+json[results[i]][o]["meaning"]+"</span>";
|
if (json[results[i]][o]["meaning"] != undefined) {
|
||||||
//longer translation (below are not required, make sure to check for them)
|
meaning.innerHTML += "<span class='result-number'>" + (o + 1) + "</span><span class='result-big'>" + escapeHTML(json[results[i]][o]["meaning"]) + "</span>";
|
||||||
if (json[results[i]][o]["translation"] != undefined && json[results[i]][o]["translation"].toLowerCase() != json[results[i]][o]["meaning"].toLowerCase()) {
|
} else if (json[results[i]][o]["translation"] != undefined) {
|
||||||
meaning.innerHTML += "<br><span class='result-translation'>"+json[results[i]][o]["translation"]+"</span>";
|
meaning.innerHTML += "<span class='result-number'>" + (o + 1) + "</span><span class='result-big'>" + escapeHTML(json[results[i]][o]["translation"]) + "</span>";
|
||||||
|
}
|
||||||
|
if (json[results[i]][o]["translation"] != undefined && json[results[i]][o]["meaning"] != undefined) {
|
||||||
|
if (json[results[i]][o]["translation"].toLowerCase() != json[results[i]][o]["meaning"].toLowerCase())
|
||||||
|
meaning.innerHTML += "<br><span class='result-translation'>" + json[results[i]][o]["translation"] + "</span>";
|
||||||
}
|
}
|
||||||
//example
|
//example
|
||||||
if (json[results[i]][o]["examples"] != undefined) {
|
if (json[results[i]][o]["examples"] != undefined) {
|
||||||
let temp = ""
|
let temp = ""
|
||||||
temp += "<details><summary>Examples</summary><p>";
|
temp += "<details><summary>Examples</summary><p>";
|
||||||
for (let e in json[results[i]][o]["examples"]) {
|
for (let e in json[results[i]][o]["examples"]) {
|
||||||
temp += "<span class='heonian'>"+generateRuby(e)+"</span> - "+json[results[i]][o]["examples"][e]+"<br>";
|
temp += "<span class='heonian'>" + generateRuby(e, true) + "</span> - " + json[results[i]][o]["examples"][e] + "<br>";
|
||||||
|
}
|
||||||
|
temp += "</p></details>";
|
||||||
|
meaning.innerHTML += temp;
|
||||||
|
}
|
||||||
|
//antonyms, synonyms
|
||||||
|
if (json[results[i]][o]["antonyms"] != undefined) {
|
||||||
|
let temp = ""
|
||||||
|
temp += "<details class='result-nyms'><summary>Antonyms</summary><p>";
|
||||||
|
for (let e in json[results[i]][o]["antonyms"]) {
|
||||||
|
let r = json[results[i]][o]["antonyms"][e];
|
||||||
|
temp += "<span class='heonian'>" + generateRuby(r, true);
|
||||||
|
if (json[r] != undefined) {
|
||||||
|
temp += " - ";
|
||||||
|
for (let i in json[r]) {
|
||||||
|
if (i != 0) temp += ", ";
|
||||||
|
temp += json[r][i]["translation"];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
temp += "</span><br>";
|
||||||
|
}
|
||||||
|
temp += "</p></details>";
|
||||||
|
meaning.innerHTML += temp;
|
||||||
|
}
|
||||||
|
if (json[results[i]][o]["synonyms"] != undefined) {
|
||||||
|
let temp = ""
|
||||||
|
temp += "<details class='result-nyms'><summary>Synonyms</summary><p>";
|
||||||
|
for (let e in json[results[i]][o]["synonyms"]) {
|
||||||
|
let r = json[results[i]][o]["synonyms"][e];
|
||||||
|
temp += "<span class='heonian'>" + generateRuby(r, true);
|
||||||
|
if (json[r] != undefined) {
|
||||||
|
temp += " - ";
|
||||||
|
for (let i in json[r]) {
|
||||||
|
if (i != 0) temp += ", ";
|
||||||
|
temp += json[r][i]["translation"];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
temp += "</span><br>";
|
||||||
}
|
}
|
||||||
temp += "</p></details>";
|
temp += "</p></details>";
|
||||||
meaning.innerHTML += temp;
|
meaning.innerHTML += temp;
|
||||||
}
|
}
|
||||||
//notes
|
//notes
|
||||||
if (json[results[i]][o]["notes"] != undefined) {
|
if (json[results[i]][o]["notes"] != undefined) {
|
||||||
meaning.innerHTML += "<p class='result-notes'>"+json[results[i]][o]["notes"]+"</p>";
|
meaning.innerHTML += "<p class='result-notes'>" + escapeHTML(json[results[i]][o]["notes"]) + "</p>";
|
||||||
}
|
}
|
||||||
//(source, etc)
|
//(source, etc)
|
||||||
if (json[results[i]][o]["canon-etymology"] != undefined) {
|
if (json[results[i]][o]["canon-etymology"] != undefined) {
|
||||||
meaning.innerHTML += "<details class='result-meta'><summary>Canon Etymology</summary><p>"+json[results[i]][o]["canon-etymology"]+"</p></details>";
|
meaning.innerHTML += "<details class='result-meta'><summary>Canon Etymology</summary><p>" + escapeHTML(json[results[i]][o]["canon-etymology"]) + "</p></details>";
|
||||||
}
|
}
|
||||||
if (json[results[i]][o]["meta-etymology"] != undefined) {
|
if (json[results[i]][o]["meta-etymology"] != undefined) {
|
||||||
meaning.innerHTML += "<details class='result-meta'><summary>Meta Etymology</summary><p>"+json[results[i]][o]["meta-etymology"]+"</p></details>";
|
meaning.innerHTML += "<details class='result-meta'><summary>Meta Etymology</summary><p>" + escapeHTML(json[results[i]][o]["meta-etymology"]) + "</p></details>";
|
||||||
}
|
}
|
||||||
//todo
|
//todo
|
||||||
result.appendChild(meaning); //y, yeah.
|
result.appendChild(meaning); //y, yeah.
|
||||||
@@ -317,24 +455,127 @@ function doSearch() {
|
|||||||
types = sortObject(types);
|
types = sortObject(types);
|
||||||
let header = document.createElement("div");
|
let header = document.createElement("div");
|
||||||
header.classList.add("results-header");
|
header.classList.add("results-header");
|
||||||
header.innerHTML += "<span class='heonian'>search results for: " + val + "</span><br>";
|
//When using search methods, accomodate search text.
|
||||||
|
//we dont wanna actually change val, because this breaks searchParams
|
||||||
|
switch (type) {
|
||||||
|
//show:all
|
||||||
|
case "all":
|
||||||
|
header.innerHTML += "<span class='heonian'>showing all words</span><br>";
|
||||||
|
break;
|
||||||
|
case "random":
|
||||||
|
//think about whether we wanna set searchparams to this, though..?
|
||||||
|
header.innerHTML += "<span class='heonian'>showing random word: " + results[0] + "</span><br>";
|
||||||
|
break;
|
||||||
|
//OMG A WORD
|
||||||
|
default:
|
||||||
|
header.innerHTML += "<span class='heonian'>search results for: " + val + "</span><br>";
|
||||||
|
break;
|
||||||
|
}
|
||||||
for (let i in types) {
|
for (let i in types) {
|
||||||
header.innerHTML += "<span class='results-header-count'>"+i+"s - "+types[i]+"</span>";
|
if (i !== "") { header.innerHTML += "<span class='results-header-count'>" + i + "s - " + types[i] + "</span>"; }
|
||||||
}
|
}
|
||||||
main.prepend(header);
|
main.prepend(header);
|
||||||
}
|
}
|
||||||
|
const url = new URL(window.location);
|
||||||
|
url.searchParams.set('s', val);
|
||||||
|
if (state == true) history.pushState(val, "", url);
|
||||||
|
}
|
||||||
|
|
||||||
|
function goHome(state = true) {
|
||||||
|
animateHeader(true);
|
||||||
|
const url = new URL(window.location);
|
||||||
|
url.searchParams.delete('s');
|
||||||
|
if (state == true) history.pushState(null, "", url);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function registerSW() {
|
||||||
|
if ('serviceWorker' in navigator) {
|
||||||
|
if (location.hostname === "localhost" || location.hostname === "127.0.0.1") {
|
||||||
|
console.log("localhost - not registering sw"); //because spamming removeSW() every time i make a change is annoying;
|
||||||
|
removeSW(); //just in case =w=
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
navigator.serviceWorker.register('./sw.js').then(registration => {
|
||||||
|
registration.onupdatefound = () => {
|
||||||
|
const installingWorker = registration.installing;
|
||||||
|
if (installingWorker == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
installingWorker.onstatechange = () => {
|
||||||
|
if (installingWorker.state === 'installed') {
|
||||||
|
if (navigator.serviceWorker.controller) {
|
||||||
|
// At this point, the updated precached content has been fetched,
|
||||||
|
// but the previous service worker will still serve the older
|
||||||
|
// content until all client tabs are closed.
|
||||||
|
header.querySelector("#update").style.display = "block";
|
||||||
|
} else {
|
||||||
|
// At this point, everything has been precached.
|
||||||
|
// It's the perfect time to display a
|
||||||
|
// "Content is cached for offline use." message.
|
||||||
|
console.log('Content is cached for offline use.');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}).catch(error => {
|
||||||
|
console.error('Error during service worker registration:', error);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function removeSW() {
|
||||||
|
caches.keys().then(function(names) {
|
||||||
|
for (let name of names)
|
||||||
|
caches.delete(name);
|
||||||
|
}); //this doesnt actually seem to work :/ but . i'll leave it in for later fixing
|
||||||
|
navigator.serviceWorker.getRegistrations().then(function(registrations) {
|
||||||
|
for (let registration of registrations)
|
||||||
|
registration.unregister();
|
||||||
|
}); //dev use only!! or whatever... i just copypasted this from SO
|
||||||
|
}
|
||||||
|
|
||||||
|
function escapeHTML(str){
|
||||||
|
return new Option(str).innerHTML;
|
||||||
}
|
}
|
||||||
|
|
||||||
window.onload = () => {
|
window.onload = () => {
|
||||||
header = document.querySelector("header");
|
header = document.querySelector("header");
|
||||||
main = document.querySelector("main");
|
main = document.querySelector("main");
|
||||||
header.querySelector("#search button").onclick = () => {toggleIME();};
|
header.querySelector("#search button").onclick = () => { toggleIME(); };
|
||||||
header.querySelector("span.heonian").onclick = () => {
|
header.querySelector("span.heonian").onclick = () => {
|
||||||
if (!header.classList.contains("fullscreen")) {
|
if (!header.classList.contains("fullscreen")) {
|
||||||
animateHeader(true);
|
goHome();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
header.querySelector("#showAllWords").onclick = () => {
|
||||||
|
if (header.classList.contains("fullscreen")) {
|
||||||
|
animateHeader(false);
|
||||||
|
}
|
||||||
|
header.querySelector("input").value = "show:all";
|
||||||
|
doSearch(true);
|
||||||
|
};
|
||||||
|
header.querySelector("#randomWord").onclick = () => {
|
||||||
|
if (header.classList.contains("fullscreen")) {
|
||||||
|
animateHeader(false);
|
||||||
|
}
|
||||||
|
header.querySelector("input").value = "show:random";
|
||||||
|
doSearch(true);
|
||||||
|
};
|
||||||
loadDictionary();
|
loadDictionary();
|
||||||
|
window.addEventListener('popstate', (e) => {
|
||||||
|
if (e.state == null) {
|
||||||
|
if (!header.classList.contains("fullscreen")) {
|
||||||
|
goHome(false);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (header.classList.contains("fullscreen")) {
|
||||||
|
animateHeader(false);
|
||||||
|
}
|
||||||
|
header.querySelector("input").value = e.state;
|
||||||
|
doSearch(false);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
registerSW(); //considering disabling this for now,.... itso nly lead to trouble :////
|
||||||
}
|
}
|
||||||
|
|
||||||
const sortObject = obj => Object.keys(obj).sort().reduce((res, key) => (res[key] = obj[key], res), {})
|
const sortObject = obj => Object.keys(obj).sort().reduce((res, key) => (res[key] = obj[key], res), {})
|
||||||
58
manifest.json
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
{
|
||||||
|
"name": "hisho",
|
||||||
|
"short_name": "hisho",
|
||||||
|
"theme_color": "#fff",
|
||||||
|
"background_color": "#fff",
|
||||||
|
"display": "fullScreen",
|
||||||
|
"orientation": "portrait",
|
||||||
|
"scope": "/hw/",
|
||||||
|
"start_url": "/hw/",
|
||||||
|
"icons": [
|
||||||
|
{
|
||||||
|
"src": "icons/icon-72x72.png",
|
||||||
|
"sizes": "72x72",
|
||||||
|
"type": "image/png"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"src": "icons/icon-96x96.png",
|
||||||
|
"sizes": "96x96",
|
||||||
|
"type": "image/png"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"src": "icons/icon-128x128.png",
|
||||||
|
"sizes": "128x128",
|
||||||
|
"type": "image/png"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"src": "icons/icon-144x144.png",
|
||||||
|
"sizes": "144x144",
|
||||||
|
"type": "image/png"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"src": "icons/icon-152x152.png",
|
||||||
|
"sizes": "152x152",
|
||||||
|
"type": "image/png"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"src": "icons/icon-192x192.png",
|
||||||
|
"sizes": "192x192",
|
||||||
|
"type": "image/png"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"src": "icons/icon-384x384.png",
|
||||||
|
"sizes": "384x384",
|
||||||
|
"type": "image/png"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"src": "icons/icon-512x512.png",
|
||||||
|
"sizes": "512x512",
|
||||||
|
"type": "image/png"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"src": "icons/maskable_icon.png",
|
||||||
|
"sizes": "640x640",
|
||||||
|
"type": "image/png",
|
||||||
|
"purpose": "any maskable"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
7
pre-commit
Executable file
@@ -0,0 +1,7 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -eo pipefail
|
||||||
|
|
||||||
|
VAR="const currentVersion = '$RANDOM';"
|
||||||
|
sed "1s/.*/$VAR/" sw.js > sw.js.new
|
||||||
|
mv sw.js.new sw.js
|
||||||
|
git add sw.js
|
||||||
91
sw.js
Normal file
@@ -0,0 +1,91 @@
|
|||||||
|
const currentVersion = '7675';
|
||||||
|
|
||||||
|
const addResourcesToCache = async (resources) => {
|
||||||
|
const cache = await caches.open(currentVersion);
|
||||||
|
await cache.addAll(resources);
|
||||||
|
};
|
||||||
|
|
||||||
|
const putInCache = async (request, response) => {
|
||||||
|
const cache = await caches.open(currentVersion);
|
||||||
|
await cache.put(request, response);
|
||||||
|
};
|
||||||
|
|
||||||
|
const cacheFirst = async ({ request, preloadResponsePromise }) => {
|
||||||
|
// First try to get the resource from the cache
|
||||||
|
const responseFromCache = await caches.match(request);
|
||||||
|
if (responseFromCache) {
|
||||||
|
return responseFromCache;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Next try to use the preloaded response, if it's there
|
||||||
|
const preloadResponse = await preloadResponsePromise;
|
||||||
|
if (preloadResponse) {
|
||||||
|
console.info('using preload response', preloadResponse);
|
||||||
|
putInCache(request, preloadResponse.clone());
|
||||||
|
return preloadResponse;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Next try to get the resource from the network
|
||||||
|
try {
|
||||||
|
const responseFromNetwork = await fetch(request);
|
||||||
|
// response may be used only once
|
||||||
|
// we need to save clone to put one copy in cache
|
||||||
|
// and serve second one
|
||||||
|
putInCache(request, responseFromNetwork.clone());
|
||||||
|
return responseFromNetwork;
|
||||||
|
} catch (error) {
|
||||||
|
return new Response('Network error happened', {
|
||||||
|
status: 408,
|
||||||
|
headers: { 'Content-Type': 'text/plain' },
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const deleteCache = async key => {
|
||||||
|
await caches.delete(key)
|
||||||
|
}
|
||||||
|
|
||||||
|
const deleteOldCaches = async () => {
|
||||||
|
const cacheKeepList = [currentVersion];
|
||||||
|
const keyList = await caches.keys()
|
||||||
|
const cachesToDelete = keyList.filter(key => !cacheKeepList.includes(key))
|
||||||
|
await Promise.all(cachesToDelete.map(deleteCache));
|
||||||
|
}
|
||||||
|
|
||||||
|
self.addEventListener('activate', (event) => {
|
||||||
|
event.waitUntil(deleteOldCaches());
|
||||||
|
});
|
||||||
|
|
||||||
|
const enableNavigationPreload = async () => {
|
||||||
|
if (self.registration.navigationPreload) {
|
||||||
|
// Enable navigation preloads!
|
||||||
|
await self.registration.navigationPreload.enable();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
self.addEventListener('activate', (event) => {
|
||||||
|
event.waitUntil(enableNavigationPreload());
|
||||||
|
});
|
||||||
|
|
||||||
|
self.addEventListener('install', (event) => {
|
||||||
|
event.waitUntil(
|
||||||
|
addResourcesToCache([
|
||||||
|
'./heonian-resources/wordlist.json',
|
||||||
|
'./heonian-ime/ime.js',
|
||||||
|
'./font.otf',
|
||||||
|
'./index.html',
|
||||||
|
'./main.css',
|
||||||
|
'./main.js',
|
||||||
|
'./manifest.json'
|
||||||
|
])
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
self.addEventListener('fetch', (event) => {
|
||||||
|
event.respondWith(
|
||||||
|
cacheFirst({
|
||||||
|
request: event.request,
|
||||||
|
preloadResponsePromise: event.preloadResponse
|
||||||
|
})
|
||||||
|
);
|
||||||
|
});
|
||||||
356
wordlist.json
@@ -1,356 +0,0 @@
|
|||||||
{
|
|
||||||
"": [
|
|
||||||
{
|
|
||||||
"type": "modifier",
|
|
||||||
"meaning": "In an early stage of development.",
|
|
||||||
"translation": "Young",
|
|
||||||
"antonyms": [
|
|
||||||
""
|
|
||||||
]
|
|
||||||
}
|
|
||||||
],
|
|
||||||
" ": [
|
|
||||||
{
|
|
||||||
"type": "expression",
|
|
||||||
"meaning": "Utilized to seek confirmation from listener.",
|
|
||||||
"translation": "Isn't that right?"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"": [
|
|
||||||
{
|
|
||||||
"type": "marker",
|
|
||||||
"meaning": "Follows an object in which the action of the verb is intended to.",
|
|
||||||
"translation": "At, to, towards, for, into"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"": [
|
|
||||||
{
|
|
||||||
"type": "verb",
|
|
||||||
"meaning": "To rest in an horizontal position.",
|
|
||||||
"translation": "To lie."
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"": [
|
|
||||||
{
|
|
||||||
"type": "noun",
|
|
||||||
"meaning": "Usable heat or power.",
|
|
||||||
"translation": "Energy"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "noun",
|
|
||||||
"meaning": "Source of sorcery power.",
|
|
||||||
"translation": "Magic energy"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"": [
|
|
||||||
{
|
|
||||||
"type": "noun",
|
|
||||||
"meaning": "Animated entity powered by sorcery or any other energy source.",
|
|
||||||
"translation": "Animated construct."
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"": [
|
|
||||||
{
|
|
||||||
"type": "noun",
|
|
||||||
"meaning": "Inducement, reason or goal that motivates someone to do something.",
|
|
||||||
"translation": "Desire"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "noun",
|
|
||||||
"meaning": "The ability to control oneself and determine oneself's course of action.",
|
|
||||||
"translation": "Willpower"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"": [
|
|
||||||
{
|
|
||||||
"type": "noun",
|
|
||||||
"meaning": "A kind of genderless shapeshifting spirits who got sealed in the depths of the world during the old era, characteristic for having intrinsic power to control a specific feeling of any conscious being.",
|
|
||||||
"translation": "Demon"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"": [
|
|
||||||
{
|
|
||||||
"type": "modifier",
|
|
||||||
"meaning": "Having little length, not long.",
|
|
||||||
"translation": "Short",
|
|
||||||
"antonyms": [
|
|
||||||
""
|
|
||||||
]
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"": [
|
|
||||||
{
|
|
||||||
"type": "expression",
|
|
||||||
"meaning": "A consenting reply.",
|
|
||||||
"translation": "Yes, correct",
|
|
||||||
"antonym": ""
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "modifier",
|
|
||||||
"meaning": "To a high degree or intensity.",
|
|
||||||
"translation": "Very"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"": [
|
|
||||||
{
|
|
||||||
"type": "noun",
|
|
||||||
"meaning": "The route or course along which something travels or moves.",
|
|
||||||
"translation": "Path",
|
|
||||||
"meta-etymology": "Used to derive meaning for a word suggested by @taminaminam@tech.lgbt"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "noun",
|
|
||||||
"meaning": "The single complete movement of raising one foot and putting it down in another spot, as in walking.",
|
|
||||||
"translation": "Step",
|
|
||||||
"meta-etymology": "Used to derive meaning for a word suggested by @taminaminam@tech.lgbt"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"": [
|
|
||||||
{
|
|
||||||
"type": "expression",
|
|
||||||
"meaning": "Used to express gratitude or grateful thoughts.",
|
|
||||||
"translation": "Thanks",
|
|
||||||
"meta-etymology": "Suggested by @gamer@bungle.online"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"": [
|
|
||||||
{
|
|
||||||
"type": "verb",
|
|
||||||
"meaning": "To move over a surface by taking steps.",
|
|
||||||
"translation": "To walk",
|
|
||||||
"canon-etymology": "Derived from the word , meaning step."
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"": [
|
|
||||||
{
|
|
||||||
"type": "noun",
|
|
||||||
"meaning": " A style of animation developed in Japan, characterized by stylized colorful art and often adult themes.",
|
|
||||||
"translation": "Anime",
|
|
||||||
"meta-etymology": "Yeah it comes from the word \"anime\"."
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"" : [
|
|
||||||
{
|
|
||||||
"type": "pronoun",
|
|
||||||
"meaning": "The second-person singular pronoun.",
|
|
||||||
"translation": "You",
|
|
||||||
"examples": {
|
|
||||||
" ?":"Were you sleeping?",
|
|
||||||
" ": "I like you."
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"": [
|
|
||||||
{
|
|
||||||
"type": "verb",
|
|
||||||
"meaning": " To name or list (the units of a group or collection) one by one in order to determine a total; number.",
|
|
||||||
"translation": "To count"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"": [
|
|
||||||
{
|
|
||||||
"type": "verb",
|
|
||||||
"meaning": "To move through or on top of a liquid.",
|
|
||||||
"translation": "To swim"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"" : [
|
|
||||||
{
|
|
||||||
"type": "noun",
|
|
||||||
"meaning": "The terminal part of the humanoid arm located below the forearm, used for grasping and holding and consisting of the wrist, palm, several fingers, and an opposable thumb.",
|
|
||||||
"translation": "Hand"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"" : [
|
|
||||||
{
|
|
||||||
"type": "verb",
|
|
||||||
"meaning": "To have and keep in one's grasp, preventing from falling or moving.",
|
|
||||||
"translation": "To hold"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "verb",
|
|
||||||
"meaning": "To clasp or hold closely, especially in the arms, as in affection; embrace.",
|
|
||||||
"translation": "To hug"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"" : [
|
|
||||||
{
|
|
||||||
"type": "modifier",
|
|
||||||
"meaning": "Below average in size or extent.",
|
|
||||||
"translation": "Small",
|
|
||||||
"antonyms": [
|
|
||||||
""
|
|
||||||
]
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"" : [
|
|
||||||
{
|
|
||||||
"type": "modifier",
|
|
||||||
"meaning": "Above average in size or extent.",
|
|
||||||
"translation": "Large",
|
|
||||||
"antonyms": [
|
|
||||||
""
|
|
||||||
]
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"" : [
|
|
||||||
{
|
|
||||||
"type": "noun",
|
|
||||||
"meaning": "The round or oval reproductive body of various animals, including birds, reptiles, amphibians, fishes, and insects, consisting usually of an embryo surrounded by nutrient material and a protective covering.",
|
|
||||||
"translation": "Egg."
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"" : [
|
|
||||||
{
|
|
||||||
"type": "noun",
|
|
||||||
"meaning": "The day before the present day.",
|
|
||||||
"translation": "Yesterday",
|
|
||||||
"canon-etymology": "Fusion of words and ."
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"" : [
|
|
||||||
{
|
|
||||||
"type": "noun",
|
|
||||||
"meaning": "A kind of plant characteristic for having jointed stems sheathed by long narrow leaves, flowers in spikes, and seedlike fruits. This includes cereals, bamboo, etc",
|
|
||||||
"translation": "Grass"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"" : [
|
|
||||||
{
|
|
||||||
"type": "noun",
|
|
||||||
"meaning": "A kind of various long-eared, short-tailed, small to moderate size burrowing mammals. They have long hind legs, with four toes on each foot, and shorter fore legs, with five toes each.",
|
|
||||||
"translation": "Rabbit",
|
|
||||||
"meta-etymology": "Meme of mispelling bunny."
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"" : [
|
|
||||||
{
|
|
||||||
"type": "modifier",
|
|
||||||
"meaning": "Existing in plentiful supply.",
|
|
||||||
"translation": "Abundant"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "pronoun",
|
|
||||||
"meaning": "A large number of something.",
|
|
||||||
"translation": "Many",
|
|
||||||
"meta-etymology": "From english \"Big\"."
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"" : [
|
|
||||||
{
|
|
||||||
"type": "noun",
|
|
||||||
"meaning": "Any kind of warm-blooded vertebrates characterised by feathers, toothless beaked jaws, the laying of hard-shelled eggs, a high metabolic rate, a four-chambered heart, and a strong yet lightweight skeleton.",
|
|
||||||
"translation": "Bird"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"" : [
|
|
||||||
{
|
|
||||||
"type": "verb",
|
|
||||||
"meaning": "To make, join or decorate pieces of fabric by means of a thread repeatedly passed through with a needle or similar implement.",
|
|
||||||
"translation": "To sew"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"" : [
|
|
||||||
{
|
|
||||||
"type": "noun",
|
|
||||||
"meaning": "Garments for the body; articles of dress; wearing apparel.",
|
|
||||||
"translation": "clothes",
|
|
||||||
"canon-etymology": "Noun formed from the verb ."
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"" : [
|
|
||||||
{
|
|
||||||
"type": "verb",
|
|
||||||
"meaning": "To deprive of life.",
|
|
||||||
"translation": "To kill"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "verb",
|
|
||||||
"meaning": "To destroy a vitally essential quality in.",
|
|
||||||
"translation": "To kill"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"" : [
|
|
||||||
{
|
|
||||||
"type": "modifier",
|
|
||||||
"meaning": "Of small or limited width, especially in comparison with length.",
|
|
||||||
"translation": "Narrow"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"" : [
|
|
||||||
{
|
|
||||||
"type": "noun",
|
|
||||||
"meaning": "The fleshy, movable, muscular organ, found mostly in most vertebrates to the floor of the mouth, that is the principal organ of taste, an aid in chewing and swallowing, and, in sometimes an important aspect of speech.",
|
|
||||||
"translation": "Tongue"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"" : [
|
|
||||||
{
|
|
||||||
"type": "noun",
|
|
||||||
"meaning": "The organ of smell and entrance to the respiratory tract, consisting of a prominent structure divided into two hair-lined air passages by a median septum.",
|
|
||||||
"translation": "Nose"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"" : [
|
|
||||||
{
|
|
||||||
"type": "modifier",
|
|
||||||
"meaning": "Being such that every part of the surface or the circumference is equidistant from the center.",
|
|
||||||
"translation": "Round"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"" : [
|
|
||||||
{
|
|
||||||
"type": "verb",
|
|
||||||
"meaning": "To increase in size or volume as a result of internal pressure; expand.",
|
|
||||||
"translation": "To swell"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"": [
|
|
||||||
{
|
|
||||||
"type": "marker",
|
|
||||||
"meaning": "Follows the subject in a clause of a sentence"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"" : [
|
|
||||||
{
|
|
||||||
"type": "verb",
|
|
||||||
"meaning": "To form letters, words, or symbols on a surface with an instrument.",
|
|
||||||
"translation": "To write"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"": [
|
|
||||||
{
|
|
||||||
"type": "noun",
|
|
||||||
"meaning": "snow",
|
|
||||||
"translation": "snow",
|
|
||||||
"meta-etymology": "I want one my names to mean something pretty - Ari.",
|
|
||||||
"examples": {
|
|
||||||
" ": "i hope ari can see snow"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "noun",
|
|
||||||
"meaning": "safety",
|
|
||||||
"translation": "Safety",
|
|
||||||
"meta-etymology": "Suggested by @taminaminam@tech.lgbt"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "modifier",
|
|
||||||
"meaning": "safety",
|
|
||||||
"translation": "Safe",
|
|
||||||
"meta-etymology": "Suggested by @taminaminam@tech.lgbt"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"": [
|
|
||||||
{
|
|
||||||
"type": "verb",
|
|
||||||
"meaning": "To have an inclination or preference",
|
|
||||||
"translation": "To like"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "verb",
|
|
||||||
"meaning": "To find pleasant or attractive, to enjoy",
|
|
||||||
"translation": "To enjoy"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||