diff --git a/.eslintrc.cjs b/.eslintrc.cjs index 42426f69f..3e67ca127 100644 --- a/.eslintrc.cjs +++ b/.eslintrc.cjs @@ -9,6 +9,7 @@ module.exports = { 'airbnb/hooks', 'plugin:@typescript-eslint/recommended', 'plugin:react-hooks/recommended', + 'prettier/react', ], ignorePatterns: ['dist', '.eslintrc.cjs'], parser: '@typescript-eslint/parser', @@ -19,10 +20,7 @@ module.exports = { rules: { 'import/prefer-default-export': 'off', 'arrow-body-style': 'off', - 'arrow-parens': ['error', 'as-needed', { - requireForBlockBody: true, - }], - 'react/jsx-indent': ['error', 4], + 'react/jsx-indent': ['error', 2], 'react/jsx-no-undef': [ "error", { "allowGlobals": true } ], 'react/require-default-props': 0, 'react/function-component-definition': 0, @@ -31,7 +29,7 @@ module.exports = { { allowConstantExport: true }, ], 'max-len': ['warn', { - 'code': 140, + 'code': 110, 'ignoreUrls': true, 'ignorePattern': '(^import|d="([\\s\\S]*?)|\\srequire\\()', 'ignoreTrailingComments': true, @@ -49,19 +47,6 @@ module.exports = { packageDir: '.', }], }, - settings: { - 'import/resolver': { - 'alias-array': { - alias: true, - map: [ - ['@api', resolve(__dirname, './src/api/')], - ['@components', resolve(__dirname, './src/components/')], - ['@store', resolve(__dirname, './src/store/')], - ['@utils', resolve(__dirname, './src/utils/')], - ], - } - } - }, overrides: [ { files: ['*.ts', '*.tsx'], diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 000000000..70878f64e --- /dev/null +++ b/.prettierrc @@ -0,0 +1,9 @@ +{ + "endOfLine": "auto", + "singleQuote": true, + "tabWidth": 2, + "semi": true, + "bracketSpacing": true, + "trailingComma": "all", + "printWidth": 110 +} \ No newline at end of file diff --git a/package.json b/package.json index cec3187e9..e4152ef8d 100644 --- a/package.json +++ b/package.json @@ -47,7 +47,8 @@ "i18next-intervalplural-postprocessor": "^3.0.0", "react": "^18.2.0", "react-dom": "^18.2.0", - "react-i18next": "^13.2.0" + "react-i18next": "^13.2.0", + "wouter": "^3.6.0" }, "devDependencies": { "@babel/plugin-syntax-jsx": "^7.22.5", diff --git a/src/App.tsx b/src/App.tsx index dd4e2530d..b2536bae4 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,30 +1,22 @@ import { useEffect } from 'react'; -import { Pane as PaneType } from '@common-types'; - import { LOCAL_STORAGE } from '@const'; import { useSelector, useDispatch } from '@store'; import { loadGame } from '@store/gameSlice'; import useAppUpdateIfNeeded from '@hooks/useAppUpdateIfNeeded'; -import useLangugeChangeIfNeeded from '@hooks/useLangugeChangeIfNeeded'; +import useLangugeChangeIfNeeded from '@features/routes/hooks/useLangugeChangeIfNeeded'; import useAddTrackersScriptsIfNeeded from '@hooks/useAddTrackersScriptsIfNeeded'; -import usePanes from '@hooks/usePanes'; import useTrackGlobal from '@hooks/useTrackGlobal'; import useUnlockEasterDaysIfPossible from '@hooks/useUnlockEasterDaysIfPossible'; import useUpdateIfSpecialWord from '@features/specialWords/hooks/useUpdateIfSpecialWord'; import Header from '@components/Header'; -import CookiesPopup from '@components/Cookies/CookiesPopup'; +import Routes from '@features/routes/components/Routes/Routes'; -import Game from '@components/Panes/Game/Game'; -import Help from '@components/Panes/Help/Help'; -import Settings from '@components/Panes/Settings/Settings'; -import Statistics from '@components/Panes/Statistics/Statistics'; -import YearSummary from '@components/Panes/YearSummary/YearSummary'; -import AboutLanguage from '@components/Panes/AboutLanguage/AboutLanguage'; +import CookiesPopup from '@components/Cookies/CookiesPopup'; import Toast from '@components/Toast/Toast'; @@ -38,8 +30,6 @@ function App() { const todayStamp = useSelector(state => state.game.today); const isErrorLoading = useSelector(state => state.game.isErrorLoading); - const { pane } = usePanes(); - useEffect(() => { dispatch(loadGame()); }, [dispatch, gameLanguage, gameMode, wordToGuess, todayStamp, isErrorLoading]); @@ -77,12 +67,7 @@ function App() {
- {pane === PaneType.Help && } - {pane === PaneType.Game && } - {pane === PaneType.Settings && } - {pane === PaneType.Statistics && } - {pane === PaneType.YearSummary && } - {pane === PaneType.AboutLanguage && } +
diff --git a/src/api/getDoesWordExist.ts b/src/api/getDoesWordExist.ts index f03cd6ab7..073cbf241 100644 --- a/src/api/getDoesWordExist.ts +++ b/src/api/getDoesWordExist.ts @@ -1,7 +1,8 @@ +import { ROOT_PATH } from '@const'; import { getNormalizedKey } from './helpers'; type FetchedWordsListByKeys = { - [key: string]: string[] + [key: string]: string[]; }; export const DoesWordExistErrorTypes = { @@ -9,12 +10,12 @@ export const DoesWordExistErrorTypes = { Fetch: 'fetch', } as const; -type DoesWordExistErrorType = typeof DoesWordExistErrorTypes[keyof typeof DoesWordExistErrorTypes]; +type DoesWordExistErrorType = (typeof DoesWordExistErrorTypes)[keyof typeof DoesWordExistErrorTypes]; type GetDoesWordExistReport = { - doesWordExist: boolean, - isError: boolean, - errorType?: DoesWordExistErrorType + doesWordExist: boolean; + isError: boolean; + errorType?: DoesWordExistErrorType; }; const cachedKeys: FetchedWordsListByKeys = {}; @@ -36,7 +37,7 @@ export const getDoesWordExist = async (word: string, lang: string): Promise { + const response = await fetch(`${ROOT_PATH}dictionary/${lang}/spelling/chunk-${key}.json`).catch((error) => { throw error; }); @@ -70,11 +71,14 @@ export const getDoesWordExist = async (word: string, lang: string): Promise => { +export const getWordsFromKeysWithIndexes = async ( + keysWithIndexes: KeyWithIndex[], + lang: string, +): Promise => { const words = []; // eslint-disable-next-line no-restricted-syntax @@ -85,7 +89,7 @@ export const getWordsFromKeysWithIndexes = async (keysWithIndexes: KeyWithIndex[ try { // eslint-disable-next-line no-await-in-loop - const response = await fetch(`./dictionary/${lang}/spelling/chunk-${key}.json`).catch((error) => { + const response = await fetch(`${ROOT_PATH}dictionary/${lang}/spelling/chunk-${key}.json`).catch((error) => { throw error; }); @@ -112,18 +116,16 @@ export const getWordsFromKeysWithIndexes = async (keysWithIndexes: KeyWithIndex[ }; export const getWordsIndexesChunks = (words: string[], lang: string) => { - const keysWithWords = words.map(word => ({ word, key: getNormalizedKey(word, lang) })); - const hasAllWordsFetched = keysWithWords.every( - ({ word, key }) => { - if (!key) { - return false; - } + const keysWithWords = words.map((word) => ({ word, key: getNormalizedKey(word, lang) })); + const hasAllWordsFetched = keysWithWords.every(({ word, key }) => { + if (!key) { + return false; + } - const cacheKey = getCacheKey(lang, key); + const cacheKey = getCacheKey(lang, key); - return Array.isArray(cachedKeys[cacheKey]) && cachedKeys[cacheKey].includes(word); - }, - ); + return Array.isArray(cachedKeys[cacheKey]) && cachedKeys[cacheKey].includes(word); + }); if (!hasAllWordsFetched) { return []; @@ -135,7 +137,10 @@ export const getWordsIndexesChunks = (words: string[], lang: string) => { return { word, key, - index: cachedKeys && cachedKeys[cacheKey] ? cachedKeys[cacheKey].findIndex(keyWords => word === keyWords) : -1, + index: + cachedKeys && cachedKeys[cacheKey] + ? cachedKeys[cacheKey].findIndex((keyWords) => word === keyWords) + : -1, }; }); }; diff --git a/src/api/getWordToGuess.ts b/src/api/getWordToGuess.ts index 51c66b0c9..4fa857429 100644 --- a/src/api/getWordToGuess.ts +++ b/src/api/getWordToGuess.ts @@ -1,4 +1,5 @@ import { GameMode, Catalog } from '@common-types'; +import { ROOT_PATH } from '@const'; import { getNow } from '@utils/date'; @@ -38,7 +39,7 @@ export const getCatalogInfo = async (gameLanguage: string) => { return cachedCatalogs[gameLanguage]; } - const catalogResponse = await fetch(`./dictionary/${gameLanguage}/catalog.json`); + const catalogResponse = await fetch(`${ROOT_PATH}dictionary/${gameLanguage}/catalog.json`); const { words = 0, items = [], @@ -82,7 +83,7 @@ export const getWordToGuess = async ( const { key, endIndex } = keyItem; - const winingKeyResponse = await fetch(`./dictionary/${gameLanguage}/winning/chunk-${key}.json`); + const winingKeyResponse = await fetch(`${ROOT_PATH}dictionary/${gameLanguage}/winning/chunk-${key}.json`); const winingKeyResult = await winingKeyResponse.json(); diff --git a/src/api/helpers.ts b/src/api/helpers.ts index 830445635..ee25249c6 100644 --- a/src/api/helpers.ts +++ b/src/api/helpers.ts @@ -204,8 +204,6 @@ export const mergeFlatAffixes = (flatAffixesA: FlatAffixes, flatAffixesB: FlatAf ); flatAffixesResult.notCorrectOrders = [...flatAffixesResult.notCorrectOrders, ...notCorrectOrdersBThatAreNew]; - console.log(JSON.stringify(flatAffixesB)); - const needsALetterBetweenBThatAreNew = flatAffixesB.needsALetterBetween.filter( (newPair) => { const hasPairAlready = flatAffixesResult.needsALetterBetween.some( diff --git a/src/components/Button/Button.tsx b/src/components/Button/Button.tsx index 3bbf725f9..593bcbaa3 100644 --- a/src/components/Button/Button.tsx +++ b/src/components/Button/Button.tsx @@ -1,5 +1,6 @@ import React, { useCallback } from 'react'; import clsx from 'clsx'; +import { Link } from 'wouter'; import useVibrate from '@hooks/useVibrate'; @@ -8,7 +9,7 @@ import IconLoader from '@components/Icons/IconLoader'; import './Button.scss'; type Props = { - tagName?: ('button' | 'a') + tagName?: 'button' | 'a' | 'link' className?: string, children: React.ReactNode, onClick?: (e: React.MouseEvent) => void, @@ -40,7 +41,10 @@ const Button = ({ hasBorder = true, dataTestId, }: Props) => { - const Tag = tagName || 'button'; + let Tag: string | typeof Link = 'button'; + if (tagName) { + Tag = tagName === 'link' ? Link : 'a'; + } const { vibrate } = useVibrate(); @@ -66,6 +70,7 @@ const Button = ({ href={href} rel={rel} target={target} + // @ts-expect-error wouter Link doesn't support it disabled={isDisabled} data-testid={dataTestId} > diff --git a/src/components/Button/ButtonTile.tsx b/src/components/Button/ButtonTile.tsx index e543dca06..03a30de16 100644 --- a/src/components/Button/ButtonTile.tsx +++ b/src/components/Button/ButtonTile.tsx @@ -1,5 +1,6 @@ import React, { useCallback } from 'react'; import clsx from 'clsx'; +import { Link } from 'wouter'; import useVibrate from '@hooks/useVibrate'; @@ -8,7 +9,7 @@ import IconLoader from '@components/Icons/IconLoader'; import './ButtonTile.scss'; type Props = { - tagName?: 'button' | 'a', + tagName?: 'button' | 'a' | 'link', variant?: 'small' | '', className?: string, children: React.ReactNode, @@ -40,7 +41,10 @@ const ButtonTile = ({ isInverted = false, dataTestId, }: Props) => { - const Tag = tagName || 'button'; + let Tag: string | typeof Link = 'button'; + if (tagName) { + Tag = tagName === 'link' ? Link : 'a'; + } const { vibrate } = useVibrate(); @@ -65,7 +69,8 @@ const ButtonTile = ({ title={title} rel={rel} target={target} - disabled={isDisabled} + // @ts-expect-error wouter Link doesn't support it + disabled={tagName !== 'link' ? isDisabled : undefined} data-testid={dataTestId} > {children} diff --git a/src/components/Header.scss b/src/components/Header.scss index 04bd9e5a0..9d2961343 100644 --- a/src/components/Header.scss +++ b/src/components/Header.scss @@ -33,8 +33,10 @@ position: absolute; top: 50%; transform: translateY(-50%); + height: 22px; + line-height: 1; - button { + a { width: 22px; } } @@ -119,6 +121,7 @@ } } + a, button { position: relative; display: inline-flex; @@ -126,6 +129,8 @@ align-items: center; background: none; border: none; + color: inherit; + text-decoration: none; svg { fill: var(--text-weaker); diff --git a/src/components/Header.tsx b/src/components/Header.tsx index 8fee03c0b..adfba30da 100644 --- a/src/components/Header.tsx +++ b/src/components/Header.tsx @@ -2,12 +2,12 @@ import clsx from 'clsx'; import { useEffect, useState } from 'react'; import { useTranslation } from 'react-i18next'; -import { GameMode, Pane } from '@common-types'; +import { GameMode } from '@common-types'; +import { ROOT_PATH } from '@const'; import { useSelector } from '@store'; import { selectIsGameEnded, selectIsTodayEasterDay } from '@store/selectors'; -import usePanes from '@hooks/usePanes'; import useEffectChange from '@hooks/useEffectChange'; import usePrevious from '@hooks/usePrevious'; @@ -21,22 +21,23 @@ import LanguagePicker from '@components/Language/LanguagePicker'; import SharedContent from '@components/Share/SharedContent'; import './Header.scss'; +import { Link } from 'wouter'; +import useLink from '@features/routes/hooks/useLinks'; const Header = () => { + const { activeLink, getLinkPath } = useLink(); const [flagKey, setFlagKey] = useState(''); const [shouldShowShared, setShouldShowShared] = useState(false); const isTodayEasterDay = useSelector(selectIsTodayEasterDay); - const today = useSelector(state => state.game.today); - const gameLanguage = useSelector(state => state.game.language); + const today = useSelector((state) => state.game.today); + const gameLanguage = useSelector((state) => state.game.language); const isGameEnded = useSelector(selectIsGameEnded); - const wordToGuess = useSelector(state => state.game.wordToGuess); - const gameMode = useSelector(state => state.game.mode); - const guesses = useSelector(state => state.game.guesses); + const wordToGuess = useSelector((state) => state.game.wordToGuess); + const gameMode = useSelector((state) => state.game.mode); + const guesses = useSelector((state) => state.game.guesses); const { t } = useTranslation(); - const { pane, changePane } = usePanes(); - const prevGameLanguage = usePrevious(gameLanguage); useEffectChange(() => { @@ -51,63 +52,68 @@ const Header = () => { } }, [wordToGuess]); - const isQuiteBadGameShouldHintHelp = pane === Pane.Game && guesses.length >= 8 && !isGameEnded; + const isQuiteBadGameShouldHintHelp = activeLink.route === 'game' && guesses.length >= 8 && !isGameEnded; + + const isLeftActive = activeLink.route === 'help'; + const isRightActive = ['settings', 'statistics', 'aboutLanguage'].includes(activeLink.route); return ( -
-
- -
-

- - {gameLanguage && ( - - {flagKey - - )} -

-
- {shouldShowShared && } - -
-
+
+
+ + {isLeftActive ? : } + + {isLeftActive && t('common.close')} + {!isLeftActive && isQuiteBadGameShouldHintHelp && t('help.howToPlayTitle')} + {!isLeftActive && !isQuiteBadGameShouldHintHelp && t('help.title')} + + +
+

+ + Diffle + {gameMode === GameMode.Practice && } + {gameMode === GameMode.SandboxLive && } + {isTodayEasterDay && ( + + {today + .split('.') + .filter((_, index) => index !== 2) + .join('.')} + + )} + + {gameLanguage && ( + + {flagKey + + )} +

+
+ {shouldShowShared && } + + {isRightActive ? : } + {t(isRightActive ? 'common.close' : 'settings.title')} + +
+
); }; diff --git a/src/components/Language/LanguagePicker.tsx b/src/components/Language/LanguagePicker.tsx index 6b36827e6..930499e4c 100644 --- a/src/components/Language/LanguagePicker.tsx +++ b/src/components/Language/LanguagePicker.tsx @@ -2,15 +2,13 @@ import clsx from 'clsx'; import { useState } from 'react'; import { useTranslation } from 'react-i18next'; -import { Pane as PaneType } from '@common-types'; - -import { SUPPORTED_LANGS, SUPPORTED_DICTIONARY_BY_LANG } from '@const'; +import { SUPPORTED_LANGS, SUPPORTED_DICTIONARY_BY_LANG, ROOT_PATH } from '@const'; import { useDispatch, useSelector } from '@store'; import { track, setToast } from '@store/appSlice'; import useVibrate from '@hooks/useVibrate'; -import usePanes from '@hooks/usePanes'; +import useLink from '@features/routes/hooks/useLinks'; import IconBookOpen from '@components/Icons/IconBookOpen'; import IconConstruction from '@components/Icons/IconConstruction'; @@ -30,26 +28,25 @@ type Props = { }; const LanguagePicker = ({ children, className, place }: Props) => { + const { activeLink, getLinkPath } = useLink(); + const dispatch = useDispatch(); const isGameUpdating = useSelector(state => state.game.isProcessing || state.game.isLoadingGame); const [isOpen, setIsOpen] = useState(false); const { t, i18n } = useTranslation(); const { vibrate } = useVibrate(); - const { pane, changePane } = usePanes(); - const handleLanguageChange = (lang: string) => { + const onLanguageChanged = (lang: string) => { if (lang === i18n.language) { return; } - vibrate(); - dispatch(track({ name: `click_change_lang_to_${lang}_from_${i18n.language}` })); + dispatch(setToast({ text: 'settings.languageChanged' })); - i18n.changeLanguage(lang); + dispatch(track({ name: `click_change_lang_to_${lang}_from_${i18n.language}` })); setIsOpen(false); - dispatch(setToast({ text: 'settings.languageChanged' })); }; const handleTriggerClick = () => { @@ -64,11 +61,7 @@ const LanguagePicker = ({ children, className, place }: Props) => { setIsOpen(value => !value); }; - const handleGoToAboutLanguage = () => { - if (pane !== PaneType.AboutLanguage) { - changePane(PaneType.AboutLanguage); - } - + const onGoToAboutLanguage = () => { setIsOpen(value => !value); }; @@ -96,7 +89,12 @@ const LanguagePicker = ({ children, className, place }: Props) => {
    {shouldShowAboutInLanguages && (
  • - + {t('settings.statisticsTitle')} @@ -110,15 +108,17 @@ const LanguagePicker = ({ children, className, place }: Props) => { {SUPPORTED_LANGS.map(lang => (
  • handleLanguageChange(lang)} + isActive={lang === activeLink.lang} + tagName="link" + onClick={() => onLanguageChanged(lang)} + href={getLinkPath({ lang, route: activeLink.route })} isDisabled={isGameUpdating} variant="small" > @@ -138,7 +138,9 @@ const LanguagePicker = ({ children, className, place }: Props) => {

    - ))} - - )} -
    -
    - {shouldShowLanguageTitle && } - {shouldShowFilter - ? ( - - ) - : ( -
    - - - - -
    - )} - -
    -
    -
    - - - -
    - setIsOpen(false)}> -
    -

    {t('settings.title')}

    -
      -
    • - setShouldShowFilter(value => !value)} - > - - {t('statistics.showOneChartWithFilters')} - -
    • -
    • - setShouldShowLanguageTitle(value => !value)} - > - - {t('statistics.showTitleWithLanguage')} - -
    • -
    • - setShouldForceEnglishChart(value => !value)} - > - - Chart labels in English - -
    • -
    -
    -
    - + ))} + + )} +
    +
    + {shouldShowLanguageTitle && } + {shouldShowFilter ? ( + + ) : ( +
    + + + + +
    + )} + +
    +
    +
    + + + +
    + setIsOpen(false)}> +
    +

    {t('settings.title')}

    +
      +
    • + setShouldShowFilter((value) => !value)}> + + {t('statistics.showOneChartWithFilters')} + +
    • +
    • + setShouldShowLanguageTitle((value) => !value)} + > + + {t('statistics.showTitleWithLanguage')} + +
    • +
    • + setShouldForceEnglishChart((value) => !value)} + > + + + Chart labels in English + + +
    • +
    +
    +
    + ); }; diff --git a/src/components/Panes/AboutLanguage/AboutLanguageNeighbours.tsx b/src/components/Panes/AboutLanguage/AboutLanguageNeighbours.tsx index 6b491e7c5..044f7ad1c 100644 --- a/src/components/Panes/AboutLanguage/AboutLanguageNeighbours.tsx +++ b/src/components/Panes/AboutLanguage/AboutLanguageNeighbours.tsx @@ -9,28 +9,18 @@ import { capitalize } from '@utils/format'; import './AboutLanguageNeighbours.scss'; type Props = { - data: DictionaryInfo + data: DictionaryInfo; }; const AboutLanguageNeighbours = ({ data: { spellchecker: { - accepted: { - all, - }, - substrings: { - first, - middle, - last, - }, + accepted: { all }, + substrings: { first, middle, last }, }, }, }: Props) => { - const { - firstKeys, - middleKeys, - lastKeys, - } = useMemo(() => { + const { firstKeys, middleKeys, lastKeys } = useMemo(() => { return { firstKeys: { length2: Object.keys(first[2]), @@ -53,102 +43,95 @@ const AboutLanguageNeighbours = ({ const { t } = useTranslation(); return ( -
    -

    {t('statistics.languageTitleAtTheBeginning')}

    -
    - {[2, 3, 4].map((chunkLength) => { - const key = `length${chunkLength}` as 'length2' | 'length3' | 'length4'; +
    +

    {t('statistics.languageTitleAtTheBeginning')}

    +
    + {[2, 3, 4].map((chunkLength) => { + const key = `length${chunkLength}` as 'length2' | 'length3' | 'length4'; - return ( -
    -
      - {firstKeys[key].map(part => ( -
    • - {capitalize(part)} - - {' "'} - {part} - {'" '} - {t('end.in', { postProcess: 'interval', count: 100 })} - {' '} - {((first[chunkLength][part] / all) * 100).toFixed(2)} - % - {' '} - {t('end.wordsUsed', { count: 100 })} - -
    • - ))} -
    -
    - ); - })} -
    -

    {t('statistics.languageTitleInTheMiddle')}

    -
    - {[2, 3, 4].map((chunkLength) => { - const key = `length${chunkLength}` as 'length2' | 'length3' | 'length4'; + return ( +
    +
      + {firstKeys[key].map((part) => ( +
    • + {capitalize(part)} + + {' "'} + {part} + {'" '} + {t('end.in', { postProcess: 'interval', count: 100 })}{' '} + {((first[chunkLength][part] / all) * 100).toFixed(2)}%{' '} + {t('end.wordsUsed', { count: 100 })} + +
    • + ))} +
    +
    + ); + })} +
    +

    {t('statistics.languageTitleInTheMiddle')}

    +
    + {[2, 3, 4].map((chunkLength) => { + const key = `length${chunkLength}` as 'length2' | 'length3' | 'length4'; - return ( -
    -
      - {middleKeys[key].map(part => ( -
    • - {part} - {' '} - ${(middle[chunkLength][part] / all).toFixed(3)}`, - }), - }} - /> -
    • - ))} -
    -
    - ); - })} -
    -

    {t('statistics.languageTitleInTheEnd')}

    -
    - {[2, 3, 4].map((chunkLength) => { - const key = `length${chunkLength}` as 'length2' | 'length3' | 'length4'; + return ( +
    +
      + {middleKeys[key].map((part) => ( +
    • + {part}{' '} + ${(middle[chunkLength][part] / all).toFixed(3)}`, + }), + }} + /> +
    • + ))} +
    +
    + ); + })} +
    +

    {t('statistics.languageTitleInTheEnd')}

    +
    + {[2, 3, 4].map((chunkLength) => { + const key = `length${chunkLength}` as 'length2' | 'length3' | 'length4'; - return ( -
    -
      - {lastKeys[key].map(part => ( -
    • - {part} - . - - {' "'} - {part} - {'" '} - {t('end.in', { postProcess: 'interval', count: 100 })} - {' '} - {((last[chunkLength][part] / all) * 100).toFixed(2)} - % - {' '} - {t('end.wordsUsed', { count: 100 })} - -
    • - ))} -
    -
    - ); - })} -
    -
    + return ( +
    +
      + {lastKeys[key].map((part) => ( +
    • + {part}. + + {' "'} + {part} + {'" '} + {t('end.in', { postProcess: 'interval', count: 100 })}{' '} + {((last[chunkLength][part] / all) * 100).toFixed(2)}%{' '} + {t('end.wordsUsed', { count: 100 })} + +
    • + ))} +
    +
    + ); + })} +
    +
    ); }; diff --git a/src/components/Panes/AboutLanguage/AboutLanguagePlayDiffle.tsx b/src/components/Panes/AboutLanguage/AboutLanguagePlayDiffle.tsx index d3f23caf4..671e01680 100644 --- a/src/components/Panes/AboutLanguage/AboutLanguagePlayDiffle.tsx +++ b/src/components/Panes/AboutLanguage/AboutLanguagePlayDiffle.tsx @@ -1,18 +1,12 @@ import { useCallback } from 'react'; import { useTranslation } from 'react-i18next'; -import { Pane } from '@common-types'; - -import { - getInitPane, -} from '@api/getInit'; - import { copyMessage } from '@utils/copyMessage'; import { useDispatch, useSelector } from '@store'; import { track, setToast } from '@store/appSlice'; -import usePanes from '@hooks/usePanes'; +import useLinks from '@features/routes/hooks/useLinks'; import IconGamepad from '@components/Icons/IconGamepad'; import IconGithub from '@components/Icons/IconGithub'; @@ -24,14 +18,12 @@ import './AboutLanguagePlayDiffle.scss'; const AboutLanguagePlayDiffle = () => { const dispatch = useDispatch(); - const gameLanguage = useSelector(state => state.game.language); + const { getLinkPath } = useLinks(); + const gameLanguage = useSelector((state) => state.game.language); const { t } = useTranslation(); - const { changePane } = usePanes(); - const handleCopy = useCallback(() => { - const diffleURL = window.location.href.split('?')[0]; - const textToCopy = `${diffleURL}?p=${Pane.AboutLanguage}`; + const textToCopy = getLinkPath({ route: 'aboutLanguage', shouldHaveDomain: true }); copyMessage(textToCopy); @@ -45,46 +37,43 @@ const AboutLanguagePlayDiffle = () => { }, [dispatch]); return ( -
    -

    {t('help.whatIsDiffleTitle')}

    -

    {t('help.whatIsDiffleDescription')}

    - -
    -
    -
    -
    - -
    -
    -
    -
    -

    - {t('settings.statisticsTitle')} - : - {' '} - {t('language.currentLanguage')} -

    -
    - -
    -
    +
    +

    {t('help.whatIsDiffleTitle')}

    +

    {t('help.whatIsDiffleDescription')}

    + +
    +
    +
    +
    + +
    +
    +
    +
    +

    + {t('settings.statisticsTitle')}:{t('language.currentLanguage')} +

    +
    + +
    +
    ); }; diff --git a/src/components/Panes/AboutLanguage/AboutLanguageWordle.tsx b/src/components/Panes/AboutLanguage/AboutLanguageWordle.tsx index adad745a1..8014bd207 100644 --- a/src/components/Panes/AboutLanguage/AboutLanguageWordle.tsx +++ b/src/components/Panes/AboutLanguage/AboutLanguageWordle.tsx @@ -16,23 +16,19 @@ import AboutLanguageWordleItem from './AboutLanguageWordleItem'; import './AboutLanguageWordle.scss'; type Props = { - data: DictionaryInfo + data: DictionaryInfo; }; const AboutLanguageWordle = ({ data }: Props) => { const { spellchecker: { - accepted: { - allWordleWords, - }, - letters: { - wordle: letterPositions, - }, + accepted: { allWordleWords }, + letters: { wordle: letterPositions }, wordle, }, meta, } = data; - const gameLanguage = useSelector(state => state.game.language); + const gameLanguage = useSelector((state) => state.game.language); const [filterGroupBy, setFilterGroupBy] = useState(BestWordleType.BestGreen1_5); const wordsData = wordle[filterGroupBy] || []; @@ -65,158 +61,126 @@ const AboutLanguageWordle = ({ data }: Props) => { const { word: firstWord, - result: { - green: firsrtWordCorrect, - orange: firsrtWordPosition, - gray: firsrtWordIncorrect, - }, + result: { green: firsrtWordCorrect, orange: firsrtWordPosition, gray: firsrtWordIncorrect }, } = wordsData[0]; return ( -
    -

    {t('statistics.bestWordleWordTitle')}

    -
    - -
    -

    {t('statistics.bestWordleWordTitle')}

    -
    -

    - - {firstWord.split('').map((letter, index) => ( - // eslint-disable-next-line react/no-array-index-key - - {/* Both text-transform: uppercase and .toUppercase() replace ß with SS */} - {letter.replace('ß', 'ẞ')} - - ))} - -

    -

    ${formatLargeNumber(allWordleWords)}`, - }), - }} - /> -

    - - - {(100 * (firsrtWordCorrect / (allWordleWords * 5))).toFixed(2)} - % - - - {t('statistics.lettersCorrect')} - - - - - {(100 * (firsrtWordPosition / (allWordleWords * 5))).toFixed(2)} - % - - - {t('statistics.lettersPosition')} - - - - - {(100 * (firsrtWordIncorrect / (allWordleWords * 5))).toFixed(2)} - % - - - {t('statistics.lettersIncorrect')} - - -
    -
    -
    -

    {t('statistics.bestWordleWordPopularLettersTitle')}

    -
      - {[1, 2, 3, 4, 5].map((position, index) => ( - -
    • - - {position} - - {' '} - {Object.entries(letterPositions[index]).slice(0, 5).map( - ([letter, value]) => ( - - {/* Both text-transform: uppercase and .toUppercase() replace ß with SS */} - {letter.replace('ß', 'ẞ')} - - - {letter.replace('ß', 'ẞ')} - - {' '} - {' - '} - {((value / allWordleWords) * 100).toFixed(1)} - {'% '} - {t('end.wordsUsed', { count: 100 })} - - - ), - )} -
    • - ))} -
    -
    -
    - {wordsData.map(({ - word, - result: { - total, green, orange, - }, - }) => ( - - ))} -
    -
    - -
    -

    ${formatLargeNumber(allWordleWords)}`, - source: sourceHTML, - }), - }} +

    +

    {t('statistics.bestWordleWordTitle')}

    +
    + +
    +

    {t('statistics.bestWordleWordTitle')}

    +
    +

    + + {firstWord.split('').map((letter, index) => ( + // eslint-disable-next-line react/no-array-index-key + + {/* Both text-transform: uppercase and .toUppercase() replace ß with SS */} + {letter.replace('ß', 'ẞ')} + + ))} + +

    +

    ${formatLargeNumber(allWordleWords)}`, + }), + }} + /> +

    + + {(100 * (firsrtWordCorrect / (allWordleWords * 5))).toFixed(2)}% + {t('statistics.lettersCorrect')} + + + {(100 * (firsrtWordPosition / (allWordleWords * 5))).toFixed(2)}% + {t('statistics.lettersPosition')} + + + {(100 * (firsrtWordIncorrect / (allWordleWords * 5))).toFixed(2)}% + {t('statistics.lettersIncorrect')} + +
    +
    +
    +

    {t('statistics.bestWordleWordPopularLettersTitle')}

    +
      + {[1, 2, 3, 4, 5].map((position, index) => ( +
    • + {position}{' '} + {Object.entries(letterPositions[index]) + .slice(0, 5) + .map(([letter, value]) => ( + + {/* Both text-transform: uppercase and .toUppercase() replace ß with SS */} + {letter.replace('ß', 'ẞ')} + + {letter.replace('ß', 'ẞ')} {' - '} + {((value / allWordleWords) * 100).toFixed(1)} + {'% '} + {t('end.wordsUsed', { count: 100 })} + + + ))} +
    • + ))} +
    +
    +
    + {wordsData.map(({ word, result: { total, green, orange } }) => ( + -
    + ))} +
    +
    + +
    +

    ${formatLargeNumber(allWordleWords)}`, + source: sourceHTML, + }), + }} + /> + ); }; diff --git a/src/components/Panes/AboutLanguage/AboutLanguageWordleFilters.tsx b/src/components/Panes/AboutLanguage/AboutLanguageWordleFilters.tsx index 0063d0d0f..51a0ed2c7 100644 --- a/src/components/Panes/AboutLanguage/AboutLanguageWordleFilters.tsx +++ b/src/components/Panes/AboutLanguage/AboutLanguageWordleFilters.tsx @@ -12,81 +12,73 @@ import IconAnimatedCaret from '@components/Icons/IconAnimatedCaret'; import Button from '@components/Button/Button'; type Props = { - filterGroupBy: BestWordleType, - setFilterGroupBy: Dispatch>, + filterGroupBy: BestWordleType; + setFilterGroupBy: Dispatch>; }; -const AboutLanguageWordleFilters = ({ - filterGroupBy, - setFilterGroupBy, -}: Props) => { +const AboutLanguageWordleFilters = ({ filterGroupBy, setFilterGroupBy }: Props) => { const { handleClickSummary } = useEnhancedDetails(); const { t } = useTranslation(); return ( -

    - -

    {t('statistics.filters')}

    - -
    -
    -
    {t('statistics.filterWordleLettersTitle')}
    - -
    {t('statistics.filterWordleMaxTitle')}
    - -
    {t('statistics.filterWordleBestTitle')}
    - -
    -
    +
    + +

    {t('statistics.filters')}

    + +
    +
    +
    {t('statistics.filterWordleLettersTitle')}
    + +
    {t('statistics.filterWordleMaxTitle')}
    + +
    {t('statistics.filterWordleBestTitle')}
    + +
    +
    ); }; diff --git a/src/components/Panes/AboutLanguage/AboutLanguageWordleItem.tsx b/src/components/Panes/AboutLanguage/AboutLanguageWordleItem.tsx index 37e5f1901..3d774398e 100644 --- a/src/components/Panes/AboutLanguage/AboutLanguageWordleItem.tsx +++ b/src/components/Panes/AboutLanguage/AboutLanguageWordleItem.tsx @@ -3,55 +3,41 @@ import clsx from 'clsx'; import './AboutLanguageWordle.scss'; type Props = { - word: string - activeLetters: string[], - green: number, - orange: number, - total: number, + word: string; + activeLetters: string[]; + green: number; + orange: number; + total: number; }; -const AboutLanguageWordleItem = ({ - word, - activeLetters, - green, - orange, - total, -}: Props) => { +const AboutLanguageWordleItem = ({ word, activeLetters, green, orange, total }: Props) => { return ( -

    - - {word.split('').map((letter, index) => ( - - {letter.replace('ß', 'ẞ')} - - ))} - - {' '} - - - {((green / (total * 5)) * 100).toFixed(2)} - % - - - {' + '} - - - {((orange / (total * 5)) * 100).toFixed(2)} - % - - - {' = '} - - {(((green + orange) / (total * 5)) * 100).toFixed(2)} - % - -

    +

    + + {word.split('').map((letter, index) => ( + + {letter.replace('ß', 'ẞ')} + + ))} + {' '} + + {((green / (total * 5)) * 100).toFixed(2)}% + + {' + '} + + {((orange / (total * 5)) * 100).toFixed(2)}% + + {' = '} + + {(((green + orange) / (total * 5)) * 100).toFixed(2)}% + +

    ); }; diff --git a/src/components/Panes/AboutLanguage/AboutLenguageLengths.tsx b/src/components/Panes/AboutLanguage/AboutLenguageLengths.tsx index fad5d81ff..fef191368 100644 --- a/src/components/Panes/AboutLanguage/AboutLenguageLengths.tsx +++ b/src/components/Panes/AboutLanguage/AboutLenguageLengths.tsx @@ -29,21 +29,17 @@ import AboutLanguageChartLanguageTitle from './AboutLanguageChartLanguageTitle'; import './AboutLanguageLetters.scss'; type Props = { - data: DictionaryInfo + data: DictionaryInfo; }; -const AboutLenguageLengths = ({ - data, -}: Props) => { +const AboutLenguageLengths = ({ data }: Props) => { const { spellchecker: { - accepted: { - length, - }, + accepted: { length }, }, } = data; const dispatch = useDispatch(); - const gameLanguage = useSelector(state => state.game.language); + const gameLanguage = useSelector((state) => state.game.language); const [shouldShowLanguageTitle, setShouldShowLanguageTitle] = useState(false); const [shouldForceEnglishChart, setShouldForceEnglishChart] = useState(false); @@ -63,7 +59,10 @@ const AboutLenguageLengths = ({ const { stampOnlyTime } = getNow(); - download(dataUrl, `diffle-${gameLanguage}-${stampOnlyTime.replaceAll(':', '').replaceAll(' ', '')}.jpeg`); + download( + dataUrl, + `diffle-${gameLanguage}-${stampOnlyTime.replaceAll(':', '').replaceAll(' ', '')}.jpeg`, + ); } catch (error) { // eslint-disable-next-line no-console console.error(error); @@ -75,49 +74,51 @@ const AboutLenguageLengths = ({ const lng = shouldForceEnglishChart ? 'en' : gameLanguage; return ( -
    -
    -
    - {shouldShowLanguageTitle && } - - -
    -
    -
    - - -
    - setIsOpen(false)}> -
    -

    {t('settings.title')}

    -
      -
    • - setShouldShowLanguageTitle(value => !value)} - > - - {t('statistics.showTitleWithLanguage')} - -
    • -
    • - setShouldForceEnglishChart(value => !value)} - > - - Chart labels in English - -
    • -
    -
    -
    -
    +
    +
    +
    + {shouldShowLanguageTitle && } + + +
    +
    +
    + + +
    + setIsOpen(false)}> +
    +

    {t('settings.title')}

    +
      +
    • + setShouldShowLanguageTitle((value) => !value)} + > + + {t('statistics.showTitleWithLanguage')} + +
    • +
    • + setShouldForceEnglishChart((value) => !value)} + > + + + Chart labels in English + + +
    • +
    +
    +
    +
    ); }; diff --git a/src/components/Panes/Help/Help.tsx b/src/components/Panes/Help/Help.tsx index ce10cbd09..5aaa58b46 100644 --- a/src/components/Panes/Help/Help.tsx +++ b/src/components/Panes/Help/Help.tsx @@ -7,7 +7,7 @@ import { SUPPORTED_LANGS } from '@const'; import { getWordReportForMultipleWords } from '@api/getWordReport'; -import usePanes from '@hooks/usePanes'; +import useLink from '@features/routes/hooks/useLinks'; import useScrollEffect from '@hooks/useScrollEffect'; import IconBookOpen from '@components/Icons/IconBookOpen'; @@ -22,13 +22,12 @@ import HelpWords from './HelpWords'; import './Help.scss'; const Help = () => { + const { getLinkPath } = useLink(); const [helpGuesses, setHelpGuesses] = useState([]); const [isAlt, setIsAlt] = useState(false); const { t, i18n } = useTranslation(); - const { changePane } = usePanes(); - const tEnd = isAlt ? 'Alt' : ''; useEffect(() => { @@ -68,7 +67,11 @@ const Help = () => {

    {t('help.howToPlayText2')}

    - @@ -81,7 +84,12 @@ const Help = () => {

    )}

    - - - - setIsOpen(false)}> -

    -

    {t('statistics.titleRemoveStatistics')}

    -
      -
    • - handleRemoveGameModeStatitics(ModeFilter.Daily)} - isDisabled={!isOpen || modeFilter === ModeFilter.Practice} - > - - {t('game.modeDaily')} - -
    • -
    • - handleRemoveGameModeStatitics(ModeFilter.Practice)} - isDisabled={!isOpen || modeFilter === ModeFilter.Daily} - > - - {t('game.modePractice')} - -
    • -
    -
    - - + <> +
    + + +
    + setIsOpen(false)}> +
    +

    {t('statistics.titleRemoveStatistics')}

    +
      +
    • + handleRemoveGameModeStatitics(ModeFilter.Daily)} + isDisabled={!isOpen || modeFilter === ModeFilter.Practice} + > + + {t('game.modeDaily')} + +
    • +
    • + handleRemoveGameModeStatitics(ModeFilter.Practice)} + isDisabled={!isOpen || modeFilter === ModeFilter.Daily} + > + + {t('game.modePractice')} + +
    • +
    +
    +
    + ); }; diff --git a/src/components/Panes/Statistics/StatisticsCard.tsx b/src/components/Panes/Statistics/StatisticsCard.tsx index 287083130..bdbfa65bf 100644 --- a/src/components/Panes/Statistics/StatisticsCard.tsx +++ b/src/components/Panes/Statistics/StatisticsCard.tsx @@ -1,9 +1,7 @@ import clsx from 'clsx'; import { useTranslation } from 'react-i18next'; -import { - StatisticDataForCard, Filters, CharactersFilter, LengthFilter, -} from '@utils/statistics'; +import { StatisticDataForCard, Filters, CharactersFilter, LengthFilter } from '@utils/statistics'; import IconDiffleChart from '@components/Icons/IconDiffleChart'; import IconGithub from '@components/Icons/IconGithub'; @@ -14,12 +12,13 @@ import StatisticsCardActiveFilters from './StatisticsCardActiveFilters'; import './StatisticsCard.scss'; -type StatisticForCard = StatisticDataForCard & Filters & { - wonStreak?: number, - lostStreak?: number, - bestStreak?: number, - worstStreak?: number, -}; +type StatisticForCard = StatisticDataForCard & + Filters & { + wonStreak?: number; + lostStreak?: number; + bestStreak?: number; + worstStreak?: number; + }; const BREAKPOINTS = { LETTERS: [90, 75, 60, 45, 35, 25], @@ -68,255 +67,248 @@ const StatisticsCard = ({ const canShowStreak = charactersFilter === CharactersFilter.All && lengthFilter === LengthFilter.All; return ( -
    -
    -
    - -
    -

    - - {lettersPerGame.toFixed(1)} - - - {t('statistics.letters')} -

    -

    - {t('statistics.medianWordsBefore')} - - {wordsPerGame.toFixed(1)} - - - {t('statistics.medianWords')} -

    -
    -

    - - {lettersPerGame.toFixed(1)} - - {t('statistics.letters')} - - {t('statistics.median')} - {' ('} - {t('statistics.average')} - {averageLettersPerGame.toFixed(1)} - {', '} - {t('statistics.maximum')} - {maxLettersInGame} - {') '} - -

    -

    - {t('statistics.medianWordsBefore')} - - {wordsPerGame.toFixed(1)} - - {t('statistics.medianWords')} - - {t('statistics.median')} - {' ('} - {t('statistics.average')} - {averageWordsPerGame.toFixed(1)} - {', '} - {t('statistics.maximum')} - {maxWordsInGame} - {') '} - -

    -
    -

    - {t('statistics.averageLetters')} - {' '} - {lettersPerWord.toFixed(1)} - {' '} - {t('statistics.inWord')} -

    -

    - {t('statistics.averageLetters')} - {lettersInFirstWord.toFixed(1)} - {t('statistics.inFirstWord')} - - {lettersInSecondWord.toFixed(1)} - {t('statistics.inSecondWord')} - -

    -

    - {t('statistics.averageGameTime')} - {timePerGame.hours > 0 && ( - <> - {timePerGame.hours} - h - - )} - {' '} - {timePerGame.minutes > 0 && ( - <> - {timePerGame.minutes} - m - - )} - {' '} - {timePerGame.seconds > 0 && ( - <> - {timePerGame.seconds} - s - - )} - - {t('statistics.totalGameTime')} - {' '} - {totalTime.hours > 0 && ( - <> - {totalTime.hours} - {' '} - h - - )} - {' '} - {totalTime.minutes > 0 && ( - <> - {totalTime.minutes} - {' '} - m - - )} - {' '} - {totalTime.seconds > 0 && ( - <> - {totalTime.seconds} - {' '} - s - - )} - -

    - {rejectedWordsPerGame > 0 && ( -

    - - - - -

    - )} - {rejectedWordsPerGame === 0 && rejectedWordsWorstWonInGame > 0 && ( -

    - -

    - )} -
    -

    - - - {(lettersCorrect * lettersPerGame).toFixed(1)} - - - {t('statistics.lettersCorrect')} - - - - {(lettersPosition * lettersPerGame).toFixed(1)} - - - {t('statistics.lettersPosition')} - - - - {(lettersIncorrect * lettersPerGame).toFixed(1)} - - - {t('statistics.lettersIncorrect')} - - - - {(lettersTypedKnownIncorrect * lettersPerGame).toFixed(1)} - - - {t('statistics.lettersIncorrectAndTyped')} - -

    -
    -

    -

    - - {((totalWon / totalGames) * 100).toFixed(0)} - % - - {t('statistics.totalWon')} -

    - {canShowStreak && wonStreak > 0 && ( -

    - {wonStreak} - {t('statistics.totalWonStreak', { - postProcess: 'interval', - count: wonStreak, - })} -

    - )} - {canShowStreak && lostStreak > 0 && ( -

    - {lostStreak} - {t('statistics.totalLostStreak', { - postProcess: 'interval', - count: lostStreak, - })} -

    - )} - {canShowStreak && bestStreak > 0 && ( -

    - {bestStreak} - {' '} - {t('statistics.totalBestStreak')} - - {t('statistics.streakTooltipWithWorstStreak')} - {' '} - {worstStreak} - -

    - )} -
    -
    - {diffleURL.includes('github') && } - - {diffleURL} - - {' '} - -
    -
    +
    +
    +
    + +
    +

    + + {lettersPerGame.toFixed(1)} + + + {t('statistics.letters')} +

    +

    + {t('statistics.medianWordsBefore')} + + {wordsPerGame.toFixed(1)} + + + {t('statistics.medianWords')} +

    +
    +

    + {lettersPerGame.toFixed(1)} + {t('statistics.letters')} + + {t('statistics.median')} + {' ('} + {t('statistics.average')} + {averageLettersPerGame.toFixed(1)} + {', '} + {t('statistics.maximum')} + {maxLettersInGame} + {') '} + +

    +

    + {t('statistics.medianWordsBefore')} + {wordsPerGame.toFixed(1)} + {t('statistics.medianWords')} + + {t('statistics.median')} + {' ('} + {t('statistics.average')} + {averageWordsPerGame.toFixed(1)} + {', '} + {t('statistics.maximum')} + {maxWordsInGame} + {') '} + +

    +
    +

    + {t('statistics.averageLetters')} {lettersPerWord.toFixed(1)}{' '} + {t('statistics.inWord')} +

    +

    + {t('statistics.averageLetters')} + {lettersInFirstWord.toFixed(1)} + {t('statistics.inFirstWord')} + + {lettersInSecondWord.toFixed(1)} + {t('statistics.inSecondWord')} + +

    +

    + {t('statistics.averageGameTime')} + {timePerGame.hours > 0 && ( + <> + {timePerGame.hours}h + + )}{' '} + {timePerGame.minutes > 0 && ( + <> + {timePerGame.minutes}m + + )}{' '} + {timePerGame.seconds > 0 && ( + <> + {timePerGame.seconds}s + + )} + + {t('statistics.totalGameTime')}{' '} + {totalTime.hours > 0 && ( + <> + {totalTime.hours} h + + )}{' '} + {totalTime.minutes > 0 && ( + <> + {totalTime.minutes} m + + )}{' '} + {totalTime.seconds > 0 && ( + <> + {totalTime.seconds} s + + )} + +

    + {rejectedWordsPerGame > 0 && ( +

    + + + + +

    + )} + {rejectedWordsPerGame === 0 && rejectedWordsWorstWonInGame > 0 && ( +

    + +

    + )} +
    +

    + + + {(lettersCorrect * lettersPerGame).toFixed(1)} + + + {t('statistics.lettersCorrect')} + + + + {(lettersPosition * lettersPerGame).toFixed(1)} + + + {t('statistics.lettersPosition')} + + + + {(lettersIncorrect * lettersPerGame).toFixed(1)} + + + {t('statistics.lettersIncorrect')} + + + + {(lettersTypedKnownIncorrect * lettersPerGame).toFixed(1)} + + + {t('statistics.lettersIncorrectAndTyped')} + +

    +
    +

    +

    + + {((totalWon / totalGames) * 100).toFixed(0)} + % + + {t('statistics.totalWon')} +

    + {canShowStreak && wonStreak > 0 && ( +

    + {wonStreak} + {t('statistics.totalWonStreak', { + postProcess: 'interval', + count: wonStreak, + })} +

    + )} + {canShowStreak && lostStreak > 0 && ( +

    + {lostStreak} + {t('statistics.totalLostStreak', { + postProcess: 'interval', + count: lostStreak, + })} +

    + )} + {canShowStreak && bestStreak > 0 && ( +

    + {bestStreak} {t('statistics.totalBestStreak')} + + {t('statistics.streakTooltipWithWorstStreak')} {worstStreak} + +

    + )}
    +
    + {diffleURL.includes('github') && } + {diffleURL}{' '} + +
    +
    +
    ); }; diff --git a/src/components/Panes/Statistics/StatisticsFilters.tsx b/src/components/Panes/Statistics/StatisticsFilters.tsx index 10afab494..e72e95eed 100644 --- a/src/components/Panes/Statistics/StatisticsFilters.tsx +++ b/src/components/Panes/Statistics/StatisticsFilters.tsx @@ -1,30 +1,15 @@ -import { - useEffect, useState, Dispatch, SetStateAction, -} from 'react'; +import { useEffect, useMemo, useCallback } from 'react'; import { useTranslation } from 'react-i18next'; +import { useSearchParams } from 'wouter'; import { WINNING_WORD_IS_CONSIDER_LONG_AFTER_X_LATERS } from '@const'; -import { useDispatch, useSelector } from '@store'; -import { track } from '@store/appSlice'; -import { - selectGameLanguageKeyboardInfo, -} from '@store/selectors'; - -import { - keepIfInEnum, -} from '@utils/ts'; -import { - Filters, - ModeFilter, - CharactersFilter, - LengthFilter, -} from '@utils/statistics'; - -import usePanes from '@hooks/usePanes'; -import useVibrate from '@hooks/useVibrate'; +import { useSelector } from '@store'; +import { selectGameLanguageKeyboardInfo } from '@store/selectors'; + +import { ModeFilter, CharactersFilter, LengthFilter } from '@utils/statistics'; + import useEnhancedDetails from '@hooks/useEnhancedDetails'; -import useEffectChange from '@hooks/useEffectChange'; import IconAnimatedCaret from '@components/Icons/IconAnimatedCaret'; import IconDay from '@components/Icons/IconDay'; @@ -37,176 +22,164 @@ import IconRulerBig from '@components/Icons/IconRulerBig'; import ButtonTile from '@components/Button/ButtonTile'; -import { INITIAL_FILTERS } from './constants'; import '../Settings/Settings.scss'; +import { StatisticUrlFilters, getFilterURLValues, getFiltersFromSearch } from './utils/statistics-params'; -type Props = { - setFiltersData: Dispatch> -}; - -const StatisticsFilters = ({ setFiltersData }: Props) => { - const dispatch = useDispatch(); - const { - paneParams: { - modeFilter: paneModeFilter = '', - }, - } = usePanes(); - const initialModeFilter = keepIfInEnum(paneModeFilter, ModeFilter) ?? INITIAL_FILTERS.modeFilter; +const StatisticsFilters = () => { const { hasSpecialCharacters: hasLanguageSpecialCharacters } = useSelector(selectGameLanguageKeyboardInfo); - const [modeFilter, setModeFilter] = useState(initialModeFilter); - const [charactersFilter, setModeCharactersFilter] = useState(INITIAL_FILTERS.charactersFilter); - const [lengthFilter, setLengthFilter] = useState(INITIAL_FILTERS.lengthFilter); + const [searchParams, setSearchParams] = useSearchParams(); - const { t } = useTranslation(); + const filtersData = useMemo(() => { + return getFiltersFromSearch(searchParams); + }, [searchParams]); - const { vibrate } = useVibrate(); + const { t } = useTranslation(); const { handleClickSummary } = useEnhancedDetails(); - useEffectChange(() => { - vibrate(); - }, [modeFilter, charactersFilter, lengthFilter]); - - useEffect(() => { - const filtersData = { - modeFilter, - charactersFilter, - lengthFilter, - }; - - dispatch(track({ name: 'click_statistics_filter', params: { filters: `${modeFilter}_${charactersFilter}_${lengthFilter}` } })); + const handleFilterChange = useCallback((name: StatisticUrlFilters, value: string) => { + setSearchParams((prev) => ({ + ...getFilterURLValues(prev), + [name]: value, + }), { + replace: true, + }); + }, []); - setFiltersData(filtersData); - }, [modeFilter, charactersFilter, lengthFilter, setFiltersData, dispatch]); useEffect(() => { // After changing language - const shouldResetSpecialCharacters = !hasLanguageSpecialCharacters && charactersFilter !== CharactersFilter.All; + const shouldResetSpecialCharacters = + !hasLanguageSpecialCharacters && filtersData.charactersFilter !== CharactersFilter.All; if (shouldResetSpecialCharacters) { - setModeCharactersFilter(CharactersFilter.All); + handleFilterChange('characters', CharactersFilter.All); } - }, [charactersFilter, hasLanguageSpecialCharacters]); + }, [filtersData.charactersFilter, hasLanguageSpecialCharacters]); return ( -
    - -

    {t('statistics.filters')}

    - -
    -
    -
      -
    • - setModeFilter(ModeFilter.All)} - > - - {t('statistics.filterAll')} - -
    • -
    • - setModeFilter(ModeFilter.Daily)} - > - - {t('game.modeDaily')} - -
    • -
    • - setModeFilter(ModeFilter.Practice)} - > - - {t('game.modePractice')} - -
    • -
    - {hasLanguageSpecialCharacters && ( -
      -
    • - setModeCharactersFilter(CharactersFilter.All)} - > - - {t('statistics.filterAll')} - -
    • -
    • - setModeCharactersFilter(CharactersFilter.NoSpecial)} - > - - - -
    • -
    • - setModeCharactersFilter(CharactersFilter.Special)} - > - - - -
    • -
    - )} -
      -
    • - setLengthFilter(LengthFilter.All)} - > - - {t('statistics.filterAll')} - -
    • -
    • - setLengthFilter(LengthFilter.Short)} - > - - - -
    • -
    • - setLengthFilter(LengthFilter.Long)} - > - - - -
    • -
    -
    -
    +
    + +

    {t('statistics.filters')}

    + +
    +
    +
      +
    • + handleFilterChange('mode', ModeFilter.All)} + > + + {t('statistics.filterAll')} + +
    • +
    • + handleFilterChange('mode', ModeFilter.Daily)} + > + + {t('game.modeDaily')} + +
    • +
    • + handleFilterChange('mode', ModeFilter.Practice)} + > + + {t('game.modePractice')} + +
    • +
    + {hasLanguageSpecialCharacters && ( +
      +
    • + handleFilterChange('characters', CharactersFilter.All)} + > + + {t('statistics.filterAll')} + +
    • +
    • + handleFilterChange('characters', CharactersFilter.NoSpecial)} + > + + + +
    • +
    • + handleFilterChange('characters', CharactersFilter.Special)} + > + + + +
    • +
    + )} +
      +
    • + handleFilterChange('length', LengthFilter.All)} + > + + {t('statistics.filterAll')} + +
    • +
    • + handleFilterChange('length', LengthFilter.Short)} + > + + + +
    • +
    • + handleFilterChange('length', LengthFilter.Long)} + > + + + +
    • +
    +
    +
    ); }; diff --git a/src/components/Panes/Statistics/StatisticsHint.tsx b/src/components/Panes/Statistics/StatisticsHint.tsx index b1820decf..8dda5c081 100644 --- a/src/components/Panes/Statistics/StatisticsHint.tsx +++ b/src/components/Panes/Statistics/StatisticsHint.tsx @@ -1,35 +1,33 @@ -import { useCallback, useMemo } from 'react'; +import { useCallback, useEffect, useMemo } from 'react'; import { useTranslation } from 'react-i18next'; -import { Pane, GameMode } from '@common-types'; +import { GameMode } from '@common-types'; -import { useSelector } from '@store'; +import { useDispatch, useSelector } from '@store'; +import { track } from '@store/appSlice'; -import { - getStatistic, - getStatisticParamsForWord, - getStreakForFilter, -} from '@utils/statistics'; +import { getStatistic, getStatisticParamsForWord, getStreakForFilter } from '@utils/statistics'; import Button from '@components/Button/Button'; -import usePanes from '@hooks/usePanes'; - import IconDiffleChart from '@components/Icons/IconDiffleChart'; import IconHeartStreak from '@components/Icons/IconHeartStreak'; import './StatisticsHint.scss'; +import useLinks from '@features/routes/hooks/useLinks'; + +import { getSearchForMode } from './utils/statistics-params'; const StatisticsHint = () => { - const wordToGuess = useSelector(state => state.game.wordToGuess); - const gameLanguage = useSelector(state => state.game.language); - const lastWordAddedToStatitstic = useSelector(state => state.game.lastWordAddedToStatitstic); - const gameMode = useSelector(state => state.game.mode); + const { getLinkPath } = useLinks(); + const dispatch = useDispatch(); + const wordToGuess = useSelector((state) => state.game.wordToGuess); + const gameLanguage = useSelector((state) => state.game.language); + const lastWordAddedToStatitstic = useSelector((state) => state.game.lastWordAddedToStatitstic); + const gameMode = useSelector((state) => state.game.mode); const { t } = useTranslation(); - const { changePane } = usePanes(); - const { wonStreak } = useMemo(() => { try { if (!gameLanguage) { @@ -39,17 +37,13 @@ const StatisticsHint = () => { if (lastWordAddedToStatitstic) { return getStreakForFilter(gameLanguage, { modeFilter: gameMode }); } - const { - isShort, + const { isShort, hasSpecialCharacters } = getStatisticParamsForWord(wordToGuess); + + const { lastGame: { word: lastIndexeWord } = {} } = getStatistic({ + gameLanguage, + gameMode, hasSpecialCharacters, - } = getStatisticParamsForWord(wordToGuess); - - const { - lastGame: { - word: lastIndexeWord, - } = {}, - } = getStatistic({ - gameLanguage, gameMode, hasSpecialCharacters, isShort, + isShort, }); if (lastIndexeWord === wordToGuess) { @@ -62,35 +56,48 @@ const StatisticsHint = () => { return { wonStreak: 0 }; }, [gameLanguage, gameMode, wordToGuess, lastWordAddedToStatitstic]); - const handleClick = useCallback(() => { - changePane(Pane.Statistics, { modeFilter: gameMode }); - }, [changePane, gameMode]); + const trackHintDetailsClicked = useCallback(() => { + dispatch(track({ name: `click_streak_${wonStreak}_${gameMode}_check` })); + }, [wonStreak, gameMode]); const isNiceNumberToHint = [5, 10].includes(wonStreak) || (wonStreak % 25 === 0 && wonStreak !== 0); const isModeWithoutStatistics = gameMode === GameMode.SandboxLive; const shouldRender = gameLanguage && isNiceNumberToHint && !isModeWithoutStatistics; + useEffect(() => { + if (shouldRender) { + dispatch(track({ name: `displayed_streak_${wonStreak}_${gameMode}_check` })); + } + }, [shouldRender, wonStreak, gameMode]); + if (!shouldRender) { return null; } return ( -
    -

    - - {wonStreak} - - {t('statistics.totalWonStreak', { - postProcess: 'interval', - count: wonStreak, - })} - -

    - -
    +
    +

    + + {wonStreak} + + {t('statistics.totalWonStreak', { + postProcess: 'interval', + count: wonStreak, + })} + +

    + +
    ); }; diff --git a/src/components/Panes/Statistics/constants.tsx b/src/components/Panes/Statistics/constants.tsx index 0f2cc188e..6b5f40491 100644 --- a/src/components/Panes/Statistics/constants.tsx +++ b/src/components/Panes/Statistics/constants.tsx @@ -1,6 +1,4 @@ -import { - Filters, ModeFilter, CharactersFilter, LengthFilter, -} from '@utils/statistics'; +import { Filters, ModeFilter, CharactersFilter, LengthFilter } from '@utils/statistics'; export const ALL_DATA_FILTERS: Filters = { modeFilter: ModeFilter.All, diff --git a/src/components/Panes/Statistics/utils/statistics-params.ts b/src/components/Panes/Statistics/utils/statistics-params.ts new file mode 100644 index 000000000..aa290830c --- /dev/null +++ b/src/components/Panes/Statistics/utils/statistics-params.ts @@ -0,0 +1,45 @@ +import { GameMode } from '@common-types'; +import { keepIfInEnum } from '@utils/ts'; +import { CharactersFilter, Filters, LengthFilter, ModeFilter } from '@utils/statistics'; +import { INITIAL_FILTERS } from '../constants'; + +const URLParams = { + mode: 'mode', + characters: 'characters', + length: 'length', +} as const; + +export type StatisticUrlFilters = keyof typeof URLParams; + +export const getFilterURLValues = (search: string | URLSearchParams) => { + const params = new URLSearchParams(search); + + return { + mode: keepIfInEnum(params.get(URLParams.mode), ModeFilter) ?? INITIAL_FILTERS.modeFilter, + characters: + keepIfInEnum(params.get(URLParams.characters), CharactersFilter) ?? + INITIAL_FILTERS.charactersFilter, + length: + keepIfInEnum(params.get(URLParams.length), LengthFilter) ?? INITIAL_FILTERS.lengthFilter, + }; +}; + +export const getFiltersFromSearch = (search: string | URLSearchParams) => { + const urlValues = getFilterURLValues(search); + + return { + modeFilter: urlValues.mode, + charactersFilter: urlValues.characters, + lengthFilter: urlValues.length, + } satisfies Filters; +}; + +export const getSearchForMode = (mode: ModeFilter | GameMode) => { + if (mode === INITIAL_FILTERS.modeFilter) { + return ''; + } + + const filterableMode = keepIfInEnum(mode, ModeFilter); + + return filterableMode ? `?${URLParams.mode}=${mode}` : ''; +}; diff --git a/src/components/Panes/YearSummary/YearSummary.tsx b/src/components/Panes/YearSummary/YearSummary.tsx index 7d6d56b2b..433f5482f 100644 --- a/src/components/Panes/YearSummary/YearSummary.tsx +++ b/src/components/Panes/YearSummary/YearSummary.tsx @@ -1,6 +1,7 @@ import { useQuery } from '@tanstack/react-query'; import { YearSummaryInfo } from '@common-types'; +import { ROOT_PATH } from '@const'; import { useSelector } from '@store'; @@ -18,7 +19,7 @@ const getSummaryData = async ( return undefined; } - const response = await fetch(`./year-summary/${lang}-info.json`); + const response = await fetch(`${ROOT_PATH}year-summary/${lang}-info.json`); const rawData = await response.json(); return rawData; diff --git a/src/components/Share/SharedContent.tsx b/src/components/Share/SharedContent.tsx index 605aa82bd..fcb860b5b 100644 --- a/src/components/Share/SharedContent.tsx +++ b/src/components/Share/SharedContent.tsx @@ -119,6 +119,7 @@ const SharedContent = () => { setHash(sharedResult); + // TODO: replace with some kind of logic const isFirstGame = getInitPane() === Pane.Help; const shouldAutoOpenSharedResult = !isFirstGame && canUserSeeUsedWords; diff --git a/src/const.ts b/src/const.ts index 2d347873d..432dec101 100644 --- a/src/const.ts +++ b/src/const.ts @@ -5,6 +5,8 @@ export const isDev = (window.location.origin || '')?.includes('localhost') || fa export const WORD_MAXLENGTH = 15; +export const ROOT_PATH = '/diffle-lang/'; + // If breaking changes are released you can set a date stamp here and it will block the game export const UPDATE_BLOCK_DAILY = '12.02.2025'; @@ -143,7 +145,6 @@ export const SUPPORTED_DICTIONARY_BY_LANG: { cs: { code: 'cs', languages: ['cs', 'cs-CZ'], - title: 'DIFFLE - Hra jako Wordle (v češtině, bez omezení znaků) 🇨🇿', keyLinesVariants: KEY_LINES_CS_VARIANTS, keyLinesToUse: KEY_LINES_CS_VARIANTS[0].keyLines, allowedKeys: [...SUPPORTED_BUT_NOT_INCLUDED_IN_VIRTUAL_KEY_LINES, ...KEY_LINES_CS_VARIANTS[0].keyLines.flatMap(key => key)], @@ -159,7 +160,6 @@ export const SUPPORTED_DICTIONARY_BY_LANG: { de: { code: 'de', languages: ['de', 'de-DE'], - title: 'DIFFLE - das Spiel wie Wordle (auf Deutsch, ohne Zeichenbegrenzung) 🇩🇪', keyLinesVariants: KEY_LINES_DE_VARIANTS, keyLinesToUse: KEY_LINES_DE_VARIANTS[0].keyLines, allowedKeys: [...SUPPORTED_BUT_NOT_INCLUDED_IN_VIRTUAL_KEY_LINES, ...KEY_LINES_DE_VARIANTS[0].keyLines.flatMap(key => key)], @@ -176,7 +176,6 @@ export const SUPPORTED_DICTIONARY_BY_LANG: { en: { code: 'en', languages: ['en', 'en-UK'], - title: 'DIFFLE - the game like Wordle (without character limit)', keyLinesVariants: KEY_LINES_EN_VARIANTS, keyLinesToUse: KEY_LINES_EN_VARIANTS[0].keyLines, allowedKeys: [...SUPPORTED_BUT_NOT_INCLUDED_IN_VIRTUAL_KEY_LINES, ...KEY_LINES_EN_VARIANTS[0].keyLines.flatMap(key => key)], @@ -194,7 +193,6 @@ export const SUPPORTED_DICTIONARY_BY_LANG: { code: 'es', languages: ['es'], isBeta: true, - title: 'DIFFLE - el juego similar a Wordle (sin límite de caracteres) 🇪🇸', keyLinesVariants: KEY_LINES_ES_VARIANTS, keyLinesToUse: KEY_LINES_ES_VARIANTS[0].keyLines, allowedKeys: [...SUPPORTED_BUT_NOT_INCLUDED_IN_VIRTUAL_KEY_LINES, ...KEY_LINES_ES_VARIANTS[0].keyLines.flatMap(key => key)], @@ -211,7 +209,6 @@ export const SUPPORTED_DICTIONARY_BY_LANG: { code: 'es', languages: ['es'], isBeta: true, - title: 'DIFFLE - peli kuin Wordle (ilman merkkirajoitusta) 🇫🇮', keyLinesVariants: KEY_LINES_FI_VARIANTS, keyLinesToUse: KEY_LINES_FI_VARIANTS[0].keyLines, allowedKeys: [...SUPPORTED_BUT_NOT_INCLUDED_IN_VIRTUAL_KEY_LINES, ...KEY_LINES_FI_VARIANTS[0].keyLines.flatMap(key => key)], @@ -227,7 +224,6 @@ export const SUPPORTED_DICTIONARY_BY_LANG: { fr: { code: 'fr', languages: ['fr'], - title: 'DIFFLE - le jeu similaire à Wordle (en français, sans limite de caractères) 🇫🇷', keyLinesVariants: KEY_LINES_FR_VARIANTS, keyLinesToUse: KEY_LINES_FR_VARIANTS[0].keyLines, allowedKeys: [...SUPPORTED_BUT_NOT_INCLUDED_IN_VIRTUAL_KEY_LINES, ...KEY_LINES_FR_VARIANTS[0].keyLines.flatMap(key => key)], @@ -245,7 +241,6 @@ export const SUPPORTED_DICTIONARY_BY_LANG: { code: 'it', languages: ['it'], isBeta: true, - title: 'DIFFLE - gioco simile a Wordle (in italiano, senza limite di caratteri) 🇮🇹', keyLinesVariants: KEY_LINES_IT_VARIANTS, keyLinesToUse: KEY_LINES_IT_VARIANTS[0].keyLines, allowedKeys: [...SUPPORTED_BUT_NOT_INCLUDED_IN_VIRTUAL_KEY_LINES, ...KEY_LINES_IT_VARIANTS[0].keyLines.flatMap(key => key)], @@ -261,7 +256,6 @@ export const SUPPORTED_DICTIONARY_BY_LANG: { pl: { code: 'pl', languages: ['pl', 'pl-PL'], - title: 'DIFFLE - gra jak Wordle (po polsku, bez limitu znaków) 🇵🇱', keyLinesVariants: KEY_LINES_PL_VARIANTS, keyLinesToUse: KEY_LINES_PL_VARIANTS[0].keyLines, allowedKeys: [...SUPPORTED_BUT_NOT_INCLUDED_IN_VIRTUAL_KEY_LINES, ...KEY_LINES_PL_VARIANTS[0].keyLines.flatMap(key => key)], diff --git a/src/features/routes/components/Routes/Routes.tsx b/src/features/routes/components/Routes/Routes.tsx new file mode 100644 index 000000000..b7d005018 --- /dev/null +++ b/src/features/routes/components/Routes/Routes.tsx @@ -0,0 +1,80 @@ +import { useEffect } from 'react'; +import { useTranslation } from 'react-i18next'; +import { Route, Switch, useLocation } from 'wouter'; + +import { ROOT_PATH } from '@const'; + +import { getLangFromUrl } from '@utils/lang'; + +import Help from '@components/Panes/Help/Help'; +import Game from '@components/Panes/Game/Game'; +import Settings from '@components/Panes/Settings/Settings'; +import Statistics from '@components/Panes/Statistics/Statistics'; +import AboutLanguage from '@components/Panes/AboutLanguage/AboutLanguage'; +import YearSummary from '@components/Panes/YearSummary/YearSummary'; + +import { linksByPaths, SupportedRoutes, path404Data } from '@features/routes/const'; + +const paths = Object.values(linksByPaths); + +const componentsByRoutes: Record React.ReactNode> = { + help: Help, + game: Game, + settings: Settings, + statistics: Statistics, + aboutLanguage: AboutLanguage, + hejto2024: YearSummary, + 404: () => '404 component', +}; + +const Routes = () => { + const [location, navigate] = useLocation(); + const { i18n } = useTranslation(); + + useEffect(() => { + const { language: appLanguage } = i18n; + const langToUse = getLangFromUrl(); + + const isRootUrl = location === ROOT_PATH; + + const shouldRedirectToLang = isRootUrl; + if (shouldRedirectToLang) { + navigate(`${ROOT_PATH}${appLanguage}`); + + return; + } + + const is404 = !langToUse; + if (is404) { + if (location !== `${ROOT_PATH}404`) { + navigate(`${ROOT_PATH}404?notFound=${location.replace(ROOT_PATH, '')}`); + } + + return; + } + + if (appLanguage !== langToUse) { + i18n.changeLanguage(langToUse); + } + + const { + title + } = linksByPaths[location.replace(ROOT_PATH, '')] || path404Data; + + document.title = title; + document.documentElement.lang = langToUse; + }, [i18n.changeLanguage, location, navigate]); + + return ( +
    + + {paths.map(({ path, route }) => ( + + ))} + 404 + +
    + ); +}; + +export default Routes; diff --git a/src/features/routes/const.ts b/src/features/routes/const.ts new file mode 100644 index 000000000..098db1bb1 --- /dev/null +++ b/src/features/routes/const.ts @@ -0,0 +1,96 @@ +import { SUPPORTED_LANGS } from '@const'; +import { resources } from '../../locales/langs'; +import { getLangRouteKey } from './utils/getLangRouteKey'; +import { getLangFromUrl } from '@utils/lang'; + +export const supportedRoutes = [ + 'game', + 'help', + 'settings', + 'statistics', + 'aboutLanguage', + 'hejto2024', +] as const; + +export type SupportedRoutes = (typeof supportedRoutes)[number] | '404'; + +type SeoData = { + title: string; + metaDescription: string; + openGraphTitle: string; + openGraphDescription: string; +}; + +const getSeoData = (strings: { [key: string]: string }, route: string, fallback?: SeoData): SeoData => { + const fallbackTitle = fallback?.title || ''; + const fallbackMetaDescription = fallback?.metaDescription || ''; + const fallbackOpenGraphTitle = strings[`route.${route}.title`] || fallback?.openGraphTitle || ''; + const fallbackOpenGraphDescription = + strings[`route.${route}.metaDescription`] || fallback?.openGraphDescription || ''; + + return { + title: strings[`route.${route}.title`] || fallbackTitle, + metaDescription: strings[`route.${route}.metaDescription`] || fallbackMetaDescription, + openGraphTitle: strings[`route.${route}.openGraphTitle`] || fallbackOpenGraphTitle, + openGraphDescription: strings[`route.${route}.openGraphDescription`] || fallbackOpenGraphDescription, + }; +}; + +export type LinkData = SeoData & { + path: string; + route: SupportedRoutes; + lang: string; +}; + +type Stack = { + linksByPaths: { + [path: string]: LinkData; + }; + pathsByLangRouteKey: { + [langRouteKey: string]: string; + }; +}; + +const routesData = SUPPORTED_LANGS.reduce( + (stack: Stack, lang) => { + const translationStrings = resources[lang]?.translation; + + if (!translationStrings) { + return stack; + } + + const defaultSeo = getSeoData(translationStrings, 'game'); + + supportedRoutes.forEach((route) => { + const path = route === 'game' ? lang : `${lang}/${resources[lang].translation[`route.${route}`]}`; + + if (!path) { + throw `Missing path for ${lang} ${route}!`; + } + + stack.linksByPaths[path] = { + ...getSeoData(translationStrings, route, defaultSeo), + path, + route, + lang, + }; + stack.pathsByLangRouteKey[getLangRouteKey({ lang, route })] = path; + }); + + return stack; + }, + { + linksByPaths: {}, + pathsByLangRouteKey: {}, + }, +); + +export const { linksByPaths } = routesData; +export const { pathsByLangRouteKey } = routesData; + +export const path404Data: LinkData = { + path: '', + route: '404', + lang: getLangFromUrl() || '', + ...getSeoData(resources.en.translation, '404'), +}; diff --git a/src/hooks/useLangugeChangeIfNeeded.ts b/src/features/routes/hooks/useLangugeChangeIfNeeded.ts similarity index 66% rename from src/hooks/useLangugeChangeIfNeeded.ts rename to src/features/routes/hooks/useLangugeChangeIfNeeded.ts index 01847c7ee..c9e06f2ee 100644 --- a/src/hooks/useLangugeChangeIfNeeded.ts +++ b/src/features/routes/hooks/useLangugeChangeIfNeeded.ts @@ -9,6 +9,7 @@ import { setGameLanguage } from '@store/gameSlice'; import { getLangFromUrl, getLangFromBrowser } from '@utils/lang'; import useEffectChange from '@hooks/useEffectChange'; +import { useLocation } from 'wouter'; /* There are two languages used by the app: one for translations (i18n), and the other for the game. @@ -17,35 +18,14 @@ import useEffectChange from '@hooks/useEffectChange'; Once the language of the game is changed, the mechanism for restoring the game is triggered the same to the game mode change. */ export default function useLangugeChangeIfNeeded() { - const isGameUpdating = useSelector(state => state.game.isProcessing || state.game.isLoadingGame); + const [location, navigate] = useLocation(); + const gameLanguage = useSelector((state) => state.game.language); + const isGameUpdating = useSelector((state) => state.game.isProcessing || state.game.isLoadingGame); const [wasAppLanguageDetected, setWasAppLanguageDetected] = useState(false); const dispatch = useDispatch(); - const gameLanguage = useSelector(state => state.game.language); const { i18n } = useTranslation(); - useEffectChange(() => { - const { language: appLanguage } = i18n; - const langFromUrl = getLangFromUrl(); - - if (!langFromUrl || appLanguage !== langFromUrl) { - const currentUrl = window.location.href.replace(window.location.search, ''); - const newLocation = `${currentUrl.replace(`diffle-lang/${langFromUrl}`, 'diffle-lang/')}${appLanguage}`; - - const { title } = SUPPORTED_DICTIONARY_BY_LANG[appLanguage]; - document.title = title; - document.documentElement.lang = appLanguage; - - window.history.replaceState(null, title, newLocation); - } - - const { title } = SUPPORTED_DICTIONARY_BY_LANG[appLanguage]; - if (appLanguage && title) { - document.title = title; - document.documentElement.lang = appLanguage; - } - }, [wasAppLanguageDetected, i18n.language]); - useEffect(() => { if (!isGameUpdating && wasAppLanguageDetected) { const appLanguage = i18n.language; diff --git a/src/features/routes/hooks/useLinks.ts b/src/features/routes/hooks/useLinks.ts new file mode 100644 index 000000000..491da84d6 --- /dev/null +++ b/src/features/routes/hooks/useLinks.ts @@ -0,0 +1,40 @@ +import { useTranslation } from 'react-i18next'; +import { useLocation } from 'wouter'; +import { useCallback, useMemo } from 'react'; + +import { ROOT_PATH } from '@const'; + +import { SupportedRoutes, linksByPaths, path404Data } from '../const'; +import { getRoute } from '../utils/getRoute'; + +function useLink() { + const [location] = useLocation(); + const { i18n } = useTranslation(); + + const activeLink = useMemo(() => { + return linksByPaths[location.replace(ROOT_PATH, '')] || path404Data; + }, [location]); + + const getLinkPath = useCallback( + ({ + route, + lang, + shouldHaveDomain = false, + }: { + route: SupportedRoutes; + lang?: string; + shouldHaveDomain?: boolean; + }) => { + const domainPart = shouldHaveDomain ? window?.location?.origin : ''; + return domainPart + getRoute({ lang: lang ?? i18n.language, route }); + }, + [i18n.language], + ); + + return { + activeLink, + getLinkPath, + }; +} + +export default useLink; diff --git a/src/hooks/usePanes.ts b/src/features/routes/hooks/usePanes.ts similarity index 100% rename from src/hooks/usePanes.ts rename to src/features/routes/hooks/usePanes.ts diff --git a/src/features/routes/utils/getLangRouteKey.ts b/src/features/routes/utils/getLangRouteKey.ts new file mode 100644 index 000000000..65ad30910 --- /dev/null +++ b/src/features/routes/utils/getLangRouteKey.ts @@ -0,0 +1,8 @@ +type Params = { + lang: string, + route: string, +}; + +export const getLangRouteKey = ({ lang, route }: Params) => { + return `${lang}-${route}`; +}; diff --git a/src/features/routes/utils/getRoute.ts b/src/features/routes/utils/getRoute.ts new file mode 100644 index 000000000..88dcb132d --- /dev/null +++ b/src/features/routes/utils/getRoute.ts @@ -0,0 +1,16 @@ +import { ROOT_PATH } from '@const'; +import { pathsByLangRouteKey, SupportedRoutes } from '../const'; +import { getLangRouteKey } from './getLangRouteKey'; + +type Params = { + lang: string; + route: SupportedRoutes; +}; + +export const getRoute = ({ lang, route }: Params) => { + if (route === '404') { + return `${ROOT_PATH}${lang ?? ''}`; + } + + return `${ROOT_PATH}${pathsByLangRouteKey[getLangRouteKey({ lang, route })]}`; +}; diff --git a/src/features/wordPopularity/api/getWordPopularityPosition.ts b/src/features/wordPopularity/api/getWordPopularityPosition.ts index 13d3b6706..9df5dd25e 100644 --- a/src/features/wordPopularity/api/getWordPopularityPosition.ts +++ b/src/features/wordPopularity/api/getWordPopularityPosition.ts @@ -1,3 +1,4 @@ +import { ROOT_PATH } from '@const'; import { getNormalizedKey } from '../../../api/helpers'; type FetchedWordsListByKeys = { @@ -21,7 +22,7 @@ export const getWordPopularityPosition = async (word: string, lang: string): Pro if (!cachedKeys[cacheKey]) { try { - const response = await fetch(`./dictionary/${lang}/popularity/chunk-${key}.json`).catch((error) => { + const response = await fetch(`${ROOT_PATH}dictionary/${lang}/popularity/chunk-${key}.json`).catch((error) => { throw error; }); diff --git a/src/hooks/useTrackGlobal.ts b/src/hooks/useTrackGlobal.ts index 2e36a1fdb..aa64acd7c 100644 --- a/src/hooks/useTrackGlobal.ts +++ b/src/hooks/useTrackGlobal.ts @@ -4,20 +4,22 @@ import { useSelector, useDispatch } from '@store'; import { track } from '@store/appSlice'; import { selectCookiesPolicyHash } from '@store/selectors'; +import useLinks from '@features/routes/hooks/useLinks'; + function useTrackGlobal() { const dispatch = useDispatch(); + const { activeLink } = useLinks(); const cookiesRefresherString = useSelector(selectCookiesPolicyHash); - const activePane = useSelector(state => state.app.pane.active); const gameLanguage = useSelector(state => state.game.language); const gameMode = useSelector(state => state.game.mode); useEffect(() => { - if (activePane && gameLanguage) { - dispatch(track({ name: `pane_view_${gameLanguage}_${activePane.replaceAll('-', '_').toLocaleLowerCase()}` })); + if (activeLink.route) { + dispatch(track({ name: `route_${activeLink.lang}_${activeLink.route}` })); } - }, [cookiesRefresherString, dispatch, activePane, gameLanguage]); + }, [cookiesRefresherString, dispatch, activeLink.route, activeLink.lang, gameLanguage]); useEffect(() => { if (gameMode && gameLanguage) { diff --git a/src/i18n.ts b/src/i18n.ts index d014f520b..b78c5e27c 100644 --- a/src/i18n.ts +++ b/src/i18n.ts @@ -2,42 +2,7 @@ import i18n from 'i18next'; import { initReactI18next } from 'react-i18next'; import intervalPlural from 'i18next-intervalplural-postprocessor'; -import localeCs from './locales/cs.json'; -import localeDe from './locales/de.json'; -import localeEn from './locales/en.json'; -import localeEs from './locales/es.json'; -import localeFi from './locales/fi.json'; -import localeFr from './locales/fr.json'; -import localeIt from './locales/it.json'; -import localePl from './locales/pl.json'; - -// TODO: manage them separated from your code: https://react.i18next.com/guides/multiple-translation-files) -const resources = { - cs: { - translation: localeCs, - }, - de: { - translation: localeDe, - }, - en: { - translation: localeEn, - }, - es: { - translation: localeEs, - }, - fi: { - translation: localeFi, - }, - fr: { - translation: localeFr, - }, - it: { - translation: localeIt, - }, - pl: { - translation: localePl, - }, -}; +import { resources } from './locales/langs'; i18n .use(initReactI18next) diff --git a/src/locales/cs.json b/src/locales/cs.json index 500e167b6..00f19e66e 100644 --- a/src/locales/cs.json +++ b/src/locales/cs.json @@ -1,271 +1,276 @@ { - "seo.pageTitle": "DIFFLE - hra jako Wordle (v češtině, bez omezení znaků) 🇨🇿", - "seo.metaDescription": "Každé použité slovo naznačuje pozici a pořadí písmen v hesle.", - "seo.openGraphTitle": "DIFFLE - hra jako Wordle (v češtině, bez omezení znaků) 🇨🇿", - "seo.openGraphDescription": "Každé použité slovo naznačuje pozici a pořadí písmen v hesle.", - "common.yes": "Ano", - "common.no": "Ne", - "common.play": "Začni hru", - "common.newGame": "Nová hra", - "common.copyResult": "Výsledek kopírovat", - "common.copyResultLink": "Kopírovat pouze odkaz", - "common.copyLink": "Zkopíruj odkaz", - "common.copied": "Zkopírováno.", - "common.checkInDictionary": "Hledej \"{{word}}\"", - "common.checkInDictionaryWithName": "Hledej \"{{word}}\" v {{name}}", - "common.dictionaryIsNotExactMatch": "Slovník vítězných slov nemá snadno přístupnou online verzi, takže můžete vyzkoušet jeden z těchto slovníků.", - "common.close": "Zavřít", - "common.more": "více", - "common.download": "Stažení", - "common.downloadError": "Chyba načtení.", - "common.fetchError": "Chyba načtení, zkuste to znovu.", - "common.unknownError": "Nastala neznámá chyba.", - "common.serviceMode": "Údržba služeb {{today}}.", - "common.serviceModeWeReturnSoon": "Zítra zpátky v akci!", - "language.currentLanguage": "Čeština", - "language.cs": "čeština", - "language.de": "němčina", - "language.en": "angličtina", - "language.es": "spanělština", - "language.fi": "Finština", - "language.fr": "francouzština", - "language.it": "Italština", - "language.pl": "polština", - "game.modeDaily": "Denně", - "game.modePractice": "Praxe", - "game.modeShare": "Sdílené", - "game.iGiveUp": "Vzdávám se", - "game.dailyGameLostToast": "Ztracená hra od {{dailyStamp}} bylo vítězné slovo \"{{word}}\"", - "game.givingUpIsNotPossible": "Začněte hru, abyste se mohli vzdát ;)", - "game.confirmCheckTheWord": "Je \"{{word}}\" Dobře?", - "game.wordToSubmitIsMissing": "Měli bychom zkontrolovat slovo?", - "game.checking": "kontrola ...", - "game.withSpecialCharacters": "Vítězné slovo obsahuje alespoň jeden {{specialCharacter}} znak.", - "game.withoutSpecialCharacters": "Vítězné slovo neobsahuje {{specialCharacters}} znaky.", - "game.csSpecialCharacter": "český", - "game.csSpecialCharacters": "českých", - "game.deSpecialCharacter": "speciální", - "game.deSpecialCharacters": "speciální", - "game.esSpecialCharacter": "speciální", - "game.esSpecialCharacters": "speciální", - "game.fiSpecialCharacter": "speciální", - "game.fiSpecialCharacters": "speciální", - "game.frSpecialCharacter": "speciální", - "game.frSpecialCharacters": "speciální", - "game.itSpecialCharacter": "speciální", - "game.itSpecialCharacters": "speciální", - "game.plSpecialCharacter": "speciální", - "game.plSpecialCharacters": "speciální", - "game.youCanUseThisWordButNotWin": "Můžete použít toto slovo, ale nemůžete s ním vyhrát.", - "game.youCanUseIncorrectLetters": "nesprávné písmeno zadáno", - "game.youCanUseLettersTypedTooManyTimes": "správné písmeno použito příliš mnohokrát", - "game.youCanUseSpace": "Slova nemají mezery, ale můžete je použít, budou odstraněny.", - "game.youCanUseIncorrectStart": "nesprávný začátek slova", - "game.youCanUseIncorrectEnd": "nesprávný konec slova", - "game.youCanUseIncorrectMiddle": "některá písmena by měla být vedle sebe", - "game.youCanUseIncorrectOrder": "některá písmena jsou ve špatném pořadí", - "game.spacesRemoved": "Mezery byly odstraněny.", - "game.isNotInDictionary": "Chybí slovo ve slovníku.", - "game.wordAlreadyUsed": "Slovo již bylo použito.", - "game.restoreError": "Chyba došlo při obnově stavu hry.", - "help.title": "Pomoc", - "help.howToPlayTitle": "Jak hrát?", - "help.howToPlayText1": "Hádejte, že slovo používá co nejméně písmen.", - "help.howToPlayText2": "Jakmile to dáte nejlepší odhad, přepněte barvy písmen, aby vám řekli, jak jste ke slovu teplé nebo studené.", - "help.exampleTitle": "Příklad", - "help.exampleTitleAlt": "Jiný příklad", - "help.incorrectLettersTip": "Šedá písmena nejsou ve slově.", - "help.correctLetters": "Písmeno {{correct1}} a {{correct2}} jsou ve slově v tomto pořadí.", - "help.positionBefore": "Písmeno {{position}} je ve slově, ale ne před {{closestCorrect}}.", - "help.positionBetween": "Písmeno {{position}} je ve slově, ale ne mezi nimi.", - "help.positionAfter": "Písmeno {{position}} je ve slově, ale ne po {{closestCorrect}}.", - "help.inRow": "Písmena {{letters}} jsou ve hesle vedle sebe.", - "help.firstAndLast": "Slovo začíná {{first}} a končí {{last}}.", - "help.winingWordMessage": "Toto je slovo odpovědi.", - "help.previousExample": "Předchozí příklad", - "help.altExample": "Další příklad?", - "help.whatIsDiffleTitle": "Co je Diffle?", - "help.whatIsDiffleDescription": "Diffle je hra inspirovaná Wordle bez omezení počtu znaků. Pokud máte rádi Wordle, tato hra je pro vás.", - "help.gameRules": "Pravidla hry", - "end.titleWon": "Úspěch", - "end.titleLost": "Porazit", - "end.titleCheater": "Jasnovid", - "end.winningWord": "Odpověď:", - "end.wordsUsed_zero": "slov", - "end.wordsUsed_one": "slovo", - "end.wordsUsed_few": "slova", - "end.wordsUsed_many": "slov", - "end.wordsUsed_other": "slov", - "end.inWordsUsed_zero": "slov", - "end.inWordsUsed_one": "slově", - "end.inWordsUsed_few": "slovech", - "end.inWordsUsed_many": "slov", - "end.inWordsUsed_other": "slovech", - "end.in_zero": "v", - "end.in_one": "v", - "end.in_few": "ve", - "end.in_many": "v", - "end.in_other": "v", - "end.lostIn": "ztracen", - "end.lettersUsedShort": "p.", - "end.lettersUsed_zero": "písmen", - "end.lettersUsed_one": "písmeno", - "end.lettersUsed_few": "písmena", - "end.lettersUsed_many": "písmen", - "end.lettersUsed_other": "písmen", - "end.nextDailyHours_zero": "Nové denní slovo bude k dispozici za méně než hodinu.", - "end.nextDailyHours_one": "Nové denní slovo bude k dispozici za hodinu.", - "end.nextDailyHours_few": "Nové denní slovo bude k dispozici za {{count}} hodiny.", - "end.nextDailyHours_many": "Nové denní slovo bude k dispozici za {{count}} hodin.", - "end.nextDailyHours_other": "Nové denní slovo bude k dispozici za {{count}} hodin.", - "end.nextDailyShort": "Další za {{count}}h", - "end.completed": "splněny", - "end.gameDuration": "Délka hry", - "settings.title": "Nastavení", - "settings.inDevelopment": "Ve vývoji", - "settings.inBetaNow": "Beta", - "settings.onlyIn": "Jedině v", - "settings.considered": "Považováno", - "settings.statisticsTitle": "Statistika", - "settings.gameModeTitle": "Herní módy", - "settings.labelFinishGame": "Dokončit", - "settings.labelFinishGameLonger": "Hádejte dnešní heslo k odemknutí.", - "settings.labelYouCanSeeSharedWords": "Uhádli jste dnešní heslo, takže je můžete vidět.", - "settings.preferencesTitle": "Preference", - "settings.highContrastMode": "Vysoký kontrast", - "settings.lightMode": "Režim světla", - "settings.darkMode": "Tmavý režim", - "settings.appVibration": "Vibrace aplikací", - "settings.showGameDuration": "Zobrazit délku hry", - "settings.accessibility": "Přístupnost", - "settings.keyboard": "Klávesnice", - "settings.confirmSubmition": "Potvrďte slova", - "settings.swapEnterAndBackspace": "Vyměňte Backspace s Enter", - "settings.languageDefault": "z jazyka", - "settings.keyboardVibration": "Vibrace klávesnice", - "settings.smallerKeyboard": "Menší klávesnice", - "settings.sourcesTitle": "Prameny", - "settings.sourcesDescription": "Všechny zdroje používané touto aplikací jsou k dispozici pod bezplatnou licencí. Uznání patří tvůrcům těchto zdrojů.", - "settings.sourcesTitleDictionaries": "Slovníky", - "settings.sourcesTitleImages": "Ikony", - "settings.sourceGithub": "repozitář této stránky", - "settings.sourceDiffle": "originální diffle", - "settings.sourceDictionarySpellchecker": "jako korektor pravopisu", - "settings.sourceDictionaryWiningWords": "jako vyhledávač vítězných slov", - "settings.lastDailyWordsTitle": "Včerejší slovo", - "settings.lastDailyWordsYesterday": "Včerejší slovo bylo \"{{word}}\".", - "settings.lastDailyWordsCanBeWrongBecauseOfUpdate": "Včerejší vítězné slovo může být chybné, protože byla vydána větší aktualizace.", - "settings.confirmInSeconds_zero": "Klikněte za {{count}}s potvrdit", - "settings.confirmInSeconds_one": "Klikněte za jednu sekundu potvrdit", - "settings.confirmInSeconds_few": "Klikněte za {{count}}s potvrdit", - "settings.confirmInSeconds_many": "Klikněte za {{count}}s potvrdit", - "settings.confirmInSeconds_other": "Klikněte za {{count}}s potvrdit", - "settings.confirmAfterWaiting": "Potvrďte kliknutím", - "settings.language": "Jazyk", - "settings.languageChanged": "Jazyk nastaven.", - "settings.reportTranslationBug": "Nahlásit chybu při překladu", - "settings.privacyTitle": "Soukromí", - "settings.cookiesTitle": "Cookies", - "settings.cookiesText1": "Tato stránka používá pro správné fungování tvého prohlížeče keš.", - "settings.cookiesText2": "Přijetím \"všechny\" také souhlasíte s volitelným sledováním vaší aktivity (včetně Google Analytics).", - "settings.acceptAll": "Přijmout vše", - "settings.acceptOnlyRequired": "Přijmout povinné", - "settings.saveSelected": "Uložit vybrané", - "settings.cookiesSavedAndRefresh": "Uloženo. Aplikace bude obnovena.", - "settings.cookiesExternalOptional": "externí a volitelné", - "settings.cookiesLocalRequierd": "místní a vyžadované", - "share.titleSettings": "Sdílení", - "share.linkWithUsedWords": "Odkaz na použitá slova", - "share.linkWithUsedWordsNoSpoilers": "(bez spoilerů)", - "share.titleSharedResult": "Sdílený výsledek s vámi", - "share.resultIsBroken": "Bohužel, tento odkaz vypršel nebo je rozbitý.", - "share.resultIsForTheFuture": "Tento odkaz by měl brzy fungovat.", - "share.resultHasExpired": "Bohužel, tento odkaz vypršel.", - "share.titleUsedWords": "Použitá slova", - "share.dontShowThisResult": "Tento výsledek už neukazujte", - "statistics.filters": "Filtry", - "statistics.filterAll": "Spojit", - "statistics.noData": "Žádná data pro vybrané filtry.", - "statistics.specialCharactersWithout": "bez speciální znaky", - "statistics.specialCharactersWith": "s speciálními znaky", - "statistics.wordLengthShort": "k {{to}} znaky", - "statistics.wordLengthLong": "nahoře {{above}} znaky", - "statistics.letters": "písmena", - "statistics.medianWordsBefore": "v", - "statistics.medianWords": "slova", - "statistics.median": "medián", - "statistics.average": "průměrný:", - "statistics.maximum": "maxium:", - "statistics.averageLetters": "průměrná písmena", - "statistics.averageGameTime": "průměrná doba hry", - "statistics.totalGameTime": "celkový čas her", - "statistics.inWord": "v slovem", - "statistics.inFirstWord": "v prvním slově", - "statistics.inSecondWord": "ve druhém slově", - "statistics.keyboardUsed": "průměrný {{value}}% použité klávesnice", - "statistics.averageWordsNotFound": " {{value}} slova, která nebyla nalezena ve slovníku", - "statistics.worstWordsNotFound": "nejhorší {{value}} v jedné hře", - "statistics.worstWordsNotFoundLonger": "nejhorší slova, která nebyla nalezena ve slovníku {{value}} ve hře", - "statistics.totalGames_zero": "0 her", - "statistics.totalGames_one": "1 hra", - "statistics.totalGames_few": "{{count}} hry", - "statistics.totalGames_many": "{{count}} hry", - "statistics.totalGames_other": "{{count}} hry", - "statistics.totalWon": "vyhrál", - "statistics.totalWonStreak": "výhry v řadě", - "statistics.totalWonStreak_zero": "výhry v řadě", - "statistics.totalWonStreak_one": "výhra v řadě", - "statistics.totalWonStreak_few": "výhry v řadě", - "statistics.totalWonStreak_many": "výhry v řadě", - "statistics.totalLostStreak": "proher v řadě", - "statistics.totalLostStreak_zero": "proher v řadě", - "statistics.totalLostStreak_one": "prohra v řadě", - "statistics.totalLostStreak_few": "prohry v řadě", - "statistics.totalLostStreak_many": "lost in a row", - "statistics.totalBestStreak": "nejlepší vyhrál v řadě", - "statistics.streakTooltipWithWorstStreak": "nejhorší ztracená v řadě:", - "statistics.lettersCorrect": "opravit", - "statistics.lettersPosition": "špatná pozice", - "statistics.lettersIncorrect": "nesprávný", - "statistics.lettersIncorrectAndTyped": "napsané nesprávné", - "statistics.titleRemoveStatistics": "Odebrat statistiky", - "statistics.statisticsWasRemoved": "Statistiky byly odstraněny", - "statistics.wordsWithSpecialCharacters": "Slova se speciálními znaky", - "statistics.languageTitleHighestLetterForCommon": "Nejoblíbenější písmeno", - "statistics.filterCommon": "popularita", - "statistics.languageDescriptionHighestLetterForCommon": "{{maxletter}} se vyskytuje {{maxLetterValue}} krát na slovo.", - "statistics.languageTitleHighestLetterForInWords": "Písmeno ve největším počtu slov", - "statistics.filterInWords": "počet slov", - "statistics.languageDescriptionHighestLetterForInWords": "{{maxletter}} se vyskytuje ve {{maxLetterValue}} slovech.", - "statistics.languageTitleHighestLetterForFirst": "Nejběžnější první písmeno", - "statistics.filterFirst": "první", - "statistics.languageDescriptionHighestLetterForFirst": "{{maxletter}} je prvním písmenem ve {{maxLetterValue}} slovech.", - "statistics.languageTitleHighestLetterForLast": "Nejběžnější poslední písmeno", - "statistics.filterLast": "poslední", - "statistics.languageDescriptionHighestLetterForLast": "{{maxletter}} je posledním písmenem ve {{maxLetterValue}} slovech.", - "statistics.languageTitleLength": "Počet písmen ve slově", - "statistics.languageDescriptionMostPopularLength": "Nejoblíbenější délka slova je {{letters}} písmen.", - "statistics.languageTitleAtTheBeginning": "Nejčastěji na začátku", - "statistics.languageTitleInTheMiddle": "Nejčastěji uprostřed", - "statistics.languageTitleInTheEnd": "Nejčastěji na konci", - "statistics.showOneChartWithFilters": "Jeden graf s filtry", - "statistics.showTitleWithLanguage": "Zobrazit název jazyka", - "statistics.basedOn": "{{product}} na základě {{words}} slov z {{source}}", - "statistics.bestWordleWordTitle": "Nejlepší výchozí slovo ve Wordle", - "statistics.bestWordleWordExplanation": "Výsledek proti {{words}} slovům:", - "statistics.filterWordleLettersTitle": "Používání písmen", - "statistics.filterWordleInWords": "Písmena", - "statistics.filterWordleLetterPosition": "Pozice (opakování)", - "statistics.filterWordleUniqueLetterPosition": "Pozice", - "statistics.filterWordleMaxTitle": "Maximalizace barev", - "statistics.filterBestMaxGreen": "Zelená", - "statistics.filterBestMax": "Barvy", - "statistics.filterBestMaxOrange": "Žlutá", - "statistics.filterBestMaxGray": "Šedá", - "statistics.filterWordleBestTitle": "Barevná rovnováha", - "statistics.filterBestGreen1_5": "1.5 × zelená + 1 × žlutá", - "statistics.filterBestGreen2_0": "2 × zelená + 1 × žlutá", - "statistics.bestWordleWordPopularLettersTitle": "Nejoblíbenější písmena na dané pozici", - "feature.specialWord.wasActivated": "Speciální slovo bylo aktivováno!", - "feature.specialWord.wasDeactivated": "Speciální slovo bylo deaktivováno!" -} \ No newline at end of file + "route.help": "pomoc", + "route.settings": "nastaveni", + "route.statistics": "tvoje-statistiky", + "route.aboutLanguage": "o-jazyku", + "route.hejto2024": "hejto-2024", + "route.game.title": "DIFFLE - hra jako Wordle (v češtině, bez omezení znaků) 🇨🇿", + "route.game.metaDescription": "Každé použité slovo naznačuje pozici a pořadí písmen v hesle.", + "route.game.openGraphTitle": "DIFFLE - hra jako Wordle (v češtině, bez omezení znaků) 🇨🇿", + "route.game.openGraphDescription": "Každé použité slovo naznačuje pozici a pořadí písmen v hesle.", + "common.yes": "Ano", + "common.no": "Ne", + "common.play": "Začni hru", + "common.newGame": "Nová hra", + "common.copyResult": "Výsledek kopírovat", + "common.copyResultLink": "Kopírovat pouze odkaz", + "common.copyLink": "Zkopíruj odkaz", + "common.copied": "Zkopírováno.", + "common.checkInDictionary": "Hledej \"{{word}}\"", + "common.checkInDictionaryWithName": "Hledej \"{{word}}\" v {{name}}", + "common.dictionaryIsNotExactMatch": "Slovník vítězných slov nemá snadno přístupnou online verzi, takže můžete vyzkoušet jeden z těchto slovníků.", + "common.close": "Zavřít", + "common.more": "více", + "common.download": "Stažení", + "common.downloadError": "Chyba načtení.", + "common.fetchError": "Chyba načtení, zkuste to znovu.", + "common.unknownError": "Nastala neznámá chyba.", + "common.serviceMode": "Údržba služeb {{today}}.", + "common.serviceModeWeReturnSoon": "Zítra zpátky v akci!", + "language.currentLanguage": "Čeština", + "language.cs": "čeština", + "language.de": "němčina", + "language.en": "angličtina", + "language.es": "spanělština", + "language.fi": "Finština", + "language.fr": "francouzština", + "language.it": "Italština", + "language.pl": "polština", + "game.modeDaily": "Denně", + "game.modePractice": "Praxe", + "game.modeShare": "Sdílené", + "game.iGiveUp": "Vzdávám se", + "game.dailyGameLostToast": "Ztracená hra od {{dailyStamp}} bylo vítězné slovo \"{{word}}\"", + "game.givingUpIsNotPossible": "Začněte hru, abyste se mohli vzdát ;)", + "game.confirmCheckTheWord": "Je \"{{word}}\" Dobře?", + "game.wordToSubmitIsMissing": "Měli bychom zkontrolovat slovo?", + "game.checking": "kontrola ...", + "game.withSpecialCharacters": "Vítězné slovo obsahuje alespoň jeden {{specialCharacter}} znak.", + "game.withoutSpecialCharacters": "Vítězné slovo neobsahuje {{specialCharacters}} znaky.", + "game.csSpecialCharacter": "český", + "game.csSpecialCharacters": "českých", + "game.deSpecialCharacter": "speciální", + "game.deSpecialCharacters": "speciální", + "game.esSpecialCharacter": "speciální", + "game.esSpecialCharacters": "speciální", + "game.fiSpecialCharacter": "speciální", + "game.fiSpecialCharacters": "speciální", + "game.frSpecialCharacter": "speciální", + "game.frSpecialCharacters": "speciální", + "game.itSpecialCharacter": "speciální", + "game.itSpecialCharacters": "speciální", + "game.plSpecialCharacter": "speciální", + "game.plSpecialCharacters": "speciální", + "game.youCanUseThisWordButNotWin": "Můžete použít toto slovo, ale nemůžete s ním vyhrát.", + "game.youCanUseIncorrectLetters": "nesprávné písmeno zadáno", + "game.youCanUseLettersTypedTooManyTimes": "správné písmeno použito příliš mnohokrát", + "game.youCanUseSpace": "Slova nemají mezery, ale můžete je použít, budou odstraněny.", + "game.youCanUseIncorrectStart": "nesprávný začátek slova", + "game.youCanUseIncorrectEnd": "nesprávný konec slova", + "game.youCanUseIncorrectMiddle": "některá písmena by měla být vedle sebe", + "game.youCanUseIncorrectOrder": "některá písmena jsou ve špatném pořadí", + "game.spacesRemoved": "Mezery byly odstraněny.", + "game.isNotInDictionary": "Chybí slovo ve slovníku.", + "game.wordAlreadyUsed": "Slovo již bylo použito.", + "game.restoreError": "Chyba došlo při obnově stavu hry.", + "help.title": "Pomoc", + "help.howToPlayTitle": "Jak hrát?", + "help.howToPlayText1": "Hádejte, že slovo používá co nejméně písmen.", + "help.howToPlayText2": "Jakmile to dáte nejlepší odhad, přepněte barvy písmen, aby vám řekli, jak jste ke slovu teplé nebo studené.", + "help.exampleTitle": "Příklad", + "help.exampleTitleAlt": "Jiný příklad", + "help.incorrectLettersTip": "Šedá písmena nejsou ve slově.", + "help.correctLetters": "Písmeno {{correct1}} a {{correct2}} jsou ve slově v tomto pořadí.", + "help.positionBefore": "Písmeno {{position}} je ve slově, ale ne před {{closestCorrect}}.", + "help.positionBetween": "Písmeno {{position}} je ve slově, ale ne mezi nimi.", + "help.positionAfter": "Písmeno {{position}} je ve slově, ale ne po {{closestCorrect}}.", + "help.inRow": "Písmena {{letters}} jsou ve hesle vedle sebe.", + "help.firstAndLast": "Slovo začíná {{first}} a končí {{last}}.", + "help.winingWordMessage": "Toto je slovo odpovědi.", + "help.previousExample": "Předchozí příklad", + "help.altExample": "Další příklad?", + "help.whatIsDiffleTitle": "Co je Diffle?", + "help.whatIsDiffleDescription": "Diffle je hra inspirovaná Wordle bez omezení počtu znaků. Pokud máte rádi Wordle, tato hra je pro vás.", + "help.gameRules": "Pravidla hry", + "end.titleWon": "Úspěch", + "end.titleLost": "Porazit", + "end.titleCheater": "Jasnovid", + "end.winningWord": "Odpověď:", + "end.wordsUsed_zero": "slov", + "end.wordsUsed_one": "slovo", + "end.wordsUsed_few": "slova", + "end.wordsUsed_many": "slov", + "end.wordsUsed_other": "slov", + "end.inWordsUsed_zero": "slov", + "end.inWordsUsed_one": "slově", + "end.inWordsUsed_few": "slovech", + "end.inWordsUsed_many": "slov", + "end.inWordsUsed_other": "slovech", + "end.in_zero": "v", + "end.in_one": "v", + "end.in_few": "ve", + "end.in_many": "v", + "end.in_other": "v", + "end.lostIn": "ztracen", + "end.lettersUsedShort": "p.", + "end.lettersUsed_zero": "písmen", + "end.lettersUsed_one": "písmeno", + "end.lettersUsed_few": "písmena", + "end.lettersUsed_many": "písmen", + "end.lettersUsed_other": "písmen", + "end.nextDailyHours_zero": "Nové denní slovo bude k dispozici za méně než hodinu.", + "end.nextDailyHours_one": "Nové denní slovo bude k dispozici za hodinu.", + "end.nextDailyHours_few": "Nové denní slovo bude k dispozici za {{count}} hodiny.", + "end.nextDailyHours_many": "Nové denní slovo bude k dispozici za {{count}} hodin.", + "end.nextDailyHours_other": "Nové denní slovo bude k dispozici za {{count}} hodin.", + "end.nextDailyShort": "Další za {{count}}h", + "end.completed": "splněny", + "end.gameDuration": "Délka hry", + "settings.title": "Nastavení", + "settings.inDevelopment": "Ve vývoji", + "settings.inBetaNow": "Beta", + "settings.onlyIn": "Jedině v", + "settings.considered": "Považováno", + "settings.statisticsTitle": "Statistika", + "settings.gameModeTitle": "Herní módy", + "settings.labelFinishGame": "Dokončit", + "settings.labelFinishGameLonger": "Hádejte dnešní heslo k odemknutí.", + "settings.labelYouCanSeeSharedWords": "Uhádli jste dnešní heslo, takže je můžete vidět.", + "settings.preferencesTitle": "Preference", + "settings.highContrastMode": "Vysoký kontrast", + "settings.lightMode": "Režim světla", + "settings.darkMode": "Tmavý režim", + "settings.appVibration": "Vibrace aplikací", + "settings.showGameDuration": "Zobrazit délku hry", + "settings.accessibility": "Přístupnost", + "settings.keyboard": "Klávesnice", + "settings.confirmSubmition": "Potvrďte slova", + "settings.swapEnterAndBackspace": "Vyměňte Backspace s Enter", + "settings.languageDefault": "z jazyka", + "settings.keyboardVibration": "Vibrace klávesnice", + "settings.smallerKeyboard": "Menší klávesnice", + "settings.sourcesTitle": "Prameny", + "settings.sourcesDescription": "Všechny zdroje používané touto aplikací jsou k dispozici pod bezplatnou licencí. Uznání patří tvůrcům těchto zdrojů.", + "settings.sourcesTitleDictionaries": "Slovníky", + "settings.sourcesTitleImages": "Ikony", + "settings.sourceGithub": "repozitář této stránky", + "settings.sourceDiffle": "originální diffle", + "settings.sourceDictionarySpellchecker": "jako korektor pravopisu", + "settings.sourceDictionaryWiningWords": "jako vyhledávač vítězných slov", + "settings.lastDailyWordsTitle": "Včerejší slovo", + "settings.lastDailyWordsYesterday": "Včerejší slovo bylo \"{{word}}\".", + "settings.lastDailyWordsCanBeWrongBecauseOfUpdate": "Včerejší vítězné slovo může být chybné, protože byla vydána větší aktualizace.", + "settings.confirmInSeconds_zero": "Klikněte za {{count}}s potvrdit", + "settings.confirmInSeconds_one": "Klikněte za jednu sekundu potvrdit", + "settings.confirmInSeconds_few": "Klikněte za {{count}}s potvrdit", + "settings.confirmInSeconds_many": "Klikněte za {{count}}s potvrdit", + "settings.confirmInSeconds_other": "Klikněte za {{count}}s potvrdit", + "settings.confirmAfterWaiting": "Potvrďte kliknutím", + "settings.language": "Jazyk", + "settings.languageChanged": "Jazyk nastaven.", + "settings.reportTranslationBug": "Nahlásit chybu při překladu", + "settings.privacyTitle": "Soukromí", + "settings.cookiesTitle": "Cookies", + "settings.cookiesText1": "Tato stránka používá pro správné fungování tvého prohlížeče keš.", + "settings.cookiesText2": "Přijetím \"všechny\" také souhlasíte s volitelným sledováním vaší aktivity (včetně Google Analytics).", + "settings.acceptAll": "Přijmout vše", + "settings.acceptOnlyRequired": "Přijmout povinné", + "settings.saveSelected": "Uložit vybrané", + "settings.cookiesSavedAndRefresh": "Uloženo. Aplikace bude obnovena.", + "settings.cookiesExternalOptional": "externí a volitelné", + "settings.cookiesLocalRequierd": "místní a vyžadované", + "share.titleSettings": "Sdílení", + "share.linkWithUsedWords": "Odkaz na použitá slova", + "share.linkWithUsedWordsNoSpoilers": "(bez spoilerů)", + "share.titleSharedResult": "Sdílený výsledek s vámi", + "share.resultIsBroken": "Bohužel, tento odkaz vypršel nebo je rozbitý.", + "share.resultIsForTheFuture": "Tento odkaz by měl brzy fungovat.", + "share.resultHasExpired": "Bohužel, tento odkaz vypršel.", + "share.titleUsedWords": "Použitá slova", + "share.dontShowThisResult": "Tento výsledek už neukazujte", + "statistics.filters": "Filtry", + "statistics.filterAll": "Spojit", + "statistics.noData": "Žádná data pro vybrané filtry.", + "statistics.specialCharactersWithout": "bez speciální znaky", + "statistics.specialCharactersWith": "s speciálními znaky", + "statistics.wordLengthShort": "k {{to}} znaky", + "statistics.wordLengthLong": "nahoře {{above}} znaky", + "statistics.letters": "písmena", + "statistics.medianWordsBefore": "v", + "statistics.medianWords": "slova", + "statistics.median": "medián", + "statistics.average": "průměrný:", + "statistics.maximum": "maxium:", + "statistics.averageLetters": "průměrná písmena", + "statistics.averageGameTime": "průměrná doba hry", + "statistics.totalGameTime": "celkový čas her", + "statistics.inWord": "v slovem", + "statistics.inFirstWord": "v prvním slově", + "statistics.inSecondWord": "ve druhém slově", + "statistics.keyboardUsed": "průměrný {{value}}% použité klávesnice", + "statistics.averageWordsNotFound": " {{value}} slova, která nebyla nalezena ve slovníku", + "statistics.worstWordsNotFound": "nejhorší {{value}} v jedné hře", + "statistics.worstWordsNotFoundLonger": "nejhorší slova, která nebyla nalezena ve slovníku {{value}} ve hře", + "statistics.totalGames_zero": "0 her", + "statistics.totalGames_one": "1 hra", + "statistics.totalGames_few": "{{count}} hry", + "statistics.totalGames_many": "{{count}} hry", + "statistics.totalGames_other": "{{count}} hry", + "statistics.totalWon": "vyhrál", + "statistics.totalWonStreak": "výhry v řadě", + "statistics.totalWonStreak_zero": "výhry v řadě", + "statistics.totalWonStreak_one": "výhra v řadě", + "statistics.totalWonStreak_few": "výhry v řadě", + "statistics.totalWonStreak_many": "výhry v řadě", + "statistics.totalLostStreak": "proher v řadě", + "statistics.totalLostStreak_zero": "proher v řadě", + "statistics.totalLostStreak_one": "prohra v řadě", + "statistics.totalLostStreak_few": "prohry v řadě", + "statistics.totalLostStreak_many": "lost in a row", + "statistics.totalBestStreak": "nejlepší vyhrál v řadě", + "statistics.streakTooltipWithWorstStreak": "nejhorší ztracená v řadě:", + "statistics.lettersCorrect": "opravit", + "statistics.lettersPosition": "špatná pozice", + "statistics.lettersIncorrect": "nesprávný", + "statistics.lettersIncorrectAndTyped": "napsané nesprávné", + "statistics.titleRemoveStatistics": "Odebrat statistiky", + "statistics.statisticsWasRemoved": "Statistiky byly odstraněny", + "statistics.wordsWithSpecialCharacters": "Slova se speciálními znaky", + "statistics.languageTitleHighestLetterForCommon": "Nejoblíbenější písmeno", + "statistics.filterCommon": "popularita", + "statistics.languageDescriptionHighestLetterForCommon": "{{maxletter}} se vyskytuje {{maxLetterValue}} krát na slovo.", + "statistics.languageTitleHighestLetterForInWords": "Písmeno ve největším počtu slov", + "statistics.filterInWords": "počet slov", + "statistics.languageDescriptionHighestLetterForInWords": "{{maxletter}} se vyskytuje ve {{maxLetterValue}} slovech.", + "statistics.languageTitleHighestLetterForFirst": "Nejběžnější první písmeno", + "statistics.filterFirst": "první", + "statistics.languageDescriptionHighestLetterForFirst": "{{maxletter}} je prvním písmenem ve {{maxLetterValue}} slovech.", + "statistics.languageTitleHighestLetterForLast": "Nejběžnější poslední písmeno", + "statistics.filterLast": "poslední", + "statistics.languageDescriptionHighestLetterForLast": "{{maxletter}} je posledním písmenem ve {{maxLetterValue}} slovech.", + "statistics.languageTitleLength": "Počet písmen ve slově", + "statistics.languageDescriptionMostPopularLength": "Nejoblíbenější délka slova je {{letters}} písmen.", + "statistics.languageTitleAtTheBeginning": "Nejčastěji na začátku", + "statistics.languageTitleInTheMiddle": "Nejčastěji uprostřed", + "statistics.languageTitleInTheEnd": "Nejčastěji na konci", + "statistics.showOneChartWithFilters": "Jeden graf s filtry", + "statistics.showTitleWithLanguage": "Zobrazit název jazyka", + "statistics.basedOn": "{{product}} na základě {{words}} slov z {{source}}", + "statistics.bestWordleWordTitle": "Nejlepší výchozí slovo ve Wordle", + "statistics.bestWordleWordExplanation": "Výsledek proti {{words}} slovům:", + "statistics.filterWordleLettersTitle": "Používání písmen", + "statistics.filterWordleInWords": "Písmena", + "statistics.filterWordleLetterPosition": "Pozice (opakování)", + "statistics.filterWordleUniqueLetterPosition": "Pozice", + "statistics.filterWordleMaxTitle": "Maximalizace barev", + "statistics.filterBestMaxGreen": "Zelená", + "statistics.filterBestMax": "Barvy", + "statistics.filterBestMaxOrange": "Žlutá", + "statistics.filterBestMaxGray": "Šedá", + "statistics.filterWordleBestTitle": "Barevná rovnováha", + "statistics.filterBestGreen1_5": "1.5 × zelená + 1 × žlutá", + "statistics.filterBestGreen2_0": "2 × zelená + 1 × žlutá", + "statistics.bestWordleWordPopularLettersTitle": "Nejoblíbenější písmena na dané pozici", + "feature.specialWord.wasActivated": "Speciální slovo bylo aktivováno!", + "feature.specialWord.wasDeactivated": "Speciální slovo bylo deaktivováno!" +} diff --git a/src/locales/de.json b/src/locales/de.json index c882aafbe..c90d69386 100644 --- a/src/locales/de.json +++ b/src/locales/de.json @@ -1,276 +1,281 @@ { - "seo.pageTitle": "DIFFLE - das Spiel wie Wordle (auf Deutsch, ohne Zeichenbegrenzung) 🇩🇪", - "seo.metaDescription": "Jedes verwendete Wort liefert Hinweise über die Position und Reihenfolge der Buchstaben in der Lösung.", - "seo.openGraphTitle": "DIFFLE - das Spiel wie Wordle (auf Deutsch, ohne Zeichenbegrenzung) 🇩🇪", - "seo.openGraphDescription": "Jedes verwendete Wort liefert Hinweise über die Position und Reihenfolge der Buchstaben in der Lösung.", - "common.yes": "Ja", - "common.no": "Nein", - "common.play": "Spiele", - "common.newGame": "Neues Spiel", - "common.copyResult": "Ergebnis kopieren", - "common.copyResultLink": "Nur Link kopieren", - "common.copyLink": "Link kopieren", - "common.copied": "Kopiert.", - "common.checkInDictionary": "Suche nach \"{{word}}\"", - "common.checkInDictionaryWithName": "Suche nach \"{{word}}\" in {{name}}", - "common.dictionaryIsNotExactMatch": "Das Wörterbuch der Gewinnerwörter verfügt nicht über eine leicht zugängliche Online-Version. Daher können Sie es mit einem dieser Wörterbücher versuchen.", - "common.close": "Schließen", - "common.more": "mehr", - "common.download": "Herunterladen", - "common.downloadError": "Ein Abruf-Fehler.", - "common.fetchError": "Ein Abruf-Fehler, versuchen Sie es erneut.", - "common.unknownError": "Ein unbekannter Fehler ist aufgetreten.", - "common.serviceMode": "Wartung des Dienstes am {{today}}.", - "common.serviceModeWeReturnSoon": "Morgen wieder im Einsatz!", - "language.currentLanguage": "Deutsch", - "language.cs": "Tschechisch", - "language.de": "Deutsch", - "language.en": "Englisch", - "language.es": "Spanisch", - "language.fi": "Finnisch", - "language.fr": "Französisch", - "language.it": "Italienisch", - "language.pl": "Polnisch", - "game.modeDaily": "Täglich", - "game.modePractice": "Übungen", - "game.modeShare": "Geteilt", - "game.iGiveUp": "Ich gebe auf", - "game.dailyGameLostToast": "\"{{word}}\" ist das ungelöste Wort vom {{dailyStamp}}.", - "game.givingUpIsNotPossible": "Beginne das Spiel, um aufgeben zu können ;)", - "game.confirmCheckTheWord": "Ist \"{{word}}\" in Ordnung?", - "game.wordToSubmitIsMissing": "Sollen wir das Wort überprüfen?", - "game.checking": "überprüfung...", - "game.withSpecialCharacters": "Das Gewinnerwort enthält mindestens ein {{specialCharacter}}.", - "game.withoutSpecialCharacters": "Das Gewinnerwort enthält keine {{specialCharacters}}.", - "game.csSpecialCharacter": "Sonderzeichen", - "game.csSpecialCharacters": "Sonderzeichen", - "game.deSpecialCharacter": "deutsches Zeichen", - "game.deSpecialCharacters": "deutschen Zeichen", - "game.esSpecialCharacter": "Sonderzeichen", - "game.esSpecialCharacters": "Sonderzeichen", - "game.fiSpecialCharacter": "Sonderzeichen", - "game.fiSpecialCharacters": "Sonderzeichen", - "game.frSpecialCharacter": "Sonderzeichen", - "game.frSpecialCharacters": "Sonderzeichen", - "game.itSpecialCharacter": "Sonderzeichen", - "game.itSpecialCharacters": "Sonderzeichen", - "game.plSpecialCharacter": "Sonderzeichen", - "game.plSpecialCharacters": "Sonderzeichen", - "game.youCanUseThisWordButNotWin": "Sie können dieses Wort verwenden, aber Sie können damit nicht gewinnen.", - "game.youCanUseIncorrectLetters": "falscher Buchstabe eingegeben", - "game.youCanUseLettersTypedTooManyTimes": "richtiger Buchstabe zu oft verwendet", - "game.youCanUseSpace": "Wörter haben keine Leerzeichen, aber du kannst sie verwenden, sie werden entfernt.", - "game.youCanUseIncorrectStart": "falscher Wortanfang", - "game.youCanUseIncorrectEnd": "falsches Wortende", - "game.youCanUseIncorrectMiddle": "einige Buchstaben sollten nebeneinander stehen", - "game.youCanUseIncorrectOrder": "einige Buchstaben sind in der falschen Reihenfolge", - "game.spacesRemoved": "Die Leerzeichen wurden entfernt.", - "game.isNotInDictionary": "Das Wort wurde im Wörterbuch nicht gefunden.", - "game.wordAlreadyUsed": "Das Wort wurde bereits verwendet.", - "game.restoreError": "Der Fehler ist beim Wiederherstellen des Spielzustands aufgetreten.", - "help.title": "Hilfe", - "help.howToPlayTitle": "Wie spielt man?", - "help.howToPlayText1": "Rate das Wort mit so wenigen Buchstaben wie möglich.", - "help.howToPlayText2": "Sobald du deine beste Vermutung abgegeben hast, wechseln die Farben der Buchstaben, um dir zu zeigen, wie warm oder kalt du beim Wort liegst.", - "help.exampleTitle": "Beispiel", - "help.exampleTitleAlt": "Ein anderes Beispiel", - "help.incorrectLettersTip": "Die grauen Buchstaben sind nicht im Wort.", - "help.correctLetters": "Die Buchstaben {{correct1}} und {{correct2}} sind in diesem Wort in dieser Reihenfolge.", - "help.positionBefore": "Der Buchstabe {{position}} ist im Wort, aber nicht vor {{closestCorrect}}.", - "help.positionBetween": "Der Buchstabe {{position}} ist nicht zwischen ihnen.", - "help.positionAfter": "Der Buchstabe {{position}} ist im Wort, aber nicht nach {{closestCorrect}}.", - "help.inRow": "Die Buchstaben {{letters}} sind in aufeinanderfolgender Reihenfolge im Wort.", - "help.firstAndLast": "Das Wort beginnt mit {{first}} und endet mit {{last}}.", - "help.winingWordMessage": "Das ist das Antwortwort.", - "help.previousExample": "Vorheriges Beispiel", - "help.altExample": "Ein weiteres Beispiel?", - "help.whatIsDiffleTitle": "Was ist Diffle?", - "help.whatIsDiffleDescription": "Diffle ist ein Spiel, das von Wordle inspiriert ist, jedoch ohne Zeichenbegrenzung. Wenn dir Wordle gefällt, ist dieses Spiel genau das Richtige für dich.", - "help.gameRules": "Spielregeln", - "end.titleWon": "Erfolg", - "end.titleLost": "Niederlage", - "end.titleCheater": "Hellseher", - "end.winningWord": "Die Antwort:", - "end.wordsUsed_zero": "words", - "end.wordsUsed_one": "Wort", - "end.wordsUsed_few": "words", - "end.wordsUsed_many": "words", - "end.wordsUsed_other": "Wörtern", - "end.inWordsUsed_zero": "words", - "end.inWordsUsed_one": "Wort", - "end.inWordsUsed_few": "words", - "end.inWordsUsed_many": "words", - "end.inWordsUsed_other": "Wörtern", - "end.in_zero": "in", - "end.in_one": "im", - "end.in_few": "in", - "end.in_many": "in", - "end.in_other": "im", - "end.lostIn": "Niederlage", - "end.lettersUsedShort": "B.", - "end.lettersUsed_zero": "letter", - "end.lettersUsed_one": "Buchstabe", - "end.lettersUsed_few": "letters", - "end.lettersUsed_many": "letters", - "end.lettersUsed_other": "Buchstaben", - "end.nextDailyHours_zero": "Das neue Tageswort wird in {{count}} Stunden verfügbar sein.", - "end.nextDailyHours_one": "Das neue Tageswort wird in einer Stunde verfügbar sein.", - "end.nextDailyHours_few": "The new daily word will be available in {{count}} hours.", - "end.nextDailyHours_many": "The new daily word will be available in {{count}} hours.", - "end.nextDailyHours_other": "Das neue Tageswort wird in {{count}} Stunden verfügbar sein.", - "end.nextDailyMinutes_zero": "Das neue Tageswort wird in {{count}} Minuten verfügbar sein.", - "end.nextDailyMinutes_one": "Das neue Tageswort wird in einer Minute verfügbar sein.", - "end.nextDailyMinutes_few": "The new daily word will be available in {{count}} minutes.", - "end.nextDailyMinutes_many": "The new daily word will be available in {{count}} minutes.", - "end.nextDailyMinutes_other": "Das neue Tageswort wird in {{count}} Minuten verfügbar sein.", - "end.nextDailyShort": "nächster im {{count}}S", - "end.completed": "abgeschlossen", - "end.gameDuration": "Dauer des Spiels", - "settings.title": "Einstellungen", - "settings.inDevelopment": "In Entwicklung", - "settings.inBetaNow": "Beta", - "settings.onlyIn": "Nur in", - "settings.considered": "Erwogen", - "settings.statisticsTitle": "Statistik", - "settings.gameModeTitle": "Spielmodi", - "settings.labelFinishGame": "Fertig", - "settings.labelFinishGameLonger": "Errate das heutige Passwort, um zu entsperren.", - "settings.labelYouCanSeeSharedWords": "Du hast das heutige Passwort erraten, also kannst du sie sehen.", - "settings.preferencesTitle": "Einstellungen", - "settings.highContrastMode": "Hoher Kontrast", - "settings.lightMode": "Hellmodus", - "settings.darkMode": "Dunkelmodus", - "settings.appVibration": "App-Vibrationen", - "settings.showGameDuration": "Spieldauer anzeigen", - "settings.accessibility": "Barrierefreiheit", - "settings.keyboard": "Tastatur", - "settings.confirmSubmition": "Wörter bestätigen", - "settings.swapEnterAndBackspace": "Backspace mit Enter tauschen", - "settings.languageDefault": "aus der Sprache", - "settings.keyboardVibration": "Tastaturvibrationen", - "settings.smallerKeyboard": "Kleinere Tastatur", - "settings.sourcesTitle": "Quellen", - "settings.sourcesDescription": "Alle von dieser App verwendeten Ressourcen stehen unter einer freien Lizenz. Lob an die Schöpfer dieser Ressourcen.", - "settings.sourcesTitleDictionaries": "Wörterbücher", - "settings.sourcesTitleImages": "Icons", - "settings.sourceGithub": "Dieses Site-Repository", - "settings.sourceDiffle": "original Diffle", - "settings.sourceDictionarySpellchecker": "als Rechtschreibprüfung", - "settings.sourceDictionaryWiningWords": "als Siegerwort-Finder", - "settings.lastDailyWordsTitle": "Wort von gestern", - "settings.lastDailyWordsYesterday": "Das Wort von gestern war \"{{word}}\".", - "settings.lastDailyWordsCanBeWrongBecauseOfUpdate": "Das gestrige Gewinnerwort könnte falsch sein, weil ein größeres Update veröffentlicht wurde.", - "settings.confirmInSeconds_zero": "Click in {{count}} seconds to confirm", - "settings.confirmInSeconds_one": "1 Sekunde klicken, bestätigen", - "settings.confirmInSeconds_few": "Click in {{count}} seconds to confirm", - "settings.confirmInSeconds_many": "Click in {{count}} seconds to confirm", - "settings.confirmInSeconds_other": "{{count}} Sekunden klicken, bestätigen", - "settings.confirmAfterWaiting": "Klicken, um zu bestätigen", - "settings.language": "Sprache", - "settings.languageChanged": "Die Sprache wurde geändert.", - "settings.reportTranslationBug": "Fehlerhafte Übersetzung melden.", - "settings.privacyTitle": "Datenschutz", - "settings.cookiesTitle": "Cookies", - "settings.cookiesText1": "Diese Website verwendet den Cache Ihres Browsers, um korrekt zu funktionieren.", - "settings.cookiesText2": "Indem Sie \"alle\" akzeptieren, stimmen Sie auch mit optionaler Verfolgung Ihrer Aktivität (einschließlich Google Analytics).", - "settings.acceptAll": "Alle akzeptieren", - "settings.acceptOnlyRequired": "Akzeptieren erforderlich", - "settings.saveSelected": "Auswahl speichern", - "settings.cookiesSavedAndRefresh": "Gespeichert. Die Anwendung wird aktualisiert.", - "settings.cookiesExternalOptional": "extern und optional", - "settings.cookiesLocalRequierd": "lokal und erforderlich", - "share.titleSettings": "Teilen", - "share.linkWithUsedWords": "Link zu verwendeten Wörtern", - "share.linkWithUsedWordsNoSpoilers": "(ohne Spoiler)", - "share.titleSharedResult": "Ergebnis geteilt mit dir", - "share.resultIsBroken": "Leider ist dieser Link abgelaufen oder defekt.", - "share.resultIsForTheFuture": "Dieser Link sollte bald funktionieren.", - "share.resultHasExpired": "Leider ist dieser Link abgelaufen.", - "share.titleUsedWords": "Verwendete Wörter", - "share.dontShowThisResult": "Ergebnis nicht mehr anzeigen", - "statistics.filters": "Filter", - "statistics.filterAll": "Verbinden", - "statistics.noData": "Keine Daten für die ausgewählten Filter.", - "statistics.specialCharactersWithout": "ohne Sonderzeichen", - "statistics.specialCharactersWith": "mit Sonderzeichen", - "statistics.wordLengthShort": "bis zu {{to}} Zeichen", - "statistics.wordLengthLong": "über {{above}} Zeichen", - "statistics.letters": "Buchstaben", - "statistics.medianWordsBefore": "in", - "statistics.medianWords": "Wörter", - "statistics.median": "Median", - "statistics.average": "Durchschnitt:", - "statistics.maximum": "Maximum:", - "statistics.averageLetters": "Durchschnittliche Buchstaben", - "statistics.averageGameTime": "Durchschnittliche Spielzeit", - "statistics.totalGameTime": "Gesamte Spielzeit", - "statistics.inWord": "im Wort", - "statistics.inFirstWord": "im ersten Wort", - "statistics.inSecondWord": "im zweiten Wort", - "statistics.keyboardUsed": "Durchschnittlich {{value}}% der Tastatur verwendet.", - "statistics.averageWordsNotFound": "{{value}} Wörter nicht im Wörterbuch gefunden", - "statistics.worstWordsNotFound": "Schlechtestes {{value}} in einem Spiel", - "statistics.worstWordsNotFoundLonger": "Schlechteste nicht im Wörterbuch gefundenen Wörter: {{value}} in einem Spiel", - "statistics.totalGames_zero": "{{count}} games", - "statistics.totalGames_one": "1 Spiel", - "statistics.totalGames_few": "{{count}} games", - "statistics.totalGames_many": "{{count}} games", - "statistics.totalGames_other": "{{count}} Spiele", - "statistics.totalWon": "gewonnen", - "statistics.totalWonStreak": "in Folge gewonnen", - "statistics.totalWonStreak_zero": "in Folge gewonnen", - "statistics.totalWonStreak_one": "in Folge gewonnen", - "statistics.totalWonStreak_few": "in Folge gewonnen", - "statistics.totalWonStreak_many": "in Folge gewonnen", - "statistics.totalLostStreak": "in Folge verloren", - "statistics.totalLostStreak_zero": "in Folge verloren", - "statistics.totalLostStreak_one": "in Folge verloren", - "statistics.totalLostStreak_few": "in Folge verloren", - "statistics.totalLostStreak_many": "in Folge verloren", - "statistics.totalBestStreak": "Bestes in Folge gewonnen", - "statistics.streakTooltipWithWorstStreak": "Das schlechteste in Folge verloren:", - "statistics.lettersCorrect": "korrekt", - "statistics.lettersPosition": "falsche Position", - "statistics.lettersIncorrect": "inkorrekt", - "statistics.lettersIncorrectAndTyped": "falsch getippt", - "statistics.titleRemoveStatistics": "Statistiken entfernen", - "statistics.statisticsWasRemoved": "Statistiken wurden entfernt", - "statistics.wordsWithSpecialCharacters": "Wörter mit Sonderzeichen", - "statistics.languageTitleHighestLetterForCommon": "Der beliebteste Buchstabe", - "statistics.filterCommon": "Beliebtheit", - "statistics.languageDescriptionHighestLetterForCommon": "{{maxletter}} tritt {{maxLetterValue}} Mal pro Wort auf.", - "statistics.languageTitleHighestLetterForInWords": "Buchstabe im größten Wortbestand", - "statistics.filterInWords": "Wortanzahl", - "statistics.languageDescriptionHighestLetterForInWords": "{{maxletter}} erscheint in {{maxLetterValue}} Wörtern.", - "statistics.languageTitleHighestLetterForFirst": "Häufigster erster Buchstabe", - "statistics.filterFirst": "erster", - "statistics.languageDescriptionHighestLetterForFirst": "{{maxletter}} ist der erste Buchstabe in {{maxLetterValue}} Wörtern.", - "statistics.languageTitleHighestLetterForLast": "Häufigster letzter Buchstabe", - "statistics.filterLast": "letzter", - "statistics.languageDescriptionHighestLetterForLast": "{{maxletter}} ist der letzte Buchstabe in {{maxLetterValue}} Wörtern.", - "statistics.languageTitleLength": "Anzahl der Buchstaben in einem Wort", - "statistics.languageDescriptionMostPopularLength": "Die häufigste Wortlänge beträgt {{letters}} Buchstaben.", - "statistics.languageTitleAtTheBeginning": "Am häufigsten am Anfang", - "statistics.languageTitleInTheMiddle": "Am häufigsten in der Mitte", - "statistics.languageTitleInTheEnd": "Am häufigsten am Ende", - "statistics.showOneChartWithFilters": "Ein Diagramm mit Filtern", - "statistics.showTitleWithLanguage": "Sprachtitel anzeigen", - "statistics.basedOn": "{{product}} basierend auf {{words}} Wörtern aus {{source}}", - "statistics.bestWordleWordTitle": "Bestes Startwort in Wordle", - "statistics.bestWordleWordExplanation": "Ergebnis gegen {{words}} Wörter:", - "statistics.filterWordleLettersTitle": "Verwendung von Buchstaben", - "statistics.filterWordleInWords": "Buchstaben", - "statistics.filterWordleLetterPosition": "Position (Wiederholungen)", - "statistics.filterWordleUniqueLetterPosition": "Position", - "statistics.filterWordleMaxTitle": "Maximierung der Farben", - "statistics.filterBestMaxGreen": "Grün", - "statistics.filterBestMax": "Farben", - "statistics.filterBestMaxOrange": "Gelb", - "statistics.filterBestMaxGray": "Grau", - "statistics.filterWordleBestTitle": "Farbbalance", - "statistics.filterBestGreen1_5": "1.5 × grün + 1 × gelb", - "statistics.filterBestGreen2_0": "2 × grün + 1 × gelb", - "statistics.bestWordleWordPopularLettersTitle": "Beliebteste Buchstaben an einer bestimmten Position", - "feature.specialWord.wasActivated": "Das Spezialwort wurde aktiviert!", - "feature.specialWord.wasDeactivated": "Das Spezialwort wurde deaktiviert!" -} \ No newline at end of file + "route.help": "hilfe", + "route.settings": "einstellungen", + "route.statistics": "deine-statistiken", + "route.aboutLanguage": "uber-sprache", + "route.hejto2024": "hejto-2024", + "route.game.title": "DIFFLE - das Spiel wie Wordle (auf Deutsch, ohne Zeichenbegrenzung) 🇩🇪", + "route.game.metaDescription": "Jedes verwendete Wort liefert Hinweise über die Position und Reihenfolge der Buchstaben in der Lösung.", + "route.game.openGraphTitle": "DIFFLE - das Spiel wie Wordle (auf Deutsch, ohne Zeichenbegrenzung) 🇩🇪", + "route.game.openGraphDescription": "Jedes verwendete Wort liefert Hinweise über die Position und Reihenfolge der Buchstaben in der Lösung.", + "common.yes": "Ja", + "common.no": "Nein", + "common.play": "Spiele", + "common.newGame": "Neues Spiel", + "common.copyResult": "Ergebnis kopieren", + "common.copyResultLink": "Nur Link kopieren", + "common.copyLink": "Link kopieren", + "common.copied": "Kopiert.", + "common.checkInDictionary": "Suche nach \"{{word}}\"", + "common.checkInDictionaryWithName": "Suche nach \"{{word}}\" in {{name}}", + "common.dictionaryIsNotExactMatch": "Das Wörterbuch der Gewinnerwörter verfügt nicht über eine leicht zugängliche Online-Version. Daher können Sie es mit einem dieser Wörterbücher versuchen.", + "common.close": "Schließen", + "common.more": "mehr", + "common.download": "Herunterladen", + "common.downloadError": "Ein Abruf-Fehler.", + "common.fetchError": "Ein Abruf-Fehler, versuchen Sie es erneut.", + "common.unknownError": "Ein unbekannter Fehler ist aufgetreten.", + "common.serviceMode": "Wartung des Dienstes am {{today}}.", + "common.serviceModeWeReturnSoon": "Morgen wieder im Einsatz!", + "language.currentLanguage": "Deutsch", + "language.cs": "Tschechisch", + "language.de": "Deutsch", + "language.en": "Englisch", + "language.es": "Spanisch", + "language.fi": "Finnisch", + "language.fr": "Französisch", + "language.it": "Italienisch", + "language.pl": "Polnisch", + "game.modeDaily": "Täglich", + "game.modePractice": "Übungen", + "game.modeShare": "Geteilt", + "game.iGiveUp": "Ich gebe auf", + "game.dailyGameLostToast": "\"{{word}}\" ist das ungelöste Wort vom {{dailyStamp}}.", + "game.givingUpIsNotPossible": "Beginne das Spiel, um aufgeben zu können ;)", + "game.confirmCheckTheWord": "Ist \"{{word}}\" in Ordnung?", + "game.wordToSubmitIsMissing": "Sollen wir das Wort überprüfen?", + "game.checking": "überprüfung...", + "game.withSpecialCharacters": "Das Gewinnerwort enthält mindestens ein {{specialCharacter}}.", + "game.withoutSpecialCharacters": "Das Gewinnerwort enthält keine {{specialCharacters}}.", + "game.csSpecialCharacter": "Sonderzeichen", + "game.csSpecialCharacters": "Sonderzeichen", + "game.deSpecialCharacter": "deutsches Zeichen", + "game.deSpecialCharacters": "deutschen Zeichen", + "game.esSpecialCharacter": "Sonderzeichen", + "game.esSpecialCharacters": "Sonderzeichen", + "game.fiSpecialCharacter": "Sonderzeichen", + "game.fiSpecialCharacters": "Sonderzeichen", + "game.frSpecialCharacter": "Sonderzeichen", + "game.frSpecialCharacters": "Sonderzeichen", + "game.itSpecialCharacter": "Sonderzeichen", + "game.itSpecialCharacters": "Sonderzeichen", + "game.plSpecialCharacter": "Sonderzeichen", + "game.plSpecialCharacters": "Sonderzeichen", + "game.youCanUseThisWordButNotWin": "Sie können dieses Wort verwenden, aber Sie können damit nicht gewinnen.", + "game.youCanUseIncorrectLetters": "falscher Buchstabe eingegeben", + "game.youCanUseLettersTypedTooManyTimes": "richtiger Buchstabe zu oft verwendet", + "game.youCanUseSpace": "Wörter haben keine Leerzeichen, aber du kannst sie verwenden, sie werden entfernt.", + "game.youCanUseIncorrectStart": "falscher Wortanfang", + "game.youCanUseIncorrectEnd": "falsches Wortende", + "game.youCanUseIncorrectMiddle": "einige Buchstaben sollten nebeneinander stehen", + "game.youCanUseIncorrectOrder": "einige Buchstaben sind in der falschen Reihenfolge", + "game.spacesRemoved": "Die Leerzeichen wurden entfernt.", + "game.isNotInDictionary": "Das Wort wurde im Wörterbuch nicht gefunden.", + "game.wordAlreadyUsed": "Das Wort wurde bereits verwendet.", + "game.restoreError": "Der Fehler ist beim Wiederherstellen des Spielzustands aufgetreten.", + "help.title": "Hilfe", + "help.howToPlayTitle": "Wie spielt man?", + "help.howToPlayText1": "Rate das Wort mit so wenigen Buchstaben wie möglich.", + "help.howToPlayText2": "Sobald du deine beste Vermutung abgegeben hast, wechseln die Farben der Buchstaben, um dir zu zeigen, wie warm oder kalt du beim Wort liegst.", + "help.exampleTitle": "Beispiel", + "help.exampleTitleAlt": "Ein anderes Beispiel", + "help.incorrectLettersTip": "Die grauen Buchstaben sind nicht im Wort.", + "help.correctLetters": "Die Buchstaben {{correct1}} und {{correct2}} sind in diesem Wort in dieser Reihenfolge.", + "help.positionBefore": "Der Buchstabe {{position}} ist im Wort, aber nicht vor {{closestCorrect}}.", + "help.positionBetween": "Der Buchstabe {{position}} ist nicht zwischen ihnen.", + "help.positionAfter": "Der Buchstabe {{position}} ist im Wort, aber nicht nach {{closestCorrect}}.", + "help.inRow": "Die Buchstaben {{letters}} sind in aufeinanderfolgender Reihenfolge im Wort.", + "help.firstAndLast": "Das Wort beginnt mit {{first}} und endet mit {{last}}.", + "help.winingWordMessage": "Das ist das Antwortwort.", + "help.previousExample": "Vorheriges Beispiel", + "help.altExample": "Ein weiteres Beispiel?", + "help.whatIsDiffleTitle": "Was ist Diffle?", + "help.whatIsDiffleDescription": "Diffle ist ein Spiel, das von Wordle inspiriert ist, jedoch ohne Zeichenbegrenzung. Wenn dir Wordle gefällt, ist dieses Spiel genau das Richtige für dich.", + "help.gameRules": "Spielregeln", + "end.titleWon": "Erfolg", + "end.titleLost": "Niederlage", + "end.titleCheater": "Hellseher", + "end.winningWord": "Die Antwort:", + "end.wordsUsed_zero": "words", + "end.wordsUsed_one": "Wort", + "end.wordsUsed_few": "words", + "end.wordsUsed_many": "words", + "end.wordsUsed_other": "Wörtern", + "end.inWordsUsed_zero": "words", + "end.inWordsUsed_one": "Wort", + "end.inWordsUsed_few": "words", + "end.inWordsUsed_many": "words", + "end.inWordsUsed_other": "Wörtern", + "end.in_zero": "in", + "end.in_one": "im", + "end.in_few": "in", + "end.in_many": "in", + "end.in_other": "im", + "end.lostIn": "Niederlage", + "end.lettersUsedShort": "B.", + "end.lettersUsed_zero": "letter", + "end.lettersUsed_one": "Buchstabe", + "end.lettersUsed_few": "letters", + "end.lettersUsed_many": "letters", + "end.lettersUsed_other": "Buchstaben", + "end.nextDailyHours_zero": "Das neue Tageswort wird in {{count}} Stunden verfügbar sein.", + "end.nextDailyHours_one": "Das neue Tageswort wird in einer Stunde verfügbar sein.", + "end.nextDailyHours_few": "The new daily word will be available in {{count}} hours.", + "end.nextDailyHours_many": "The new daily word will be available in {{count}} hours.", + "end.nextDailyHours_other": "Das neue Tageswort wird in {{count}} Stunden verfügbar sein.", + "end.nextDailyMinutes_zero": "Das neue Tageswort wird in {{count}} Minuten verfügbar sein.", + "end.nextDailyMinutes_one": "Das neue Tageswort wird in einer Minute verfügbar sein.", + "end.nextDailyMinutes_few": "The new daily word will be available in {{count}} minutes.", + "end.nextDailyMinutes_many": "The new daily word will be available in {{count}} minutes.", + "end.nextDailyMinutes_other": "Das neue Tageswort wird in {{count}} Minuten verfügbar sein.", + "end.nextDailyShort": "nächster im {{count}}S", + "end.completed": "abgeschlossen", + "end.gameDuration": "Dauer des Spiels", + "settings.title": "Einstellungen", + "settings.inDevelopment": "In Entwicklung", + "settings.inBetaNow": "Beta", + "settings.onlyIn": "Nur in", + "settings.considered": "Erwogen", + "settings.statisticsTitle": "Statistik", + "settings.gameModeTitle": "Spielmodi", + "settings.labelFinishGame": "Fertig", + "settings.labelFinishGameLonger": "Errate das heutige Passwort, um zu entsperren.", + "settings.labelYouCanSeeSharedWords": "Du hast das heutige Passwort erraten, also kannst du sie sehen.", + "settings.preferencesTitle": "Einstellungen", + "settings.highContrastMode": "Hoher Kontrast", + "settings.lightMode": "Hellmodus", + "settings.darkMode": "Dunkelmodus", + "settings.appVibration": "App-Vibrationen", + "settings.showGameDuration": "Spieldauer anzeigen", + "settings.accessibility": "Barrierefreiheit", + "settings.keyboard": "Tastatur", + "settings.confirmSubmition": "Wörter bestätigen", + "settings.swapEnterAndBackspace": "Backspace mit Enter tauschen", + "settings.languageDefault": "aus der Sprache", + "settings.keyboardVibration": "Tastaturvibrationen", + "settings.smallerKeyboard": "Kleinere Tastatur", + "settings.sourcesTitle": "Quellen", + "settings.sourcesDescription": "Alle von dieser App verwendeten Ressourcen stehen unter einer freien Lizenz. Lob an die Schöpfer dieser Ressourcen.", + "settings.sourcesTitleDictionaries": "Wörterbücher", + "settings.sourcesTitleImages": "Icons", + "settings.sourceGithub": "Dieses Site-Repository", + "settings.sourceDiffle": "original Diffle", + "settings.sourceDictionarySpellchecker": "als Rechtschreibprüfung", + "settings.sourceDictionaryWiningWords": "als Siegerwort-Finder", + "settings.lastDailyWordsTitle": "Wort von gestern", + "settings.lastDailyWordsYesterday": "Das Wort von gestern war \"{{word}}\".", + "settings.lastDailyWordsCanBeWrongBecauseOfUpdate": "Das gestrige Gewinnerwort könnte falsch sein, weil ein größeres Update veröffentlicht wurde.", + "settings.confirmInSeconds_zero": "Click in {{count}} seconds to confirm", + "settings.confirmInSeconds_one": "1 Sekunde klicken, bestätigen", + "settings.confirmInSeconds_few": "Click in {{count}} seconds to confirm", + "settings.confirmInSeconds_many": "Click in {{count}} seconds to confirm", + "settings.confirmInSeconds_other": "{{count}} Sekunden klicken, bestätigen", + "settings.confirmAfterWaiting": "Klicken, um zu bestätigen", + "settings.language": "Sprache", + "settings.languageChanged": "Die Sprache wurde geändert.", + "settings.reportTranslationBug": "Fehlerhafte Übersetzung melden.", + "settings.privacyTitle": "Datenschutz", + "settings.cookiesTitle": "Cookies", + "settings.cookiesText1": "Diese Website verwendet den Cache Ihres Browsers, um korrekt zu funktionieren.", + "settings.cookiesText2": "Indem Sie \"alle\" akzeptieren, stimmen Sie auch mit optionaler Verfolgung Ihrer Aktivität (einschließlich Google Analytics).", + "settings.acceptAll": "Alle akzeptieren", + "settings.acceptOnlyRequired": "Akzeptieren erforderlich", + "settings.saveSelected": "Auswahl speichern", + "settings.cookiesSavedAndRefresh": "Gespeichert. Die Anwendung wird aktualisiert.", + "settings.cookiesExternalOptional": "extern und optional", + "settings.cookiesLocalRequierd": "lokal und erforderlich", + "share.titleSettings": "Teilen", + "share.linkWithUsedWords": "Link zu verwendeten Wörtern", + "share.linkWithUsedWordsNoSpoilers": "(ohne Spoiler)", + "share.titleSharedResult": "Ergebnis geteilt mit dir", + "share.resultIsBroken": "Leider ist dieser Link abgelaufen oder defekt.", + "share.resultIsForTheFuture": "Dieser Link sollte bald funktionieren.", + "share.resultHasExpired": "Leider ist dieser Link abgelaufen.", + "share.titleUsedWords": "Verwendete Wörter", + "share.dontShowThisResult": "Ergebnis nicht mehr anzeigen", + "statistics.filters": "Filter", + "statistics.filterAll": "Verbinden", + "statistics.noData": "Keine Daten für die ausgewählten Filter.", + "statistics.specialCharactersWithout": "ohne Sonderzeichen", + "statistics.specialCharactersWith": "mit Sonderzeichen", + "statistics.wordLengthShort": "bis zu {{to}} Zeichen", + "statistics.wordLengthLong": "über {{above}} Zeichen", + "statistics.letters": "Buchstaben", + "statistics.medianWordsBefore": "in", + "statistics.medianWords": "Wörter", + "statistics.median": "Median", + "statistics.average": "Durchschnitt:", + "statistics.maximum": "Maximum:", + "statistics.averageLetters": "Durchschnittliche Buchstaben", + "statistics.averageGameTime": "Durchschnittliche Spielzeit", + "statistics.totalGameTime": "Gesamte Spielzeit", + "statistics.inWord": "im Wort", + "statistics.inFirstWord": "im ersten Wort", + "statistics.inSecondWord": "im zweiten Wort", + "statistics.keyboardUsed": "Durchschnittlich {{value}}% der Tastatur verwendet.", + "statistics.averageWordsNotFound": "{{value}} Wörter nicht im Wörterbuch gefunden", + "statistics.worstWordsNotFound": "Schlechtestes {{value}} in einem Spiel", + "statistics.worstWordsNotFoundLonger": "Schlechteste nicht im Wörterbuch gefundenen Wörter: {{value}} in einem Spiel", + "statistics.totalGames_zero": "{{count}} games", + "statistics.totalGames_one": "1 Spiel", + "statistics.totalGames_few": "{{count}} games", + "statistics.totalGames_many": "{{count}} games", + "statistics.totalGames_other": "{{count}} Spiele", + "statistics.totalWon": "gewonnen", + "statistics.totalWonStreak": "in Folge gewonnen", + "statistics.totalWonStreak_zero": "in Folge gewonnen", + "statistics.totalWonStreak_one": "in Folge gewonnen", + "statistics.totalWonStreak_few": "in Folge gewonnen", + "statistics.totalWonStreak_many": "in Folge gewonnen", + "statistics.totalLostStreak": "in Folge verloren", + "statistics.totalLostStreak_zero": "in Folge verloren", + "statistics.totalLostStreak_one": "in Folge verloren", + "statistics.totalLostStreak_few": "in Folge verloren", + "statistics.totalLostStreak_many": "in Folge verloren", + "statistics.totalBestStreak": "Bestes in Folge gewonnen", + "statistics.streakTooltipWithWorstStreak": "Das schlechteste in Folge verloren:", + "statistics.lettersCorrect": "korrekt", + "statistics.lettersPosition": "falsche Position", + "statistics.lettersIncorrect": "inkorrekt", + "statistics.lettersIncorrectAndTyped": "falsch getippt", + "statistics.titleRemoveStatistics": "Statistiken entfernen", + "statistics.statisticsWasRemoved": "Statistiken wurden entfernt", + "statistics.wordsWithSpecialCharacters": "Wörter mit Sonderzeichen", + "statistics.languageTitleHighestLetterForCommon": "Der beliebteste Buchstabe", + "statistics.filterCommon": "Beliebtheit", + "statistics.languageDescriptionHighestLetterForCommon": "{{maxletter}} tritt {{maxLetterValue}} Mal pro Wort auf.", + "statistics.languageTitleHighestLetterForInWords": "Buchstabe im größten Wortbestand", + "statistics.filterInWords": "Wortanzahl", + "statistics.languageDescriptionHighestLetterForInWords": "{{maxletter}} erscheint in {{maxLetterValue}} Wörtern.", + "statistics.languageTitleHighestLetterForFirst": "Häufigster erster Buchstabe", + "statistics.filterFirst": "erster", + "statistics.languageDescriptionHighestLetterForFirst": "{{maxletter}} ist der erste Buchstabe in {{maxLetterValue}} Wörtern.", + "statistics.languageTitleHighestLetterForLast": "Häufigster letzter Buchstabe", + "statistics.filterLast": "letzter", + "statistics.languageDescriptionHighestLetterForLast": "{{maxletter}} ist der letzte Buchstabe in {{maxLetterValue}} Wörtern.", + "statistics.languageTitleLength": "Anzahl der Buchstaben in einem Wort", + "statistics.languageDescriptionMostPopularLength": "Die häufigste Wortlänge beträgt {{letters}} Buchstaben.", + "statistics.languageTitleAtTheBeginning": "Am häufigsten am Anfang", + "statistics.languageTitleInTheMiddle": "Am häufigsten in der Mitte", + "statistics.languageTitleInTheEnd": "Am häufigsten am Ende", + "statistics.showOneChartWithFilters": "Ein Diagramm mit Filtern", + "statistics.showTitleWithLanguage": "Sprachtitel anzeigen", + "statistics.basedOn": "{{product}} basierend auf {{words}} Wörtern aus {{source}}", + "statistics.bestWordleWordTitle": "Bestes Startwort in Wordle", + "statistics.bestWordleWordExplanation": "Ergebnis gegen {{words}} Wörter:", + "statistics.filterWordleLettersTitle": "Verwendung von Buchstaben", + "statistics.filterWordleInWords": "Buchstaben", + "statistics.filterWordleLetterPosition": "Position (Wiederholungen)", + "statistics.filterWordleUniqueLetterPosition": "Position", + "statistics.filterWordleMaxTitle": "Maximierung der Farben", + "statistics.filterBestMaxGreen": "Grün", + "statistics.filterBestMax": "Farben", + "statistics.filterBestMaxOrange": "Gelb", + "statistics.filterBestMaxGray": "Grau", + "statistics.filterWordleBestTitle": "Farbbalance", + "statistics.filterBestGreen1_5": "1.5 × grün + 1 × gelb", + "statistics.filterBestGreen2_0": "2 × grün + 1 × gelb", + "statistics.bestWordleWordPopularLettersTitle": "Beliebteste Buchstaben an einer bestimmten Position", + "feature.specialWord.wasActivated": "Das Spezialwort wurde aktiviert!", + "feature.specialWord.wasDeactivated": "Das Spezialwort wurde deaktiviert!" +} diff --git a/src/locales/en.json b/src/locales/en.json index d5e0ffdee..12cbafb2a 100644 --- a/src/locales/en.json +++ b/src/locales/en.json @@ -1,8 +1,21 @@ { - "seo.pageTitle": "DIFFLE - the game like Wordle (without character limit)", - "seo.metaDescription": "Each used word provides hints about the position and order of letters in the solution.", - "seo.openGraphTitle": "DIFFLE - the game like Wordle (without character limit)", - "seo.openGraphDescription": "Each used word provides hints about the position and order of letters in the solution.", + "route.help": "help", + "route.settings": "settings", + "route.statistics": "your-statistics", + "route.aboutLanguage": "about-language", + "route.hejto2024": "hejto-2024", + "route.game.title": "DIFFLE - the game like Wordle (without character limit)", + "route.game.metaDescription": "Each used word provides hints about the position and order of letters in the solution.", + "route.game.openGraphTitle": "DIFFLE - the game like Wordle (without character limit)", + "route.game.openGraphDescription": "Each used word provides hints about the position and order of letters in the solution.", + "route.help.title": "How to play DIFFLE? - a word game", + "route.help.metaDescription": "Each used word provides hints about the position and order of letters in the solution.", + "route.statistics.title": "", + "route.statistics.metaDescription": "Each used word provides hints about the position and order of letters in the solution.", + "route.aboutLanguage.title": "English letter and word statistics: most common letters, word lengths, and first letters", + "route.aboutLanguage.metaDescription": "English dictionary analysis.", + "route.404.title": "404 - page not found in the dictionary - DIFFLE", + "route.404.metaDescription": "A daily word game.", "common.yes": "Yes", "common.no": "No", "common.play": "Play", diff --git a/src/locales/es.json b/src/locales/es.json index 3690fc9d2..5a8f2984a 100644 --- a/src/locales/es.json +++ b/src/locales/es.json @@ -1,271 +1,276 @@ { - "seo.pageTitle": "DIFFLE - el juego similar a Wordle (sin límite de caracteres) 🇪🇸", - "seo.metaDescription": "Cada palabra utilizada proporciona pistas sobre la posición y el orden de las letras en la solución.", - "seo.openGraphTitle": "DIFFLE - el juego similar a Wordle (sin límite de caracteres) 🇪🇸", - "seo.openGraphDescription": "Cada palabra utilizada proporciona pistas sobre la posición y el orden de las letras en la solución.", - "common.yes": "Sí", - "common.no": "No", - "common.play": "Iniciar juego", - "common.newGame": "Nuevo juego", - "common.copyResult": "Copiar resultado", - "common.copyResultLink": "Copiar solo enlace", - "common.copyLink": "Copiar enlace", - "common.copied": "Copiado.", - "common.checkInDictionary": "Buscar \"{{word}}\"", - "common.checkInDictionaryWithName": "Buscar \"{{word}}\" en {{name}}", - "common.dictionaryIsNotExactMatch": "El diccionario de palabras ganadoras no tiene una versión en línea fácilmente accesible. Por lo tanto, puedes intentarlo con alguno de estos diccionarios.", - "common.close": "Cerrar", - "common.more": "Más", - "common.download": "Descargar", - "common.downloadError": "Error de recuperación.", - "common.fetchError": "Error de recuperación, inténtalo de nuevo.", - "common.unknownError": "Se ha producido un error desconocido.", - "common.serviceMode": "Servicio en mantenimiento el {{today}}.", - "common.serviceModeWeReturnSoon": "¡Volverá a estar en funcionamiento mañana!", - "language.currentLanguage": "Español", - "language.cs": "Checo", - "language.de": "Alemán", - "language.en": "Inglés", - "language.es": "Español", - "language.fi": "Finlandés", - "language.fr": "Francés", - "language.it": "Italiano", - "language.pl": "Polaco", - "game.modeDaily": "Diario", - "game.modePractice": "Práctica", - "game.modeShare": "Compartido", - "game.iGiveUp": "Me rindo", - "game.dailyGameLostToast": "Partida perdida desde {{dailyStamp}}, la palabra ganadora fue \"{{word}}\"", - "game.givingUpIsNotPossible": "Comienza una partida para poder rendirte ;)", - "game.confirmCheckTheWord": "¿Es \"{{word}}\" aceptable?", - "game.wordToSubmitIsMissing": "¿Deberíamos verificar la palabra?", - "game.checking": "verificando...", - "game.withSpecialCharacters": "La palabra ganadora contiene al menos un carácter en {{specialCharacter}}.", - "game.withoutSpecialCharacters": "La palabra ganadora no contiene caracteres en {{specialCharacters}}.", - "game.csSpecialCharacter": "especial", - "game.csSpecialCharacters": "especiales", - "game.deSpecialCharacter": "especial", - "game.deSpecialCharacters": "especiales", - "game.esSpecialCharacter": "español", - "game.esSpecialCharacters": "español", - "game.fiSpecialCharacter": "especial", - "game.fiSpecialCharacters": "especiales", - "game.frSpecialCharacter": "especial", - "game.frSpecialCharacters": "especiales", - "game.itSpecialCharacter": "especial", - "game.itSpecialCharacters": "especiales", - "game.plSpecialCharacter": "especial", - "game.plSpecialCharacters": "especiales", - "game.youCanUseThisWordButNotWin": "Puedes usar esta palabra, pero no puedes ganar con ella.", - "game.youCanUseIncorrectLetters": "letra incorrecta ingresada", - "game.youCanUseLettersTypedTooManyTimes": "letra correcta usada demasiadas veces", - "game.youCanUseSpace": "Las palabras no tienen espacios, pero puedes usarlos, serán eliminados.", - "game.youCanUseIncorrectStart": "inicio de palabra incorrecto", - "game.youCanUseIncorrectEnd": "fin de palabra incorrecto", - "game.youCanUseIncorrectMiddle": "algunas letras deben estar juntas", - "game.youCanUseIncorrectOrder": "algunas letras están en el orden incorrecto", - "game.spacesRemoved": "Los espacios fueron eliminados.", - "game.isNotInDictionary": "Palabra no encontrada en el diccionario.", - "game.wordAlreadyUsed": "La palabra ya había sido utilizada.", - "game.restoreError": "Se produjo un error al restaurar el estado del juego.", - "help.title": "Ayuda", - "help.howToPlayTitle": "¿Cómo se juega?", - "help.howToPlayText1": "Adivina la palabra usando la menor cantidad de letras posible.", - "help.howToPlayText2": "Una vez que realices tu mejor intento, los colores de las letras cambiarán para indicarte cuán cerca o lejos estás de la palabra.", - "help.exampleTitle": "Un ejemplo", - "help.exampleTitleAlt": "Otro ejemplo", - "help.incorrectLettersTip": "Las letras grises no están en la palabra.", - "help.correctLetters": "Las letras {{correct1}} y {{correct2}} están en la palabra en este orden.", - "help.positionBefore": "La letra {{position}} está en la palabra, pero no antes de {{closestCorrect}}.", - "help.positionBetween": "La letra {{position}} pero no entre ellas.", - "help.positionAfter": "La letra {{position}} está en la palabra, pero no después de {{closestCorrect}}.", - "help.inRow": "Las letras {{letters}} están en la palabra en fila.", - "help.firstAndLast": "La palabra comienza con {{first}} y termina con {{last}}.", - "help.winingWordMessage": "Esta es la palabra respuesta.", - "help.previousExample": "Ejemplo anterior", - "help.altExample": "¿Otro ejemplo?", - "help.whatIsDiffleTitle": "¿Qué es Diffle?", - "help.whatIsDiffleDescription": "Diffle es un juego inspirado en Wordle sin límite de caracteres. Si disfrutas de Wordle, este juego es para ti.", - "help.gameRules": "Reglas del juego", - "end.titleWon": "Éxito", - "end.titleLost": "Derrota", - "end.titleCheater": "Un clarividente", - "end.winningWord": "La respuesta:", - "end.wordsUsed_zero": "palabras", - "end.wordsUsed_one": "palabra", - "end.wordsUsed_few": "palabras", - "end.wordsUsed_many": "palabras", - "end.wordsUsed_other": "palabras", - "end.inWordsUsed_zero": "palabras", - "end.inWordsUsed_one": "palabra", - "end.inWordsUsed_few": "palabras", - "end.inWordsUsed_many": "palabras", - "end.inWordsUsed_other": "palabras", - "end.in_zero": "en", - "end.in_one": "en", - "end.in_few": "en", - "end.in_many": "en", - "end.in_other": "en", - "end.lostIn": "perdido", - "end.lettersUsedShort": "l.", - "end.lettersUsed_zero": "letter", - "end.lettersUsed_one": "letra", - "end.lettersUsed_few": "letras", - "end.lettersUsed_many": "letras", - "end.lettersUsed_other": "letras", - "end.nextDailyHours_zero": "La nueva palabra diaria estará disponible en {{count}} horas.", - "end.nextDailyHours_one": "La nueva palabra diaria estará disponible en una hora.", - "end.nextDailyHours_few": "La nueva palabra diaria estará disponible en {{count}} horas.", - "end.nextDailyHours_many": "La nueva palabra diaria estará disponible en {{count}} horas.", - "end.nextDailyHours_other": "La nueva palabra diaria estará disponible en {{count}} horas.", - "end.nextDailyShort": "Próximo en {{count}}h", - "end.completed": "completado", - "end.gameDuration": "Duración del juego", - "settings.title": "Configuración", - "settings.inDevelopment": "En desarrollo", - "settings.inBetaNow": "Beta", - "settings.onlyIn": "Solo en", - "settings.considered": "Considerado", - "settings.statisticsTitle": "Estadísticas", - "settings.gameModeTitle": "Modos de juego", - "settings.labelFinishGame": "Finalizar", - "settings.labelFinishGameLonger": "Adivina la contraseña de hoy para desbloquear.", - "settings.labelYouCanSeeSharedWords": "Adivinaste la contraseña de hoy, así que puedes verlos.", - "settings.preferencesTitle": "Preferencias", - "settings.highContrastMode": "Contraste alto", - "settings.lightMode": "Modo claro", - "settings.darkMode": "Modo oscuro", - "settings.appVibration": "Vibraciones de la app", - "settings.showGameDuration": "Mostrar duración del juego", - "settings.accessibility": "Accesibilidad", - "settings.keyboard": "Teclado", - "settings.confirmSubmition": "Confirmar palabras", - "settings.swapEnterAndBackspace": "Intercambiar retroceso con enter", - "settings.languageDefault": "Idioma", - "settings.keyboardVibration": "Vibraciones teclado", - "settings.smallerKeyboard": "Teclado más pequeño", - "settings.sourcesTitle": "Fuentes", - "settings.sourcesDescription": "Todos los recursos utilizados por esta aplicación están bajo una licencia gratuita. Reconocimientos a los creadores de esos recursos.", - "settings.sourcesTitleDictionaries": "Diccionarios", - "settings.sourcesTitleImages": "Iconos", - "settings.sourceGithub": "repositorio de este sitio", - "settings.sourceDiffle": "Diffle original", - "settings.sourceDictionarySpellchecker": "como corrector ortográfico", - "settings.sourceDictionaryWiningWords": "como buscador de palabras ganadoras", - "settings.lastDailyWordsTitle": "Palabra de ayer", - "settings.lastDailyWordsYesterday": "La palabra de ayer fue \"{{word}}\".", - "settings.lastDailyWordsCanBeWrongBecauseOfUpdate": "La palabra ganadora de ayer podría estar equivocada porque se lanzó una actualización más grande.", - "settings.confirmInSeconds_zero": "Clic en {{count}} seg. para confirmar", - "settings.confirmInSeconds_one": "Clic en 1 segundo para confirmar.", - "settings.confirmInSeconds_few": "Clic en {{count}} seg. para confirmar", - "settings.confirmInSeconds_many": "Clic en {{count}} seg. para confirmar", - "settings.confirmInSeconds_other": "Clic en {{count}} seg. para confirmar", - "settings.confirmAfterWaiting": "Confirmar", - "settings.language": "Idioma", - "settings.languageChanged": "Se ha cambiado el idioma.", - "settings.reportTranslationBug": "Informar sobre un error de traducción", - "settings.privacyTitle": "Privacidad", - "settings.cookiesTitle": "Cookies", - "settings.cookiesText1": "Este sitio web utiliza la memoria caché de su navegador para funcionar correctamente.", - "settings.cookiesText2": "Al aceptar \"todo\", también aceptas el seguimiento opcional de tu actividad (incluido Google Analytics).", - "settings.acceptAll": "Aceptar todo", - "settings.acceptOnlyRequired": "Aceptar requeridos", - "settings.saveSelected": "Guardar seleccionado", - "settings.cookiesSavedAndRefresh": "Guardado. La aplicación se actualizará.", - "settings.cookiesExternalOptional": "externo y opcional", - "settings.cookiesLocalRequierd": "local y requerido", - "share.titleSettings": "Compartir", - "share.linkWithUsedWords": "Enlace a las palabras utilizadas", - "share.linkWithUsedWordsNoSpoilers": "(sin spoilers)", - "share.titleSharedResult": "Resultado compartido contigo", - "share.resultIsBroken": "Lamentablemente, este enlace ha caducado o está roto.", - "share.resultIsForTheFuture": "Este enlace debería funcionar pronto.", - "share.resultHasExpired": "Lamentablemente, este enlace ha caducado.", - "share.titleUsedWords": "Palabras utilizadas", - "share.dontShowThisResult": "No mostrar este resultado más", - "statistics.filters": "Filtros", - "statistics.filterAll": "Combinar", - "statistics.noData": "Sin datos para los filtros seleccionados.", - "statistics.specialCharactersWithout": "sin caracteres especiales", - "statistics.specialCharactersWith": "strong>con caracteres especiales", - "statistics.wordLengthShort": "a {{to}} caracteres", - "statistics.wordLengthLong": "más de {{above}} caracteres", - "statistics.letters": "letras", - "statistics.medianWordsBefore": "en", - "statistics.medianWords": "palabras", - "statistics.median": "mediana", - "statistics.average": "promedio:", - "statistics.maximum": "máximo:", - "statistics.averageLetters": "promedio de letras", - "statistics.averageGameTime": "tiempo promedio de juego", - "statistics.totalGameTime": "tiempo total de juego", - "statistics.inWord": "en palabra", - "statistics.inFirstWord": "en la primera palabra", - "statistics.inSecondWord": "en la segunda palabra", - "statistics.keyboardUsed": "promedio de {{value}}% del teclado utilizado", - "statistics.averageWordsNotFound": "{{value}} palabras no encontradas en un diccionario", - "statistics.worstWordsNotFound": "peor {{value}} en un juego", - "statistics.worstWordsNotFoundLonger": "peores palabras no encontradas en un diccionario {{value}} en un juego", - "statistics.totalGames_zero": "{{count}} juegos", - "statistics.totalGames_one": "1 juego", - "statistics.totalGames_few": "{{count}} juegos", - "statistics.totalGames_many": "{{count}} juegos", - "statistics.totalGames_other": "{{count}} juegos", - "statistics.totalWon": "ganado", - "statistics.totalWonStreak": "ganado en fila", - "statistics.totalWonStreak_zero": "ganado en fila", - "statistics.totalWonStreak_one": "ganado en fila", - "statistics.totalWonStreak_few": "ganado en fila", - "statistics.totalWonStreak_many": "ganado en fila", - "statistics.totalLostStreak": "perdido en fila", - "statistics.totalLostStreak_zero": "perdido en fila", - "statistics.totalLostStreak_one": "perdido en fila", - "statistics.totalLostStreak_few": "perdido en fila", - "statistics.totalLostStreak_many": "perdido en fila", - "statistics.totalBestStreak": "mejor ganado en fila", - "statistics.streakTooltipWithWorstStreak": "lo peor perdido en fila:", - "statistics.lettersCorrect": "correcto", - "statistics.lettersPosition": "posición incorrecta", - "statistics.lettersIncorrect": "incorrecto", - "statistics.lettersIncorrectAndTyped": "escrito incorrecto", - "statistics.titleRemoveStatistics": "Eliminar estadísticas", - "statistics.statisticsWasRemoved": "Las estadísticas fueron eliminadas", - "statistics.wordsWithSpecialCharacters": "Palabras con caracteres especiales", - "statistics.languageTitleHighestLetterForCommon": "La letra más popular", - "statistics.filterCommon": "popularidad", - "statistics.languageDescriptionHighestLetterForCommon": "{{maxletter}} aparece {{maxLetterValue}} veces por palabra.", - "statistics.languageTitleHighestLetterForInWords": "Letra en el mayor número de palabras", - "statistics.filterInWords": "número de palabras", - "statistics.languageDescriptionHighestLetterForInWords": "{{maxletter}} aparece en {{maxLetterValue}} palabras.", - "statistics.languageTitleHighestLetterForFirst": "Letra más común al principio", - "statistics.filterFirst": "primera", - "statistics.languageDescriptionHighestLetterForFirst": "{{maxletter}} es la primera letra en {{maxLetterValue}} palabras.", - "statistics.languageTitleHighestLetterForLast": "Letra más común al final", - "statistics.filterLast": "última", - "statistics.languageDescriptionHighestLetterForLast": "{{maxletter}} es la última letra en {{maxLetterValue}} palabras.", - "statistics.languageTitleLength": "Número de letras en una palabra", - "statistics.languageDescriptionMostPopularLength": "La longitud de palabra más popular es de {{letters}} letras.", - "statistics.languageTitleAtTheBeginning": "Más frecuente al principio", - "statistics.languageTitleInTheMiddle": "Más frecuente en el medio", - "statistics.languageTitleInTheEnd": "Más frecuente al final", - "statistics.showOneChartWithFilters": "Un gráfico con filtros", - "statistics.showTitleWithLanguage": "Mostrar título del idioma", - "statistics.basedOn": "{{product}} basado en {{words}} palabras de {{source}}", - "statistics.bestWordleWordTitle": "Mejor palabra inicial en Wordle", - "statistics.bestWordleWordExplanation": "Resultado contra {{words}} palabras:", - "statistics.filterWordleLettersTitle": "Uso de letras", - "statistics.filterWordleInWords": "Letras", - "statistics.filterWordleLetterPosition": "Posición (repeticiones)", - "statistics.filterWordleUniqueLetterPosition": "Posición", - "statistics.filterWordleMaxTitle": "Maximizando colores", - "statistics.filterBestMaxGreen": "Verde", - "statistics.filterBestMax": "Colores", - "statistics.filterBestMaxOrange": "Amarillo", - "statistics.filterBestMaxGray": "Gris", - "statistics.filterWordleBestTitle": "Equilibrio de color", - "statistics.filterBestGreen1_5": "1.5 × verde + 1 × amarillo", - "statistics.filterBestGreen2_0": "2 × verde + 1 × amarillo", - "statistics.bestWordleWordPopularLettersTitle": "Letras más populares en una posición dada", - "feature.specialWord.wasActivated": "¡La palabra especial ha sido activada!", - "feature.specialWord.wasDeactivated": "¡La palabra especial ha sido desactivada!" -} \ No newline at end of file + "route.help": "ayuda", + "route.settings": "configuracion", + "route.statistics": "tus-estadisticas", + "route.aboutLanguage": "sobre-idioma", + "route.hejto2024": "hejto-2024", + "route.game.title": "DIFFLE - el juego similar a Wordle (sin límite de caracteres) 🇪🇸", + "route.game.metaDescription": "Cada palabra utilizada proporciona pistas sobre la posición y el orden de las letras en la solución.", + "route.game.openGraphTitle": "DIFFLE - el juego similar a Wordle (sin límite de caracteres) 🇪🇸", + "route.game.openGraphDescription": "Cada palabra utilizada proporciona pistas sobre la posición y el orden de las letras en la solución.", + "common.yes": "Sí", + "common.no": "No", + "common.play": "Iniciar juego", + "common.newGame": "Nuevo juego", + "common.copyResult": "Copiar resultado", + "common.copyResultLink": "Copiar solo enlace", + "common.copyLink": "Copiar enlace", + "common.copied": "Copiado.", + "common.checkInDictionary": "Buscar \"{{word}}\"", + "common.checkInDictionaryWithName": "Buscar \"{{word}}\" en {{name}}", + "common.dictionaryIsNotExactMatch": "El diccionario de palabras ganadoras no tiene una versión en línea fácilmente accesible. Por lo tanto, puedes intentarlo con alguno de estos diccionarios.", + "common.close": "Cerrar", + "common.more": "Más", + "common.download": "Descargar", + "common.downloadError": "Error de recuperación.", + "common.fetchError": "Error de recuperación, inténtalo de nuevo.", + "common.unknownError": "Se ha producido un error desconocido.", + "common.serviceMode": "Servicio en mantenimiento el {{today}}.", + "common.serviceModeWeReturnSoon": "¡Volverá a estar en funcionamiento mañana!", + "language.currentLanguage": "Español", + "language.cs": "Checo", + "language.de": "Alemán", + "language.en": "Inglés", + "language.es": "Español", + "language.fi": "Finlandés", + "language.fr": "Francés", + "language.it": "Italiano", + "language.pl": "Polaco", + "game.modeDaily": "Diario", + "game.modePractice": "Práctica", + "game.modeShare": "Compartido", + "game.iGiveUp": "Me rindo", + "game.dailyGameLostToast": "Partida perdida desde {{dailyStamp}}, la palabra ganadora fue \"{{word}}\"", + "game.givingUpIsNotPossible": "Comienza una partida para poder rendirte ;)", + "game.confirmCheckTheWord": "¿Es \"{{word}}\" aceptable?", + "game.wordToSubmitIsMissing": "¿Deberíamos verificar la palabra?", + "game.checking": "verificando...", + "game.withSpecialCharacters": "La palabra ganadora contiene al menos un carácter en {{specialCharacter}}.", + "game.withoutSpecialCharacters": "La palabra ganadora no contiene caracteres en {{specialCharacters}}.", + "game.csSpecialCharacter": "especial", + "game.csSpecialCharacters": "especiales", + "game.deSpecialCharacter": "especial", + "game.deSpecialCharacters": "especiales", + "game.esSpecialCharacter": "español", + "game.esSpecialCharacters": "español", + "game.fiSpecialCharacter": "especial", + "game.fiSpecialCharacters": "especiales", + "game.frSpecialCharacter": "especial", + "game.frSpecialCharacters": "especiales", + "game.itSpecialCharacter": "especial", + "game.itSpecialCharacters": "especiales", + "game.plSpecialCharacter": "especial", + "game.plSpecialCharacters": "especiales", + "game.youCanUseThisWordButNotWin": "Puedes usar esta palabra, pero no puedes ganar con ella.", + "game.youCanUseIncorrectLetters": "letra incorrecta ingresada", + "game.youCanUseLettersTypedTooManyTimes": "letra correcta usada demasiadas veces", + "game.youCanUseSpace": "Las palabras no tienen espacios, pero puedes usarlos, serán eliminados.", + "game.youCanUseIncorrectStart": "inicio de palabra incorrecto", + "game.youCanUseIncorrectEnd": "fin de palabra incorrecto", + "game.youCanUseIncorrectMiddle": "algunas letras deben estar juntas", + "game.youCanUseIncorrectOrder": "algunas letras están en el orden incorrecto", + "game.spacesRemoved": "Los espacios fueron eliminados.", + "game.isNotInDictionary": "Palabra no encontrada en el diccionario.", + "game.wordAlreadyUsed": "La palabra ya había sido utilizada.", + "game.restoreError": "Se produjo un error al restaurar el estado del juego.", + "help.title": "Ayuda", + "help.howToPlayTitle": "¿Cómo se juega?", + "help.howToPlayText1": "Adivina la palabra usando la menor cantidad de letras posible.", + "help.howToPlayText2": "Una vez que realices tu mejor intento, los colores de las letras cambiarán para indicarte cuán cerca o lejos estás de la palabra.", + "help.exampleTitle": "Un ejemplo", + "help.exampleTitleAlt": "Otro ejemplo", + "help.incorrectLettersTip": "Las letras grises no están en la palabra.", + "help.correctLetters": "Las letras {{correct1}} y {{correct2}} están en la palabra en este orden.", + "help.positionBefore": "La letra {{position}} está en la palabra, pero no antes de {{closestCorrect}}.", + "help.positionBetween": "La letra {{position}} pero no entre ellas.", + "help.positionAfter": "La letra {{position}} está en la palabra, pero no después de {{closestCorrect}}.", + "help.inRow": "Las letras {{letters}} están en la palabra en fila.", + "help.firstAndLast": "La palabra comienza con {{first}} y termina con {{last}}.", + "help.winingWordMessage": "Esta es la palabra respuesta.", + "help.previousExample": "Ejemplo anterior", + "help.altExample": "¿Otro ejemplo?", + "help.whatIsDiffleTitle": "¿Qué es Diffle?", + "help.whatIsDiffleDescription": "Diffle es un juego inspirado en Wordle sin límite de caracteres. Si disfrutas de Wordle, este juego es para ti.", + "help.gameRules": "Reglas del juego", + "end.titleWon": "Éxito", + "end.titleLost": "Derrota", + "end.titleCheater": "Un clarividente", + "end.winningWord": "La respuesta:", + "end.wordsUsed_zero": "palabras", + "end.wordsUsed_one": "palabra", + "end.wordsUsed_few": "palabras", + "end.wordsUsed_many": "palabras", + "end.wordsUsed_other": "palabras", + "end.inWordsUsed_zero": "palabras", + "end.inWordsUsed_one": "palabra", + "end.inWordsUsed_few": "palabras", + "end.inWordsUsed_many": "palabras", + "end.inWordsUsed_other": "palabras", + "end.in_zero": "en", + "end.in_one": "en", + "end.in_few": "en", + "end.in_many": "en", + "end.in_other": "en", + "end.lostIn": "perdido", + "end.lettersUsedShort": "l.", + "end.lettersUsed_zero": "letter", + "end.lettersUsed_one": "letra", + "end.lettersUsed_few": "letras", + "end.lettersUsed_many": "letras", + "end.lettersUsed_other": "letras", + "end.nextDailyHours_zero": "La nueva palabra diaria estará disponible en {{count}} horas.", + "end.nextDailyHours_one": "La nueva palabra diaria estará disponible en una hora.", + "end.nextDailyHours_few": "La nueva palabra diaria estará disponible en {{count}} horas.", + "end.nextDailyHours_many": "La nueva palabra diaria estará disponible en {{count}} horas.", + "end.nextDailyHours_other": "La nueva palabra diaria estará disponible en {{count}} horas.", + "end.nextDailyShort": "Próximo en {{count}}h", + "end.completed": "completado", + "end.gameDuration": "Duración del juego", + "settings.title": "Configuración", + "settings.inDevelopment": "En desarrollo", + "settings.inBetaNow": "Beta", + "settings.onlyIn": "Solo en", + "settings.considered": "Considerado", + "settings.statisticsTitle": "Estadísticas", + "settings.gameModeTitle": "Modos de juego", + "settings.labelFinishGame": "Finalizar", + "settings.labelFinishGameLonger": "Adivina la contraseña de hoy para desbloquear.", + "settings.labelYouCanSeeSharedWords": "Adivinaste la contraseña de hoy, así que puedes verlos.", + "settings.preferencesTitle": "Preferencias", + "settings.highContrastMode": "Contraste alto", + "settings.lightMode": "Modo claro", + "settings.darkMode": "Modo oscuro", + "settings.appVibration": "Vibraciones de la app", + "settings.showGameDuration": "Mostrar duración del juego", + "settings.accessibility": "Accesibilidad", + "settings.keyboard": "Teclado", + "settings.confirmSubmition": "Confirmar palabras", + "settings.swapEnterAndBackspace": "Intercambiar retroceso con enter", + "settings.languageDefault": "Idioma", + "settings.keyboardVibration": "Vibraciones teclado", + "settings.smallerKeyboard": "Teclado más pequeño", + "settings.sourcesTitle": "Fuentes", + "settings.sourcesDescription": "Todos los recursos utilizados por esta aplicación están bajo una licencia gratuita. Reconocimientos a los creadores de esos recursos.", + "settings.sourcesTitleDictionaries": "Diccionarios", + "settings.sourcesTitleImages": "Iconos", + "settings.sourceGithub": "repositorio de este sitio", + "settings.sourceDiffle": "Diffle original", + "settings.sourceDictionarySpellchecker": "como corrector ortográfico", + "settings.sourceDictionaryWiningWords": "como buscador de palabras ganadoras", + "settings.lastDailyWordsTitle": "Palabra de ayer", + "settings.lastDailyWordsYesterday": "La palabra de ayer fue \"{{word}}\".", + "settings.lastDailyWordsCanBeWrongBecauseOfUpdate": "La palabra ganadora de ayer podría estar equivocada porque se lanzó una actualización más grande.", + "settings.confirmInSeconds_zero": "Clic en {{count}} seg. para confirmar", + "settings.confirmInSeconds_one": "Clic en 1 segundo para confirmar.", + "settings.confirmInSeconds_few": "Clic en {{count}} seg. para confirmar", + "settings.confirmInSeconds_many": "Clic en {{count}} seg. para confirmar", + "settings.confirmInSeconds_other": "Clic en {{count}} seg. para confirmar", + "settings.confirmAfterWaiting": "Confirmar", + "settings.language": "Idioma", + "settings.languageChanged": "Se ha cambiado el idioma.", + "settings.reportTranslationBug": "Informar sobre un error de traducción", + "settings.privacyTitle": "Privacidad", + "settings.cookiesTitle": "Cookies", + "settings.cookiesText1": "Este sitio web utiliza la memoria caché de su navegador para funcionar correctamente.", + "settings.cookiesText2": "Al aceptar \"todo\", también aceptas el seguimiento opcional de tu actividad (incluido Google Analytics).", + "settings.acceptAll": "Aceptar todo", + "settings.acceptOnlyRequired": "Aceptar requeridos", + "settings.saveSelected": "Guardar seleccionado", + "settings.cookiesSavedAndRefresh": "Guardado. La aplicación se actualizará.", + "settings.cookiesExternalOptional": "externo y opcional", + "settings.cookiesLocalRequierd": "local y requerido", + "share.titleSettings": "Compartir", + "share.linkWithUsedWords": "Enlace a las palabras utilizadas", + "share.linkWithUsedWordsNoSpoilers": "(sin spoilers)", + "share.titleSharedResult": "Resultado compartido contigo", + "share.resultIsBroken": "Lamentablemente, este enlace ha caducado o está roto.", + "share.resultIsForTheFuture": "Este enlace debería funcionar pronto.", + "share.resultHasExpired": "Lamentablemente, este enlace ha caducado.", + "share.titleUsedWords": "Palabras utilizadas", + "share.dontShowThisResult": "No mostrar este resultado más", + "statistics.filters": "Filtros", + "statistics.filterAll": "Combinar", + "statistics.noData": "Sin datos para los filtros seleccionados.", + "statistics.specialCharactersWithout": "sin caracteres especiales", + "statistics.specialCharactersWith": "strong>con caracteres especiales", + "statistics.wordLengthShort": "a {{to}} caracteres", + "statistics.wordLengthLong": "más de {{above}} caracteres", + "statistics.letters": "letras", + "statistics.medianWordsBefore": "en", + "statistics.medianWords": "palabras", + "statistics.median": "mediana", + "statistics.average": "promedio:", + "statistics.maximum": "máximo:", + "statistics.averageLetters": "promedio de letras", + "statistics.averageGameTime": "tiempo promedio de juego", + "statistics.totalGameTime": "tiempo total de juego", + "statistics.inWord": "en palabra", + "statistics.inFirstWord": "en la primera palabra", + "statistics.inSecondWord": "en la segunda palabra", + "statistics.keyboardUsed": "promedio de {{value}}% del teclado utilizado", + "statistics.averageWordsNotFound": "{{value}} palabras no encontradas en un diccionario", + "statistics.worstWordsNotFound": "peor {{value}} en un juego", + "statistics.worstWordsNotFoundLonger": "peores palabras no encontradas en un diccionario {{value}} en un juego", + "statistics.totalGames_zero": "{{count}} juegos", + "statistics.totalGames_one": "1 juego", + "statistics.totalGames_few": "{{count}} juegos", + "statistics.totalGames_many": "{{count}} juegos", + "statistics.totalGames_other": "{{count}} juegos", + "statistics.totalWon": "ganado", + "statistics.totalWonStreak": "ganado en fila", + "statistics.totalWonStreak_zero": "ganado en fila", + "statistics.totalWonStreak_one": "ganado en fila", + "statistics.totalWonStreak_few": "ganado en fila", + "statistics.totalWonStreak_many": "ganado en fila", + "statistics.totalLostStreak": "perdido en fila", + "statistics.totalLostStreak_zero": "perdido en fila", + "statistics.totalLostStreak_one": "perdido en fila", + "statistics.totalLostStreak_few": "perdido en fila", + "statistics.totalLostStreak_many": "perdido en fila", + "statistics.totalBestStreak": "mejor ganado en fila", + "statistics.streakTooltipWithWorstStreak": "lo peor perdido en fila:", + "statistics.lettersCorrect": "correcto", + "statistics.lettersPosition": "posición incorrecta", + "statistics.lettersIncorrect": "incorrecto", + "statistics.lettersIncorrectAndTyped": "escrito incorrecto", + "statistics.titleRemoveStatistics": "Eliminar estadísticas", + "statistics.statisticsWasRemoved": "Las estadísticas fueron eliminadas", + "statistics.wordsWithSpecialCharacters": "Palabras con caracteres especiales", + "statistics.languageTitleHighestLetterForCommon": "La letra más popular", + "statistics.filterCommon": "popularidad", + "statistics.languageDescriptionHighestLetterForCommon": "{{maxletter}} aparece {{maxLetterValue}} veces por palabra.", + "statistics.languageTitleHighestLetterForInWords": "Letra en el mayor número de palabras", + "statistics.filterInWords": "número de palabras", + "statistics.languageDescriptionHighestLetterForInWords": "{{maxletter}} aparece en {{maxLetterValue}} palabras.", + "statistics.languageTitleHighestLetterForFirst": "Letra más común al principio", + "statistics.filterFirst": "primera", + "statistics.languageDescriptionHighestLetterForFirst": "{{maxletter}} es la primera letra en {{maxLetterValue}} palabras.", + "statistics.languageTitleHighestLetterForLast": "Letra más común al final", + "statistics.filterLast": "última", + "statistics.languageDescriptionHighestLetterForLast": "{{maxletter}} es la última letra en {{maxLetterValue}} palabras.", + "statistics.languageTitleLength": "Número de letras en una palabra", + "statistics.languageDescriptionMostPopularLength": "La longitud de palabra más popular es de {{letters}} letras.", + "statistics.languageTitleAtTheBeginning": "Más frecuente al principio", + "statistics.languageTitleInTheMiddle": "Más frecuente en el medio", + "statistics.languageTitleInTheEnd": "Más frecuente al final", + "statistics.showOneChartWithFilters": "Un gráfico con filtros", + "statistics.showTitleWithLanguage": "Mostrar título del idioma", + "statistics.basedOn": "{{product}} basado en {{words}} palabras de {{source}}", + "statistics.bestWordleWordTitle": "Mejor palabra inicial en Wordle", + "statistics.bestWordleWordExplanation": "Resultado contra {{words}} palabras:", + "statistics.filterWordleLettersTitle": "Uso de letras", + "statistics.filterWordleInWords": "Letras", + "statistics.filterWordleLetterPosition": "Posición (repeticiones)", + "statistics.filterWordleUniqueLetterPosition": "Posición", + "statistics.filterWordleMaxTitle": "Maximizando colores", + "statistics.filterBestMaxGreen": "Verde", + "statistics.filterBestMax": "Colores", + "statistics.filterBestMaxOrange": "Amarillo", + "statistics.filterBestMaxGray": "Gris", + "statistics.filterWordleBestTitle": "Equilibrio de color", + "statistics.filterBestGreen1_5": "1.5 × verde + 1 × amarillo", + "statistics.filterBestGreen2_0": "2 × verde + 1 × amarillo", + "statistics.bestWordleWordPopularLettersTitle": "Letras más populares en una posición dada", + "feature.specialWord.wasActivated": "¡La palabra especial ha sido activada!", + "feature.specialWord.wasDeactivated": "¡La palabra especial ha sido desactivada!" +} diff --git a/src/locales/fi.json b/src/locales/fi.json index 4ccb189ac..50bd7b370 100644 --- a/src/locales/fi.json +++ b/src/locales/fi.json @@ -1,269 +1,274 @@ { - "seo.pageTitle": "DIFFLE - peli kuin Wordle suomeksi (ilman merkkirajaa) 🇫🇮", - "seo.metaDescription": "Jokainen käytetty sana antaa vihjeitä kirjainten sijainnista ja järjestyksestä ratkaisussa.", - "seo.openGraphTitle": "DIFFLE - peli kuin Wordle (ilman merkkirajaa)", - "seo.openGraphDescription": "Jokainen käytetty sana antaa vihjeitä kirjainten sijainnista ja järjestyksestä ratkaisussa.", - "common.yes": "Kyllä", - "common.no": "Ei", - "common.play": "Pelaa", - "common.newGame": "Uusi peli", - "common.copyResult": "Kopioi tulos", - "common.copyResultLink": "Kopioi vain linkki", - "common.copyLink": "Kopioi linkki", - "common.copied": "Kopioitu.", - "common.checkInDictionary": "Etsi \"{{word}}\"", - "common.checkInDictionaryWithName": "Etsi \"{{word}}\" {{name}}-sanakirjasta", - "common.dictionaryIsNotExactMatch": "Voittosanojen sanakirjasta ei ole helposti saatavilla olevaa online-versiota, joten voit kokeilla jotakin näistä sanakirjoista.", - "common.close": "Sulje", - "common.more": "lisää", - "common.download": "Lataa", - "common.downloadError": "Hakeminen epäonnistui.", - "common.fetchError": "Hakeminen epäonnistui, yritä uudelleen.", - "common.unknownError": "Tapahtui tuntematon virhe.", - "common.serviceMode": "Huoltotila {{today}}.", - "common.serviceModeWeReturnSoon": "Takaisin toiminnassa huomenna!", - "language.currentLanguage": "Suomi", - "language.cs": "Tšekki", - "language.de": "Saksa", - "language.en": "Englanti", - "language.es": "Espanja", - "language.fi": "Suomi", - "language.fr": "Ranska", - "language.it": "Italia", - "language.pl": "Puola", - "game.modeDaily": "Päivittäinen", - "game.modePractice": "Harjoitus", - "game.modeShare": "Jaettu", - "game.iGiveUp": "Luovutan", - "game.dailyGameLostToast": "Hävitty peli {{dailyStamp}}, voittosana oli \"{{word}}\"", - "game.givingUpIsNotPossible": "Aloita peli voidaksesi luovuttaa ;)", - "game.confirmCheckTheWord": "Onko \"{{word}}\" oikein?", - "game.wordToSubmitIsMissing": "Pitäisikö tarkistaa sana?", - "game.checking": "tarkistetaan...", - "game.withSpecialCharacters": "Voittosana sisältää vähintään yhden {{specialCharacter}}-merkin.", - "game.withoutSpecialCharacters": "Voittosana ei sisällä {{specialCharacters}}-merkkejä.", - "game.csSpecialCharacter": "erikoismerkki", - "game.csSpecialCharacters": "erikoismerkkejä", - "game.deSpecialCharacter": "erikoismerkki", - "game.deSpecialCharacters": "erikoismerkkejä", - "game.esSpecialCharacter": "erikoismerkki", - "game.esSpecialCharacters": "erikoismerkkejä", - "game.fiSpecialCharacter": "erikoismerkki", - "game.fiSpecialCharacters": "erikoismerkkejä", - "game.frSpecialCharacter": "erikoismerkki", - "game.frSpecialCharacters": "erikoismerkkejä", - "game.itSpecialCharacter": "erikoismerkki", - "game.itSpecialCharacters": "erikoismerkkejä", - "game.plSpecialCharacter": "erikoismerkki", - "game.plSpecialCharacters": "erikoismerkkejä", - "game.youCanUseThisWordButNotWin": "Voit käyttää tätä sanaa, mutta et voi voittaa sillä.", - "game.youCanUseIncorrectLetters": "väärä kirjain kirjoitettu", - "game.youCanUseLettersTypedTooManyTimes": "oikea kirjain käytetty liian monta kertaa", - "game.youCanUseSpace": "Sanat eivät sisällä välilyöntejä, mutta voit käyttää niitä, ne poistetaan.", - "game.youCanUseIncorrectStart": "väärä sanan alku", - "game.youCanUseIncorrectEnd": "väärä sanan loppu", - "game.youCanUseIncorrectMiddle": "joidenkin kirjainten tulisi olla vierekkäin", - "game.youCanUseIncorrectOrder": "joidenkin kirjainten järjestys on väärä", - "game.spacesRemoved": "Välilyönnit poistettiin.", - "game.isNotInDictionary": "Sanaa ei löydy sanakirjasta.", - "game.wordAlreadyUsed": "Sana on jo käytetty.", - "game.restoreError": "Virhe tapahtui pelitilaa palautettaessa.", - "help.title": "Ohje", - "help.howToPlayTitle": "Kuinka pelata?", - "help.howToPlayText1": "Arvaa sana käyttämällä mahdollisimman vähän kirjaimia.", - "help.howToPlayText2": "Kun olet antanut parhaan arvauksesi, kirjainten värit vaihtuvat kertoakseen, kuinka lähellä tai kaukana olet sanasta.", - "help.exampleTitle": "Esimerkki", - "help.exampleTitleAlt": "Toinen esimerkki", - "help.incorrectLettersTip": "Harmaat kirjaimet eivät ole sanassa.", - "help.correctLetters": "Kirjaimet {{correct1}} ja {{correct2}} ovat sanassa tässä järjestyksessä.", - "help.positionBefore": "Kirjain {{position}} on sanassa, mutta ei ennen {{closestCorrect}}.", - "help.positionBetween": "Kirjain {{position}}, mutta ei niiden välillä.", - "help.positionAfter": "Kirjain {{position}} on sanassa, mutta ei jälkeen {{closestCorrect}}.", - "help.inRow": "Kirjaimet {{letters}} ovat sanassa peräkkäin.", - "help.firstAndLast": "Sana alkaa kirjaimella {{first}} ja päättyy kirjaimeen {{last}}.", - "help.winingWordMessage": "Tämä on vastaussana.", - "help.previousExample": "Edellinen esimerkki", - "help.altExample": "Toinen esimerkki?", - "help.whatIsDiffleTitle": "Mikä on Diffle?", - "help.whatIsDiffleDescription": "Diffle on Wordlen inspiroima peli ilman merkkirajoitusta. Jos pidät Wordlesta, tämä peli on sinulle.", - "help.gameRules": "Pelin säännöt", - "end.titleWon": "Onnistuminen", - "end.titleLost": "Tappio", - "end.titleCheater": "Selvännäkijä", - "end.winningWord": "Vastaus:", - "end.wordsUsed_zero": "sanaa", - "end.wordsUsed_one": "sana", - "end.wordsUsed_few": "sanaa", - "end.wordsUsed_many": "sanaa", - "end.wordsUsed_other": "sanaa", - "end.inWordsUsed_zero": "sanaa", - "end.inWordsUsed_one": "sana", - "end.inWordsUsed_few": "sanaa", - "end.inWordsUsed_many": "sanaa", - "end.inWordsUsed_other": "sanaa", - "end.in_zero": "ssa", - "end.in_one": "ssa", - "end.in_few": "ssa", - "end.in_many": "ssa", - "end.in_other": "ssa", - "end.lostIn": "hävitty", - "end.lettersUsedShort": "k.", - "end.lettersUsed_zero": "kirjain", - "end.lettersUsed_one": "kirjain", - "end.lettersUsed_few": "kirjainta", - "end.lettersUsed_many": "kirjainta", - "end.lettersUsed_other": "kirjainta", - "end.nextDailyHours_zero": "Uusi päivittäinen sana on saatavilla {{count}} tunnin kuluttua.", - "end.nextDailyHours_one": "Uusi päivittäinen sana on saatavilla tunnin kuluttua.", - "end.nextDailyHours_few": "Uusi päivittäinen sana on saatavilla {{count}} tunnin kuluttua.", - "end.nextDailyHours_many": "Uusi päivittäinen sana on saatavilla {{count}} tunnin kuluttua.", - "end.nextDailyHours_other": "Uusi päivittäinen sana on saatavilla {{count}} tunnin kuluttua.", - "end.nextDailyShort": "seuraava {{count}}h kuluttua", - "end.completed": "valmistunut", - "end.gameDuration": "Pelin kesto", - "settings.title": "Asetukset", - "settings.inDevelopment": "Kehitteillä", - "settings.inBetaNow": "Beta", - "settings.onlyIn": "Vain", - "settings.considered": "Harkittu", - "settings.statisticsTitle": "Tilastot", - "settings.gameModeTitle": "Pelimuodot", - "settings.labelFinishGame": "Lopeta", - "settings.labelFinishGameLonger": "Arvaa päivän sana avataksesi.", - "settings.labelYouCanSeeSharedWords": "Olet arvannut päivän sanan, joten voit nähdä ne.", - "settings.preferencesTitle": "Asetukset", - "settings.highContrastMode": "Korkea kontrasti", - "settings.lightMode": "Vaalea tila", - "settings.darkMode": "Tumma tila", - "settings.appVibration": "Sovelluksen värinät", - "settings.showGameDuration": "Näytä pelin kesto", - "settings.accessibility": "Saavutettavuus", - "settings.keyboard": "Näppäimistö", - "settings.confirmSubmition": "Vahvista sanat", - "settings.swapEnterAndBackspace": "Vaihda Enter ja Backspace", - "settings.languageDefault": "kielestä", - "settings.keyboardVibration": "Näppäimistön värinät", - "settings.smallerKeyboard": "Pienempi näppäimistö", - "settings.sourcesTitle": "Lähteet", - "settings.sourcesDescription": "Kaikki tämän sovelluksen käyttämät resurssit ovat vapaan lisenssin alaisia. Kiitokset näiden resurssien luojille.", - "settings.sourcesTitleDictionaries": "Sanakirjat", - "settings.sourcesTitleImages": "Kuvakkeet", - "settings.sourceGithub": "tämän sivuston arkisto", - "settings.sourceDiffle": "alkuperäinen diffle", - "settings.sourceDictionarySpellchecker": "oikeinkirjoituksen tarkistajana", - "settings.sourceDictionaryWiningWords": "voittosanojen etsijänä", - "settings.lastDailyWordsTitle": "Eilisen sana", - "settings.lastDailyWordsYesterday": "Eilinen sana oli \"{{word}}\".", - "settings.lastDailyWordsCanBeWrongBecauseOfUpdate": "Eilinen voittosana voi olla väärin, koska suurempi päivitys julkaistiin.", - "settings.confirmInSeconds_zero": "Klikkaa {{count}} sekunnin kuluttua vahvistaaksesi", - "settings.confirmInSeconds_one": "Klikkaa sekunnin kuluttua vahvistaaksesi", - "settings.confirmInSeconds_few": "Klikkaa {{count}} sekunnin kuluttua vahvistaaksesi", - "settings.confirmInSeconds_many": "Klikkaa {{count}} sekunnin kuluttua vahvistaaksesi", - "settings.confirmInSeconds_other": "Klikkaa {{count}} sekunnin kuluttua vahvistaaksesi", - "settings.confirmAfterWaiting": "Klikkaa vahvistaaksesi", - "settings.language": "Kieli", - "settings.languageChanged": "Kieli on vaihdettu.", - "settings.reportTranslationBug": "Ilmoita käännösvirheestä", - "settings.privacyTitle": "Tietosuoja", - "settings.cookiesTitle": "Evästeet", - "settings.cookiesText1": "Tämä sivusto käyttää selaimesi välimuistia toimiakseen oikein.", - "settings.cookiesText2": "Hyväksymällä \"kaikki\" hyväksyt myös valinnaisen toimintasi seurannan (mukaan lukien Google Analytics).", - "settings.acceptAll": "Hyväksy kaikki", - "settings.acceptOnlyRequired": "Hyväksy vain vaaditut", - "settings.saveSelected": "Tallenna valitut", - "settings.cookiesSavedAndRefresh": "Tallennettu. Sovellus päivittyy.", - "settings.cookiesExternalOptional": "ulkoinen ja valinnainen", - "settings.cookiesLocalRequierd": "paikallinen ja vaadittu", - "share.titleSettings": "Jakaminen", - "share.linkWithUsedWords": "Linkki käytettyihin sanoihin", - "share.linkWithUsedWordsNoSpoilers": "(ilman spoilereita)", - "share.titleSharedResult": "Tulokset jaettu kanssasi", - "share.resultIsBroken": "Valitettavasti tämä linkki on vanhentunut tai rikki.", - "share.resultIsForTheFuture": "Tämä linkki pitäisi toimia pian.", - "share.resultHasExpired": "Valitettavasti tämä linkki on vanhentunut.", - "share.titleUsedWords": "Käytetyt sanat", - "share.dontShowThisResult": "Älä näytä tätä tulosta enää", - "statistics.filters": "Suodattimet", - "statistics.filterAll": "Yhdistä", - "statistics.noData": "Ei tietoja valituille suodattimille.", - "statistics.specialCharactersWithout": "ilman erikoismerkkejä", - "statistics.specialCharactersWith": "erikoismerkkien kanssa", - "statistics.wordLengthShort": "enintään {{to}} merkkiä", - "statistics.wordLengthLong": "yli {{above}} merkkiä", - "statistics.letters": "kirjainta", - "statistics.medianWordsBefore": "keskimäärin", - "statistics.medianWords": "sanaa", - "statistics.median": "mediaani", - "statistics.average": "keskimäärin:", - "statistics.maximum": "maksimi:", - "statistics.averageLetters": "keskimääräinen kirjainten määrä", - "statistics.averageGameTime": "keskimääräinen peliaika", - "statistics.totalGameTime": "kokonaispeliaika", - "statistics.inWord": "sanassa", - "statistics.inFirstWord": "ensimmäisessä sanassa", - "statistics.inSecondWord": "toisessa sanassa", - "statistics.keyboardUsed": "keskimäärin {{value}}% näppäimistöstä käytetty", - "statistics.averageWordsNotFound": "{{value}} sanaa ei löydy sanakirjasta", - "statistics.worstWordsNotFound": "huonoin {{value}} yhdessä pelissä", - "statistics.worstWordsNotFoundLonger": "huonoin sanakirjasta löytymättömien sanojen määrä {{value}} pelissä", - "statistics.totalGames_zero": "{{count}} peliä", - "statistics.totalGames_one": "1 peli", - "statistics.totalGames_few": "{{count}} peliä", - "statistics.totalGames_many": "{{count}} peliä", - "statistics.totalGames_other": "{{count}} peliä", - "statistics.totalWon": "voitettu", - "statistics.totalWonStreak": "peräkkäin voitettu", - "statistics.totalWonStreak_zero": "peräkkäin voitettu", - "statistics.totalWonStreak_one": "peräkkäin voitettu", - "statistics.totalWonStreak_few": "peräkkäin voitettu", - "statistics.totalWonStreak_many": "peräkkäin voitettu", - "statistics.totalLostStreak": "peräkkäin hävitty", - "statistics.totalLostStreak_zero": "peräkkäin hävitty", - "statistics.totalLostStreak_one": "peräkkäin hävitty", - "statistics.totalLostStreak_few": "peräkkäin hävitty", - "statistics.totalLostStreak_many": "peräkkäin hävitty", - "statistics.totalBestStreak": "paras peräkkäin voitettu", - "statistics.streakTooltipWithWorstStreak": "huonoin peräkkäin hävitty:", - "statistics.lettersCorrect": "oikein", - "statistics.lettersPosition": "väärä sijainti", - "statistics.lettersIncorrect": "väärin", - "statistics.lettersIncorrectAndTyped": "väärin kirjoitettu", - "statistics.titleRemoveStatistics": "Poista tilastot", - "statistics.statisticsWasRemoved": "Tilastot poistettiin", - "statistics.wordsWithSpecialCharacters": "Sanat, joissa on erikoismerkkejä", - "statistics.languageTitleHighestLetterForCommon": "Yleisin kirjain", - "statistics.filterCommon": "suosio", - "statistics.languageDescriptionHighestLetterForCommon": "{{maxletter}} esiintyy {{maxLetterValue}} kertaa per sana.", - "statistics.languageTitleHighestLetterForInWords": "Kirjain, joka esiintyy eniten sanoissa", - "statistics.filterInWords": "sanojen määrä", - "statistics.languageDescriptionHighestLetterForInWords": "{{maxletter}} esiintyy {{maxLetterValue}} sanassa.", - "statistics.languageTitleHighestLetterForFirst": "Yleisin ensimmäinen kirjain", - "statistics.filterFirst": "ensimmäinen", - "statistics.languageDescriptionHighestLetterForFirst": "{{maxletter}} on ensimmäinen kirjain {{maxLetterValue}} sanassa.", - "statistics.languageTitleHighestLetterForLast": "Yleisin viimeinen kirjain", - "statistics.filterLast": "viimeinen", - "statistics.languageDescriptionHighestLetterForLast": "{{maxletter}} on viimeinen kirjain {{maxLetterValue}} sanassa.", - "statistics.languageTitleLength": "Kirjainten määrä sanassa", - "statistics.languageDescriptionMostPopularLength": "Suosituin sanan pituus on {{letters}} kirjainta.", - "statistics.languageTitleAtTheBeginning": "Yleisimmin alussa", - "statistics.languageTitleInTheMiddle": "Yleisimmin keskellä", - "statistics.languageTitleInTheEnd": "Yleisimmin lopussa", - "statistics.showOneChartWithFilters": "Yksi kaavio suodattimilla", - "statistics.showTitleWithLanguage": "Näytä kieli otsikossa", - "statistics.basedOn": "{{product}} perustuu {{words}} sanaan lähteestä {{source}}", - "statistics.bestWordleWordTitle": "Paras aloitussana Wordlessa", - "statistics.bestWordleWordExplanation": "Tulos {{words}} sanaa vastaan:", - "statistics.filterWordleLettersTitle": "Käytetyt kirjaimet", - "statistics.filterWordleInWords": "Kirjaimet", - "statistics.filterWordleLetterPosition": "Sijainti (toistot)", - "statistics.filterWordleUniqueLetterPosition": "Sijainti", - "statistics.filterWordleMaxTitle": "Maksimoi värit", - "statistics.filterBestMaxGreen": "Vihreä", - "statistics.filterBestMax": "Värit", - "statistics.filterBestMaxOrange": "Oranssi", - "statistics.filterBestMaxGray": "Harmaa", - "statistics.filterWordleBestTitle": "Väritasapaino", - "statistics.filterBestGreen1_5": "1,5 × vihreä + 1 × keltainen", - "statistics.filterBestGreen2_0": "2 × vihreä + 1 × keltainen", - "statistics.bestWordleWordPopularLettersTitle": "Suosituimmat kirjaimet tietyssä asemassa" -} \ No newline at end of file + "route.help": "apu", + "route.settings": "asetukset", + "route.statistics": "tilastosi", + "route.aboutLanguage": "kielesta", + "route.hejto2024": "hejto-2024", + "route.game.title": "DIFFLE - peli kuin Wordle suomeksi (ilman merkkirajaa) 🇫🇮", + "route.game.metaDescription": "Jokainen käytetty sana antaa vihjeitä kirjainten sijainnista ja järjestyksestä ratkaisussa.", + "route.game.openGraphTitle": "DIFFLE - peli kuin Wordle (ilman merkkirajaa)", + "route.game.openGraphDescription": "Jokainen käytetty sana antaa vihjeitä kirjainten sijainnista ja järjestyksestä ratkaisussa.", + "common.yes": "Kyllä", + "common.no": "Ei", + "common.play": "Pelaa", + "common.newGame": "Uusi peli", + "common.copyResult": "Kopioi tulos", + "common.copyResultLink": "Kopioi vain linkki", + "common.copyLink": "Kopioi linkki", + "common.copied": "Kopioitu.", + "common.checkInDictionary": "Etsi \"{{word}}\"", + "common.checkInDictionaryWithName": "Etsi \"{{word}}\" {{name}}-sanakirjasta", + "common.dictionaryIsNotExactMatch": "Voittosanojen sanakirjasta ei ole helposti saatavilla olevaa online-versiota, joten voit kokeilla jotakin näistä sanakirjoista.", + "common.close": "Sulje", + "common.more": "lisää", + "common.download": "Lataa", + "common.downloadError": "Hakeminen epäonnistui.", + "common.fetchError": "Hakeminen epäonnistui, yritä uudelleen.", + "common.unknownError": "Tapahtui tuntematon virhe.", + "common.serviceMode": "Huoltotila {{today}}.", + "common.serviceModeWeReturnSoon": "Takaisin toiminnassa huomenna!", + "language.currentLanguage": "Suomi", + "language.cs": "Tšekki", + "language.de": "Saksa", + "language.en": "Englanti", + "language.es": "Espanja", + "language.fi": "Suomi", + "language.fr": "Ranska", + "language.it": "Italia", + "language.pl": "Puola", + "game.modeDaily": "Päivittäinen", + "game.modePractice": "Harjoitus", + "game.modeShare": "Jaettu", + "game.iGiveUp": "Luovutan", + "game.dailyGameLostToast": "Hävitty peli {{dailyStamp}}, voittosana oli \"{{word}}\"", + "game.givingUpIsNotPossible": "Aloita peli voidaksesi luovuttaa ;)", + "game.confirmCheckTheWord": "Onko \"{{word}}\" oikein?", + "game.wordToSubmitIsMissing": "Pitäisikö tarkistaa sana?", + "game.checking": "tarkistetaan...", + "game.withSpecialCharacters": "Voittosana sisältää vähintään yhden {{specialCharacter}}-merkin.", + "game.withoutSpecialCharacters": "Voittosana ei sisällä {{specialCharacters}}-merkkejä.", + "game.csSpecialCharacter": "erikoismerkki", + "game.csSpecialCharacters": "erikoismerkkejä", + "game.deSpecialCharacter": "erikoismerkki", + "game.deSpecialCharacters": "erikoismerkkejä", + "game.esSpecialCharacter": "erikoismerkki", + "game.esSpecialCharacters": "erikoismerkkejä", + "game.fiSpecialCharacter": "erikoismerkki", + "game.fiSpecialCharacters": "erikoismerkkejä", + "game.frSpecialCharacter": "erikoismerkki", + "game.frSpecialCharacters": "erikoismerkkejä", + "game.itSpecialCharacter": "erikoismerkki", + "game.itSpecialCharacters": "erikoismerkkejä", + "game.plSpecialCharacter": "erikoismerkki", + "game.plSpecialCharacters": "erikoismerkkejä", + "game.youCanUseThisWordButNotWin": "Voit käyttää tätä sanaa, mutta et voi voittaa sillä.", + "game.youCanUseIncorrectLetters": "väärä kirjain kirjoitettu", + "game.youCanUseLettersTypedTooManyTimes": "oikea kirjain käytetty liian monta kertaa", + "game.youCanUseSpace": "Sanat eivät sisällä välilyöntejä, mutta voit käyttää niitä, ne poistetaan.", + "game.youCanUseIncorrectStart": "väärä sanan alku", + "game.youCanUseIncorrectEnd": "väärä sanan loppu", + "game.youCanUseIncorrectMiddle": "joidenkin kirjainten tulisi olla vierekkäin", + "game.youCanUseIncorrectOrder": "joidenkin kirjainten järjestys on väärä", + "game.spacesRemoved": "Välilyönnit poistettiin.", + "game.isNotInDictionary": "Sanaa ei löydy sanakirjasta.", + "game.wordAlreadyUsed": "Sana on jo käytetty.", + "game.restoreError": "Virhe tapahtui pelitilaa palautettaessa.", + "help.title": "Ohje", + "help.howToPlayTitle": "Kuinka pelata?", + "help.howToPlayText1": "Arvaa sana käyttämällä mahdollisimman vähän kirjaimia.", + "help.howToPlayText2": "Kun olet antanut parhaan arvauksesi, kirjainten värit vaihtuvat kertoakseen, kuinka lähellä tai kaukana olet sanasta.", + "help.exampleTitle": "Esimerkki", + "help.exampleTitleAlt": "Toinen esimerkki", + "help.incorrectLettersTip": "Harmaat kirjaimet eivät ole sanassa.", + "help.correctLetters": "Kirjaimet {{correct1}} ja {{correct2}} ovat sanassa tässä järjestyksessä.", + "help.positionBefore": "Kirjain {{position}} on sanassa, mutta ei ennen {{closestCorrect}}.", + "help.positionBetween": "Kirjain {{position}}, mutta ei niiden välillä.", + "help.positionAfter": "Kirjain {{position}} on sanassa, mutta ei jälkeen {{closestCorrect}}.", + "help.inRow": "Kirjaimet {{letters}} ovat sanassa peräkkäin.", + "help.firstAndLast": "Sana alkaa kirjaimella {{first}} ja päättyy kirjaimeen {{last}}.", + "help.winingWordMessage": "Tämä on vastaussana.", + "help.previousExample": "Edellinen esimerkki", + "help.altExample": "Toinen esimerkki?", + "help.whatIsDiffleTitle": "Mikä on Diffle?", + "help.whatIsDiffleDescription": "Diffle on Wordlen inspiroima peli ilman merkkirajoitusta. Jos pidät Wordlesta, tämä peli on sinulle.", + "help.gameRules": "Pelin säännöt", + "end.titleWon": "Onnistuminen", + "end.titleLost": "Tappio", + "end.titleCheater": "Selvännäkijä", + "end.winningWord": "Vastaus:", + "end.wordsUsed_zero": "sanaa", + "end.wordsUsed_one": "sana", + "end.wordsUsed_few": "sanaa", + "end.wordsUsed_many": "sanaa", + "end.wordsUsed_other": "sanaa", + "end.inWordsUsed_zero": "sanaa", + "end.inWordsUsed_one": "sana", + "end.inWordsUsed_few": "sanaa", + "end.inWordsUsed_many": "sanaa", + "end.inWordsUsed_other": "sanaa", + "end.in_zero": "ssa", + "end.in_one": "ssa", + "end.in_few": "ssa", + "end.in_many": "ssa", + "end.in_other": "ssa", + "end.lostIn": "hävitty", + "end.lettersUsedShort": "k.", + "end.lettersUsed_zero": "kirjain", + "end.lettersUsed_one": "kirjain", + "end.lettersUsed_few": "kirjainta", + "end.lettersUsed_many": "kirjainta", + "end.lettersUsed_other": "kirjainta", + "end.nextDailyHours_zero": "Uusi päivittäinen sana on saatavilla {{count}} tunnin kuluttua.", + "end.nextDailyHours_one": "Uusi päivittäinen sana on saatavilla tunnin kuluttua.", + "end.nextDailyHours_few": "Uusi päivittäinen sana on saatavilla {{count}} tunnin kuluttua.", + "end.nextDailyHours_many": "Uusi päivittäinen sana on saatavilla {{count}} tunnin kuluttua.", + "end.nextDailyHours_other": "Uusi päivittäinen sana on saatavilla {{count}} tunnin kuluttua.", + "end.nextDailyShort": "seuraava {{count}}h kuluttua", + "end.completed": "valmistunut", + "end.gameDuration": "Pelin kesto", + "settings.title": "Asetukset", + "settings.inDevelopment": "Kehitteillä", + "settings.inBetaNow": "Beta", + "settings.onlyIn": "Vain", + "settings.considered": "Harkittu", + "settings.statisticsTitle": "Tilastot", + "settings.gameModeTitle": "Pelimuodot", + "settings.labelFinishGame": "Lopeta", + "settings.labelFinishGameLonger": "Arvaa päivän sana avataksesi.", + "settings.labelYouCanSeeSharedWords": "Olet arvannut päivän sanan, joten voit nähdä ne.", + "settings.preferencesTitle": "Asetukset", + "settings.highContrastMode": "Korkea kontrasti", + "settings.lightMode": "Vaalea tila", + "settings.darkMode": "Tumma tila", + "settings.appVibration": "Sovelluksen värinät", + "settings.showGameDuration": "Näytä pelin kesto", + "settings.accessibility": "Saavutettavuus", + "settings.keyboard": "Näppäimistö", + "settings.confirmSubmition": "Vahvista sanat", + "settings.swapEnterAndBackspace": "Vaihda Enter ja Backspace", + "settings.languageDefault": "kielestä", + "settings.keyboardVibration": "Näppäimistön värinät", + "settings.smallerKeyboard": "Pienempi näppäimistö", + "settings.sourcesTitle": "Lähteet", + "settings.sourcesDescription": "Kaikki tämän sovelluksen käyttämät resurssit ovat vapaan lisenssin alaisia. Kiitokset näiden resurssien luojille.", + "settings.sourcesTitleDictionaries": "Sanakirjat", + "settings.sourcesTitleImages": "Kuvakkeet", + "settings.sourceGithub": "tämän sivuston arkisto", + "settings.sourceDiffle": "alkuperäinen diffle", + "settings.sourceDictionarySpellchecker": "oikeinkirjoituksen tarkistajana", + "settings.sourceDictionaryWiningWords": "voittosanojen etsijänä", + "settings.lastDailyWordsTitle": "Eilisen sana", + "settings.lastDailyWordsYesterday": "Eilinen sana oli \"{{word}}\".", + "settings.lastDailyWordsCanBeWrongBecauseOfUpdate": "Eilinen voittosana voi olla väärin, koska suurempi päivitys julkaistiin.", + "settings.confirmInSeconds_zero": "Klikkaa {{count}} sekunnin kuluttua vahvistaaksesi", + "settings.confirmInSeconds_one": "Klikkaa sekunnin kuluttua vahvistaaksesi", + "settings.confirmInSeconds_few": "Klikkaa {{count}} sekunnin kuluttua vahvistaaksesi", + "settings.confirmInSeconds_many": "Klikkaa {{count}} sekunnin kuluttua vahvistaaksesi", + "settings.confirmInSeconds_other": "Klikkaa {{count}} sekunnin kuluttua vahvistaaksesi", + "settings.confirmAfterWaiting": "Klikkaa vahvistaaksesi", + "settings.language": "Kieli", + "settings.languageChanged": "Kieli on vaihdettu.", + "settings.reportTranslationBug": "Ilmoita käännösvirheestä", + "settings.privacyTitle": "Tietosuoja", + "settings.cookiesTitle": "Evästeet", + "settings.cookiesText1": "Tämä sivusto käyttää selaimesi välimuistia toimiakseen oikein.", + "settings.cookiesText2": "Hyväksymällä \"kaikki\" hyväksyt myös valinnaisen toimintasi seurannan (mukaan lukien Google Analytics).", + "settings.acceptAll": "Hyväksy kaikki", + "settings.acceptOnlyRequired": "Hyväksy vain vaaditut", + "settings.saveSelected": "Tallenna valitut", + "settings.cookiesSavedAndRefresh": "Tallennettu. Sovellus päivittyy.", + "settings.cookiesExternalOptional": "ulkoinen ja valinnainen", + "settings.cookiesLocalRequierd": "paikallinen ja vaadittu", + "share.titleSettings": "Jakaminen", + "share.linkWithUsedWords": "Linkki käytettyihin sanoihin", + "share.linkWithUsedWordsNoSpoilers": "(ilman spoilereita)", + "share.titleSharedResult": "Tulokset jaettu kanssasi", + "share.resultIsBroken": "Valitettavasti tämä linkki on vanhentunut tai rikki.", + "share.resultIsForTheFuture": "Tämä linkki pitäisi toimia pian.", + "share.resultHasExpired": "Valitettavasti tämä linkki on vanhentunut.", + "share.titleUsedWords": "Käytetyt sanat", + "share.dontShowThisResult": "Älä näytä tätä tulosta enää", + "statistics.filters": "Suodattimet", + "statistics.filterAll": "Yhdistä", + "statistics.noData": "Ei tietoja valituille suodattimille.", + "statistics.specialCharactersWithout": "ilman erikoismerkkejä", + "statistics.specialCharactersWith": "erikoismerkkien kanssa", + "statistics.wordLengthShort": "enintään {{to}} merkkiä", + "statistics.wordLengthLong": "yli {{above}} merkkiä", + "statistics.letters": "kirjainta", + "statistics.medianWordsBefore": "keskimäärin", + "statistics.medianWords": "sanaa", + "statistics.median": "mediaani", + "statistics.average": "keskimäärin:", + "statistics.maximum": "maksimi:", + "statistics.averageLetters": "keskimääräinen kirjainten määrä", + "statistics.averageGameTime": "keskimääräinen peliaika", + "statistics.totalGameTime": "kokonaispeliaika", + "statistics.inWord": "sanassa", + "statistics.inFirstWord": "ensimmäisessä sanassa", + "statistics.inSecondWord": "toisessa sanassa", + "statistics.keyboardUsed": "keskimäärin {{value}}% näppäimistöstä käytetty", + "statistics.averageWordsNotFound": "{{value}} sanaa ei löydy sanakirjasta", + "statistics.worstWordsNotFound": "huonoin {{value}} yhdessä pelissä", + "statistics.worstWordsNotFoundLonger": "huonoin sanakirjasta löytymättömien sanojen määrä {{value}} pelissä", + "statistics.totalGames_zero": "{{count}} peliä", + "statistics.totalGames_one": "1 peli", + "statistics.totalGames_few": "{{count}} peliä", + "statistics.totalGames_many": "{{count}} peliä", + "statistics.totalGames_other": "{{count}} peliä", + "statistics.totalWon": "voitettu", + "statistics.totalWonStreak": "peräkkäin voitettu", + "statistics.totalWonStreak_zero": "peräkkäin voitettu", + "statistics.totalWonStreak_one": "peräkkäin voitettu", + "statistics.totalWonStreak_few": "peräkkäin voitettu", + "statistics.totalWonStreak_many": "peräkkäin voitettu", + "statistics.totalLostStreak": "peräkkäin hävitty", + "statistics.totalLostStreak_zero": "peräkkäin hävitty", + "statistics.totalLostStreak_one": "peräkkäin hävitty", + "statistics.totalLostStreak_few": "peräkkäin hävitty", + "statistics.totalLostStreak_many": "peräkkäin hävitty", + "statistics.totalBestStreak": "paras peräkkäin voitettu", + "statistics.streakTooltipWithWorstStreak": "huonoin peräkkäin hävitty:", + "statistics.lettersCorrect": "oikein", + "statistics.lettersPosition": "väärä sijainti", + "statistics.lettersIncorrect": "väärin", + "statistics.lettersIncorrectAndTyped": "väärin kirjoitettu", + "statistics.titleRemoveStatistics": "Poista tilastot", + "statistics.statisticsWasRemoved": "Tilastot poistettiin", + "statistics.wordsWithSpecialCharacters": "Sanat, joissa on erikoismerkkejä", + "statistics.languageTitleHighestLetterForCommon": "Yleisin kirjain", + "statistics.filterCommon": "suosio", + "statistics.languageDescriptionHighestLetterForCommon": "{{maxletter}} esiintyy {{maxLetterValue}} kertaa per sana.", + "statistics.languageTitleHighestLetterForInWords": "Kirjain, joka esiintyy eniten sanoissa", + "statistics.filterInWords": "sanojen määrä", + "statistics.languageDescriptionHighestLetterForInWords": "{{maxletter}} esiintyy {{maxLetterValue}} sanassa.", + "statistics.languageTitleHighestLetterForFirst": "Yleisin ensimmäinen kirjain", + "statistics.filterFirst": "ensimmäinen", + "statistics.languageDescriptionHighestLetterForFirst": "{{maxletter}} on ensimmäinen kirjain {{maxLetterValue}} sanassa.", + "statistics.languageTitleHighestLetterForLast": "Yleisin viimeinen kirjain", + "statistics.filterLast": "viimeinen", + "statistics.languageDescriptionHighestLetterForLast": "{{maxletter}} on viimeinen kirjain {{maxLetterValue}} sanassa.", + "statistics.languageTitleLength": "Kirjainten määrä sanassa", + "statistics.languageDescriptionMostPopularLength": "Suosituin sanan pituus on {{letters}} kirjainta.", + "statistics.languageTitleAtTheBeginning": "Yleisimmin alussa", + "statistics.languageTitleInTheMiddle": "Yleisimmin keskellä", + "statistics.languageTitleInTheEnd": "Yleisimmin lopussa", + "statistics.showOneChartWithFilters": "Yksi kaavio suodattimilla", + "statistics.showTitleWithLanguage": "Näytä kieli otsikossa", + "statistics.basedOn": "{{product}} perustuu {{words}} sanaan lähteestä {{source}}", + "statistics.bestWordleWordTitle": "Paras aloitussana Wordlessa", + "statistics.bestWordleWordExplanation": "Tulos {{words}} sanaa vastaan:", + "statistics.filterWordleLettersTitle": "Käytetyt kirjaimet", + "statistics.filterWordleInWords": "Kirjaimet", + "statistics.filterWordleLetterPosition": "Sijainti (toistot)", + "statistics.filterWordleUniqueLetterPosition": "Sijainti", + "statistics.filterWordleMaxTitle": "Maksimoi värit", + "statistics.filterBestMaxGreen": "Vihreä", + "statistics.filterBestMax": "Värit", + "statistics.filterBestMaxOrange": "Oranssi", + "statistics.filterBestMaxGray": "Harmaa", + "statistics.filterWordleBestTitle": "Väritasapaino", + "statistics.filterBestGreen1_5": "1,5 × vihreä + 1 × keltainen", + "statistics.filterBestGreen2_0": "2 × vihreä + 1 × keltainen", + "statistics.bestWordleWordPopularLettersTitle": "Suosituimmat kirjaimet tietyssä asemassa" +} diff --git a/src/locales/fr.json b/src/locales/fr.json index 5a98a69bd..3a58aa03b 100644 --- a/src/locales/fr.json +++ b/src/locales/fr.json @@ -1,271 +1,276 @@ { - "seo.pageTitle": "DIFFLE - le jeu similaire à Wordle (en français, sans limite de caractères) 🇫🇷", - "seo.metaDescription": "Chaque mot utilisé fournit des indices sur la position et l'ordre des lettres dans la solution.", - "seo.openGraphTitle": "DIFFLE - le jeu similaire à Wordle (en français, sans limite de caractères) 🇫🇷", - "seo.openGraphDescription": "Chaque mot utilisé fournit des indices sur la position et l'ordre des lettres dans la solution.", - "common.yes": "Oui", - "common.no": "Non", - "common.play": "Jouer", - "common.newGame": "Nouveau jeu", - "common.copyResult": "Copier le résultat", - "common.copyResultLink": "Seulement copier lien", - "common.copyLink": "Copier le lien", - "common.copied": "Copié.", - "common.checkInDictionary": "Rechercher \"{{word}}\"", - "common.checkInDictionaryWithName": "Rechercher \"{{word}}\" sur {{name}}", - "common.dictionaryIsNotExactMatch": "Le dictionnaire des mots gagnants n'a pas de version en ligne facilement accessible, vous pouvez donc essayer l'un de ces dictionnaires.", - "common.close": "Fermer", - "common.more": "plus", - "common.download": "Télécharger", - "common.downloadError": "Une erreur de récupération.", - "common.fetchError": "Une erreur de récupération, veuillez réessayer.", - "common.unknownError": "Une erreur inconnue s'est produite.", - "common.serviceMode": "Maintenance du service {{today}}.", - "common.serviceModeWeReturnSoon": "\"De retour en action demain !", - "language.currentLanguage": "Français", - "language.cs": "Tchèque", - "language.de": "Allemand", - "language.en": "Anglais", - "language.es": "Espagnol", - "language.fi": "Finnois", - "language.fr": "Français", - "language.it": "Italien", - "language.pl": "Polonais", - "game.modeDaily": "Quotidien", - "game.modePractice": "Pratique", - "game.modeShare": "Partagé", - "game.iGiveUp": "J'abandonne", - "game.dailyGameLostToast": "Partie perdue depuis le {{dailyStamp}}, le mot gagnant était \"{{word}}\"", - "game.givingUpIsNotPossible": "Commencez une partie pour pouvoir abandonner ;)", - "game.confirmCheckTheWord": "Est-ce que \"{{word}}\" va bien ?", - "game.wordToSubmitIsMissing": "Devrions-nous vérifier le mot ?", - "game.checking": "vérification...", - "game.withSpecialCharacters": "Le mot gagnant contient au moins un caractère {{specialCharacter}}.", - "game.withoutSpecialCharacters": "Le mot gagnant ne contient pas de caractères {{specialCharacters}}.", - "game.csSpecialCharacter": "spéciaux", - "game.csSpecialCharacters": "spéciaux", - "game.deSpecialCharacter": "spéciaux", - "game.deSpecialCharacters": "spéciaux", - "game.esSpecialCharacter": "spéciaux", - "game.esSpecialCharacters": "spéciaux", - "game.fiSpecialCharacter": "spéciaux", - "game.fiSpecialCharacters": "spéciaux", - "game.frSpecialCharacter": "spéciaux", - "game.frSpecialCharacters": "spéciaux", - "game.itSpecialCharacter": "spéciaux", - "game.itSpecialCharacters": "spéciaux", - "game.plSpecialCharacter": "spéciaux", - "game.plSpecialCharacters": "spéciaux", - "game.youCanUseThisWordButNotWin": "Vous pouvez utiliser ce mot, mais vous ne pouvez pas gagner avec.", - "game.youCanUseIncorrectLetters": "(lettre incorrecte saisie", - "game.youCanUseLettersTypedTooManyTimes": "lettre correcte utilisée trop de fois", - "game.youCanUseSpace": "Les mots n'ont pas d'espaces, mais vous pouvez les utiliser, ils seront supprimés.", - "game.youCanUseIncorrectStart": "début de mot incorrect", - "game.youCanUseIncorrectEnd": "fin de mot incorrecte", - "game.youCanUseIncorrectMiddle": "certaines lettres doivent être côte à côte", - "game.youCanUseIncorrectOrder": "certaines lettres sont dans le mauvais ordre", - "game.spacesRemoved": "Les espaces ont été supprimés.", - "game.isNotInDictionary": "Mot non trouvé dans le dictionnaire.", - "game.wordAlreadyUsed": "Le mot a déjà été utilisé.", - "game.restoreError": "L'erreur s'est produite lors de la restauration de l'état du jeu.", - "help.title": "Aide", - "help.howToPlayTitle": "Comment jouer ?", - "help.howToPlayText1": "Devinez le mot en utilisant le moins de lettres possible.", - "help.howToPlayText2": "Une fois que vous avez fait de votre mieux pour deviner, les couleurs des lettres changent pour vous indiquer à quel point vous vous rapprochez ou vous éloignez du mot.", - "help.exampleTitle": "Un exemple", - "help.exampleTitleAlt": "Un exemple différent", - "help.incorrectLettersTip": "Les lettres grises ne sont pas dans le mot.", - "help.correctLetters": "Les lettres {{correct1}} et {{correct2}} sont dans le mot dans cet ordre.", - "help.positionBefore": "La lettre {{position}} est dans le mot mais pas avant la lettre {{closestCorrect}}.", - "help.positionBetween": "La lettre {{position}} mais pas entre elles.", - "help.positionAfter": "La lettre {{position}} est dans le mot mais pas après la lettre {{closestCorrect}}.", - "help.inRow": "Les lettres {{letters}} sont dans le mot consécutivement.", - "help.firstAndLast": "Le mot commence par {{first}} et se termine par {{last}}.", - "help.winingWordMessage": "Ceci est le mot réponse.", - "help.previousExample": "Exemple précédent", - "help.altExample": "Un autre exemple ?", - "help.whatIsDiffleTitle": "Qu'est-ce que Diffle ?", - "help.whatIsDiffleDescription": "Diffle est un jeu inspiré de Wordle sans limite de caractères. Si vous aimez Wordle, ce jeu est fait pour vous.", - "help.gameRules": "Règles du jeu", - "end.titleWon": "Succès", - "end.titleLost": "Défaite", - "end.titleCheater": "Un clairvoyant", - "end.winningWord": "La réponse :", - "end.wordsUsed_zero": "mots", - "end.wordsUsed_one": "mot", - "end.wordsUsed_few": "mots", - "end.wordsUsed_many": "mots", - "end.wordsUsed_other": "mots", - "end.inWordsUsed_zero": "mots", - "end.inWordsUsed_one": "mot", - "end.inWordsUsed_few": "mots", - "end.inWordsUsed_many": "mots", - "end.inWordsUsed_other": "mots", - "end.in_zero": "en", - "end.in_one": "en", - "end.in_few": "en", - "end.in_many": "en", - "end.in_other": "en", - "end.lostIn": "défaite", - "end.lettersUsedShort": "l.", - "end.lettersUsed_zero": "lettres", - "end.lettersUsed_one": "lettre", - "end.lettersUsed_few": "lettres", - "end.lettersUsed_many": "lettres", - "end.lettersUsed_other": "lettres", - "end.nextDailyHours_zero": "Le nouveau mot quotidien sera disponible dans {{count}} heures.", - "end.nextDailyHours_one": "Le nouveau mot quotidien sera disponible dans une heure.", - "end.nextDailyHours_few": "Le nouveau mot quotidien sera disponible dans {{count}} heures.", - "end.nextDailyHours_many": "Le nouveau mot quotidien sera disponible dans {{count}} heures.", - "end.nextDailyHours_other": "Le nouveau mot quotidien sera disponible dans {{count}} heures.", - "end.nextDailyShort": "suivant dans {{count}}h", - "end.completed": "terminé", - "end.gameDuration": "Durée du jeu", - "settings.title": "Paramétrage", - "settings.inDevelopment": "En développement", - "settings.inBetaNow": "Bêta", - "settings.onlyIn": "Uniquement en", - "settings.considered": "Considéré", - "settings.statisticsTitle": "Statistiques", - "settings.gameModeTitle": "Modes de jeu", - "settings.labelFinishGame": "Terminer", - "settings.labelFinishGameLonger": "Devinez le mot de passe d'aujourd'hui pour déverrouiller.", - "settings.labelYouCanSeeSharedWords": "Vous avez deviné le mot de passe d'aujourd'hui, donc vous pouvez les voir.", - "settings.preferencesTitle": "Préférences", - "settings.highContrastMode": "Contraste élevé", - "settings.lightMode": "Mode Clair", - "settings.darkMode": "Mode sombre", - "settings.appVibration": "Vibrations app", - "settings.showGameDuration": "Afficher la durée du jeu", - "settings.accessibility": "Accessibilité", - "settings.keyboard": "Clavier", - "settings.confirmSubmition": "Confirmer les mots", - "settings.swapEnterAndBackspace": "Échanger Retour / Entrée", - "settings.languageDefault": "de la langue", - "settings.keyboardVibration": "Vibrations clavier", - "settings.smallerKeyboard": "Petit clavier", - "settings.sourcesTitle": "Sources", - "settings.sourcesDescription": "Toutes les ressources utilisées par cette application sont sous licence libre. Bravo aux créateurs de ces ressources.", - "settings.sourcesTitleDictionaries": "Dictionnaires", - "settings.sourcesTitleImages": "Icônes", - "settings.sourceGithub": "le dépôt de ce site", - "settings.sourceDiffle": "diffle d'origine", - "settings.sourceDictionarySpellchecker": "- correcteur orthographique", - "settings.sourceDictionaryWiningWords": "- chercheur de mots gagnants", - "settings.lastDailyWordsTitle": "Mot d'hier", - "settings.lastDailyWordsYesterday": "Le mot d'hier était \"{{word}}\".", - "settings.lastDailyWordsCanBeWrongBecauseOfUpdate": "Le mot gagnant d'hier pourrait être incorrect car une mise à jour plus importante a été publiée.", - "settings.confirmInSeconds_zero": "Cliquez dans {{count}} secondes pour confirmer", - "settings.confirmInSeconds_one": "Cliquez dans une seconde pour confirmer", - "settings.confirmInSeconds_few": "Cliquez dans {{count}} secondes pour confirmer", - "settings.confirmInSeconds_many": "Cliquez dans {{count}} secondes pour confirmer", - "settings.confirmInSeconds_other": "Cliquez dans {{count}} secondes pour confirmer", - "settings.confirmAfterWaiting": "Cliquez pour confirmer", - "settings.language": "Langue", - "settings.languageChanged": "La langue a été changée.", - "settings.reportTranslationBug": "Signaler un bug de traduction", - "settings.privacyTitle": "Confidentialité", - "settings.cookiesTitle": "Cookies", - "settings.cookiesText1": "Ce site utilise le cache de votre navigateur pour fonctionner correctement.", - "settings.cookiesText2": "En acceptant \"tout\", vous consentez également au suivi facultatif de votre activité (y compris Google Analytics).", - "settings.acceptAll": "Accepter tout", - "settings.acceptOnlyRequired": "Accepter nécessaire", - "settings.saveSelected": "Enregistrer la sélection", - "settings.cookiesSavedAndRefresh": "Enregistré. L'application sera actualisée.", - "settings.cookiesExternalOptional": "externe et facultatif", - "settings.cookiesLocalRequierd": "local et nécessaire", - "share.titleSettings": "Partage", - "share.linkWithUsedWords": "Lien mots utilisés", - "share.linkWithUsedWordsNoSpoilers": "(sans spoilers)", - "share.titleSharedResult": "Résultat partagé avec vous", - "share.resultIsBroken": "Malheureusement, ce lien a expiré ou est cassé.", - "share.resultIsForTheFuture": "Ce lien devrait fonctionner bientôt.", - "share.resultHasExpired": "Malheureusement, ce lien a expiré.", - "share.titleUsedWords": "Mots utilisés", - "share.dontShowThisResult": "Ne plus afficher ce résultat", - "statistics.filters": "Filtres", - "statistics.filterAll": "Regrouper", - "statistics.noData": "Aucune donnée pour les filtres sélectionnés.", - "statistics.specialCharactersWithout": "sans caractères spéciaux", - "statistics.specialCharactersWith": "avec caractères spéciaux", - "statistics.wordLengthShort": "jusqu'à {{to}} caractères", - "statistics.wordLengthLong": "plus de {{above}} caractères", - "statistics.letters": "lettres", - "statistics.medianWordsBefore": "en", - "statistics.medianWords": "mots", - "statistics.median": "médiane", - "statistics.average": "moyenne :", - "statistics.maximum": "maximum :", - "statistics.averageLetters": "moyenne de lettres", - "statistics.averageGameTime": "temps de jeu moyen", - "statistics.totalGameTime": "temps total de jeu", - "statistics.inWord": "dans mot", - "statistics.inFirstWord": "dans le premier mot", - "statistics.inSecondWord": "dans le deuxième mot", - "statistics.keyboardUsed": "moyenne {{value}}% du clavier utilisée", - "statistics.averageWordsNotFound": "{{value}} mots non trouvés dans un dictionnaire", - "statistics.worstWordsNotFound": "pire {{value}} en une partie", - "statistics.worstWordsNotFoundLonger": "les pires mots non trouvés dans un dictionnaire {{value}} dans un jeu", - "statistics.totalGames_zero": "{{count}} parties", - "statistics.totalGames_one": "1 partie", - "statistics.totalGames_few": "{{count}} parties", - "statistics.totalGames_many": "{{count}} parties", - "statistics.totalGames_other": "{{count}} parties", - "statistics.totalWon": "gagnées", - "statistics.totalWonStreak": "gagnées d'affilée", - "statistics.totalWonStreak_zero": "gagnées d'affilée", - "statistics.totalWonStreak_one": "gagnée d'affilée", - "statistics.totalWonStreak_few": "gagnées d'affilée", - "statistics.totalWonStreak_many": "gagnées d'affilée", - "statistics.totalLostStreak": "perdues d'affilée", - "statistics.totalLostStreak_zero": "perdues d'affilée", - "statistics.totalLostStreak_one": "perdue d'affilée", - "statistics.totalLostStreak_few": "perdues d'affilée", - "statistics.totalLostStreak_many": "perdues d'affilée", - "statistics.totalBestStreak": "meilleure série gagnante d'affilée", - "statistics.streakTooltipWithWorstStreak": "le pire perdu d'affilée :", - "statistics.lettersCorrect": "correctes", - "statistics.lettersPosition": "mauvaise position", - "statistics.lettersIncorrect": "incorrectes", - "statistics.lettersIncorrectAndTyped": "tapées incorrectes", - "statistics.titleRemoveStatistics": "Supprimer les statistiques", - "statistics.statisticsWasRemoved": "Les statistiques ont été supprimées", - "statistics.wordsWithSpecialCharacters": "Mots avec des caractères spéciaux", - "statistics.languageTitleHighestLetterForCommon": "La lettre la plus populaire", - "statistics.filterCommon": "popularité", - "statistics.languageDescriptionHighestLetterForCommon": "{{maxletter}} apparaît {{maxLetterValue}} fois par mot.", - "statistics.languageTitleHighestLetterForInWords": "Lettre dans le plus grand nombre de mots", - "statistics.filterInWords": "nombre de mots", - "statistics.languageDescriptionHighestLetterForInWords": "{{maxletter}} apparaît dans {{maxLetterValue}} mots.", - "statistics.languageTitleHighestLetterForFirst": "Lettre initiale la plus courante", - "statistics.filterFirst": "première", - "statistics.languageDescriptionHighestLetterForFirst": "{{maxletter}} est la première lettre dans {{maxLetterValue}} mots.", - "statistics.languageTitleHighestLetterForLast": "Lettre finale la plus courante", - "statistics.filterLast": "dernière", - "statistics.languageDescriptionHighestLetterForLast": "{{maxletter}} est la dernière lettre dans {{maxLetterValue}} mots.", - "statistics.languageTitleLength": "Nombre de lettres dans un mot", - "statistics.languageDescriptionMostPopularLength": "La longueur de mot la plus populaire est de {{letters}} lettres.", - "statistics.languageTitleAtTheBeginning": "Le plus souvent au début", - "statistics.languageTitleInTheMiddle": "Le plus souvent au milieu", - "statistics.languageTitleInTheEnd": "Le plus souvent à la fin", - "statistics.showOneChartWithFilters": "Un graphique avec des filtres", - "statistics.showTitleWithLanguage": "Afficher le titre de la langue", - "statistics.basedOn": "{{product}} basé sur {{words}} mots provenant de {{source}}", - "statistics.bestWordleWordTitle": "Meilleur mot de départ dans Wordle", - "statistics.bestWordleWordExplanation": "Résultat contre {{words}} mots :", - "statistics.filterWordleLettersTitle": "Utilisation des lettres", - "statistics.filterWordleInWords": "Lettres", - "statistics.filterWordleLetterPosition": "Position (répétitions)", - "statistics.filterWordleUniqueLetterPosition": "Position unique", - "statistics.filterWordleMaxTitle": "Maximiser les couleurs", - "statistics.filterBestMaxGreen": "Vert", - "statistics.filterBestMax": "Couleurs", - "statistics.filterBestMaxOrange": "Jaune", - "statistics.filterBestMaxGray": "Gris", - "statistics.filterWordleBestTitle": "Équilibre des couleurs", - "statistics.filterBestGreen1_5": "1,5 × vert + 1 × jaune", - "statistics.filterBestGreen2_0": "2 × vert + 1 × jaune", - "statistics.bestWordleWordPopularLettersTitle": "Lettres les plus populaires à chaque position donnée", - "feature.specialWord.wasActivated": "Le mot spécial a été activé !", - "feature.specialWord.wasDeactivated": "Le mot spécial a été désactivé !" -} \ No newline at end of file + "route.help": "aide", + "route.settings": "parametres", + "route.statistics": "tes-statistiques", + "route.aboutLanguage": "a-propos-de-la-langue", + "route.hejto2024": "hejto-2024", + "route.game.title": "DIFFLE - le jeu similaire à Wordle (en français, sans limite de caractères) 🇫🇷", + "route.game.metaDescription": "Chaque mot utilisé fournit des indices sur la position et l'ordre des lettres dans la solution.", + "route.game.openGraphTitle": "DIFFLE - le jeu similaire à Wordle (en français, sans limite de caractères) 🇫🇷", + "route.game.openGraphDescription": "Chaque mot utilisé fournit des indices sur la position et l'ordre des lettres dans la solution.", + "common.yes": "Oui", + "common.no": "Non", + "common.play": "Jouer", + "common.newGame": "Nouveau jeu", + "common.copyResult": "Copier le résultat", + "common.copyResultLink": "Seulement copier lien", + "common.copyLink": "Copier le lien", + "common.copied": "Copié.", + "common.checkInDictionary": "Rechercher \"{{word}}\"", + "common.checkInDictionaryWithName": "Rechercher \"{{word}}\" sur {{name}}", + "common.dictionaryIsNotExactMatch": "Le dictionnaire des mots gagnants n'a pas de version en ligne facilement accessible, vous pouvez donc essayer l'un de ces dictionnaires.", + "common.close": "Fermer", + "common.more": "plus", + "common.download": "Télécharger", + "common.downloadError": "Une erreur de récupération.", + "common.fetchError": "Une erreur de récupération, veuillez réessayer.", + "common.unknownError": "Une erreur inconnue s'est produite.", + "common.serviceMode": "Maintenance du service {{today}}.", + "common.serviceModeWeReturnSoon": "\"De retour en action demain !", + "language.currentLanguage": "Français", + "language.cs": "Tchèque", + "language.de": "Allemand", + "language.en": "Anglais", + "language.es": "Espagnol", + "language.fi": "Finnois", + "language.fr": "Français", + "language.it": "Italien", + "language.pl": "Polonais", + "game.modeDaily": "Quotidien", + "game.modePractice": "Pratique", + "game.modeShare": "Partagé", + "game.iGiveUp": "J'abandonne", + "game.dailyGameLostToast": "Partie perdue depuis le {{dailyStamp}}, le mot gagnant était \"{{word}}\"", + "game.givingUpIsNotPossible": "Commencez une partie pour pouvoir abandonner ;)", + "game.confirmCheckTheWord": "Est-ce que \"{{word}}\" va bien ?", + "game.wordToSubmitIsMissing": "Devrions-nous vérifier le mot ?", + "game.checking": "vérification...", + "game.withSpecialCharacters": "Le mot gagnant contient au moins un caractère {{specialCharacter}}.", + "game.withoutSpecialCharacters": "Le mot gagnant ne contient pas de caractères {{specialCharacters}}.", + "game.csSpecialCharacter": "spéciaux", + "game.csSpecialCharacters": "spéciaux", + "game.deSpecialCharacter": "spéciaux", + "game.deSpecialCharacters": "spéciaux", + "game.esSpecialCharacter": "spéciaux", + "game.esSpecialCharacters": "spéciaux", + "game.fiSpecialCharacter": "spéciaux", + "game.fiSpecialCharacters": "spéciaux", + "game.frSpecialCharacter": "spéciaux", + "game.frSpecialCharacters": "spéciaux", + "game.itSpecialCharacter": "spéciaux", + "game.itSpecialCharacters": "spéciaux", + "game.plSpecialCharacter": "spéciaux", + "game.plSpecialCharacters": "spéciaux", + "game.youCanUseThisWordButNotWin": "Vous pouvez utiliser ce mot, mais vous ne pouvez pas gagner avec.", + "game.youCanUseIncorrectLetters": "(lettre incorrecte saisie", + "game.youCanUseLettersTypedTooManyTimes": "lettre correcte utilisée trop de fois", + "game.youCanUseSpace": "Les mots n'ont pas d'espaces, mais vous pouvez les utiliser, ils seront supprimés.", + "game.youCanUseIncorrectStart": "début de mot incorrect", + "game.youCanUseIncorrectEnd": "fin de mot incorrecte", + "game.youCanUseIncorrectMiddle": "certaines lettres doivent être côte à côte", + "game.youCanUseIncorrectOrder": "certaines lettres sont dans le mauvais ordre", + "game.spacesRemoved": "Les espaces ont été supprimés.", + "game.isNotInDictionary": "Mot non trouvé dans le dictionnaire.", + "game.wordAlreadyUsed": "Le mot a déjà été utilisé.", + "game.restoreError": "L'erreur s'est produite lors de la restauration de l'état du jeu.", + "help.title": "Aide", + "help.howToPlayTitle": "Comment jouer ?", + "help.howToPlayText1": "Devinez le mot en utilisant le moins de lettres possible.", + "help.howToPlayText2": "Une fois que vous avez fait de votre mieux pour deviner, les couleurs des lettres changent pour vous indiquer à quel point vous vous rapprochez ou vous éloignez du mot.", + "help.exampleTitle": "Un exemple", + "help.exampleTitleAlt": "Un exemple différent", + "help.incorrectLettersTip": "Les lettres grises ne sont pas dans le mot.", + "help.correctLetters": "Les lettres {{correct1}} et {{correct2}} sont dans le mot dans cet ordre.", + "help.positionBefore": "La lettre {{position}} est dans le mot mais pas avant la lettre {{closestCorrect}}.", + "help.positionBetween": "La lettre {{position}} mais pas entre elles.", + "help.positionAfter": "La lettre {{position}} est dans le mot mais pas après la lettre {{closestCorrect}}.", + "help.inRow": "Les lettres {{letters}} sont dans le mot consécutivement.", + "help.firstAndLast": "Le mot commence par {{first}} et se termine par {{last}}.", + "help.winingWordMessage": "Ceci est le mot réponse.", + "help.previousExample": "Exemple précédent", + "help.altExample": "Un autre exemple ?", + "help.whatIsDiffleTitle": "Qu'est-ce que Diffle ?", + "help.whatIsDiffleDescription": "Diffle est un jeu inspiré de Wordle sans limite de caractères. Si vous aimez Wordle, ce jeu est fait pour vous.", + "help.gameRules": "Règles du jeu", + "end.titleWon": "Succès", + "end.titleLost": "Défaite", + "end.titleCheater": "Un clairvoyant", + "end.winningWord": "La réponse :", + "end.wordsUsed_zero": "mots", + "end.wordsUsed_one": "mot", + "end.wordsUsed_few": "mots", + "end.wordsUsed_many": "mots", + "end.wordsUsed_other": "mots", + "end.inWordsUsed_zero": "mots", + "end.inWordsUsed_one": "mot", + "end.inWordsUsed_few": "mots", + "end.inWordsUsed_many": "mots", + "end.inWordsUsed_other": "mots", + "end.in_zero": "en", + "end.in_one": "en", + "end.in_few": "en", + "end.in_many": "en", + "end.in_other": "en", + "end.lostIn": "défaite", + "end.lettersUsedShort": "l.", + "end.lettersUsed_zero": "lettres", + "end.lettersUsed_one": "lettre", + "end.lettersUsed_few": "lettres", + "end.lettersUsed_many": "lettres", + "end.lettersUsed_other": "lettres", + "end.nextDailyHours_zero": "Le nouveau mot quotidien sera disponible dans {{count}} heures.", + "end.nextDailyHours_one": "Le nouveau mot quotidien sera disponible dans une heure.", + "end.nextDailyHours_few": "Le nouveau mot quotidien sera disponible dans {{count}} heures.", + "end.nextDailyHours_many": "Le nouveau mot quotidien sera disponible dans {{count}} heures.", + "end.nextDailyHours_other": "Le nouveau mot quotidien sera disponible dans {{count}} heures.", + "end.nextDailyShort": "suivant dans {{count}}h", + "end.completed": "terminé", + "end.gameDuration": "Durée du jeu", + "settings.title": "Paramétrage", + "settings.inDevelopment": "En développement", + "settings.inBetaNow": "Bêta", + "settings.onlyIn": "Uniquement en", + "settings.considered": "Considéré", + "settings.statisticsTitle": "Statistiques", + "settings.gameModeTitle": "Modes de jeu", + "settings.labelFinishGame": "Terminer", + "settings.labelFinishGameLonger": "Devinez le mot de passe d'aujourd'hui pour déverrouiller.", + "settings.labelYouCanSeeSharedWords": "Vous avez deviné le mot de passe d'aujourd'hui, donc vous pouvez les voir.", + "settings.preferencesTitle": "Préférences", + "settings.highContrastMode": "Contraste élevé", + "settings.lightMode": "Mode Clair", + "settings.darkMode": "Mode sombre", + "settings.appVibration": "Vibrations app", + "settings.showGameDuration": "Afficher la durée du jeu", + "settings.accessibility": "Accessibilité", + "settings.keyboard": "Clavier", + "settings.confirmSubmition": "Confirmer les mots", + "settings.swapEnterAndBackspace": "Échanger Retour / Entrée", + "settings.languageDefault": "de la langue", + "settings.keyboardVibration": "Vibrations clavier", + "settings.smallerKeyboard": "Petit clavier", + "settings.sourcesTitle": "Sources", + "settings.sourcesDescription": "Toutes les ressources utilisées par cette application sont sous licence libre. Bravo aux créateurs de ces ressources.", + "settings.sourcesTitleDictionaries": "Dictionnaires", + "settings.sourcesTitleImages": "Icônes", + "settings.sourceGithub": "le dépôt de ce site", + "settings.sourceDiffle": "diffle d'origine", + "settings.sourceDictionarySpellchecker": "- correcteur orthographique", + "settings.sourceDictionaryWiningWords": "- chercheur de mots gagnants", + "settings.lastDailyWordsTitle": "Mot d'hier", + "settings.lastDailyWordsYesterday": "Le mot d'hier était \"{{word}}\".", + "settings.lastDailyWordsCanBeWrongBecauseOfUpdate": "Le mot gagnant d'hier pourrait être incorrect car une mise à jour plus importante a été publiée.", + "settings.confirmInSeconds_zero": "Cliquez dans {{count}} secondes pour confirmer", + "settings.confirmInSeconds_one": "Cliquez dans une seconde pour confirmer", + "settings.confirmInSeconds_few": "Cliquez dans {{count}} secondes pour confirmer", + "settings.confirmInSeconds_many": "Cliquez dans {{count}} secondes pour confirmer", + "settings.confirmInSeconds_other": "Cliquez dans {{count}} secondes pour confirmer", + "settings.confirmAfterWaiting": "Cliquez pour confirmer", + "settings.language": "Langue", + "settings.languageChanged": "La langue a été changée.", + "settings.reportTranslationBug": "Signaler un bug de traduction", + "settings.privacyTitle": "Confidentialité", + "settings.cookiesTitle": "Cookies", + "settings.cookiesText1": "Ce site utilise le cache de votre navigateur pour fonctionner correctement.", + "settings.cookiesText2": "En acceptant \"tout\", vous consentez également au suivi facultatif de votre activité (y compris Google Analytics).", + "settings.acceptAll": "Accepter tout", + "settings.acceptOnlyRequired": "Accepter nécessaire", + "settings.saveSelected": "Enregistrer la sélection", + "settings.cookiesSavedAndRefresh": "Enregistré. L'application sera actualisée.", + "settings.cookiesExternalOptional": "externe et facultatif", + "settings.cookiesLocalRequierd": "local et nécessaire", + "share.titleSettings": "Partage", + "share.linkWithUsedWords": "Lien mots utilisés", + "share.linkWithUsedWordsNoSpoilers": "(sans spoilers)", + "share.titleSharedResult": "Résultat partagé avec vous", + "share.resultIsBroken": "Malheureusement, ce lien a expiré ou est cassé.", + "share.resultIsForTheFuture": "Ce lien devrait fonctionner bientôt.", + "share.resultHasExpired": "Malheureusement, ce lien a expiré.", + "share.titleUsedWords": "Mots utilisés", + "share.dontShowThisResult": "Ne plus afficher ce résultat", + "statistics.filters": "Filtres", + "statistics.filterAll": "Regrouper", + "statistics.noData": "Aucune donnée pour les filtres sélectionnés.", + "statistics.specialCharactersWithout": "sans caractères spéciaux", + "statistics.specialCharactersWith": "avec caractères spéciaux", + "statistics.wordLengthShort": "jusqu'à {{to}} caractères", + "statistics.wordLengthLong": "plus de {{above}} caractères", + "statistics.letters": "lettres", + "statistics.medianWordsBefore": "en", + "statistics.medianWords": "mots", + "statistics.median": "médiane", + "statistics.average": "moyenne :", + "statistics.maximum": "maximum :", + "statistics.averageLetters": "moyenne de lettres", + "statistics.averageGameTime": "temps de jeu moyen", + "statistics.totalGameTime": "temps total de jeu", + "statistics.inWord": "dans mot", + "statistics.inFirstWord": "dans le premier mot", + "statistics.inSecondWord": "dans le deuxième mot", + "statistics.keyboardUsed": "moyenne {{value}}% du clavier utilisée", + "statistics.averageWordsNotFound": "{{value}} mots non trouvés dans un dictionnaire", + "statistics.worstWordsNotFound": "pire {{value}} en une partie", + "statistics.worstWordsNotFoundLonger": "les pires mots non trouvés dans un dictionnaire {{value}} dans un jeu", + "statistics.totalGames_zero": "{{count}} parties", + "statistics.totalGames_one": "1 partie", + "statistics.totalGames_few": "{{count}} parties", + "statistics.totalGames_many": "{{count}} parties", + "statistics.totalGames_other": "{{count}} parties", + "statistics.totalWon": "gagnées", + "statistics.totalWonStreak": "gagnées d'affilée", + "statistics.totalWonStreak_zero": "gagnées d'affilée", + "statistics.totalWonStreak_one": "gagnée d'affilée", + "statistics.totalWonStreak_few": "gagnées d'affilée", + "statistics.totalWonStreak_many": "gagnées d'affilée", + "statistics.totalLostStreak": "perdues d'affilée", + "statistics.totalLostStreak_zero": "perdues d'affilée", + "statistics.totalLostStreak_one": "perdue d'affilée", + "statistics.totalLostStreak_few": "perdues d'affilée", + "statistics.totalLostStreak_many": "perdues d'affilée", + "statistics.totalBestStreak": "meilleure série gagnante d'affilée", + "statistics.streakTooltipWithWorstStreak": "le pire perdu d'affilée :", + "statistics.lettersCorrect": "correctes", + "statistics.lettersPosition": "mauvaise position", + "statistics.lettersIncorrect": "incorrectes", + "statistics.lettersIncorrectAndTyped": "tapées incorrectes", + "statistics.titleRemoveStatistics": "Supprimer les statistiques", + "statistics.statisticsWasRemoved": "Les statistiques ont été supprimées", + "statistics.wordsWithSpecialCharacters": "Mots avec des caractères spéciaux", + "statistics.languageTitleHighestLetterForCommon": "La lettre la plus populaire", + "statistics.filterCommon": "popularité", + "statistics.languageDescriptionHighestLetterForCommon": "{{maxletter}} apparaît {{maxLetterValue}} fois par mot.", + "statistics.languageTitleHighestLetterForInWords": "Lettre dans le plus grand nombre de mots", + "statistics.filterInWords": "nombre de mots", + "statistics.languageDescriptionHighestLetterForInWords": "{{maxletter}} apparaît dans {{maxLetterValue}} mots.", + "statistics.languageTitleHighestLetterForFirst": "Lettre initiale la plus courante", + "statistics.filterFirst": "première", + "statistics.languageDescriptionHighestLetterForFirst": "{{maxletter}} est la première lettre dans {{maxLetterValue}} mots.", + "statistics.languageTitleHighestLetterForLast": "Lettre finale la plus courante", + "statistics.filterLast": "dernière", + "statistics.languageDescriptionHighestLetterForLast": "{{maxletter}} est la dernière lettre dans {{maxLetterValue}} mots.", + "statistics.languageTitleLength": "Nombre de lettres dans un mot", + "statistics.languageDescriptionMostPopularLength": "La longueur de mot la plus populaire est de {{letters}} lettres.", + "statistics.languageTitleAtTheBeginning": "Le plus souvent au début", + "statistics.languageTitleInTheMiddle": "Le plus souvent au milieu", + "statistics.languageTitleInTheEnd": "Le plus souvent à la fin", + "statistics.showOneChartWithFilters": "Un graphique avec des filtres", + "statistics.showTitleWithLanguage": "Afficher le titre de la langue", + "statistics.basedOn": "{{product}} basé sur {{words}} mots provenant de {{source}}", + "statistics.bestWordleWordTitle": "Meilleur mot de départ dans Wordle", + "statistics.bestWordleWordExplanation": "Résultat contre {{words}} mots :", + "statistics.filterWordleLettersTitle": "Utilisation des lettres", + "statistics.filterWordleInWords": "Lettres", + "statistics.filterWordleLetterPosition": "Position (répétitions)", + "statistics.filterWordleUniqueLetterPosition": "Position unique", + "statistics.filterWordleMaxTitle": "Maximiser les couleurs", + "statistics.filterBestMaxGreen": "Vert", + "statistics.filterBestMax": "Couleurs", + "statistics.filterBestMaxOrange": "Jaune", + "statistics.filterBestMaxGray": "Gris", + "statistics.filterWordleBestTitle": "Équilibre des couleurs", + "statistics.filterBestGreen1_5": "1,5 × vert + 1 × jaune", + "statistics.filterBestGreen2_0": "2 × vert + 1 × jaune", + "statistics.bestWordleWordPopularLettersTitle": "Lettres les plus populaires à chaque position donnée", + "feature.specialWord.wasActivated": "Le mot spécial a été activé !", + "feature.specialWord.wasDeactivated": "Le mot spécial a été désactivé !" +} diff --git a/src/locales/it.json b/src/locales/it.json index 7d6b56949..70f3f9763 100644 --- a/src/locales/it.json +++ b/src/locales/it.json @@ -1,271 +1,276 @@ { - "seo.pageTitle": "DIFFLE - il gioco simile a Wordle (senza limite di caratteri)", - "seo.metaDescription": "Ogni parola utilizzata fornisce suggerimenti sulla posizione e sull'ordine delle lettere nella soluzione.", - "seo.openGraphTitle": "DIFFLE - il gioco simile a Wordle (senza limite di caratteri)", - "seo.openGraphDescription": "Ogni parola utilizzata fornisce suggerimenti sulla posizione e sull'ordine delle lettere nella soluzione.", - "common.yes": "Si", - "common.no": "No", - "common.play": "Inizia", - "common.newGame": "Nuovo gioco", - "common.copyResult": "Risultato copiato", - "common.copyResultLink": "Solo copia il link", - "common.copyLink": "Link da copiare", - "common.copied": "Copiato.", - "common.checkInDictionary": "Ricerca di \"{{word}}\"", - "common.checkInDictionaryWithName": "Ricerca di \"{{word}}\" in {{name}}", - "common.dictionaryIsNotExactMatch": "Il dizionario delle parole vincenti non ha una versione online facilmente accessibile, quindi puoi provare uno di quei dizionari.", - "common.close": "Chiudi", - "common.more": "altro", - "common.download": "Scarica", - "common.downloadError": "Un errore di caricamento.", - "common.fetchError": "Un errore di caricamento, riprova.", - "common.unknownError": "Si è verificato un errore sconosciuto.", - "common.serviceMode": "Manutenzione del servizio {{today}}.", - "common.serviceModeWeReturnSoon": "Di nuovo operativo domani!", - "language.currentLanguage": "Italiano", - "language.cs": "Ceco", - "language.de": "Tedesco", - "language.en": "Inglese", - "language.es": "Spagnolo", - "language.fi": "Finlandese", - "language.fr": "Francese", - "language.it": "Italiano", - "language.pl": "Polacco", - "game.modeDaily": "Giornaliero", - "game.modePractice": "Pratica", - "game.modeShare": "Condiviso", - "game.iGiveUp": "Mi arrendo", - "game.dailyGameLostToast": "Partita persa del {{dailyStamp}}, la parola vincente era \"{{word}}\"", - "game.givingUpIsNotPossible": "Avvia una partita per poterti arrendere ;)", - "game.confirmCheckTheWord": "Va bene \"{{word}}\"?", - "game.wordToSubmitIsMissing": "Dovremmo controllare la parola?", - "game.checking": "controllo in corso...", - "game.withSpecialCharacters": "La parola vincente contiene almeno un carattere {{specialCharacter}}.", - "game.withoutSpecialCharacters": "La parola vincente non contiene caratteri {{specialCharacters}}.", - "game.csSpecialCharacter": "speciale", - "game.csSpecialCharacters": "speciali", - "game.deSpecialCharacter": "speciale", - "game.deSpecialCharacters": "speciali", - "game.esSpecialCharacter": "speciale", - "game.esSpecialCharacters": "speciali", - "game.fiSpecialCharacter": "speciale", - "game.fiSpecialCharacters": "speciali", - "game.frSpecialCharacter": "speciale", - "game.frSpecialCharacters": "speciali", - "game.itSpecialCharacter": "speciale", - "game.itSpecialCharacters": "speciali", - "game.plSpecialCharacter": "speciale", - "game.plSpecialCharacters": "speciali", - "game.youCanUseThisWordButNotWin": "Puoi usare questa parola, ma non puoi vincere con essa.", - "game.youCanUseIncorrectLetters": "lettera errata inserita", - "game.youCanUseLettersTypedTooManyTimes": "lettera corretta usata troppe volte", - "game.youCanUseSpace": "Le parole non hanno spazi, ma puoi usarli, verranno rimossi.", - "game.youCanUseIncorrectStart": "inizio parola errato", - "game.youCanUseIncorrectEnd": "fine parola errato", - "game.youCanUseIncorrectMiddle": "alcune lettere devono essere vicine", - "game.youCanUseIncorrectOrder": "alcune lettere sono nell'ordine sbagliato", - "game.spacesRemoved": "Gli spazi sono stati rimossi.", - "game.isNotInDictionary": "Parola non trovata nel dizionario.", - "game.wordAlreadyUsed": "La parola era già stata usata.", - "game.restoreError": "Si è verificato un errore durante il ripristino dello stato della partita.", - "help.title": "Aiuto", - "help.howToPlayTitle": "Come si gioca?", - "help.howToPlayText1": "Indovina la parola utilizzando il minor numero possibile di lettere.", - "help.howToPlayText2": "Dopo aver fatto la tua migliore supposizione, i colori delle lettere si alternano per dirti quanto sei vicino o lontano dalla parola.", - "help.exampleTitle": "Esempio", - "help.exampleTitleAlt": "Un esempio diverso", - "help.incorrectLettersTip": "Le lettere grigie non sono nella parola.", - "help.correctLetters": "Le lettere {{correct1}} e {{correct2}} sono nella parola in quest'ordine.", - "help.positionBefore": "La lettera {{position}} è nella parola ma non prima di {{closestCorrect}}.", - "help.positionBetween": "La lettera {{position}} ma non tra di loro.", - "help.positionAfter": "La lettera {{position}} è nella parola ma non dopo {{closestCorrect}}.", - "help.inRow": "Le lettere {{letters}} sono nella parola in fila.", - "help.firstAndLast": "La parola inizia con {{first}} e finisce con {{last}}.", - "help.winingWordMessage": "Questa è la parola di risposta.", - "help.previousExample": "Esempio precedente", - "help.altExample": "Un altro esempio?", - "help.whatIsDiffleTitle": "Cos'è Diffle?", - "help.whatIsDiffleDescription": "Diffle è un gioco ispirato a Wordle senza limiti di caratteri. Se ti piace Wordle, questo gioco fa per te.", - "help.gameRules": "Regole del gioco", - "end.titleWon": "Successo", - "end.titleLost": "Sconfitta", - "end.titleCheater": "Un chiaroveggente", - "end.winningWord": "La risposta:", - "end.wordsUsed_zero": "parole", - "end.wordsUsed_one": "parola", - "end.wordsUsed_few": "parole", - "end.wordsUsed_many": "parole", - "end.wordsUsed_other": "parole", - "end.inWordsUsed_zero": "parole", - "end.inWordsUsed_one": "parola", - "end.inWordsUsed_few": "parole", - "end.inWordsUsed_many": "parole", - "end.inWordsUsed_other": "parole", - "end.in_zero": "in", - "end.in_one": "in", - "end.in_few": "in", - "end.in_many": "in", - "end.in_other": "in", - "end.lostIn": "perso", - "end.lettersUsedShort": "l.", - "end.lettersUsed_zero": "lettere", - "end.lettersUsed_one": "lettera", - "end.lettersUsed_few": "lettere", - "end.lettersUsed_many": "lettere", - "end.lettersUsed_other": "lettere", - "end.nextDailyHours_zero": "La nuova parola del giorno sarà disponibile tra {{count}} ore.", - "end.nextDailyHours_one": "La nuova parola quotidiana sarà disponibile in un'ora.", - "end.nextDailyHours_few": "La nuova parola quotidiana sarà disponibile in {{count}} ore.", - "end.nextDailyHours_many": "La nuova parola quotidiana sarà disponibile in {{count}} ore.", - "end.nextDailyHours_other": "La nuova parola quotidiana sarà disponibile in {{count}} ore.", - "end.nextDailyShort": "prossimo tra {{count}}h", - "end.completed": "completato", - "end.gameDuration": "Durata del gioco", - "settings.title": "Impostazioni", - "settings.inDevelopment": "In fase di sviluppo", - "settings.inBetaNow": "Beta", - "settings.onlyIn": "Solo in", - "settings.considered": "Considerato", - "settings.statisticsTitle": "Statistiche", - "settings.gameModeTitle": "Modalità di gioco", - "settings.labelFinishGame": "Fine", - "settings.labelFinishGameLonger": "Indovina la password di oggi per sbloccare.", - "settings.labelYouCanSeeSharedWords": "Hai indovinato la password di oggi, quindi puoi vederli.", - "settings.preferencesTitle": "Preferenze", - "settings.highContrastMode": "Alto contrasto", - "settings.lightMode": "Modalità luminosa", - "settings.darkMode": "Modalità scura", - "settings.appVibration": "Vibrazioni dell'app", - "settings.showGameDuration": "Mostra durata del gioco", - "settings.accessibility": "Accessibilità", - "settings.keyboard": "Tastiera", - "settings.confirmSubmition": "Conferma parole", - "settings.swapEnterAndBackspace": "Scambia Backspace con Invio", - "settings.languageDefault": "lingua di origine", - "settings.keyboardVibration": "Vibrazioni della tastiera", - "settings.smallerKeyboard": "Tastiera più piccola", - "settings.sourcesTitle": "Fonti", - "settings.sourcesDescription": "Tutte le risorse utilizzate da questa app sono sotto una licenza gratuita. Applausi agli autori di tali risorse.", - "settings.sourcesTitleDictionaries": "Dizionari", - "settings.sourcesTitleImages": "Icone", - "settings.sourceGithub": "repository di questo sito", - "settings.sourceDiffle": "diffle originale", - "settings.sourceDictionarySpellchecker": "correttore ortografico", - "settings.sourceDictionaryWiningWords": "trovatore di parole vincenti", - "settings.lastDailyWordsTitle": "Parola di ieri", - "settings.lastDailyWordsYesterday": "La parola di ieri era \"{{word}}\".", - "settings.lastDailyWordsCanBeWrongBecauseOfUpdate": "La parola vincente di ieri potrebbe essere sbagliata perché è stato rilasciato un aggiornamento più grande.", - "settings.confirmInSeconds_zero": "Fai clic in {{count}} secondi per confermare", - "settings.confirmInSeconds_one": "Fai clic in un secondo per confermare", - "settings.confirmInSeconds_few": "Fai clic in {{count}} secondi per confermare", - "settings.confirmInSeconds_many": "Fai clic in {{count}} secondi per confermare", - "settings.confirmInSeconds_other": "Fai clic in {{count}} secondi per confermare", - "settings.confirmAfterWaiting": "Fai clic per confermare", - "settings.language": "Lingua", - "settings.languageChanged": "La lingua è stata cambiata.", - "settings.reportTranslationBug": "Segnala un bug di traduzione", - "settings.privacyTitle": "Privacy", - "settings.cookiesTitle": "Cookies", - "settings.cookiesText1": "Questo sito web utilizza la cache del tuo browser per funzionare correttamente.", - "settings.cookiesText2": "Accettando \"tutto\" accetti anche il tracciamento opzionale della tua attività (incluso Google Analytics).", - "settings.acceptAll": "Accetta tutto", - "settings.acceptOnlyRequired": "Accetta richiesti", - "settings.saveSelected": "Salva selezionati", - "settings.cookiesSavedAndRefresh": "Salvato. L'applicazione verrà aggiornata.", - "settings.cookiesExternalOptional": "esterno e opzionale", - "settings.cookiesLocalRequierd": "locale e richiesto", - "share.titleSettings": "Condivisione", - "share.linkWithUsedWords": "Link alle parole utilizzate", - "share.linkWithUsedWordsNoSpoilers": "(senza spoiler)", - "share.titleSharedResult": "Il risultato condiviso con te", - "share.resultIsBroken": "Sfortunatamente, questo link è scaduto o non funziona.", - "share.resultIsForTheFuture": "Questo link dovrebbe funzionare presto.", - "share.resultHasExpired": "Purtroppo, questo link è scaduto.", - "share.titleUsedWords": "Parole utilizzate", - "share.dontShowThisResult": "Non mostrare più questo risultato", - "statistics.filters": "Filtri", - "statistics.filterAll": "Unisci", - "statistics.noData": "Nessun dato per i filtri selezionati.", - "statistics.specialCharactersWithout": "senza caratteri speciali", - "statistics.specialCharactersWith": "con caratteri speciali", - "statistics.wordLengthShort": "a {{to}} caratteri", - "statistics.wordLengthLong": "sopra {{above}} caratteri", - "statistics.letters": "lettere", - "statistics.medianWordsBefore": "in", - "statistics.medianWords": "parole", - "statistics.median": "mediana", - "statistics.average": "media:", - "statistics.maximum": "massimo:", - "statistics.averageLetters": "media delle lettere", - "statistics.averageGameTime": "tempo medio di gioco", - "statistics.totalGameTime": "tempo totale di gioco", - "statistics.inWord": "nella parola", - "statistics.inFirstWord": "nella prima parola", - "statistics.inSecondWord": "nella seconda parola", - "statistics.keyboardUsed": "in media {{value}}% della tastiera utilizzata", - "statistics.averageWordsNotFound": "{{value}} parole non trovate in un dizionario", - "statistics.worstWordsNotFound": "peggior risultato {{value}} in una partita", - "statistics.worstWordsNotFoundLonger": "peggiori parole non trovate in un dizionario {{value}} in una partita", - "statistics.totalGames_zero": "{{count}} partite", - "statistics.totalGames_one": "1 partita", - "statistics.totalGames_few": "{{count}} partite", - "statistics.totalGames_many": "{{count}} partite", - "statistics.totalGames_other": "{{count}} partite", - "statistics.totalWon": "vinto", - "statistics.totalWonStreak": "vinto di seguito", - "statistics.totalWonStreak_zero": "vinto di seguito", - "statistics.totalWonStreak_one": "vinto di seguito", - "statistics.totalWonStreak_few": "vinto di seguito", - "statistics.totalWonStreak_many": "vinto di seguito", - "statistics.totalLostStreak": "perso di seguito", - "statistics.totalLostStreak_zero": "perso di seguito", - "statistics.totalLostStreak_one": "perso di seguito", - "statistics.totalLostStreak_few": "perso di seguito", - "statistics.totalLostStreak_many": "perso di seguito", - "statistics.totalBestStreak": "miglior vinto di seguito", - "statistics.streakTooltipWithWorstStreak": "il peggiore perso di seguito:", - "statistics.lettersCorrect": "corretto", - "statistics.lettersPosition": "posizione errata", - "statistics.lettersIncorrect": "sbagliato", - "statistics.lettersIncorrectAndTyped": "digitato in modo errato", - "statistics.titleRemoveStatistics": "Rimuovi statistiche", - "statistics.statisticsWasRemoved": "Le statistiche sono state rimosse", - "statistics.wordsWithSpecialCharacters": "Parole con caratteri speciali", - "statistics.languageTitleHighestLetterForCommon": "La lettera più popolare", - "statistics.filterCommon": "popolarità", - "statistics.languageDescriptionHighestLetterForCommon": "{{maxletter}} compare {{maxLetterValue}} volte per parola.", - "statistics.languageTitleHighestLetterForInWords": "Lettera nel maggior numero di parole", - "statistics.filterInWords": "numero di parole", - "statistics.languageDescriptionHighestLetterForInWords": "{{maxletter}} appare in {{maxLetterValue}} parole.", - "statistics.languageTitleHighestLetterForFirst": "Lettera più comune all'inizio", - "statistics.filterFirst": "inizio", - "statistics.languageDescriptionHighestLetterForFirst": "{{maxletter}} è la prima lettera in {{maxLetterValue}} parole.", - "statistics.languageTitleHighestLetterForLast": "Lettera più comune alla fine", - "statistics.filterLast": "fine", - "statistics.languageDescriptionHighestLetterForLast": "{{maxletter}} è l'ultima lettera in {{maxLetterValue}} parole.", - "statistics.languageTitleLength": "Numero di lettere in una parola", - "statistics.languageDescriptionMostPopularLength": "La lunghezza di parola più popolare è di {{letters}} lettere.", - "statistics.languageTitleAtTheBeginning": "Più spesso all'inizio", - "statistics.languageTitleInTheMiddle": "Più spesso nel mezzo", - "statistics.languageTitleInTheEnd": "Più spesso alla fine", - "statistics.showOneChartWithFilters": "Un grafico con filtri", - "statistics.showTitleWithLanguage": "Mostra il titolo della lingua", - "statistics.basedOn": "{{product}} basato su {{words}} parole da {{source}}", - "statistics.bestWordleWordTitle": "Migliore parola di partenza in Wordle", - "statistics.bestWordleWordExplanation": "Risultato contro {{words}} parole:", - "statistics.filterWordleLettersTitle": "Utilizzando lettere", - "statistics.filterWordleInWords": "Lettere", - "statistics.filterWordleLetterPosition": "Posizione (ripetizioni)", - "statistics.filterWordleUniqueLetterPosition": "Posizione", - "statistics.filterWordleMaxTitle": "Massimizzazione dei colori", - "statistics.filterBestMaxGreen": "Verde", - "statistics.filterBestMax": "Colori", - "statistics.filterBestMaxOrange": "Arancione", - "statistics.filterBestMaxGray": "Grigio", - "statistics.filterWordleBestTitle": "Bilanciamento dei colori", - "statistics.filterBestGreen1_5": "1,5 × verde + 1 × giallo", - "statistics.filterBestGreen2_0": "2 × verde + 1 × giallo", - "statistics.bestWordleWordPopularLettersTitle": "Lettere più popolari in una data posizione", - "feature.specialWord.wasActivated": "La parola speciale è stata attivata!", - "feature.specialWord.wasDeactivated": "La parola speciale è stata disattivata!" -} \ No newline at end of file + "route.help": "aiuto", + "route.settings": "impostazioni", + "route.statistics": "le-tue-statistiche", + "route.aboutLanguage": "sulla-lingua", + "route.hejto2024": "hejto-2024", + "route.game.title": "DIFFLE - il gioco simile a Wordle (senza limite di caratteri)", + "route.game.metaDescription": "Ogni parola utilizzata fornisce suggerimenti sulla posizione e sull'ordine delle lettere nella soluzione.", + "route.game.openGraphTitle": "DIFFLE - il gioco simile a Wordle (senza limite di caratteri)", + "route.game.openGraphDescription": "Ogni parola utilizzata fornisce suggerimenti sulla posizione e sull'ordine delle lettere nella soluzione.", + "common.yes": "Si", + "common.no": "No", + "common.play": "Inizia", + "common.newGame": "Nuovo gioco", + "common.copyResult": "Risultato copiato", + "common.copyResultLink": "Solo copia il link", + "common.copyLink": "Link da copiare", + "common.copied": "Copiato.", + "common.checkInDictionary": "Ricerca di \"{{word}}\"", + "common.checkInDictionaryWithName": "Ricerca di \"{{word}}\" in {{name}}", + "common.dictionaryIsNotExactMatch": "Il dizionario delle parole vincenti non ha una versione online facilmente accessibile, quindi puoi provare uno di quei dizionari.", + "common.close": "Chiudi", + "common.more": "altro", + "common.download": "Scarica", + "common.downloadError": "Un errore di caricamento.", + "common.fetchError": "Un errore di caricamento, riprova.", + "common.unknownError": "Si è verificato un errore sconosciuto.", + "common.serviceMode": "Manutenzione del servizio {{today}}.", + "common.serviceModeWeReturnSoon": "Di nuovo operativo domani!", + "language.currentLanguage": "Italiano", + "language.cs": "Ceco", + "language.de": "Tedesco", + "language.en": "Inglese", + "language.es": "Spagnolo", + "language.fi": "Finlandese", + "language.fr": "Francese", + "language.it": "Italiano", + "language.pl": "Polacco", + "game.modeDaily": "Giornaliero", + "game.modePractice": "Pratica", + "game.modeShare": "Condiviso", + "game.iGiveUp": "Mi arrendo", + "game.dailyGameLostToast": "Partita persa del {{dailyStamp}}, la parola vincente era \"{{word}}\"", + "game.givingUpIsNotPossible": "Avvia una partita per poterti arrendere ;)", + "game.confirmCheckTheWord": "Va bene \"{{word}}\"?", + "game.wordToSubmitIsMissing": "Dovremmo controllare la parola?", + "game.checking": "controllo in corso...", + "game.withSpecialCharacters": "La parola vincente contiene almeno un carattere {{specialCharacter}}.", + "game.withoutSpecialCharacters": "La parola vincente non contiene caratteri {{specialCharacters}}.", + "game.csSpecialCharacter": "speciale", + "game.csSpecialCharacters": "speciali", + "game.deSpecialCharacter": "speciale", + "game.deSpecialCharacters": "speciali", + "game.esSpecialCharacter": "speciale", + "game.esSpecialCharacters": "speciali", + "game.fiSpecialCharacter": "speciale", + "game.fiSpecialCharacters": "speciali", + "game.frSpecialCharacter": "speciale", + "game.frSpecialCharacters": "speciali", + "game.itSpecialCharacter": "speciale", + "game.itSpecialCharacters": "speciali", + "game.plSpecialCharacter": "speciale", + "game.plSpecialCharacters": "speciali", + "game.youCanUseThisWordButNotWin": "Puoi usare questa parola, ma non puoi vincere con essa.", + "game.youCanUseIncorrectLetters": "lettera errata inserita", + "game.youCanUseLettersTypedTooManyTimes": "lettera corretta usata troppe volte", + "game.youCanUseSpace": "Le parole non hanno spazi, ma puoi usarli, verranno rimossi.", + "game.youCanUseIncorrectStart": "inizio parola errato", + "game.youCanUseIncorrectEnd": "fine parola errato", + "game.youCanUseIncorrectMiddle": "alcune lettere devono essere vicine", + "game.youCanUseIncorrectOrder": "alcune lettere sono nell'ordine sbagliato", + "game.spacesRemoved": "Gli spazi sono stati rimossi.", + "game.isNotInDictionary": "Parola non trovata nel dizionario.", + "game.wordAlreadyUsed": "La parola era già stata usata.", + "game.restoreError": "Si è verificato un errore durante il ripristino dello stato della partita.", + "help.title": "Aiuto", + "help.howToPlayTitle": "Come si gioca?", + "help.howToPlayText1": "Indovina la parola utilizzando il minor numero possibile di lettere.", + "help.howToPlayText2": "Dopo aver fatto la tua migliore supposizione, i colori delle lettere si alternano per dirti quanto sei vicino o lontano dalla parola.", + "help.exampleTitle": "Esempio", + "help.exampleTitleAlt": "Un esempio diverso", + "help.incorrectLettersTip": "Le lettere grigie non sono nella parola.", + "help.correctLetters": "Le lettere {{correct1}} e {{correct2}} sono nella parola in quest'ordine.", + "help.positionBefore": "La lettera {{position}} è nella parola ma non prima di {{closestCorrect}}.", + "help.positionBetween": "La lettera {{position}} ma non tra di loro.", + "help.positionAfter": "La lettera {{position}} è nella parola ma non dopo {{closestCorrect}}.", + "help.inRow": "Le lettere {{letters}} sono nella parola in fila.", + "help.firstAndLast": "La parola inizia con {{first}} e finisce con {{last}}.", + "help.winingWordMessage": "Questa è la parola di risposta.", + "help.previousExample": "Esempio precedente", + "help.altExample": "Un altro esempio?", + "help.whatIsDiffleTitle": "Cos'è Diffle?", + "help.whatIsDiffleDescription": "Diffle è un gioco ispirato a Wordle senza limiti di caratteri. Se ti piace Wordle, questo gioco fa per te.", + "help.gameRules": "Regole del gioco", + "end.titleWon": "Successo", + "end.titleLost": "Sconfitta", + "end.titleCheater": "Un chiaroveggente", + "end.winningWord": "La risposta:", + "end.wordsUsed_zero": "parole", + "end.wordsUsed_one": "parola", + "end.wordsUsed_few": "parole", + "end.wordsUsed_many": "parole", + "end.wordsUsed_other": "parole", + "end.inWordsUsed_zero": "parole", + "end.inWordsUsed_one": "parola", + "end.inWordsUsed_few": "parole", + "end.inWordsUsed_many": "parole", + "end.inWordsUsed_other": "parole", + "end.in_zero": "in", + "end.in_one": "in", + "end.in_few": "in", + "end.in_many": "in", + "end.in_other": "in", + "end.lostIn": "perso", + "end.lettersUsedShort": "l.", + "end.lettersUsed_zero": "lettere", + "end.lettersUsed_one": "lettera", + "end.lettersUsed_few": "lettere", + "end.lettersUsed_many": "lettere", + "end.lettersUsed_other": "lettere", + "end.nextDailyHours_zero": "La nuova parola del giorno sarà disponibile tra {{count}} ore.", + "end.nextDailyHours_one": "La nuova parola quotidiana sarà disponibile in un'ora.", + "end.nextDailyHours_few": "La nuova parola quotidiana sarà disponibile in {{count}} ore.", + "end.nextDailyHours_many": "La nuova parola quotidiana sarà disponibile in {{count}} ore.", + "end.nextDailyHours_other": "La nuova parola quotidiana sarà disponibile in {{count}} ore.", + "end.nextDailyShort": "prossimo tra {{count}}h", + "end.completed": "completato", + "end.gameDuration": "Durata del gioco", + "settings.title": "Impostazioni", + "settings.inDevelopment": "In fase di sviluppo", + "settings.inBetaNow": "Beta", + "settings.onlyIn": "Solo in", + "settings.considered": "Considerato", + "settings.statisticsTitle": "Statistiche", + "settings.gameModeTitle": "Modalità di gioco", + "settings.labelFinishGame": "Fine", + "settings.labelFinishGameLonger": "Indovina la password di oggi per sbloccare.", + "settings.labelYouCanSeeSharedWords": "Hai indovinato la password di oggi, quindi puoi vederli.", + "settings.preferencesTitle": "Preferenze", + "settings.highContrastMode": "Alto contrasto", + "settings.lightMode": "Modalità luminosa", + "settings.darkMode": "Modalità scura", + "settings.appVibration": "Vibrazioni dell'app", + "settings.showGameDuration": "Mostra durata del gioco", + "settings.accessibility": "Accessibilità", + "settings.keyboard": "Tastiera", + "settings.confirmSubmition": "Conferma parole", + "settings.swapEnterAndBackspace": "Scambia Backspace con Invio", + "settings.languageDefault": "lingua di origine", + "settings.keyboardVibration": "Vibrazioni della tastiera", + "settings.smallerKeyboard": "Tastiera più piccola", + "settings.sourcesTitle": "Fonti", + "settings.sourcesDescription": "Tutte le risorse utilizzate da questa app sono sotto una licenza gratuita. Applausi agli autori di tali risorse.", + "settings.sourcesTitleDictionaries": "Dizionari", + "settings.sourcesTitleImages": "Icone", + "settings.sourceGithub": "repository di questo sito", + "settings.sourceDiffle": "diffle originale", + "settings.sourceDictionarySpellchecker": "correttore ortografico", + "settings.sourceDictionaryWiningWords": "trovatore di parole vincenti", + "settings.lastDailyWordsTitle": "Parola di ieri", + "settings.lastDailyWordsYesterday": "La parola di ieri era \"{{word}}\".", + "settings.lastDailyWordsCanBeWrongBecauseOfUpdate": "La parola vincente di ieri potrebbe essere sbagliata perché è stato rilasciato un aggiornamento più grande.", + "settings.confirmInSeconds_zero": "Fai clic in {{count}} secondi per confermare", + "settings.confirmInSeconds_one": "Fai clic in un secondo per confermare", + "settings.confirmInSeconds_few": "Fai clic in {{count}} secondi per confermare", + "settings.confirmInSeconds_many": "Fai clic in {{count}} secondi per confermare", + "settings.confirmInSeconds_other": "Fai clic in {{count}} secondi per confermare", + "settings.confirmAfterWaiting": "Fai clic per confermare", + "settings.language": "Lingua", + "settings.languageChanged": "La lingua è stata cambiata.", + "settings.reportTranslationBug": "Segnala un bug di traduzione", + "settings.privacyTitle": "Privacy", + "settings.cookiesTitle": "Cookies", + "settings.cookiesText1": "Questo sito web utilizza la cache del tuo browser per funzionare correttamente.", + "settings.cookiesText2": "Accettando \"tutto\" accetti anche il tracciamento opzionale della tua attività (incluso Google Analytics).", + "settings.acceptAll": "Accetta tutto", + "settings.acceptOnlyRequired": "Accetta richiesti", + "settings.saveSelected": "Salva selezionati", + "settings.cookiesSavedAndRefresh": "Salvato. L'applicazione verrà aggiornata.", + "settings.cookiesExternalOptional": "esterno e opzionale", + "settings.cookiesLocalRequierd": "locale e richiesto", + "share.titleSettings": "Condivisione", + "share.linkWithUsedWords": "Link alle parole utilizzate", + "share.linkWithUsedWordsNoSpoilers": "(senza spoiler)", + "share.titleSharedResult": "Il risultato condiviso con te", + "share.resultIsBroken": "Sfortunatamente, questo link è scaduto o non funziona.", + "share.resultIsForTheFuture": "Questo link dovrebbe funzionare presto.", + "share.resultHasExpired": "Purtroppo, questo link è scaduto.", + "share.titleUsedWords": "Parole utilizzate", + "share.dontShowThisResult": "Non mostrare più questo risultato", + "statistics.filters": "Filtri", + "statistics.filterAll": "Unisci", + "statistics.noData": "Nessun dato per i filtri selezionati.", + "statistics.specialCharactersWithout": "senza caratteri speciali", + "statistics.specialCharactersWith": "con caratteri speciali", + "statistics.wordLengthShort": "a {{to}} caratteri", + "statistics.wordLengthLong": "sopra {{above}} caratteri", + "statistics.letters": "lettere", + "statistics.medianWordsBefore": "in", + "statistics.medianWords": "parole", + "statistics.median": "mediana", + "statistics.average": "media:", + "statistics.maximum": "massimo:", + "statistics.averageLetters": "media delle lettere", + "statistics.averageGameTime": "tempo medio di gioco", + "statistics.totalGameTime": "tempo totale di gioco", + "statistics.inWord": "nella parola", + "statistics.inFirstWord": "nella prima parola", + "statistics.inSecondWord": "nella seconda parola", + "statistics.keyboardUsed": "in media {{value}}% della tastiera utilizzata", + "statistics.averageWordsNotFound": "{{value}} parole non trovate in un dizionario", + "statistics.worstWordsNotFound": "peggior risultato {{value}} in una partita", + "statistics.worstWordsNotFoundLonger": "peggiori parole non trovate in un dizionario {{value}} in una partita", + "statistics.totalGames_zero": "{{count}} partite", + "statistics.totalGames_one": "1 partita", + "statistics.totalGames_few": "{{count}} partite", + "statistics.totalGames_many": "{{count}} partite", + "statistics.totalGames_other": "{{count}} partite", + "statistics.totalWon": "vinto", + "statistics.totalWonStreak": "vinto di seguito", + "statistics.totalWonStreak_zero": "vinto di seguito", + "statistics.totalWonStreak_one": "vinto di seguito", + "statistics.totalWonStreak_few": "vinto di seguito", + "statistics.totalWonStreak_many": "vinto di seguito", + "statistics.totalLostStreak": "perso di seguito", + "statistics.totalLostStreak_zero": "perso di seguito", + "statistics.totalLostStreak_one": "perso di seguito", + "statistics.totalLostStreak_few": "perso di seguito", + "statistics.totalLostStreak_many": "perso di seguito", + "statistics.totalBestStreak": "miglior vinto di seguito", + "statistics.streakTooltipWithWorstStreak": "il peggiore perso di seguito:", + "statistics.lettersCorrect": "corretto", + "statistics.lettersPosition": "posizione errata", + "statistics.lettersIncorrect": "sbagliato", + "statistics.lettersIncorrectAndTyped": "digitato in modo errato", + "statistics.titleRemoveStatistics": "Rimuovi statistiche", + "statistics.statisticsWasRemoved": "Le statistiche sono state rimosse", + "statistics.wordsWithSpecialCharacters": "Parole con caratteri speciali", + "statistics.languageTitleHighestLetterForCommon": "La lettera più popolare", + "statistics.filterCommon": "popolarità", + "statistics.languageDescriptionHighestLetterForCommon": "{{maxletter}} compare {{maxLetterValue}} volte per parola.", + "statistics.languageTitleHighestLetterForInWords": "Lettera nel maggior numero di parole", + "statistics.filterInWords": "numero di parole", + "statistics.languageDescriptionHighestLetterForInWords": "{{maxletter}} appare in {{maxLetterValue}} parole.", + "statistics.languageTitleHighestLetterForFirst": "Lettera più comune all'inizio", + "statistics.filterFirst": "inizio", + "statistics.languageDescriptionHighestLetterForFirst": "{{maxletter}} è la prima lettera in {{maxLetterValue}} parole.", + "statistics.languageTitleHighestLetterForLast": "Lettera più comune alla fine", + "statistics.filterLast": "fine", + "statistics.languageDescriptionHighestLetterForLast": "{{maxletter}} è l'ultima lettera in {{maxLetterValue}} parole.", + "statistics.languageTitleLength": "Numero di lettere in una parola", + "statistics.languageDescriptionMostPopularLength": "La lunghezza di parola più popolare è di {{letters}} lettere.", + "statistics.languageTitleAtTheBeginning": "Più spesso all'inizio", + "statistics.languageTitleInTheMiddle": "Più spesso nel mezzo", + "statistics.languageTitleInTheEnd": "Più spesso alla fine", + "statistics.showOneChartWithFilters": "Un grafico con filtri", + "statistics.showTitleWithLanguage": "Mostra il titolo della lingua", + "statistics.basedOn": "{{product}} basato su {{words}} parole da {{source}}", + "statistics.bestWordleWordTitle": "Migliore parola di partenza in Wordle", + "statistics.bestWordleWordExplanation": "Risultato contro {{words}} parole:", + "statistics.filterWordleLettersTitle": "Utilizzando lettere", + "statistics.filterWordleInWords": "Lettere", + "statistics.filterWordleLetterPosition": "Posizione (ripetizioni)", + "statistics.filterWordleUniqueLetterPosition": "Posizione", + "statistics.filterWordleMaxTitle": "Massimizzazione dei colori", + "statistics.filterBestMaxGreen": "Verde", + "statistics.filterBestMax": "Colori", + "statistics.filterBestMaxOrange": "Arancione", + "statistics.filterBestMaxGray": "Grigio", + "statistics.filterWordleBestTitle": "Bilanciamento dei colori", + "statistics.filterBestGreen1_5": "1,5 × verde + 1 × giallo", + "statistics.filterBestGreen2_0": "2 × verde + 1 × giallo", + "statistics.bestWordleWordPopularLettersTitle": "Lettere più popolari in una data posizione", + "feature.specialWord.wasActivated": "La parola speciale è stata attivata!", + "feature.specialWord.wasDeactivated": "La parola speciale è stata disattivata!" +} diff --git a/src/locales/langs.ts b/src/locales/langs.ts new file mode 100644 index 000000000..86f10739b --- /dev/null +++ b/src/locales/langs.ts @@ -0,0 +1,42 @@ +import localeCs from './cs.json'; +import localeDe from './de.json'; +import localeEn from './en.json'; +import localeEs from './es.json'; +import localeFi from './fi.json'; +import localeFr from './fr.json'; +import localeIt from './it.json'; +import localePl from './pl.json'; + +// TODO: manage them separated from your code: https://react.i18next.com/guides/multiple-translation-files) +export const resources: { + [lang: string]: { + translation: { + [key: string]: string + }, + }, +} = { + cs: { + translation: localeCs, + }, + de: { + translation: localeDe, + }, + en: { + translation: localeEn, + }, + es: { + translation: localeEs, + }, + fi: { + translation: localeFi, + }, + fr: { + translation: localeFr, + }, + it: { + translation: localeIt, + }, + pl: { + translation: localePl, + }, +}; diff --git a/src/locales/pl.json b/src/locales/pl.json index 1f5471411..b2b0cc634 100644 --- a/src/locales/pl.json +++ b/src/locales/pl.json @@ -1,8 +1,15 @@ { - "seo.pageTitle": "DIFFLE - gra jak Wordle (po polsku, bez limitu znaków) 🇵🇱", - "seo.metaDescription": "Każde użyte słowo podpowiada pozycję i kolejność liter w haśle.", - "seo.openGraphTitle": "DIFFLE - gra jak Wordle (po polsku, bez limitu znaków) 🇵🇱", - "seo.openGraphDescription": "Każde użyte słowo podpowiada pozycję i kolejność liter w haśle.", + "route.help": "pomoc", + "route.settings": "ustawienia", + "route.statistics": "twoje-statystyki", + "route.aboutLanguage": "o-jezyku", + "route.hejto2024": "hejto-2024", + "route.game.title": "DIFFLE - gra jak Wordle (po polsku, bez limitu znaków) 🇵🇱", + "route.game.metaDescription": "Każde użyte słowo podpowiada pozycję i kolejność liter w haśle.", + "route.game.openGraphTitle": "DIFFLE - gra jak Wordle (po polsku, bez limitu znaków) 🇵🇱", + "route.game.openGraphDescription": "Każde użyte słowo podpowiada pozycję i kolejność liter w haśle.", + "route.aboutLanguage.title": "Statystyki liter i słów w języku polskim: najczęstsze litery, długości słów i pierwsze litery", + "route.aboutLanguage.metaDescription": "Analiza słownika języka polskiego.", "common.yes": "Tak", "common.no": "Nie", "common.play": "Graj", diff --git a/src/types.d.ts b/src/types.d.ts index 9f691fd8c..d5bd0d029 100644 --- a/src/types.d.ts +++ b/src/types.d.ts @@ -21,7 +21,6 @@ export type KeyLinesVariant = { export type Dictionary = { code?: string, languages: string[], - title: string, isBeta?: boolean, keyLinesVariants: KeyLinesVariant[], keyLinesToUse: string[][], diff --git a/src/utils/lang.ts b/src/utils/lang.ts index 889368708..2576316a4 100644 --- a/src/utils/lang.ts +++ b/src/utils/lang.ts @@ -1,7 +1,7 @@ import { SUPPORTED_LANGS, SUPPORTED_DICTIONARY_BY_LANG } from '@const'; export const getLangFromUrl = () => { - const langFromUrl = SUPPORTED_LANGS.find(lang => window.location.pathname.endsWith(`/${lang}`)); + const langFromUrl = SUPPORTED_LANGS.find(lang => window.location.pathname.split('/').includes(lang)); return langFromUrl; }; diff --git a/src/utils/ts.ts b/src/utils/ts.ts index 2ebe8e46f..7f27dc215 100644 --- a/src/utils/ts.ts +++ b/src/utils/ts.ts @@ -1,5 +1,5 @@ export function keepIfInEnum( - value: string | undefined | number, + value: string | undefined | number | null, enumObject: { [key: string]: T }, ) { if (!value) { diff --git a/yarn.lock b/yarn.lock index ddd74940c..154870373 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4013,6 +4013,11 @@ minimist@^1.2.0, minimist@^1.2.6: resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c" integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== +mitt@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/mitt/-/mitt-3.0.1.tgz#ea36cf0cc30403601ae074c8f77b7092cdab36d1" + integrity sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw== + ms@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" @@ -4518,6 +4523,11 @@ regexp.prototype.flags@^1.5.1, regexp.prototype.flags@^1.5.2: es-errors "^1.3.0" set-function-name "^2.0.1" +regexparam@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/regexparam/-/regexparam-3.0.0.tgz#1673e09d41cb7fd41eaafd4040a6aa90daa0a21a" + integrity sha512-RSYAtP31mvYLkAHrOlh25pCNQ5hWnT106VukGaaFfuJrZFkGRX5GhUAdPqpSDXxOhA2c4akmRuplv1mRqnBn6Q== + regexpp@^3.2.0: version "3.2.0" resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.2.0.tgz#0425a2768d8f23bad70ca4b90461fa2f1213e1b2" @@ -5320,6 +5330,15 @@ word-wrap@^1.2.5: resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.5.tgz#d2c45c6dd4fbce621a66f136cbe328afd0410b34" integrity sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA== +wouter@^3.6.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/wouter/-/wouter-3.6.0.tgz#8d89cd9108e9a61d5b288fe95e370c6550565622" + integrity sha512-l11eR4urCc+CbY8+pV8HKFHxEqMgffss9aVB1XwiSkLDtH3cI6XpCa50cOzREzL0KwQqrwCVE5dCyeNcCgFpPg== + dependencies: + mitt "^3.0.1" + regexparam "^3.0.0" + use-sync-external-store "^1.0.0" + wrap-ansi@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43"