mirror of
https://github.com/monkeytypegame/monkeytype.git
synced 2025-11-17 22:29:52 +08:00
Merge branch 'master' into newads
This commit is contained in:
commit
e97db0cb5a
24 changed files with 764 additions and 181 deletions
|
|
@ -388,7 +388,10 @@ export async function addResult(
|
|||
|
||||
const { funbox, bailedOut } = result;
|
||||
const validResultCriteria =
|
||||
(funbox === "none" || funbox === "plus_one" || funbox === "plus_two") &&
|
||||
(funbox === "none" ||
|
||||
funbox === "plus_one" ||
|
||||
funbox === "plus_two" ||
|
||||
funbox === "plus_three") &&
|
||||
!bailedOut &&
|
||||
user.banned !== true &&
|
||||
user.lbOptOut !== true &&
|
||||
|
|
|
|||
|
|
@ -87,8 +87,9 @@ const CONFIG_SCHEMA = joi.object({
|
|||
paceCaretCustomSpeed: joi.number().min(0),
|
||||
repeatedPace: joi.boolean(),
|
||||
pageWidth: joi.string().valid("100", "125", "150", "200", "max"),
|
||||
chartAccuracy: joi.boolean(),
|
||||
chartStyle: joi.string().valid("line", "scatter"),
|
||||
accountChart: joi.array().items(joi.string()),
|
||||
chartAccuracy: joi.boolean().optional(), //remove after a bit
|
||||
chartStyle: joi.string().valid("line", "scatter").optional(), //remove after a bit
|
||||
minWpm: joi.string().valid("off", "custom"),
|
||||
minWpmCustomSpeed: joi.number().min(0),
|
||||
highlightMode: joi.string().valid("off", "letter", "word"),
|
||||
|
|
|
|||
|
|
@ -75,6 +75,10 @@ const Funboxes: Record<string, MonkeyTypes.FunboxMetadata> = {
|
|||
canGetPb: true,
|
||||
difficultyLevel: 0,
|
||||
},
|
||||
plus_three: {
|
||||
canGetPb: true,
|
||||
difficultyLevel: 0,
|
||||
},
|
||||
read_ahead_easy: {
|
||||
canGetPb: true,
|
||||
difficultyLevel: 1,
|
||||
|
|
|
|||
|
|
@ -231,28 +231,16 @@
|
|||
color: var(--sub-color);
|
||||
margin-top: 1rem;
|
||||
display: grid;
|
||||
grid-template-columns: auto 300px;
|
||||
grid-template-columns: auto 400px;
|
||||
align-items: center;
|
||||
.text {
|
||||
height: min-content;
|
||||
}
|
||||
.buttons {
|
||||
font-size: 0.75rem;
|
||||
display: grid;
|
||||
gap: 0.5rem;
|
||||
.smoothing {
|
||||
display: grid;
|
||||
gap: 0.25rem;
|
||||
grid-template-columns: 1fr auto;
|
||||
grid-template-rows: auto auto;
|
||||
justify-items: start;
|
||||
color: var(--text-color);
|
||||
.title {
|
||||
color: var(--text-color);
|
||||
}
|
||||
input[type="range"] {
|
||||
grid-column: 1/3;
|
||||
}
|
||||
}
|
||||
grid-template-columns: 1fr 1fr 1fr;
|
||||
}
|
||||
}
|
||||
.chart {
|
||||
|
|
|
|||
|
|
@ -448,6 +448,13 @@
|
|||
}
|
||||
}
|
||||
|
||||
.pageAccount {
|
||||
.group.chart .below {
|
||||
grid-template-columns: 1fr;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
}
|
||||
|
||||
.pageSettings {
|
||||
.section.themes .tabContent.customTheme {
|
||||
}
|
||||
|
|
@ -496,10 +503,6 @@
|
|||
display: none;
|
||||
}
|
||||
}
|
||||
.group.chart .below {
|
||||
grid-template-columns: 1fr;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
.group.topFilters .buttonsAndTitle .buttons {
|
||||
display: grid;
|
||||
justify-content: unset;
|
||||
|
|
|
|||
|
|
@ -299,32 +299,64 @@ export function setBlindMode(blind: boolean, nosave?: boolean): boolean {
|
|||
return true;
|
||||
}
|
||||
|
||||
export function setChartAccuracy(
|
||||
chartAccuracy: boolean,
|
||||
export function setAccountChart(
|
||||
array: MonkeyTypes.AccountChart,
|
||||
nosave?: boolean
|
||||
): boolean {
|
||||
if (!isConfigValueValid("chart accuracy", chartAccuracy, ["boolean"])) {
|
||||
if (
|
||||
!isConfigValueValid("account chart", array, [["on", "off"], "stringArray"])
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
config.chartAccuracy = chartAccuracy;
|
||||
saveToLocalStorage("chartAccuracy", nosave);
|
||||
ConfigEvent.dispatch("chartAccuracy", config.chartAccuracy);
|
||||
config.accountChart = array;
|
||||
saveToLocalStorage("accountChart", nosave);
|
||||
ConfigEvent.dispatch("accountChart", config.accountChart);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
export function setChartStyle(
|
||||
chartStyle: MonkeyTypes.ChartStyle,
|
||||
export function setAccountChartAccuracy(
|
||||
value: boolean,
|
||||
nosave?: boolean
|
||||
): boolean {
|
||||
if (!isConfigValueValid("chart style", chartStyle, [["line", "scatter"]])) {
|
||||
if (!isConfigValueValid("account chart accuracy", value, ["boolean"])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
config.chartStyle = chartStyle;
|
||||
saveToLocalStorage("chartStyle", nosave);
|
||||
ConfigEvent.dispatch("chartStyle", config.chartStyle);
|
||||
config.accountChart[0] = value ? "on" : "off";
|
||||
saveToLocalStorage("accountChart", nosave);
|
||||
ConfigEvent.dispatch("accountChart", config.accountChart);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
export function setAccountChartAvg10(
|
||||
value: boolean,
|
||||
nosave?: boolean
|
||||
): boolean {
|
||||
if (!isConfigValueValid("account chart avg 10", value, ["boolean"])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
config.accountChart[1] = value ? "on" : "off";
|
||||
saveToLocalStorage("accountChart", nosave);
|
||||
ConfigEvent.dispatch("accountChart", config.accountChart);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
export function setAccountChartAvg100(
|
||||
value: boolean,
|
||||
nosave?: boolean
|
||||
): boolean {
|
||||
if (!isConfigValueValid("account chart avg 100", value, ["boolean"])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
config.accountChart[2] = value ? "on" : "off";
|
||||
saveToLocalStorage("accountChart", nosave);
|
||||
ConfigEvent.dispatch("accountChart", config.accountChart);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
@ -1824,8 +1856,7 @@ export function apply(
|
|||
setPaceCaretCustomSpeed(configObj.paceCaretCustomSpeed, true);
|
||||
setRepeatedPace(configObj.repeatedPace, true);
|
||||
setPageWidth(configObj.pageWidth, true);
|
||||
setChartAccuracy(configObj.chartAccuracy, true);
|
||||
setChartStyle(configObj.chartStyle, true);
|
||||
setAccountChart(configObj.accountChart, true);
|
||||
setMinBurst(configObj.minBurst, true);
|
||||
setMinBurstCustomSpeed(configObj.minBurstCustomSpeed, true);
|
||||
setMinWpm(configObj.minWpm, true);
|
||||
|
|
|
|||
|
|
@ -69,8 +69,7 @@ export default <MonkeyTypes.Config>{
|
|||
paceCaretCustomSpeed: 100,
|
||||
repeatedPace: true,
|
||||
pageWidth: "125",
|
||||
chartAccuracy: true,
|
||||
chartStyle: "line",
|
||||
accountChart: ["on", "on", "on"],
|
||||
minWpm: "off",
|
||||
minWpmCustomSpeed: 100,
|
||||
highlightMode: "letter",
|
||||
|
|
|
|||
|
|
@ -243,38 +243,76 @@ export let accountHistoryActiveIndex: number;
|
|||
|
||||
export const accountHistory: ChartWithUpdateColors<
|
||||
"line",
|
||||
MonkeyTypes.HistoryChartData[] | MonkeyTypes.AccChartData[],
|
||||
| MonkeyTypes.HistoryChartData[]
|
||||
| MonkeyTypes.AccChartData[]
|
||||
| MonkeyTypes.OtherChartData[],
|
||||
string
|
||||
> = new ChartWithUpdateColors($(".pageAccount #accountHistoryChart"), {
|
||||
type: "line",
|
||||
data: {
|
||||
labels: [],
|
||||
datasets: [
|
||||
{
|
||||
yAxisID: "wpm",
|
||||
label: "wpm",
|
||||
fill: false,
|
||||
data: [],
|
||||
borderColor: "#f44336",
|
||||
borderWidth: 2,
|
||||
trendlineLinear: {
|
||||
style: "rgba(255,105,180, .8)",
|
||||
lineStyle: "dotted",
|
||||
width: 4,
|
||||
},
|
||||
fill: false,
|
||||
borderWidth: 0,
|
||||
order: 3,
|
||||
},
|
||||
{
|
||||
yAxisID: "pb",
|
||||
data: [],
|
||||
fill: false,
|
||||
stepped: true,
|
||||
pointRadius: 0,
|
||||
pointHoverRadius: 0,
|
||||
order: 4,
|
||||
},
|
||||
{
|
||||
yAxisID: "acc",
|
||||
label: "acc",
|
||||
fill: false,
|
||||
data: [],
|
||||
borderColor: "#cccccc",
|
||||
borderWidth: 2,
|
||||
pointStyle: "triangle",
|
||||
borderWidth: 0,
|
||||
pointRadius: 3.5,
|
||||
order: 3,
|
||||
},
|
||||
{
|
||||
yAxisID: "wpmAvgTen",
|
||||
data: [],
|
||||
fill: false,
|
||||
pointRadius: 0,
|
||||
pointHoverRadius: 0,
|
||||
order: 2,
|
||||
},
|
||||
{
|
||||
yAxisID: "accAvgTen",
|
||||
data: [],
|
||||
fill: false,
|
||||
pointRadius: 0,
|
||||
pointHoverRadius: 0,
|
||||
order: 2,
|
||||
},
|
||||
{
|
||||
yAxisID: "wpmAvgHundred",
|
||||
data: [],
|
||||
fill: false,
|
||||
pointRadius: 0,
|
||||
pointHoverRadius: 0,
|
||||
order: 1,
|
||||
},
|
||||
{
|
||||
yAxisID: "accAvgHundred",
|
||||
label: "accAvgHundred",
|
||||
data: [],
|
||||
fill: false,
|
||||
pointRadius: 0,
|
||||
pointHoverRadius: 0,
|
||||
order: 1,
|
||||
},
|
||||
],
|
||||
},
|
||||
options: {
|
||||
responsive: true,
|
||||
// responsive: true,
|
||||
maintainAspectRatio: false,
|
||||
hover: {
|
||||
mode: "nearest",
|
||||
|
|
@ -283,13 +321,18 @@ export const accountHistory: ChartWithUpdateColors<
|
|||
scales: {
|
||||
x: {
|
||||
axis: "x",
|
||||
type: "timeseries",
|
||||
bounds: "ticks",
|
||||
type: "linear",
|
||||
min: 0,
|
||||
ticks: {
|
||||
stepSize: 10,
|
||||
},
|
||||
display: false,
|
||||
offset: true,
|
||||
title: {
|
||||
display: true,
|
||||
text: "Test Number",
|
||||
},
|
||||
grid: {
|
||||
display: false,
|
||||
text: "Date",
|
||||
},
|
||||
},
|
||||
wpm: {
|
||||
|
|
@ -306,21 +349,86 @@ export const accountHistory: ChartWithUpdateColors<
|
|||
},
|
||||
position: "right",
|
||||
},
|
||||
pb: {
|
||||
axis: "y",
|
||||
beginAtZero: true,
|
||||
min: 0,
|
||||
ticks: {
|
||||
stepSize: 10,
|
||||
},
|
||||
display: false,
|
||||
},
|
||||
acc: {
|
||||
axis: "y",
|
||||
beginAtZero: true,
|
||||
min: 0,
|
||||
max: 100,
|
||||
reverse: true,
|
||||
ticks: {
|
||||
stepSize: 10,
|
||||
},
|
||||
display: true,
|
||||
position: "left",
|
||||
title: {
|
||||
display: true,
|
||||
text: "Error rate (100 - accuracy)",
|
||||
text: "Accuracy",
|
||||
},
|
||||
grid: {
|
||||
display: false,
|
||||
},
|
||||
position: "left",
|
||||
},
|
||||
wpmAvgTen: {
|
||||
axis: "y",
|
||||
beginAtZero: true,
|
||||
min: 0,
|
||||
ticks: {
|
||||
stepSize: 10,
|
||||
},
|
||||
display: false,
|
||||
grid: {
|
||||
display: false,
|
||||
},
|
||||
},
|
||||
accAvgTen: {
|
||||
axis: "y",
|
||||
beginAtZero: true,
|
||||
min: 0,
|
||||
reverse: true,
|
||||
ticks: {
|
||||
stepSize: 10,
|
||||
},
|
||||
display: false,
|
||||
grid: {
|
||||
display: false,
|
||||
},
|
||||
},
|
||||
wpmAvgHundred: {
|
||||
axis: "y",
|
||||
beginAtZero: true,
|
||||
min: 0,
|
||||
ticks: {
|
||||
stepSize: 10,
|
||||
},
|
||||
display: false,
|
||||
grid: {
|
||||
display: false,
|
||||
},
|
||||
},
|
||||
accAvgHundred: {
|
||||
axis: "y",
|
||||
beginAtZero: true,
|
||||
min: 0,
|
||||
reverse: true,
|
||||
ticks: {
|
||||
stepSize: 10,
|
||||
},
|
||||
display: false,
|
||||
grid: {
|
||||
display: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
plugins: {
|
||||
annotation: {
|
||||
annotations: [],
|
||||
|
|
@ -329,15 +437,26 @@ export const accountHistory: ChartWithUpdateColors<
|
|||
animation: { duration: 250 },
|
||||
// Disable the on-canvas tooltip
|
||||
enabled: true,
|
||||
|
||||
intersect: false,
|
||||
external: function (ctx): void {
|
||||
if (!ctx) return;
|
||||
ctx.tooltip.options.displayColors = false;
|
||||
},
|
||||
filter: function (tooltipItem): boolean {
|
||||
return (
|
||||
tooltipItem.datasetIndex !== 1 &&
|
||||
tooltipItem.datasetIndex !== 3 &&
|
||||
tooltipItem.datasetIndex !== 4 &&
|
||||
tooltipItem.datasetIndex !== 5 &&
|
||||
tooltipItem.datasetIndex !== 6
|
||||
);
|
||||
},
|
||||
callbacks: {
|
||||
title: function (): string {
|
||||
return "";
|
||||
},
|
||||
|
||||
beforeLabel: function (tooltipItem): string {
|
||||
if (tooltipItem.datasetIndex !== 0) {
|
||||
const resultData = tooltipItem.dataset.data[
|
||||
|
|
@ -828,21 +947,55 @@ export const miniResult: ChartWithUpdateColors<
|
|||
});
|
||||
|
||||
function updateAccuracy(): void {
|
||||
accountHistory.data.datasets[1].hidden = !Config.chartAccuracy;
|
||||
const accOn = Config.accountChart[0] === "on";
|
||||
const avg10On = Config.accountChart[1] === "on";
|
||||
const avg100On = Config.accountChart[2] === "on";
|
||||
|
||||
if (avg10On && avg100On) {
|
||||
accountHistory.data.datasets[2].hidden = !accOn;
|
||||
accountHistory.data.datasets[4].hidden = !accOn;
|
||||
accountHistory.data.datasets[6].hidden = !accOn;
|
||||
} else if (avg10On) {
|
||||
accountHistory.data.datasets[2].hidden = !accOn;
|
||||
accountHistory.data.datasets[4].hidden = !accOn;
|
||||
} else if (Config.accountChart[2] === "on") {
|
||||
accountHistory.data.datasets[2].hidden = !accOn;
|
||||
accountHistory.data.datasets[6].hidden = !accOn;
|
||||
} else {
|
||||
accountHistory.data.datasets[2].hidden = !accOn;
|
||||
}
|
||||
|
||||
(accountHistory.options as ScaleChartOptions<"line">).scales["acc"].display =
|
||||
Config.chartAccuracy;
|
||||
accOn;
|
||||
accountHistory.update();
|
||||
}
|
||||
|
||||
function updateStyle(): void {
|
||||
if (Config.chartStyle == "scatter") {
|
||||
accountHistory.data.datasets[0].showLine = false;
|
||||
accountHistory.data.datasets[1].showLine = false;
|
||||
function updateAverage10(): void {
|
||||
const accOn = Config.accountChart[0] === "on";
|
||||
const avg10On = Config.accountChart[1] === "on";
|
||||
|
||||
if (accOn) {
|
||||
accountHistory.data.datasets[3].hidden = !avg10On;
|
||||
accountHistory.data.datasets[4].hidden = !avg10On;
|
||||
} else {
|
||||
accountHistory.data.datasets[0].showLine = true;
|
||||
accountHistory.data.datasets[1].showLine = true;
|
||||
accountHistory.data.datasets[3].hidden = !avg10On;
|
||||
}
|
||||
accountHistory.updateColors();
|
||||
accountHistory.update();
|
||||
}
|
||||
|
||||
function updateAverage100(): void {
|
||||
const accOn = Config.accountChart[0] === "on";
|
||||
const avg100On = Config.accountChart[2] === "on";
|
||||
|
||||
if (accOn) {
|
||||
accountHistory.data.datasets[5].hidden = !avg100On;
|
||||
accountHistory.data.datasets[6].hidden = !avg100On;
|
||||
} else {
|
||||
accountHistory.data.datasets[5].hidden = !avg100On;
|
||||
}
|
||||
accountHistory.updateColors();
|
||||
accountHistory.update();
|
||||
}
|
||||
|
||||
export async function updateColors<
|
||||
|
|
@ -866,6 +1019,7 @@ export async function updateColors<
|
|||
const color = isPb ? textcolor : maincolor;
|
||||
return color;
|
||||
};
|
||||
|
||||
if (chart.data.datasets[1]) {
|
||||
chart.data.datasets[1].borderColor = subcolor;
|
||||
}
|
||||
|
|
@ -910,6 +1064,60 @@ export async function updateColors<
|
|||
)[1].pointBackgroundColor = subcolor;
|
||||
}
|
||||
}
|
||||
if (chart.data.datasets.length === 2) {
|
||||
chart.data.datasets[1].borderColor = (): string => {
|
||||
const color = subcolor;
|
||||
return color;
|
||||
};
|
||||
}
|
||||
|
||||
if (chart.data.datasets.length === 7) {
|
||||
chart.data.datasets[2].borderColor = (): string => {
|
||||
const color = subcolor;
|
||||
return color;
|
||||
};
|
||||
const avg10On = Config.accountChart[1] === "on";
|
||||
const avg100On = Config.accountChart[2] === "on";
|
||||
|
||||
const text02 = Misc.blendTwoHexColors(bgcolor, textcolor, 0.2);
|
||||
const main02 = Misc.blendTwoHexColors(bgcolor, maincolor, 0.2);
|
||||
const main04 = Misc.blendTwoHexColors(bgcolor, maincolor, 0.4);
|
||||
|
||||
const sub02 = Misc.blendTwoHexColors(bgcolor, subcolor, 0.2);
|
||||
const sub04 = Misc.blendTwoHexColors(bgcolor, subcolor, 0.4);
|
||||
|
||||
const [
|
||||
wpmDataset,
|
||||
pbDataset,
|
||||
accDataset,
|
||||
ao10wpmDataset,
|
||||
ao10accDataset,
|
||||
ao100wpmDataset,
|
||||
ao100accDataset,
|
||||
] = chart.data.datasets as ChartDataset<"line", TData>[];
|
||||
|
||||
if (avg10On && avg100On) {
|
||||
wpmDataset.pointBackgroundColor = main02;
|
||||
pbDataset.borderColor = text02;
|
||||
accDataset.pointBackgroundColor = sub02;
|
||||
ao10wpmDataset.borderColor = main04;
|
||||
ao10accDataset.borderColor = sub04;
|
||||
ao100wpmDataset.borderColor = maincolor;
|
||||
ao100accDataset.borderColor = subcolor;
|
||||
} else if ((avg10On && !avg100On) || (!avg10On && avg100On)) {
|
||||
pbDataset.borderColor = text02;
|
||||
wpmDataset.pointBackgroundColor = main04;
|
||||
accDataset.pointBackgroundColor = sub04;
|
||||
ao10wpmDataset.borderColor = maincolor;
|
||||
ao100wpmDataset.borderColor = maincolor;
|
||||
ao10accDataset.borderColor = subcolor;
|
||||
ao100accDataset.borderColor = subcolor;
|
||||
} else {
|
||||
pbDataset.borderColor = text02;
|
||||
wpmDataset.pointBackgroundColor = maincolor;
|
||||
accDataset.pointBackgroundColor = subcolor;
|
||||
}
|
||||
}
|
||||
|
||||
const chartScaleOptions = chart.options as ScaleChartOptions<TType>;
|
||||
Object.keys(chartScaleOptions.scales).forEach((scaleID) => {
|
||||
|
|
@ -923,10 +1131,6 @@ export async function updateColors<
|
|||
chart.data.datasets[0]
|
||||
.trendlineLinear as TrendlineLinearPlugin.TrendlineLinearOptions
|
||||
).style = subcolor;
|
||||
(
|
||||
chart.data.datasets[1]
|
||||
.trendlineLinear as TrendlineLinearPlugin.TrendlineLinearOptions
|
||||
).style = subcolor;
|
||||
} catch {}
|
||||
|
||||
(
|
||||
|
|
@ -958,7 +1162,10 @@ export function updateAllChartColors(): void {
|
|||
}
|
||||
|
||||
ConfigEvent.subscribe((eventKey, eventValue) => {
|
||||
if (eventKey === "chartAccuracy") updateAccuracy();
|
||||
if (eventKey === "chartStyle") updateStyle();
|
||||
if (eventKey === "accountChart") {
|
||||
updateAccuracy();
|
||||
updateAverage10();
|
||||
updateAverage100();
|
||||
}
|
||||
if (eventKey === "fontFamily") setDefaultFontFamily(eventValue as string);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -196,53 +196,17 @@ export function reset(): void {
|
|||
ChartController.accountActivity.data.datasets[1].data = [];
|
||||
ChartController.accountHistory.data.datasets[0].data = [];
|
||||
ChartController.accountHistory.data.datasets[1].data = [];
|
||||
ChartController.accountHistory.data.datasets[2].data = [];
|
||||
ChartController.accountHistory.data.datasets[3].data = [];
|
||||
ChartController.accountHistory.data.datasets[4].data = [];
|
||||
ChartController.accountHistory.data.datasets[5].data = [];
|
||||
ChartController.accountHistory.data.datasets[6].data = [];
|
||||
}
|
||||
|
||||
let totalSecondsFiltered = 0;
|
||||
let chartData: MonkeyTypes.HistoryChartData[] = [];
|
||||
let accChartData: MonkeyTypes.AccChartData[] = [];
|
||||
|
||||
export function smoothHistory(factor: number): void {
|
||||
const smoothedWpmData = Misc.smooth(
|
||||
chartData.map((a) => a.y),
|
||||
factor
|
||||
);
|
||||
const smoothedAccData = Misc.smooth(
|
||||
accChartData.map((a) => a.y),
|
||||
factor
|
||||
);
|
||||
|
||||
const chartData2 = chartData.map((a, i) => {
|
||||
const ret = Object.assign({}, a);
|
||||
ret.y = smoothedWpmData[i];
|
||||
return ret;
|
||||
});
|
||||
|
||||
const accChartData2 = accChartData.map((a, i) => {
|
||||
const ret = Object.assign({}, a);
|
||||
ret.y = smoothedAccData[i];
|
||||
return ret;
|
||||
});
|
||||
|
||||
ChartController.accountHistory.data.datasets[0].data = chartData2;
|
||||
ChartController.accountHistory.data.datasets[1].data = accChartData2;
|
||||
|
||||
if (chartData2.length || accChartData2.length) {
|
||||
ChartController.accountHistory.options.animation = false;
|
||||
ChartController.accountHistory.update();
|
||||
delete ChartController.accountHistory.options.animation;
|
||||
}
|
||||
}
|
||||
|
||||
async function applyHistorySmoothing(): Promise<void> {
|
||||
const smoothing = $(
|
||||
".pageAccount .content .below .smoothing input"
|
||||
).val() as string;
|
||||
$(".pageAccount .content .below .smoothing .value").text(smoothing);
|
||||
smoothHistory(parseInt(smoothing));
|
||||
await Misc.sleep(0);
|
||||
}
|
||||
|
||||
function fillContent(): void {
|
||||
LoadingPage.updateText("Displaying stats...");
|
||||
LoadingPage.updateBar(100);
|
||||
|
|
@ -310,6 +274,9 @@ function fillContent(): void {
|
|||
|
||||
filteredResults = [];
|
||||
$(".pageAccount .history table tbody").empty();
|
||||
|
||||
let testNum = DB.getSnapshot()?.results?.length || 0;
|
||||
|
||||
DB.getSnapshot()?.results?.forEach(
|
||||
(result: MonkeyTypes.Result<MonkeyTypes.Mode>) => {
|
||||
// totalSeconds += tt;
|
||||
|
|
@ -634,7 +601,7 @@ function fillContent(): void {
|
|||
}
|
||||
|
||||
chartData.push({
|
||||
x: result.timestamp,
|
||||
x: testNum,
|
||||
y: Config.alwaysShowCPM ? Misc.roundTo2(result.wpm * 5) : result.wpm,
|
||||
wpm: Config.alwaysShowCPM ? Misc.roundTo2(result.wpm * 5) : result.wpm,
|
||||
acc: result.acc,
|
||||
|
|
@ -653,11 +620,13 @@ function fillContent(): void {
|
|||
wpmChartData.push(result.wpm);
|
||||
|
||||
accChartData.push({
|
||||
x: result.timestamp,
|
||||
y: 100 - result.acc,
|
||||
x: testNum,
|
||||
y: result.acc,
|
||||
errorRate: 100 - result.acc,
|
||||
});
|
||||
|
||||
testNum--;
|
||||
|
||||
if (result.wpm > topWpm) {
|
||||
const puncsctring = result.punctuation ? ",<br>with punctuation" : "";
|
||||
const numbsctring = result.numbers
|
||||
|
|
@ -759,8 +728,76 @@ function fillContent(): void {
|
|||
accountHistoryScaleOptions["wpm"].title.text = "Words per Minute";
|
||||
}
|
||||
|
||||
ChartController.accountHistory.data.datasets[0].data = chartData;
|
||||
ChartController.accountHistory.data.datasets[1].data = accChartData;
|
||||
if (chartData.length > 0) {
|
||||
chartData.reverse();
|
||||
accChartData.reverse();
|
||||
|
||||
// get pb points
|
||||
let currentPb = 0;
|
||||
const pb: { x: number; y: number }[] = [];
|
||||
|
||||
chartData.forEach((a) => {
|
||||
if (a.y > currentPb) {
|
||||
currentPb = a.y;
|
||||
pb.push(a);
|
||||
}
|
||||
});
|
||||
|
||||
// add last point to pb
|
||||
const xMax = chartData.length;
|
||||
|
||||
pb.push({
|
||||
x: xMax,
|
||||
y: pb[pb.length - 1].y,
|
||||
});
|
||||
|
||||
const avgTen = [];
|
||||
const avgTenAcc = [];
|
||||
const avgHundred = [];
|
||||
const avgHundredAcc = [];
|
||||
|
||||
for (let i = 0; i < chartData.length; i++) {
|
||||
// calculate 10 subset averages
|
||||
const startIdxTen = i < 10 ? 0 : i - 9;
|
||||
const subsetTen = chartData.slice(startIdxTen, i + 1);
|
||||
const accSubsetTen = accChartData.slice(startIdxTen, i + 1);
|
||||
const avgTenValue =
|
||||
subsetTen.reduce((acc, { y }) => acc + y, 0) / subsetTen.length;
|
||||
const accAvgTenValue =
|
||||
accSubsetTen.reduce((acc, { y }) => acc + y, 0) / subsetTen.length;
|
||||
|
||||
// add values to arrays
|
||||
avgTen.push({ x: i + 1, y: avgTenValue });
|
||||
avgTenAcc.push({ x: i + 1, y: accAvgTenValue });
|
||||
|
||||
// calculate 100 subset averages
|
||||
const startIdxHundred = i < 100 ? 0 : i - 99;
|
||||
const subsetHundred = chartData.slice(startIdxHundred, i + 1);
|
||||
const accSubsetHundred = accChartData.slice(startIdxHundred, i + 1);
|
||||
const avgHundredValue =
|
||||
subsetHundred.reduce((acc, { y }) => acc + y, 0) / subsetHundred.length;
|
||||
const accAvgHundredValue =
|
||||
accSubsetHundred.reduce((acc, { y }) => acc + y, 0) /
|
||||
subsetHundred.length;
|
||||
|
||||
// add values to arrays
|
||||
avgHundred.push({ x: i + 1, y: avgHundredValue });
|
||||
avgHundredAcc.push({ x: i + 1, y: accAvgHundredValue });
|
||||
}
|
||||
|
||||
ChartController.accountHistory.data.datasets[0].data = chartData;
|
||||
ChartController.accountHistory.data.datasets[1].data = pb;
|
||||
ChartController.accountHistory.data.datasets[2].data = accChartData;
|
||||
ChartController.accountHistory.data.datasets[3].data = avgTen;
|
||||
ChartController.accountHistory.data.datasets[4].data = avgTenAcc;
|
||||
ChartController.accountHistory.data.datasets[5].data = avgHundred;
|
||||
ChartController.accountHistory.data.datasets[6].data = avgHundredAcc;
|
||||
|
||||
accountHistoryScaleOptions["x"].max = xMax + 1;
|
||||
|
||||
chartData.reverse();
|
||||
accChartData.reverse();
|
||||
}
|
||||
|
||||
const wpms = chartData.map((r) => r.y);
|
||||
const minWpmChartVal = Math.min(...wpms);
|
||||
|
|
@ -769,6 +806,12 @@ function fillContent(): void {
|
|||
// let accuracies = accChartData.map((r) => r.y);
|
||||
accountHistoryScaleOptions["wpm"].max =
|
||||
Math.floor(maxWpmChartVal) + (10 - (Math.floor(maxWpmChartVal) % 10));
|
||||
accountHistoryScaleOptions["pb"].max =
|
||||
Math.floor(maxWpmChartVal) + (10 - (Math.floor(maxWpmChartVal) % 10));
|
||||
accountHistoryScaleOptions["wpmAvgTen"].max =
|
||||
Math.floor(maxWpmChartVal) + (10 - (Math.floor(maxWpmChartVal) % 10));
|
||||
accountHistoryScaleOptions["wpmAvgHundred"].max =
|
||||
Math.floor(maxWpmChartVal) + (10 - (Math.floor(maxWpmChartVal) % 10));
|
||||
|
||||
if (!Config.startGraphsAtZero) {
|
||||
accountHistoryScaleOptions["wpm"].min = Math.floor(minWpmChartVal);
|
||||
|
|
@ -800,8 +843,6 @@ function fillContent(): void {
|
|||
Misc.secondsToString(Math.round(totalSecondsFiltered), true, true)
|
||||
);
|
||||
|
||||
const wpmCpm = Config.alwaysShowCPM ? "cpm" : "wpm";
|
||||
|
||||
let highestSpeed: number | string = topWpm;
|
||||
if (Config.alwaysShowCPM) {
|
||||
highestSpeed = topWpm * 5;
|
||||
|
|
@ -812,6 +853,8 @@ function fillContent(): void {
|
|||
highestSpeed = Math.round(highestSpeed);
|
||||
}
|
||||
|
||||
const wpmCpm = Config.alwaysShowCPM ? "cpm" : "wpm";
|
||||
|
||||
$(".pageAccount .highestWpm .title").text(`highest ${wpmCpm}`);
|
||||
$(".pageAccount .highestWpm .val").text(highestSpeed);
|
||||
|
||||
|
|
@ -981,12 +1024,17 @@ function fillContent(): void {
|
|||
Misc.roundTo2(
|
||||
Config.alwaysShowCPM ? wpmChangePerHour * 5 : wpmChangePerHour
|
||||
)
|
||||
} ${Config.alwaysShowCPM ? "cpm" : "wpm"}.`
|
||||
} ${Config.alwaysShowCPM ? "cpm" : "wpm"}`
|
||||
);
|
||||
|
||||
$(".pageAccount .estimatedWordsTyped .val").text(totalEstimatedWords);
|
||||
|
||||
applyHistorySmoothing();
|
||||
if (chartData.length || accChartData.length) {
|
||||
ChartController.accountHistory.options.animation = false;
|
||||
ChartController.accountHistory.update();
|
||||
delete ChartController.accountHistory.options.animation;
|
||||
}
|
||||
|
||||
ChartController.accountActivity.update();
|
||||
ChartController.accountHistogram.update();
|
||||
LoadingPage.updateBar(100, true);
|
||||
|
|
@ -1117,15 +1165,15 @@ function sortAndRefreshHistory(
|
|||
}
|
||||
|
||||
$(".pageAccount .toggleAccuracyOnChart").on("click", () => {
|
||||
UpdateConfig.setChartAccuracy(!Config.chartAccuracy);
|
||||
UpdateConfig.setAccountChartAccuracy(!(Config.accountChart[0] == "on"));
|
||||
});
|
||||
|
||||
$(".pageAccount .toggleChartStyle").on("click", () => {
|
||||
if (Config.chartStyle == "line") {
|
||||
UpdateConfig.setChartStyle("scatter");
|
||||
} else {
|
||||
UpdateConfig.setChartStyle("line");
|
||||
}
|
||||
$(".pageAccount .toggleAverage10OnChart").on("click", () => {
|
||||
UpdateConfig.setAccountChartAvg10(!(Config.accountChart[1] == "on"));
|
||||
});
|
||||
|
||||
$(".pageAccount .toggleAverage100OnChart").on("click", () => {
|
||||
UpdateConfig.setAccountChartAvg100(!(Config.accountChart[2] == "on"));
|
||||
});
|
||||
|
||||
$(".pageAccount .loadMoreButton").on("click", () => {
|
||||
|
|
@ -1232,10 +1280,6 @@ $(".pageAccount .group.presetFilterButtons").on(
|
|||
}
|
||||
);
|
||||
|
||||
$(".pageAccount .content .below .smoothing input").on("input", () => {
|
||||
applyHistorySmoothing();
|
||||
});
|
||||
|
||||
$(".pageAccount .content .group.aboveHistory .exportCSV").on("click", () => {
|
||||
Misc.downloadResultsCSV(filteredResults);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -118,6 +118,11 @@ const list: MonkeyTypes.FunboxMetadata[] = [
|
|||
info: "Only two future words are visible.",
|
||||
properties: ["changesWordsVisibility", "toPush:3", "noInfiniteDuration"],
|
||||
},
|
||||
{
|
||||
name: "plus_three",
|
||||
info: "Only three future words are visible.",
|
||||
properties: ["changesWordsVisibility", "toPush:4", "noInfiniteDuration"],
|
||||
},
|
||||
{
|
||||
name: "read_ahead_easy",
|
||||
info: "Only the current word is invisible.",
|
||||
|
|
|
|||
|
|
@ -901,14 +901,25 @@ 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) ||
|
||||
(Config.mode === "custom" &&
|
||||
!CustomText.isTimeRandom &&
|
||||
CustomText.word < wordsBound)
|
||||
) {
|
||||
if (Config.mode === "words" && Config.words < wordsBound) {
|
||||
wordsBound = Config.words;
|
||||
}
|
||||
if (
|
||||
Config.mode === "custom" &&
|
||||
!CustomText.isTimeRandom &&
|
||||
CustomText.isWordRandom &&
|
||||
CustomText.word < wordsBound
|
||||
) {
|
||||
wordsBound = CustomText.word;
|
||||
}
|
||||
if (
|
||||
Config.mode === "custom" &&
|
||||
!CustomText.isTimeRandom &&
|
||||
!CustomText.isWordRandom &&
|
||||
CustomText.text.length < wordsBound
|
||||
) {
|
||||
wordsBound = CustomText.text.length;
|
||||
}
|
||||
} else if (Config.showAllLines) {
|
||||
if (Config.mode === "quote") {
|
||||
wordsBound = 100;
|
||||
|
|
@ -1798,7 +1809,7 @@ async function saveResult(
|
|||
}
|
||||
DB.saveLocalResult(completedEvent);
|
||||
DB.updateLocalStats(
|
||||
TestStats.restartCount + 1,
|
||||
completedEvent.incompleteTests.length + 1,
|
||||
completedEvent.testDuration +
|
||||
completedEvent.incompleteTestSeconds -
|
||||
completedEvent.afkDuration
|
||||
|
|
|
|||
|
|
@ -54,6 +54,8 @@ ConfigEvent.subscribe((eventKey, eventValue, nosave) => {
|
|||
updateWordsInputPosition(true);
|
||||
}
|
||||
|
||||
if (eventKey === "theme") applyBurstHeatmap();
|
||||
|
||||
if (eventValue === undefined || typeof eventValue !== "boolean") return;
|
||||
if (eventKey === "flipTestColors") flipColors(eventValue);
|
||||
if (eventKey === "colorfulMode") colorful(eventValue);
|
||||
|
|
|
|||
10
frontend/src/ts/types/types.d.ts
vendored
10
frontend/src/ts/types/types.d.ts
vendored
|
|
@ -119,7 +119,7 @@ declare namespace MonkeyTypes {
|
|||
|
||||
type PageWidth = "100" | "125" | "150" | "200" | "max";
|
||||
|
||||
type ChartStyle = "line" | "scatter";
|
||||
type AccountChart = ("off" | "on")[];
|
||||
|
||||
type MinimumWordsPerMinute = "off" | "custom";
|
||||
|
||||
|
|
@ -177,6 +177,11 @@ declare namespace MonkeyTypes {
|
|||
errorRate: number;
|
||||
}
|
||||
|
||||
interface OtherChartData {
|
||||
x: number;
|
||||
y: number;
|
||||
}
|
||||
|
||||
interface ActivityChartDataPoint {
|
||||
x: number;
|
||||
y: number;
|
||||
|
|
@ -448,8 +453,7 @@ declare namespace MonkeyTypes {
|
|||
paceCaretCustomSpeed: number;
|
||||
repeatedPace: boolean;
|
||||
pageWidth: PageWidth;
|
||||
chartAccuracy: boolean;
|
||||
chartStyle: ChartStyle;
|
||||
accountChart: AccountChart;
|
||||
minWpm: MinimumWordsPerMinute;
|
||||
minWpmCustomSpeed: number;
|
||||
highlightMode: HighlightMode;
|
||||
|
|
|
|||
|
|
@ -288,6 +288,7 @@ function hexToRgb(hex: string):
|
|||
} else {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return { r, g, b };
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -94,6 +94,11 @@
|
|||
"info": "Only two future words are visible.",
|
||||
"canGetPb": true
|
||||
},
|
||||
{
|
||||
"name": "plus_three",
|
||||
"info": "Only three future words are visible.",
|
||||
"canGetPb": true
|
||||
},
|
||||
{
|
||||
"name": "read_ahead_easy",
|
||||
"info": "Only the current word is invisible.",
|
||||
|
|
|
|||
|
|
@ -430,21 +430,21 @@
|
|||
<div class="chart">
|
||||
<canvas id="accountHistoryChart"></canvas>
|
||||
</div>
|
||||
|
||||
<div class="below">
|
||||
<div class="text"></div>
|
||||
<div class="buttons">
|
||||
<div class="smoothing">
|
||||
<div class="title">smoothing</div>
|
||||
<div class="value">0</div>
|
||||
<input type="range" min="0" max="20" value="0" step="1" />
|
||||
</div>
|
||||
<div class="toggleAccuracyOnChart button">
|
||||
<i class="fas fa-bullseye"></i>
|
||||
Toggle Accuracy
|
||||
Accuracy
|
||||
</div>
|
||||
<div class="toggleChartStyle button">
|
||||
<div class="toggleAverage10OnChart button">
|
||||
<i class="fas fa-chart-line"></i>
|
||||
Toggle Chart Style
|
||||
Avg of 10
|
||||
</div>
|
||||
<div class="toggleAverage100OnChart button">
|
||||
<i class="fas fa-chart-line"></i>
|
||||
Avg of 100
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -272,7 +272,7 @@
|
|||
},
|
||||
{
|
||||
"name": "swedish",
|
||||
"languages": ["swedish", "swedish_1k"]
|
||||
"languages": ["swedish", "swedish_1k", "swedish_diacritics"]
|
||||
},
|
||||
{
|
||||
"name": "serbian",
|
||||
|
|
|
|||
|
|
@ -151,6 +151,7 @@
|
|||
,"hausa_1k"
|
||||
,"swedish"
|
||||
,"swedish_1k"
|
||||
,"swedish_diacritics"
|
||||
,"serbian"
|
||||
,"yoruba_1k"
|
||||
,"swahili_1k"
|
||||
|
|
|
|||
|
|
@ -185,6 +185,7 @@
|
|||
["neighbored", "neighboured"],
|
||||
["neighbor", "neighbour"],
|
||||
["neighbors", "neighbours"],
|
||||
["neighboring", "neighbouring"],
|
||||
["magnetizer", "magnetiser"],
|
||||
["appetizer", "appetiser"],
|
||||
["hebraizing", "hebraising"],
|
||||
|
|
|
|||
|
|
@ -2924,7 +2924,7 @@
|
|||
"negotiation",
|
||||
"neighbor",
|
||||
"neighborhood",
|
||||
"neighbouring",
|
||||
"neighboring",
|
||||
"neither",
|
||||
"nerve",
|
||||
"nervous",
|
||||
|
|
|
|||
268
frontend/static/languages/swedish_diacritics.json
Normal file
268
frontend/static/languages/swedish_diacritics.json
Normal file
|
|
@ -0,0 +1,268 @@
|
|||
{
|
||||
"name": "swedish_diacritics",
|
||||
"leftToRight": true,
|
||||
"bcp47": "sv-SE",
|
||||
"words": [
|
||||
"blåbär",
|
||||
"blågrå",
|
||||
"blåräv",
|
||||
"blåröd",
|
||||
"blåträ",
|
||||
"blåögd",
|
||||
"bågsåg",
|
||||
"bärvåg",
|
||||
"bärår",
|
||||
"böjträ",
|
||||
"börsår",
|
||||
"dådlös",
|
||||
"därför",
|
||||
"därhän",
|
||||
"därpå",
|
||||
"däråt",
|
||||
"dödsjö",
|
||||
"dödsår",
|
||||
"frångå",
|
||||
"fåfäng",
|
||||
"fåmäld",
|
||||
"fårlår",
|
||||
"fåtölj",
|
||||
"fänkål",
|
||||
"fästmö",
|
||||
"fäsör",
|
||||
"förbön",
|
||||
"föregå",
|
||||
"förgå",
|
||||
"förgås",
|
||||
"förhör",
|
||||
"förklä",
|
||||
"förköp",
|
||||
"förlåt",
|
||||
"förmå",
|
||||
"förmån",
|
||||
"förnäm",
|
||||
"förnär",
|
||||
"förråa",
|
||||
"förråd",
|
||||
"förrän",
|
||||
"förslå",
|
||||
"försmå",
|
||||
"förstå",
|
||||
"försåt",
|
||||
"försök",
|
||||
"förvår",
|
||||
"förväg",
|
||||
"förår",
|
||||
"förära",
|
||||
"föräta",
|
||||
"föröda",
|
||||
"föröka",
|
||||
"föröva",
|
||||
"gråblå",
|
||||
"grågås",
|
||||
"gråsäl",
|
||||
"gråögd",
|
||||
"gåpåig",
|
||||
"gåsört",
|
||||
"gåtåg",
|
||||
"gökärt",
|
||||
"håglös",
|
||||
"hålkäl",
|
||||
"hålslå",
|
||||
"hålsöm",
|
||||
"hålväg",
|
||||
"hålögd",
|
||||
"hårfön",
|
||||
"hårlös",
|
||||
"hårnål",
|
||||
"hårnät",
|
||||
"håröm",
|
||||
"härför",
|
||||
"härpå",
|
||||
"härtåg",
|
||||
"härväg",
|
||||
"häråt",
|
||||
"häxbål",
|
||||
"häxört",
|
||||
"höfång",
|
||||
"högblå",
|
||||
"högröd",
|
||||
"höhäck",
|
||||
"höstså",
|
||||
"hösäck",
|
||||
"hövålm",
|
||||
"jämväl",
|
||||
"järnår",
|
||||
"knähög",
|
||||
"knärör",
|
||||
"kåsör",
|
||||
"kåsös",
|
||||
"köksö",
|
||||
"kölbåt",
|
||||
"könlös",
|
||||
"köpråd",
|
||||
"köpslå",
|
||||
"körspö",
|
||||
"körväg",
|
||||
"låglön",
|
||||
"läläge",
|
||||
"läroår",
|
||||
"läsår",
|
||||
"lättöl",
|
||||
"löksås",
|
||||
"lönlös",
|
||||
"löshår",
|
||||
"lössnö",
|
||||
"lösöre",
|
||||
"lövlös",
|
||||
"lövsåg",
|
||||
"löväng",
|
||||
"måbär",
|
||||
"måfå",
|
||||
"mållös",
|
||||
"månår",
|
||||
"märsrå",
|
||||
"nådeår",
|
||||
"nåväl",
|
||||
"närapå",
|
||||
"närköp",
|
||||
"nödlån",
|
||||
"nödår",
|
||||
"nöthår",
|
||||
"påbrå",
|
||||
"påbröd",
|
||||
"påföra",
|
||||
"pågå",
|
||||
"påhäng",
|
||||
"påkörd",
|
||||
"pålägg",
|
||||
"påläst",
|
||||
"påsköl",
|
||||
"påstå",
|
||||
"påstöt",
|
||||
"påtår",
|
||||
"påtänd",
|
||||
"påväxt",
|
||||
"påökt",
|
||||
"rådlös",
|
||||
"rådslå",
|
||||
"rågång",
|
||||
"rårörd",
|
||||
"råstål",
|
||||
"råämne",
|
||||
"rättså",
|
||||
"rävröd",
|
||||
"rödblå",
|
||||
"rödkål",
|
||||
"rödlök",
|
||||
"rödräv",
|
||||
"rödögd",
|
||||
"röjsåg",
|
||||
"rötägg",
|
||||
"rövhål",
|
||||
"sjöblå",
|
||||
"sjönöd",
|
||||
"sjönöt",
|
||||
"sjörök",
|
||||
"sjöväg",
|
||||
"slösäd",
|
||||
"småbåt",
|
||||
"småkär",
|
||||
"smålån",
|
||||
"småsjö",
|
||||
"småsår",
|
||||
"småväg",
|
||||
"småäta",
|
||||
"snöbär",
|
||||
"snöhög",
|
||||
"snölös",
|
||||
"snörök",
|
||||
"sådär",
|
||||
"såhär",
|
||||
"sångmö",
|
||||
"sånär",
|
||||
"såpört",
|
||||
"såväl",
|
||||
"sädgås",
|
||||
"säldöd",
|
||||
"sälhål",
|
||||
"sökväg",
|
||||
"sömhål",
|
||||
"sömlös",
|
||||
"träbåt",
|
||||
"träkåk",
|
||||
"trälår",
|
||||
"träpåk",
|
||||
"tvåårs",
|
||||
"tvärdö",
|
||||
"tågrån",
|
||||
"tåjärn",
|
||||
"tålös",
|
||||
"tårlös",
|
||||
"tårögd",
|
||||
"tätört",
|
||||
"töföre",
|
||||
"töjmån",
|
||||
"tösnö",
|
||||
"vrålåk",
|
||||
"vågrät",
|
||||
"vårdkö",
|
||||
"vårlök",
|
||||
"vårså",
|
||||
"vårsäd",
|
||||
"våtår",
|
||||
"väglös",
|
||||
"vägnät",
|
||||
"vägrån",
|
||||
"västpå",
|
||||
"åbrädd",
|
||||
"åbäka",
|
||||
"åbäke",
|
||||
"åbäkig",
|
||||
"ådöma",
|
||||
"åfåra",
|
||||
"åhåga",
|
||||
"åhöra",
|
||||
"åkhöjd",
|
||||
"åkpåse",
|
||||
"ålgräs",
|
||||
"ålägga",
|
||||
"åmålit",
|
||||
"ångbåt",
|
||||
"ångrör",
|
||||
"ångtåg",
|
||||
"årgång",
|
||||
"årslön",
|
||||
"åskblå",
|
||||
"åskrön",
|
||||
"åskåda",
|
||||
"åsätta",
|
||||
"åtbörd",
|
||||
"återfå",
|
||||
"återgå",
|
||||
"åtgå",
|
||||
"åtgång",
|
||||
"åtgärd",
|
||||
"åtlöje",
|
||||
"åtnöja",
|
||||
"åtrå",
|
||||
"äggört",
|
||||
"älgört",
|
||||
"ändlös",
|
||||
"ändträ",
|
||||
"ändå",
|
||||
"ängshö",
|
||||
"ärekär",
|
||||
"ärelös",
|
||||
"ärmhål",
|
||||
"ärmlös",
|
||||
"ävenså",
|
||||
"öbåge",
|
||||
"ödesår",
|
||||
"ökänd",
|
||||
"öltält",
|
||||
"örtsås",
|
||||
"östpå",
|
||||
"övergå",
|
||||
"övärld"
|
||||
]
|
||||
}
|
||||
|
|
@ -494,6 +494,17 @@
|
|||
"row5": [" "]
|
||||
}
|
||||
},
|
||||
"mongolian": {
|
||||
"keymapShowTopRow": true,
|
||||
"type": "ansi",
|
||||
"keys": {
|
||||
"row1": ["=+", "№1", "-2", "\"3", "₮4", ":5", ".6", "_7", ",8", "%9", "?0", "еЕ", "щЩ"],
|
||||
"row2": ["фФ", "цЦ", "уУ", "жЖ", "эЭ", "нН", "гГ", "шШ", "үҮ", "зЗ", "кК", "ъЪ", "\\|"],
|
||||
"row3": ["йЙ", "ыЫ", "бБ", "өӨ", "аА", "хХ", "рР", "оО", "лЛ", "дД", "пП"],
|
||||
"row4": ["яЯ", "чЧ", "ёЁ", "сС", "мМ", "иИ", "тТ", "ьЬ", "вВ", "юЮ"],
|
||||
"row5": [" "]
|
||||
}
|
||||
},
|
||||
"JCUKEN": {
|
||||
"keymapShowTopRow": true,
|
||||
"type": "ansi",
|
||||
|
|
@ -740,10 +751,10 @@
|
|||
"keymapShowTopRow": true,
|
||||
"type": "ansi",
|
||||
"keys": {
|
||||
"row1": ["-%", "ๅ+", "/๑", "_๒", "ภ๓", "ถ๔", "ุู", "ึ฿", "ค๕", "ต๖", "จ๗", "ข๘", "ช๙"],
|
||||
"row1": ["_%", "ๅ+", "/๑", "-๒", "ภ๓", "ถ๔", "ุู", "ึ฿", "ค๕", "ต๖", "จ๗", "ข๘", "ช๙"],
|
||||
"row2": ["ๆ๐", "ไ\"", "ำฎ", "พฑ", "ะธ", "ัํ", "ี๊", "รณ", "นฯ", "ยญ", "บฐ", "ล,", "ฃฅ"],
|
||||
"row3": ["ฟฤ", "หฆ", "กฏ", "ดโ", "เฌ", "้็", "่๋", "าษ", "สศ", "วซ", "ง."],
|
||||
"row4": ["ฃฅ", "ผ(", "ป)", "แฉ", "อฮ", "ิฺ", "ื์", "ท?", "มฒ", "ใฬ"],
|
||||
"row4": ["ผ(", "ป)", "แฉ", "อฮ", "ิฺ", "ื์", "ท?", "มฒ", "ใฬ", "ฝฦ"],
|
||||
"row5": [" "]
|
||||
}
|
||||
},
|
||||
|
|
|
|||
|
|
@ -4783,12 +4783,6 @@
|
|||
"id": 814,
|
||||
"length": 355
|
||||
},
|
||||
{
|
||||
"text": "There's no more harm in a kiss than shaving a monkey and pretending it's a woman.",
|
||||
"source": "QI",
|
||||
"id": 815,
|
||||
"length": 81
|
||||
},
|
||||
{
|
||||
"text": "The most precious treasures we have in life are the images we store in the memory banks of our brains. The sum of these stored experiences is responsible for our sense of personal identity and our sense of connectedness to those around us.",
|
||||
"source": "Change Your Brain, Change Your Life",
|
||||
|
|
@ -6745,12 +6739,6 @@
|
|||
"id": 1148,
|
||||
"length": 211
|
||||
},
|
||||
{
|
||||
"text": "They say that right after God created man, he took a rib from him and made a chick. That's actually a bit of a creation myth - the truth is, after God saw that man was good, he created another man and saw that it was all good.",
|
||||
"source": "Brocabulary: The New Man-i-festo of Dude Talk",
|
||||
"id": 1149,
|
||||
"length": 226
|
||||
},
|
||||
{
|
||||
"text": "When the snow is on our mind, rows and rows and lines and lines. In the haze of your fixation, we all crave for you, we all crave. And you can kill the wildest thing, but when you murder it's a sin. In the midst of your conviction, we all crave for you, we all crave.",
|
||||
"source": "Crave",
|
||||
|
|
@ -11577,7 +11565,7 @@
|
|||
},
|
||||
{
|
||||
"text": "The world ain't all sunshine and rainbows. It's a very mean and nasty place and I don't care how tough you are, it will beat you to your knees and keep you there permanently if you let it. You, me, or nobody is gonna hit as hard as life. But it ain't about how hard you hit. It's about how hard you can get hit and keep moving forward. That's how winning is done! Now if you know what you're worth then go out and get what you're worth. But you've gotta be willing to take the hits, and not pointing fingers saying you ain't where you wanna be because of him, or her, or anybody! Cowards do that and that ain't you! You're better than that!",
|
||||
"source": "Rocky IV",
|
||||
"source": "Rocky Balboa (2006)",
|
||||
"id": 1984,
|
||||
"length": 640
|
||||
},
|
||||
|
|
@ -15991,12 +15979,6 @@
|
|||
"id": 2753,
|
||||
"length": 174
|
||||
},
|
||||
{
|
||||
"text": "I know you're coming in the night like a thief, but I've had some time alone to hone my lying technique. I know you think that I'm someone you can trust, but I'm scared I'll get scared and I swear I'll try to nail you back up.",
|
||||
"source": "Jesus Christ",
|
||||
"id": 2754,
|
||||
"length": 226
|
||||
},
|
||||
{
|
||||
"text": "Keep drinking coffee, stare me down across the table while I look outside. So many things I'd say if only I were able, but I just keep quiet and count the cars that pass by.",
|
||||
"source": "King of Anything",
|
||||
|
|
@ -28039,12 +28021,6 @@
|
|||
"id": 4844,
|
||||
"length": 281
|
||||
},
|
||||
{
|
||||
"text": "The oracles of God foretold the rising of an Antichrist in the Christian Church: and in the Pope of Rome, all the characteristics of that Antichrist are so marvelously answered that if any who read the Scriptures do not see it, there is a marvelous blindness upon them.",
|
||||
"source": "Prophetic Faith of Our Fathers Vol 3",
|
||||
"id": 4845,
|
||||
"length": 269
|
||||
},
|
||||
{
|
||||
"text": "We didn't start the fire. It was always burning since the world's been turning. We didn't start the fire. No, we didn't light it, but we tried to fight it.",
|
||||
"source": "We Didn't Start the Fire",
|
||||
|
|
|
|||
|
|
@ -762,6 +762,24 @@
|
|||
"source": "Marshal D. Teach - One Piece",
|
||||
"length": 150,
|
||||
"id": 126
|
||||
},
|
||||
{
|
||||
"text": "Ayer tuve un amor que hoy me abandonó porque no me quería. Fue tanta la ilusión por hacerla feliz pero todo fue en vano.",
|
||||
"source": "Manuel Jiménez. Máximo Fonseca - Ayer y Hoy",
|
||||
"length": 120,
|
||||
"id": 127
|
||||
},
|
||||
{
|
||||
"text": "Ódiame por piedad yo te lo pido, ódiame sin medida ni clemencia. Odio quiero más que indiferencia, porque el rencor hiere menos que el olvido.",
|
||||
"source": "Rafael Otero López - Ódiame",
|
||||
"length": 142,
|
||||
"id": 128
|
||||
},
|
||||
{
|
||||
"text": "Dicen que con el tiempo los recuerdos se esfuman. Se ahonda en el olvido lo que fue una pasión, Mentira, cuando mueras y bajas a mi tumba verás que aún por ti arde la llama de mi amor.",
|
||||
"source": "Luis Aguirre Pinto - Reminiscencias",
|
||||
"length": 184,
|
||||
"id": 129
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue