diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index fff0cab3e..fd9eaf1b2 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -1,46 +1,52 @@ --- name: Bug report about: Create a report to help us improve -title: '' +title: "" labels: bug -assignees: '' - +assignees: "" --- -**Did you make sure to clear cache before opening an issue?** -Sometimes your browser has old files cached and the bug you are experiencing might be already fixed, or a side effect of a new update. If you've already tried that, please delete this section. If you don't know how to do that, this website should help: https://clear-my-cache.com/ - + **Describe the bug** -A clear and concise description of what the bug is. + **Did it happen in incognito mode?** -Sometimes things work in incognito mode, which allows me to further track down the issue. + + **To Reproduce** -Steps to reproduce the behavior: + + + 1. Go to '...' 2. Click on '....' 3. Scroll down to '....' 4. See error **Expected behavior** -A clear and concise description of what you expected to happen. + + **Screenshots** -If applicable, add screenshots to help explain your problem. -**Desktop (please complete the following information):** - - OS: [e.g. iOS] - - Browser [e.g. chrome, safari] - - Version [e.g. 22] + -**Smartphone (please complete the following information):** - - Device: [e.g. iPhone6] - - OS: [e.g. iOS8.1] - - Browser [e.g. stock browser, safari] - - Version [e.g. 22] +**Desktop:** + +- OS: [] +- Browser [] +- Version [] + +**Smartphone:** + +- Device: [] +- OS: [] +- Browser [] +- Version [] **Additional context** -Add any other context about the problem here. + + diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md index cb6e40ec0..3835ef724 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -1,11 +1,9 @@ --- name: Feature request about: Please use GitHub Discussions https://github.com/Miodec/monkeytype/discussions -title: '' -labels: '' -assignees: '' - +title: "" +labels: "" +assignees: "" --- -Please use GitHub Discussions: -https://github.com/Miodec/monkeytype/discussions +Please do not file an issue for feature requests, use [GitHub discussions (Discussions tab)](https://github.com/Miodec/monkeytype/discussions) diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 1fe9cd7b1..19adc9d92 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -1,4 +1,4 @@ -Adding a language or a theme? Make sure to edit the `_list.json` file as well, otherwise, it will not work! +Adding a language or a theme? Make sure to edit the `_list.json` file and add the `language.json` or `theme.css` as well, otherwise, it will not work! Please reference any issues related to your pull request. diff --git a/README.md b/README.md index c542e778b..11b6cfc9d 100644 --- a/README.md +++ b/README.md @@ -21,6 +21,7 @@ Monkeytype is a minimalistic, customisable typing test, featuring many test mode - different test modes - punctuation mode - themes +- quotes - live wpm - smooth caret - account system @@ -29,29 +30,28 @@ Monkeytype is a minimalistic, customisable typing test, featuring many test mode # Discord bot -Recently, a Discord bot was added to autoassign roles on our server. You can find the code for it over at https://github.com/Miodec/monkey-bot +On the [monkeytype Discord server](https://www.discord.gg/monkeytype), we added a Discord bot to autoassign roles on our server. You can find its code over at https://github.com/Miodec/monkey-bot # Bug report or Feature request -If you encounter a bug, or have a feature request - send me a message on Reddit, [create an issue](https://github.com/Miodec/monkeytype/issues), [create a discussion thread](https://github.com/Miodec/monkeytype/discussions), or [join the Discord server](https://www.discord.gg/monkeytype). +If you encounter a bug, or have a feature request - [send me a message on Reddit](https://reddit.com/user/miodec), [create an issue](https://github.com/Miodec/monkeytype/issues), [create a discussion thread](https://github.com/Miodec/monkeytype/discussions), or [join the Discord server](https://www.discord.gg/monkeytype). # Contribute -Refer to [CONTRIBUTING.md](https://github.com/Miodec/monkeytype/blob/master/CONTRIBUTING.md) +Refer to [CONTRIBUTING.md.](https://github.com/Miodec/monkeytype/blob/master/CONTRIBUTING.md) # Code Of Conduct -Before contributing to this repository please refer to [CODE_OF_CONDUCT.md](https://github.com/Miodec/monkeytype/blob/master/CODE_OF_CONDUCT.md) +Before contributing to this repository please carefully read and understand the [code of conduct.](https://github.com/Miodec/monkeytype/blob/master/CODE_OF_CONDUCT.md) + # Credits -Montydrei for the name suggestion +[Montydrei](https://www.reddit.com/user/montydrei) for the name suggestion. -Everyone who provided valuable feedback on the original reddit post for the prototype of this website +Everyone who provided valuable feedback on the [original reddit post](https://www.reddit.com/r/MechanicalKeyboards/comments/gc6wx3/experimenting_with_a_completely_new_type_of/) for the prototype of this website. -Contributors that have helped with implementing various features, adding themes and more +All the [contributors](https://github.com/Miodec/monkeytype/graphs/contributors) that have helped with implementing various features, adding themes, fixing bugs, and more. # Support If you wish to support further development and feel extra awesome, you can do so [here](https://www.paypal.me/jackbartnik). - - diff --git a/functions/index.js b/functions/index.js index bb0d02bf3..be146432f 100644 --- a/functions/index.js +++ b/functions/index.js @@ -866,8 +866,8 @@ function validateResult(result) { } } - if (result.chartData.wpm !== undefined) { - if (result.chartData.wpm.filter((w) => w > 400).length > 0) return false; + if (result.chartData.raw !== undefined) { + if (result.chartData.raw.filter((w) => w > 350).length > 0) return false; } if (result.wpm > 100 && result.consistency < 10) return false; @@ -1383,7 +1383,7 @@ exports.testCompleted = functions.https.onRequest(async (request, response) => { // .then((user) => { // return user.emailVerified; // }); - emailVerified = true; + // emailVerified = true; // if (obj.funbox === "nospace") { // response.status(200).send({ data: { resultCode: -1 } }); @@ -2307,7 +2307,7 @@ exports.checkLeaderboards = functions.https.onRequest( return; } request = request.body.data; - + function verifyValue(val) { let errCount = 0; if (val === null || val === undefined) { @@ -2333,15 +2333,24 @@ exports.checkLeaderboards = functions.https.onRequest( request.uid } error count ${errCount} - bad input - ${JSON.stringify(request.obj)}` ); - response.status(200).send({ data: { - status: -999, - message: "Bad input", - }}); + response.status(200).send({ + data: { + status: -999, + message: "Bad input", + }, + }); return; } + let emailVerified = await admin + .auth() + .getUser(request.uid) + .then((user) => { + return user.emailVerified; + }); + try { - if (request.emailVerified === false) { + if (emailVerified === false) { response.status(200).send({ data: { needsToVerifyEmail: true, @@ -2454,10 +2463,12 @@ exports.checkLeaderboards = functions.https.onRequest( console.error( `error in transaction checking leaderboards - ${error}` ); - response.status(200).send({ data: { - status: -999, - message: error, - }}); + response.status(200).send({ + data: { + status: -999, + message: error, + }, + }); }); let daily = await db @@ -2532,15 +2543,17 @@ exports.checkLeaderboards = functions.https.onRequest( console.error( `error in transaction checking leaderboards - ${error}` ); - response.status(200).send({ data: { - status: -999, - message: error, - }}); + response.status(200).send({ + data: { + status: -999, + message: error, + }, + }); }); //send discord update let usr = - request.discordId !== undefined ? request.discordId : request.name; + request.discordId != undefined ? request.discordId : request.name; if ( global !== null && @@ -2598,6 +2611,7 @@ exports.checkLeaderboards = functions.https.onRequest( } else { response.status(200).send({ data: { + status: 1, daily: { insertedAt: null, }, @@ -2775,10 +2789,10 @@ exports.scheduledFunctionCrontab = functions.pubsub } }); -async function announceLbUpdate(discordId, pos, lb, wpm, raw, acc) { +async function announceLbUpdate(discordId, pos, lb, wpm, raw, acc, con) { db.collection("bot-commands").add({ command: "sayLbUpdate", - arguments: [discordId, pos, lb, wpm, raw, acc], + arguments: [discordId, pos, lb, wpm, raw, acc, con], executed: false, requestTimestamp: Date.now(), }); diff --git a/src/js/account-controller.js b/src/js/account-controller.js index 4ed197bcb..8dc204c81 100644 --- a/src/js/account-controller.js +++ b/src/js/account-controller.js @@ -298,7 +298,7 @@ firebase.auth().onAuthStateChanged(function (user) { AccountButton.update(); AccountButton.loading(true); Account.getDataAndInit(); - var displayName = user.displayName; + // var displayName = user.displayName; // var email = user.email; // var emailVerified = user.emailVerified; // var photoURL = user.photoURL; @@ -306,7 +306,6 @@ firebase.auth().onAuthStateChanged(function (user) { // var uid = user.uid; // var providerData = user.providerData; $(".pageLogin .preloader").addClass("hidden"); - $("#menu .icon-button.account .text").text(displayName); // showFavouriteThemesAtTheTop(); CommandlineLists.updateThemeCommands(); diff --git a/src/js/account.js b/src/js/account.js index c0f8a0ee4..0a27f3685 100644 --- a/src/js/account.js +++ b/src/js/account.js @@ -23,6 +23,7 @@ export function getDataAndInit() { DB.initSnapshot() .then(async (e) => { let snap = DB.getSnapshot(); + $("#menu .icon-button.account .text").text(snap.name); if (snap === null) { throw "Missing db snapshot. Client likely could not connect to the backend."; } @@ -65,11 +66,11 @@ export function getDataAndInit() { CloudFunctions.removeSmallTests({ uid: user.uid }); } if (!UpdateConfig.changedBeforeDb) { - if (Config.cookieConfig === null) { + if (Config.localStorageConfig === null) { AccountButton.loading(false); UpdateConfig.apply(DB.getSnapshot().config); Settings.update(); - UpdateConfig.saveToCookie(true); + UpdateConfig.saveToLocalStorage(true); TestLogic.restart(false, true); } else if (DB.getSnapshot().config !== undefined) { //loading db config, keep for now @@ -112,8 +113,10 @@ export function getDataAndInit() { AccountButton.loading(false); UpdateConfig.apply(DB.getSnapshot().config); Settings.update(); - UpdateConfig.saveToCookie(true); - TestLogic.restart(false, true); + UpdateConfig.saveToLocalStorage(true); + if ($(".page.pageTest").hasClass("active")) { + TestLogic.restart(false, true); + } } } UpdateConfig.setDbConfigLoaded(true); @@ -135,7 +138,7 @@ export function getDataAndInit() { AccountButton.loading(false); ResultFilters.updateTags(); CommandlineLists.updateTagCommands(); - TagController.loadActiveFromCookie(); + TagController.loadActiveFromLocalStorage(); ResultTagsPopup.updateButtons(); Settings.showAccountSection(); }) @@ -287,6 +290,7 @@ let totalSecondsFiltered = 0; export function update() { function cont() { + console.log("updating account page"); ThemeColors.update(); ChartController.accountHistory.updateColors(); ChartController.accountActivity.updateColors(); diff --git a/src/js/account/result-filters.js b/src/js/account/result-filters.js index ad46511fc..75b94b5d8 100644 --- a/src/js/account/result-filters.js +++ b/src/js/account/result-filters.js @@ -62,7 +62,7 @@ let defaultResultFilters = { }, }; -export let filters; +export let filters = defaultResultFilters; Promise.all([Misc.getLanguageList(), Misc.getFunboxList()]).then((values) => { let languages = values[0]; @@ -73,7 +73,7 @@ Promise.all([Misc.getLanguageList(), Misc.getFunboxList()]).then((values) => { funboxModes.forEach((funbox) => { defaultResultFilters.funbox[funbox.name] = true; }); - filters = defaultResultFilters; + // filters = defaultResultFilters; }); export function getFilters() { @@ -98,19 +98,19 @@ export function getFilter(group, filter) { export function loadTags(tags) { tags.forEach((tag) => { - defaultResultFilters[tag.id] = true; + defaultResultFilters.tags[tag.id] = true; }); } export function save() { - Misc.setCookie("resultFilters", JSON.stringify(filters), 365); + window.localStorage.setItem("resultFilters", JSON.stringify(filters)); } export function load() { // let newTags = $.cookie("activeTags"); try { - let newResultFilters = Misc.getCookie("resultFilters"); - if (newResultFilters !== undefined && newResultFilters !== "") { + let newResultFilters = window.localStorage.getItem("resultFilters"); + if (newResultFilters != undefined && newResultFilters !== "") { filters = JSON.parse(newResultFilters); save(); } else { @@ -118,6 +118,7 @@ export function load() { save(); } } catch { + console.log("error in loading result filters"); filters = defaultResultFilters; save(); } @@ -333,7 +334,7 @@ $( }); } }); - } else { + } else if ($(e.target).hasClass("button")) { if (e.shiftKey) { Object.keys(getGroup(group)).forEach((filter) => { filters[group][filter] = false; diff --git a/src/js/chart-controller.js b/src/js/chart-controller.js index d61846563..6b3e1ef68 100644 --- a/src/js/chart-controller.js +++ b/src/js/chart-controller.js @@ -664,8 +664,8 @@ export function updateColors(chart) { } catch {} try { - chart.options.scales.yAxes[2].ticks.minor.fontColor = ThemeColors.sub; - chart.options.scales.yAxes[2].scaleLabel.fontColor = ThemeColors.sub; + chart.options.scales.yAxes[1].ticks.minor.fontColor = ThemeColors.sub; + chart.options.scales.yAxes[1].scaleLabel.fontColor = ThemeColors.sub; } catch {} try { diff --git a/src/js/commandline-lists.js b/src/js/commandline-lists.js index a4353cbdd..fbd6cc44e 100644 --- a/src/js/commandline-lists.js +++ b/src/js/commandline-lists.js @@ -198,7 +198,7 @@ export function updateTagCommands() { tag.active = false; }); TestUI.updateModesNotice(); - TagController.saveActiveToCookie(); + TagController.saveActiveToLocalStorage(); }, }); @@ -490,6 +490,14 @@ let commandsCaretStyle = { UpdateConfig.setCaretStyle("carrot"); }, }, + { + id: "setCaretStyleBanana", + display: "banana", + visible: false, + exec: () => { + UpdateConfig.setCaretStyle("banana"); + }, + }, ], }; @@ -531,6 +539,22 @@ let commandsPaceCaretStyle = { UpdateConfig.setPaceCaretStyle("underline"); }, }, + { + id: "setPaceCaretStyleCarrot", + display: "carrot", + visible: false, + exec: () => { + UpdateConfig.setPaceCaretStyle("carrot"); + }, + }, + { + id: "setPaceCaretStyleBanana", + display: "banana", + visible: false, + exec: () => { + UpdateConfig.setPaceCaretStyle("banana"); + }, + }, ], }; diff --git a/src/js/config.js b/src/js/config.js index aaf991c38..47038d191 100644 --- a/src/js/config.js +++ b/src/js/config.js @@ -1,5 +1,4 @@ import * as DB from "./db"; -import * as Misc from "./misc"; import * as Sound from "./sound"; import * as TestUI from "./test-ui"; import * as ChartController from "./chart-controller"; @@ -18,12 +17,12 @@ import * as UI from "./ui"; import * as CommandlineLists from "./commandline-lists"; import * as BackgroundFilter from "./custom-background-filter"; -export let cookieConfig = null; +export let localStorageConfig = null; export let dbConfigLoaded = false; export let changedBeforeDb = false; -export function setCookieConfig(val) { - cookieConfig = val; +export function setLocalStorageConfig(val) { + localStorageConfig = val; } export function setDbConfigLoaded(val) { @@ -74,7 +73,6 @@ let defaultConfig = { flipTestColors: false, capsLockBackspace: false, layout: "default", - savedLayout: "default", confidenceMode: "off", indicateTypos: false, timerStyle: "mini", @@ -87,7 +85,7 @@ let defaultConfig = { keymapMode: "off", keymapStyle: "staggered", keymapLegendStyle: "lowercase", - keymapLayout: "qwerty", + keymapLayout: "overrideSync", fontFamily: "Roboto_Mono", smoothLineScroll: false, alwaysShowDecimalPlaces: false, @@ -131,7 +129,7 @@ let config = { ...defaultConfig, }; -export async function saveToCookie(noDbCheck = false) { +export async function saveToLocalStorage(noDbCheck = false) { if (!dbConfigLoaded && !noDbCheck) { setChangedBeforeDb(true); } @@ -143,7 +141,7 @@ export async function saveToCookie(noDbCheck = false) { // }); let save = config; delete save.resultFilters; - Misc.setCookie("config", JSON.stringify(save), 365); + window.localStorage.setItem("config", JSON.stringify(save)); // restartCount = 0; if (!noDbCheck) await DB.saveConfig(save); } @@ -159,7 +157,7 @@ export function setNumbers(numb, nosave) { } else { $("#top .config .numbersMode .text-button").addClass("active"); } - if (!nosave) saveToCookie(); + if (!nosave) saveToLocalStorage(); } export function toggleNumbers() { @@ -172,7 +170,7 @@ export function toggleNumbers() { } else { $("#top .config .numbersMode .text-button").removeClass("active"); } - saveToCookie(); + saveToLocalStorage(); } //punctuation @@ -186,7 +184,7 @@ export function setPunctuation(punc, nosave) { } else { $("#top .config .punctuationMode .text-button").addClass("active"); } - if (!nosave) saveToCookie(); + if (!nosave) saveToLocalStorage(); } export function togglePunctuation() { @@ -199,7 +197,7 @@ export function togglePunctuation() { } else { $("#top .config .punctuationMode .text-button").removeClass("active"); } - saveToCookie(); + saveToLocalStorage(); } export function setMode(mode, nosave) { @@ -273,7 +271,7 @@ export function setMode(mode, nosave) { } // setPaceCaret("off", true); } - if (!nosave) saveToCookie(); + if (!nosave) saveToLocalStorage(); } export function setPlaySoundOnError(val, nosave) { @@ -281,7 +279,7 @@ export function setPlaySoundOnError(val, nosave) { val = false; } config.playSoundOnError = val; - if (!nosave) saveToCookie(); + if (!nosave) saveToLocalStorage(); } export function setPlaySoundOnClick(val, nosave) { @@ -290,7 +288,7 @@ export function setPlaySoundOnClick(val, nosave) { } config.playSoundOnClick = val; if (config.playSoundOnClick !== "off") Sound.init(); - if (!nosave) saveToCookie(); + if (!nosave) saveToLocalStorage(); } export function togglePlaySoundOnError() { @@ -311,14 +309,14 @@ export function setDifficulty(diff, nosave) { config.difficulty = diff; if (!nosave) TestLogic.restart(false, nosave); TestUI.updateModesNotice(); - if (!nosave) saveToCookie(); + if (!nosave) saveToLocalStorage(); } //set fav themes export function setFavThemes(themes, nosave) { config.favThemes = themes; if (!nosave) { - saveToCookie(); + saveToLocalStorage(); } } @@ -330,7 +328,7 @@ export function toggleBlindMode() { } config.blindMode = blind; TestUI.updateModesNotice(); - saveToCookie(); + saveToLocalStorage(); } export function setBlindMode(blind, nosave) { @@ -339,7 +337,7 @@ export function setBlindMode(blind, nosave) { } config.blindMode = blind; TestUI.updateModesNotice(); - if (!nosave) saveToCookie(); + if (!nosave) saveToLocalStorage(); } function updateChartAccuracy() { @@ -367,7 +365,7 @@ export function toggleChartAccuracy() { config.chartAccuracy = true; } updateChartAccuracy(); - saveToCookie(); + saveToLocalStorage(); } export function setChartAccuracy(chartAccuracy, nosave) { @@ -376,7 +374,7 @@ export function setChartAccuracy(chartAccuracy, nosave) { } config.chartAccuracy = chartAccuracy; updateChartAccuracy(); - if (!nosave) saveToCookie(); + if (!nosave) saveToLocalStorage(); } export function toggleChartStyle() { @@ -386,7 +384,7 @@ export function toggleChartStyle() { config.chartStyle = "scatter"; } updateChartStyle(); - saveToCookie(); + saveToLocalStorage(); } export function setChartStyle(chartStyle, nosave) { @@ -395,7 +393,7 @@ export function setChartStyle(chartStyle, nosave) { } config.chartStyle = chartStyle; updateChartStyle(); - if (!nosave) saveToCookie(); + if (!nosave) saveToLocalStorage(); } export function setStopOnError(soe, nosave) { @@ -407,13 +405,13 @@ export function setStopOnError(soe, nosave) { config.confidenceMode = "off"; } TestUI.updateModesNotice(); - if (!nosave) saveToCookie(); + if (!nosave) saveToLocalStorage(); } //alwaysshowdecimal export function toggleAlwaysShowDecimalPlaces() { config.alwaysShowDecimalPlaces = !config.alwaysShowDecimalPlaces; - saveToCookie(); + saveToLocalStorage(); } export function setAlwaysShowDecimalPlaces(val, nosave) { @@ -421,12 +419,12 @@ export function setAlwaysShowDecimalPlaces(val, nosave) { val = false; } config.alwaysShowDecimalPlaces = val; - if (!nosave) saveToCookie(); + if (!nosave) saveToLocalStorage(); } export function toggleAlwaysShowCPM() { config.alwaysShowCPM = !config.alwaysShowCPM; - saveToCookie(); + saveToLocalStorage(); } export function setAlwaysShowCPM(val, nosave) { @@ -434,7 +432,7 @@ export function setAlwaysShowCPM(val, nosave) { val = false; } config.alwaysShowCPM = val; - if (!nosave) saveToCookie(); + if (!nosave) saveToLocalStorage(); } //show out of focus warning @@ -443,7 +441,7 @@ export function toggleShowOutOfFocusWarning() { if (!config.showOutOfFocusWarning) { OutOfFocus.hide(); } - saveToCookie(); + saveToLocalStorage(); } export function setShowOutOfFocusWarning(val, nosave) { @@ -454,13 +452,13 @@ export function setShowOutOfFocusWarning(val, nosave) { if (!config.showOutOfFocusWarning) { OutOfFocus.hide(); } - if (!nosave) saveToCookie(); + if (!nosave) saveToLocalStorage(); } //swap esc and tab export function toggleSwapEscAndTab() { config.swapEscAndTab = !config.swapEscAndTab; - saveToCookie(); + saveToLocalStorage(); UI.updateKeytips(); } @@ -470,7 +468,7 @@ export function setSwapEscAndTab(val, nosave) { } config.swapEscAndTab = val; UI.updateKeytips(); - if (!nosave) saveToCookie(); + if (!nosave) saveToLocalStorage(); } //pace caret @@ -491,7 +489,7 @@ export function setPaceCaret(val, nosave) { config.paceCaret = val; TestUI.updateModesNotice(); PaceCaret.init(nosave); - if (!nosave) saveToCookie(); + if (!nosave) saveToLocalStorage(); } export function setPaceCaretCustomSpeed(val, nosave) { @@ -499,7 +497,7 @@ export function setPaceCaretCustomSpeed(val, nosave) { val = 100; } config.paceCaretCustomSpeed = val; - if (!nosave) saveToCookie(); + if (!nosave) saveToLocalStorage(); } //min wpm @@ -509,7 +507,7 @@ export function setMinWpm(minwpm, nosave) { } config.minWpm = minwpm; TestUI.updateModesNotice(); - if (!nosave) saveToCookie(); + if (!nosave) saveToLocalStorage(); } export function setMinWpmCustomSpeed(val, nosave) { @@ -517,7 +515,7 @@ export function setMinWpmCustomSpeed(val, nosave) { val = 100; } config.minWpmCustomSpeed = val; - if (!nosave) saveToCookie(); + if (!nosave) saveToLocalStorage(); } //min acc @@ -527,7 +525,7 @@ export function setMinAcc(min, nosave) { } config.minAcc = min; TestUI.updateModesNotice(); - if (!nosave) saveToCookie(); + if (!nosave) saveToLocalStorage(); } export function setMinAccCustom(val, nosave) { @@ -535,7 +533,7 @@ export function setMinAccCustom(val, nosave) { val = 90; } config.minAccCustom = val; - if (!nosave) saveToCookie(); + if (!nosave) saveToLocalStorage(); } //always show words history @@ -544,7 +542,7 @@ export function setAlwaysShowWordsHistory(val, nosave) { val = false; } config.alwaysShowWordsHistory = val; - if (!nosave) saveToCookie(); + if (!nosave) saveToLocalStorage(); } export function toggleAlwaysShowWordsHistory() { @@ -553,14 +551,14 @@ export function toggleAlwaysShowWordsHistory() { val = false; } config.alwaysShowWordsHistory = val; - saveToCookie(); + saveToLocalStorage(); } //single list command line export function setSingleListCommandLine(option, nosave) { if (!option) option = "manual"; config.singleListCommandLine = option; - if (!nosave) saveToCookie(); + if (!nosave) saveToLocalStorage(); } //show all lines @@ -571,7 +569,7 @@ export function toggleShowAllLines() { } config.showAllLines = sal; TestLogic.restart(); - saveToCookie(); + saveToLocalStorage(); } export function setShowAllLines(sal, nosave) { @@ -580,7 +578,7 @@ export function setShowAllLines(sal, nosave) { } config.showAllLines = sal; if (!nosave) { - saveToCookie(); + saveToLocalStorage(); TestLogic.restart(); } } @@ -592,7 +590,7 @@ export function toggleQuickEnd() { qe = false; } config.quickEnd = qe; - saveToCookie(); + saveToLocalStorage(); } export function setQuickEnd(qe, nosave) { @@ -600,7 +598,7 @@ export function setQuickEnd(qe, nosave) { qe = false; } config.quickEnd = qe; - if (!nosave) saveToCookie(); + if (!nosave) saveToLocalStorage(); } export function setEnableAds(val, nosave) { @@ -608,7 +606,7 @@ export function setEnableAds(val, nosave) { val = "off"; } config.enableAds = val; - if (!nosave) saveToCookie(); + if (!nosave) saveToLocalStorage(); } export function setRepeatQuotes(val, nosave) { @@ -616,7 +614,7 @@ export function setRepeatQuotes(val, nosave) { val = "off"; } config.repeatQuotes = val; - if (!nosave) saveToCookie(); + if (!nosave) saveToLocalStorage(); } //flip colors @@ -626,13 +624,13 @@ export function setFlipTestColors(flip, nosave) { } config.flipTestColors = flip; TestUI.flipColors(flip); - if (!nosave) saveToCookie(); + if (!nosave) saveToLocalStorage(); } export function toggleFlipTestColors() { config.flipTestColors = !config.flipTestColors; TestUI.flipColors(config.flipTestColors); - saveToCookie(); + saveToLocalStorage(); } //extra color @@ -642,13 +640,13 @@ export function setColorfulMode(extra, nosave) { } config.colorfulMode = extra; TestUI.colorful(extra); - if (!nosave) saveToCookie(); + if (!nosave) saveToLocalStorage(); } export function toggleColorfulMode() { config.colorfulMode = !config.colorfulMode; TestUI.colorful(config.colorfulMode); - saveToCookie(); + saveToLocalStorage(); } //strict space @@ -657,12 +655,12 @@ export function setStrictSpace(val, nosave) { val = false; } config.strictSpace = val; - if (!nosave) saveToCookie(); + if (!nosave) saveToLocalStorage(); } export function toggleStrictSpace() { config.strictSpace = !config.strictSpace; - saveToCookie(); + saveToLocalStorage(); } //opposite shift space @@ -671,7 +669,7 @@ export function setOppositeShiftMode(val, nosave) { val = "off"; } config.oppositeShiftMode = val; - if (!nosave) saveToCookie(); + if (!nosave) saveToLocalStorage(); } export function setPageWidth(val, nosave) { @@ -687,7 +685,7 @@ export function setPageWidth(val, nosave) { if (val !== "100") { $("#centerContent").addClass("wide" + val); } - if (!nosave) saveToCookie(); + if (!nosave) saveToLocalStorage(); } export function setCaretStyle(caretStyle, nosave) { @@ -701,6 +699,7 @@ export function setCaretStyle(caretStyle, nosave) { $("#caret").removeClass("outline"); $("#caret").removeClass("block"); $("#caret").removeClass("carrot"); + $("#caret").removeClass("banana"); if (caretStyle == "off") { $("#caret").addClass("off"); @@ -714,8 +713,10 @@ export function setCaretStyle(caretStyle, nosave) { $("#caret").addClass("underline"); } else if (caretStyle == "carrot") { $("#caret").addClass("carrot"); + } else if (caretStyle == "banana") { + $("#caret").addClass("banana"); } - if (!nosave) saveToCookie(); + if (!nosave) saveToLocalStorage(); } export function setPaceCaretStyle(caretStyle, nosave) { @@ -728,6 +729,8 @@ export function setPaceCaretStyle(caretStyle, nosave) { $("#paceCaret").removeClass("underline"); $("#paceCaret").removeClass("outline"); $("#paceCaret").removeClass("block"); + $("#paceCaret").removeClass("carrot"); + $("#paceCaret").removeClass("banana"); if (caretStyle == "off") { $("#paceCaret").addClass("off"); @@ -739,8 +742,12 @@ export function setPaceCaretStyle(caretStyle, nosave) { $("#paceCaret").addClass("outline"); } else if (caretStyle == "underline") { $("#paceCaret").addClass("underline"); + } else if (caretStyle == "carrot") { + $("#paceCaret").addClass("carrot"); + } else if (caretStyle == "banana") { + $("#paceCaret").addClass("banana"); } - if (!nosave) saveToCookie(); + if (!nosave) saveToLocalStorage(); } export function setShowTimerProgress(timer, nosave) { @@ -753,7 +760,7 @@ export function setShowTimerProgress(timer, nosave) { } else { TimerProgress.hide(); } - if (!nosave) saveToCookie(); + if (!nosave) saveToLocalStorage(); } export function toggleShowTimerProgress() { @@ -763,7 +770,7 @@ export function toggleShowTimerProgress() { } else { TimerProgress.hide(); } - saveToCookie(); + saveToLocalStorage(); } export function setShowLiveWpm(live, nosave) { @@ -776,7 +783,7 @@ export function setShowLiveWpm(live, nosave) { } else { LiveWpm.hide(); } - if (!nosave) saveToCookie(); + if (!nosave) saveToLocalStorage(); } export function toggleShowLiveWpm() { @@ -786,7 +793,7 @@ export function toggleShowLiveWpm() { } else { LiveWpm.hide(); } - saveToCookie(); + saveToLocalStorage(); } export function setShowLiveAcc(live, nosave) { @@ -799,7 +806,7 @@ export function setShowLiveAcc(live, nosave) { } else { LiveAcc.hide(); } - if (!nosave) saveToCookie(); + if (!nosave) saveToLocalStorage(); } export function toggleLiveAcc() { @@ -809,7 +816,7 @@ export function toggleLiveAcc() { } else { LiveAcc.hide(); } - saveToCookie(); + saveToLocalStorage(); } export function setHighlightMode(mode, nosave) { @@ -827,7 +834,7 @@ export function setHighlightMode(mode, nosave) { mode = "letter"; } config.highlightMode = mode; - if (!nosave) saveToCookie(); + if (!nosave) saveToLocalStorage(); } export function setHideExtraLetters(val, nosave) { @@ -835,12 +842,12 @@ export function setHideExtraLetters(val, nosave) { val = false; } config.hideExtraLetters = val; - if (!nosave) saveToCookie(); + if (!nosave) saveToLocalStorage(); } export function toggleHideExtraLetters() { config.hideExtraLetters = !config.hideExtraLetters; - saveToCookie(); + saveToLocalStorage(); } export function setTimerStyle(style, nosave) { @@ -848,7 +855,7 @@ export function setTimerStyle(style, nosave) { style = "mini"; } config.timerStyle = style; - if (!nosave) saveToCookie(); + if (!nosave) saveToLocalStorage(); } export function setTimerColor(color, nosave) { @@ -890,14 +897,14 @@ export function setTimerColor(color, nosave) { $("#miniTimerAndLiveWpm").addClass("timerText"); } - if (!nosave) saveToCookie(); + if (!nosave) saveToLocalStorage(); } export function setTimerOpacity(opacity, nosave) { if (opacity == null || opacity == undefined) { opacity = 0.25; } config.timerOpacity = opacity; - if (!nosave) saveToCookie(); + if (!nosave) saveToLocalStorage(); } //key tips @@ -908,7 +915,7 @@ export function setKeyTips(keyTips, nosave) { } else { $("#bottom .keyTips").addClass("hidden"); } - if (!nosave) saveToCookie(); + if (!nosave) saveToLocalStorage(); } export function toggleKeyTips() { @@ -918,7 +925,7 @@ export function toggleKeyTips() { } else { $("#bottom .keyTips").addClass("hidden"); } - saveToCookie(); + saveToLocalStorage(); } //mode @@ -936,7 +943,7 @@ export function setTimeConfig(time, nosave) { $("#top .config .time .text-button[timeConfig='" + time + "']").addClass( "active" ); - if (!nosave) saveToCookie(); + if (!nosave) saveToLocalStorage(); } //quote length @@ -952,7 +959,12 @@ export function setQuoteLength(len, nosave, multipleMode) { } len = parseInt(len); if (multipleMode) { - if (!config.quoteLength.includes(len)) config.quoteLength.push(len); + if (!config.quoteLength.includes(len)) { + config.quoteLength.push(len); + } else { + if (config.quoteLength.length > 1) + config.quoteLength = config.quoteLength.filter((ql) => ql !== len); + } } else { config.quoteLength = [len]; } @@ -964,7 +976,7 @@ export function setQuoteLength(len, nosave, multipleMode) { "#top .config .quoteLength .text-button[quoteLength='" + ql + "']" ).addClass("active"); }); - if (!nosave) saveToCookie(); + if (!nosave) saveToLocalStorage(); } export function setWordCount(wordCount, nosave) { @@ -981,13 +993,13 @@ export function setWordCount(wordCount, nosave) { $( "#top .config .wordCount .text-button[wordCount='" + wordCount + "']" ).addClass("active"); - if (!nosave) saveToCookie(); + if (!nosave) saveToLocalStorage(); } //caret export function setSmoothCaret(mode, nosave) { config.smoothCaret = mode; - if (!nosave) saveToCookie(); + if (!nosave) saveToLocalStorage(); if (mode) { $("#caret").css("animation-name", "caretFlashSmooth"); } else { @@ -997,7 +1009,7 @@ export function setSmoothCaret(mode, nosave) { export function toggleSmoothCaret() { config.smoothCaret = !config.smoothCaret; - saveToCookie(); + saveToLocalStorage(); if (config.smoothCaret) { $("#caret").css("animation-name", "caretFlashSmooth"); } else { @@ -1008,23 +1020,23 @@ export function toggleSmoothCaret() { //startgraphsatzero export function toggleStartGraphsAtZero() { config.startGraphsAtZero = !config.startGraphsAtZero; - saveToCookie(); + saveToLocalStorage(); } export function setStartGraphsAtZero(mode, nosave) { config.startGraphsAtZero = mode; - if (!nosave) saveToCookie(); + if (!nosave) saveToLocalStorage(); } //linescroll export function setSmoothLineScroll(mode, nosave) { config.smoothLineScroll = mode; - if (!nosave) saveToCookie(); + if (!nosave) saveToLocalStorage(); } export function toggleSmoothLineScroll() { config.smoothLineScroll = !config.smoothLineScroll; - saveToCookie(); + saveToLocalStorage(); } //quick tab @@ -1041,12 +1053,10 @@ export function setQuickTabMode(mode, nosave) { $("#bottom .keyTips").html(`tab - restart test
esc - command line`); } - if (!nosave) saveToCookie(); + if (!nosave) saveToLocalStorage(); } export function toggleQuickTabMode() { - console.log("before change"); - console.log(config.quickTab); config.quickTab = !config.quickTab; if (!config.quickTab) { $("#restartTestButton").removeClass("hidden"); @@ -1059,13 +1069,7 @@ export function toggleQuickTabMode() { $("#bottom .keyTips").html(`tab - restart test
esc - command line`); } - console.log("after change"); - console.log(config.quickTab); - console.log("before save"); - console.log(config.quickTab); - saveToCookie(); - console.log("after save"); - console.log(config.quickTab); + saveToLocalStorage(); } export function previewFontFamily(font) { @@ -1104,7 +1108,7 @@ export function setFontFamily(font, nosave) { '"' + font.replace(/_/g, " ") + '"' ); ChartController.setDefaultFontFamily(font); - if (!nosave) saveToCookie(); + if (!nosave) saveToLocalStorage(); } //freedom @@ -1116,7 +1120,7 @@ export function setFreedomMode(freedom, nosave) { if (config.freedomMode && config.confidenceMode !== "off") { config.confidenceMode = "off"; } - if (!nosave) saveToCookie(); + if (!nosave) saveToLocalStorage(); } export function toggleFreedomMode() { @@ -1124,7 +1128,7 @@ export function toggleFreedomMode() { if (config.freedomMode && config.confidenceMode !== "off") { config.confidenceMode = false; } - saveToCookie(); + saveToLocalStorage(); } export function setConfidenceMode(cm, nosave) { @@ -1138,7 +1142,7 @@ export function setConfidenceMode(cm, nosave) { } TestUI.updateModesNotice(); - if (!nosave) saveToCookie(); + if (!nosave) saveToLocalStorage(); } export function toggleIndicateTypos() { @@ -1147,7 +1151,7 @@ export function toggleIndicateTypos() { it = false; } config.indicateTypos = it; - saveToCookie(); + saveToLocalStorage(); } export function setIndicateTypos(it, nosave) { @@ -1155,7 +1159,7 @@ export function setIndicateTypos(it, nosave) { it = false; } config.indicateTypos = it; - if (!nosave) saveToCookie(); + if (!nosave) saveToLocalStorage(); } export function setCustomTheme(boolean, nosave) { @@ -1165,14 +1169,14 @@ export function setCustomTheme(boolean, nosave) { } else if (!boolean && !nosave) { ThemeController.set(config.theme); } - if (!nosave) saveToCookie(); + if (!nosave) saveToLocalStorage(); } export function setTheme(name, nosave) { config.theme = name; setCustomTheme(false, true, true); ThemeController.set(config.theme); - if (!nosave) saveToCookie(); + if (!nosave) saveToLocalStorage(); } export function setRandomTheme(val, nosave) { @@ -1183,7 +1187,7 @@ export function setRandomTheme(val, nosave) { ThemeController.clearRandom(); } config.randomTheme = val; - if (!nosave) saveToCookie(); + if (!nosave) saveToLocalStorage(); } export function toggleCustomTheme(nosave) { @@ -1194,7 +1198,7 @@ export function toggleCustomTheme(nosave) { setCustomTheme(true); ThemeController.set("custom"); } - if (!nosave) saveToCookie(); + if (!nosave) saveToLocalStorage(); } export function setCustomThemeColors(colors, nosave) { @@ -1203,7 +1207,7 @@ export function setCustomThemeColors(colors, nosave) { // ThemeController.set("custom"); // applyCustomThemeColors(); } - if (!nosave) saveToCookie(); + if (!nosave) saveToLocalStorage(); } export function setLanguage(language, nosave) { @@ -1218,7 +1222,7 @@ export function setLanguage(language, nosave) { } catch (e) { console.log("Analytics unavailable"); } - if (!nosave) saveToCookie(); + if (!nosave) saveToLocalStorage(); } export function toggleMonkey(nosave) { @@ -1228,7 +1232,7 @@ export function toggleMonkey(nosave) { } else { $("#monkey").addClass("hidden"); } - if (!nosave) saveToCookie(); + if (!nosave) saveToLocalStorage(); } export function setMonkey(monkey, nosave) { @@ -1241,7 +1245,7 @@ export function setMonkey(monkey, nosave) { } else { $("#monkey").addClass("hidden"); } - if (!nosave) saveToCookie(); + if (!nosave) saveToLocalStorage(); } export function setCapsLockBackspace(capsLockBackspace, nosave) { @@ -1249,7 +1253,7 @@ export function setCapsLockBackspace(capsLockBackspace, nosave) { capsLockBackspace = false; } config.capsLockBackspace = capsLockBackspace; - if (!nosave) saveToCookie(); + if (!nosave) saveToLocalStorage(); } export function toggleCapsLockBackspace() { @@ -1264,7 +1268,7 @@ export function setKeymapMode(mode, nosave) { $(".keymap-key").attr("style", ""); config.keymapMode = mode; if (!nosave) TestLogic.restart(false, nosave); - if (!nosave) saveToCookie(); + if (!nosave) saveToLocalStorage(); } export function setKeymapLegendStyle(style, nosave) { @@ -1292,7 +1296,7 @@ export function setKeymapLegendStyle(style, nosave) { // Update and save to cookie for persistence $(".keymapLegendStyle").addClass(style); config.keymapLegendStyle = style; - if (!nosave) saveToCookie(); + if (!nosave) saveToLocalStorage(); } export function setKeymapStyle(style, nosave) { @@ -1303,7 +1307,7 @@ export function setKeymapStyle(style, nosave) { $(".keymap").addClass(style); config.keymapStyle = style; - if (!nosave) saveToCookie(); + if (!nosave) saveToLocalStorage(); } export function setKeymapLayout(layout, nosave) { @@ -1312,7 +1316,7 @@ export function setKeymapLayout(layout, nosave) { } config.keymapLayout = layout; Keymap.refreshKeys(layout, setKeymapLayout); - if (!nosave) saveToCookie(); + if (!nosave) saveToLocalStorage(); } export function setLayout(layout, nosave) { @@ -1324,7 +1328,7 @@ export function setLayout(layout, nosave) { if (config.keymapLayout === "overrideSync") { Keymap.refreshKeys(config.keymapLayout, setKeymapLayout); } - if (!nosave) saveToCookie(); + if (!nosave) saveToLocalStorage(); } // export function setSavedLayout(layout, nosave) { @@ -1371,7 +1375,7 @@ export function setFontSize(fontSize, nosave) { $("#caret, #paceCaret").addClass("size3"); $("#miniTimerAndLiveWpm").addClass("size3"); } - if (!nosave) saveToCookie(); + if (!nosave) saveToLocalStorage(); } export function setCustomBackground(value, nosave) { @@ -1390,7 +1394,7 @@ export function setCustomBackground(value, nosave) { (command) => command.id == "changeCustomBackground" )[0].defaultValue = value; ThemeController.applyCustomBackground(); - if (!nosave) saveToCookie(); + if (!nosave) saveToLocalStorage(); } else { Notifications.add("Invalid custom background URL", 0); } @@ -1402,14 +1406,14 @@ export function setCustomBackgroundSize(value, nosave) { } config.customBackgroundSize = value; ThemeController.applyCustomBackgroundSize(); - if (!nosave) saveToCookie(); + if (!nosave) saveToLocalStorage(); } export function setCustomBackgroundFilter(array, nosave) { config.customBackgroundFilter = array; BackgroundFilter.loadConfig(config.customBackgroundFilter); BackgroundFilter.apply(); - if (!nosave) saveToCookie(); + if (!nosave) saveToLocalStorage(); } export function apply(configObj) { @@ -1682,24 +1686,24 @@ export function reset() { ...defaultConfig, }; apply(); - saveToCookie(); + saveToLocalStorage(); } -export function loadFromCookie() { - console.log("loading cookie config"); +export function loadFromLocalStorage() { + console.log("loading localStorage config"); // let newConfig = $.cookie("config"); - let newConfig = Misc.getCookie("config"); - if (newConfig !== undefined && newConfig !== "") { + let newConfig = window.localStorage.getItem("config"); + if (newConfig !== undefined && newConfig !== null && newConfig !== "") { try { newConfig = JSON.parse(newConfig); } catch (e) { newConfig = {}; } apply(newConfig); - console.log("applying cookie config"); - cookieConfig = newConfig; - saveToCookie(true); - console.log("saving cookie config"); + console.log("applying localStorage config"); + localStorageConfig = newConfig; + saveToLocalStorage(true); + console.log("saving localStorage config"); } TestLogic.restart(false, true); loadDone(); diff --git a/src/js/db.js b/src/js/db.js index 55d1be143..4ba0e7ba0 100644 --- a/src/js/db.js +++ b/src/js/db.js @@ -212,23 +212,46 @@ export async function getUserAverageWpm10( function cont() { let wpmSum = 0; let count = 0; + let last10Wpm = 0; + let last10Count = 0; // You have to use every so you can break out of the loop dbSnapshot.results.every((result) => { if ( result.mode == mode && - result.mode2 == mode2 && result.punctuation == punctuation && result.language == language && result.difficulty == difficulty ) { - wpmSum += result.wpm; - count++; - if (count >= 10) { - return false; + // Continue if the mode2 doesn't match unless it's a quote. + if (result.mode2 != mode2 && mode != "quote") { + return true; + } + + // Grab the most recent 10 wpm's for the current mode. + if (last10Count < 10) { + last10Wpm += result.wpm; + last10Count++; + } + + // Check mode2 matches and append, for quotes this is the quote id. + if (result.mode2 == mode2) { + wpmSum += result.wpm; + count++; + if (count >= 10) { + // Break out of every loop since we a maximum of the last 10 wpm results. + return false; + } } } return true; }); + + // Return the last 10 average wpm for quote if the current quote id has never been completed before by the user. + if (count == 0 && mode == "quote") { + return Math.round(last10Wpm / last10Count); + } + + // Return the average wpm of the last 10 completions for the targeted test mode. return Math.round(wpmSum / count); } diff --git a/src/js/exports.js b/src/js/exports.js index 4df468469..91de5b101 100644 --- a/src/js/exports.js +++ b/src/js/exports.js @@ -11,4 +11,4 @@ global.config = Config; // global.addnotif = Notifications.add; global.link = AccountController.linkWithGoogle; -global.filters = ResultFilters.filters; +global.filters = ResultFilters.getFilters(); diff --git a/src/js/input-controller.js b/src/js/input-controller.js index 0e975aa0e..a244a30a6 100644 --- a/src/js/input-controller.js +++ b/src/js/input-controller.js @@ -58,7 +58,10 @@ function handleTab(event) { ) { if ($(".pageTest").hasClass("active")) { if (Config.quickTab) { - if (Config.mode == "zen" && !event.shiftKey) { + if ( + (Config.mode == "zen" && !event.shiftKey) || + (TestLogic.hasTab && !event.shiftKey) + ) { //ignore } else { if (event.shiftKey) ManualRestart.set(); @@ -457,7 +460,9 @@ function handleAlpha(event) { return; if (event.metaKey) return; - let originalEvent = event; + let originalEvent = { + code: event.code, + }; event = LayoutEmulator.updateEvent(event); @@ -752,7 +757,7 @@ $(document).keydown(function (event) { ) { TestUI.focusWords(); wordsFocused = true; - // if (Config.showOutOfFocusWarning) return; + if (Config.showOutOfFocusWarning) return; } //tab diff --git a/src/js/layouts.js b/src/js/layouts.js index 5409fc53f..5d30e2061 100644 --- a/src/js/layouts.js +++ b/src/js/layouts.js @@ -166,12 +166,12 @@ const layouts = { qwpr: { keymapShowTopRow: false, keys: [ - "`~","1!","2@","3#","4$","5%","6^","7&","8*","9(","0)","-_","=+", - "qQ","wW","pP","rR","fF","yY","uU","kK","lL",";:","[{","]}","\\|", - "aA","sS","dD","tT","gG","hH","nN","iI","oO","eE","'\"", - "\\|","zZ","xX","cC","vV","bB","jJ","mM",",<",".>","/?", + "`~", "1!", "2@", "3#", "4$", "5%", "6^", "7&", "8*", "9(", "0)", "-_", "=+", + "qQ", "wW", "pP", "rR", "fF", "yY", "uU", "kK", "lL", ";:", "[{", "]}", "\\|", + "aA", "sS", "dD", "tT", "gG", "hH", "nN", "iI", "oO", "eE", "'\"", + "\\|", "zZ", "xX", "cC", "vV", "bB", "jJ", "mM", ",<", ".>", "/?", " " - ], + ], }, prog_dvorak: { keymapShowTopRow: true, @@ -240,7 +240,7 @@ const layouts = { keys: [ "`~", "1!", "2@", "3#", "4$", "5%", "6^", "7&", "8*", "9(", "0)", "-_", "=+", "wW", "gG", "hH", "mM", "kK", "qQ", "cC", "uU", "jJ", "'\"", "[{", "]}", "\\|", - "rR", "sS", "nN", "tT", "fF", "yY", "aA", "eE", "oO", "iI", ";:", + "rR", "sS", "nN", "tT", "fF", "yY", "aA", "eE", "oO", "iI", ";:", "\\|", "xX", "bB", "lL", "dD", "vV", "zZ", "pP", ",<", ".>", "/?", " " ] @@ -251,7 +251,7 @@ const layouts = { "^~", "1!", "2@", "3#", "4$", "5%", "6&", "7`", "8(", "9)", "0=", "*+", "\\|", "jJ", "gG", "hH", "pP", "fF", "qQ", "vV", "oO", "uU", ";:", "/?", "[{", "]}", "rR", "sS", "nN", "tT", "kK", "yY", "iI", "aA", "eE", "lL", "-_", - "\\|","zZ", "wW", "mM", "dD", "bB", "cC", ",<", "'\"", ".>", "xX", + "\\|", "zZ", "wW", "mM", "dD", "bB", "cC", ",<", "'\"", ".>", "xX", " " ], }, @@ -285,5 +285,15 @@ const layouts = { " " ] }, + JCUKEN: { + keymapShowTopRow: true, + keys: [ + "ёЁ", "1!", "2\"", "3№", "4;", "5%", "6:", "7?", "8*", "9(", "0)", "-_", "=+", + "йЙ", "цЦ", "уУ", "кК", "еЕ", "нН", "гГ", "шШ", "щЩ", "зЗ", "хХ", "ъЪ", "\\/", + "фФ", "ыЫ", "вВ", "аА", "пП", "рР", "оО", "лЛ", "дД", "жЖ", "эЭ", + "\\|", "яЯ", "чЧ", "сС", "мМ", "иИ", "тТ", "ьЬ", "бБ", "юЮ", ".,", + " " + ] + } } export default layouts; diff --git a/src/js/misc.js b/src/js/misc.js index e72a9d9c7..a8e7190c8 100644 --- a/src/js/misc.js +++ b/src/js/misc.js @@ -287,27 +287,28 @@ export async function getLanguage(lang) { } } -export function setCookie(cname, cvalue, exdays) { - var d = new Date(); - d.setTime(d.getTime() + exdays * 24 * 60 * 60 * 1000); - var expires = "expires=" + d.toUTCString(); - document.cookie = cname + "=" + cvalue + ";" + expires + ";path=/"; -} +export function migrateFromCookies() { + ["resultFilters", "config", "merchbannerclosed", "activeTags"].forEach( + function (name) { + let decodedCookie = decodeURIComponent(document.cookie).split(";"); + let value = null; -export function getCookie(cname) { - var name = cname + "="; - var decodedCookie = decodeURIComponent(document.cookie); - var ca = decodedCookie.split(";"); - for (var i = 0; i < ca.length; i++) { - var c = ca[i]; - while (c.charAt(0) == " ") { - c = c.substring(1); + for (var i = 0; i < decodedCookie.length; i++) { + var c = decodedCookie[i]; + while (c.charAt(0) == " ") { + c = c.substring(1); + } + if (c.indexOf(name + "=") == 0) { + value = c.substring(name.length + 1, c.length); + } + } + + if (value) { + window.localStorage.setItem(name, value); + $.removeCookie(name, { path: "/" }); + } } - if (c.indexOf(name) == 0) { - return c.substring(name.length, c.length); - } - } - return ""; + ); } export function sendVerificationEmail() { @@ -648,6 +649,10 @@ export function remove_non_ascii(str) { return str.replace(/[^\x20-\x7E]/g, ""); } +export function escapeRegExp(str) { + return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); +} + export function cleanTypographySymbols(textToClean) { var specials = { "“": '"', // “ “ @@ -715,3 +720,9 @@ export function clearTimeouts(timeouts) { to = null; }); } + +//https://stackoverflow.com/questions/1431094/how-do-i-replace-a-character-at-a-particular-index-in-javascript +export function setCharAt(str, index, chr) { + if (index > str.length - 1) return str; + return str.substring(0, index) + chr + str.substring(index + 1); +} diff --git a/src/js/popups/custom-text-popup.js b/src/js/popups/custom-text-popup.js index ee64e6215..a50d8a17d 100644 --- a/src/js/popups/custom-text-popup.js +++ b/src/js/popups/custom-text-popup.js @@ -70,7 +70,7 @@ $(`${popup} .inputs .check input`).change(() => { $(`${popup} textarea`).keypress((e) => { if (e.code === "Enter" && e.ctrlKey) { - $(`${popup} .button`).click(); + $(`${popup} .button.apply`).click(); } }); diff --git a/src/js/popups/import-settings-popup.js b/src/js/popups/import-settings-popup.js index 2c65f5d04..989bf58c5 100644 --- a/src/js/popups/import-settings-popup.js +++ b/src/js/popups/import-settings-popup.js @@ -27,7 +27,7 @@ function hide() { -1 ); } - UpdateConfig.saveToCookie(); + UpdateConfig.saveToLocalStorage(); Settings.update(); } $("#settingsImportWrapper") diff --git a/src/js/popups/word-filter-popup.js b/src/js/popups/word-filter-popup.js index 7a3c70c0f..79cb583d6 100644 --- a/src/js/popups/word-filter-popup.js +++ b/src/js/popups/word-filter-popup.js @@ -33,12 +33,12 @@ function hide() { async function filter(language) { let filterin = $("#wordFilterPopup .wordIncludeInput").val(); - filterin = filterin.trim(); - filterin = filterin.replace(/ /gi, "|"); + filterin = Misc.escapeRegExp(filterin.trim()); + filterin = filterin.replace(/\s+/gi, "|"); let regincl = new RegExp(filterin, "i"); let filterout = $("#wordFilterPopup .wordExcludeInput").val(); - filterout = filterout.trim(); - filterout = filterout.replace(/ /gi, "|"); + filterout = Misc.escapeRegExp(filterout.trim()); + filterout = filterout.replace(/\s+/gi, "|"); let regexcl = new RegExp(filterout, "i"); let filteredWords = []; let languageWordList = await Misc.getLanguage(language); diff --git a/src/js/ready.js b/src/js/ready.js index da30218ba..bbad0d91b 100644 --- a/src/js/ready.js +++ b/src/js/ready.js @@ -7,7 +7,8 @@ import * as RouteController from "./route-controller"; import * as UI from "./ui"; ManualRestart.set(); -UpdateConfig.loadFromCookie(); +Misc.migrateFromCookies(); +UpdateConfig.loadFromLocalStorage(); Misc.getReleasesFromGitHub(); $(document).ready(() => { @@ -19,7 +20,7 @@ $(document).ready(() => { if (Config.quickTab) { $("#restartTestButton").addClass("hidden"); } - if (!Misc.getCookie("merchbannerclosed")) { + if (!window.localStorage.getItem("merchbannerclosed")) { $(".merchBanner").removeClass("hidden"); } else { $(".merchBanner").remove(); diff --git a/src/js/settings.js b/src/js/settings.js index a5daf775e..4db31652f 100644 --- a/src/js/settings.js +++ b/src/js/settings.js @@ -219,7 +219,7 @@ async function initGroups() { "capsLockBackspace", UpdateConfig.setCapsLockBackspace ); - groups.layout = new SettingsGroup("layout", UpdateConfig.layout); + groups.layout = new SettingsGroup("layout", UpdateConfig.setLayout); groups.language = new SettingsGroup("language", UpdateConfig.setLanguage); groups.fontSize = new SettingsGroup("fontSize", UpdateConfig.setFontSize); groups.pageWidth = new SettingsGroup("pageWidth", UpdateConfig.setPageWidth); diff --git a/src/js/settings/theme-picker.js b/src/js/settings/theme-picker.js index 61669124a..d98aa961c 100644 --- a/src/js/settings/theme-picker.js +++ b/src/js/settings/theme-picker.js @@ -93,7 +93,7 @@ function toggleFavourite(themename) { newlist.push(themename); UpdateConfig.setFavThemes(newlist); } - UpdateConfig.saveToCookie(); + UpdateConfig.saveToLocalStorage(); refreshButtons(); // showFavouriteThemesAtTheTop(); CommandlineLists.updateThemeCommands(); diff --git a/src/js/tag-controller.js b/src/js/tag-controller.js index d0375b1ba..df0951558 100644 --- a/src/js/tag-controller.js +++ b/src/js/tag-controller.js @@ -1,8 +1,7 @@ import * as DB from "./db"; import * as TestUI from "./test-ui"; -import * as Misc from "./misc"; -export function saveActiveToCookie() { +export function saveActiveToLocalStorage() { let tags = []; try { @@ -18,7 +17,7 @@ export function saveActiveToCookie() { // expires: d, // path: "/", // }); - Misc.setCookie("activeTags", JSON.stringify(tags), 365); + window.localStorage.setItem("activeTags", JSON.stringify(tags)); } catch (e) {} } @@ -33,13 +32,13 @@ export function toggle(tagid, nosave = false) { } }); TestUI.updateModesNotice(); - if (!nosave) saveActiveToCookie(); + if (!nosave) saveActiveToLocalStorage(); } -export function loadActiveFromCookie() { +export function loadActiveFromLocalStorage() { // let newTags = $.cookie("activeTags"); - let newTags = Misc.getCookie("activeTags"); - if (newTags !== undefined && newTags !== "") { + let newTags = window.localStorage.getItem("activeTags"); + if (newTags != undefined && newTags !== "") { try { newTags = JSON.parse(newTags); } catch (e) { @@ -48,6 +47,6 @@ export function loadActiveFromCookie() { newTags.forEach((ntag) => { toggle(ntag, true); }); - saveActiveToCookie(); + saveActiveToLocalStorage(); } } diff --git a/src/js/test/pace-caret.js b/src/js/test/pace-caret.js index 6994c92ca..d6e4af60a 100644 --- a/src/js/test/pace-caret.js +++ b/src/js/test/pace-caret.js @@ -28,6 +28,7 @@ function resetCaretPosition() { } export async function init() { + $("#paceCaret").addClass("hidden"); let mode2 = ""; if (Config.mode === "time") { mode2 = Config.time; diff --git a/src/js/test/test-leaderboards.js b/src/js/test/test-leaderboards.js index 0fd77ed3b..f3053f838 100644 --- a/src/js/test/test-leaderboards.js +++ b/src/js/test/test-leaderboards.js @@ -163,7 +163,7 @@ export function check(completedEvent) { CloudFunctions.checkLeaderboards({ uid: completedEvent.uid, lbMemory: DB.getSnapshot().lbMemory, - emailVerified: DB.getSnapshot().emailVerified, + // emailVerified: DB.getSnapshot().emailVerified, name: DB.getSnapshot().name, banned: DB.getSnapshot().banned, verified: DB.getSnapshot().verified, diff --git a/src/js/test/test-logic.js b/src/js/test/test-logic.js index 82401412e..9d7943e92 100644 --- a/src/js/test/test-logic.js +++ b/src/js/test/test-logic.js @@ -190,101 +190,113 @@ export function setRandomQuote(rq) { export function punctuateWord(previousWord, currentWord, index, maxindex) { let word = currentWord; - if ( - (index == 0 || - Misc.getLastChar(previousWord) == "." || - Misc.getLastChar(previousWord) == "?" || - Misc.getLastChar(previousWord) == "!") && - Config.language.split("_")[0] != "code" - ) { - //always capitalise the first word or if there was a dot unless using a code alphabet - word = Misc.capitalizeFirstLetter(word); - } else if ( - (Math.random() < 0.1 && - Misc.getLastChar(previousWord) != "." && + if (Funbox.funboxSaved === "58008") { + if (currentWord.length > 3) { + if (Math.random() < 0.75) { + let special = ["/", "*", "-", "+"][Math.floor(Math.random() * 4)]; + word = Misc.setCharAt(word, Math.floor(word.length / 2), special); + } + } + } else { + if ( + (index == 0 || + Misc.getLastChar(previousWord) == "." || + Misc.getLastChar(previousWord) == "?" || + Misc.getLastChar(previousWord) == "!") && + Config.language.split("_")[0] != "code" + ) { + //always capitalise the first word or if there was a dot unless using a code alphabet + word = Misc.capitalizeFirstLetter(word); + } else if ( + (Math.random() < 0.1 && + Misc.getLastChar(previousWord) != "." && + Misc.getLastChar(previousWord) != "," && + index != maxindex - 2) || + index == maxindex - 1 + ) { + let rand = Math.random(); + if (rand <= 0.8) { + word += "."; + } else if (rand > 0.8 && rand < 0.9) { + if (Config.language.split("_")[0] == "french") { + word = "?"; + } else { + word += "?"; + } + } else { + if (Config.language.split("_")[0] == "french") { + word = "!"; + } else { + word += "!"; + } + } + } else if ( + Math.random() < 0.01 && Misc.getLastChar(previousWord) != "," && - index != maxindex - 2) || - index == maxindex - 1 - ) { - let rand = Math.random(); - if (rand <= 0.8) { - word += "."; - } else if (rand > 0.8 && rand < 0.9) { - if (Config.language.split("_")[0] == "french") { - word = "?"; + Misc.getLastChar(previousWord) != "." && + Config.language.split("_")[0] !== "russian" + ) { + word = `"${word}"`; + } else if ( + Math.random() < 0.011 && + Misc.getLastChar(previousWord) != "," && + Misc.getLastChar(previousWord) != "." && + Config.language.split("_")[0] !== "russian" + ) { + word = `'${word}'`; + } else if ( + Math.random() < 0.012 && + Misc.getLastChar(previousWord) != "," && + Misc.getLastChar(previousWord) != "." + ) { + if (Config.language.split("_")[0] == "code") { + let r = Math.random(); + if (r < 0.25) { + word = `(${word})`; + } else if (r < 0.5) { + word = `{${word}}`; + } else if (r < 0.75) { + word = `[${word}]`; + } else { + word = `<${word}>`; + } } else { - word += "?"; - } - } else { - if (Config.language.split("_")[0] == "french") { - word = "!"; - } else { - word += "!"; - } - } - } else if ( - Math.random() < 0.01 && - Misc.getLastChar(previousWord) != "," && - Misc.getLastChar(previousWord) != "." && - Config.language.split("_")[0] !== "russian" - ) { - word = `"${word}"`; - } else if ( - Math.random() < 0.011 && - Misc.getLastChar(previousWord) != "," && - Misc.getLastChar(previousWord) != "." && - Config.language.split("_")[0] !== "russian" - ) { - word = `'${word}'`; - } else if ( - Math.random() < 0.012 && - Misc.getLastChar(previousWord) != "," && - Misc.getLastChar(previousWord) != "." - ) { - if (Config.language.split("_")[0] == "code") { - let r = Math.random(); - if (r < 0.25) { word = `(${word})`; - } else if (r < 0.5) { - word = `{${word}}`; - } else if (r < 0.75) { - word = `[${word}]`; - } else { - word = `<${word}>`; } - } else { - word = `(${word})`; - } - } else if (Math.random() < 0.013) { - if (Config.language.split("_")[0] == "french") { - word = ":"; - } else { - word += ":"; - } - } else if ( - Math.random() < 0.014 && - Misc.getLastChar(previousWord) != "," && - Misc.getLastChar(previousWord) != "." && - previousWord != "-" - ) { - word = "-"; - } else if ( - Math.random() < 0.015 && - Misc.getLastChar(previousWord) != "," && - Misc.getLastChar(previousWord) != "." && - Misc.getLastChar(previousWord) != ";" - ) { - if (Config.language.split("_")[0] == "french") { - word = ";"; - } else { - word += ";"; - } - } else if (Math.random() < 0.2 && Misc.getLastChar(previousWord) != ",") { - word += ","; - } else if (Math.random() < 0.25 && Config.language.split("_")[0] == "code") { - let specials = ["{", "}", "[", "]", "(", ")", ";", "=", "%", "/"]; + } else if (Math.random() < 0.013) { + if (Config.language.split("_")[0] == "french") { + word = ":"; + } else { + word += ":"; + } + } else if ( + Math.random() < 0.014 && + Misc.getLastChar(previousWord) != "," && + Misc.getLastChar(previousWord) != "." && + previousWord != "-" + ) { + word = "-"; + } else if ( + Math.random() < 0.015 && + Misc.getLastChar(previousWord) != "," && + Misc.getLastChar(previousWord) != "." && + Misc.getLastChar(previousWord) != ";" + ) { + if (Config.language.split("_")[0] == "french") { + word = ";"; + } else { + word += ";"; + } + } else if (Math.random() < 0.2 && Misc.getLastChar(previousWord) != ",") { + word += ","; + } else if ( + Math.random() < 0.25 && + Config.language.split("_")[0] == "code" + ) { + let specials = ["{", "}", "[", "]", "(", ")", ";", "=", "%", "/"]; - word = specials[Math.floor(Math.random() * 10)]; + word = specials[Math.floor(Math.random() * 10)]; + } } return word; } @@ -439,7 +451,7 @@ export async function init() { } } - if (Funbox.active === "rAnDoMcAsE") { + if (Funbox.funboxSaved === "rAnDoMcAsE") { let randomcaseword = ""; for (let i = 0; i < randomWord.length; i++) { if (i % 2 != 0) { @@ -449,17 +461,17 @@ export async function init() { } } randomWord = randomcaseword; - } else if (Funbox.active === "gibberish") { + } else if (Funbox.funboxSaved === "gibberish") { randomWord = Misc.getGibberish(); - } else if (Funbox.active === "58008") { - UpdateConfig.setPunctuation(false, true); + } else if (Funbox.funboxSaved === "58008") { + // UpdateConfig.setPunctuation(false, true); UpdateConfig.setNumbers(false, true); randomWord = Misc.getNumbers(7); - } else if (Funbox.active === "specials") { + } else if (Funbox.funboxSaved === "specials") { UpdateConfig.setPunctuation(false, true); UpdateConfig.setNumbers(false, true); randomWord = Misc.getSpecials(); - } else if (Funbox.active === "ascii") { + } else if (Funbox.funboxSaved === "ascii") { UpdateConfig.setPunctuation(false, true); UpdateConfig.setNumbers(false, true); randomWord = Misc.getASCII(); @@ -469,8 +481,15 @@ export async function init() { randomWord = punctuateWord(previousWord, randomWord, i, wordsBound); } if (Config.numbers) { - if (Math.random() < 0.1) { + if ( + Math.random() < 0.1 && + i !== 0 && + Misc.getLastChar(previousWord) !== "." + ) { randomWord = Misc.getNumbers(4); + if (i == wordsBound - 1) { + randomWord += "."; + } } } @@ -1297,7 +1316,7 @@ export function finish(difficultyFailed = false) { keyDuration: TestStats.keypressTimings.duration.array, consistency: consistency, keyConsistency: keyConsistency, - funbox: Funbox.active, + funbox: Funbox.funboxSaved, bailedOut: bailout, chartData: chartData, customText: cdata, @@ -1644,8 +1663,9 @@ export function finish(difficultyFailed = false) { } if ( Config.mode != "custom" && - Funbox.active !== "gibberish" && - Funbox.active !== "58008" + Funbox.funboxSaved !== "gibberish" && + Funbox.funboxSaved !== "ascii" && + Funbox.funboxSaved !== "58008" ) { testType += "
" + lang; } diff --git a/src/js/ui.js b/src/js/ui.js index dfc1ab06c..85b8bdae3 100644 --- a/src/js/ui.js +++ b/src/js/ui.js @@ -1,6 +1,5 @@ import Config, * as UpdateConfig from "./config"; import * as Notifications from "./notifications"; -import * as Misc from "./misc"; import * as Caret from "./caret"; import * as TestLogic from "./test-logic"; import * as CustomText from "./custom-text"; @@ -163,6 +162,9 @@ export function changePage(page) { SignOutButton.hide(); } else if (page == "account") { if (!firebase.auth().currentUser) { + console.log( + `current user is ${firebase.auth().currentUser}, going back to login` + ); changePage("login"); } else { setPageTransition(true); @@ -231,12 +233,12 @@ window.addEventListener("keydown", function (e) { $(".merchBanner a").click((event) => { $(".merchBanner").remove(); - Misc.setCookie("merchbannerclosed", true, 365); + window.localStorage.setItem("merchbannerclosed", true); }); $(".merchBanner .fas").click((event) => { $(".merchBanner").remove(); - Misc.setCookie("merchbannerclosed", true, 365); + window.localStorage.setItem("merchbannerclosed", true); Notifications.add( "Won't remind you anymore. Thanks for continued support <3", 0, diff --git a/src/sass/media-queries.scss b/src/sass/media-queries.scss new file mode 100644 index 000000000..fd4332c68 --- /dev/null +++ b/src/sass/media-queries.scss @@ -0,0 +1,265 @@ +@media only screen and (max-width: 1050px) { + #centerContent { + .pageSettings .section.themes .buttons, + .pageSettings .section.language .buttons, + .pageSettings .section.layout .buttons, + .pageSettings .section.keymapLayout .buttons, + .pageSettings .section.keymapLegendStyle .buttons, + .pageSettings .section.fontFamily .buttons, + .pageSettings .section.funbox .buttons, + .pageSettings .section.keymapStyle .buttons, + .pageSettings .section.languageGroups .buttons { + grid-template-columns: 1fr 1fr 1fr; + } + + #result .morestats { + gap: 1rem; + grid-template-rows: 1fr 1fr; + } + } + #supportMe { + width: 90vw !important; + .buttons { + .button { + .icon { + font-size: 3rem !important; + line-height: 3rem !important; + } + } + } + } +} + +@media only screen and (max-width: 800px) { + .settingsGroup.quickNav { + display: none; + } + #centerContent { + #top { + grid-template-areas: + "logo config" + "menu config"; + grid-template-columns: auto auto; + .logo { + margin-bottom: 0; + } + } + + #menu { + gap: 0.5rem; + font-size: 0.8rem; + line-height: 0.8rem; + + .icon-button { + padding: 0.25rem; + } + } + } + #bottom { + .leftright { + .left { + gap: 0.25rem 1rem; + display: grid; + grid-template-rows: 1fr 1fr; + grid-auto-flow: column; + } + .right { + display: grid; + grid-template-rows: 1fr 1fr; + gap: 0.25rem 1rem; + } + } + } + + .pageAbout .section .supporters, + .pageAbout .section .contributors { + grid-template-columns: 1fr 1fr 1fr; + } + + .pageSettings .section.customBackgroundFilter { + .groups { + grid-template-columns: 1fr; + } + .saveContainer { + grid-column: -1/-2; + } + } + + #commandLine, + #commandLineInput { + width: 600px !important; + } +} + +@media only screen and (max-width: 650px) { + .pageSettings .section { + grid-template-columns: 1fr; + grid-template-areas: + "title title" + "text text" + "buttons buttons"; + + & > .text { + margin-bottom: 1rem; + } + } + + #result { + .buttons { + grid-template-rows: 1fr 1fr; + #nextTestButton { + grid-column: 1/5; + width: 100%; + text-align: center; + } + } + } + + #supportMe { + width: 80vw !important; + .buttons { + grid-template-columns: none !important; + .button { + grid-template-columns: auto auto; + align-items: center; + .icon { + font-size: 2rem !important; + line-height: 2rem !important; + } + } + } + } + + #centerContent { + .pageSettings .section.themes .buttons, + .pageSettings .section.language .buttons, + .pageSettings .section.layout .buttons, + .pageSettings .section.keymapLayout .buttons, + .pageSettings .section.keymapLegendStyle .buttons, + .pageSettings .section.fontFamily .buttons, + .pageSettings .section.funbox .buttons, + .pageSettings .section.keymapStyle .buttons, + .pageSettings .section.languageGroups .buttons { + grid-template-columns: 1fr 1fr; + } + } +} + +@media only screen and (max-width: 600px) { + .pageAbout .section .supporters, + .pageAbout .section .contributors { + grid-template-columns: 1fr 1fr; + } + #top .logo .bottom { + margin-top: 0; + } + #middle { + #result { + grid-template-areas: + "stats stats" + "chart chart" + "morestats morestats"; + .stats { + grid-template-areas: "wpm acc"; + gap: 4rem; + } + .stats.morestats { + grid-template-rows: 1fr 1fr 1fr; + gap: 1rem; + } + } + } + #commandLine, + #commandLineInput { + width: 500px !important; + } +} + +@media only screen and (max-width: 500px) { + .pageAbout .section .supporters, + .pageAbout .section .contributors { + grid-template-columns: 1fr 1fr; + } + + #top { + align-items: self-end; + .logo { + .bottom { + font-size: 1.75rem; + line-height: 1.75rem; + margin-top: 0; + } + .top { + display: none; + } + } + #menu { + .icon-button { + padding: 0; + } + } + } + #bottom { + .leftright { + .left { + gap: 0.25rem 1rem; + display: grid; + grid-template-rows: 1fr 1fr 1fr; + grid-auto-flow: column; + } + .right { + display: grid; + grid-template-rows: 1fr 1fr 1fr; + gap: 0.25rem 1rem; + } + } + } + #centerContent { + padding: 1rem; + } + #result { + .buttons { + grid-template-rows: 1fr 1fr 1fr; + #nextTestButton { + grid-column: 1/3; + width: 100%; + text-align: center; + } + } + } + #commandLine, + #commandLineInput { + width: 400px !important; + } +} + +@media only screen and (max-width: 400px) { + #top .logo .bottom { + font-size: 1.5rem; + line-height: 1.5rem; + margin-top: 0; + } + + #top .config { + grid-gap: 0.25rem; + .group .buttons { + font-size: 0.65rem; + line-height: 0.65rem; + } + } + + #bottom { + font-size: 0.65rem; + } + + #commandLine, + #commandLineInput { + width: 300px !important; + } +} + +@media (hover: none) and (pointer: coarse) { + #commandLineMobileButton { + display: block; + } +} diff --git a/src/sass/style.scss b/src/sass/style.scss index d96e7113d..915f15b81 100644 --- a/src/sass/style.scss +++ b/src/sass/style.scss @@ -11,6 +11,8 @@ :root { --roundness: 0.25rem; --font: "Roboto Mono"; + // scroll-behavior: smooth; + scroll-padding-top: 2rem; } ::placeholder { @@ -124,7 +126,7 @@ body { padding: 0; min-height: 100vh; font-family: var(--font); - color: var(--main-color); + color: var(--text-color); overflow-x: hidden; background: var(--bg-color); } @@ -273,7 +275,7 @@ a { } a:hover { - color: var(--main-color); + color: var(--text-color); } .merchBanner { @@ -657,6 +659,7 @@ a:hover { padding: 5rem 0; #wordFilterPopup { + color: var(--sub-color); background: var(--bg-color); border-radius: var(--roundness); padding: 2rem; @@ -1211,7 +1214,7 @@ a:hover { input { background: var(--bg-color); padding: 1rem; - color: var(--main-color); + color: var(--text-color); border: none; outline: none; font-size: 1rem; @@ -1228,7 +1231,7 @@ a:hover { } .listTitle { - color: var(--main-color); + color: var(--text-color); padding: 0.5rem 1rem; font-size: 0.75rem; line-height: 0.75rem; @@ -1256,14 +1259,14 @@ a:hover { } &.activeMouse { - color: var(--text-color); - background: var(--sub-color); + color: var(--bg-color); + background: var(--text-color); cursor: pointer; } &.activeKeyboard { color: var(--bg-color); - background: var(--main-color); + background: var(--text-color); } // &:hover { @@ -1456,6 +1459,21 @@ a:hover { } } + &.banana { + background-color: transparent; + background-image: url("../images/banana.png"); + background-size: contain; + background-position: center; + background-repeat: no-repeat; + width: 1rem; + &.size2 { + margin-left: -0.1rem; + } + &.size3 { + margin-left: -0.5rem; + } + } + &.block { width: 0.7em; margin-left: 0.25em; @@ -1544,40 +1562,15 @@ a:hover { width: fit-content; width: -moz-fit-content; - /* transition: 0.25s; */ - .button.discord { - &.discord { - position: relative; - - &::after { - transition: 0.25s; - width: 0.5rem; - height: 0.5rem; - content: ""; - position: absolute; - background: var(--main-color); - border-radius: 1rem; - top: 0.25rem; - right: 0.25rem; - border: 2px solid var(--bg-color); - } - - &.dotHidden::after { - background: transparent; - border-color: transparent; - } - } - } - .icon-button { - .icon { - display: grid; - align-items: center; - justify-items: center; - text-align: center; - width: 1.25rem; - height: 1.25rem; - } + // .icon { + // display: grid; + // align-items: center; + // justify-items: center; + // text-align: center; + // width: 1.25rem; + // height: 1.25rem; + // } .text { font-size: 0.65rem; @@ -1586,10 +1579,10 @@ a:hover { margin-left: 0.25rem; } - &:hover { - cursor: pointer; - color: var(--main-color); - } + // &:hover { + // cursor: pointer; + // color: var(--main-color); + // } } .separator { @@ -1770,38 +1763,44 @@ key { // margin-bottom: 2rem; .keyTips { - margin-bottom: 1rem; + margin-bottom: 2rem; } #supportMeButton { transition: 0.25s; &:hover { - color: var(--main-color); + color: var(--text-color); cursor: pointer; } } .leftright { display: grid; - grid-template-columns: 1fr 1fr; + grid-template-columns: auto auto; gap: 1rem; a { text-decoration: none; } .left { text-align: left; + display: grid; + grid-auto-flow: column; + width: fit-content; + gap: 1rem; } .right { text-align: right; - // display: flex; - // gap: 1rem; + display: grid; + grid-auto-flow: column; + width: fit-content; + justify-self: right; + gap: 1rem; // align-items: center; - // justify-content: flex-end; .current-theme { transition: 0.25s; text-decoration: none; &:hover { - color: var(--main-color); + color: var(--text-color); cursor: pointer; } } @@ -1809,7 +1808,7 @@ key { transition: 0.25s; text-decoration: none; &:hover { - color: var(--main-color); + color: var(--text-color); cursor: pointer; } } @@ -1821,7 +1820,7 @@ key { transition: 0.25s; &:hover { cursor: pointer; - color: var(--main-color); + color: var(--text-color); } } } @@ -2337,6 +2336,7 @@ key { line-height: 1rem; transition: 0.125s; justify-content: center; + user-select: none; .fas { margin-right: 0.5rem; @@ -2579,8 +2579,8 @@ key { #forgotPasswordButton { grid-area: forgotButton; - font-size: 0.5rem; - line-height: 0.5rem; + font-size: 0.75rem; + line-height: 0.75rem; height: fit-content; align-self: center; justify-self: right; @@ -2590,7 +2590,7 @@ key { transition: 0.25s; &:hover { - color: var(--main-color); + color: var(--text-color); } } @@ -2651,14 +2651,29 @@ key { display: grid; gap: 2rem; + .created { + text-align: center; + color: var(--sub-color); + a { + text-decoration: none; + } + } + .section { display: grid; - gap: 0.5rem; + gap: 0.25rem; - .supporters { + .title { + font-size: 2rem; + line-height: 2rem; + color: var(--sub-color); + margin: 1rem 0; + } + + .supporters, + .contributors { display: grid; grid-template-columns: 1fr 1fr 1fr 1fr; - justify-items: center; gap: 0.25rem; color: var(--text-color); } @@ -2696,7 +2711,7 @@ key { transition: 0.25s; &:hover { - color: var(--main-color); + color: var(--text-color); } .fas { @@ -2720,7 +2735,7 @@ key { justify-content: space-between; a { text-decoration: none; - opacity: 0.5; + // opacity: 0.5; &:hover { opacity: 1; } @@ -2742,7 +2757,7 @@ key { background: var(--error-color); color: #eee; &:hover { - background: var(--main-color); + background: var(--text-color); color: var(--bg-color); } } @@ -2849,31 +2864,19 @@ key { } &.discordIntegration { - #unlinkDiscordButton { - margin-top: 0.5rem; - font-size: 0.75rem; - } - - .code { - grid-area: buttons; - justify-content: center; - display: grid; - - .top { - font-size: 1rem; - line-height: 1rem; - color: var(--sub-color); - } - - .bottom { - font-size: 2rem; - line-height: 2rem; - } - } - .info { grid-area: buttons; text-align: center; + color: var(--main-color); + } + + #unlinkDiscordButton { + margin-top: 0.5rem; + font-size: 0.75rem; + color: var(--sub-color); + &:hover { + color: var(--text-color); + } } .howto { @@ -2914,15 +2917,14 @@ key { color: var(--sub-color); &:focus { - background: var(--sub-color); - color: var(--main-color); + color: var(--sub-color); border: none; outline: none; } &:hover { cursor: pointer; - color: var(--main-color); + color: var(--text-color); } } } @@ -2952,7 +2954,7 @@ key { &:hover, &:focus { color: var(--bg-color); - background: var(--main-color); + background: var(--text-color); outline: none; } } @@ -3115,7 +3117,7 @@ key { float: right; &:hover { - color: var(--main-color); + color: var(--text-color); } .fas { @@ -3168,6 +3170,7 @@ key { .preloader { font-size: 2rem; justify-self: center; + color: var(--main-color); } .doublegroup { @@ -3225,7 +3228,7 @@ key { &:hover, &:focus { color: var(--bg-color); - background: var(--main-color); + background: var(--text-color); } } } @@ -3330,7 +3333,7 @@ key { #resultEditTags:hover { cursor: pointer; - color: var(--main-color); + color: var(--text-color); opacity: 1 !important; } } @@ -3448,27 +3451,50 @@ key { margin-right: 0.5rem; } - &.active { - background: var(--main-color); + &:hover { color: var(--bg-color); + background: var(--text-color); + outline: none; } - - &:hover, &:focus { - color: var(--bg-color); - background: var(--main-color); + color: var(--text-color); + background: rgba(0, 0, 0, 0.1); outline: none; } + &.active { + background: var(--main-color); + color: var(--bg-color); + &:hover { + // color: var(--text-color); + background: var(--text-color); + outline: none; + } + &:focus { + color: var(--bg-color); + background: var(--main-color); + outline: none; + } + } + &.disabled { + opacity: 0.5; + cursor: default; &:hover { color: var(--sub-color); - background: var(--bg-color); - cursor: default; + background: rgba(0, 0, 0, 0.1); + outline: none; } - color: var(--sub-color); - background: var(--bg-color); + } + + &.disabled.active { + opacity: 0.5; cursor: default; + &:hover { + color: var(--bg-color); + background: var(--main-color); + outline: none; + } } } @@ -3480,13 +3506,13 @@ key { cursor: pointer; outline: none; - &:hover, - &:focus { + &.active { color: var(--main-color); } - &.active { - color: var(--main-color); + &:hover, + &:focus { + color: var(--text-color); } } @@ -3500,11 +3526,11 @@ key { cursor: pointer; &:hover { - color: var(--main-color); + color: var(--text-color); } &:focus { - background: var(--sub-color); - color: var(--main-color); + // background: var(--sub-color); + color: var(--sub-color); border: none; outline: none; } @@ -3526,7 +3552,7 @@ key { color: var(--sub-color); transition: 0.25s; &:hover { - color: var(--main-color); + color: var(--text-color); } } @@ -3548,184 +3574,6 @@ key { transition: 0.25s; } -@media only screen and (max-width: 1050px) { - #centerContent { - .pageSettings .section.themes .buttons, - .pageSettings .section.language .buttons, - .pageSettings .section.layout .buttons, - .pageSettings .section.keymapLayout .buttons, - .pageSettings .section.keymapLegendStyle .buttons, - .pageSettings .section.fontFamily .buttons, - .pageSettings .section.funbox .buttons, - .pageSettings .section.keymapStyle .buttons { - grid-template-columns: 1fr 1fr 1fr; - } - - #result .morestats { - gap: 1rem; - grid-template-rows: 1fr 1fr; - } - } - #supportMe { - width: 90vw !important; - .buttons { - .button { - .icon { - font-size: 3rem !important; - line-height: 3rem !important; - } - } - } - } -} - -@media only screen and (max-width: 800px) { - #centerContent { - #top { - grid-template-areas: - "logo config" - "menu config"; - .logo { - margin-bottom: 0; - } - } - - #menu { - gap: 0.5rem; - font-size: 0.8rem; - line-height: 0.8rem; - - .icon-button { - padding: 0.25rem; - } - } - } - - .pageSettings .section.customBackgroundFilter { - .groups { - grid-template-columns: 1fr; - } - .saveContainer { - grid-column: -1/-2; - } - } - - #commandLine, - #commandLineInput { - width: 500px !important; - } -} - -@media only screen and (max-width: 650px) { - .pageSettings .section { - grid-template-columns: 1fr; - grid-template-areas: - "title title" - "text text" - "buttons buttons"; - - & > .text { - margin-bottom: 1rem; - } - } - - #result { - .buttons { - grid-template-rows: 1fr 1fr; - #nextTestButton { - grid-column: 1/5; - width: 100%; - text-align: center; - } - } - } - - #supportMe { - width: 80vw !important; - .buttons { - grid-template-columns: none !important; - .button { - grid-template-columns: auto auto; - align-items: center; - .icon { - font-size: 2rem !important; - line-height: 2rem !important; - } - } - } - } - - #commandLine, - #commandLineInput { - width: 400px !important; - } - - #centerContent { - .pageSettings .section.themes .buttons, - .pageSettings .section.language .buttons, - .pageSettings .section.layout .buttons, - .pageSettings .section.keymapLayout .buttons, - .pageSettings .section.keymapLegendStyle .buttons, - .pageSettings .section.fontFamily .buttons, - .pageSettings .section.funbox .buttons, - .pageSettings .section.keymapStyle .buttons { - grid-template-columns: 1fr 1fr; - } - } -} - -@media only screen and (max-width: 600px) { - #middle { - #result { - grid-template-areas: - "stats stats" - "chart chart" - "morestats morestats"; - .stats { - grid-template-areas: "wpm acc"; - gap: 4rem; - } - .stats.morestats { - grid-template-rows: 1fr 1fr 1fr; - gap: 1rem; - } - } - } -} - -@media only screen and (max-width: 500px) { - #top { - .logo { - .bottom { - font-size: 1.75rem; - line-height: 1.75rem; - margin-top: 0.5rem; - } - .top { - display: none; - } - } - #menu { - .icon-button { - padding: 0; - } - } - } - #centerContent { - padding: 1rem; - } - #result { - .buttons { - grid-template-rows: 1fr 1fr 1fr; - #nextTestButton { - grid-column: 1/3; - width: 100%; - text-align: center; - } - } - } -} - .keymap { display: grid; grid-template-rows: 1fr 1fr 1fr; @@ -3912,11 +3760,10 @@ key { // } } -// .matrix { -// display: flex; -// justify-content: left; -// margin-left: 4.51rem; -// } +#nitropay_ad_left, +#nitropay_ad_right { + margin-top: 1rem; +} .keymap { &.matrix { @@ -4030,34 +3877,3 @@ key { } } } - -@media (hover: none) and (pointer: coarse) { - #commandLineMobileButton { - display: block; - } -} - -#nitropay_ad_left, -#nitropay_ad_right { - margin-top: 1rem; -} - -// .adcontainer{ -// position: relative; -// &>div{ -// top: 0px; -// left: 0px; -// position: absolute; -// } -// .bg{ -// background: var(--bg-color); -// color: var(--sub-color); -// display: grid; -// align-items: center; -// justify-content: center; -// height: 100%; -// width: 100%; -// font-size: .75rem; -// user-select: none; -// } -// } diff --git a/static/images/banana.png b/static/images/banana.png new file mode 100644 index 000000000..c9ea682c0 Binary files /dev/null and b/static/images/banana.png differ diff --git a/static/index.html b/static/index.html index 8e5a35bee..6cabad89f 100644 --- a/static/index.html +++ b/static/index.html @@ -11,6 +11,7 @@ /> + @@ -42,8 +43,8 @@ /> @@ -1473,8 +1474,16 @@ diff --git a/static/quotes/code_javascript.json b/static/quotes/code_javascript.json index 9c843c0f2..a5e7fdf0f 100644 --- a/static/quotes/code_javascript.json +++ b/static/quotes/code_javascript.json @@ -30,6 +30,24 @@ "source": "Basic React.js Example", "length": 111, "id": 4 + }, + { + "text": "const arrayToHtmlList = (arr, listID) =>\\n\\t(el => (\\n\\t\\t(el = document.querySelector('#' + listID)),\\n\\t\\t(el.innerHTML += arr.map(item => `
  • ${item}
  • `).join(''))\\n\\t))();", + "source": "GitHub Gist - fatosmorina/array_to_html.js", + "length": 179, + "id": 5 + }, + { + "text": "subdivide(quadrant) {\\n\\tswitch (quadrant) {\\n\\t\\tcase 'ne':\\n\\t\\t\\treturn new Rectangle(this.x + this.w / 4, this.y - this.h / 4, this.w / 2, this.h / 2);\\n\\t\\tcase 'nw':\\n\\t\\t\\treturn new Rectangle(this.x - this.w / 4, this.y - this.h / 4, this.w / 2, this.h / 2);\\n\\t\\tcase 'se':\\n\\t\\t\\treturn new Rectangle(this.x + this.w / 4, this.y + this.h / 4, this.w / 2, this.h / 2);\\n\\t\\tcase 'sw':\\n\\t\\treturn new Rectangle(this.x - this.w / 4, this.y + this.h / 4, this.w / 2, this.h / 2);\\n\\t}\\n}", + "source": "Github - CodingTrain/QuadTree", + "length": 494, + "id": 6 + }, + { + "text": "canvas.parent('rgb-Canvas');\\nlet colors = [];\\nlet labels = [];\\nfor (let record of data.entries) {\\n\\tlet col = [record.r / 255, record.g / 255, record.b / 255];\\n\\tcolors.push(col);\\n\\tlabels.push(labelList.indexOf(record.label));\\n}", + "source": "GitHub - CodingTrain/ColorClassifer-TensorFlow.js", + "length": 236, + "id": 7 } ] } diff --git a/static/quotes/code_python.json b/static/quotes/code_python.json new file mode 100644 index 000000000..eaa255c15 --- /dev/null +++ b/static/quotes/code_python.json @@ -0,0 +1,47 @@ +{ + "language": "code_python", + "groups": [ + [0, 100], + [101, 300], + [301, 600], + [601, 9999] + ], + "quotes": [ + { + "text": "class Person:\\n\\tdef __init__(self, name, age):\\n\\t\\tself.name = name\\n\\t\\tself.age = age", + "source": "w3schools - Python Classes/Objects", + "id": 1, + "length": 89 + }, + { + "text": "def my_function(food):\\n\\tfor x in food:\\n\\t\\tprint(x)\\n\\nfruits = [\"apple\", \"banana\", \"cherry\"]\\nmy_function(fruits)", + "source": "w3schools - Python functions", + "id": 2, + "length": 117 + }, + { + "text": "f = open(\"demofile.txt\", \"r\")\\nprint(f.readline())\\nf.close()", + "source": "w3schools - Python Read File", + "id": 3, + "length": 61 + }, + { + "text": "def solveSudoku(sudoku, i=0, j=0):\\n\\ti, j = findNextCellToFill(sudoku)\\n\\tif i == -1:\\n\\t\\treturn True\\n\\tfor e in range(1, 10):\\n\\t\\tif isValid(sudoku, i, j, e):\\n\\t\\t\\tsudoku[i][j] = e\\n\\t\\t\\tif solveSudoku(sudoku, i, j):\\n\\t\\t\\t\\treturn True\\n\\t\\t\\tsudoku[i][j] = 0\\n\\treturn False", + "source": "GitHub - hastagAB/Awesome-Python-Scripts - sudoku solver by ayedaemon", + "id": 4, + "length": 285 + }, + { + "text": "def bruteforce(charset, maxlength):\\n\\treturn (''.join(candidate)\\n\\t\\tfor candidate in itertools.chain.from_iterable(itertools.product(charset, repeat=i)\\n\\t\\tfor i in range(1, maxlength + 1)))\\ndef extractFile(arFile, attempt):\\n\\ttry:\\n\\t\\tarFile.extractall(pwd=attempt)\\n\\t\\tprint \"Password found! password is %s\"%attempt\\n\\t\\texit(0)\\n\\texcept Exception,e:\\n\\t\\tpass\\n\\tif datetime.datetime.now().second%20==0:\\n\\t\\tprint 'At %s'%attempt", + "source": "GitHub - GauthamGoli/rar-Password-Cracker", + "id": 5, + "length": 444 + }, + { + "text": "soup = BeautifulSoup(html, features='lxml')\\nprint(soup.h1)\\nprint(line_break, soup.p)\\n\\nall_href = soup.find_all('a')\\nall_href = [l['href'] for l in all_href]\\nprint(line_break, all_href)", + "source": "GitHub - MorvanZhou/easy-scraping-tutorial", + "id": 6, + "length": 178 + } + ] +} diff --git a/static/quotes/english.json b/static/quotes/english.json index 0c7712bf7..622c8a5a5 100644 --- a/static/quotes/english.json +++ b/static/quotes/english.json @@ -1,22 +1,10 @@ { "language": "english", "groups": [ - [ - 0, - 100 - ], - [ - 101, - 300 - ], - [ - 301, - 600 - ], - [ - 601, - 9999 - ] + [0, 100], + [101, 300], + [301, 600], + [601, 9999] ], "quotes": [ { @@ -30086,7 +30074,7 @@ "length": 62 }, { - "text": "You see, the quality of any advice anybody has to offer has to be judged against the quality Of life they actually lead.", + "text": "You see, the quality of any advice anybody has to offer has to be judged against the quality of life they actually lead.", "source": "Mostly Harmless", "id": 5064, "length": 120 @@ -32072,7 +32060,7 @@ "id": 5394 }, { - "text": "My first girlfriend turned into the moon...That's rough, buddy.", + "text": "My first girlfriend turned into the moon... That's rough, buddy.", "source": "Avatar: The Last Airbender", "length": 63, "id": 5395 @@ -32385,13 +32373,13 @@ }, { "text": "Do not pity the dead, Harry. Pity the living, and, above all those who live without love.", - "source": "Albus Dumbledore", + "source": "Harry Potter And The Deathly Hallows", "length": 89, "id": 5447 }, { "text": "It does not do well to dwell on dreams and forget to live.", - "source": "Albus Dumbledore", + "source": "Harry Potter and the Sorcerer's Stone", "length": 58, "id": 5448 }, @@ -32408,7 +32396,7 @@ "id": 5450 }, { - "text": "If you ain’t scared… you ain’t human.", + "text": "If you ain’t scared... you ain’t human.", "source": "Alby, The Maze Runner", "length": 37, "id": 5451 @@ -32498,7 +32486,7 @@ "id": 5465 }, { - "text": "Human beings were never meant to participate in a worldwide social network comprised of billions of people. We were designed by evolution to be hunter-gatherers, with the mental capacity to interact and socialize with the other members of our tribe—a tribe made up of a few hundred other people at most. Interacting with thousands or even millions of other people on a daily basis was way too much for our ape-descended melons to handle. That was why social media had been gradually driving the entire population of the world insane since it emerged back around the turn of the century.", + "text": "Human beings were never meant to participate in a worldwide social network comprised of billions of people. We were designed by evolution to be hunter-gatherers, with the mental capacity to interact and socialize with the other members of our tribe - a tribe made up of a few hundred other people at most. Interacting with thousands or even millions of other people on a daily basis was way too much for our ape-descended melons to handle. That was why social media had been gradually driving the entire population of the world insane since it emerged back around the turn of the century.", "source": "Ready Player Two", "length": 586, "id": 5466 @@ -32616,310 +32604,304 @@ "id": 5484 }, { - "text": "My father picked me up from school one day and we played hookey and went to the beach. It was too cold to go in the water so we sat on a blanket and ate pizza. When I got home my sneakers were full of sand and I dumped it on my bedroom floor. I didn't know the difference, I was six. My mother screamed at me for the mess but he wasn't mad. He said that billions of years ago the world 's shifting and ocean moving brought that sand to that spot on the beach and then I took it away. Every day he said we change the world. Which is a nice thought until I think about how many days and lifetimes I would need to bring a shoe full of sand home until there is no beach. Until it made a difference to anyone. Every day we change the world. But to change the world in a way that means anything that takes more time than most people have. it never happens all at once. Its slow. Its methodical. Its exhausting. We don't all have the stomach for it.", + "text": "My father picked me up from school one day and we played hookey and went to the beach. It was too cold to go in the water so we sat on a blanket and ate pizza. When I got home my sneakers were full of sand and I dumped it on my bedroom floor. I didn't know the difference, I was six. My mother screamed at me for the mess but he wasn't mad. He said that billions of years ago the world's shifting and ocean moving brought that sand to that spot on the beach and then I took it away. Every day he said we change the world. Which is a nice thought until I think about how many days and lifetimes I would need to bring a shoe full of sand home until there is no beach. Until it made a difference to anyone. Every day we change the world. But to change the world in a way that means anything that takes more time than most people have. It never happens all at once. It's slow. It's methodical. It's exhausting. We don't all have the stomach for it.", "source": "Mr. Robot", "length": 942, "id": 5485 }, { - "text": "Hello. It's me, Choromatsu. I'm currently in Egypt. I heard that pieces of shit were more popular, so I tried being one, and... I was arrested. I'm scared. I didn't want to be held prisoner by anything anymore, so I left Japan, and now I'm literally a prisoner. Life's pretty funny isn't it? But some good things came out of this. I don't have time to think about anything other than eating, going to the bathroom, and sleeping, so I don't let the little things get me down. There's no envy, no self-loathing, and no hope. And because there's no hope, I'm in a lovely state where there's also no despair. I don't know how much happier I am being a prisoner physically versus being one mentally, but the fact that I'm thinking this way might be a sign that I'm still a prisoner.I shouldn't feel trapped, but I do, but I also feel trapped by the fact that I don't feel trapped over feeling trapped. What the hell am I even saying? I feel like I might go insane. Anyway I'm going to try to live life without being held prisoner by anyone.", + "text": "Hello. It's me, Choromatsu. I'm currently in Egypt. I heard that pieces of shit were more popular, so I tried being one, and... I was arrested. I'm scared. I didn't want to be held prisoner by anything anymore, so I left Japan, and now I'm literally a prisoner. Life's pretty funny isn't it? But some good things came out of this. I don't have time to think about anything other than eating, going to the bathroom, and sleeping, so I don't let the little things get me down. There's no envy, no self-loathing, and no hope. And because there's no hope, I'm in a lovely state where there's also no despair. I don't know how much happier I am being a prisoner physically versus being one mentally, but the fact that I'm thinking this way might be a sign that I'm still a prisoner. I shouldn't feel trapped, but I do, but I also feel trapped by the fact that I don't feel trapped over feeling trapped. What the hell am I even saying? I feel like I might go insane. Anyway I'm going to try to live life without being held prisoner by anyone.", "source": "Osomatsu-san 3rd Season", "length": 1036, - "id": null + "id": 5486 }, { "text": "She wished she had cancer instead. She'd trade Alzheimer's for cancer in a heartbeat. She felt ashamed for wishing this, and it was certainly a pointless bargaining, but she permitted herself the fantasy anyway. With cancer, she'd have something to fight. There was surgery, radiation, and chemotherapy. There was the chance that she could win. Her family and the community at Harvard would rally behind her battle and consider it noble. And even if it defeated her in the end, she'd be able to look them knowingly in the eye and say good-bye before she left.", "source": "Lisa Genova, Still Alice", "length": 559, - "id": null + "id": 5487 }, { "text": "What about you? Why are you still alive? You wanted revenge against the Vanettis, right? And you finished that crap already, right? Hey, you listening to me? He never wanted to join the Family. Even when I told him how rich he could get, he wouldn't even think about it. It was stupid how damn straight-laced he was. But you... You drove him crazy. And you killed him. He'd never even been with a woman... How is it right that you live and he dies!? Hey, are you listening!?", "source": "91 days", "length": 474, - "id": null + "id": 5488 }, { "text": "We're all afraid, you know... to get up on the stage. Maybe you will mess up. Maybe they'll totally reject you. Even so, you grit your teeth and get up on the stage anyway.", "source": "Your Lie In April", "length": 172, - "id": null + "id": 5489 }, { "text": "A lump of steel, like a shooting star. Just seeing the same sky as you makes familiar scenery look different. I swing between hope and despair at your slightest gesture, and my heart starts to play a melody. What kind of feeling is this again? What do they call this kind of feeling? I think it's probably... called love. I'm sure this is what they call love.", "source": "Your Lie In April", "length": 359, - "id": null + "id": 5490 }, { "text": "What one programmer can do in one month, two programmers can do in two months.", "source": "Fred Brooks", "length": 78, - "id": null + "id": 5491 }, { "text": "An ideal is only an ideal after all. As long as you embrace that ideal, the friction with reality will continue to increase. So you will someday face reality and will have to pay the price for your compromises.", "source": "Archer, Fate/Stay Night Anime", "length": 210, - "id": null + "id": 5492 }, { "text": "When dreams become more important than reality, you give up travel, building, creating; you even forget how to repair the machines left behind by your ancestors. You just sit living and reliving other lives left behind in the thought records.", "source": "Star Trek: The Original Series", "length": 242, - "id": null + "id": 5493 }, { "text": "Genius doesn't work on an assembly line basis. Did Einstein, Kazanga or Sitar of Vulcan produce new and revolutionary theories on a regular schedule? You can't simply say, 'Today I will be brilliant'.", "source": "Star Trek: The Original Series", "length": 200, - "id": null + "id": 5494 }, { "text": "I speak of rights! A machine has none; a man must. If you do not grant him that right, you have brought us down to the level of the machine; indeed, you have elevated that machine above us!", "source": "Star Trek : The Original Series", "length": 189, - "id": null + "id": 5495 }, { "text": "Human beings do not survive on bread alone ... but on the nourishments of liberty. For what indeed is a man without freedom ... naught but a mechanism, trapped in the cogwheels of eternity.", "source": "Star Trek: The Original Series", "length": 189, - "id": null + "id": 5496 }, { "text": "Your will to survive, your love of life, your passion to know ... Everything that is truest and best in all species of beings has been revealed to you. Those are the qualities that make a civilization worthy to survive.", "source": "Star Trek: The Original Series", "length": 219, - "id": null + "id": 5497 }, { "text": "Now, I don't pretend to tell you how to find happiness and love, when every day is a struggle to survive. But I do insist that you do survive, because the days and the years ahead are worth living for!", "source": "Star Trek: The Original Series", "length": 201, - "id": null + "id": 5498 }, { "text": "With the first link, the chain is forged. The first speech censored, the first thought forbidden, the first freedom denied, chains us all irrevocably.", "source": "Star Trek: The Next Generation", "length": 150, - "id": null + "id": 5499 }, { "text": "Our species can only survive if we have obstacles to overcome. You remove those obstacles. Without them to strengthen us, we will weaken and die.", "source": "Star Trek: The Original Series", "length": 145, - "id": null + "id": 5500 }, { "text": "You know the greatest danger facing us is ourselves, and irrational fear of the unknown. There is no such thing as the unknown. Only things temporarily hidden, temporarily not understood.", "source": "Star Trek: The Original Series", "length": 187, - "id": null + "id": 5501 }, { "text": "You may find that having is not so pleasing a thing as wanting. This is not logical, but it is often true.", "source": "Star Trek: The Original Series", "length": 106, - "id": null + "id": 5502 }, { "text": "He taught me that being born with natural talent is not the greatest gift. The truly lucky ones are those with an unwavering belief in themselves. And the passion to keep striving to the very end.", "source": "Naruto", "length": 196, - "id": null + "id": 5503 }, { "text": "I cannot believe this shit! First I get a bullshit assignment, now Mr. Rice-a-Roni don't even speak American. C'mon, man, my ride over here. Put your bag in the back.", "source": "Rush Hour", "length": 166, - "id": null + "id": 5504 }, { "text": "It's like how hot dogs come in packs of 10, and buns come in packs of eight or 12; you have to buy nine packs to make it come out even.", "source": "Miss Rollings (Swoosie Kurtz) - True Stories", "length": 135, - "id": null + "id": 5505 }, { "text": "Physical wounds will definitely bleed and may look painful but over time they heal by themselves and if you apply medicine, they will heal faster. What's troublesome are wounds of the heart. Nothing is harder to heal. They're a bit different from physical injuries. You can't apply medicine for one thing and sometimes, they never heal. There's only one cure for a wound of the heart. It's a bit bothersome and you can only receive it from someone else. What is it? Love.", "source": "Yashamaru Character - Masashi Kishimoto, Naruto Shippuden", "length": 471, - "id": null + "id": 5506 }, { "text": "Normally, I don't condone leaving early, but I have an appointment with the horse doctor. How that horse became a doctor, I don't know.\\n No, I'm kidding. He's just a regular doctor... who shoots your horse in the head when its leg is broken.", "source": "Dwight K. Schrute - The Office (US)", "length": 242, - "id": null + "id": 5507 }, { "text": "This is me! Up to now, you still don't even see me for who I really am! I'm you, Dad. I tried to give you one last chance, like you said with Breeze, but you're in the way. You're in the way of my future, like you said he was in the way of yours. Ain't that what you said? In the way of your future right? Put the gun down. Tariq, if you do this, you can never go back. I'll do anything to go back, to go back to how it was before you left us for Angela. I just can't, it's too late.", "source": "Power, Tariq St Patrick , James St Patrick", "length": 483, - "id": null + "id": 5508 }, { "text": "Mental? Well, let me tell you something, Mr. 100% Tip-Top Mental. My daughter may be no spring chicken, and her jaw may crack when she chews, and she may have noticeable trouble digesting raw vegetables. But one thing she is not, is mental!", "source": "Sophia Petrillo, The Golden Girls", "length": 240, - "id": null + "id": 5509 }, { "text": "Picture this. Two young girls, best friends, who share three things: some dough and a dream. Everything is going great, until one day, a fast-talking pepperoni salesman gallops into town. Of course, both girls are impressed. He dates one one night, and the other the next night. Pretty soon, he drives a wedge between them. Before you know it, the pizza suffers, the business suffers, the friendship suffers. The girls part company and head for America, never to see one another again. Rose, one of those girls was me. The other one, you probably know as Mama Celeste.", "source": "Sophia Petrillo, The Golden Girls", "length": 568, - "id": null + "id": 5510 }, { "text": "No, Blanche. I'm not going to let you do that. I've been doing a lot of thinking. If, after all the years of love and companionship, Fernando and I are meant to part company, I'll just have to accept that. Time to time, life deals you an unfriendly hand; there's nothing you can do about it. I guess there's a lesson to be learned here. Sometimes life just isn't fair, kiddo.", "source": "Rose Nylund, The Golden Girls", "length": 375, - "id": null + "id": 5511 }, { "text": "The most romantic thing was when Stan proposed. I went to the powder room, and when I returned to the table, there was an open bottle of Dom Perignon and two filled glasses. We clinked the glasses in a toast and Stan gave me a coy smile, and I winked at him and I just downed the champagne in one gulp. And it didn't go down smoothly. Later, Stan told me that he put my engagement ring in the bottom of the glass.", "source": "Dorothy Zbornak, The Golden Girls", "length": 413, - "id": null + "id": 5512 }, { "text": "The serum amplifies everything that is inside, so good becomes great; bad becomes worse. This is why you were chosen. Because the strong man who has known power all his life, may lose respect for that power, but a weak man knows the value of strength, and knows compassion.", "source": "Abraham Erskine, Captain America: The First Avenger", "length": 273, - "id": null + "id": 5513 }, { "text": "I don't want to kill anyone. I don't like bullies; I don't care where they're from.", "source": "Steve Rogers, Captain America: The First Avenger", "length": 83, - "id": null + "id": 5514 }, { "text": "Let me tell you a story. Picture it: Sicily, 1922. An attractive peasant girl who has saved her lira embarks on a glorious vacation to a Crimean resort on the Black Sea. For weeks, she frolics at the seaside resorts, and enjoys the company of many young men, all of whom adore her. When it's time to return to Sicily, three different suitors beg her to stay. But she can't decide who to choose, so she chooses none of them. But she agrees to meet with them at the same resort many years later. To her trio of suitors, that eventful gathering was referred to as \"Rendezvous with Sophia.\" But to the rest of the world, it was better known as the Yalta Conference.", "source": "Sophia Petrillo, The Golden Girls", "length": 661, - "id": null + "id": 5515 }, { "text": "I'm not gonna kill myself because if my depression wants me dead THAT badly it's gonna have to start shutting my organs down like a REAL disease instead of being a coward and hiding in my brain and trying to get ME to do it's dirty work for it!", "source": "scottishsafehouse - Tumblr", "length": 244, - "id": null + "id": 5516 }, { "text": "Human touch. Our first form of communication. Safety, security, comfort, all in the gentle caress of a finger. Or the brush of lips on a soft cheek. It connects us when we're happy, bolsters us in times of fear, excites us in times of passion and love. We need that touch from the one we love, almost as much as we need air to breathe. But I never understood the importance of touch. His touch. Until I couldn't have it. So if you're watching this, and you're able, touch him. Touch her. Life's too short to waste a second.", "source": "Five Feet Apart", "length": 523, - "id": null + "id": 5517 }, { "text": "Tom, don't let anybody kid you. It's all personal, every bit of business. Every piece of shit every man has to eat every day of his life is personal. They call it business. OK. But it's personal as hell. You know where I learned that from? The Don. My old man. The Godfather. If a bolt of lightning hit a friend of his the old man would take it personal. He took my going into the Marines personal. That's what makes him great. The Great Don. He takes everything personal Like God. He knows every feather that falls from the tail of a sparrow or however the hell it goes? Right? And you know something? Accidents don't happen to people who take accidents as a personal insult.", "source": "The Godfather", "length": 677, - "id": null + "id": 5518 }, { "text": "One of the main differences between introverts and extroverts is that extroverts get their energy from hanging out with other people, and introverts are mentally ill.", "source": "Exurb1a", "length": 166, - "id": null + "id": 5519 }, { "text": "Unfortunately, my birthday has always been the lousiest day of the year. It all began on the day of my actual birth... both of my parents failed to show up. By the age of 5, I was forced to throw my own surprise party at Gunther Goat Cheese's: the goat-cheesiest place in all of Drusselstein. Many of my closest friends were there: Count Wolfgang, Betty the She-Boar, Ratputin, and the licekins, Olga and Chicago Joe. But one should never walk the paths of Drusselstein with uncovered doonkleberry cake, lest the doonkleberry bats swarm.", "source": "Dr. Doofenshmirtz, Phineas and Ferb", "length": 538, - "id": null + "id": 5520 }, { "text": "I believe there's a hero in all of us that keeps us honest, gives us strength, makes us noble, and finally allows us to die with pride, even though sometimes we have to be steady and give up the things we want the most, even our dreams.", "source": "Aunt May, *Spider-Man 2*", "length": 236, - "id": null + "id": 5521 }, { "text": "I play Russian roulette every day, a man's sport with the bullet called life. Yeah, mama called life. Yeah and every time I try to go where I really want to be, it's already where I am, 'cause I'm already there!", "source": "Sugar, System of a Down", "length": 211, - "id": null + "id": 5522 }, { "text": "Back in Gimmelshtump in the days of my youth, the Doofenshmirtzes were a proud family. But those were lean times for my father, and our beloved lawn gnome was repossessed. Who would protect our zatzenfruit garden from those witches, spells, and wood trolls? From a tender age, my father decided that it would be me. While the other children played Kick-the-Shtumpel and ate doonkelberries, I would stand for hours. All through the cold night as the spitzenhound howled, my only companion was the moon. And my neighbor Kenny. And since my lawn gnome was taken away from me, I will destroy every lawn gnome in the entire tri-state area!", "source": "Heinz Doofenshmirtz, Phineas and Ferb", "length": 634, - "id": null + "id": 5523 }, { "text": "A good brass player spends many hours in front of a mirror watching and listening. A good rule to follow is to form the embouchure so that all the muscles around the aperture are working in unison. Picture a fireman's net - the center being the aperture of your embouchure. Around this net are eight firemen pulling out from the center to keep the net taut. Think of your muscles working in this same way to preserve the stability and openness of the aperture. Keep a close eye on the area just below the bottom lip, the goal being to have as little movement as possible and to maintain a flat chin. In addition, try to form your embouchure away from the mouthpiece and the instrument. A good brass player knows how to do this.", "source": "Joseph Alessi, Arban Complete Method for Trombone and Euphonium", "length": 727, - "id": null + "id": 5524 }, { "text": "Assist Mode allows you to modify the game's rules to fit your specific needs. This includes options such as slowing the game speed, granting yourself invincibility or infinite stamina, and skipping chapters entirely. Celeste is intended to be a challenging and rewarding experience. If the default game proves inaccessible to you, we hope that you can still find that experience with Assist Mode. Would you like to play with Assist Mode?", "source": "Celeste", "length": 437, - "id": null + "id": 5525 }, { "text": "When I was young, I entered a science fair with my very first Inator. I wasn't very clever with the names yet. It was just, you know, \"Inator.\" Just as I was about to demonstrate my invention to the judges, a kid with a baking soda volcano stole the show! The next year I tried again with my Even-Bigger-Inator. And again, my thunder was stolen by a baking soda volcano! I had enough of science. I decided to devote my life to poetry instead. Yet curiously, I still lost to a baking soda volcano!", "source": "Heinz Doofenshmirtz, Phineas and Ferb", "length": 496, - "id": null + "id": 5526 }, { "text": "Back in Gimmelshtump, in the depths of my childhood, my parents were expecting a brand new baby girl. My mother spent months knitting pretty dresses. Unfortunately the baby turned out to be a boy, and because we were out of material, I was forced to wear those same dresses for an entire year, drawing mockery and scorn from all of my manly classmates!", "source": "Heinz Doofenshmirtz, Phineas and Ferb", "length": 352, - "id": null + "id": 5527 }, { "text": "Wonder if I gave an Oreo to the Big Bad Wolf. How would the story go? Would he still go huff and puff? Or would he bring those pigs cool stuff to decorate the deck he helped them build? Would they not get killed? Wonder if I gave an Oreo to a vampire in a creepy show. Would he not act so undead? Would he thirst for milk instead? I've just got this feeling that it might work out all right. 'Cause cream does wondrous things inside a chocolate sandwich dream. If I gave 'em to great white sharks, would they share 'em with baby seals? Would they call up a giant squid for a friendly meal?", "source": "Oreo Wonderfilled Anthem", "length": 589, - "id": null - }, - { - "text": "One thing only I know, and that is that I know nothing.", - "source": "Socrates", - "length": 55, - "id": null + "id": 5528 }, { "text": "I'm not the sweet, forebearing guy that I try to make out that I am. I get irritated at things. I feel like snapping at people, and I feel like being selfish at times; and I don't know why I should pretend I'm not that way.", "source": "Carl Rogers, On Becoming a Person", "length": 223, - "id": null + "id": 5529 }, { "text": "We as a nation are slowly realizing our enormous strength, and the power and responsibility which go with that strength. We are moving, somewhat ignorantly and clumsily, toward accepting a position of responsible world leadership. We make many mistakes. We are often inconsistent. We are far from perfect. We are deeply frightened by the strength of Communism, a view of life different from our own.", "source": "Carl Rogers, On Becoming a Person", "length": 399, - "id": null + "id": 5530 }, { "text": "The FitnessGram Pacer Test is a multistage aerobic capacity test that progressively gets more difficult as it continues. The 20 meter pacer test will begin in 30 seconds. Line up at the start. The running speed starts slowly, but gets faster each minute after you hear this signal. [beep] A single lap should be completed each time you hear this sound. [ding] Remember to run in a straight line, and run as long as possible. The second time you fail to complete a lap before the sound, your test is over. The test will begin on the word start. On your mark, get ready, start.", "source": "The Cooper Institute", "length": 575, - "id": null + "id": 5531 }, { "text": "I have little sympathy with the rather prevalent concept that man is basically irrational, and that his impulses, if not controlled, will lead to destruction of others and self. Man's behavior is exquisitely rational, moving with subtle and ordered complexity toward the goals his organism is endeavoring to achieve. The tragedy for most of us is that our defenses keep us from being aware of this rationality, so that conciously we are moving in one direction, while organismically we are moving in another.", "source": "Carl Rogers, On Becoming a Person", "length": 508, - "id": null + "id": 5532 }, { "text": "Often the learnings take such simple forms as \"I am different from others\"; \"I do feel hatred for him\"; \"I am fearful of feeling dependent\"; \"I do feel sorry for myself\"; \"I am self-centered\"; \"I do have tender and loving feelings\"; \"I could be what I want to be\"; etc. But in spite of their seeming simplicity these learnings are vastly significant in some new way which is very difficult to define. We can think of it in various ways. They are self-appropriated learnings, for one thing, based somehow in experience, not in symbols.", "source": "Carl Rogers, On Becoming a Person", "length": 534, - "id": null + "id": 5533 }, { "text": "How can you know that this account, or any account given at a previous or later time, is true? How do you know that it has any relationship to reality? If we are to rely on this inner and subjective experience as being the truth about human relationships or about ways of altering personality, then Yogi, Christian Science, dianetics, and the delusions of a psychotic individual who believes himself to be Jesus Christ, are all true, just as true as this account.", "source": "Carl Rogers, On Becoming a Person", "length": 463, - "id": null + "id": 5534 } ] -} \ No newline at end of file +} diff --git a/static/quotes/french.json b/static/quotes/french.json index 28252be76..0a49d3430 100644 --- a/static/quotes/french.json +++ b/static/quotes/french.json @@ -120,6 +120,48 @@ "source": "Max Boublil \"J'aime les moches\"", "length": 178, "id": 19 + }, + { + "text": "La principale critique vient du fait que l’arrangement AZERTY provient du QWERTY, lui-même optimisé pour pallier les contraintes mécaniques des premières machines à écrire et non pas pour la langue anglaise. L’origine de l’AZERTY est plutôt sombre mais il est clair qu’il n’a pas été pensé pour la langue française.", + "source": "Wikipedia - AZERTY", + "length": 315, + "id": 19 + }, + { + "text": "Les savants ont calculé que les chances d'exister d'un phénomène aussi manifestement absurde sont de une sur un million. Mais les magiciens, eux, ont calculé que les chances uniques sur un million se réalisent neuf fois sur dix.", + "source": "Terry Pratchett - Mortimer (les Annales du Disque-monde)", + "length": 228, + "id": 20 + }, + { + "text": "On vous l’a sûrement déjà dit, il faut apprendre à bien choisir ses lectures. Mal les choisir peut nuire gravement à la santé. Un exemple. Vous vous baladez en montagne et, tout en marchant, vous lisez les oeuvres complètes d’Hérodote au lieu de lire : ATTENTION, RAVIN. Vous n’irez pas au bout de cette lecture. Vous n’avez pas fait le bon choix.", + "source": "Lemony Snicket - Les Désastreuses aventures des orphelins Baudelaire, tome 7", + "length": 346, + "id": 21 + }, + { + "text": "Si tu savais le temps que fait une minute, écoute le son de mon coeur quand il explose comme une cocotte minute.", + "source": "Stupeflip - Nan?..Si?", + "length": 112, + "id": 22 + }, + { + "text": "Ce qui est élevé est destiné à être aplani... Ce qui est dense deviendra fluide... L'entropie fait son œuvre et, en définitive, toute chose tend vers l'uniformisation. C'est une loi inévitable et irréversible d'équilibre. L'homme croit toujours pouvoir inverser ce fleuve cosmique. Mais il n'est qu'un fétu de paille emporté par les flots.", + "source": "Katsuhiro Otomo - Akira, tome 4", + "length": 339, + "id": 23 + }, + { + "text": "Les Bacillidae forment une famille d'insectes phasmoptères de l'infra-ordre des Areolatae, de la super-famille des Bacilloidea, caractérisés par un thorax dont le dernier tergite n'est pas soudé avec le premier segment abdominal.", + "source": "Wikipedia - Bacillidae", + "length": 229, + "id": 24 + }, + { + "text": "Le Gouvernement français a demandé à l’ennemi à quelles conditions honorables un cessez-le-feu était possible. Il a déclaré que, si ces conditions étaient contraires à l’honneur, la dignité et l’indépendance de la France, la lutte devait continuer.", + "source": "Charles de Gaulle - Appel du 18 Juin", + "length": 248, + "id": 25 } ] } diff --git a/static/quotes/lithuanian.json b/static/quotes/lithuanian.json new file mode 100644 index 000000000..bd6adab07 --- /dev/null +++ b/static/quotes/lithuanian.json @@ -0,0 +1,131 @@ +{ + "language": "lithuanian", + "groups": [ + [0, 100], + [101, 300], + [301, 600], + [601, 9999] + ], + "quotes": [ + { + "text": "Kol kas tu man tik mažas berniukas, panašus į šimtus tūkstančių kitų berniukų. Tu man nereikalingas. Aš tau irgi nereikalinga. Aš tau esu tik lapė, panaši į šimtą tūkstančių kitų lapių. Bet jei mane prisijaukinsi, mudu tapsime vienas kitam reikalingi. Tu būsi man vienintelis pasaulyje... Aš būsiu tau vienintelė pasaulyje...", + "source": "Mažasis princas", + "length": 50, + "id": 1 + }, + { + "text": "Dabar ji suprato, kodėl jo veidas pilkas - odon įsiėdė akmens dulkės. Ji glostė abiem rankom didelį, grubų, kietą kumštį ir žiūrėjo sau po kojomis, ten, kur gulėjo akmenys, prigludę vienas prie kito, akmuo prie akmens, kieti kaip jie patys.", + "source": "Lygiosios trunka akimirką", + "length": 40, + "id": 2 + }, + { + "text": "Prasidėjus liepai, žemės paviršius atšilo, ir darbų padaugėjo: taigos properšoje Usolės lietuviai gavo sklypelį žemės. Mumyse atgijo žemdirbių kraujas. Tad puolėme kasti žemelę, sodinti bulves.", + "source": "Amžino įšalo žemė", + "length": 25, + "id": 3 + }, + { + "text": "Saulė švietė, lingavo žalios, skarotos maumedžių šakos, jose striksėjo voverės, žaibais į šešėlius nardė sabalai, o nuklydęs gilyn į girią, bijojai sutikti taigos šeimininką - lokį.", + "source": "Amžino įšalo žemė", + "length": 26, + "id": 4 + }, + { + "text": "Pusę vienuoliktos jis išgirdo, kaip visi nuėjo gulti. Kiek laiko jį erzino laukinis juokas iš dvynukų kambario - jie su lengvabūdiška paauglių linksmybe išdykavo prieš miegą, - bet pusę dvyliktos viskas nurimo ir išmušus vidurnaktį jis leidosi pirmyn.", + "source": "Kentervilio pilies vaiduoklis", + "length": 38, + "id": 5 + }, + { + "text": "Oras buvo vaiskus. Ralfas tiesiog nebesitvėrė iš džiaugsmo ir, negalėdamas to niekaip kitaip išreikšti, apsivertė kūlvirsčia. Kai visi trys prisikvatojo iki valiai, Saimonas nedrąsiai paglostė Ralfui ranką, ir vėl visi prapliupo juoktis.", + "source": "Musių valdovas", + "length": 32, + "id": 6 + }, + { + "text": "Palmių kraštai mėlynam vandenyne, kviečia atogrąžų saldūs kerai, o tarp savanų, smėlėtam žemyne, iš baobabų suręsti namai.", + "source": "Robinzonas", + "length": 17, + "id": 7 + }, + { + "text": "Nešęs velnias akmenį, didumo kaip gryčios,\nIr sudaužyt norėjęs Anykščių bažnyčios\nArba ažuverst upės; bet kaip tik išvydęs\nĄžuolyną pašvęstą ir gaidys pragydęs,\nTuoj iš nagų paleidęs ir smėlin įmušęs:\nNet žemė sudrebėjus, senos griuvę pušys.", + "source": "Anykščių šilelis", + "length": 36, + "id": 8 + }, + { + "text": "Jau saulelė vėl atkopdama budino svietą\nIr žiemos šaltos trūsus pargraudama juokės.\nŠalčių pramonės su ledais sugaišti pagavo,\nIr putodams sniegs visur į nieką pavirto.", + "source": "Metai", + "length": 37, + "id": 9 + }, + { + "text": "Kalk geležį, kol karšta, paskui neįveiksi, mokyk vaiką, kol mažas, paskui nepriveiksi.", + "source": "Lietuvių liaudies patarlės", + "length": 12, + "id": 10 + }, + { + "text": "Jei turi ką valgyti ir su kuo apsirėdyti, nieko geresnio neturėtum ir karalium būdamas.", + "source": "Lietuvių liaudies patarlės", + "length": 14, + "id": 11 + }, + { + "text": "Žodžiu galvos nepramuši, o sužeisti gali. Žodis kaip žvirblis, išlėks – nepagausi.", + "source": "Lietuvių liaudies patarlės", + "length": 11, + "id": 12 + }, + { + "text": "Tavęs klausiu apie ragaišį, o tu pasakoji, kad katinas nugaišo.", + "source": "Lietuvių liaudies patarlės", + "length": 10, + "id": 13 + }, + { + "text": "Geriau sužiedėjusi duona savo namuose, negu daugybė valgių ant svetimo stalo.", + "source": "Lietuvių liaudies patarlės", + "length": 11, + "id": 14 + }, + { + "text": "Gudrus svetimas klaidas suskaityti, kvailas, kai reikia savo nors vieną pamatyti.", + "source": "Lietuvių liaudies patarlės", + "length": 11, + "id": 15 + }, + { + "text": "Šerkšno ji nematė, tačiau jautė, kaip gyslose kraujas spragsėdamas virsta ledo kristalėliais. Jos plaukai tarsi jūržolės plaikstėsi ant pagalvės.", + "source": "Lietuvos nacionalinis diktantas - Milinė", + "length": 19, + "id": 16 + }, + { + "text": "Angelas nusklendė žemyn, praskyręs rūką įleido sielą vidun: eik, šį kartą tau bus lemta ilgiau Žemėje užtrukti - kol pastatysi šventovę.", + "source": "Lietuvos nacionalinis diktantas - Milinė", + "length": 21, + "id": 17 + }, + { + "text": "Ir neturėjau kam pasiskųsti, kad aš taip pavargau. Norėjau pailsėti nors valandėlę, nors penkiolika minučių. Sustojau ties aukštąja pušim ir atsirėmiau į jos kamieną.", + "source": "Diktantai - Pagalbinė medžiaga vidurinių mokyklų lietuvių kalbos dėstytojams", + "length": 24, + "id": 18 + }, + { + "text": "Po aprašytųjų peštynių lageryje santykiuose su mumis kažkas pasikeitė. Kažkas nauja dvelktelėjo. Pajutome kažkokią nematomą, neaiškią gerą ranką. Kažkas nematomas ėmė mus globoti.", + "source": "Dievų miškas", + "length": 23, + "id": 19 + }, + { + "text": "Dviratukas mano niekaip nesustoja. Aš minu į priekį ir dainas dainuoju.", + "source": "Dviratukas", + "length": 11, + "id": 20 + } + ] +}