Compare commits
42 Commits
a4f1a04c72
...
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 | ||
| 08b5f6daf6 | |||
| 85f9625fea | |||
| fad6471e48 | |||
| 260e25e37a | |||
| a035ea3201 | |||
|
|
a2e7559f5d | ||
| 57ea079eaf | |||
| 9c513f8319 | |||
| af8a9e6763 |
1
.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
update.php
|
||||||
1
.gitignore_global
Normal file
@@ -0,0 +1 @@
|
|||||||
|
.DS_Store
|
||||||
6
.gitmodules
vendored
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
[submodule "heonian-ime"]
|
||||||
|
path = 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-ime
Submodule
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 |
14
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,14 +37,16 @@
|
|||||||
</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>
|
||||||
|
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
|
<script src="./heonian-ime/ime.js"></script>
|
||||||
<script src="./main.js"></script>
|
<script src="./main.js"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
70
main.css
@@ -32,19 +32,33 @@
|
|||||||
:root {
|
:root {
|
||||||
--font: "Helvetica Neue", Helvetica, Arial, sans-serif;
|
--font: "Helvetica Neue", Helvetica, Arial, sans-serif;
|
||||||
--font-h: "heonian", "Helvatica Neue", Helvetica, Arial, sans-serif;
|
--font-h: "heonian", "Helvatica Neue", Helvetica, Arial, sans-serif;
|
||||||
--nice-shadow: 0 1px 3px rgba(0,0,0,0.12), 0 1px 2px rgba(0,0,0,0.24);
|
--fg: rgb(0,0,0);
|
||||||
--grey: rgb(226, 226, 226);
|
--bg: rgb(255,255,255);
|
||||||
--darkgrey: rgb(150, 150, 150);
|
--grey: rgb(152, 152, 152);
|
||||||
|
--darkgrey: rgb(100, 100, 100);
|
||||||
|
--link: rgb(27 120 151);
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (prefers-color-scheme: dark) {
|
||||||
|
:root {
|
||||||
|
--fg: rgb(255,255,255);
|
||||||
|
--bg: rgb(0,0,0);
|
||||||
|
--grey: rgb(226, 226, 226);
|
||||||
|
--darkgrey: rgb(215, 215, 215);
|
||||||
|
--link: rgb(27 120 151);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
body {
|
body {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
font-family: var(--font);
|
font-family: var(--font);
|
||||||
|
color: var(--fg);
|
||||||
|
background-color: var(--bg);
|
||||||
}
|
}
|
||||||
|
|
||||||
a {
|
a {
|
||||||
color: rgb(27 120 151);
|
color: var(--link);
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -53,6 +67,10 @@ a:hover {
|
|||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.clickable {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
.heonian {
|
.heonian {
|
||||||
font-family: "heonian";
|
font-family: "heonian";
|
||||||
}
|
}
|
||||||
@@ -87,6 +105,9 @@ header #search button {
|
|||||||
text-align: center;
|
text-align: center;
|
||||||
height: 2rem;
|
height: 2rem;
|
||||||
border-left: 1px solid var(--grey);
|
border-left: 1px solid var(--grey);
|
||||||
|
color: var(--grey);
|
||||||
|
transition: 0.3s color ease;
|
||||||
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
header input {
|
header input {
|
||||||
@@ -100,6 +121,8 @@ header input {
|
|||||||
font-weight: 100;
|
font-weight: 100;
|
||||||
transition: border-color 0.3s;
|
transition: border-color 0.3s;
|
||||||
width: calc(100% - 52px - 24px);
|
width: calc(100% - 52px - 24px);
|
||||||
|
background-color: var(--bg);
|
||||||
|
color: var(--fg);
|
||||||
}
|
}
|
||||||
|
|
||||||
header input:focus {
|
header input:focus {
|
||||||
@@ -109,6 +132,9 @@ header input:focus {
|
|||||||
|
|
||||||
header span.heonian {
|
header span.heonian {
|
||||||
font-size: 1.5rem;
|
font-size: 1.5rem;
|
||||||
|
cursor: pointer;
|
||||||
|
user-select: none;
|
||||||
|
-webkit-user-select: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
header.fullscreen {
|
header.fullscreen {
|
||||||
@@ -126,6 +152,7 @@ header.fullscreen {
|
|||||||
|
|
||||||
header.fullscreen span.heonian {
|
header.fullscreen span.heonian {
|
||||||
font-size: 8rem;
|
font-size: 8rem;
|
||||||
|
cursor: default;
|
||||||
}
|
}
|
||||||
|
|
||||||
header.fullscreen #search {
|
header.fullscreen #search {
|
||||||
@@ -133,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;
|
||||||
}
|
}
|
||||||
@@ -145,7 +176,7 @@ main {
|
|||||||
opacity: 0;
|
opacity: 0;
|
||||||
max-width: 600px;
|
max-width: 600px;
|
||||||
margin: auto;
|
margin: auto;
|
||||||
margin-top: 1rem;
|
margin-top: calc(1rem + 24px);
|
||||||
padding-left: 1rem;
|
padding-left: 1rem;
|
||||||
padding-right: 1rem;
|
padding-right: 1rem;
|
||||||
}
|
}
|
||||||
@@ -168,6 +199,14 @@ main {
|
|||||||
border-bottom: 1px solid var(--darkgrey);
|
border-bottom: 1px solid var(--darkgrey);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.result:first-child {
|
||||||
|
padding-top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.result:last-child {
|
||||||
|
border-bottom: none;
|
||||||
|
}
|
||||||
|
|
||||||
.result-meaning {
|
.result-meaning {
|
||||||
padding-bottom: 8px;
|
padding-bottom: 8px;
|
||||||
}
|
}
|
||||||
@@ -199,6 +238,14 @@ main {
|
|||||||
color: var(--darkgrey);
|
color: var(--darkgrey);
|
||||||
margin-top: 6px;
|
margin-top: 6px;
|
||||||
margin-bottom: 6px;
|
margin-bottom: 6px;
|
||||||
|
border-left: 3px solid var(--darkgrey);
|
||||||
|
padding-left: 4px;
|
||||||
|
font-family: var(--font-h);
|
||||||
|
}
|
||||||
|
|
||||||
|
.result-translation {
|
||||||
|
font-size: 0.9rem;
|
||||||
|
color: var(--darkgrey);
|
||||||
}
|
}
|
||||||
|
|
||||||
.result summary {
|
.result summary {
|
||||||
@@ -212,4 +259,17 @@ main {
|
|||||||
font-size: 1.25rem;
|
font-size: 1.25rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.result details.result-meta p {
|
||||||
|
font-size: 1rem;
|
||||||
|
font-family: var(--font-h);
|
||||||
|
}
|
||||||
|
|
||||||
|
.results-header-count::after {
|
||||||
|
content: ", ";
|
||||||
|
}
|
||||||
|
|
||||||
|
.results-header-count:last-child::after {
|
||||||
|
content: "";
|
||||||
|
}
|
||||||
|
|
||||||
/* todo. organize this file better. this is a fucking mess */
|
/* todo. organize this file better. this is a fucking mess */
|
||||||
387
main.js
@@ -5,8 +5,22 @@ let searchDictionary = {};
|
|||||||
let header = null;
|
let header = null;
|
||||||
let main = null;
|
let main = null;
|
||||||
|
|
||||||
|
let ime = null;
|
||||||
|
|
||||||
|
function toggleIME() {
|
||||||
|
if (ime == null) {
|
||||||
|
ime = new HeonianIME(header.querySelector("input"));
|
||||||
|
header.querySelector("#search button").style.color = "var(--fg)";
|
||||||
|
} else {
|
||||||
|
ime.imeDetach();
|
||||||
|
ime = null;
|
||||||
|
header.querySelector("#search button").style.color = "var(--grey)";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
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");
|
||||||
@@ -15,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");
|
||||||
@@ -46,11 +61,15 @@ 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) {
|
||||||
|
toggleIME();
|
||||||
|
} else if (header.querySelector("input").matches(":focus")) {
|
||||||
|
header.querySelector("input").value = "";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (e.keyCode === 13) {
|
if (e.keyCode === 13) {
|
||||||
if (header.querySelector("input").matches(":focus")) {
|
if (header.querySelector("input").matches(":focus") && ime == null) {
|
||||||
//search
|
//search
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
if (header.classList.contains("fullscreen")) {
|
if (header.classList.contains("fullscreen")) {
|
||||||
@@ -61,8 +80,9 @@ document.addEventListener("keydown", (e) => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
function stripWord(word) {
|
function stripWord(word, space = false) {
|
||||||
return 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();
|
||||||
}
|
}
|
||||||
|
|
||||||
heonianVowels = {
|
heonianVowels = {
|
||||||
@@ -114,7 +134,7 @@ heonianConsonants = {
|
|||||||
"10": "h",
|
"10": "h",
|
||||||
};
|
};
|
||||||
|
|
||||||
function heonianToRoman(text) {
|
function heonianToRoman(text, strict = false) {
|
||||||
let roman = "";
|
let roman = "";
|
||||||
for (let i = 0; i < text.length; i++) {
|
for (let i = 0; i < text.length; i++) {
|
||||||
let h = text.codePointAt(i);
|
let h = text.codePointAt(i);
|
||||||
@@ -129,15 +149,64 @@ function heonianToRoman(text) {
|
|||||||
roman += heonianConsonants[h[1] + "" + h[2]] + heonianVowels[h[3] - 1];
|
roman += heonianConsonants[h[1] + "" + h[2]] + heonianVowels[h[3] - 1];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else if (strict == false) {
|
||||||
roman += text.charAt(i);
|
roman += text.charAt(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return roman;
|
return roman;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function processVerb(word) {
|
||||||
|
//basically, turn welikanyapash into liku
|
||||||
|
//and uhhhhhhhhhhh maybe. return as an object with. all the things . used, for info
|
||||||
|
return word;
|
||||||
|
//but ... not yet uwu
|
||||||
|
}
|
||||||
|
|
||||||
|
function isHeonian(word) {
|
||||||
|
letters = word.split("");
|
||||||
|
for (let i = 0; i < letters.length; i++) {
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
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) => {
|
||||||
@@ -147,24 +216,40 @@ function loadDictionary() {
|
|||||||
let keys = Object.keys(json);
|
let keys = Object.keys(json);
|
||||||
//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++) {
|
||||||
//create array
|
try {
|
||||||
searchDictionary[keys[i]] = [];
|
if (keys[i] == "") continue;
|
||||||
|
//create array
|
||||||
|
searchDictionary[keys[i]] = [];
|
||||||
|
|
||||||
//add: word
|
//add: word
|
||||||
searchDictionary[keys[i]].push(keys[i]);
|
// searchDictionary[keys[i]].push(keys[i]);
|
||||||
|
|
||||||
//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.
|
||||||
|
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++) {
|
||||||
searchDictionary[keys[i]].push(stripWord(values[i][o]["meaning"]));
|
if (values[i][o].hasOwnProperty("translation")) {
|
||||||
searchDictionary[keys[i]].push(stripWord(values[i][o]["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));
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.log(keys[i] + " failed to load :/");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//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");
|
||||||
@@ -173,41 +258,104 @@ function loadDictionary() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function search(word) {
|
function search(word, type) {
|
||||||
word = stripWord(word);
|
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(" ");
|
||||||
|
for (let i = 0; i < words.length; i++) {
|
||||||
|
words[i] = stripWord(words[i]);
|
||||||
|
words[i] = heonianToRoman(words[i]);
|
||||||
|
words[i] = processVerb(words[i]);
|
||||||
|
}
|
||||||
|
word = words.join("");
|
||||||
|
console.log("debug - search: " + word);
|
||||||
let result = [];
|
let result = [];
|
||||||
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) {
|
||||||
let results = search(header.querySelector("input").value);
|
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;
|
||||||
|
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 = "";
|
||||||
/*
|
/*
|
||||||
[words - 420 found / expressions - 69 found / wahtever else - ygettheidea] (click one to filter to just those)
|
[words - 420 found / expressions - 69 found / wahtever else - ygettheidea] (click one to filter to just those)
|
||||||
*/
|
*/
|
||||||
|
let types = {}
|
||||||
for (let i = 0; i < results.length; i++) {
|
for (let i = 0; i < results.length; i++) {
|
||||||
let result = document.createElement("div");
|
let result = document.createElement("div");
|
||||||
result.classList.add("result");
|
result.classList.add("result");
|
||||||
|
|
||||||
// 1. add word in heo + romanized ruby as header
|
// 1. add word in heo + romanized ruby as header
|
||||||
let header = document.createElement("ruby");
|
let header = document.createElement("span");
|
||||||
header.classList.add("result-header");
|
header.classList.add("result-header");
|
||||||
header.innerHTML = results[i] + " <rt>" + heonianToRoman(results[i]) + "</rt>";
|
header.innerHTML = generateRuby(results[i]);
|
||||||
|
|
||||||
// 2. add tags [tags like. common word, slang, formal???, type, etc]
|
// 2. add tags [tags like. common word, slang, formal???, type, etc]
|
||||||
|
// hhh how do i do this part, what tags. would i add. would this be. per word, or per definition?
|
||||||
|
|
||||||
// 3. formal/nonformal versions, inflections button
|
// 3. formal/nonformal versions, inflections button
|
||||||
|
// could try to work on this though
|
||||||
|
|
||||||
// 4. audio clip if found
|
// 4. audio clip if found
|
||||||
|
|
||||||
@@ -219,48 +367,215 @@ function doSearch() {
|
|||||||
repeat for all meanings of word,
|
repeat for all meanings of word,
|
||||||
*/
|
*/
|
||||||
result.appendChild(header);
|
result.appendChild(header);
|
||||||
|
let last = "";
|
||||||
for (let o = 0; o < json[results[i]].length; o++) {
|
for (let o = 0; o < json[results[i]].length; o++) {
|
||||||
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)
|
||||||
meaning.innerHTML += "<b class='capitalize'>"+json[results[i]][o]["type"]+"</b>";
|
if (last != json[results[i]][o]["type"]) meaning.innerHTML += "<b class='capitalize'>" + json[results[i]][o]["type"] + "</b><br>";
|
||||||
//number, meaning (*required)
|
last = json[results[i]][o]["type"];
|
||||||
meaning.innerHTML += "<br><span class='result-number'>"+(o+1)+"</span><span class='result-big'>"+json[results[i]][o]["meaning"]+"</span>";
|
if (types[json[results[i]][o]["type"]] == undefined) {
|
||||||
//longer translation (below are not required, make sure to check for them)
|
types[json[results[i]][o]["type"]] = 1;
|
||||||
if (json[results[i]][o]["translation"] != undefined) {
|
} else {
|
||||||
meaning.innerHTML += "<br><details><summary>Translation</summary><p>"+json[results[i]][o]["translation"]+"</p></details>";
|
types[json[results[i]][o]["type"]]++;
|
||||||
|
}
|
||||||
|
//meaning, tl, etc
|
||||||
|
if (json[results[i]][o]["meaning"] != undefined) {
|
||||||
|
meaning.innerHTML += "<span class='result-number'>" + (o + 1) + "</span><span class='result-big'>" + escapeHTML(json[results[i]][o]["meaning"]) + "</span>";
|
||||||
|
} else if (json[results[i]][o]["translation"] != undefined) {
|
||||||
|
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'>"+e+"</span> - "+json[results[i]][o]["examples"][e];
|
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><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><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.
|
||||||
}
|
}
|
||||||
main.appendChild(result);
|
main.appendChild(result);
|
||||||
}
|
}
|
||||||
|
types = sortObject(types);
|
||||||
|
let header = document.createElement("div");
|
||||||
|
header.classList.add("results-header");
|
||||||
|
//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) {
|
||||||
|
if (i !== "") { header.innerHTML += "<span class='results-header-count'>" + i + "s - " + types[i] + "</span>"; }
|
||||||
|
}
|
||||||
|
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("span.heonian").onclick = () => {
|
||||||
|
if (!header.classList.contains("fullscreen")) {
|
||||||
|
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), {})
|
||||||
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
|
||||||
|
})
|
||||||
|
);
|
||||||
|
});
|
||||||
164
wordlist.json
@@ -1,164 +0,0 @@
|
|||||||
{
|
|
||||||
"": [
|
|
||||||
{
|
|
||||||
"type": "modifier",
|
|
||||||
"meaning": "In an early stage of development.",
|
|
||||||
"translation": "Young",
|
|
||||||
"antonym": ""
|
|
||||||
}
|
|
||||||
],
|
|
||||||
" ": [
|
|
||||||
{
|
|
||||||
"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",
|
|
||||||
"antonym": ""
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"": [
|
|
||||||
{
|
|
||||||
"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": "noun",
|
|
||||||
"meaning": "snow",
|
|
||||||
"translation": "snow",
|
|
||||||
"notes": "this is where notes go",
|
|
||||||
"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"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||