Only show accPenalty if it's relevant. Still need to build and test :)
### Description
<!-- Please describe the change(s) made in your PR -->
### Checks
- [ ] Adding quotes?
- [ ] Make sure to include translations for the quotes in the
description (or another comment) so we can verify their content.
- [ ] Adding a language?
- Make sure to follow the [languages
documentation](https://github.com/monkeytypegame/monkeytype/blob/master/docs/LANGUAGES.md)
- [ ] Add language to `packages/contracts/src/schemas/languages.ts`
- [ ] Add language to exactly one group in
`frontend/src/ts/constants/languages.ts`
- [ ] Add language json file to `frontend/static/languages`
- [ ] Adding a theme?
- Make sure to follow the [themes
documentation](https://github.com/monkeytypegame/monkeytype/blob/master/docs/THEMES.md)
- [ ] Add theme to `packages/contracts/src/schemas/themes.ts`
- [ ] Add theme to `frontend/src/ts/constants/themes.ts`
- [ ] Add theme css file to `frontend/static/themes`
- Also please add a screenshot of the theme, it would be extra awesome
if you do so!
- [ ] Adding a layout?
- [ ] Make sure to follow the [layouts
documentation](https://github.com/monkeytypegame/monkeytype/blob/master/docs/LAYOUTS.md)
- [ ] Add layout to `packages/contracts/src/schemas/layouts.ts`
- [ ] Add layout json file to `frontend/static/layouts`
- [x] Check if any open issues are related to this PR; if so, be sure to
tag them below.
- [x] Make sure the PR title follows the Conventional Commits standard.
(https://www.conventionalcommits.org for more info)
- [x] Make sure to include your GitHub username prefixed with @ inside
parentheses at the end of the PR title.
<!-- label(optional scope): pull request title (@your_github_username)
-->
<!-- I know I know they seem boring but please do them, they help us and
you will find out it also helps you.-->
Closes #
<!-- the issue(s) your PR resolves if any (delete if that is not the
case) -->
<!-- please also reference any issues and or PRs related to your pull
request -->
<!-- Also remove it if you are not following any issues. -->
<!-- pro tip: you can mention an issue, PR, or discussion on GitHub by
referencing its hash number e.g:
[#1234](https://github.com/monkeytypegame/monkeytype/pull/1234) -->
<!-- pro tip: you can press . (dot or period) in the code tab of any
GitHub repo to get access to GitHub's VS Code web editor Enjoy! :) -->
### Description
This adds Njutro (An idiolect of Viossa) to Monkeytype.
### Checks
- [X] Adding a language
- [X] Added language to `packages/contracts/src/schemas/languages.ts`
- [X] Added language to exactly one group in
`frontend/src/ts/constants/languages.ts`
- [X] Added language json file to `frontend/static/languages`
- [X] Checked if there are any open issues are related to this PR.
- [X] PR title follows Conventional Commits standard.
- [X] Included GitHub username prefixed with @ inside parentheses at the
end of the PR title.
---------
Co-authored-by: Nginearing <142851004+Nginearing@users.noreply.github.com>
### Description
Added 1 quote from the Outlast game in english.
### Checks
- [x] Adding quotes?
- [ ] Make sure to include translations for the quotes in the
description (or another comment) so we can verify their content.
- [x] Check if any open issues are related to this PR; if so, be sure to
tag them below.
- [x] Make sure the PR title follows the Conventional Commits standard.
(https://www.conventionalcommits.org for more info)
- [x] Make sure to include your GitHub username prefixed with @ inside
parentheses at the end of the PR title.
<!-- label(optional scope): pull request title (@your_github_username)
-->
<!-- I know I know they seem boring but please do them, they help us and
you will find out it also helps you.-->
<!-- the issue(s) your PR resolves if any (delete if that is not the
case) -->
<!-- please also reference any issues and or PRs related to your pull
request -->
<!-- Also remove it if you are not following any issues. -->
<!-- pro tip: you can mention an issue, PR, or discussion on GitHub by
referencing its hash number e.g:
[#1234](https://github.com/monkeytypegame/monkeytype/pull/1234) -->
<!-- pro tip: you can press . (dot or period) in the code tab of any
GitHub repo to get access to GitHub's VS Code web editor Enjoy! :) -->
### Description
This PR fixes two related caret positioning issues that occurred
**before any user input**:
* **Resize Bug**:
Resizing the browser immediately after a page refresh caused the caret
to appear misaligned. The position only corrected itself after the user
typed the first character.
* **Navigation Bug**:
Navigating away from the test page and back (especially after a refresh)
caused the caret to initially render in the wrong position, then animate
into place.
---
### Solution
* Refactor `Caret.updatePosition()` to use `getComputedStyle` for
width/height instead of `getBoundingClientRect()` and `offsetHeight`
makes caret positioning more accurate.
* Redundant calls to Caret.updatePosition() have been removed from the
resize handler, relying instead on the more
comprehensive caret re-initialization.
These changes resolve caret alignment and animation issues after
loading, resizing, or navigating, including in tape mode.
---
> ~~Replaced early calls to `Caret.updatePosition()` with `Caret.show()`
when no input has been entered yet.~~
> ~~`Caret.show()` ensures the caret is:~~
> ~~* Visible~~
> ~~* Properly initialized~~
> ~~* Animated via `startAnimation()`~~
> ~~* Positioned correctly via internal `updatePosition()` call~~
> ~~Once the caret is initialized (i.e., after first input), we continue
using `updatePosition()` directly for subsequent updates.~~
>
---
Closes#6639
### Description
In RTL tape mode (which will be a reality after #5748), if a long word
is wider than the #wordsWrapper, then #wordsInput may overflow to the
left causing a horizontal scroll to keep it in view. This PR prevents
its left edge from overflowing the #wordsWrapper.
Co-authored-by: Jack <jack@monkeytype.com>
### Description
Added quotes from Russian classics.
### Translations
1090: The sun was already beginning to hide behind the snowy ridge when
I entered the Koishaur valley. The Ossetian coachman was tirelessly
chasing his horses in order to climb the Koishaur mountain before
nightfall, and singing songs at the top of his voice. This valley is a
glorious place! On all sides the mountains are impregnable, reddish
cliffs covered with green ivy and crowned with clumps of chinaras,
yellow precipices strewn with scouring holes, and there, high above, a
golden fringe of snows, and below, the Aragva, embraced by another
nameless river, noisily bursting out of a black, full of darkness gorge,
stretches a silver thread and glistens like a snake with its scales.
1091: After all, there are some people who have it written in their
hearts that all sorts of extraordinary things should happen to them.
1092: Contrary to my companion's prediction, the weather had cleared up,
and promised us a quiet morning; the stars were weaving themselves in
strange patterns in the distant sky, and one after another were
extinguished as the pale glow of the east spread across the dark purple
vault, gradually illuminating the steep slopes of the mountains covered
with virgin snow. To right and left blackened the dark, mysterious
chasms, and the mists, writhing and wriggling like snakes, slid down the
wrinkles of the neighbouring rocks, as if sensing and dreading the
approach of day.
1093: When we get away from the conditions of society and come closer to
nature, we involuntarily become children; everything acquired falls away
from the soul, and it becomes again what it once was, and will probably
be again someday. Those who, like me, have had the chance to wander
through the desert mountains, and to gaze long and long at their bizarre
images, and to greedily swallow the life-giving air in their gorges,
will certainly understand my desire to convey, to tell, to paint these
magical pictures.
1094: So, we went down from Hood Mountain to Chertov Valley... That's a
romantic name! You can already see the nest of the evil spirit between
the impregnable cliffs - but that's not the case: the name Devil's
Valley comes from the word “line”, not “devil”, because this was once
the border of Georgia. This valley was covered with snow drifts, which
reminded quite vividly of Saratov, Tambov and other nice places of our
fatherland.
1095: We had to descend another five versts over icy rocks and heavy
snow to reach Kobi station. The horses were exhausted, we were freezing;
the blizzard was blowing harder and harder, just like our native,
northern one; only its wild tunes were sadder, more mournful. ‘And you,
exile,’ thought I, "weep for your wide, spreading steppes! There you
have a place to spread your cold wings, but here you are stuffy and
cramped, like an eagle that beats with a cry against the bars of its
iron cage."
1096: What began in an extraordinary way must also end in the same way.
~~1097: Soon I was transferred to the Caucasus: it was the happiest time
of my life. I hoped that boredom did not live under Chechen bullets - in
vain: in a month I was so accustomed to their buzzing and to the
nearness of death that, rightly, I paid more attention to the mosquitoes
- and I became more bored than before, because I had lost almost the
last hope.~~
~~1098: Whether I am a fool or a villain, I do not know; but it is true
that I am also very worthy of regret, perhaps more than she: my soul is
corrupted by light, my imagination is restless, my heart is insatiable;
everything is not enough for me: I am as easily accustomed to sorrow as
to pleasure, and my life grows emptier day by day; there is only one
remedy left to me: to travel. As soon as I can, I shall go - not to
Europe, God forbid! - I shall go to America, to Arabia, to India, and I
may die somewhere on the road! At least I am sure that this last
consolation will not soon be exhausted by storms and bad roads.~~
1099: It is sad to see when a young man loses his best hopes and dreams,
when the rosy veil through which he looked at human affairs and feelings
is pulled away, though there is hope that he will replace the old
delusions with new ones, no less passing, but no less sweet.
1100: He has so often endeavoured to assure others that he is a creature
not made for the world, doomed to some secret misery, that he has almost
become convinced of it himself. That is why he wears his thick soldier's
overcoat so proudly. I understood him, and he did not like me for it,
though we were on the outwardly most friendly terms.
~~1101: We know in advance that everything can be argued about
endlessly, and therefore we do not argue; we know almost all each
other's innermost thoughts; one word is a whole story to us; we see the
grain of each of our feelings through a triple shell. The sad is funny
to us, the funny is sad, and in general, in truth, we are rather
indifferent to everything, except ourselves. So, the exchange of
feelings and thoughts between us can not be: we know one about the other
all that we want to know, and do not want to know more. There is only
one remedy left: to tell the news.~~
1102: Doctor, at last I am triumphant: you do not understand me...! It
grieves me, doctor,‘ continued I, after a moment's silence, ’I never
reveal my secrets myself, but I am terribly fond of having them guessed,
because in this way I can always be safe from them on occasion.
1103: Oh ego! You're the lever Archimedes used to lift the globe!
1104: Sadness in society is comical, and too much merriment is unseemly.
1105: It is not that restless need of love which torments us in the
early years of youth, throwing us from one woman to another until we
find one who cannot stand us: here begins our constancy - a true
infinite passion, which can be expressed mathematically by a line
falling from a point into space; the secret of this infinity is only the
impossibility of reaching the goal, that is, the end.
1106: Like all boys, he has the pretence of being an old man; he thinks
that on his face the deep marks of passion replace the imprint of years.
~~1107: I love my enemies, though not in a Christian way. They amuse me,
stir my blood. To be always on the alert, to catch every look, the
meaning of every word, to guess intentions, to destroy plots, to pretend
to be deceived, and suddenly, with a single push, to topple the whole
huge and difficult edifice of their cunning and schemes - that is what I
call life.~~
1108: I am ready for all sacrifices but this one; twenty times my life,
even my honour will be at stake.... but I will not sell my freedom.
~~1109: And maybe I'll die tomorrow. And there won't be a single
creature left on earth who will understand me perfectly. Some will think
me worse, others better than I really am... Some will say he was a good
man, others will say he was a scoundrel. Both will be false. After that,
is it worth the labour of living? And you live out of curiosity: you
expect something new..... Ridiculous and frustrating!~~
1110: I am like a sailor, born and bred on the deck of a brig: his soul
has grown accustomed to storms and battles, and, cast ashore, he is
bored and languid, no matter how much the shady grove beckons him, no
matter how much the peaceful sun shines on him; he walks all day long on
the coastal sand, listening to the monotonous murmur of the crashing
waves, and gazing into the misty distance: whether there, on the pale
line separating the blue abyss from the grey clouds, the desired sail,
at first like the wing of a sea gull, but little by little separating
from the foam of the boulders and smoothly approaching the deserted
wharf. ..
1111: Yes, gentlemen, life is short, philosophers say, so you must know
how to use it.
1112: There's no equality in love, it's not my custom. In love,
sometimes you have to cry.
1113: There's nothing worse than this shame, when you have to be ashamed
of others. We're not guilty of anything, but we're ashamed, so ashamed
I'd run away somewhere. But he doesn't seem to notice anything, he's
even cheerful.
1114: I know I'm a funny man myself. Do people get executed for being
funny?
1115: A man should spend a whole lifetime being brought up, but there is
an epoch after which he should not be brought up.
1116: One love for your neighbour, one love for the good must be the
goal. If love dries up in thy soul, thou wilt do nothing, thou wilt
deceive thyself; love alone builds up the lasting and living, but pride
is barren, then; that it needs nothing outside itself.
1117: Nothing in the world is so tempting to the ardent nature as to
take part in current affairs, in this witnessed history; he who has
allowed dreams of such activity into his bosom has spoilt himself for
all other fields; he, whatever he does, will be a guest in everything:
his unconditional field is not there - he will bring a civil dispute
into art, he will paint his thought if he is a painter, he will sing if
he is a musician.
1118: What is a name day? Why is there a brighter sense of sorrow and
joy on this day than the day before, not the day after? I don't know
why, but it is. Not only the name day, but every anniversary shakes the
soul deeply.
1119: Life does not pass in vain for people who have awakened at least
some strong thought..... Everything is nothing, today goes like
yesterday, everything is very ordinary, but suddenly you turn back and
see with amazement that a terrible distance has been travelled, an abyss
has been gained and lived.
1120: Now, in his thirties, he was preparing to begin his life like a
sixteen-year-old boy, not noticing that the door, closer and closer
open, was not the one through which gladiators enter, but the one into
which their bodies are carried out.
1121: Well, if misfortune befalls you, if grief breaks out over your
head, you will weep and sorrow; but to think, when it is necessary to
drink fine wine, that tomorrow fate will give you a bad kvass for it, is
a kind of madness. The inability to live in the present, to appreciate
the future, to give oneself to it, is one of the moral epidemics most
developed in our time. We are still like those Jews who do not drink, do
not eat, but save a penny for a rainy day; and whatever rainy day comes,
we will not open our coffers-what kind of life is that?
~~1122: What use would it be if I lived not ten but fifty years; who
would need my life but my mother, who herself is very unreliable?
Whether from weakness of strength, or lack of character, the fact is
that I am a useless man, and, convinced of this, I believe that I am the
only master of my life; I have not yet loved life enough to shoot
myself, and I certainly do not love it enough to live on a diet, to
drive myself on stretchers, to eliminate strong sensations and tasty
dishes in order to prolong for a long time this life of a hospital
patient.~~
1123: It is simply incomprehensible, why people are given such strength
and aspirations, which have nowhere to use. Every beast is cleverly
adapted by nature to a known form of life. And man. isn't there some
mistake? Just the heart and mind is repugnant to agree in the
possibility that the beautiful forces and aspiration given to people to
eat their own chest. What is it?
1124: Wherever one looks and whenever one looks at nature, at life with
an open soul, straightforwardly, unselfishly - they will give an abyss
of pleasure.
1125: I must confess that the man has arranged his life very foolishly:
nine tenths of it is spent in nonsense and trifles, and he does not know
how to use the last part.
1126: What fun it is to talk when we can be faithfully, deeply
understood and empathised with.
1127: Sometimes such characters are set in our places that, however many
years may have passed since you met them, you will never think of some
of them without a thrill of heart.
1128: To every disgusting situation man becomes accustomed as far as
possible, and in every position he retains as far as possible the
ability to pursue his meagre joys.
1129: He read novels, idylls, had quite a vivid imagination and often
moved mentally to those times (former or not), in which, if you believe
the poets, all people carelessly walked in the meadows, bathed in clean
springs, kissed like doves, rested under roses and myrtles and in happy
idleness all their days spent.
1130: I was healthy, young, cheerful, I had plenty of money, I had no
worries yet - I lived without looking back, did what I wanted,
prospered, in a word. It did not occur to me at that time that a man is
not a plant and it is impossible for him to flourish for a long time.
Youth eats gilded gingerbread, and thinks that this is its daily bread;
and when the time comes, you will ask for bread.
1131: I travelled without purpose, without a plan; I stopped wherever I
liked and went on as soon as I felt the desire to see new faces -
exactly faces. I was exclusively occupied by people; I hated curious
monuments, remarkable assemblies, the mere sight of a lon-lackey aroused
in me a feeling of longing and anger; I almost went mad at the Grün
Gewölbe in Dresden.
1132: When you dream of work, you soar like an eagle: you seem to move
the earth, but in the performance you immediately become weak and tired.
1133: Looking round, listening, remembering, I suddenly felt a secret
uneasiness in my heart.... I lifted my eyes to the sky - but there was
no peace in the sky: mottled with stars, it was moving, shuddering; I
leaned towards the river.... but there, too, in the dark, cold depths,
the stars were shaking and trembling; I could sense a disturbing
stirring everywhere, and the disturbance was growing in me.
1134: Tears boiled in my eyes, but they were not tears of senseless
rapture. What I felt was not that vague, still recently experienced
feeling of comprehensive desires, when the soul grows wide, sounds, when
it seems that it understands everything and loves everything..... No! A
thirst for happiness was kindled in me. I did not yet dare to call it by
its name, but happiness, happiness to the point of satiety - that is
what I wanted, that is what I longed for...
1135: Remember yesterday when you were talking about wings? I've grown
wings, but I can't fly.
1136: Laughter without reason is the best laughter in the world - all
that joyous ebullience of young, fresh life, that rush forward -
anywhere but forward.
1137: Happiness has no tomorrow; it has no yesterday; it does not
remember the past, does not think of the future; it has the present -
and that is not a day - but a moment.
1138: There are such happy faces in the world: everyone likes to look at
them, as if they were warming you or stroking you.
1139: What the hell is this nonsense! Every man hangs on a string, the
abyss may open under him every minute, and he invents all sorts of
troubles for himself, spoils his life.
1140: You will not believe me now, but I tell you: you and I got into a
society of women, and it was pleasant for us; but to leave such a
society is like being thrown into cold water on a hot day.
1141: And I think: I am lying here under a stack..... The narrow place I
occupy is so tiny compared to the rest of the space where I am not and
where I do not care; and the part of time that I will be able to live is
so insignificant before eternity, where I have not been and will not be.
1142: Yes,‘ Bazarov began, ’man is a strange creature. When you look
from the side and from afar at the deaf life that the ‘fathers’ lead
here, it seems: what better? Eat, drink, and know that you are acting in
the most correct, the most reasonable manner. But no; I get bored. I
want to deal with people, even to scold them, but to deal with them.
1143: Look,‘ said Arkady suddenly, ’a dry maple leaf has broken off and
is falling to the ground; its movements are quite similar to the flight
of a butterfly. Isn't that strange? The saddest and deadest things are
similar to the merriest and liveliest things.
1144: Think about it, what could be more horrible than to love and not
be loved!
1145: 'Don't you find,' began Arkady, 'that the ash-tree is very well
named in Russian: no tree so easily and clearly squeals in the air as it
does.
1146: Well, goodbye! Live long, that's the best, and enjoy it while it
lasts. Look at this ugly sight: a worm half-crushed, and still clinging.
And I also thought: I'll break a lot of things, I won't die, where to! I
have a task, because I'm a giant! And now the whole task of a giant is
to die decently, though nobody cares about it..... All the same, I won't
wag my tail.
1147: Whatever passionate, sinful, rebellious heart may lurk in the
grave, the flowers growing on it look serenely at us with their innocent
eyes: it is not of one eternal tranquillity that they speak to us, that
great tranquillity of ‘indifferent’ nature; they speak also of eternal
reconciliation and of life infinite.
1148: You don't have to be so hot, because I don't care. A romantic
would say: I feel that our roads are beginning to diverge, but I'm just
saying that we're boring each other.
1149: We should arrange life in such a way that every moment in it is
significant.
1150: You cannot imagine how strange it is to read in 1829 a novel
written in 775. It seems as if suddenly from our drawing-room we enter
an ancient hall upholstered in shtoff, sit down in satin down armchairs,
see strange dresses, but familiar faces, and recognise in them our
uncles and grandmothers, but younger.
1151: Of course, in the old days a lover for a favourable look left for
three years to fight in Palestine; but in our times to go 500 versts
away from St. Petersburg, in order to see the ruler of his heart - right
means a lot.
1152: To dislike the countryside is forgivable to a nun who has just
been released from a cage, or to an 18-year-old chamber-junker -
Petersburg is the antechamber, Moscow is the maiden room, the
countryside is our study. A respectable man, of necessity, passes
through the antechamber and seldom looks into the maiden room, but sits
in his study.
1153: Isn't it better to get used to the rigours of adulthood in advance
and voluntarily give up fading youth?
1154: I have often marvelled at the stupidity of the notion or the
impurity of the imagination of the ladies, who are, however, very
amiable. Often the most delicate joke, the most poetic greeting, they
take it either as a cheeky epigram or an unseemly platitude. In such a
case the cold look they adopt is so murderously disgusting that the most
ardent love cannot resist it.
1155: Not only the first fluff of cheeks and young blond curls,
sometimes even the stern appearance of an old man, the scars of his
forehead, the gray hair instill passionate dreams into the imagination
of beauty.
1156: The Ukrainian night is quiet. The sky is transparent. The stars
are shining. The air does not want to overcome its drowsiness. The
silvery poplar leaves barely tremble. But the strange dreams in Mazepa's
soul are gloomy: the stars of the night, like accusatory eyes, look at
him mockingly. And the poplars, crowded in a row, quietly shaking their
heads, like judges, whisper among themselves. And the darkness of the
warm summer night is stifling like a black prison.
### Checks
- [ ] Adding quotes?
- [ ] Make sure to include translations for the quotes in the
description (or another comment) so we can verify their content.
- [ ] Adding a language?
- Make sure to follow the [languages
documentation](https://github.com/monkeytypegame/monkeytype/blob/master/docs/LANGUAGES.md)
- [ ] Add language to `packages/contracts/src/schemas/languages.ts`
- [ ] Add language to exactly one group in
`frontend/src/ts/constants/languages.ts`
- [ ] Add language json file to `frontend/static/languages`
- [ ] Adding a theme?
- Make sure to follow the [themes
documentation](https://github.com/monkeytypegame/monkeytype/blob/master/docs/THEMES.md)
- [ ] Add theme to `packages/contracts/src/schemas/themes.ts`
- [ ] Add theme to `frontend/src/ts/constants/themes.ts`
- [ ] Add theme css file to `frontend/static/themes`
- Also please add a screenshot of the theme, it would be extra awesome
if you do so!
- [ ] Adding a layout?
- [ ] Make sure to follow the [layouts
documentation](https://github.com/monkeytypegame/monkeytype/blob/master/docs/LAYOUTS.md)
- [ ] Add layout to `packages/contracts/src/schemas/layouts.ts`
- [ ] Add layout json file to `frontend/static/layouts`
- [ ] Check if any open issues are related to this PR; if so, be sure to
tag them below.
- [ ] Make sure the PR title follows the Conventional Commits standard.
(https://www.conventionalcommits.org for more info)
- [ ] Make sure to include your GitHub username prefixed with @ inside
parentheses at the end of the PR title.
<!-- label(optional scope): pull request title (@your_github_username)
-->
<!-- I know I know they seem boring but please do them, they help us and
you will find out it also helps you.-->
Closes #
<!-- the issue(s) your PR resolves if any (delete if that is not the
case) -->
<!-- please also reference any issues and or PRs related to your pull
request -->
<!-- Also remove it if you are not following any issues. -->
<!-- pro tip: you can mention an issue, PR, or discussion on GitHub by
referencing its hash number e.g:
[#1234](https://github.com/monkeytypegame/monkeytype/pull/1234) -->
<!-- pro tip: you can press . (dot or period) in the code tab of any
GitHub repo to get access to GitHub's VS Code web editor Enjoy! :) -->
### Description
<!-- Please describe the change(s) made in your PR -->
### Checks
- [ ] Adding quotes?
- [ ] Make sure to include translations for the quotes in the
description (or another comment) so we can verify their content.
- [ ] Adding a language?
- Make sure to follow the [languages
documentation](https://github.com/monkeytypegame/monkeytype/blob/master/docs/LANGUAGES.md)
- [ ] Add language to `packages/contracts/src/schemas/languages.ts`
- [ ] Add language to exactly one group in
`frontend/src/ts/constants/languages.ts`
- [ ] Add language json file to `frontend/static/languages`
- [ ] Adding a theme?
- Make sure to follow the [themes
documentation](https://github.com/monkeytypegame/monkeytype/blob/master/docs/THEMES.md)
- [ ] Add theme to `packages/contracts/src/schemas/themes.ts`
- [ ] Add theme to `frontend/src/ts/constants/themes.ts`
- [ ] Add theme css file to `frontend/static/themes`
- Also please add a screenshot of the theme, it would be extra awesome
if you do so!
- [ ] Adding a layout?
- [ ] Make sure to follow the [layouts
documentation](https://github.com/monkeytypegame/monkeytype/blob/master/docs/LAYOUTS.md)
- [ ] Add layout to `packages/contracts/src/schemas/layouts.ts`
- [ ] Add layout json file to `frontend/static/layouts`
- [x] Check if any open issues are related to this PR; if so, be sure to
tag them below.
- [x] Make sure the PR title follows the Conventional Commits standard.
(https://www.conventionalcommits.org for more info)
- [x] Make sure to include your GitHub username prefixed with @ inside
parentheses at the end of the PR title.
<!-- label(optional scope): pull request title (@your_github_username)
-->
<!-- I know I know they seem boring but please do them, they help us and
you will find out it also helps you.-->
Closes [#6634](https://github.com/monkeytypegame/monkeytype/issues/6634)
<!-- the issue(s) your PR resolves if any (delete if that is not the
case) -->
<!-- please also reference any issues and or PRs related to your pull
request -->
<!-- Also remove it if you are not following any issues. -->
<!-- pro tip: you can mention an issue, PR, or discussion on GitHub by
referencing its hash number e.g:
[#1234](https://github.com/monkeytypegame/monkeytype/pull/1234) -->
<!-- pro tip: you can press . (dot or period) in the code tab of any
GitHub repo to get access to GitHub's VS Code web editor Enjoy! :) -->
### Description
Closes#6616
Changes:
- Refactored theme preview state management to use a single state object
- Removed redundant state variables
- Maintained the same debouncing behavior for smooth scrolling
### Description
1. Support RTL in tape mode:
- In `scrollTape()`: flip the sign of `#words.margin-left` and add
`.word.margin-right` to center first letter in RTL.
- In `Caret.getTargetPositionLeft()`: flip the direction of tapeMargin
in RTL.
- Remove restriction on RTL tape mode from test-logic.ts.
2. Support zero-width characters in tape mode:
- Subtract the width of the last letter that has a positive width if the
current letter has a zero width (e.g, diacritics). This is needed when
calculation is based on letter widths instead of letter position, which
is done in caret.ts when tape=word, and in `scrollTape()` when
tape=letter.
3. Remove the width change of `#words` in tape mode to 200vw because
it's not needed anymore now that we're using `white-space: nowrap`:
- Also adjust the limit of `.afterNewline.margin-left` to be 3 times the
new width of `#words` which is now equal to `#wordsWrapper.width` by
default.
4. Make `.word.height` in `.withLigature` langs similar to their height
in english:
- Imitate the appearance and behavior of `inline-block` `<letter>`s in
`.withLigatures` lanuages. These languages make the display of
`<letter>` elements `inline` in order to allow the joining of letters.
However, this causes `<letter>`'s `border-bottom` to be ignored, which
changes `.word` height, so we add a `padding-bottom` to the `.word` in
that case.
- Also, `inline` `<letter>`s overflow the `#wordWrapper` without
wrapping (e.g, when `maxLineWidth` = 20ch and we type 30 letters), so we
add the property `overflow-wrap: anywhere`, but we don't allow `.hints`
to inherit this property.
- P.S, it is necessary that all `.word`s have the same height (with and
without ligatures), because we now set the height of `.beforeNewline`s
in css, and we depend on these elements to have the same height as
`.word`s so that the user won't feel a vertical shift in lines in tape
mode.
5. Animate turning off tape mode in `updateWordsMargin()` if
`SmoothLineScroller` is on.
6. Block removing words at the first call of `scrollTape()`:
- Because the inline style of `#words.margin-left` may be negative when
restarting the test, making `scrollTape()` start when the first word is
overflown to the left, which makes `scrollTape()` remove that word (this
bug affects LTR and RTL langs).
closes#3923
---------
Co-authored-by: Jack <jack@monkeytype.com>
### Description
Update a Gladiator quote to fix a typo and fix the title to properly
reference the movie name.
### Checks
- [ ] Adding quotes?
- [ ] Make sure to include translations for the quotes in the
description (or another comment) so we can verify their content.
- [ ] Adding a language?
- Make sure to follow the [languages
documentation](https://github.com/monkeytypegame/monkeytype/blob/master/docs/LANGUAGES.md)
- [ ] Add language to `packages/contracts/src/schemas/languages.ts`
- [ ] Add language to exactly one group in
`frontend/src/ts/constants/languages.ts`
- [ ] Add language json file to `frontend/static/languages`
- [ ] Adding a theme?
- Make sure to follow the [themes
documentation](https://github.com/monkeytypegame/monkeytype/blob/master/docs/THEMES.md)
- [ ] Add theme to `packages/contracts/src/schemas/themes.ts`
- [ ] Add theme to `frontend/src/ts/constants/themes.ts`
- [ ] Add theme css file to `frontend/static/themes`
- Also please add a screenshot of the theme, it would be extra awesome
if you do so!
- [ ] Adding a layout?
- [ ] Make sure to follow the [layouts
documentation](https://github.com/monkeytypegame/monkeytype/blob/master/docs/LAYOUTS.md)
- [ ] Add layout to `packages/contracts/src/schemas/layouts.ts`
- [ ] Add layout json file to `frontend/static/layouts`
- [ ] Check if any open issues are related to this PR; if so, be sure to
tag them below.
- [ ] Make sure the PR title follows the Conventional Commits standard.
(https://www.conventionalcommits.org for more info)
- [ ] Make sure to include your GitHub username prefixed with @ inside
parentheses at the end of the PR title.
<!-- label(optional scope): pull request title (@your_github_username)
-->
<!-- I know I know they seem boring but please do them, they help us and
you will find out it also helps you.-->
Closes #
<!-- the issue(s) your PR resolves if any (delete if that is not the
case) -->
<!-- please also reference any issues and or PRs related to your pull
request -->
<!-- Also remove it if you are not following any issues. -->
<!-- pro tip: you can mention an issue, PR, or discussion on GitHub by
referencing its hash number e.g:
[#1234](https://github.com/monkeytypegame/monkeytype/pull/1234) -->
<!-- pro tip: you can press . (dot or period) in the code tab of any
GitHub repo to get access to GitHub's VS Code web editor Enjoy! :) -->
### Description
60 more famous Chinese Simplified Quotes
<!-- Please describe the change(s) made in your PR -->
### Checks
- [x] Adding quotes?
- [x] Make sure to include translations for the quotes in the
description (or another comment) so we can verify their content.
Closes #
<!-- the issue(s) your PR resolves if any (delete if that is not the
case) -->
<!-- please also reference any issues and or PRs related to your pull
request -->
<!-- Also remove it if you are not following any issues. -->
<!-- pro tip: you can mention an issue, PR, or discussion on GitHub by
referencing its hash number e.g:
[#1234](https://github.com/monkeytypegame/monkeytype/pull/1234) -->
<!-- pro tip: you can press . (dot or period) in the code tab of any
GitHub repo to get access to GitHub's VS Code web editor Enjoy! :) -->
### Translations:
- "Heaven progresses vigorously; a gentleman should persist in
self-improvement." - **"id": 241**
- "The sea accommodates hundreds of rivers, only with tolerance can one
be great." - **"id": 242**
- "A journey of a thousand miles begins with a single step." - **"id":
243**
- "To learn without thinking is labor lost; to think without learning is
dangerous." - **"id": 244**
- "A keen learner does not shy away from asking questions." - **"id":
245**
- "Those who are content are always happy." - **"id": 246**
- "Where there is a will, there is a way." - **"id": 247**
- "Read thousands of books and travel thousands of miles." - **"id":
248**
- "Do not impose on others what you do not desire for yourself." -
**"id": 249**
- "The road is long and winding; I will seek diligently." - **"id":
250**
- "Without accumulating small steps, one cannot reach a thousand miles."
- **"id": 251**
- "Knowing others is intelligence; knowing oneself is true wisdom." -
**"id": 252**
- "Teaching others to seek truth is the essence of education." - **"id":
253**
- "Isn't it a joy to have friends come from afar?" - **"id": 254**
- "Do not be joyous over material things, nor be sad over personal
losses." - **"id": 255**
- "When heaven is about to assign a great responsibility to a person, it
will first temper their will." - **"id": 256**
- "Skill is honed by diligence, while laziness destroys it." - **"id":
257**
- "The strength of a horse is known through its endurance; the heart of
a person is revealed over time." - **"id": 258**
- "Without enduring the bitter cold, how can one smell the fragrant plum
blossoms?" - **"id": 259**
- "Reading a book a hundred times reveals its meaning." - **"id": 260**
- "Lessons from past events serve as guidance for future actions." -
**"id": 261**
- "Those close to vermilion become red; those close to ink become
black." - **"id": 262**
- "Dripping water can penetrate stone; a rope saw can cut wood." -
**"id": 263**
- "Without entering the tiger's den, how can one catch a tiger cub?" -
**"id": 264**
- "The loss of the old horse might be a blessing." - **"id": 265**
- "Peach and plum trees do not speak, yet a path forms beneath them." -
**"id": 266**
- "Without rules, one cannot achieve a circle or a square." - **"id":
267**
- "Everyone has strengths and weaknesses." - **"id": 268**
- "Those who understand are not as good as those who love; those who
love are not as good as those who find joy." - **"id": 269**
- "A gentleman is harmonious yet distinct; a petty person is identical
yet disharmonious." - **"id": 270**
- "A thousand-mile gift of goose feathers is light in value but heavy in
sentiment." - **"id": 271**
- "An inch of time is worth an inch of gold, but gold cannot buy an inch
of time." - **"id": 272**
- "Bitter medicine is good for illness; harsh words are beneficial for
action." - **"id": 273**
- "A thousand troops are easy to find, but a good general is hard to
come by." - **"id": 274**
- "It's not the slow pace that is to be feared, but standing still." -
**"id": 275**
- "From a high pole, one can go further." - **"id": 276**
- "A single leaf can block the view of Mount Tai." - **"id": 277**
- "Unconsciously, time flows quietly." - **"id": 278**
- "Since ancient times, who has not died? Let my loyal heart shine
through history." - **"id": 279**
- "With a thousand hammers and chisels, one can emerge from the
mountains; facing fierce flames is nothing." - **"id": 280**
- "Without knowing the true face of Mount Lu, one is limited by being in
the mountain." - **"id": 281**
- "When one reaches the summit, they can see all the mountains as
small." - **"id": 282**
- "Fallen petals are not heartless; they turn into spring mud to protect
the flowers." - **"id": 283**
- "If life were just as it was at first sight, what sorrow would autumn
winds bring to painted fans?" - **"id": 284**
- "Life is like a dream; let us toast to the moon over the river." -
**"id": 285**
- "The spring silkworms die only when their silk is exhausted; the wax
torch turns to ash only when the tears have dried." - **"id": 286**
- "To see a thousand miles ahead, one must climb another floor." -
**"id": 287**
- "Heaven has given me talent for a purpose; even if I spend a fortune,
it will return." - **"id": 288**
- "Do not worry about having no friends on the road; who in the world
does not know you?" - **"id": 289**
- "A thousand sails pass by the sunken boat; a thousand trees bloom in
front of the sick tree." - **"id": 290**
- "In the midst of mountains and rivers, one may think there is no way;
but within the shadows of willows and flowers, there lies another
village." - **"id": 291**
- "After gathering a hundred flowers to make honey, for whom do you toil
and for whom do you sweeten?" - **"id": 292**
- "Fallen red clouds fly alongside solitary wild ducks; autumn waters
blend with the long sky in one color." - **"id": 293**
- "Life is like a journey against the current; I too am a traveler." -
**"id": 294**
- "In times of joy, one should enjoy thoroughly; do not let the golden
cup face the moon empty." - **"id": 295**
- "The spring breeze once again greens the southern bank; when will the
bright moon shine on my return?" - **"id": 296**
- "When one strikes water for three thousand miles, one trusts in life
for two hundred years." - **"id": 297**
- "If the nation benefits from life or death, how can one avoid fortune
or misfortune?" - **"id": 298**
- "Life is like a white horse passing through a crack; it is all too
sudden." - **"id": 299**
- "A thousand-mile dike collapses from an ant's nest." - **"id": 300**
- "Without climbing a high mountain, one cannot know the height of
heaven; without approaching a deep stream, one cannot know the thickness
of earth." - **"id": 301**
- "Those who know their insufficiencies are always present." - **"id":
302**
- "Reading ten thousand books, writing as if inspired by a divine
spirit." - **"id": 303**
- "Do not forget your original intention, and you will achieve your
goal." - **"id": 304**
- "A journey of a thousand miles begins with a single step." - **"id":
305**
- "Learning has no limits." - **"id": 306**
- "Knowing shame leads to courage." - **"id": 307**
- "Do not worry about others not knowing you; worry about not knowing
others." - **"id": 308**
- "One should help others achieve their goals while seeking their own."
- **"id": 309**
- "To know what is to know, and to not know what is not to know, is
knowledge." - **"id": 310**
- "Think thrice before acting." - **"id": 311**
- "Review the old to learn the new." - **"id": 312**
- "To study and practice regularly, is that not a joy?" - **"id": 313**
- "Those who know are not as good as those who love." - **"id": 314**
- "A keen learner does not shy away from asking questions." - **"id":
315**
- "A gentleman is open and relaxed; a petty person is always anxious." -
**"id": 316**
- "Do not impose on others what you do not desire for yourself." -
**"id": 317**
- "When three people walk together, there must be a teacher among them."
- **"id": 318**
- "To study without fatigue, to teach without weariness." - **"id":
319**
- "The wise are not confused; the benevolent are not worried; the brave
are not afraid." - **"id": 320**
- "A gentleman seeks from himself; a petty person seeks from others." -
**"id": 321**
- "A gentleman helps others to succeed but does not participate in their
wrongs." - **"id": 322**
- "A gentleman cherishes virtue, while a petty person cherishes land. A
gentleman cherishes punishment, while a petty person cherishes favor." -
**"id": 323**
- "A gentleman understands righteousness; a petty person understands
profit." - **"id": 324**
- "In the cold of winter, only then do we know the pine and cypress are
the last to wither." - **"id": 325**
- "Do not worry about lacking a position; worry about how to stand. Do
not worry about being unknown; seek to be known." - **"id": 326**
- "The wise love water; the benevolent love mountains." - **"id": 327**
- "A gentleman is cautious in speech but quick in action." - **"id":
328**
- "A gentleman is not a tool." - **"id": 329**
- "A gentleman is harmonious yet distinct." - **"id": 330**
### Description
I added some quotes of various lengths from Andor season 1.
### Checks
- [x] Adding quotes?
- [ ] Make sure to include translations for the quotes in the
description (or another comment) so we can verify their content.
- [ ] Adding a language?
- Make sure to follow the [languages
documentation](https://github.com/monkeytypegame/monkeytype/blob/master/docs/LANGUAGES.md)
- [ ] Add language to `packages/contracts/src/schemas/languages.ts`
- [ ] Add language to exactly one group in
`frontend/src/ts/constants/languages.ts`
- [ ] Add language json file to `frontend/static/languages`
- [ ] Adding a theme?
- Make sure to follow the [themes
documentation](https://github.com/monkeytypegame/monkeytype/blob/master/docs/THEMES.md)
- [ ] Add theme to `packages/contracts/src/schemas/themes.ts`
- [ ] Add theme to `frontend/src/ts/constants/themes.ts`
- [ ] Add theme css file to `frontend/static/themes`
- [ ] Adding a layout?
- [ ] Make sure to follow the [layouts
documentation](https://github.com/monkeytypegame/monkeytype/blob/master/docs/LAYOUTS.md)
- [ ] Add layout to `packages/contracts/src/schemas/layouts.ts`
- [ ] Add layout json file to `frontend/static/layouts`
- Also please add a screenshot of the theme, it would be extra awesome
if you do so!
- [x] Check if any open issues are related to this PR; if so, be sure to
tag them below.
- [x] Make sure the PR title follows the Conventional Commits standard.
(https://www.conventionalcommits.org for more info)
- [x] Make sure to include your GitHub username prefixed with @ inside
parentheses at the end of the PR title.
<!-- label(optional scope): pull request title (@your_github_username)
-->
<!-- I know I know they seem boring but please do them, they help us and
you will find out it also helps you.-->
<!-- the issue(s) your PR resolves if any (delete if that is not the
case) -->
<!-- please also reference any issues and or PRs related to your pull
request -->
<!-- Also remove it if you are not following any issues. -->
<!-- pro tip: you can mention an issue, PR, or discussion on GitHub by
referencing its hash number e.g:
[#1234](https://github.com/monkeytypegame/monkeytype/pull/1234) -->
<!-- pro tip: you can press . (dot or period) in the code tab of any
GitHub repo to get access to GitHub's VS Code web editor Enjoy! :) -->
### Description
Added a few missing keywords, some common attributes and procedures.
Removed complex_double/complex_float (not sure why they were there).
### Checks
- [x] Check if any open issues are related to this PR; if so, be sure to
tag them below.
- [x] Make sure the PR title follows the Conventional Commits standard.
(https://www.conventionalcommits.org for more info)
- [x] Make sure to include your GitHub username prefixed with @ inside
parentheses at the end of the PR title.
### Description
When using the command line to add or remove a theme from favorites
while on the settings page, the favorites UI would not reflect the
changes until the user manually refreshed the page or changed the theme.
This caused confusion, despite the changes being correctly saved in the
config.
**Solution**
Added a ConfigEvent subscription in theme-picker.ts to listen for
"favThemes" updates. If the active page is "settings", the UI is now
refreshed immediately by calling refreshPresetButtons().
### Add Quick Favorite ~~Toggle~~ **Indicator** and Prioritized
Favorites to Theme Picker
This pull request adds a new feature to MonkeyType’s theme picker &
(**current theme button** in the **footer**) ~~making it super easy for
users to save/unsave and access their favorite themes instead of going
to the settings or any other thing~~ to display a small **star icon**
indicating whether the **the theme** is marked as a favorite. Favorited
themes appear at the top of the theme list for quick access.
~~Also, I added a small heart icon next to the current theme button in
the footer to quickly favorite the active theme with one click—making it
even easier to save a new favorite without needing to open the list.~~
The star icon next to the current theme button **only acts as a visual
indicator**, showing whether the current theme is a favorite or not.
**No longer clickable**.
---
**User Benefits:**
* **Favorites at the Top:**
Favorite themes appear first in the theme picker, so you can switch to
them instantly without searching through the list.
* ~~**One-Click Star Toggle:**~~
~~Click a star next to any theme to favorite or unfavorite it right in
the picker. No need to dig through settings, saving you time and
effort.~~
* **Visual Indicator for Active Theme:**
A small star icon beside the current theme button tells you at a glance
whether your active theme is in your favorites—without needing to open
the list.
---
**What I Did:**
* Added a star icon appears next to the favorite themes ~~each theme in
the theme picker for quick favoriting or unfavoriting.~~
* Made favorite themes show up at the top of the list for easy access.
* ~~Added a small heart icon next to the current theme button in the
footer to favorite the active theme quickly.~~
* Added a small star icon next to the current theme button in the footer
**as an indicator only** — it shows whether the active theme is a
favorite, but **is not clickable**.
* ~~- Added notifications to confirm when a theme is favorited or
unfavorited.~~
---
**Preview:** (**OUTDATED**)
[https://github.com/user-attachments/assets/5bba15c4-edbb-4577-abfe-fd581f196b98](https://github.com/user-attachments/assets/5bba15c4-edbb-4577-abfe-fd581f196b98)
---
### Checks
* [ ] Adding quotes?
* [ ] Make sure to include translations for the quotes in the
description (or another comment) so we can verify their content.
* [ ] Adding a language or a theme?
* [ ] If it’s a language, did you edit `_list.json`, `_groups.json`, and
add `languages.json`?
* [ ] If it’s a theme, did you add the theme.css?
* Also please add a screenshot of the theme, it would be extra awesome
if you do so!
* [x] Check if any open issues are related to this PR; if so, be sure to
tag them below.
* [x] Make sure the PR title follows the Conventional Commits standard.
([https://www.conventionalcommits.org/](https://www.conventionalcommits.org)
for more info)
* [x] Make sure to include your GitHub username prefixed with @ inside
parentheses at the end of the PR title.
---
---------
Co-authored-by: Miodec <jack@monkeytype.com>
Co-authored-by: Nginearing <142851004+Nginearing@users.noreply.github.com>
Co-authored-by: Pavel Ivashkov <paiv@users.noreply.github.com>
Co-authored-by: Christian Fehmer <fehmer@users.noreply.github.com>
Co-authored-by: siilyg <149881151+siily-g@users.noreply.github.com>
Co-authored-by: Omar Abdelrahman Abbas <tryomarabbas@gmail.com>
### Description
Previously, when selecting a language via the text button on the test
page, the checkmark (fa-check) in the commandline language list wouldn't
update until a page refresh. This was due to the commandline's caching
mechanism not detecting changes triggered outside its own control.
Although it first appeared to be a language-specific issue, it was later
identified that the caching logic was generally insufficient — it didn’t
account for updates to the active command state or configuration flags
like usingSingleList.
## Solution
Fixed the caching logic in the commandline module by tracking a more
complete internal state. The system now correctly detects changes in the
command list, active state, and configuration, and rebuilds the list UI
when necessary.
## Technical Details
- The commandline uses a caching mechanism (`lastList`) to avoid
rebuilding the HTML if the list hasn't changed done in #6559
- Replaced the old lastList cache with a new lastState object that
stores: the list of commands, each with its isActive flag, the
usingSingleList configuration flag
- Improved the cache comparison logic, uses areSortedArraysEqual to
compare command lists including active state ,compares the
usingSingleList flag
- Previously, this cache wasn't being cleared when the language changed
through the text button
- Now we clear the cache on changes, forcing a rebuild of the list with
the correct checkmark
## Performance Impact
- Minimal performance impact
- The list is only rebuilt when:
1. The language actually changes
2. The list content changes
3. The input value changes
- The caching mechanism still prevents unnecessary rebuilds in all other
cases
## Testing
- [x] Language selection through text button updates checkmark
immediately
- [x] Language selection through commandline works as before
- [x] No unnecessary rebuilds when language hasn't changed
- [x] Checkmark appears next to correct language in all cases
If frontend and backend are deployed with a new COMPATABILITY_CHECK
header frontend might show the backend version is lower because of the
http header of a cached response.
Adding the COMPATABILITY_CHECK version as part of the etag fixes this.
Add Open Graph meta tags to user profile pages to improve how they
appear when shared on social media platforms. This includes title,
description and URL meta tags.
Closes#6597
### Description
This PR adds Open Graph Protocol (OGP) meta tags to user profile pages
to fix the issue with LinkedIn and other social media platforms
incorrectly redirecting profile links to the homepage. The
implementation:
- Adds dynamic Open Graph meta tags for title, description and URL
- Updates tags whenever a profile page is loaded
- Uses the user's name in the title tag for better personalization
### Checks
- [x] Check if any open issues are related to this PR; if so, be sure to
tag them below.
- [x] Make sure the PR title follows the Conventional Commits standard.
- [x] Make sure to include your GitHub username prefixed with @ inside
parentheses at the end of the PR title.
<!-- label(optional scope): pull request title (@your_github_username)
-->
Closes#6597
<!-- pro tip: you can mention an issue, PR, or discussion on GitHub by
referencing its hash number e.g:
[#1234](https://github.com/monkeytypegame/monkeytype/pull/1234) -->
<!-- pro tip: you can press . (dot or period) in the code tab of any
GitHub repo to get access to GitHub's VS Code web editor Enjoy! :) -->
### Description
The tarmak layout(s) is a set of transition layouts for qwerty user
switching to colemak, it changes only about 3-4 keys for every stage.
[More about tarmak](https://dreymar.colemak.org/tarmak-intro.html)
### Checks
- [ ] Adding quotes?
- [ ] Make sure to include translations for the quotes in the
description (or another comment) so we can verify their content.
- [ ] Adding a language?
- Make sure to follow the [languages
documentation](https://github.com/monkeytypegame/monkeytype/blob/master/docs/LANGUAGES.md)
- [ ] Add language to `packages/contracts/src/schemas/languages.ts`
- [ ] Add language to exactly one group in
`frontend/src/ts/constants/languages.ts`
- [ ] Add language json file to `frontend/static/languages`
- [ ] Adding a theme?
- Make sure to follow the [themes
documentation](https://github.com/monkeytypegame/monkeytype/blob/master/docs/THEMES.md)
- [ ] Add theme to `packages/contracts/src/schemas/themes.ts`
- [ ] Add theme to `frontend/src/ts/constants/themes.ts`
- [ ] Add theme css file to `frontend/static/themes`
- [x] Adding a layout?
- [x] Make sure to follow the [layouts
documentation](https://github.com/monkeytypegame/monkeytype/blob/master/docs/LAYOUTS.md)
- [x] Add layout to `packages/contracts/src/schemas/layouts.ts`
- [x] Add layout json file to `frontend/static/layouts`
- [x] Check if any open issues are related to this PR; if so, be sure to
tag them below.
- [x] Make sure the PR title follows the Conventional Commits standard.
(https://www.conventionalcommits.org for more info)
- [x] Make sure to include your GitHub username prefixed with @ inside
parentheses at the end of the PR title.