aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorEvan <[email protected]>2023-03-10 13:27:10 -0600
committerEvan <[email protected]>2023-03-10 13:27:10 -0600
commit27965be7ff0d4e492718fac4b3d4bfd48cc405ce (patch)
tree0d51b481512802094201e411c0630748473e008a
parent0ee13d8ac88553a1f2edbca1a4c1594cb10fa3ff (diff)
parent00646da6fe295014962c7d748b0df2d383dd6796 (diff)
downloadmonkeytype-27965be7ff0d4e492718fac4b3d4bfd48cc405ce.tar.gz
monkeytype-27965be7ff0d4e492718fac4b3d4bfd48cc405ce.zip
Merge branch 'master' into strict-equality
-rw-r--r--backend/src/queues/later-queue.ts40
-rw-r--r--backend/src/utils/daily-leaderboards.ts4
-rw-r--r--backend/src/workers/later-worker.ts28
-rw-r--r--frontend/package-lock.json14
-rw-r--r--frontend/package.json1
-rw-r--r--frontend/src/styles/core.scss1
-rw-r--r--frontend/src/styles/test.scss40
-rw-r--r--frontend/src/ts/commandline/lists/font-size.ts4
-rw-r--r--frontend/src/ts/config.ts2
-rw-r--r--frontend/src/ts/controllers/chart-controller.ts45
-rw-r--r--frontend/src/ts/elements/scroll-to-top.ts2
-rw-r--r--frontend/src/ts/popups/result-tags-popup.ts7
-rw-r--r--frontend/src/ts/settings/theme-picker.ts13
-rw-r--r--frontend/src/ts/test/practise-words.ts2
-rw-r--r--frontend/src/ts/test/result.ts8
-rw-r--r--frontend/src/ts/test/test-logic.ts23
-rw-r--r--frontend/src/ts/test/test-ui.ts222
-rw-r--r--frontend/src/ts/ui.ts11
-rw-r--r--frontend/src/ts/utils/misc.ts60
-rw-r--r--frontend/static/html/pages/settings.html31
-rw-r--r--frontend/static/html/pages/test.html26
-rw-r--r--frontend/static/languages/code_lua.json2
-rw-r--r--frontend/static/languages/code_luau.json6
-rw-r--r--frontend/static/languages/english_10k.json1
-rw-r--r--frontend/static/languages/russian_375k.json135
-rw-r--r--frontend/static/layouts/_list.json26
-rw-r--r--frontend/static/quotes/code_c++.json6
-rw-r--r--frontend/static/quotes/english.json100
-rw-r--r--frontend/static/quotes/german.json64
-rw-r--r--frontend/static/quotes/indonesian.json4
-rw-r--r--frontend/static/quotes/russian.json6
-rw-r--r--frontend/static/themes/_list.json7
-rw-r--r--frontend/static/themes/cherry_blossom.css12
-rw-r--r--frontend/static/themes/dracula.css16
34 files changed, 550 insertions, 419 deletions
diff --git a/backend/src/queues/later-queue.ts b/backend/src/queues/later-queue.ts
index 8a556a67e..56993b5ec 100644
--- a/backend/src/queues/later-queue.ts
+++ b/backend/src/queues/later-queue.ts
@@ -5,24 +5,36 @@ import { getCurrentDayTimestamp, getCurrentWeekTimestamp } from "../utils/misc";
const QUEUE_NAME = "later";
-type LaterTasks = "daily-leaderboard-results" | "weekly-xp-leaderboard-results";
+export type LaterTaskType =
+ | "daily-leaderboard-results"
+ | "weekly-xp-leaderboard-results";
-export interface LaterTask {
- taskName: LaterTasks;
- ctx: any;
+export interface LaterTask<T extends LaterTaskType> {
+ taskName: LaterTaskType;
+ ctx: LaterTaskContexts[T];
}
+export type LaterTaskContexts = {
+ "daily-leaderboard-results": {
+ yesterdayTimestamp: number;
+ modeRule: MonkeyTypes.ValidModeRule;
+ };
+ "weekly-xp-leaderboard-results": {
+ lastWeekTimestamp: number;
+ };
+};
+
const ONE_MINUTE_IN_MILLISECONDS = 1000 * 60;
const ONE_DAY_IN_MILLISECONDS = 1000 * 60 * 60 * 24;
-class LaterQueue extends MonkeyQueue<LaterTask> {
+class LaterQueue extends MonkeyQueue<LaterTask<LaterTaskType>> {
private scheduledJobCache = new LRUCache<string, boolean>({
max: 100,
});
private async scheduleTask(
taskName: string,
- task: LaterTask,
+ task: LaterTask<LaterTaskType>,
jobId: string,
delay: number
): Promise<void> {
@@ -41,9 +53,8 @@ class LaterQueue extends MonkeyQueue<LaterTask> {
}
async scheduleForNextWeek(
- taskName: LaterTasks,
- taskId: string,
- taskContext?: any
+ taskName: LaterTaskType,
+ taskId: string
): Promise<void> {
const currentWeekTimestamp = getCurrentWeekTimestamp();
const jobId = `${taskName}:${currentWeekTimestamp}:${taskId}`;
@@ -52,10 +63,9 @@ class LaterQueue extends MonkeyQueue<LaterTask> {
return;
}
- const task: LaterTask = {
+ const task: LaterTask<LaterTaskType> = {
taskName,
ctx: {
- ...taskContext,
lastWeekTimestamp: currentWeekTimestamp,
},
};
@@ -70,9 +80,9 @@ class LaterQueue extends MonkeyQueue<LaterTask> {
}
async scheduleForTomorrow(
- taskName: LaterTasks,
+ taskName: LaterTaskType,
taskId: string,
- taskContext: any
+ modeRule: MonkeyTypes.ValidModeRule
): Promise<void> {
const currentDayTimestamp = getCurrentDayTimestamp();
const jobId = `${taskName}:${currentDayTimestamp}:${taskId}`;
@@ -81,10 +91,10 @@ class LaterQueue extends MonkeyQueue<LaterTask> {
return;
}
- const task: LaterTask = {
+ const task: LaterTask<LaterTaskType> = {
taskName,
ctx: {
- ...taskContext,
+ modeRule,
yesterdayTimestamp: currentDayTimestamp,
},
};
diff --git a/backend/src/utils/daily-leaderboards.ts b/backend/src/utils/daily-leaderboards.ts
index 8ae4a7860..79f5645e4 100644
--- a/backend/src/utils/daily-leaderboards.ts
+++ b/backend/src/utils/daily-leaderboards.ts
@@ -101,9 +101,7 @@ export class DailyLeaderboard {
await LaterQueue.scheduleForTomorrow(
"daily-leaderboard-results",
this.leaderboardModeKey,
- {
- modeRule: this.modeRule,
- }
+ this.modeRule
);
}
diff --git a/backend/src/workers/later-worker.ts b/backend/src/workers/later-worker.ts
index dacf5c010..5857808c4 100644
--- a/backend/src/workers/later-worker.ts
+++ b/backend/src/workers/later-worker.ts
@@ -8,21 +8,16 @@ import { buildMonkeyMail } from "../utils/monkey-mail";
import { DailyLeaderboard } from "../utils/daily-leaderboards";
import { getCachedConfiguration } from "../init/configuration";
import { formatSeconds, getOrdinalNumberString, mapRange } from "../utils/misc";
-import LaterQueue, { LaterTask } from "../queues/later-queue";
+import LaterQueue, {
+ LaterTask,
+ LaterTaskContexts,
+ LaterTaskType,
+} from "../queues/later-queue";
import { WeeklyXpLeaderboard } from "../services/weekly-xp-leaderboard";
import { recordTimeToCompleteJob } from "../utils/prometheus";
-interface DailyLeaderboardMailContext {
- yesterdayTimestamp: number;
- modeRule: MonkeyTypes.ValidModeRule;
-}
-
-interface WeeklyXpLeaderboardResultContext {
- lastWeekTimestamp: number;
-}
-
async function handleDailyLeaderboardResults(
- ctx: DailyLeaderboardMailContext
+ ctx: LaterTaskContexts["daily-leaderboard-results"]
): Promise<void> {
const { yesterdayTimestamp, modeRule } = ctx;
const { language, mode, mode2 } = modeRule;
@@ -106,7 +101,7 @@ async function handleDailyLeaderboardResults(
}
async function handleWeeklyXpLeaderboardResults(
- ctx: WeeklyXpLeaderboardResultContext
+ ctx: LaterTaskContexts["weekly-xp-leaderboard-results"]
): Promise<void> {
const {
leaderboards: { weeklyXp: weeklyXpConfig },
@@ -184,15 +179,18 @@ async function handleWeeklyXpLeaderboardResults(
}
async function jobHandler(job: Job): Promise<void> {
- const { taskName, ctx }: LaterTask = job.data;
+ const { taskName, ctx }: LaterTask<LaterTaskType> = job.data;
+
Logger.info(`Starting job: ${taskName}`);
const start = performance.now();
if (taskName === "daily-leaderboard-results") {
- await handleDailyLeaderboardResults(ctx);
+ const taskCtx = ctx as LaterTaskContexts["daily-leaderboard-results"];
+ await handleDailyLeaderboardResults(taskCtx);
} else if (taskName === "weekly-xp-leaderboard-results") {
- await handleWeeklyXpLeaderboardResults(ctx);
+ const taskCtx = ctx as LaterTaskContexts["weekly-xp-leaderboard-results"];
+ await handleWeeklyXpLeaderboardResults(taskCtx);
}
const elapsed = performance.now() - start;
diff --git a/frontend/package-lock.json b/frontend/package-lock.json
index 8a69c3cdc..032c15843 100644
--- a/frontend/package-lock.json
+++ b/frontend/package-lock.json
@@ -15,6 +15,7 @@
"chartjs-adapter-date-fns": "2.0.0",
"chartjs-plugin-annotation": "1.4.0",
"chartjs-plugin-trendline": "1.0.2",
+ "color-blend": "4.0.0",
"crypto-browserify": "3.12.0",
"damerau-levenshtein": "1.0.8",
"date-fns": "2.28.0",
@@ -5027,6 +5028,14 @@
"node": ">=0.10.0"
}
},
+ "node_modules/color-blend": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/color-blend/-/color-blend-4.0.0.tgz",
+ "integrity": "sha512-fYODTHhI/NG+B5GnzvuL3kiFrK/UnkUezWFTgEPBTY5V+kpyfAn95Vn9sJeeCX6omrCOdxnqCL3CvH+6sXtIbw==",
+ "engines": {
+ "node": ">=10.0.0"
+ }
+ },
"node_modules/color-convert": {
"version": "1.9.3",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
@@ -21733,6 +21742,11 @@
"object-visit": "^1.0.0"
}
},
+ "color-blend": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/color-blend/-/color-blend-4.0.0.tgz",
+ "integrity": "sha512-fYODTHhI/NG+B5GnzvuL3kiFrK/UnkUezWFTgEPBTY5V+kpyfAn95Vn9sJeeCX6omrCOdxnqCL3CvH+6sXtIbw=="
+ },
"color-convert": {
"version": "1.9.3",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
diff --git a/frontend/package.json b/frontend/package.json
index 81c4aa847..d965c63d3 100644
--- a/frontend/package.json
+++ b/frontend/package.json
@@ -64,6 +64,7 @@
"chartjs-adapter-date-fns": "2.0.0",
"chartjs-plugin-annotation": "1.4.0",
"chartjs-plugin-trendline": "1.0.2",
+ "color-blend": "4.0.0",
"crypto-browserify": "3.12.0",
"damerau-levenshtein": "1.0.8",
"date-fns": "2.28.0",
diff --git a/frontend/src/styles/core.scss b/frontend/src/styles/core.scss
index 98bf17466..ff98210c5 100644
--- a/frontend/src/styles/core.scss
+++ b/frontend/src/styles/core.scss
@@ -48,6 +48,7 @@
html {
@extend .ffscroll;
overflow-y: scroll;
+ scroll-behavior: smooth;
}
a {
diff --git a/frontend/src/styles/test.scss b/frontend/src/styles/test.scss
index f40c28dfd..5936e82af 100644
--- a/frontend/src/styles/test.scss
+++ b/frontend/src/styles/test.scss
@@ -400,14 +400,10 @@
outline: none;
display: block;
resize: none;
- position: fixed;
+ position: absolute;
z-index: -1;
cursor: default;
pointer-events: none;
- margin-left: 1rem;
- // left: 50%;
- // top: 50%;
- // transform: translate(-50%, -50%);
}
#capsWarning {
@@ -508,22 +504,9 @@
place-content: center center;
}
.box:nth-child(1) {
- background: var(--colorful-error-color);
border-radius: var(--roundness) 0 0 var(--roundness);
}
- .box:nth-child(2) {
- background: var(--colorful-error-color);
- filter: opacity(0.6);
- }
- .box:nth-child(3) {
- background: var(--sub-color);
- }
- .box:nth-child(4) {
- background: var(--main-color);
- filter: opacity(0.6);
- }
.box:nth-child(5) {
- background: var(--main-color);
border-radius: 0 var(--roundness) var(--roundness) 0;
}
}
@@ -550,25 +533,8 @@
letter.incorrect.extra {
color: var(--error-extra-color);
}
- &.unreached letter {
- filter: opacity(0.2);
- }
- &.heatmap0 letter {
- color: var(--colorful-error-color);
- }
- &.heatmap1 letter {
- color: var(--colorful-error-color);
- filter: opacity(0.6);
- }
- &.heatmap2 letter {
- color: var(--sub-color);
- }
- &.heatmap3 letter {
- color: var(--main-color);
- filter: opacity(0.6);
- }
- &.heatmap4 letter {
- color: var(--main-color);
+ &.heatmapInherit letter {
+ color: inherit;
}
}
&.rightToLeftTest {
diff --git a/frontend/src/ts/commandline/lists/font-size.ts b/frontend/src/ts/commandline/lists/font-size.ts
index aebef6f36..8190adc0d 100644
--- a/frontend/src/ts/commandline/lists/font-size.ts
+++ b/frontend/src/ts/commandline/lists/font-size.ts
@@ -1,5 +1,4 @@
import Config, * as UpdateConfig from "../../config";
-import * as TestUI from "../../test/test-ui";
const commands: MonkeyTypes.Command[] = [
{
@@ -13,9 +12,6 @@ const commands: MonkeyTypes.Command[] = [
exec: (input): void => {
if (!input) return;
UpdateConfig.setFontSize(parseFloat(input));
- setTimeout(() => {
- TestUI.updateWordsHeight();
- }, 0); //honestly no clue why it i need to wait for the next event loop to do this
},
},
];
diff --git a/frontend/src/ts/config.ts b/frontend/src/ts/config.ts
index 7854e1a61..9cfb5b3cc 100644
--- a/frontend/src/ts/config.ts
+++ b/frontend/src/ts/config.ts
@@ -1594,7 +1594,7 @@ export function setFontSize(fontSize: number, nosave?: boolean): boolean {
);
saveToLocalStorage("fontSize", nosave);
- ConfigEvent.dispatch("fontSize", config.fontSize);
+ ConfigEvent.dispatch("fontSize", config.fontSize, nosave);
// trigger a resize event to update the layout - handled in ui.ts:108
$(window).trigger("resize");
diff --git a/frontend/src/ts/controllers/chart-controller.ts b/frontend/src/ts/controllers/chart-controller.ts
index 70c3649ee..47074ed82 100644
--- a/frontend/src/ts/controllers/chart-controller.ts
+++ b/frontend/src/ts/controllers/chart-controller.ts
@@ -1,21 +1,32 @@
import {
- Chart,
BarController,
BarElement,
CategoryScale,
+ Chart,
Filler,
- LinearScale,
LineController,
LineElement,
+ LinearScale,
PointElement,
ScatterController,
TimeScale,
TimeSeriesScale,
Tooltip,
+ type AnimationSpec,
+ type CartesianScaleOptions,
+ type ChartConfiguration,
+ type ChartDataset,
+ type ChartType,
+ type DefaultDataPoint,
+ type PluginChartOptions,
+ type ScaleChartOptions,
} from "chart.js";
+import chartAnnotation, {
+ type AnnotationOptions,
+ type LabelOptions,
+} from "chartjs-plugin-annotation";
import chartTrendline from "chartjs-plugin-trendline";
-import chartAnnotation from "chartjs-plugin-annotation";
Chart.register(
BarController,
@@ -40,31 +51,13 @@ Chart.register(
Chart.defaults.elements.line.tension = 0.3;
Chart.defaults.elements.line.fill = "origin";
-import * as TestInput from "../test/test-input";
-import * as ThemeColors from "../elements/theme-colors";
-import * as Misc from "../utils/misc";
+import "chartjs-adapter-date-fns";
+import format from "date-fns/format";
import Config from "../config";
+import * as ThemeColors from "../elements/theme-colors";
import * as ConfigEvent from "../observables/config-event";
-import format from "date-fns/format";
-import "chartjs-adapter-date-fns";
-
-// eslint-disable-next-line no-duplicate-imports -- need to ignore because eslint doesnt know what import type is
-import type {
- AnimationSpec,
- CartesianScaleOptions,
- ChartConfiguration,
- ChartDataset,
- ChartType,
- DefaultDataPoint,
- PluginChartOptions,
- ScaleChartOptions,
-} from "chart.js";
-
-// eslint-disable-next-line no-duplicate-imports -- need to ignore because eslint doesnt know what import type is
-import type {
- AnnotationOptions,
- LabelOptions,
-} from "chartjs-plugin-annotation";
+import * as TestInput from "../test/test-input";
+import * as Misc from "../utils/misc";
class ChartWithUpdateColors<
TType extends ChartType = ChartType,
diff --git a/frontend/src/ts/elements/scroll-to-top.ts b/frontend/src/ts/elements/scroll-to-top.ts
index 715dd8922..0bd63ba0a 100644
--- a/frontend/src/ts/elements/scroll-to-top.ts
+++ b/frontend/src/ts/elements/scroll-to-top.ts
@@ -2,7 +2,7 @@ import * as ActivePage from "../states/active-page";
let visible = false;
-$(".scrollToTopButton").on("click", () => {
+$(document).on("click", ".scrollToTopButton", () => {
window.scrollTo({ top: 0, behavior: "smooth" });
});
diff --git a/frontend/src/ts/popups/result-tags-popup.ts b/frontend/src/ts/popups/result-tags-popup.ts
index 6ca053683..1b83b0b79 100644
--- a/frontend/src/ts/popups/result-tags-popup.ts
+++ b/frontend/src/ts/popups/result-tags-popup.ts
@@ -241,4 +241,11 @@ $("#resultEditTagsPanelWrapper .confirmButton").on("click", async () => {
}
});
+$(document).on("keydown", (event) => {
+ if (event.key === "Escape" && isPopupVisible(wrapperId)) {
+ hide();
+ event.preventDefault();
+ }
+});
+
Skeleton.save(wrapperId);
diff --git a/frontend/src/ts/settings/theme-picker.ts b/frontend/src/ts/settings/theme-picker.ts
index bd97d846d..8f8a4651c 100644
--- a/frontend/src/ts/settings/theme-picker.ts
+++ b/frontend/src/ts/settings/theme-picker.ts
@@ -280,12 +280,13 @@ function toggleFavourite(themeName: string): void {
export function saveCustomThemeColors(): void {
const newColors: string[] = [];
- $.each(
- $(".pageSettings .customTheme .customThemeEdit [type='color']"),
- (_index, element) => {
- newColors.push($(element).attr("value") as string);
- }
- );
+ for (const color of ThemeController.colorVars) {
+ newColors.push(
+ $(
+ `.pageSettings .customTheme .customThemeEdit #${color}[type='color']`
+ ).attr("value") as string
+ );
+ }
UpdateConfig.setCustomThemeColors(newColors);
Notifications.add("Custom theme saved", 1);
}
diff --git a/frontend/src/ts/test/practise-words.ts b/frontend/src/ts/test/practise-words.ts
index 5273eccd3..59217c18c 100644
--- a/frontend/src/ts/test/practise-words.ts
+++ b/frontend/src/ts/test/practise-words.ts
@@ -91,7 +91,7 @@ export function init(missed: boolean, slow: boolean): boolean {
const punctuation =
before.punctuation === null ? Config.punctuation : before.punctuation;
const numbers = before.numbers === null ? Config.numbers : before.numbers;
- UpdateConfig.setMode("custom");
+ UpdateConfig.setMode("custom", true);
CustomText.setText(newCustomText);
CustomText.setIsWordRandom(true);
diff --git a/frontend/src/ts/test/result.ts b/frontend/src/ts/test/result.ts
index 77faa7e8b..860b748e5 100644
--- a/frontend/src/ts/test/result.ts
+++ b/frontend/src/ts/test/result.ts
@@ -1,4 +1,8 @@
-import { Chart } from "chart.js";
+import {
+ Chart,
+ type PluginChartOptions,
+ type ScaleChartOptions,
+} from "chart.js";
import Config from "../config";
import * as AdController from "../controllers/ad-controller";
import * as ChartController from "../controllers/chart-controller";
@@ -22,8 +26,6 @@ import * as TestUI from "./test-ui";
import * as TodayTracker from "./today-tracker";
import confetti from "canvas-confetti";
-// eslint-disable-next-line no-duplicate-imports -- need to ignore because eslint doesnt know what import type is
-import type { PluginChartOptions, ScaleChartOptions } from "chart.js";
import type { AnnotationOptions } from "chartjs-plugin-annotation";
import Ape from "../ape";
diff --git a/frontend/src/ts/test/test-logic.ts b/frontend/src/ts/test/test-logic.ts
index 259141cad..a3cdde90b 100644
--- a/frontend/src/ts/test/test-logic.ts
+++ b/frontend/src/ts/test/test-logic.ts
@@ -177,7 +177,8 @@ export async function punctuateWord(
lastChar !== "," &&
lastChar !== "." &&
currentLanguage !== "russian" &&
- currentLanguage !== "ukrainian"
+ currentLanguage !== "ukrainian" &&
+ currentLanguage !== "slovak"
) {
word = `'${word}'`;
} else if (Math.random() < 0.012 && lastChar !== "," && lastChar !== ".") {
@@ -381,13 +382,6 @@ export function restart(options = {} as RestartOptions): void {
}
if (ActivePage.get() === "test" && !TestUI.resultVisible) {
if (!ManualRestart.get()) {
- if (
- TestWords.hasTab &&
- !options.event?.shiftKey &&
- Config.quickRestart !== "esc"
- ) {
- return;
- }
if (Config.mode !== "zen") event?.preventDefault();
if (
!Misc.canQuickRestart(
@@ -501,9 +495,9 @@ export function restart(options = {} as RestartOptions): void {
$("#restartTestButton").blur();
MemoryFunboxTimer.reset();
QuoteRatePopup.clearQuoteStats();
- if (ActivePage.get() === "test" && window.scrollY > 0) {
- window.scrollTo({ top: 0, behavior: "smooth" });
- }
+ // if (ActivePage.get() == "test" && window.scrollY > 0) {
+ // window.scrollTo({ top: 0, behavior: "smooth" });
+ // }
$("#wordsInput").val(" ");
TestUI.reset();
@@ -904,7 +898,12 @@ export async function init(): Promise<void> {
?.properties?.find((fp) => fp.startsWith("toPush:"));
if (funboxToPush) {
wordsBound = +funboxToPush.split(":")[1];
- if (Config.mode === "words" && Config.words < wordsBound) {
+ if (
+ (Config.mode === "words" && Config.words < wordsBound) ||
+ (Config.mode === "custom" &&
+ !CustomText.isTimeRandom &&
+ CustomText.word < wordsBound)
+ ) {
wordsBound = Config.words;
}
} else if (Config.showAllLines) {
diff --git a/frontend/src/ts/test/test-ui.ts b/frontend/src/ts/test/test-ui.ts
index 0c39649b1..0f6cce4f8 100644
--- a/frontend/src/ts/test/test-ui.ts
+++ b/frontend/src/ts/test/test-ui.ts
@@ -42,13 +42,17 @@ const debouncedZipfCheck = debounce(250, () => {
});
});
-ConfigEvent.subscribe((eventKey, eventValue) => {
+ConfigEvent.subscribe((eventKey, eventValue, nosave) => {
if (
(eventKey === "language" || eventKey === "funbox") &&
(eventValue as string).split("#").includes("zipf")
) {
debouncedZipfCheck();
}
+ if (eventKey === "fontSize" && !nosave) {
+ updateWordsHeight(true);
+ updateWordsInputPosition(true);
+ }
if (eventValue === undefined || typeof eventValue !== "boolean") return;
if (eventKey === "flipTestColors") flipColors(eventValue);
@@ -106,7 +110,10 @@ export function focusWords(): void {
}
}
-export function updateActiveElement(backspace?: boolean): void {
+export function updateActiveElement(
+ backspace?: boolean,
+ initial = false
+): void {
const active = document.querySelector("#words .active");
if (Config.mode === "zen" && backspace) {
active?.remove();
@@ -131,6 +138,9 @@ export function updateActiveElement(backspace?: boolean): void {
});
}
} catch (e) {}
+ if (!initial && shouldUpdateWordsInputPosition()) {
+ updateWordsInputPosition();
+ }
}
function getWordHTML(word: string): string {
@@ -187,10 +197,75 @@ export function showWords(): void {
$("#words").html(wordsHTML);
- updateWordsHeight();
+ updateActiveElement(undefined, true);
+ updateWordsHeight(true);
+ updateWordsInputPosition(true);
+}
+
+const posUpdateLangList = ["japanese", "chinese", "korean"];
+function shouldUpdateWordsInputPosition(): boolean {
+ const language = posUpdateLangList.some((l) => Config.language.startsWith(l));
+ return language || (Config.mode !== "time" && Config.showAllLines);
+}
+
+export function updateWordsInputPosition(initial = false): void {
+ if (Config.tapeMode !== "off" && !initial) return;
+ const el = document.querySelector("#wordsInput") as HTMLElement;
+ const activeWord = document.querySelector(
+ "#words .active"
+ ) as HTMLElement | null;
+
+ if (!activeWord) {
+ el.style.top = "0px";
+ el.style.left = "0px";
+ return;
+ }
+
+ const computed = window.getComputedStyle(activeWord);
+ const activeWordMargin =
+ parseInt(computed.marginTop) + parseInt(computed.marginBottom);
+
+ const wordsWrapperTop =
+ (document.querySelector("#wordsWrapper") as HTMLElement | null)
+ ?.offsetTop || 0;
+
+ if (Config.tapeMode !== "off") {
+ el.style.top =
+ wordsWrapperTop +
+ activeWord.offsetHeight +
+ activeWordMargin * 0.25 +
+ -el.offsetHeight +
+ "px";
+ el.style.left = activeWord.offsetLeft + "px";
+ return;
+ }
+
+ if (
+ initial &&
+ !posUpdateLangList.some((l) => Config.language.startsWith(l))
+ ) {
+ el.style.left = "0px";
+ el.style.top =
+ wordsWrapperTop +
+ activeWord.offsetHeight * 2 +
+ activeWordMargin * 1.5 +
+ -el.offsetHeight +
+ "px";
+ } else {
+ el.style.left = activeWord.offsetLeft + "px";
+ el.style.top =
+ activeWord.offsetTop -
+ activeWordMargin +
+ wordsWrapperTop +
+ activeWord.offsetHeight +
+ activeWordMargin +
+ -el.offsetHeight +
+ "px";
+ }
}
-export function updateWordsHeight(): void {
+function updateWordsHeight(force = false): void {
+ if (!force && Config.mode !== "custom") return;
$("#wordsWrapper").removeClass("hidden");
const wordHeight = <number>(
$(<Element>document.querySelector(".word")).outerHeight(true)
@@ -218,36 +293,62 @@ export function updateWordsHeight(): void {
}
$(".outOfFocusWarning").css("line-height", nh + "px");
} else {
+ let finalWordsHeight: number, finalWrapperHeight: number;
+
if (Config.tapeMode !== "off") {
- const wrapperHeight = wordHeight;
+ finalWordsHeight = wordHeight * 2;
+ finalWrapperHeight = wordHeight;
+ } else {
+ let lines = 0;
+ let lastHeight = 0;
+ let wordIndex = 0;
+ const words = document.querySelectorAll("#words .word");
+ let wrapperHeight = 0;
+
+ const wordComputedStyle = window.getComputedStyle(words[0]);
+ const wordTopMargin = parseInt(wordComputedStyle.marginTop);
+ const wordBottomMargin = parseInt(wordComputedStyle.marginBottom);
+
+ while (lines < 3) {
+ const word = words[wordIndex] as HTMLElement | null;
+ if (!word) break;
+ const height = word.offsetTop;
+ if (height > lastHeight) {
+ lines++;
+ wrapperHeight += word.offsetHeight + wordTopMargin + wordBottomMargin;
+ lastHeight = height;
+ }
+ wordIndex++;
+ }
- $("#words")
- .css("height", wordHeight * 2 + "px")
- .css("overflow", "hidden")
- .css("width", "200%")
- .css("margin-left", "50%");
- $("#wordsWrapper")
- .css("height", wrapperHeight + "px")
- .css("overflow", "hidden");
- $(".outOfFocusWarning").css("line-height", wrapperHeight + "px");
+ if (lines < 3) wrapperHeight = wrapperHeight * (3 / lines);
+
+ const wordsHeight = (wrapperHeight / 3) * 4;
+
+ finalWordsHeight = wordsHeight;
+ finalWrapperHeight = wrapperHeight;
+ }
+
+ $("#words")
+ .css("height", finalWordsHeight + "px")
+ .css("overflow", "hidden");
+
+ if (Config.tapeMode !== "off") {
+ $("#words").css("width", "200%").css("margin-left", "50%");
} else {
- $("#words")
- .css("height", wordHeight * 4 + "px")
- .css("overflow", "hidden")
- .css("width", "100%")
- .css("margin-left", "unset");
- $("#wordsWrapper")
- .css("height", wordHeight * 3 + "px")
- .css("overflow", "hidden");
- $(".outOfFocusWarning").css("line-height", wordHeight * 3 + "px");
+ $("#words").css("width", "100%").css("margin-left", "unset");
}
+
+ $("#wordsWrapper")
+ .css("height", finalWrapperHeight + "px")
+ .css("overflow", "hidden");
+ $(".outOfFocusWarning").css("line-height", finalWrapperHeight + "px");
}
if (Config.mode === "zen") {
$(<Element>document.querySelector(".word")).remove();
}
- updateActiveElement();
Caret.updatePosition();
}
@@ -280,9 +381,9 @@ export async function screenshot(): Promise<void> {
}
function revertScreenshot(): void {
- // $("#testConfig").removeClass("invisible");
$("#ad-result-wrapper").removeClass("hidden");
$("#ad-result-small-wrapper").removeClass("hidden");
+ $("#testConfig").removeClass("hidden");
$("#notificationCenter").removeClass("hidden");
$("#commandLineMobileButton").removeClass("hidden");
$(".pageTest .ssWatermark").addClass("hidden");
@@ -295,6 +396,8 @@ export async function screenshot(): Promise<void> {
if (!Auth?.currentUser) {
$(".pageTest .loginTip").removeClass("hidden");
}
+ (document.querySelector("html") as HTMLElement).style.scrollBehavior =
+ "smooth";
}
if (!$("#resultReplay").hasClass("hidden")) {
@@ -316,7 +419,6 @@ export async function screenshot(): Promise<void> {
);
}
$(".pageTest .buttons").addClass("hidden");
- // $("#testConfig").addClass("invisible");
$("#notificationCenter").addClass("hidden");
$("#commandLineMobileButton").addClass("hidden");
$(".pageTest .loginTip").addClass("hidden");
@@ -324,8 +426,13 @@ export async function screenshot(): Promise<void> {
$("#nocss").addClass("hidden");
$("#ad-result-wrapper").addClass("hidden");
$("#ad-result-small-wrapper").addClass("hidden");
+ $("#testConfig").addClass("hidden");
if (revertCookie) $("#cookiePopupWrapper").addClass("hidden");
+ (document.querySelector("html") as HTMLElement).style.scrollBehavior = "auto";
+ window.scrollTo({
+ top: 0,
+ });
const src = $("#result");
const sourceX = src.offset()?.left ?? 0; /*X position from div#target*/
const sourceY = src.offset()?.top ?? 0; /*Y position from div#target*/
@@ -711,6 +818,7 @@ export function lineJump(currentTop: number): void {
}
}
currentTestLine++;
+ updateWordsHeight();
}
export function arrangeCharactersRightToLeft(): void {
@@ -909,7 +1017,7 @@ export function toggleResultWords(): void {
}
}
-export function applyBurstHeatmap(): void {
+export async function applyBurstHeatmap(): Promise<void> {
if (Config.burstHeatmap) {
$("#resultWordsHistory .heatmapLegend").removeClass("hidden");
@@ -931,26 +1039,53 @@ export function applyBurstHeatmap(): void {
adatm.push(Math.abs(median - burst));
});
const step = Misc.mean(adatm);
+
+ const themeColors = await ThemeColors.getAll();
+
+ let colors = [
+ themeColors.colorfulError,
+ Misc.blendTwoHexColors(themeColors.colorfulError, themeColors.text, 0.5),
+ themeColors.text,
+ Misc.blendTwoHexColors(themeColors.main, themeColors.text, 0.5),
+ themeColors.main,
+ ];
+ let unreachedColor = themeColors.sub;
+
+ if (themeColors.main === themeColors.text) {
+ colors = [
+ themeColors.colorfulError,
+ Misc.blendTwoHexColors(
+ themeColors.colorfulError,
+ themeColors.text,
+ 0.5
+ ),
+ themeColors.sub,
+ Misc.blendTwoHexColors(themeColors.sub, themeColors.text, 0.5),
+ themeColors.main,
+ ];
+ unreachedColor = themeColors.subAlt;
+ }
+
const steps = [
{
val: 0,
- class: "heatmap0",
+ colorId: 0,
},
{
val: median - step * 1.5,
- class: "heatmap1",
+ colorId: 1,
},
{
val: median - step * 0.5,
- class: "heatmap2",
+ colorId: 2,
},
{
val: median + step * 0.5,
- class: "heatmap3",
+ colorId: 3,
},
{
val: median + step * 1.5,
- class: "heatmap4",
+ colorId: 4,
},
];
@@ -972,26 +1107,29 @@ export function applyBurstHeatmap(): void {
});
$("#resultWordsHistory .words .word").each((_, word) => {
- let cls = "";
const wordBurstAttr = $(word).attr("burst");
if (wordBurstAttr === undefined) {
- cls = "unreached";
+ $(word).css("color", unreachedColor);
} else {
const wordBurstVal = parseInt(<string>wordBurstAttr);
steps.forEach((step) => {
- if (wordBurstVal >= step.val) cls = step.class;
+ if (wordBurstVal >= step.val) {
+ $(word).addClass("heatmapInherit");
+ $(word).css("color", colors[step.colorId]);
+ }
});
}
- $(word).addClass(cls);
+ });
+
+ $("#resultWordsHistory .heatmapLegend .boxes .box").each((index, box) => {
+ $(box).css("background", colors[index]);
});
} else {
$("#resultWordsHistory .heatmapLegend").addClass("hidden");
- $("#resultWordsHistory .words .word").removeClass("heatmap0");
- $("#resultWordsHistory .words .word").removeClass("heatmap1");
- $("#resultWordsHistory .words .word").removeClass("heatmap2");
- $("#resultWordsHistory .words .word").removeClass("heatmap3");
- $("#resultWordsHistory .words .word").removeClass("heatmap4");
- $("#resultWordsHistory .words .word").removeClass("unreached");
+ $("#resultWordsHistory .words .word").removeClass("heatmapInherit");
+ $("#resultWordsHistory .words .word").css("color", "");
+
+ $("#resultWordsHistory .heatmapLegend .boxes .box").css("color", "");
}
}
diff --git a/frontend/src/ts/ui.ts b/frontend/src/ts/ui.ts
index 589d437e0..8abf9c5b4 100644
--- a/frontend/src/ts/ui.ts
+++ b/frontend/src/ts/ui.ts
@@ -93,13 +93,16 @@ const debouncedEvent = debounce(250, async () => {
document.querySelectorAll<HTMLElement>("#words .word")[
TestUI.currentWordElementIndex - 1
];
- if (!word) return;
- const currentTop: number = Math.floor(word.offsetTop);
- TestUI.lineJump(currentTop);
+ if (word) {
+ const currentTop: number = Math.floor(word.offsetTop);
+ TestUI.lineJump(currentTop);
+ }
}
}
setTimeout(() => {
- Caret.show();
+ if ($("#wordsInput").is(":focus")) {
+ Caret.show();
+ }
}, 250);
});
diff --git a/frontend/src/ts/utils/misc.ts b/frontend/src/ts/utils/misc.ts
index eb796bd0c..b66fe5662 100644
--- a/frontend/src/ts/utils/misc.ts
+++ b/frontend/src/ts/utils/misc.ts
@@ -1,4 +1,5 @@
import * as Loader from "../elements/loader";
+import { normal as normalBlend } from "color-blend";
async function fetchJson<T>(url: string): Promise<T> {
try {
@@ -235,6 +236,65 @@ export async function getContributorsList(): Promise<string[]> {
}
}
+export function blendTwoHexColors(
+ color1: string,
+ color2: string,
+ opacity: number
+): string {
+ const rgb1 = hexToRgb(color1);
+ const rgb2 = hexToRgb(color2);
+
+ if (rgb1 && rgb2) {
+ const rgba1 = {
+ r: rgb1.r,
+ g: rgb1.g,
+ b: rgb1.b,
+ a: 1,
+ };
+ const rgba2 = {
+ r: rgb2.r,
+ g: rgb2.g,
+ b: rgb2.b,
+ a: opacity,
+ };
+ const blended = normalBlend(rgba1, rgba2);
+ return rgbToHex(blended.r, blended.g, blended.b);
+ } else {
+ return "#000000";
+ }
+}
+
+function hexToRgb(hex: string):
+ | {
+ r: number;
+ g: number;
+ b: number;
+ }
+ | undefined {
+ if (hex.length != 4 && hex.length != 7 && !hex.startsWith("#")) {
+ return undefined;
+ }
+ let r: number;
+ let g: number;
+ let b: number;
+ if (hex.length == 4) {
+ r = ("0x" + hex[1] + hex[1]) as unknown as number;
+ g = ("0x" + hex[2] + hex[2]) as unknown as number;
+ b = ("0x" + hex[3] + hex[3]) as unknown as number;
+ } else if (hex.length == 7) {
+ r = ("0x" + hex[1] + hex[2]) as unknown as number;
+ g = ("0x" + hex[3] + hex[4]) as unknown as number;
+ b = ("0x" + hex[5] + hex[6]) as unknown as number;
+ } else {
+ return undefined;
+ }
+ return { r, g, b };
+}
+
+function rgbToHex(r: number, g: number, b: number): string {
+ return "#" + ((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1);
+}
+
function hexToHSL(hex: string): {
hue: number;
sat: number;
diff --git a/frontend/static/html/pages/settings.html b/frontend/static/html/pages/settings.html
index 8c5323749..132c4c34b 100644
--- a/frontend/static/html/pages/settings.html
+++ b/frontend/static/html/pages/settings.html
@@ -2151,40 +2151,47 @@
id="--bg-color"
/>
</div>
- <label class="colorText">main</label>
+ <label class="colorText">sub alt</label>
<div class="colorPicker inputAndButton">
<input
type="text"
value="#000000"
class="input"
- id="--main-color-txt"
+ id="--sub-alt-color-txt"
/>
- <label for="--main-color" class="button">
+ <label
+ for="--sub-alt-color"
+ class="button"
+ style="
+ color: var(--text-color);
+ background: var(--sub-alt-color);
+ "
+ >
<i class="fas fa-fw fa-palette"></i>
</label>
<input
type="color"
class="color"
value="#000000"
- id="--main-color"
+ id="--sub-alt-color"
/>
</div>
- <label class="colorText">caret</label>
+ <label class="colorText">main</label>
<div class="colorPicker inputAndButton">
<input
type="text"
value="#000000"
class="input"
- id="--caret-color-txt"
+ id="--main-color-txt"
/>
- <label for="--caret-color" class="button">
+ <label for="--main-color" class="button">
<i class="fas fa-fw fa-palette"></i>
</label>
<input
type="color"
class="color"
value="#000000"
- id="--caret-color"
+ id="--main-color"
/>
</div>
<label class="colorText">sub</label>
@@ -2205,22 +2212,22 @@
id="--sub-color"
/>
</div>
- <label class="colorText">sub alt</label>
+ <label class="colorText">caret</label>
<div class="colorPicker inputAndButton">
<input
type="text"
value="#000000"
class="input"
- id="--sub-alt-color-txt"
+ id="--caret-color-txt"
/>
- <label for="--sub-alt-color" class="button">
+ <label for="--caret-color" class="button">
<i class="fas fa-fw fa-palette"></i>
</label>
<input
type="color"
class="color"
value="#000000"
- id="--sub-alt-color"
+ id="--caret-color"
/>
</div>
<label class="colorText">text</label>
diff --git a/frontend/static/html/pages/test.html b/frontend/static/html/pages/test.html
index b3a2e33a1..17bfe952b 100644
--- a/frontend/static/html/pages/test.html
+++ b/frontend/static/html/pages/test.html
@@ -100,19 +100,6 @@
</div>
<div id="memoryTimer">Time left to memorise all words: 0s</div>
<div id="testModesNotice"></div>
- <input
- id="wordsInput"
- class=""
- tabindex="0"
- type="text"
- autocomplete="off"
- autocapitalize="off"
- autocorrect="off"
- data-gramm="false"
- data-gramm_editor="false"
- data-enable-grammarly="false"
- list="autocompleteOff"
- />
<div id="timerNumber" class="timerMain">
<div>60</div>
</div>
@@ -126,6 +113,19 @@
<i class="fas fa-mouse-pointer"></i>
Click here or start typing to focus
</div>
+ <input
+ id="wordsInput"
+ class=""
+ tabindex="0"
+ type="text"
+ autocomplete="off"
+ autocapitalize="off"
+ autocorrect="off"
+ data-gramm="false"
+ data-gramm_editor="false"
+ data-enable-grammarly="false"
+ list="autocompleteOff"
+ />
<div id="wordsWrapper" translate="no">
<div id="paceCaret" class="default hidden"></div>
<div id="caret" class="default"></div>
diff --git a/frontend/static/languages/code_lua.json b/frontend/static/languages/code_lua.json
index 5a91bc32b..fc5dc134e 100644
--- a/frontend/static/languages/code_lua.json
+++ b/frontend/static/languages/code_lua.json
@@ -24,7 +24,6 @@
"true",
"until",
"while",
-
"assert",
"collectgarbage",
"dofile",
@@ -47,6 +46,7 @@
"rawset",
"require",
"select",
+ "self",
"setfenv",
"setmetatable",
"tonumber",
diff --git a/frontend/static/languages/code_luau.json b/frontend/static/languages/code_luau.json
index c3f71d620..c36864c28 100644
--- a/frontend/static/languages/code_luau.json
+++ b/frontend/static/languages/code_luau.json
@@ -7,6 +7,7 @@
"break",
"do",
"else",
+ "self",
"elseif",
"end",
"false",
@@ -24,13 +25,10 @@
"true",
"until",
"while",
-
"export",
"typeof",
"continue",
-
"assert",
- "collectgarbage",
"error",
"gcinfo",
"getfenv",
@@ -54,7 +52,6 @@
"type",
"unpack",
"xpcall",
-
"wait",
"delay",
"elapsedTime",
@@ -69,7 +66,6 @@
"usersettings",
"version",
"warn",
-
"bit32",
"coroutine",
"debug",
diff --git a/frontend/static/languages/english_10k.json b/frontend/static/languages/english_10k.json
index 934f5d61e..1f0ed2413 100644
--- a/frontend/static/languages/english_10k.json
+++ b/frontend/static/languages/english_10k.json
@@ -3999,7 +3999,6 @@
"pour",
"digest",
"lodging",
- "tion",
"dust",
"hence",
"entirely",
diff --git a/frontend/static/languages/russian_375k.json b/frontend/static/languages/russian_375k.json
index 14b1cb543..ed6e470ff 100644
--- a/frontend/static/languages/russian_375k.json
+++ b/frontend/static/languages/russian_375k.json
@@ -318,7 +318,6 @@
"абонентскую",
"абоненту",
"абоненты",
-
"абонетский",
"абонплата",
"абонплату",
@@ -1877,7 +1876,6 @@
"автомобилям",
"автомобилями",
"автомобилях",
-
"автомоек",
"автомойка",
"автомойке",
@@ -3195,7 +3193,6 @@
"адмиралы",
"адмиральского",
"адмонт",
-
"аднан",
"аднана",
"адоби",
@@ -3894,7 +3891,6 @@
"айтишных",
"айтюнс",
"айтюнсе",
-
"айфон",
"айфона",
"айфонам",
@@ -22663,7 +22659,6 @@
"благодушно",
"благодушные",
"благодушный",
-
"благое",
"благожелателей",
"благожелательно",
@@ -30199,7 +30194,6 @@
"бёртта",
"бёрч",
"бёёми",
-
"в",
"ва",
"ваагн",
@@ -31362,7 +31356,6 @@
"вартапетова",
"вартога",
"вартон",
-
"варум",
"варун",
"варуфакис",
@@ -35037,7 +35030,6 @@
"вжух",
"вза",
"взависимости",
-
"взад",
"взаимен",
"взаимная",
@@ -38851,7 +38843,6 @@
"владычицы",
"владэлектротранс",
"владэлектротранса",
-
"влажен",
"влажная",
"влажнее",
@@ -39401,7 +39392,6 @@
"вмятину",
"вмятины",
"вмёржены",
-
"внаглую",
"внаем",
"внакладе",
@@ -42307,7 +42297,6 @@
"волина",
"волински",
"волинского",
-
"волину",
"волиным",
"волк",
@@ -45362,7 +45351,6 @@
"времён",
"врет",
"врете",
-
"врешь",
"ври",
"вриеса",
@@ -46629,7 +46617,6 @@
"всячины",
"всё",
"всём",
-
"вт",
"вта",
"втайне",
@@ -53871,7 +53858,6 @@
"вёслами",
"вёслах",
"вёх",
-
"г",
"га",
"гаага",
@@ -56742,7 +56728,6 @@
"геннадия",
"геннадьевич",
"геннадьевича",
-
"геннаро",
"генная",
"генндий",
@@ -63155,7 +63140,6 @@
"готэме",
"готэмом",
"готэму",
-
"гоу",
"гоув",
"гоупро",
@@ -65009,7 +64993,6 @@
"грошовые",
"грошовых",
"грошом",
-
"грп",
"грс",
"гру",
@@ -66612,7 +66595,6 @@
"гётеборгского",
"гёттингенского",
"гётце",
-
"д",
"да",
"дааа",
@@ -70645,7 +70627,6 @@
"делёз",
"делёза",
"делённая",
-
"демагог",
"демагоги",
"демагогией",
@@ -71401,7 +71382,6 @@
"депутатство",
"депутату",
"депутаты",
-
"дер",
"дераа",
"дерба",
@@ -72652,7 +72632,6 @@
"деэскалация",
"дея",
"деяк",
-
"деян",
"деяна",
"деяние",
@@ -73701,7 +73680,6 @@
"дзамбротта",
"дзантиев",
"дзвинка",
-
"дзекон",
"дзекона",
"дземброне",
@@ -74265,7 +74243,6 @@
"дизайнерскую",
"дизайнеру",
"дизайнеры",
-
"дизайнить",
"дизайнов",
"дизайном",
@@ -76129,7 +76106,6 @@
"дняо",
"днях",
"днём",
-
"до",
"доан",
"доб",
@@ -77111,7 +77087,6 @@
"додавить",
"додарвиновский",
"додарвиновского",
-
"додд",
"додда",
"доде",
@@ -77638,7 +77613,6 @@
"докладной",
"докладную",
"докладные",
-
"докладов",
"докладом",
"докладу",
@@ -78559,7 +78533,6 @@
"донбассу",
"донбассэнерго",
"донбасу",
-
"донвудом",
"донг",
"донга",
@@ -79450,7 +79423,6 @@
"досанкционный",
"досанкционных",
"досветку",
-
"доселе",
"досецу",
"досидел",
@@ -82801,7 +82773,6 @@
"дёшева",
"дёшево",
"дёшевы",
-
"е",
"еа",
"еабр",
@@ -83790,9 +83761,7 @@
"елеазарова",
"елеем",
"елей",
-
"електронного",
-
"електротранспорт",
"елена",
"елене",
@@ -89198,7 +89167,6 @@
"задачник",
"задачником",
"задачу",
-
"задашься",
"задаю",
"задаюсь",
@@ -97259,7 +97227,6 @@
"затребованные",
"затребованных",
"затребовать",
-
"затрется",
"затрещину",
"затрещины",
@@ -99199,7 +99166,6 @@
"здрадовский",
"здрасте",
"здрасьте",
-
"зе",
"зеаксантин",
"зеаксантина",
@@ -99562,7 +99528,6 @@
"землячка",
"землячку",
"землёй",
-
"земмельвайс",
"земмельвайса",
"земмеринг",
@@ -100621,7 +100586,6 @@
"знойным",
"зноя",
"зноў",
-
"зо",
"зоба",
"зобнина",
@@ -100636,7 +100600,6 @@
"зови",
"зовите",
"зовом",
-
"зову",
"зовут",
"зовутся",
@@ -101391,7 +101354,6 @@
"зёрнышек",
"зёрнышко",
"зёрнышку",
-
"и",
"иа",
"иааф",
@@ -114917,7 +114879,6 @@
"капюшонов",
"капюшоном",
"капюшоны",
-
"кар",
"кара",
"карабаев",
@@ -117954,7 +117915,6 @@
"квят",
"квята",
"квятковский",
-
"кг",
"кгб",
"кгбшник",
@@ -120593,7 +120553,6 @@
"киянка",
"кияшко",
"киёси",
-
"київ",
"київстар",
"київська",
@@ -122018,7 +121977,6 @@
"клёпки",
"клёсов",
"клёсова",
-
"км",
"кма",
"кмв",
@@ -125244,7 +125202,6 @@
"компаньоном",
"компаньону",
"компаньоны",
-
"компаративистами",
"компаративистике",
"компаративистики",
@@ -127714,7 +127671,6 @@
"конференциям",
"конференциями",
"конференциях",
-
"конферренции",
"конфессией",
"конфессии",
@@ -131161,7 +131117,6 @@
"кошмарят",
"кошта",
"кошти",
-
"кошута",
"кощеевна",
"кощей",
@@ -134466,7 +134421,6 @@
"крёстного",
"крёстному",
"крёстный",
-
"кс",
"кса",
"ксавье",
@@ -136948,7 +136902,6 @@
"кёртина",
"кёртис",
"кёртиса",
-
"л",
"ла",
"лаад",
@@ -139794,7 +139747,6 @@
"леонхардта",
"леонхардтом",
"леонхардту",
-
"леопард",
"леопарда",
"леопардам",
@@ -140650,7 +140602,6 @@
"либсет",
"либу",
"либы",
-
"лив",
"лива",
"ливадии",
@@ -144557,7 +144508,6 @@
"львовяне",
"львовянин",
"львовянина",
-
"львом",
"льву",
"львы",
@@ -144565,7 +144515,6 @@
"львята",
"львятник",
"львёнка",
-
"льгот",
"льгота",
"льготам",
@@ -145462,7 +145411,6 @@
"лёха",
"лёхе",
"лёша",
-
"м",
"ма",
"маа",
@@ -153168,7 +153116,6 @@
"меняющуюся",
"меняя",
"меняясь",
-
"мео",
"меола",
"мер",
@@ -153195,7 +153142,6 @@
"мережах",
"мережко",
"мережковский",
-
"мерей",
"мерен",
"мерена",
@@ -157808,7 +157754,6 @@
"ммс",
"ммси",
"ммц",
-
"мн",
"мнацеканов",
"мнб",
@@ -158729,7 +158674,6 @@
"мобулы",
"мобуту",
"мобы",
-
"мова",
"мове",
"моветон",
@@ -159245,7 +159189,6 @@
"можжевельником",
"можин",
"можливо",
-
"можна",
"можно",
"можной",
@@ -161227,7 +161170,6 @@
"москалькову",
"москаля",
"москалям",
-
"москапстрой",
"москапстроя",
"москва",
@@ -162149,7 +162091,6 @@
"мруэ",
"мрц",
"мрэо",
-
"мс",
"мсб",
"мсвати",
@@ -164459,7 +164400,6 @@
"мёрфи",
"мёста",
"мёсты",
-
"н",
"на",
"наааааамного",
@@ -165340,7 +165280,6 @@
"навязывая",
"навёл",
"навёрстывать",
-
"нага",
"нагадала",
"нагадил",
@@ -166946,7 +166885,6 @@
"наихудшим",
"наихудших",
"най",
-
"найгард",
"найгарда",
"найговзиной",
@@ -172463,7 +172401,6 @@
"нашумела",
"нашёл",
"нашёлся",
-
"нащальника",
"нащелкать",
"нащупав",
@@ -177455,7 +177392,6 @@
"необходимым",
"необходимыми",
"необходимых",
-
"необщего",
"необщительные",
"необъединимое",
@@ -181451,7 +181387,6 @@
"нетарифного",
"нетарифные",
"нетарифных",
-
"нетассист",
"нетбук",
"нетбука",
@@ -184727,7 +184662,6 @@
"новых",
"новь",
"новёхоньким",
-
"ног",
"нога",
"ногам",
@@ -186393,7 +186327,6 @@
"нёс",
"нёстлингер",
"нётер",
-
"нѣсколько",
"н•м",
"н∙м",
@@ -192454,7 +192387,6 @@
"обёрткой",
"обёртку",
"обёрточную",
-
"ов",
"овайн",
"овакимян",
@@ -193886,7 +193818,6 @@
"одноквантовой",
"одноквантовым",
"однокилевым",
-
"одноклассник",
"одноклассника",
"одноклассникам",
@@ -196044,7 +195975,6 @@
"окрыляет",
"окрылённая",
"окрылённые",
-
"оксазол",
"оксана",
"оксане",
@@ -196400,7 +196330,6 @@
"олекас",
"олекминская",
"олександр",
-
"олене",
"оленев",
"оленевод",
@@ -197327,7 +197256,6 @@
"операторскую",
"оператору",
"операторы",
-
"операх",
"операцией",
"операции",
@@ -199411,7 +199339,6 @@
"органотипические",
"органу",
"органы",
-
"оргбюро",
"оргвыводов",
"оргвыводы",
@@ -200860,7 +200787,6 @@
"оскудение",
"оскудением",
"оскудения",
-
"осла",
"ослаб",
"ослабев",
@@ -201755,7 +201681,6 @@
"останкинскую",
"останков",
"останкову",
-
"останов",
"останова",
"останови",
@@ -223151,7 +223076,6 @@
"платёжным",
"платёжными",
"платёжных",
-
"плауновидных",
"плафон",
"плафона",
@@ -225131,7 +225055,6 @@
"повнимательней",
"повнич",
"повнушительнее",
-
"повод",
"повода",
"поводам",
@@ -231244,7 +231167,6 @@
"подэтапов",
"подэтапы",
"подёнщики",
-
"поебени",
"поебень",
"поеботины",
@@ -232010,7 +231932,6 @@
"позициям",
"позициями",
"позициях",
-
"позлить",
"позлорадствовать",
"познавали",
@@ -238499,7 +238420,6 @@
"портфелям",
"портфелях",
"портфолио",
-
"порты",
"портье",
"портьеры",
@@ -241399,7 +241319,6 @@
"потрёпанным",
"потрёпанных",
"потрёпаны",
-
"потсдама",
"потсдаме",
"потсдамского",
@@ -241520,7 +241439,6 @@
"потёртостей",
"потёртости",
"потёртый",
-
"поубавилось",
"поубавится",
"поубавить",
@@ -243467,7 +243385,6 @@
"прахом",
"праху",
"працювати",
-
"прачек",
"прачета",
"прачетт",
@@ -245758,7 +245675,6 @@
"презентациям",
"презентациями",
"презентациях",
-
"презентов",
"презентовав",
"презентовавшая",
@@ -248379,7 +248295,6 @@
"привязь",
"привёз",
"привёл",
-
"пригасил",
"пригашаем",
"пригвозди",
@@ -256096,7 +256011,6 @@
"проекторы",
"проекту",
"проекты",
-
"проекцией",
"проекции",
"проекций",
@@ -259212,7 +259126,6 @@
"просвистела",
"просвистели",
"просвистит",
-
"просевшей",
"просевшие",
"просевший",
@@ -265062,7 +264975,6 @@
"пёстрых",
"пётр",
"пётра",
-
"р",
"ра",
"рааг",
@@ -270893,7 +270805,6 @@
"разьем",
"разьемы",
"разьём",
-
"раи",
"раид",
"раиль",
@@ -276187,7 +276098,6 @@
"реанимируют",
"реанимобиле",
"реанимобиль",
-
"реассортации",
"реассортаций",
"реации",
@@ -276468,7 +276378,6 @@
"революциям",
"революциями",
"революциях",
-
"ревом",
"ревонсуо",
"ревоя",
@@ -281211,7 +281120,6 @@
"роботят",
"роботята",
"роботятам",
-
"робофабрика",
"робофест",
"робофеста",
@@ -281985,11 +281893,9 @@
"розрахункових",
"розробка",
"розробляли",
-
"розтех",
"розу",
"розумна",
-
"розуэлле",
"розы",
"розыгрыш",
@@ -282112,7 +282018,6 @@
"рокфеллеры",
"рокфор",
"рокфора",
-
"ролан",
"ролана",
"роланд",
@@ -284293,7 +284198,6 @@
"русскоязычными",
"русскоязычных",
"русскую",
-
"руссланд",
"русснефти",
"русснефть",
@@ -285267,7 +285171,6 @@
"рёске",
"рёсуке",
"рѕс‚",
-
"с",
"са",
"саабы",
@@ -285275,7 +285178,6 @@
"саади",
"саак",
"саакашвили",
-
"саакян",
"саакяна",
"саакянца",
@@ -286905,11 +286807,9 @@
"самопознания",
"самополива",
"самопомич",
-
"самопомощи",
"самопомощь",
"самопомощью",
-
"самопощь",
"самопрезентации",
"самопрезентация",
@@ -291025,7 +290925,6 @@
"свёртываемость",
"свёртывание",
"свёртывания",
-
"сг",
"сгау",
"сгенерировав",
@@ -292710,7 +292609,6 @@
"селфшоте",
"селфшотов",
"селфшоты",
-
"сель",
"сельберг",
"сельва",
@@ -293612,7 +293510,6 @@
"сергунин",
"сергунина",
"сергуниной",
-
"серда",
"сердар",
"сердацков",
@@ -294150,7 +294047,6 @@
"серёжки",
"серёжкой",
"серёня",
-
"сесамовидной",
"сесар",
"сесеньи",
@@ -296479,7 +296375,6 @@
"ситуациям",
"ситуациями",
"ситуациях",
-
"ситуейшн",
"ситуция",
"ситуэлл",
@@ -299172,7 +299067,6 @@
"скфо",
"скьямма",
"скэнлан",
-
"сл",
"сла",
"слаб",
@@ -302031,7 +301925,6 @@
"смятым",
"смятых",
"смять",
-
"сн",
"сна",
"снаббер",
@@ -307882,7 +307775,6 @@
"соцтруда",
"соцфак",
"соццани",
-
"соч",
"сочатся",
"сочащихся",
@@ -309175,7 +309067,6 @@
"спецэффектах",
"спецэффектов",
"спецэффекты",
-
"спеченного",
"спеша",
"спешат",
@@ -310125,7 +310016,6 @@
"способствуя",
"способу",
"способы",
-
"спот",
"спота",
"спотах",
@@ -310172,7 +310062,6 @@
"спп",
"сппк",
"справа",
-
"справедлив",
"справедлива",
"справедливая",
@@ -318430,7 +318319,6 @@
"суспензий",
"суспензию",
"суспензия",
-
"сусс",
"суссе",
"суссекс",
@@ -318873,7 +318761,6 @@
"сферу",
"сферулы",
"сферы",
-
"сфи",
"сфигмографии",
"сфинкс",
@@ -319262,7 +319149,6 @@
"сху",
"схунартса",
"схуя",
-
"сц",
"сцвм",
"сцеживайтесь",
@@ -320140,7 +320026,6 @@
"сьерва",
"сьервы",
"сьерра",
-
"сьоландер",
"сьон",
"сьонзье",
@@ -320503,7 +320388,6 @@
"сёстрами",
"сёстрах",
"сёстры",
-
"та",
"таааак",
"тааак",
@@ -321302,7 +321186,6 @@
"такэда",
"такэси",
"такэути",
-
"так-то",
"тал",
"тала",
@@ -322798,7 +322681,6 @@
"твёрже",
"твёрк",
"твёркинга",
-
"тга",
"тгб",
"тгв",
@@ -325745,7 +325627,6 @@
"технологиях",
"технологов",
"технологом",
-
"технолоджи",
"техномагия",
"техномарафон",
@@ -334490,7 +334371,6 @@
"тёщей",
"тёщи",
"тёщу",
-
"т′чалла",
"у",
"уа",
@@ -338534,9 +338414,7 @@
"україни",
"українська",
"український",
-
"україну",
-
"укргазбанк",
"укргазбанке",
"укргаздобыча",
@@ -338625,7 +338503,6 @@
"укрзализныце",
"укрзализныци",
"укрзализныця",
-
"укринтеринвест",
"укринтерэнерго",
"укринформ",
@@ -342903,7 +342780,6 @@
"успокойтесь",
"успокою",
"успокоятся",
-
"усрачки",
"усреднение",
"усреднением",
@@ -343689,7 +343565,6 @@
"усядется",
"усядутся",
"усё",
-
"ут",
"утаивает",
"утаивали",
@@ -347573,7 +347448,6 @@
"ферхульст",
"ферье",
"ферьян",
-
"фес",
"фесе",
"фесенко",
@@ -352509,7 +352383,6 @@
"фёрт",
"фёрта",
"фёртом",
-
"х",
"ха",
"хааке",
@@ -356650,7 +356523,6 @@
"хотя",
"хотябы",
"хотят",
-
"хоу",
"хоуг",
"хоуга",
@@ -357393,7 +357265,6 @@
"худайнатову",
"худайнатовым",
"худая",
-
"худдинге",
"худее",
"худеет",
@@ -357939,7 +357810,6 @@
"хёрста",
"хёрш",
"хёршем",
-
"ц",
"ца",
"цаава",
@@ -360085,7 +359955,6 @@
"цяо",
"цяпа",
"цёльнера",
-
"ч",
"ча",
"чаадаев",
@@ -360544,7 +360413,6 @@
"частям",
"частями",
"частях",
-
"часу",
"часы",
"чат",
@@ -363103,7 +362971,6 @@
"чолитами",
"чолиты",
"чоллет",
-
"чолош",
"чомпу",
"чому",
@@ -375545,7 +375412,6 @@
"ютв",
"юте",
"ютейр",
-
"ютившиеся",
"ютилась",
"ютились",
@@ -376232,7 +376098,6 @@
"якх",
"якху",
"якщо",
-
"ялалов",
"ялалова",
"ялалову",
diff --git a/frontend/static/layouts/_list.json b/frontend/static/layouts/_list.json
index a5ba18901..72554b9ad 100644
--- a/frontend/static/layouts/_list.json
+++ b/frontend/static/layouts/_list.json
@@ -1349,7 +1349,7 @@
"row1": ["`~", "1!", "2@", "3#", "4$", "5%", "6^", "7&", "8*", "9(", "0)", "-_", "=+"],
"row2": ["bB", "lL", "dD", "cC", "vV", "zZ", "yY", "oO", "uU", ",<", "[{", "]}", "\\|"],
"row3": ["nN", "rR", "tT", "sS", "gG", "pP", "hH", "aA", "eE", "iI", "/?"],
- "row4": ["qQ", "xX", "mM", "wW", "jJ", "kK", "fF", "'\"", ";:", ",)"],
+ "row4": ["qQ", "xX", "mM", "wW", "jJ", "kK", "fF", "'\"", ";:", ".>"],
"row5": [" "]
}
},
@@ -1360,7 +1360,29 @@
"row1": ["`~", "1!", "2@", "3#", "4$", "5%", "6^", "7&", "8*", "9(", "0)", "-_", "=+"],
"row2": ["bB", "lL", "dD", "cC", "jJ", "zZ", "yY", "oO", "uU", ",<", "[{", "]}", "\\|"],
"row3": ["nN", "rR", "tT", "sS", "vV", "pP", "hH", "aA", "eE", "iI", "/?"],
- "row4": ["xX", "mM", "wW", "gG", "qQ", "kK", "fF", "'\"", ";:", ",)"],
+ "row4": ["xX", "mM", "wW", "gG", "qQ", "kK", "fF", "'\"", ";:", ".>"],
+ "row5": [" "]
+ }
+ },
+ "maya": {
+ "keymapShowTopRow": false,
+ "type": "ansi",
+ "keys": {
+ "row1": ["`~", "1!", "2@", "3#", "4$", "5%", "6^", "7&", "8*", "9(", "0)", "[{", "]}"],
+ "row2": ["bB", "lL", "dD", "gG", "qQ", "jJ", "fF", "oO", "uU", ",<", ";:", "=+", "\\|"],
+ "row3": ["nN", "rR", "tT", "sS", "vV", "kK", "hH", "aA", "eE", "iI", "-_"],
+ "row4": ["xX", "mM", "cC", "wW", "zZ", "pP", "yY", "'\"", "/?", ".>"],
+ "row5": [" "]
+ }
+ },
+ "nila": {
+ "keymapShowTopRow": false,
+ "type": "ansi",
+ "keys": {
+ "row1": ["`~", "1!", "2@", "3#", "4$", "5%", "6^", "7&", "8*", "9(", "0)", "[{", "]}"],
+ "row2": ["xX", "dD", "lL", "gG", "vV", "jJ", "fF", "oO", "uU", ",<", ";:", "=+", "\\|"],
+ "row3": ["rR", "tT", "nN", "sS", "bB", "qQ", "hH", "aA", "eE", "iI", "-_"],
+ "row4": ["kK", "mM", "cC", "wW", "zZ", "pP", "yY", "'\"", "/?", ".>"],
"row5": [" "]
}
}
diff --git a/frontend/static/quotes/code_c++.json b/frontend/static/quotes/code_c++.json
index 044c1b0b4..3a81355b3 100644
--- a/frontend/static/quotes/code_c++.json
+++ b/frontend/static/quotes/code_c++.json
@@ -164,12 +164,6 @@
"id": 26
},
{
- "text": "void Person::display_p() { cout << endl << id << \"\\t\" << name; }",
- "source": "geeksforgeeks - Inheritance in C++",
- "length": 64,
- "id": 27
- },
- {
"text": "class Student : private Person {\\n\\tchar course[50];\\n\\tint fee;\\npublic:\\n\\tvoid set_s();\\n\\tvoid display_s();\\n};",
"source": "geeksforgeeks - Inheritance in C++",
"length": 115,
diff --git a/frontend/static/quotes/english.json b/frontend/static/quotes/english.json
index f16c517ae..4954d5b70 100644
--- a/frontend/static/quotes/english.json
+++ b/frontend/static/quotes/english.json
@@ -446,12 +446,6 @@
"length": 154
},
{
- "text": "This is the second most tragic thing to happen in my life...",
- "source": "Lisa",
- "id": 74,
- "length": 60
- },
- {
"text": "Lights up and they know who you are, know who you are. Do you know who you are?",
"source": "Lights Up",
"id": 75,
@@ -663,7 +657,7 @@
},
{
"text": "Do not act as if you were going to live ten thousand years. Death hangs over you. While you live, while it is in your power, be good.",
- "source": "Meditations",
+ "source": "Marcus Aurelius",
"id": 113,
"length": 133
},
@@ -8198,12 +8192,6 @@
"length": 87
},
{
- "text": "While there are few problems in today's world that the United States can solve alone, there are even fewer that can be solved without the United States.",
- "source": "Hard Choices",
- "id": 1400,
- "length": 152
- },
- {
"text": "We all know that something is eternal. And it ain't houses and it ain't names, and it ain't earth, and it ain't even the stars... everybody knows in their bones that something is eternal, and that something has to do with human beings. All the greatest people ever lived have been telling us that for five thousand years and yet you'd be surprised how people are always losing hold of it. There's something way down deep that's eternal about every human being.",
"source": "Our Town",
"id": 1401,
@@ -13850,12 +13838,6 @@
"length": 177
},
{
- "text": "There is a door at the end of a silent corridor. And it's haunting Harry Potter's dreams. Why else would he be waking in the middle of the night, screaming in terror?",
- "source": "Harry Potter and the Order of the Phoenix",
- "id": 2376,
- "length": 166
- },
- {
"text": "I am assured by our merchants, that a boy or a girl before twelve years old, is no salable commodity, and even when they come to this age, they will not yield above three pounds, or three pounds and half a crown at most, on the exchange; which cannot turn to account either to the parents or kingdom, the charge of nutriments and rags having been at least four times that value.",
"source": "A Modest Proposal",
"id": 2377,
@@ -14438,12 +14420,6 @@
"length": 70
},
{
- "text": "I wrote him back a letter and I told him it was not the perfect country and western song, because he hadn't said anything at all about mama, or trains, or trucks, or prison, or gettin' drunk. Well, he sat down and wrote another verse to this song and he sent it to me, and after reading it I realized that my friend had written the perfect country and western song, and I felt obliged to include it on this album. The last verse goes like this here. Well, I was drunk the day my mom got out of prison, and I went to pick her up in the rain. But before I could get to the station in my pickup truck, she got runned over by a damned old train.",
- "source": "You Never Even Called Me by My Name",
- "id": 2476,
- "length": 641
- },
- {
"text": "And I said, I don't care if they lay me off either, because I told Bill that if they move my desk one more time, then I'm quitting, I'm going to quit. They've moved my desk four times already this year, and I used to be over by the window, and I could see the squirrels, and they were married, but then, they switched from the Swingline to the Boston stapler, but I kept my Swingline stapler.",
"source": "Office Space",
"id": 2477,
@@ -19046,12 +19022,6 @@
"length": 172
},
{
- "text": "If one person casts a stone at us, cast stones back with two people! If two people cast stones, cast stones back with four! If eight do, with sixteen! If a thousand do, stand up and fight with the entire village! Consider an insult to one an insult to everyone!",
- "source": "When They Cry",
- "id": 3279,
- "length": 261
- },
- {
"text": "A setup like that cost more than we ever took. That crazy Harriman. That's bad business! How long do you think I'd stay in operation if every time I pulled a job it cost me money? If he'd just pay me what he's spending to make me stop robbing him, I'd stop robbing him!",
"source": "Butch Cassidy and the Sundance Kid",
"id": 3280,
@@ -20708,10 +20678,10 @@
"length": 392
},
{
- "text": "At that very moment, time stopped, as it was wont to do when present, past, and future collide; when one's existence ceases to be measured in days, hours, and minutes, but instead in immeasurable quantity of life events.",
+ "text": "At that very moment, time stopped, as it was one to do when present, past, and future collide; when one's existence ceases to be measured in days, hours, and minutes, but instead in immeasurable quantity of life events.",
"source": "Pushing Daisies",
"id": 3568,
- "length": 220
+ "length": 219
},
{
"text": "That's Tommy. He tells people he was named after a gun, but I know he was really named after a famous 19th century ballet dancer.",
@@ -31178,12 +31148,6 @@
"id": 5400
},
{
- "text": "I would burn the world and use my soul for tinder to hear her laugh again.",
- "source": "Robert Jordan",
- "length": 74,
- "id": 5401
- },
- {
"text": "How do I take off a mask when it stops being a mask, when it's as much a part of me as I am?",
"source": "Mr. Robot",
"length": 92,
@@ -32294,12 +32258,6 @@
"id": 5632
},
{
- "text": "I'm sick of following my dreams. I'm just going to ask them where they're going and hook up with them later.",
- "source": "Mitch Hedberg",
- "length": 108,
- "id": 5634
- },
- {
"text": "Know what I pray for? The strength to change what I can, the inability to accept what I can't, and the incapacity to tell the difference.",
"source": "Calvin & Hobbes",
"length": 137,
@@ -32456,9 +32414,9 @@
"id": 5664
},
{
- "text": "It is better to live one day as a lion, than a thousand days as a lamb.",
+ "text": "It is better to live one day as a lion than a thousand days as a lamb.",
"source": "Proverbs",
- "length": 71,
+ "length": 70,
"id": 5665
},
{
@@ -32732,7 +32690,7 @@
"id": 5715
},
{
- "text": "Kristy! Ms. Esposito! Hold up. Hey, Jimmy McGill, we met inside. Hi. You didn't get it. You were never gonna get it. They dangle these things in front of you. They tell you, you got a chance, but I'm sorry. It's a lie because they had already made up their mind and they knew what they were going to do before you walked in the door. You made a mistake and they are never forgetting it. As far as they're concerned, your mistake is just, it's who you are. And it's all you are. And I'm not just talking about the scholarship here, I'm talking about everything. I mean, they'll smile at you, they'll pat you on the head, but they are never, ever letting you in. But listen. Listen. it doesn't matter. It doesn't because you don't need them. They're not going to give it to you? So what? You're going to take it. You're going to do whatever it takes. Do you hear me? You are not going to play by the rules. You're going to go your own way. You're going to do what they won't do. You're going to be smart. You are going to cut corners and you are going to win. They're on the 35th floor? You're going to be on the 50th floor. You're going to be looking down on them. And the higher you rise, the more they're going to hate you. Good. Good! You rub their noses in it. You make them suffer. Because you don't matter all that much to them. So what? So what? Screw them! Remember... the winner takes it all. You understand what I'm trying to tell you, right? All right. All right. Go get them.",
+ "text": "Kristy! Ms. Esposito! Hold up. Hey, Jimmy McGill, we met inside. Hi. You didn't get it. You were never gonna get it. They dangle these things in front of you. They tell you, you got a chance, but I'm sorry. It's a lie because they had already made up their mind and they knew what they were going to do before you walked in the door. You made a mistake and they are never forgetting it. As far as they're concerned, your mistake is just, it's who you are. And it's all you are. And I'm not just talking about the scholarship here, I'm talking about everything. I mean, they'll smile at you, they'll pat you on the head, but they are never, ever letting you in. But listen. Listen. It doesn't matter. It doesn't because you don't need them. They're not going to give it to you? So what? You're going to take it. You're going to do whatever it takes. Do you hear me? You are not going to play by the rules. You're going to go your own way. You're going to do what they won't do. You're going to be smart. You are going to cut corners and you are going to win. They're on the 35th floor? You're going to be on the 50th floor. You're going to be looking down on them. And the higher you rise, the more they're going to hate you. Good. Good! You rub their noses in it. You make them suffer. Because you don't matter all that much to them. So what? So what? Screw them! Remember... the winner takes it all. You understand what I'm trying to tell you, right? All right. All right. Go get them.",
"source": "Better Call Saul",
"length": 1486,
"id": 5716
@@ -32769,7 +32727,7 @@
},
{
"text": "When I was younger, I left a trail of broken hearts like a rockstar. I'm not proud of it.",
- "source": "Owl House",
+ "source": "Modern Family",
"length": 89,
"id": 5722
},
@@ -32936,9 +32894,9 @@
"id": 5751
},
{
- "text": "You know. I've been working here for 44 years. Ain't nobody ever ordered nothing but T-Bone steak and a baked potato. Except this one asshole from New York tried to order trout back in 1987. We don't sell no goddamned trout. T-Bone steaks. So either you don't want the corn on the cob, or you don't want the green beans. So what don't you want?",
+ "text": "You know. I've been working here for 44 years. Ain't nobody ever ordered nothing but T-Bone steak and a baked potato. Except this one dude from New York tried to order trout back in 1987. We don't sell no goddamned trout. T-Bone steaks. So either you don't want the corn on the cob, or you don't want the green beans. So what don't you want?",
"source": "Hell or High Water",
- "length": 344,
+ "length": 341,
"id": 5752
},
{
@@ -34830,9 +34788,9 @@
"id": 6184
},
{
- "text": "The autumn chill that wakes me up; you loved the amber skies so much. Long limbs and frozen swims - you'd always go past where our feet would touch - and I complained the whole ride there, the car ride back and up the stairs. I should've asked you questions, I should've asked you how to be.",
+ "text": "The autumn chill that wakes me up; you loved the amber skies so much. Long limbs and frozen swims - you'd always go past where our feet would touch - and I complained the whole way there, the car ride back and up the stairs. I should've asked you questions, I should've asked you how to be.",
"source": "Taylor Swift - Marjorie",
- "length": 291,
+ "length": 290,
"id": 6185
},
{
@@ -37569,9 +37527,9 @@
"id": 6600
},
{
- "text": "Whatever you do, don't reveal all of your tactics in a YouTube video. You fool. You moron.",
+ "text": "Whatever you do, don't reveal all of your tactics in a YouTube video. You fool.",
"source": "Great Potato War",
- "length": 90,
+ "length": 79,
"approvedBy": "Smithster",
"id": 6601
},
@@ -37849,9 +37807,9 @@
"id": 6641
},
{
- "text": "Rooted deep within the Puritans souls like some strange invasive weed lurked their belief in a second world, and Invisible World swarming with shadowy apparitions and unearthly phantoms of the air.",
+ "text": "Rooted deep within the Puritans souls like some strange invasive weed lurked their belief in a second world, an Invisible World swarming with shadowy apparitions and unearthly phantoms of the air.",
"source": "Witches by Rosalyn Schanzer",
- "length": 197,
+ "length": 196,
"approvedBy": "Smithster",
"id": 6642
},
@@ -38241,9 +38199,9 @@
"id": 6703
},
{
- "text": "It's about drive, it's about power, we stay hungry, we devour. Put in the work, put in the hours and take whats ours. Black and Samoan in my veins, my culture banging with Strange. I changed the game so what's my name?",
+ "text": "It's about drive, it's about power, we stay hungry, we devour. Put in the work, put in the hours and take what's ours. Black and Samoan in my veins, my culture banging with Strange. I changed the game so what's my name?",
"source": "Face Off",
- "length": 218,
+ "length": 219,
"approvedBy": "Smithster",
"id": 6704
},
@@ -38735,6 +38693,30 @@
"source": "The Legend of Vox Machina",
"id": 6782,
"length": 183
+ },
+ {
+ "text": "Most cities aren't. They want to believe they have a cash-flow problem because it is convenient, because insolvency is too difficult to fathom, especially when everyone else appears to be doing the exact same thing. Could everyone be wrong? Could we all be insolvent? These two questions probably cost me a total of six years in the intellectual wilderness as I clung to the notion that what I was seeing and measuring could not possibly be true, that a wisdom greater than mine had to be at work that I hadn't perceived.",
+ "source": "Strong Towns - A Bottom-Up Revolution to Rebuild American Prosperity",
+ "id": 6783,
+ "length": 521
+ },
+ {
+ "text": "It's also our path to salvation. Our cities are struggling financially, trapped in a system grinding them into decline. Working together in an intentional way, it is possible to make our places stronger financially while also improving the lives of people.",
+ "source": "Strong Towns - A Bottom-Up Revolution to Rebuild American Prosperity",
+ "id": 6784,
+ "length": 256
+ },
+ {
+ "text": "That is the essence of a Strong Towns approach, the bottom-up revolution America desperately needs.",
+ "source": "Strong Towns - A Bottom-Up Revolution to Rebuild American Prosperity",
+ "id": 6785,
+ "length": 99
+ },
+ {
+ "text": "I'm not against the automobile, but I just feel that the automobile has moved into communities too much. I feel that you can design so that the automobile is there, but still put pedestrians back again... I’d love to work on a project like that.",
+ "source": "Walt Disney",
+ "id": 6786,
+ "length": 245
}
]
}
diff --git a/frontend/static/quotes/german.json b/frontend/static/quotes/german.json
index 933bf0ab4..7d1fa4c08 100644
--- a/frontend/static/quotes/german.json
+++ b/frontend/static/quotes/german.json
@@ -392,9 +392,9 @@
"id": 65
},
{
- "text": "In so ferne ist die Metaphysik eine Wissenschaft von den Grenzen der menschlichen Vernunft, und da ein kleines Land jederzeit viel Grenze hat, überhaupt auch mehr daran liegt, seine Besitzungen wohl zu erkennen und zu behaupten, als blindlings auf Eroberung auszugehen, so ist dieser Nutze der erwähnten Wissenschaft der unbekannteste und zugleich wichtigste, wie er denn auch nur ziemlich spät und nach langer Erfahrung erreichet wird.",
+ "text": "In so ferne ist die Metaphysik eine Wissenschaft von den Grenzen der menschlichen Vernunft, und da ein kleines Land jederzeit viel Grenze hat, überhaupt auch mehr daran liegt, seine Besitzungen wohl zu erkennen und zu behaupten, als blindlings auf Eroberung auszugehen, so ist dieser Nutze der erwähnten Wissenschaft der unbekannteste und zugleich wichtigste, wie er denn auch nur ziemlich spät und nach langer Erfahrung erreicht wird.",
"source": "Immanuel Kant",
- "length": 436,
+ "length": 435,
"id": 66
},
{
@@ -3246,6 +3246,66 @@
"source": "[5/5] 20 Affirmationen zur Selbstheilung",
"length": 1255,
"id": 548
+ },
+ {
+ "text": "Durch das Gedränge der Menschenmenge bahnen wir uns den altbekannten Weg. Entlang der Gassen, zu den Rheinterrassen, über die Brücken, bis hin zu der Musik. Wo alles laut ist, wo alle drauf sind, um durchzudrehen. Wo die anderen warten, um mit uns zu starten und abzugehen.",
+ "source": "Die Toten Hosen - Tage wie diese",
+ "length": 273,
+ "id": 549
+ },
+ {
+ "text": "Das Internet ist für uns alle Neuland und es ermöglicht auch Feinden und Gegnern unserer demokratischen Grundordnung natürlich, mit neuen Mitteln und neuen Herangehensweisen unsere Art zu leben in Gefahr zu bringen. Deshalb müssen wir auch darüber sprechen, welche Regeln gelten, wie die Dinge eingeschränkt werden müssen, wo es auch Ausnahmen geben muss, wo es Transparenz geben muss.",
+ "source": "Angela Merkel",
+ "length": 385,
+ "id": 550
+ },
+ {
+ "text": "Steige aus dem Bett, dreh den Swag auf, schaue kurz in den Spiegel, sag \"What up?\"",
+ "source": "Money Boy - Dreh den Swag auf",
+ "length": 82,
+ "id": 551
+ },
+ {
+ "text": "Sieh dir diese kleine Karte an. So viel bedeutet sie. Die Vorderseite ist schlicht weiß, dezent, das Firmenlogo in Silber. Die Rückseite enthält alle wichtigen Informationen: Name, Adresse, Telefonnummern, E-Mail-Adresse. Die Schriftart ist etwas kühn, aber nicht aufdringlich. Ein Hauch von Vanille.",
+ "source": "American Psycho",
+ "length": 300,
+ "id": 552
+ },
+ {
+ "text": "Weißt du, wenn wir erst mal wieder zu Hause sind, dann machen wir was Großes. Wir beide. Wir beide zusammen, ja?",
+ "source": "Im Westen nichts Neues (2022)",
+ "length": 112,
+ "id": 553
+ },
+ {
+ "text": "Ich stehe von Ihnen in der Hoffnung, dass Sie unsere Anwesenheit zum Anlass nehmen, alle Feindseligkeiten auszusetzen. Im Namen der Menschlichkeit bitte ich Sie, für die Dauer der Verhandlungen einer sofortigen Waffenruhe zuzustimmen, um unseren Völkern unnötige Opfer zu ersparen. Matthias Erzberger, Leiter der deutschen Delegation.",
+ "source": "Im Westen nichts Neues (2022)",
+ "length": 334,
+ "id": 554
+ },
+ {
+ "text": "Was sollen wir machen? Zusammen Schuhsohlen vernageln? Ich kann nicht mal 'n Brief lesen von meiner Frau. Du gehst studieren, Paul. Sonst erschieße ich dich gleich hier. Meine Hose rutscht. Die Hose ist lose.",
+ "source": "Im Westen nichts Neues (2022)",
+ "length": 208,
+ "id": 555
+ },
+ {
+ "text": "Isst Olaf Scholz gerne Döner? Klar. Mir schmecken die jedenfalls schon sehr lange und ich esse gerne Döner.",
+ "source": "Olaf Scholz",
+ "length": 107,
+ "id": 556
+ },
+ {
+ "text": "Herr Scholz, wann Bubatz legal? - Wir haben ja beschlossen, dass wir die Cannabis-Legalisierung vornehmen wollen, und das wird umgesetzt. Da ist jetzt die Vorbereitung im Gange, das kommt in dieser Legislaturperiode, das genaue Datum haben wir noch nicht festgelegt.",
+ "source": "Tina Hassel, Olaf Scholz",
+ "length": 266,
+ "id": 557
+ },
+ {
+ "text": "Deutschland ist ein starkes Land, und das Motiv, in dem wir an diese Dinge herangehen, muss sein: \"Wir haben so vieles geschafft, wir schaffen das.\"",
+ "source": "Angela Merkel",
+ "length": 148,
+ "id": 558
}
]
}
diff --git a/frontend/static/quotes/indonesian.json b/frontend/static/quotes/indonesian.json
index e6f033d6a..1131d40e5 100644
--- a/frontend/static/quotes/indonesian.json
+++ b/frontend/static/quotes/indonesian.json
@@ -908,9 +908,9 @@
"id": 151
},
{
- "text": "Indahnya kisah-kasih kita di masa remaja. Di bawah rayu senja kita di madu bermanja. Tiada masa-masa yang lebih indah dari masa remaja. Seakan dunia, milik berdua.",
+ "text": "Indahnya kisah-kasih kita di masa remaja. Di bawah rayu senja kita dimadu bermanja. Tiada masa-masa yang lebih indah dari masa remaja. Seakan dunia, milik berdua.",
"source": "HIVI! - Remaja",
- "length": 163,
+ "length": 162,
"id": 152
},
{
diff --git a/frontend/static/quotes/russian.json b/frontend/static/quotes/russian.json
index c02402e13..fbe37c9c3 100644
--- a/frontend/static/quotes/russian.json
+++ b/frontend/static/quotes/russian.json
@@ -1660,7 +1660,7 @@
{
"id": 279,
"source": "Кундера Милан - Неспешность",
- "text": "Дружба необходима человеку для того, чтобы у него как следует работала память. Помнить о своём прошлом, вечно хранить его в душé - таково необходимое условие, позволяющее нам, как говорится, сберечь цельность нашего \"я\". Чтобы это \"я\" не съёживалось, не утрачивало своей полноты, его нужно орошать воспоминаниями, как горшок с цветами, а такая поливка невозможна без постоянного общения со свидетелями прошлого, то есть с друзьями. Они - наше зеркало, наша память; от них требуется лишь одно - хотя бы время от времени протирать это зеркало, чтобы мы могли в него смотреться.",
+ "text": "Дружба необходима человеку для того, чтобы у него как следует работала память. Помнить о своём прошлом, вечно хранить его в душе - таково необходимое условие, позволяющее нам, как говорится, сберечь цельность нашего \"я\". Чтобы это \"я\" не съёживалось, не утрачивало своей полноты, его нужно орошать воспоминаниями, как горшок с цветами, а такая поливка невозможна без постоянного общения со свидетелями прошлого, то есть с друзьями. Они - наше зеркало, наша память; от них требуется лишь одно - хотя бы время от времени протирать это зеркало, чтобы мы могли в него смотреться.",
"length": 575
},
{
@@ -5032,8 +5032,8 @@
{
"id": 850,
"source": "Пивоваров Виктор - Влюблённый агент",
- "text": "Методы строительства альбомного сооружения у меня и Кабакова диаметрально противоположны. Илья чаще всего начинает как бы сверху, с отдельных рисунков, разворачивает их в серию, двигаясь на ощупь, группирует их, отбирает, снабжает текстами и завершает фундаментом, то есть жёсткой смысловой и изобразительной конструкцией. У него поэтому много \"отходов\", которые он, однако, необычайно умно и экономно использует для создания других сочинений. меня, наоборот, возникает сначала идея, сценарий, как бы фундамент, общая структура, которая потом уже редко подвергается изменениям и на которой я строю отдельные блоки рисунков, текстов и т. п.",
- "length": 639
+ "text": "Методы строительства альбомного сооружения у меня и Кабакова диаметрально противоположны. Илья чаще всего начинает как бы сверху, с отдельных рисунков, разворачивает их в серию, двигаясь на ощупь, группирует их, отбирает, снабжает текстами и завершает фундаментом, то есть жёсткой смысловой и изобразительной конструкцией. У него поэтому много \"отходов\", которые он, однако, необычайно умно и экономно использует для создания других сочинений. У меня, наоборот, возникает сначала идея, сценарий, как бы фундамент, общая структура, которая потом уже редко подвергается изменениям и на которой я строю отдельные блоки рисунков, текстов и т. п.",
+ "length": 641
},
{
"id": 851,
diff --git a/frontend/static/themes/_list.json b/frontend/static/themes/_list.json
index 2793c7ad8..82cb1ba39 100644
--- a/frontend/static/themes/_list.json
+++ b/frontend/static/themes/_list.json
@@ -1153,5 +1153,12 @@
"mainColor": "#7d67a9",
"subColor": "#3a98b9",
"textColor": "#1b4c5e"
+ },
+ {
+ "name": "cherry_blossom",
+ "bgColor": "#323437",
+ "mainColor": "#d65ccc",
+ "subColor": "#787d82",
+ "textColor": "#d1d0c5"
}
]
diff --git a/frontend/static/themes/cherry_blossom.css b/frontend/static/themes/cherry_blossom.css
new file mode 100644
index 000000000..21beeee6a
--- /dev/null
+++ b/frontend/static/themes/cherry_blossom.css
@@ -0,0 +1,12 @@
+:root {
+ --bg-color: #323437;
+ --main-color: #d65ccc;
+ --caret-color: #ffffff;
+ --sub-color: #787d82;
+ --sub-alt-color: #2d2f31;
+ --text-color: #d1d0c5;
+ --error-color: #ca4754;
+ --error-extra-color: #d32738;
+ --colorful-error-color: #ec182d;
+ --colorful-error-extra-color: #6e0c16;
+}
diff --git a/frontend/static/themes/dracula.css b/frontend/static/themes/dracula.css
index ac844f1e5..b17f38db5 100644
--- a/frontend/static/themes/dracula.css
+++ b/frontend/static/themes/dracula.css
@@ -1,14 +1,14 @@
:root {
--bg-color: #282a36;
- --main-color: #f2f2f2;
- --caret-color: #f2f2f2;
- --sub-color: #bd93f9;
+ --main-color: #bd93f9;
+ --caret-color: #bd93f9;
+ --sub-color: #6272a4;
--sub-alt-color: #20222c;
- --text-color: #f2f2f2;
- --error-color: #f758a0;
- --error-extra-color: #732e51;
- --colorful-error-color: #f758a0;
- --colorful-error-extra-color: #732e51;
+ --text-color: #f8f8f2;
+ --error-color: #ff5555;
+ --error-extra-color: #f1fa8c;
+ --colorful-error-color: #ff5555;
+ --colorful-error-extra-color: #f1fa8c;
}
#menu .textButton:nth-child(1) {