Add initial files

This commit is contained in:
Nathan McRae
2022-02-28 13:16:41 -08:00
commit 47ccd46ac5
12 changed files with 4721 additions and 0 deletions

File diff suppressed because it is too large Load Diff

After

Width:  |  Height:  |  Size: 27 KiB

View File

@ -0,0 +1,212 @@
<?xml version="1.0" encoding="utf-8"?>
<svg version="1.1" width="836" height="362" viewBox="0 0 836 362"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xml:space="preserve">
<style type="text/css">
circle, line, path{
fill: none;
stroke: #000;
stroke-width: 2.5;
}
circle{
stroke-width: 1.5;
}
text{
font-size: 28px;
font-family: "Bitstream Charter", Charter, serif;
text-anchor: middle;
}
.arrowhead{
fill: #000;
stroke-width: 3.2;
}
.big { stroke-width: 3; font-size: 32px; }
.dot { stroke-dasharray: 2.5, 7.5; }
.dash { stroke-dasharray: 7.5, 7.5; }
.thin { stroke-width: 1; }
.grey { stroke: #808080; }
.tiny { font-size: 20px; }
</style>
<circle r="18" cx="209.1975" cy="96.7551"/>
<circle r="18" cx="626.7500" cy="96.8076"/>
<path class="dot" d="M384.1785583,48.2296791l-157.529892,43.7463417"/>
<path class="dash" d="M451.8214417,48.2296791l157.5299377,43.7463417"/>
<circle r="18" cx="104.8225" cy="156.279"/>
<circle r="18" cx="313.5725" cy="156.279"/>
<circle r="18" cx="522.3225" cy="156.279"/>
<circle r="18" cx="731.0725" cy="156.279"/>
<circle r="18" cx="70.03075" cy="224.2428"/>
<circle r="18" cx="139.614" cy="224.2428"/>
<circle r="18" cx="278.7808" cy="224.2428"/>
<circle r="18" cx="348.364" cy="224.2428"/>
<circle r="18" cx="487.5308" cy="224.2428"/>
<circle r="18" cx="557.114" cy="224.2428"/>
<circle r="18" cx="696.2801" cy="224.2428"/>
<circle r="18" cx="765.864" cy="224.2428"/>
<circle r="18" cx="793.6975" cy="284.211" class="grey"/>
<circle r="18" cx="751.9475" cy="284.211" class="grey"/>
<circle r="18" cx="710.1975" cy="284.211"/>
<circle r="18" cx="668.4475" cy="284.211"/>
<circle r="18" cx="584.9475" cy="284.211"/>
<circle r="18" cx="543.1975" cy="284.211"/>
<circle r="18" cx="501.4475" cy="284.211"/>
<circle r="18" cx="459.6975" cy="284.211"/>
<circle r="18" cx="376.1975" cy="284.211"/>
<circle r="18" cx="334.4475" cy="284.211"/>
<circle r="18" cx="292.6975" cy="284.211" class="grey"/>
<circle r="18" cx="250.9475" cy="284.211"/>
<circle r="18" cx="167.4475" cy="284.211" class="grey"/>
<circle r="18" cx="125.6975" cy="284.211"/>
<circle r="18" cx="83.9475" cy="284.211"/>
<circle r="18" cx="42.1975" cy="284.211"/>
<circle r="10" cx="24.162" cy="344.255" class="thin"/>
<circle r="10" cx="47.35625" cy="344.255" class="thin"/>
<circle r="10" cx="70.55075" cy="344.255" class="thin grey"/>
<circle r="10" cx="93.74525" cy="344.255" class="thin"/>
<circle r="10" cx="116.93975" cy="344.255" class="thin grey"/>
<circle r="10" cx="140.134" cy="344.255" class="thin grey"/>
<circle r="10" cx="163.3285" cy="344.255" class="thin grey"/>
<circle r="10" cx="186.523" cy="344.255" class="thin"/>
<circle r="10" cx="232.912" cy="344.255" class="thin grey"/>
<circle r="10" cx="256.10625" cy="344.255" class="thin grey"/>
<circle r="10" cx="279.30075" cy="344.255" class="thin"/>
<circle r="10" cx="302.49525" cy="344.255" class="thin grey"/>
<circle r="10" cx="325.68975" cy="344.255" class="thin grey"/>
<circle r="10" cx="348.884" cy="344.255" class="thin grey"/>
<circle r="10" cx="372.0785" cy="344.255" class="thin grey"/>
<circle r="10" cx="395.273" cy="344.255" class="thin"/>
<circle r="10" cx="441.66175" cy="344.255" class="thin"/>
<circle r="10" cx="464.85625" cy="344.255" class="thin"/>
<circle r="10" cx="488.05075" cy="344.255" class="thin"/>
<circle r="10" cx="511.24525" cy="344.255" class="thin grey"/>
<circle r="10" cx="534.43975" cy="344.255" class="thin grey"/>
<circle r="10" cx="557.63425" cy="344.255" class="thin grey"/>
<circle r="10" cx="580.8285" cy="344.255" class="thin grey"/>
<circle r="10" cx="604.023" cy="344.255" class="thin grey"/>
<circle r="10" cx="650.412" cy="344.255" class="thin"/>
<circle r="10" cx="673.60625" cy="344.255" class="thin grey"/>
<circle r="10" cx="696.80075" cy="344.255" class="thin grey"/>
<circle r="10" cx="719.99525" cy="344.255" class="thin grey"/>
<circle r="10" cx="743.18975" cy="344.255" class="thin"/>
<circle r="10" cx="766.384" cy="344.255" class="thin grey"/>
<circle r="10" cx="789.5785" cy="344.255" class="thin"/>
<circle r="10" cx="812.773" cy="344.255" class="thin"/>
<path class="dot" d="M193.5657043,105.7522507l-73.0063782,41.6347122"/>
<path class="dash" d="M224.9343567,105.7522507l73.0063171,41.6347122"/>
<path class="dot" d="M611.0656738,105.7522507l-73.0063477,41.6347122"/>
<path class="dash" d="M642.4343262,105.7522507l73.0063477,41.6347122"/>
<path class="dash" d="M739.3528442,172.4042816l18.3359375,35.8184357"/>
<path class="dot" d="M722.8971558,172.4042816l-18.3359985,35.8184357"/>
<path class="dash" d="M530.6028442,172.4042816l18.3359375,35.8184357"/>
<path class="dot" d="M514.1471558,172.4042816l-18.335968,35.8184357"/>
<path class="dash" d="M321.8528442,172.4042816l18.335968,35.8184357"/>
<path class="dot" d="M305.3971558,172.4042816l-18.335968,35.8184357"/>
<path class="dash" d="M113.1028519,172.4042816l18.3359756,35.8184357"/>
<path class="dot" d="M96.6471481,172.4042816l-18.3359604,35.8184357"/>
<path class="dot" d="M62.4814339,240.674057l-12.629528,27.2108612"/>
<path class="dash" d="M74.1651917,241.8845062l5.7529526,24.7899933"/>
<path class="dot" d="M135.5848236,241.8845062l-5.7529449,24.7899933"/>
<path class="dash" d="M147.2685852,240.674057l12.6295471,27.2108612"/>
<path class="dot" d="M271.2314453,240.674057l-12.6295166,27.2108612"/>
<path class="dash" d="M282.9151917,241.8845062l5.7529297,24.7899628"/>
<path class="dot" d="M344.3348083,241.8845062l-5.7529602,24.7899933"/>
<path class="dash" d="M356.0185852,240.674057l12.6295166,27.2108612"/>
<path class="dot" d="M479.9814148,240.674057l-12.6295166,27.2108612"/>
<path class="dash" d="M491.6651917,241.8845062l5.7529297,24.7899628"/>
<path class="dot" d="M553.0847778,241.8845062l-5.7529297,24.7899628"/>
<path class="dash" d="M564.7685547,240.674057l12.6295166,27.2108612"/>
<path class="dot" d="M688.7314453,240.674057l-12.6295166,27.2108612"/>
<path class="dash" d="M700.4151611,241.8845062l5.7529907,24.7899933"/>
<path class="dot" d="M761.8348389,241.8845062l-5.7529297,24.7899628"/>
<path class="dash" d="M773.5185547,240.674057l12.6295166,27.2108612"/>
<path class="dash" d="M799.1239624,301.502655l10.3438721,33.1818848"/>
<path class="dot" d="M792.34729,302.2623291l-2.4954834,32.0210571"/>
<path class="grey dash" d="M756.1107788,301.8459167l7.6352539,32.6573486"/>
<path class="dot" d="M749.2194214,302.1032104l-5.0289307,32.2642212"/>
<path class="grey dash" d="M713.0306396,302.1032104l5.0289307,32.2642212"/>
<path class="grey dot" d="M706.1392822,301.8459167l-7.6353149,32.6573486"/>
<path class="grey dash" d="M669.90271,302.2623291l2.4954834,32.0210571"/>
<path class="dot" d="M663.1259766,301.502655l-10.3438721,33.1818848"/>
<path class="grey dash" d="M590.3739624,301.502655l10.3438721,33.1818848"/>
<path class="grey dot" d="M583.59729,302.2623291l-2.4954834,32.0210571"/>
<path class="grey dash" d="M547.3607788,301.8459167l7.6353149,32.6573486"/>
<path class="grey dot" d="M540.4694214,302.1032104l-5.0289307,32.2642212"/>
<path class="grey dash" d="M504.2805786,302.1032104l5.0289001,32.2642212"/>
<path class="dot" d="M497.3892517,301.8459167l-7.6352539,32.6573486"/>
<path class="dash" d="M461.15271,302.2623291l2.4955139,32.0210571"/>
<path class="dot" d="M454.3760071,301.502655l-10.3439026,33.1818848"/>
<path class="dash" d="M381.6239929,301.502655l10.3439026,33.1818848"/>
<path class="grey dot" d="M374.84729,302.2623291l-2.4955139,32.0210571"/>
<path class="grey dash" d="M338.6107483,301.8459167l7.6352844,32.6573486"/>
<path class="grey dot" d="M331.7193909,302.1032104l-5.0289001,32.2641907"/>
<path class="grey dash" d="M295.5306091,302.1032104l5.0289307,32.2642212"/>
<path class="dot" d="M288.6392517,301.8459167l-7.6352844,32.6573486"/>
<path class="grey dash" d="M252.40271,302.2623291l2.4955139,32.0210571"/>
<path class="grey dot" d="M245.6260223,301.502655l-10.3438873,33.1818848"/>
<path class="dash" d="M172.8740082,301.502655l10.3438873,33.1818848"/>
<path class="grey dot" d="M166.0973053,302.2623291l-2.4955139,32.0210571"/>
<path class="grey dash" d="M129.8607635,301.8459167l7.6352844,32.6573486"/>
<path class="grey dot" d="M122.9694138,302.1032104l-5.0289078,32.2642212"/>
<path class="dash" d="M86.7806091,302.1032104l5.0289078,32.2642212"/>
<path class="grey dot" d="M79.8892593,301.8459167l-7.6352768,32.6573486"/>
<path class="dash" d="M43.65271,302.2623291l2.4955025,32.0210571"/>
<path class="dot" d="M36.8760147,301.502655l-10.3438854,33.1818848"/>
<text x="209" y="106">E</text>
<text x="626" y="106">T</text>
<text x="105" y="166">I</text>
<text x="314" y="166">A</text>
<text x="522" y="166">N</text>
<text x="731" y="166">M</text>
<text x="70" y="234">S</text>
<text x="140" y="234">U</text>
<text x="279" y="234">R</text>
<text x="349" y="234">W</text>
<text x="488" y="234">D</text>
<text x="558" y="234">K</text>
<text x="696" y="234">G</text>
<text x="766" y="234">O</text>
<text x="42" y="294">H</text>
<text x="84" y="294">V</text>
<text x="126" y="294">F</text>
<text x="252" y="294">L</text>
<text x="335" y="294">P</text>
<text x="376" y="294">J</text>
<text x="461" y="294">B</text>
<text x="501" y="294">X</text>
<text x="543" y="294">C</text>
<text x="585" y="294">Y</text>
<text x="669" y="294">Z</text>
<text x="710" y="292">Q</text>
<text x="24" y="351" class="tiny">5</text>
<text x="46" y="351" class="tiny">4</text>
<text x="94" y="351" class="tiny">3</text>
<text x="187" y="351" class="tiny">2</text>
<text x="279" y="350" class="tiny">+</text>
<text x="395" y="351" class="tiny">1</text>
<text x="441" y="351" class="tiny">6</text>
<text x="465" y="350" class="tiny">=</text>
<text x="489" y="349" style="font-size: 16px">/</text>
<text x="650" y="351" class="tiny">7</text>
<text x="743" y="351" class="tiny">8</text>
<text x="790" y="351" class="tiny">9</text>
<text x="813" y="351" class="tiny">0</text>
<g>
<circle r="37" cx="418" cy="39" class="big"/>
<text x="417" y="48" class="big">start</text>
</g>
<g>
<g>
<line class="dot big" style="stroke-dasharray: 3.5, 8.5" x1="102.2679901" y1="50.8910065" x2="249.2680054" y2="50.8910065"/>
<path class="arrowhead" d="M120.2640381,50.9020538l12-12l-42,12l42,12L120.2640381,50.9020538z"/>
</g>
<text x="177" y="35" class="big">Dot</text>
</g>
<g>
<g>
<line class="dash big" style="stroke-dasharray: 8.55, 9.55" x1="592.7290039" y1="50.8910065" x2="727.7290039" y2="50.8910065"/>
<path class="arrowhead" d="M715.7359619,50.9020538l-12,12l42-12l-42-12L715.7359619,50.9020538z"/>
</g>
<text x="657" y="35" class="big">Dash</text>
</g>
</svg>

After

Width:  |  Height:  |  Size: 10 KiB

File diff suppressed because it is too large Load Diff

4
morse-code_files/font-awesome.css vendored Normal file

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,98 @@
/* http://jmblog.github.com/color-themes-for-google-code-highlightjs */
code {
background: #fff;
font-size: 13px;
/*font-weight: 100;*/
padding: 4px;
border: none;
box-shadow: inset 0 0 0 1px #E4EBF2;
border-radius: 4px;
overflow: scroll;
font-family: 'Menlo', 'Monaco', Courier, monospace;
}
pre code {
font-size: 13px;
word-wrap: break-word;
-webkit-font-smoothing: subpixel-antialiased;
-moz-osx-font-smoothing: auto;
padding: 0 16px;
display: block;
color: #222;
background: #fff;
border: none;
box-shadow: inset 0 0 0 1px #E4EBF2;
border-radius: 4px;
overflow: auto;
}
/* Tomorrow Comment */
.hljs-comment,
.hljs-quote {
color: #8e908c;
}
/* Tomorrow Red */
.hljs-variable,
.hljs-template-variable,
.hljs-tag,
.hljs-name,
.hljs-selector-id,
.hljs-selector-class,
.hljs-regexp,
.hljs-deletion {
color: #c82829;
}
/* Tomorrow Orange */
.hljs-number,
.hljs-built_in,
.hljs-builtin-name,
.hljs-literal,
.hljs-type,
.hljs-params,
.hljs-meta,
.hljs-link {
color: #f5871f;
}
/* Tomorrow Yellow */
.hljs-attribute {
color: #eab700;
}
/* Tomorrow Green */
.hljs-string,
.hljs-symbol,
.hljs-bullet,
.hljs-addition {
color: #718c00;
}
/* Tomorrow Blue */
.hljs-title,
.hljs-section {
color: #4271ae;
}
/* Tomorrow Purple */
.hljs-keyword,
.hljs-selector-tag {
color: #8959a8;
}
code.hljs {
display: block;
white-space: pre;
overflow-x: auto;
word-wrap: normal;
}
.hljs-emphasis {
font-style: italic;
}
.hljs-strong {
font-weight: bold;
}

File diff suppressed because one or more lines are too long

4
morse-code_files/jquery-2.js vendored Normal file

File diff suppressed because one or more lines are too long

36
morse-code_files/main.js Normal file
View File

@ -0,0 +1,36 @@
// To make images retina, add a class "2x" to the img element
// and add a <image-name>@2x.png image. Assumes jquery is loaded.
function isRetina() {
var mediaQuery = "(-webkit-min-device-pixel-ratio: 1.5),\
(min--moz-device-pixel-ratio: 1.5),\
(-o-min-device-pixel-ratio: 3/2),\
(min-resolution: 1.5dppx)";
if (window.devicePixelRatio > 1)
return true;
if (window.matchMedia && window.matchMedia(mediaQuery).matches)
return true;
return false;
};
function retina() {
if (!isRetina())
return;
$("img.2x").map(function(i, image) {
var path = $(image).attr("src");
path = path.replace(".png", "@2x.png");
path = path.replace(".jpg", "@2x.jpg");
$(image).attr("src", path);
});
};
$(document).ready(retina);

View File

@ -0,0 +1,680 @@
const FREQUENCY = 440;
var DOT_TIME = 300;
var DASH_TIME = DOT_TIME * 3;
var SYMBOL_BREAK = DOT_TIME;
var LETTER_BREAK = DOT_TIME * 3;
var WORD_BREAK = DOT_TIME * 7;
let note_context;
let note_node;
let gain_node;
let audioContextInitialized = false;
async function initializeAudioContext() {
note_context = new AudioContext();
await note_context.resume();
note_node = note_context.createOscillator();
gain_node = note_context.createGain();
note_node.frequency.value = FREQUENCY.toFixed(2);
gain_node.gain.value = 0;
note_node.connect(gain_node);
gain_node.connect(note_context.destination);
note_node.start();
audioContextInitialized = true;
}
function startNotePlaying() {
// Pass a start time of 0 so it starts ramping up immediately.
gain_node.gain.setTargetAtTime(0.1, 0, 0.001)
}
function stopNotePlaying() {
// Pass a start time of 0 so it starts ramping down immediately.
gain_node.gain.setTargetAtTime(0, 0, 0.001)
}
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
// Global strictly increasing play counter to avoid multiple replays at the same time.
var playCounter = 0;
async function playDash(currentPlayCounter) {
if (currentPlayCounter != playCounter) { return; }
startNotePlaying();
await sleep(DASH_TIME);
stopNotePlaying();
}
async function playDot(currentPlayCounter) {
if (currentPlayCounter != playCounter) { return; }
startNotePlaying();
await sleep(DOT_TIME);
stopNotePlaying();
}
/**
* message is something like '---'
*/
async function playLetter(letter, currentPlayCounter) {
// console.log('playSentence with', playCounter, currentPlayCounter);
if (!audioContextInitialized) {
initializeAudioContext();
}
// console.log('playing', letter);
for (let i = 0; i < letter.length; i++) {
if (currentPlayCounter != playCounter) { return; }
if (letter[i] == '-') {
await playDash(currentPlayCounter);
} else if (letter[i] == '.') {
await playDot(currentPlayCounter);
}
await sleep(SYMBOL_BREAK);
}
}
// Word is an array of letters, like ['.', '.-', '-']
async function playWord(word, currentPlayCounter) {
// console.log('playSentence with', playCounter, currentPlayCounter);
for (let i = 0; i < word.length; i++) {
if (currentPlayCounter != playCounter) { return; }
await playLetter(word[i], currentPlayCounter);
await sleep(LETTER_BREAK);
}
}
// Sentence is an array of words.
// Ex. "dog is good" -> [['-..', '---', '--.'], ['..', '...'], ['--.', '---', '---', '-..']]
async function playSentence(sentence, currentPlayCounter) {
// console.log('playSentence with', playCounter, currentPlayCounter);
if (currentPlayCounter != playCounter) { return; }
// Slight pause before it starts
// console.log('playSentence with', playCounter, currentPlayCounter);
await sleep(LETTER_BREAK);
// console.log('playSentence with', playCounter, currentPlayCounter);
for (let i = 0; i < sentence.length; i++) {
if (currentPlayCounter != playCounter) { return; }
await playWord(sentence[i], currentPlayCounter);
await sleep(WORD_BREAK);
}
}
// asciiChar is something like 'd'
// Assumes [a-z0-9]
function convertAsciiCharToMorse(asciiChar) {
return MORSE_MAP[asciiChar];
}
// asciiWord is something like 'dog'
// Assumes [a-z0-9]
function convertAsciiWordToMorse(asciiWord) {
return asciiWord.split('').map(convertAsciiCharToMorse);
}
// asciiSentence is something like 'dog is good'
// Assumes words are separated by spaces.
function convertAsciiSentenceToMorse(asciiSentence) {
let splitSentence = asciiSentence.toLowerCase().split(' ');
return splitSentence.map(convertAsciiWordToMorse);
}
function getRandomLetter() {
const randomIndex = Math.floor(Math.random() * 26);
return Object.keys(MORSE_MAP)[randomIndex];
}
function getRandomWord() {
const randomIndex = Math.floor(Math.random() * EASY_WORDS.length);
return EASY_WORDS[randomIndex];
}
function getRandomEasyWords() {
const totalLength = Math.floor(Math.random() * 3) + 2;
let finalSentence = ''
for (let i = 0; i < totalLength; i++) {
finalSentence += EASY_WORDS[Math.floor(Math.random() * EASY_WORDS.length)];
if (i < totalLength - 1) {
finalSentence += ' ';
}
}
return finalSentence;
}
function getRandomWords() {
const totalLength = Math.floor(Math.random() * 4) + 2;
let finalSentence = ''
for (let i = 0; i < totalLength; i++) {
finalSentence += ALL_WORDS[Math.floor(Math.random() * ALL_WORDS.length)];
if (i < totalLength - 1) {
finalSentence += ' ';
}
}
return finalSentence;
}
function updateSpeed() {
const useFarnsworth = document.querySelector('input[name="farnsworth"]:checked').value == 'yes';
// Get the difficulty and update the constants.
const difficulty = document.querySelector('input[name="speed"]:checked').value
if (useFarnsworth) {
DOT_TIME = 60;
DASH_TIME = DOT_TIME * 3;
SYMBOL_BREAK = DOT_TIME;
let letterBreakMultiplier;
switch (difficulty) {
case 'easy':
letterBreakMultiplier = 24;
break;
case 'medium':
letterBreakMultiplier = 12;
break;
case 'hard':
letterBreakMultiplier = 6;
break;
default:
letterBreakMultiplier = 3;
break;
}
LETTER_BREAK = DOT_TIME * letterBreakMultiplier;
WORD_BREAK = DOT_TIME * (letterBreakMultiplier * 2.5);
} else {
switch (difficulty) {
case 'easy':
DOT_TIME = 300;
break;
case 'medium':
DOT_TIME = 200;
break;
case 'hard':
DOT_TIME = 100;
break;
default:
DOT_TIME = 60;
break;
}
DASH_TIME = DOT_TIME * 3;
SYMBOL_BREAK = DOT_TIME;
LETTER_BREAK = DOT_TIME * 3;
WORD_BREAK = DOT_TIME * 7;
}
}
function getTarget() {
let target;
// Get the difficulty and assign a random target.
const difficulty = document.querySelector('input[name="difficulty"]:checked').value
switch (difficulty) {
case 'easy':
target = getRandomLetter();
break;
case 'medium':
target = getRandomWord();
break;
case 'hard':
target = getRandomEasyWords();
break;
default:
target = getRandomWords();
break;
}
return target;
}
var startButton = document.getElementById('playGame');
class ListeningGame {
constructor(wordInput, statusElement, submitButton, resetButton) {
this.stopped = false;
this.messageFound = false;
// DOM elements we'll interact with
this.wordInput = wordInput;
this.statusElement = statusElement;
this.submitButton = submitButton;
this.resetButton = resetButton;
// Bind listeners to `this`.
this.inputListener = this.inputListener.bind(this);
this.submit = this.submit.bind(this);
this.resetButtonListener = this.resetButtonListener.bind(this);
// Initialize listeners
this.wordInput.addEventListener('keyup', this.inputListener);
this.submitButton.addEventListener('click', this.submit);
this.resetButton.addEventListener('click', this.resetButtonListener);
this.wordInput.removeAttribute('disabled');
this.submitButton.removeAttribute('disabled');
this.resetButton.removeAttribute('disabled');
this.target = '';
}
startNewGame() {
// Start listening
if (!audioContextInitialized) {
initializeAudioContext();
}
// Focus on the word input box.
this.wordInput.focus();
// Update speed based on difficulty.
updateSpeed();
// Get a new target
this.target = getTarget();
// console.log('target: ', this.target);
// Reset
this.messageFound = false;
this.wordInput.value = '';
this.statusElement.textContent = 'Waiting...';
this.playTarget();
}
submit(event) {
event.preventDefault();
if (this.messageFound) {
// If we found it already, get a new target and play it.
this.startNewGame();
} else {
const enteredWord = this.wordInput.value;
// console.log('enteredWord: ', enteredWord, 'target: ', this.target);
if (enteredWord.toLowerCase() == this.target) {
// If they got the word, show message and switch event listener.
this.statusElement.textContent = 'Correct! Press enter to play a new round.';
this.messageFound = true;
// Extra playCounter increase to stop any current playing.
this.stopCurrentPlaying();
} else {
// If they didn't, clear the text box and let them try again.
this.statusElement.textContent = 'Not quite! Try again.';
this.replay();
}
}
}
stopCurrentPlaying() {
// console.log('stopping current playing');
// Also increase playCounter to stop any current playing. Wastes a count, but we have the bits to spare.
playCounter += 1;
}
async replay() {
if (this.messageFound) {
this.startNewGame();
return;
}
// Stop the current playing, and play the target again.
this.stopCurrentPlaying();
this.wordInput.focus();
this.playTarget();
}
resetButtonListener(event) {
event.preventDefault();
this.replay();
}
inputListener(event) {
if (this.messageFound) {
this.startNewGame();
return;
}
if (event.key == 'Control') {
this.replay();
} else if (event.key == 'Enter') {
this.submit(event);
}
}
playTarget() {
playCounter += 1;
// console.log('playing with counter', playCounter)
playSentence(convertAsciiSentenceToMorse(this.target), playCounter);
}
stopGame() {
this.stopCurrentPlaying();
this.wordInput.value = '';
this.statusElement.textContent = 'Press Start to begin.';
this.wordInput.removeEventListener('keyup', this.inputListener);
this.submitButton.removeEventListener('click', this.submit);
this.resetButton.removeEventListener('click', this.resetButtonListener);
this.wordInput.setAttribute('disabled', 'disabled');
this.submitButton.setAttribute('disabled', 'disabled');
this.resetButton.setAttribute('disabled', 'disabled');
}
}
var currentGame;
var playListeningGameButton = document.getElementById("playListeningGame");
async function playListeningGame() {
// Check if there's a currentGame already. If there is, stop it!
if (currentGame) {
currentGame.stopGame();
}
const wordInput = document.getElementById('wordInput');
const status = document.getElementById('status');
const submitButton = document.getElementById('submitButton');
const resetButton = document.getElementById('resetButton');
currentGame = new ListeningGame(wordInput, status, submitButton, resetButton);
currentGame.startNewGame();
playListeningGameButton.removeEventListener('click', playListeningGame);
playListeningGameButton.addEventListener('click', stopListeningGame);
playListeningGameButton.textContent = 'Stop';
}
async function stopListeningGame() {
if (currentGame) {
// Stop current game
currentGame.stopGame();
}
playListeningGameButton.removeEventListener('click', stopListeningGame);
playListeningGameButton.addEventListener('click', playListeningGame);
playListeningGameButton.textContent = 'Start';
}
playListeningGameButton.addEventListener('click', playListeningGame);
class InputGame {
constructor(signalButton, startOverButton, targetDisplay, inputDisplay, inputStatus) {
this.signalButton = signalButton;
this.startOverButton = startOverButton;
this.targetDisplay = targetDisplay;
this.inputDisplay = inputDisplay;
this.inputStatus = inputStatus;
this.target = '';
// Stack for keeping track of dots and dashes that make up letter
this.dotAndDashStack = [];
// Stack for keeping track of letters that make up word
this.letterStack = [];
this.lastKeyDownTime = 0;
this.lastKeyUpTime = 0;
this.letterTimeout = null;
this.spaceTimeout = null;
this.matchFound = false;
// Keep track of where the spacebar is to prevent duplicate keydowns when you hold it down.
this.spacebarDown = false;
// Keep track of if the tap key is down or not to prevent weird state issues when restarting game.
// this.keyIsDown = false;
this.documentKeydownListener = this.documentKeydownListener.bind(this);
this.documentKeyupListener = this.documentKeyupListener.bind(this);
this.buttonMousedownListener = this.buttonMousedownListener.bind(this);
this.buttonMouseupListener = this.buttonMouseupListener.bind(this);
this.startOver = this.startOver.bind(this);
this.handleLetterTimeout = this.handleLetterTimeout.bind(this);
this.handleSpaceTimeout = this.handleSpaceTimeout.bind(this);
document.addEventListener('keydown', this.documentKeydownListener);
document.addEventListener('keyup', this.documentKeyupListener);
this.signalButton.addEventListener('mousedown', this.buttonMousedownListener);
this.signalButton.addEventListener('mouseup', this.buttonMouseupListener);
this.signalButton.addEventListener('touchstart', this.buttonMousedownListener);
this.signalButton.addEventListener('touchend', this.buttonMouseupListener);
this.startOverButton.addEventListener('click', this.startOver);
}
startNewGame() {
this.matchFound = false;
this.startOver();
// Update speed based on difficulty.
updateSpeed();
// Get target word
this.target = getTarget();
// console.log('target: ', this.target);
// Update target display with the new target
this.targetDisplay.textContent = 'Target: ' + this.target;
this.inputDisplay.textContent = '';
this.inputStatus.textContent = '';
this.signalButton.removeAttribute('disabled');
this.startOverButton.removeAttribute('disabled');
// Focus on the tap button
this.signalButton.focus();
// Start listening
if (!audioContextInitialized) {
initializeAudioContext();
}
}
keyDown() {
if (this.matchFound) {
// console.log('match found! doing nothing on keydown')
return;
}
startNotePlaying();
const currentTime = Date.now();
// Update the marker for the last signal ending
this.lastKeyDownTime = currentTime;
// Get the total silence time since we last had a signal
const silenceDelta = currentTime - this.lastKeyUpTime;
this.handleSilence(silenceDelta);
// We also want to clear any pending intervals so we don't duplicate them.
clearTimeout(this.letterTimeout);
clearTimeout(this.spaceTimeout);
}
keyUp() {
if (this.matchFound) {
this.startNewGame();
return;
}
// console.log('keyup!');
stopNotePlaying();
const currentTime = Date.now();
// Update the marker for the last silence ending
this.lastKeyUpTime = currentTime;
// Get the total signal time since we last had silence
const signalDelta = currentTime - this.lastKeyDownTime;
this.handleSignal(signalDelta);
// TODO: start timer
this.letterTimeout = setTimeout(this.handleLetterTimeout, LETTER_BREAK);
this.spaceTimeout = setTimeout(this.handleSpaceTimeout, WORD_BREAK);
}
handleLetterTimeout() {
this.handleSilence(LETTER_BREAK);
}
handleSpaceTimeout() {
this.handleSilence(WORD_BREAK)
}
handleSignal(signalDelta) {
// console.log('signalDelta: ', signalDelta)
// See if it's a dot or a dash
if (signalDelta < DASH_TIME) {
this.dotAndDashStack.push('.');
} else {
this.dotAndDashStack.push('-');
}
}
handleSilence(silenceDelta) {
// If there's no input yet, don't do anything
if (this.dotAndDashStack.length == 0 && this.letterStack.length == 0) {
return;
}
// console.log('silenceDelta: ', silenceDelta, 'LETTER_BREAK: ', LETTER_BREAK);
// If we have at least a letter break, try to add a new character if we have any dots or dashes
if (silenceDelta >= LETTER_BREAK && this.dotAndDashStack.length != 0) {
// TODO: handle letter being done.
const currentLetterCombo = this.dotAndDashStack.join('');
if (currentLetterCombo in REVERSE_MORSE_MAP) {
this.letterStack.push(REVERSE_MORSE_MAP[currentLetterCombo]);
} else {
// Push a question mark
this.letterStack.push('?');
}
// Clear current stack.
this.dotAndDashStack = [];
}
// If we have more than a word break, we may also want to add a space after doing the above.
// We may want to do this without dots and dashes (e.g. the timeout), but only if the last char
// isn't a space
if (silenceDelta >= WORD_BREAK &&
this.letterStack.length != 0 &&
this.letterStack[this.letterStack.length - 1] != ' ') {
this.letterStack.push(' ');
}
// Update the display.
this.inputDisplay.textContent = this.letterStack.join('');
this.checkForMatch();
}
documentKeydownListener(event) {
event.preventDefault();
// console.log('document keydown');
if (event.key == ' ' && !this.spacebarDown) {
// console.log('sending keydown');
this.spacebarDown = true;
this.keyDown();
} else if (event.key == 'Control') {
this.startOver();
}
}
documentKeyupListener(event) {
event.preventDefault();
if (this.matchFound) {
this.spacebarDown = false;
this.startNewGame();
return;
}
// console.log('document keyup');
// console.log(this);
if (event.key == ' ') {
this.spacebarDown = false;
this.keyUp();
}
}
buttonMousedownListener(event) {
event.preventDefault();
// console.log('button mousedown');
// console.log(this);
this.keyDown();
}
buttonMouseupListener(event) {
event.preventDefault();
// console.log('button mouseup');
// console.log(this);
this.keyUp();
}
startOver(event) {
if (event) {
event.preventDefault();
}
if (this.matchFound) {
this.startNewGame();
return;
}
this.inputDisplay.textContent = '';
this.inputStatus.textContent = '';
this.dotAndDashStack = [];
this.letterStack = [];
this.lastKeyDownTime = 0;
this.lastKeyUpTime = 0;
clearTimeout(this.letterTimeout);
clearTimeout(this.spaceTimeout);
}
checkForMatch() {
// console.log('checking for match');
// console.log('target: \'' + this.target + '\'');
// console.log('this.letterStack.join(\'\'): \'' + this.letterStack.join('') + '\'');
// console.log(this.letterStack.join('') == this.target);
if (this.letterStack.join('') == this.target) {
// console.log('match!');
// Clear intervals
clearTimeout(this.letterTimeout);
clearTimeout(this.spaceTimeout);
// Show message
this.inputStatus.textContent = 'You got it! Press any key or click either button to start a new round.';
this.matchFound = true;
}
}
stopGame() {
this.startOver();
this.targetDisplay.textContent = 'Press Start to begin.';
this.inputStatus.textContent = '';
document.removeEventListener('keydown', this.documentKeydownListener);
document.removeEventListener('keyup', this.documentKeyupListener);
this.signalButton.removeEventListener('mousedown', this.buttonMousedownListener);
this.signalButton.removeEventListener('mouseup', this.buttonMouseupListener);
this.signalButton.removeEventListener('touchstart', this.buttonMousedownListener);
this.signalButton.removeEventListener('touchend', this.buttonMouseupListener);
this.startOverButton.removeEventListener('click', this.startOver);
this.signalButton.setAttribute('disabled', 'disabled');
this.startOverButton.setAttribute('disabled', 'disabled');
}
}
var playInputGameButton = document.getElementById("playInputGame");
async function playInputGame() {
// TODO: check if there's a currentGame already. If there is, stop it!
if (currentGame) {
currentGame.stopGame();
}
const signalButton = document.getElementById('signalButton');
const startOverButton = document.getElementById('startOverButton');
const targetDisplay = document.getElementById('targetDisplay');
const inputDisplay = document.getElementById('inputDisplay');
const inputStatus = document.getElementById('inputStatus');
currentGame = new InputGame(signalButton, startOverButton, targetDisplay, inputDisplay, inputStatus);
currentGame.startNewGame();
playInputGameButton.removeEventListener('click', playInputGame);
playInputGameButton.addEventListener('click', stopInputGame);
playInputGameButton.textContent = 'Stop';
}
async function stopInputGame() {
if (currentGame) {
// Stop current game
currentGame.stopGame();
}
playInputGameButton.removeEventListener('click', stopInputGame);
playInputGameButton.addEventListener('click', playInputGame);
playInputGameButton.textContent = 'Start';
}
playInputGameButton.addEventListener('click', playInputGame);
// For iOS, you need a touch event before you can play audio!
var initializeAudioOnTouch = function() {
if (!audioContextInitialized) {
initializeAudioContext();
}
document.removeEventListener('touchend', initializeAudioOnTouch);
}
document.addEventListener('touchend', initializeAudioOnTouch);

935
morse-code_files/style.css Normal file
View File

@ -0,0 +1,935 @@
/* Reset */
/* Removed sub from this so that subscript and superscript still do what they should */
html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, big, cite, code, del, dfn, em, img, ins, kbd, q, s, samp, small, strike, strong, tt, var, b, u, i, center, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td, article, aside, canvas, details, embed, figure, figcaption, footer, header, hgroup, menu, nav, output, ruby, section, summary, time, mark, audio, video {
border: 0;
font-size: 100%;
font: inherit;
vertical-align: baseline;
margin: 0;
padding: 0
}
article, aside, details, figcaption, figure, footer, header, hgroup, menu, nav, section {
display: block
}
body {
line-height: 1
}
blockquote, q {
quotes: none
}
blockquote:before, blockquote:after, q:before, q:after {
content: none
}
table {
border-collapse: collapse;
border-spacing: 0
}
*, *:before, *:after {
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
box-sizing: border-box;
}
/* Clearfix */
.clearfix:after {
content: "";
display: table;
clear: both;
}
.hidden {
display: none;
}
/* Icons */
@font-face {
font-family: 'icons';
src: url('../fonts/icons.eot');
src: url('../fonts/icons.eot#iefix') format('embedded-opentype'), url('../fonts/icons.woff') format('woff'), url('../fonts/icons.ttf') format('truetype'), url('../fonts/icons.svg#icons') format('svg');
font-weight: normal;
font-style: normal;
}
[class^="icon-"]:before, [class*=" icon-"]:before {
font-family: "icons";
font-style: normal;
font-weight: normal;
speak: none;
display: inline-block;
text-decoration: inherit;
text-align: center;
font-variant: normal;
text-transform: none;
line-height: 1em;
}
.icon-facebook:before {
content: '\e802';
}
.icon-facebook-squared:before {
content: '\e800';
}
.icon-twitter:before {
content: '\e801';
}
.icon-twitter-1:before {
content: '\e804';
}
.icon-facebook-circled:before {
content: '\e805';
}
.icon-twitter-circled:before {
content: '\e806';
}
.icon-facebook-rect:before {
content: '\e803';
}
/* Spacing */
.post h1, h3, h4, h5, p, pre {
margin-bottom: 20px;
}
/* We don't want sublists to have additional margins. Looks bad when unnested */
#post-body ul, #post-list li, #post-body ol {
margin-bottom: 0px;
}
/* Base */
html, body {
height: 100%;
}
body {
font: 16px/1 "Helvetica Neue", Helvetica, Arial, sans-serif;
color: #222;
-webkit-font-smoothing: antialiased;
text-rendering: optimizeLegibility;
}
h1 {
font-size: 30px;
letter-spacing: -1px;
color: #222;
font-weight: bold;
}
h2 {
font: italic 19px/1.3em Georgia, serif;
color: #222;
}
.profile #wrapper {
padding: 60px 40px 0px;
max-width: 800px;
margin: 0 auto;
}
.profile #header {
margin-bottom: 20px;
text-align: center;
position: relative;
}
.profile #avatar {
display: inline-block;
width: 140px;
height: 140px;
margin-bottom: 20px;
}
.profile h1 {
font-weight: 400;
letter-spacing: 0px;
font-size: 20px;
color: #222;
}
.profile h2 {
font-size: 20px;
font-weight: 300;
color: #222;
margin-top: 10px;
font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
font-style: normal;
}
nav.main-nav {
padding: 20px 20px 0;
background: #fff;
background: rgba(255, 255, 255, .90);
margin: 0 auto;
text-align: right;
z-index: 100;
}
nav.main-nav a {
top: 8px;
right: 6px;
padding: 8px 12px;
color: #5badf0;
font-size: 16px;
line-height: 1.35;
border-radius: 3px;
}
nav.main-nav a.cta {
background: #5badf0;
color: #fff;
margin-left: 12px;
}
@media (max-width: 700px) {
nav.main-nav {
padding: 20px 10px 0 0;
background: #fff;
background: rgba(255, 255, 255, .90);
margin: 0 auto;
text-align: right;
z-index: 100;
}
nav.main-nav a {
top: 8px;
right: 6px;
padding: 8px 8px;
color: #5badf0;
line-height: 1.35;
border-radius: 3px;
}
}
@media (max-width: 324px) {
nav.main-nav a.cta {
display: none;
}
}
#wrapper {
max-width: 800px;
margin: 0 auto;
padding: 60px 40px 100px 40px;
}
#wrapper.home {
max-width: 800px;
margin: 0 auto;
padding: 0px 40px 20px 40px;
}
.home #avatar {
float: right;
width: 40px;
height: 40px;
border-radius: 50%;
}
/* Typography */
/*Accent color*/
a, #title, #post-list a:hover, #title:hover {
text-decoration: none;
color: #5badf0;
color: #5694f1;
}
p a {
color: #5694f1;
}
/*Transitions*/
a, #post-nav a, #post-list a {
-webkit-transition: all 0.15s ease;
-moz-transition: all 0.15s ease;
-ms-transition: all 0.15s ease;
-o-transition: all 0.15s ease;
transition: all 0.15s ease;
}
ul {
margin: 0;
padding: 0;
padding-left: 1em;
}
/*
Remove this so that lists are normal?
See the "reading this in the future" footnotes
*/
/* li {
list-style-position: inside;
} */
ul>li {
list-style-type: circle;
}
/* Line Height */
#post-body, p {
line-height: 1.7;
}
#post-body p > a {
word-break: break-word;
white-space: pre-wrap;
}
b, strong {
font-weight: 500;
color: #1E2025;
}
em, i {
font-style: italic;
}
#title {
display: inline-block;
line-height: 100%;
font-weight: 500;
font-size: 19px;
margin: 0;
padding-bottom: 20px;
}
.description {
float: right;
font: italic 14px/1.4em Georgia, serif;
color: #333;
}
.home h1 {
font-size: 30px;
letter-spacing: -1px;
color: #222;
font-weight: bold;
}
.home h2 {
font: italic 19px/1.3em Georgia, serif;
color: #222;
}
.post header {
text-align: center;
}
.post h1 {
margin-bottom: 20px;
color: #222;
font: 300 32px/1.4em "Helvetica Neue", Helvetica, Arial, sans-serif;
}
.post h2 {
margin-bottom: 20px;
font: 300 24px/1.5 "Helvetica Neue", Helvetica, Arial, sans-serif;
color: #111;
}
.post h2.headline {
font: normal 13px/1.5em "Helvetica Neue", Helvetica, Arial, sans-serif;
margin: -5px 0 0 0;
color: #333;
font-size: 13px;
letter-spacing: 1px;
display: inline-block;
}
.post h2.headline .tags {
font: normal 13px/1.5em "Helvetica Neue", Helvetica, Arial, sans-serif;
margin: -5px 0 40px 0;
color: #b2b9be;
font-size: 13px;
text-transform: uppercase;
letter-spacing: 2px;
margin-top: 5px;
display: block;
}
#post-list h2 {
font: normal 17px/1.5em "Helvetica Neue", Helvetica, Arial, sans-serif;
color: #333;
margin-top: 2px;
}
h3, h4, h5 {
color: #333;
}
h3 {
font-size: 20px;
font-weight: 400;
}
h4 {
font-size: 16px;
font-weight: bold;
}
h5 {
font-size: 15px;
font-weight: bold;
}
h6 {
font-size: 13px;
font-weight: bold;
color: #222;
margin-bottom: 6px;
}
p.small {
color: #222;
font-size: 14px;
line-height: 1.5;
display: block;
text-align: center;
margin-top: 20px;
}
blockquote {
padding-left: 15px;
border-left: 3px solid #eee;
}
hr {
display: block;
border: none;
height: 1px;
margin: 40px auto;
background: #eee;
}
table {
width: 100%;
margin: 40px 0;
border-collapse: collapse;
font-size: 13px;
line-height: 1.5em;
}
th, td {
text-align: left;
padding-right: 20px;
vertical-align: top;
}
table td, td {
border-spacing: none;
border-style: solid;
padding: 10px 15px;
border-width: 1px 0 0 0;
}
tr>td {
border-top: 1px solid #eaeaea;
}
tr:nth-child(odd)>td {
background: #fcfcfc;
}
thead th, th {
text-align: left;
padding: 10px 15px;
height: 20px;
font-size: 13px;
font-weight: bold;
color: #444;
border-bottom: 1px solid #dadadc;
cursor: default;
white-space: nowrap;
}
img {
display: block;
max-width: 100%;
margin: 0 auto;
}
video {
display: block;
max-width: 100%;
margin: 0 auto;
}
/* Made with Cactus Badge */
#badge {
position: absolute;
bottom: 8px;
right: 8px;
height: 48px;
width: 48px;
}
/*=========================================
Post List
=========================================== */
#post-list, #archive-list {
padding-left: 0px;
}
#post-list li, #archive-list li {
list-style-type: none;
border: 1px solid #333;
padding: 10px;
margin: 10px 0;
}
#post-list li:last-child {
margin-bottom: 0;
}
#post-list a {
color: #333;
display: block;
font: bold 19px/1.0 "Helvetica Neue", helvetica, Arial, sans-serif;
}
#post-list .dates {
font: 300 17px/1.8 "Helvetica Neue", helvetica, Arial, sans-serif;
color: #222;
}
#post-list-footer {
border-top: 1px solid #eee;
margin-top: 20px;
padding-top: 100px;
}
#archive-link {
display: inline-block;
font-size: 13px;
font-weight: bold;
border-radius: 4px;
padding: 3px 10px 6px;
box-shadow: 0 0 0 1px hsla(207, 83%, 80%, 1);
}
#archive-link:hover {
background: #5694f1;
color: #fff;
box-shadow: 0 0 0 1px #5694f1;
}
#archive-link span {
position: relative;
top: 0;
font-size: 17px;
}
#footer {
margin-top: 100px;
}
/* Post Page */
#header {
}
.post {
margin: auto;
}
#post-meta {
font-size: 13px;
font-weight: bold;
line-height: 1.4;
border-top: 1px solid #eee;
padding-top: 40px;
margin-bottom: 40px;
padding-bottom: 40px;
margin-top: 40px;
color: #444;
border-bottom: 1px solid #eee;
}
#post-meta div span {
color: #333;
font-weight: 500;
display: block;
}
#post-meta div span.dark {
color: #1E2025;
}
#post-meta div {
margin: 0 25px 0 0;
float: left;
}
#sharing {
float: right;
margin: -2px;
}
#sharing a {
font-size: 20px;
font-size: 23px;
margin-left: 1px;
margin-top: 4px;
color: #d4d4d4;
display: inline-block;
vertical-align: middle;
}
#sharing a:hover {
opacity: 0.8;
}
/* Post Navigation */
#post-nav {
text-align: center;
padding-top: 20px;
font-size: 13px;
font-weight: 500;
margin-top: 40px;
}
#post-nav span {
-webkit-transition: all 0.1s linear;
-moz-transition: all 0.1s linear;
-ms-transition: all 0.1s linear;
-o-transition: all 0.1s linear;
transition: all 0.1s linear;
position: relative;
}
#post-nav span.prev {
float: left;
}
#post-nav span.next {
float: right;
}
#post-nav span .arrow {
position: relative;
padding: 1px;
}
#post-nav span.prev:hover .arrow {
left: -4px;
}
#post-nav span.next:hover .arrow {
right: -4px;
}
#post-nav span.prev:hover {
left: -3px;
}
#post-nav span.next:hover {
right: -3px;
}
/* Archive */
h1.archive {
margin-bottom: 0px;
}
h2.month {
width: 100%;
font: bold 13px/1 "Helvetica Neue", helvetica, Arial, sans-serif;
text-transform: uppercase;
margin-top: 40px;
margin-bottom: 10px;
padding-bottom: 10px;
border-bottom: 1px solid #eee;
}
#archive-list li:last-child {
margin-bottom: 0;
}
#archive-list a {
display: block;
font: bold 17px/1.7 "Helvetica Neue", helvetica, Arial, sans-serif;
color: #333;
}
#archive-list .dates {
float: right;
position: relative;
top: 1px;
font: 300 17px/1.7 "Helvetica Neue", helvetica, Arial, sans-serif;
color: #222;
}
#archive-list li a:hover, #archive-list li:hover .dates {
color: #5694f1;
}
#post-meta img.avatar {
height: 36px;
width: 36px;
float: left;
border-radius: 50%;
margin-top: 3px;
margin-right: 20px;
box-shadow: 0 0 0 3px #fff, 0 0 0 4px #eee;
}
#post-list.archive.readmore {
margin-top: 100px;
}
#post-list.archive.readmore h3 {
font: 400 20px "Helvetica Neue", Helvetica, Arial, sans-serif;
margin-bottom: 30px;
}
#post-list.archive.readmore a {
font: 400 16px/1.6 "Helvetica Neue", helvetica, Arial, sans-serif;
color: #5694f1;
}
#post-list.archive.readmore a:hover {
opacity: 0.8;
}
#post-list.archive.readmore .dates {
font: 300 16px/1.6 "Helvetica Neue", helvetica, Arial, sans-serif;
}
#disqus_thread, #ds-thread {
margin-top: 100px;
}
#sharing a.facebook {
background: #4361b3;
}
#sharing a.twitter {
background: #4fafed;
}
#sharing a {
font-size: 20px;
font-size: 13px;
font-weight: bold;
color: #fff;
padding: 6px 10px;
border-radius: 4px;
margin-left: 2px;
}
/* Media Queries */
@media screen and (max-width: 540px) {
#wrapper {
padding: 20px 20px 20px 20px;
}
#header {
margin-bottom: 60px;
}
.post {
margin: 40px 0;
}
#footer {
margin-top: 60px;
}
#post-list, #archive-list {
margin-top: 0;
}
#post-meta {
margin-top: 60px;
}
#title {
font-size: 17px;
}
#post-list .dates {
}
#post-list-footer {
margin-top: 20px;
padding-top: 40px;
}
h1 {
font-size: 26px;
}
.post h2.headline {
font-size: 13px;
}
.post h1 {
font-size: 24px;
}
.post h2 {
font-size: 20px;
}
}
.archive {
margin: 0 0 50px 0;
font-size: 16px;
}
.archive .post-item {
padding: 10px 0px;
overflow-x: hidden;
white-space:nowrap;
}
.archive .post-time {
display: inline-block;
width: 60px;
margin: 0;
color: #222;
}
@media screen and (max-width: 768px) {
.archive .post-time {
margin: 5px 0;
width: auto;
font-size: 13px;
display: block;
}
}
.archive .post-link {
color: #222;
}
.archive .post-item:hover {
color: #5694f1;
transition: 0.3s ease-out;
}
.archive .post-item:hover .post-link {
color: #5694f1;
}
.fa.fa-heart:hover {
color: #ff3356;
transition: 0.7s ease-out;
cursor: pointer;
}
/* CUSTOM ADDITIONS */
#social {
display: flex;
flex-direction: row;
justify-content: center;
}
a.symbol {
color: #222;
font-size: 2rem;
text-decoration: none;
margin-right: 0.3rem;
}
a.symbol:hover {
color: #BCD4DA;
}
/**
* Table of content
*/
#toc {
line-height: 1em;
word-wrap: break-word;
padding: 8px;
padding-left: 16px;
padding-bottom: 14px;
margin: 0 0 25px 0;
display: block;
color: #808080;
background: #fff;
border: none;
box-shadow: inset 0 0 0 1px #E4EBF2;
border-radius: 4px;
overflow: hidden;
}
#TableOfContents {
overflow-x: auto;
word-wrap: normal;
word-break: break-all;
white-space: nowrap;
}
#TableOfContents ul {
list-style-type:none;
margin: 0;
padding: 0 .5em;
}
#TableOfContents ul li {
list-style-type: none;
line-height: 1.7em;
}
#TableOfContents > ul {
padding: 0;
}
#TableOfContents > ul > li > ul {
padding: 0 3em;
}
#TableOfContents a code{
font-family: Menlo, Monaco, Courier;
background-color: #fff;
font-size: 11px;
padding: 2px 3px;
font-weight: 100;
}
/**
* tags page
*/
#wrapper.tags {
padding: 0px 40px 20px 40px;
}
.page-tags {
text-align: center;
}
.page-tags .tags {
font: "Helvetica Neue", Helvetica, Arial, sans-serif;
margin: 10px 15px;
text-transform: uppercase;
letter-spacing: 1px;
display: inline-block;
}
.page-tags .tags a {
color: #222;
}
.page-tags .tags:hover a {
color: #5694f1;
}

View File

@ -0,0 +1,60 @@
.game-container {
padding: 10px;
border-radius: 36px;
box-shadow: 0px 11px 20px 4px #aaa;
}
#wordInput {
text-align: center;
}
.start-button {
width: 100px;
height: 40px;
border-radius: 10px;
margin: 10px;
font-size: 20px;
}
.interaction-button {
width: 100px;
height: 100px;
border-radius: 100%;
margin: 10px;
font-size: 20px;
}
.game-container {
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
}
.input {
font-size: 20px;
}
.display-message {
font-size: 20px;
text-align: center;
min-height: 1.7em;
}
.morse-input {
white-space: pre-wrap;
border-bottom: 1px solid #aaa;
border-radius: 4px;
min-height: calc(1.7em + 1px);
}
.button-container {
display: flex;
width: 100%;
justify-content: space-evenly;
}
#speed-table {
max-width: 100%;
overflow: scroll;
}