@scrabble-solver/scrabble-solver 2.9.3 → 2.10.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.next/BUILD_ID +1 -1
- package/.next/build-manifest.json +11 -11
- package/.next/cache/.tsbuildinfo +1 -1
- package/.next/cache/eslint/.cache_8dgz12 +1 -1
- package/.next/cache/next-server.js.nft.json +1 -1
- package/.next/cache/webpack/client-production/0.pack +0 -0
- package/.next/cache/webpack/client-production/index.pack +0 -0
- package/.next/cache/webpack/edge-server-production/0.pack +0 -0
- package/.next/cache/webpack/edge-server-production/index.pack +0 -0
- package/.next/cache/webpack/server-production/0.pack +0 -0
- package/.next/cache/webpack/server-production/index.pack +0 -0
- package/.next/next-server.js.nft.json +1 -1
- package/.next/prerender-manifest.json +1 -1
- package/.next/routes-manifest.json +1 -1
- package/.next/server/chunks/{429.js → 131.js} +2 -3652
- package/.next/server/chunks/413.js +399 -199
- package/.next/server/chunks/44.js +71 -45
- package/.next/server/chunks/515.js +1114 -542
- package/.next/server/chunks/911.js +96 -2
- package/.next/server/chunks/939.js +1 -0
- package/.next/server/middleware-build-manifest.js +1 -1
- package/.next/server/pages/404.html +2 -2
- package/.next/server/pages/404.js.nft.json +1 -1
- package/.next/server/pages/500.html +2 -2
- package/.next/server/pages/_app.js.nft.json +1 -1
- package/.next/server/pages/api/dictionary/[locale]/[word].js +49 -11
- package/.next/server/pages/api/dictionary/[locale]/[word].js.nft.json +1 -1
- package/.next/server/pages/api/dictionary/[locale].js +1 -8
- package/.next/server/pages/api/dictionary/[locale].js.nft.json +1 -1
- package/.next/server/pages/api/solve.js +67 -57
- package/.next/server/pages/api/solve.js.nft.json +1 -1
- package/.next/server/pages/api/verify.js +2 -9
- package/.next/server/pages/api/verify.js.nft.json +1 -1
- package/.next/server/pages/index.html +9 -1
- package/.next/server/pages/index.js +43 -36
- package/.next/server/pages/index.js.nft.json +1 -1
- package/.next/server/pages/index.json +1 -1
- package/.next/server/pages-manifest.json +1 -1
- package/.next/static/chunks/368-8b386c3106556f62.js +1 -0
- package/.next/static/chunks/pages/{404-8650986dc56dab75.js → 404-932294135c3206dd.js} +1 -1
- package/.next/static/chunks/pages/_app-8f0df20f771045ed.js +1 -0
- package/.next/static/chunks/pages/index-8af7a9d7a2cd98a7.js +1 -0
- package/.next/static/css/6b1833fd19d3a74a.css +1 -0
- package/.next/static/css/a6154e4ca046ca13.css +1 -0
- package/.next/static/css/bad53af6f8616677.css +1 -0
- package/.next/static/hf94cues-LcXZRCpAzQ6w/_buildManifest.js +1 -0
- package/.next/static/{s5pE_3C3ebZuSfaqE7xat → hf94cues-LcXZRCpAzQ6w}/_ssgManifest.js +0 -0
- package/.next/trace +52 -52
- package/package.json +9 -9
- package/src/components/Board/components/Cell/Cell.module.scss +45 -9
- package/src/components/Board/hooks/useGrid.ts +6 -4
- package/src/components/Dictionary/Dictionary.module.scss +8 -1
- package/src/components/EmptyState/EmptyState.tsx +6 -2
- package/src/components/Loading/Loading.tsx +13 -2
- package/src/components/NavButtons/NavButtons.module.scss +8 -7
- package/src/components/NavButtons/NavButtons.tsx +35 -28
- package/src/components/PlainTiles/PlainTiles.tsx +7 -1
- package/src/components/PlainTiles/Tile.tsx +4 -3
- package/src/components/Rack/Rack.tsx +18 -4
- package/src/components/Radio/Radio.module.scss +1 -1
- package/src/components/RemainingTiles/Character.tsx +7 -2
- package/src/components/RemainingTiles/RemainingTiles.tsx +28 -20
- package/src/components/Results/Cell.tsx +5 -3
- package/src/components/Results/Result.tsx +8 -3
- package/src/components/Results/Results.module.scss +31 -9
- package/src/components/Results/Results.tsx +8 -4
- package/src/components/Results/getColumns.ts +58 -0
- package/src/components/Settings/components/AutoGroupTilesSetting/AutoGroupTilesSetting.tsx +2 -2
- package/src/components/Settings/components/ConfigSetting/ConfigSetting.module.scss +1 -0
- package/src/components/Settings/components/LocaleSetting/LocaleSetting.module.scss +12 -1
- package/src/components/Settings/components/LocaleSetting/LocaleSetting.tsx +1 -1
- package/src/components/Settings/components/LocaleSetting/options.ts +16 -2
- package/src/components/Sidebar/Sidebar.module.scss +42 -8
- package/src/components/SvgFontCss/SvgFontCss.tsx +8 -7
- package/src/components/SvgFontCss/createCss.ts +11 -0
- package/src/components/SvgFontCss/createStyle.ts +9 -0
- package/src/components/SvgFontCss/createSvg.ts +10 -0
- package/src/components/SvgFontFix/SvgFontFix.module.scss +5 -0
- package/src/components/SvgFontFix/SvgFontFix.tsx +21 -0
- package/src/components/SvgFontFix/index.ts +1 -0
- package/src/components/Tile/Tile.module.scss +10 -2
- package/src/components/Tile/Tile.tsx +4 -0
- package/src/components/Tile/TilePure.tsx +3 -1
- package/src/components/Words/Words.tsx +4 -3
- package/src/components/index.ts +1 -0
- package/src/hooks/index.ts +2 -0
- package/src/hooks/useDirection.ts +22 -0
- package/src/hooks/useLanguage.ts +22 -0
- package/src/i18n/constants.ts +53 -0
- package/src/i18n/fa.json +56 -0
- package/src/i18n/fr.json +1 -1
- package/src/i18n/i18n.ts +22 -0
- package/src/i18n/index.ts +2 -20
- package/src/icons/FlagFa.svg +95 -0
- package/src/icons/index.ts +1 -0
- package/src/lib/createComparator.ts +22 -0
- package/src/lib/createKeyComparator.ts +4 -2
- package/src/lib/createStringComparator.ts +5 -0
- package/src/lib/detectLocale.ts +4 -0
- package/src/lib/getRemainingTiles.ts +4 -2
- package/src/lib/getRemainingTilesGroups.ts +54 -31
- package/src/lib/index.ts +2 -2
- package/src/lib/sortResults.ts +11 -9
- package/src/lib/unorderedArraysEqual.ts +3 -2
- package/src/pages/api/verify.ts +1 -1
- package/src/pages/index.module.scss +7 -18
- package/src/pages/index.tsx +10 -2
- package/src/sdk/findWordDefinitions.ts +1 -1
- package/src/service-worker/routeVerifyRequests.ts +1 -1
- package/src/state/sagas.ts +19 -5
- package/src/state/selectors.ts +15 -7
- package/src/styles/global.scss +6 -1
- package/.next/static/chunks/880-18e3aea6915aebe7.js +0 -1
- package/.next/static/chunks/pages/_app-183f598b1d4d480b.js +0 -1
- package/.next/static/chunks/pages/index-f1cef1e67e14d022.js +0 -1
- package/.next/static/css/751e8a14776d05d8.css +0 -1
- package/.next/static/css/ad2a08918868cad8.css +0 -1
- package/.next/static/css/e8de67ad5ea35427.css +0 -1
- package/.next/static/s5pE_3C3ebZuSfaqE7xat/_buildManifest.js +0 -1
- package/src/components/Results/constants.ts +0 -42
- package/src/lib/comparator.ts +0 -16
- package/src/lib/stringComparator.ts +0 -5
package/src/hooks/index.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
|
+
export { default as useDirection } from './useDirection';
|
|
1
2
|
export { default as useIsTablet } from './useIsTablet';
|
|
3
|
+
export { default as useLanguage } from './useLanguage';
|
|
2
4
|
export { default as useLocalStorage } from './useLocalStorage';
|
|
3
5
|
export { default as usePortal } from './usePortal';
|
|
4
6
|
export { default as useUniqueId } from './useUniqueId';
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { useLayoutEffect } from 'react';
|
|
2
|
+
|
|
3
|
+
import { noop } from 'lib';
|
|
4
|
+
|
|
5
|
+
const useDirection = (direction: 'ltr' | 'rtl') => {
|
|
6
|
+
useLayoutEffect(() => {
|
|
7
|
+
const html = document.body.parentElement;
|
|
8
|
+
|
|
9
|
+
if (!html) {
|
|
10
|
+
return noop;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
const old = html.dir;
|
|
14
|
+
html.dir = direction;
|
|
15
|
+
|
|
16
|
+
return () => {
|
|
17
|
+
html.dir = old;
|
|
18
|
+
};
|
|
19
|
+
}, [direction]);
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
export default useDirection;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { useLayoutEffect } from 'react';
|
|
2
|
+
|
|
3
|
+
import { noop } from 'lib';
|
|
4
|
+
|
|
5
|
+
const useLanguage = (language: string) => {
|
|
6
|
+
useLayoutEffect(() => {
|
|
7
|
+
const html = document.body.parentElement;
|
|
8
|
+
|
|
9
|
+
if (!html) {
|
|
10
|
+
return noop;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
const old = html.lang;
|
|
14
|
+
html.lang = language;
|
|
15
|
+
|
|
16
|
+
return () => {
|
|
17
|
+
html.lang = old;
|
|
18
|
+
};
|
|
19
|
+
}, [language]);
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
export default useLanguage;
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { Locale } from '@scrabble-solver/types';
|
|
2
|
+
|
|
3
|
+
interface LocaleFeatures {
|
|
4
|
+
direction: 'ltr' | 'rtl';
|
|
5
|
+
fontFamily: string;
|
|
6
|
+
consonants: boolean;
|
|
7
|
+
vowels: boolean;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export const LOCALE_FEATURES: Record<Locale, LocaleFeatures> = {
|
|
11
|
+
[Locale.DE_DE]: {
|
|
12
|
+
direction: 'ltr',
|
|
13
|
+
fontFamily: 'Open Sans',
|
|
14
|
+
consonants: true,
|
|
15
|
+
vowels: true,
|
|
16
|
+
},
|
|
17
|
+
[Locale.EN_GB]: {
|
|
18
|
+
direction: 'ltr',
|
|
19
|
+
fontFamily: 'Open Sans',
|
|
20
|
+
consonants: true,
|
|
21
|
+
vowels: true,
|
|
22
|
+
},
|
|
23
|
+
[Locale.EN_US]: {
|
|
24
|
+
direction: 'ltr',
|
|
25
|
+
fontFamily: 'Open Sans',
|
|
26
|
+
consonants: true,
|
|
27
|
+
vowels: true,
|
|
28
|
+
},
|
|
29
|
+
[Locale.ES_ES]: {
|
|
30
|
+
direction: 'ltr',
|
|
31
|
+
fontFamily: 'Open Sans',
|
|
32
|
+
consonants: true,
|
|
33
|
+
vowels: true,
|
|
34
|
+
},
|
|
35
|
+
[Locale.FA_IR]: {
|
|
36
|
+
direction: 'rtl',
|
|
37
|
+
fontFamily: 'Vazirmatn',
|
|
38
|
+
consonants: false,
|
|
39
|
+
vowels: false,
|
|
40
|
+
},
|
|
41
|
+
[Locale.FR_FR]: {
|
|
42
|
+
direction: 'ltr',
|
|
43
|
+
fontFamily: 'Open Sans',
|
|
44
|
+
consonants: true,
|
|
45
|
+
vowels: true,
|
|
46
|
+
},
|
|
47
|
+
[Locale.PL_PL]: {
|
|
48
|
+
direction: 'ltr',
|
|
49
|
+
fontFamily: 'Open Sans',
|
|
50
|
+
consonants: true,
|
|
51
|
+
vowels: true,
|
|
52
|
+
},
|
|
53
|
+
};
|
package/src/i18n/fa.json
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
{
|
|
2
|
+
"cell.filter-cell": "مقصد - کلیک برای تغییر",
|
|
3
|
+
"cell.set-blank": "علامت گذاری به عنوان خالی",
|
|
4
|
+
"cell.set-not-blank": "علامت گذاری به عنوان غیر خالی",
|
|
5
|
+
"cell.toggle-direction": "جهت تایپ - کلیک برای تغییر",
|
|
6
|
+
"common.blanks": "خالی",
|
|
7
|
+
"common.clear": "پاک کردن",
|
|
8
|
+
"common.close": "بستن",
|
|
9
|
+
"common.consonants": "حروف صامت",
|
|
10
|
+
"common.loading": "در حال بارگزاری",
|
|
11
|
+
"common.points": "امتیازات",
|
|
12
|
+
"common.tiles": "کاشی ها",
|
|
13
|
+
"common.two-letter-tiles": "دو حرفی",
|
|
14
|
+
"common.vowels": "حروف مصوت",
|
|
15
|
+
"common.word": "کلمه",
|
|
16
|
+
"common.words": "کلمات",
|
|
17
|
+
"dictionary.empty-state.no-definitions": "کلمه در فرهنگ لغت وجود دارد، ولی معنایی برای آن ثبت نشده است.",
|
|
18
|
+
"dictionary.empty-state.no-results": "کلمه در فرهنگ لغت یافت نشد.",
|
|
19
|
+
"dictionary.empty-state.not-allowed": "این کلمه مجاز نیست.",
|
|
20
|
+
"dictionary.empty-state.uninitialized": "معنی لغت اینجا نمایش داده خواهد شد.",
|
|
21
|
+
"dictionary.input.placeholder": "جستجو در فرهنگ لغت ...",
|
|
22
|
+
"empty-state.error": "خطا",
|
|
23
|
+
"empty-state.info": "اطلاعات",
|
|
24
|
+
"empty-state.success": "حله!",
|
|
25
|
+
"empty-state.warning": "اوووخ!",
|
|
26
|
+
"github": "به این پروژه در گیتهاب سر بزنید",
|
|
27
|
+
"keyMap": "میانبر های کیبورد",
|
|
28
|
+
"keyMap.board": "صفحه",
|
|
29
|
+
"keyMap.board.toggle-blank": "علامت/عدم علامت گذاری کاشی به عنوان خالی",
|
|
30
|
+
"keyMap.board.toggle-direction": "تغییر جهت تایپ",
|
|
31
|
+
"keyMap.board-and-rack": "صفحه و طاقچه",
|
|
32
|
+
"keyMap.board-and-rack.insert-two-letter-tile": "وارد کردن کاشی دو حرفی",
|
|
33
|
+
"keyMap.board-and-rack.navigate": "حرکت",
|
|
34
|
+
"keyMap.board-and-rack.remove-tile": "حذف کاشی",
|
|
35
|
+
"keyMap.board-and-rack.submit": "حل کردن",
|
|
36
|
+
"keyMap.rack": "طاقچه",
|
|
37
|
+
"keyMap.rack.insert-blank": "وارد کردن کاشی خالی (دکمه اسپیس)",
|
|
38
|
+
"rack.placeholder": "لیستحرف",
|
|
39
|
+
"remaining-tiles": "کاشی های باقی مانده",
|
|
40
|
+
"results.empty-state.no-filtered-results": "پاسخی یافت نشد.",
|
|
41
|
+
"results.empty-state.no-results": "کلمه قابل استفاده پیدا نشد.",
|
|
42
|
+
"results.empty-state.outdated": "نتایج به روز نیستند، برای بروز رسانی کلیک کنید.",
|
|
43
|
+
"results.empty-state.uninitialized": "کلمات تولید شده از حروف شما اینجا نمایش داده خواهد شد.",
|
|
44
|
+
"results.input.placeholder": "جستجو در نتایج (RegExp)",
|
|
45
|
+
"results.solve": "حل کن",
|
|
46
|
+
"settings": "تنظیمات",
|
|
47
|
+
"settings.autoGroupTiles": "کاشی های باقی مانده ی طاقچه را کنار هم قرار بده",
|
|
48
|
+
"settings.autoGroupTiles.left": "در سمت چپ",
|
|
49
|
+
"settings.autoGroupTiles.right": "در سمت راست",
|
|
50
|
+
"settings.autoGroupTiles.null": "کنار هم قرار نده",
|
|
51
|
+
"settings.game": "بازی",
|
|
52
|
+
"settings.language": "زبان",
|
|
53
|
+
"words": "کلمات ساخته شده",
|
|
54
|
+
"words.invalid": "نا معتبر",
|
|
55
|
+
"words.valid": "معتبر"
|
|
56
|
+
}
|
package/src/i18n/fr.json
CHANGED
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
"results.empty-state.no-filtered-results": "Aucun résultat ne correspond à cette requête",
|
|
41
41
|
"results.empty-state.no-results": "Pas de résultats - impossible de générer des mots.",
|
|
42
42
|
"results.empty-state.outdated": "Les résultats sont dépassé. Cliquer ci-dessous pour mettre à jour.",
|
|
43
|
-
"results.empty-state.uninitialized": "
|
|
43
|
+
"results.empty-state.uninitialized": "Les mots générés à partir de vos lettres seront affichés ici.",
|
|
44
44
|
"results.input.placeholder": "Rechercher les résultats... (RegExp)",
|
|
45
45
|
"results.solve": "Résoudre",
|
|
46
46
|
"settings": "Options",
|
package/src/i18n/i18n.ts
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { Locale } from '@scrabble-solver/types';
|
|
2
|
+
|
|
3
|
+
import { Translations } from 'types';
|
|
4
|
+
|
|
5
|
+
import de from './de.json';
|
|
6
|
+
import en from './en.json';
|
|
7
|
+
import es from './es.json';
|
|
8
|
+
import fa from './fa.json';
|
|
9
|
+
import fr from './fr.json';
|
|
10
|
+
import pl from './pl.json';
|
|
11
|
+
|
|
12
|
+
const i18n: Record<Locale, Translations> = {
|
|
13
|
+
[Locale.DE_DE]: de,
|
|
14
|
+
[Locale.EN_GB]: en,
|
|
15
|
+
[Locale.EN_US]: en,
|
|
16
|
+
[Locale.ES_ES]: es,
|
|
17
|
+
[Locale.FA_IR]: fa,
|
|
18
|
+
[Locale.FR_FR]: fr,
|
|
19
|
+
[Locale.PL_PL]: pl,
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
export default i18n;
|
package/src/i18n/index.ts
CHANGED
|
@@ -1,20 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
import { Translations } from 'types';
|
|
4
|
-
|
|
5
|
-
import de from './de.json';
|
|
6
|
-
import en from './en.json';
|
|
7
|
-
import es from './es.json';
|
|
8
|
-
import fr from './fr.json';
|
|
9
|
-
import pl from './pl.json';
|
|
10
|
-
|
|
11
|
-
const i18n: Record<Locale, Translations> = {
|
|
12
|
-
[Locale.DE_DE]: de,
|
|
13
|
-
[Locale.EN_GB]: en,
|
|
14
|
-
[Locale.EN_US]: en,
|
|
15
|
-
[Locale.ES_ES]: es,
|
|
16
|
-
[Locale.FR_FR]: fr,
|
|
17
|
-
[Locale.PL_PL]: pl,
|
|
18
|
-
};
|
|
19
|
-
|
|
20
|
-
export default i18n;
|
|
1
|
+
export { default } from './i18n';
|
|
2
|
+
export * from './constants';
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" viewBox="0 0 630 360">
|
|
2
|
+
<path style="fill:#da0000" d="M 0,0 H 630 V 360 H 0 Z" />
|
|
3
|
+
<path style="fill:#ffffff" d="M 0,0 H 630 V 240 H 0 Z" />
|
|
4
|
+
<path style="fill:#239f40" d="M 0,0 H 630 V 120 H 0 Z" />
|
|
5
|
+
<g transform="translate(8.4,100.4)">
|
|
6
|
+
<g fill="none" stroke="#fff" stroke-width="2">
|
|
7
|
+
<path d="M0,1H26M1,10V5H9V9H17V5H12M4,9H6M26,9H21V5H29M29,0V9H37V0M33,0V9" transform="scale(1.4)" />
|
|
8
|
+
<path d="M0,7H9M10,7H19" transform="scale(2.8)" />
|
|
9
|
+
<path d="m 0,139.6 h 25.2 m 2.8,0 h 25.2" style="stroke-width:5.6" />
|
|
10
|
+
<path d="m 0,146.6 h 36.4 m -35,12.6 v -7 h 11.2 v 5.6 h 11.2 v -5.6 h -7 m -11.2,5.6 h 2.8 m 28,0 h -7 v -5.6 h 11.2 m 0,-7 v 12.6 h 11.2 v -12.6 m -5.6,0 v 12.6" style="stroke-width:2.8" />
|
|
11
|
+
</g>
|
|
12
|
+
<g>
|
|
13
|
+
<g fill="none" stroke="#ffffff" stroke-width="2" transform="translate(56)">
|
|
14
|
+
<path d="M 0,1 H 26 M 1,10 V 5 h 8 v 4 h 8 V 5 H 12 M 4,9 H 6 M 26,9 H 21 V 5 h 8 m 0,-5 v 9 h 8 V 0 m -4,0 v 9" transform="scale(1.4)" />
|
|
15
|
+
<path d="m 0,7 h 9 m 1,0 h 9" transform="scale(2.8)" />
|
|
16
|
+
<path d="m 0,139.6 h 25.2 m 2.8,0 h 25.2" style="stroke-width:5.6" />
|
|
17
|
+
<path d="m 0,146.6 h 36.4 m -35,12.6 v -7 h 11.2 v 5.6 h 11.2 v -5.6 h -7 m -11.2,5.6 h 2.8 m 28,0 h -7 v -5.6 h 11.2 m 0,-7 v 12.6 h 11.2 v -12.6 m -5.6,0 v 12.6" style="stroke-width:2.8" />
|
|
18
|
+
</g>
|
|
19
|
+
<g fill="none" stroke="#ffffff" stroke-width="2" transform="translate(112)">
|
|
20
|
+
<path d="M 0,1 H 26 M 1,10 V 5 h 8 v 4 h 8 V 5 H 12 M 4,9 H 6 M 26,9 H 21 V 5 h 8 m 0,-5 v 9 h 8 V 0 m -4,0 v 9" transform="scale(1.4)" />
|
|
21
|
+
<path d="m 0,7 h 9 m 1,0 h 9" transform="scale(2.8)" />
|
|
22
|
+
<path d="m 0,139.6 h 25.2 m 2.8,0 h 25.2" style="stroke-width:5.6" />
|
|
23
|
+
<path d="m 0,146.6 h 36.4 m -35,12.6 v -7 h 11.2 v 5.6 h 11.2 v -5.6 h -7 m -11.2,5.6 h 2.8 m 28,0 h -7 v -5.6 h 11.2 m 0,-7 v 12.6 h 11.2 v -12.6 m -5.6,0 v 12.6" style="stroke-width:2.8" />
|
|
24
|
+
</g>
|
|
25
|
+
<g fill="none" stroke="#ffffff" stroke-width="2" transform="translate(168)">
|
|
26
|
+
<path d="M 0,1 H 26 M 1,10 V 5 h 8 v 4 h 8 V 5 H 12 M 4,9 H 6 M 26,9 H 21 V 5 h 8 m 0,-5 v 9 h 8 V 0 m -4,0 v 9" transform="scale(1.4)" />
|
|
27
|
+
<path d="m 0,7 h 9 m 1,0 h 9" transform="scale(2.8)" />
|
|
28
|
+
<path d="m 0,139.6 h 25.2 m 2.8,0 h 25.2" style="stroke-width:5.6" />
|
|
29
|
+
<path d="m 0,146.6 h 36.4 m -35,12.6 v -7 h 11.2 v 5.6 h 11.2 v -5.6 h -7 m -11.2,5.6 h 2.8 m 28,0 h -7 v -5.6 h 11.2 m 0,-7 v 12.6 h 11.2 v -12.6 m -5.6,0 v 12.6" style="stroke-width:2.8" />
|
|
30
|
+
</g>
|
|
31
|
+
</g>
|
|
32
|
+
<g transform="translate(168)">
|
|
33
|
+
<g fill="none" stroke="#ffffff" stroke-width="2" transform="translate(56)">
|
|
34
|
+
<path d="M 0,1 H 26 M 1,10 V 5 h 8 v 4 h 8 V 5 H 12 M 4,9 H 6 M 26,9 H 21 V 5 h 8 m 0,-5 v 9 h 8 V 0 m -4,0 v 9" transform="scale(1.4)" />
|
|
35
|
+
<path d="m 0,7 h 9 m 1,0 h 9" transform="scale(2.8)" />
|
|
36
|
+
<path d="m 0,139.6 h 25.2 m 2.8,0 h 25.2" style="stroke-width:5.6" />
|
|
37
|
+
<path d="m 0,146.6 h 36.4 m -35,12.6 v -7 h 11.2 v 5.6 h 11.2 v -5.6 h -7 m -11.2,5.6 h 2.8 m 28,0 h -7 v -5.6 h 11.2 m 0,-7 v 12.6 h 11.2 v -12.6 m -5.6,0 v 12.6" style="stroke-width:2.8" />
|
|
38
|
+
</g>
|
|
39
|
+
<g fill="none" stroke="#ffffff" stroke-width="2" transform="translate(112)">
|
|
40
|
+
<path d="M 0,1 H 26 M 1,10 V 5 h 8 v 4 h 8 V 5 H 12 M 4,9 H 6 M 26,9 H 21 V 5 h 8 m 0,-5 v 9 h 8 V 0 m -4,0 v 9" transform="scale(1.4)" />
|
|
41
|
+
<path d="m 0,7 h 9 m 1,0 h 9" transform="scale(2.8)" />
|
|
42
|
+
<path d="m 0,139.6 h 25.2 m 2.8,0 h 25.2" style="stroke-width:5.6" />
|
|
43
|
+
<path d="m 0,146.6 h 36.4 m -35,12.6 v -7 h 11.2 v 5.6 h 11.2 v -5.6 h -7 m -11.2,5.6 h 2.8 m 28,0 h -7 v -5.6 h 11.2 m 0,-7 v 12.6 h 11.2 v -12.6 m -5.6,0 v 12.6" style="stroke-width:2.8" />
|
|
44
|
+
</g>
|
|
45
|
+
<g fill="none" stroke="#ffffff" stroke-width="2" transform="translate(168)">
|
|
46
|
+
<path d="M 0,1 H 26 M 1,10 V 5 h 8 v 4 h 8 V 5 H 12 M 4,9 H 6 M 26,9 H 21 V 5 h 8 m 0,-5 v 9 h 8 V 0 m -4,0 v 9" transform="scale(1.4)" />
|
|
47
|
+
<path d="m 0,7 h 9 m 1,0 h 9" transform="scale(2.8)" />
|
|
48
|
+
<path d="m 0,139.6 h 25.2 m 2.8,0 h 25.2" style="stroke-width:5.6" />
|
|
49
|
+
<path d="m 0,146.6 h 36.4 m -35,12.6 v -7 h 11.2 v 5.6 h 11.2 v -5.6 h -7 m -11.2,5.6 h 2.8 m 28,0 h -7 v -5.6 h 11.2 m 0,-7 v 12.6 h 11.2 v -12.6 m -5.6,0 v 12.6" style="stroke-width:2.8" />
|
|
50
|
+
</g>
|
|
51
|
+
</g>
|
|
52
|
+
<g transform="translate(392)">
|
|
53
|
+
<g fill="none" stroke="#ffffff" stroke-width="2">
|
|
54
|
+
<path d="M 0,1 H 26 M 1,10 V 5 h 8 v 4 h 8 V 5 H 12 M 4,9 H 6 M 26,9 H 21 V 5 h 8 m 0,-5 v 9 h 8 V 0 m -4,0 v 9" transform="scale(1.4)" />
|
|
55
|
+
<path d="m 0,7 h 9 m 1,0 h 9" transform="scale(2.8)" />
|
|
56
|
+
<path d="m 0,139.6 h 25.2 m 2.8,0 h 25.2" style="stroke-width:5.6" />
|
|
57
|
+
<path d="m 0,146.6 h 36.4 m -35,12.6 v -7 h 11.2 v 5.6 h 11.2 v -5.6 h -7 m -11.2,5.6 h 2.8 m 28,0 h -7 v -5.6 h 11.2 m 0,-7 v 12.6 h 11.2 v -12.6 m -5.6,0 v 12.6" style="stroke-width:2.8" />
|
|
58
|
+
</g>
|
|
59
|
+
<g>
|
|
60
|
+
<g fill="none" stroke="#ffffff" stroke-width="2" transform="translate(56)">
|
|
61
|
+
<path d="M 0,1 H 26 M 1,10 V 5 h 8 v 4 h 8 V 5 H 12 M 4,9 H 6 M 26,9 H 21 V 5 h 8 m 0,-5 v 9 h 8 V 0 m -4,0 v 9" transform="scale(1.4)" />
|
|
62
|
+
<path d="m 0,7 h 9 m 1,0 h 9" transform="scale(2.8)" />
|
|
63
|
+
<path d="m 0,139.6 h 25.2 m 2.8,0 h 25.2" style="stroke-width:5.6" />
|
|
64
|
+
<path d="m 0,146.6 h 36.4 m -35,12.6 v -7 h 11.2 v 5.6 h 11.2 v -5.6 h -7 m -11.2,5.6 h 2.8 m 28,0 h -7 v -5.6 h 11.2 m 0,-7 v 12.6 h 11.2 v -12.6 m -5.6,0 v 12.6" style="stroke-width:2.8" />
|
|
65
|
+
</g>
|
|
66
|
+
<g fill="none" stroke="#ffffff" stroke-width="2" transform="translate(112)">
|
|
67
|
+
<path d="M 0,1 H 26 M 1,10 V 5 h 8 v 4 h 8 V 5 H 12 M 4,9 H 6 M 26,9 H 21 V 5 h 8 m 0,-5 v 9 h 8 V 0 m -4,0 v 9" transform="scale(1.4)" />
|
|
68
|
+
<path d="m 0,7 h 9 m 1,0 h 9" transform="scale(2.8)" />
|
|
69
|
+
<path d="m 0,139.6 h 25.2 m 2.8,0 h 25.2" style="stroke-width:5.6" />
|
|
70
|
+
<path d="m 0,146.6 h 36.4 m -35,12.6 v -7 h 11.2 v 5.6 h 11.2 v -5.6 h -7 m -11.2,5.6 h 2.8 m 28,0 h -7 v -5.6 h 11.2 m 0,-7 v 12.6 h 11.2 v -12.6 m -5.6,0 v 12.6" style="stroke-width:2.8" />
|
|
71
|
+
</g>
|
|
72
|
+
<g fill="none" stroke="#ffffff" stroke-width="2" transform="translate(168)">
|
|
73
|
+
<path d="M 0,1 H 26 M 1,10 V 5 h 8 v 4 h 8 V 5 H 12 M 4,9 H 6 M 26,9 H 21 V 5 h 8 m 0,-5 v 9 h 8 V 0 m -4,0 v 9" transform="scale(1.4)" />
|
|
74
|
+
<path d="m 0,7 h 9 m 1,0 h 9" transform="scale(2.8)" />
|
|
75
|
+
<path d="m 0,139.6 h 25.2 m 2.8,0 h 25.2" style="stroke-width:5.6" />
|
|
76
|
+
<path d="m 0,146.6 h 36.4 m -35,12.6 v -7 h 11.2 v 5.6 h 11.2 v -5.6 h -7 m -11.2,5.6 h 2.8 m 28,0 h -7 v -5.6 h 11.2 m 0,-7 v 12.6 h 11.2 v -12.6 m -5.6,0 v 12.6" style="stroke-width:2.8" />
|
|
77
|
+
</g>
|
|
78
|
+
</g>
|
|
79
|
+
</g>
|
|
80
|
+
</g>
|
|
81
|
+
<g fill="#da0000" transform="matrix(45,0,0,45,315,180)">
|
|
82
|
+
<g>
|
|
83
|
+
<path d="M-0.54815,0.83638A0.912046,0.912046 0 0,0 0.328544,-0.722384A1,1 0 0,1 -0.54815,0.83638" />
|
|
84
|
+
<path d="M0.618339,0.661409A0.763932,0.763932 0 0,0 0.421644,-0.741049A1,1 0 0,1 0.618339,0.661409" />
|
|
85
|
+
<path d="M0,1 -0.05,0 0,-0.787278A0.309995,0.309995 0 0,0 0.118034,-0.688191V-0.100406L0.077809,0.892905z" />
|
|
86
|
+
<path d="M-0.02,-0.85 0,-0.831217A0.14431,0.14431 0 0,0 0.252075,-0.967708A0.136408,0.136408 0 0,1 0,-0.924634" />
|
|
87
|
+
</g>
|
|
88
|
+
<g transform="scale(-1,1)">
|
|
89
|
+
<path d="M -0.54815,0.83638 A 0.912046,0.912046 0 0 0 0.328544,-0.722384 1,1 0 0 1 -0.54815,0.83638" />
|
|
90
|
+
<path d="M 0.618339,0.661409 A 0.763932,0.763932 0 0 0 0.421644,-0.741049 1,1 0 0 1 0.618339,0.661409" />
|
|
91
|
+
<path d="M 0,1 -0.05,0 0,-0.787278 a 0.309995,0.309995 0 0 0 0.118034,0.099087 v 0.587785 L 0.077809,0.892905 Z" />
|
|
92
|
+
<path d="M -0.02,-0.85 0,-0.831217 A 0.14431,0.14431 0 0 0 0.252075,-0.967708 0.136408,0.136408 0 0 1 0,-0.924634" />
|
|
93
|
+
</g>
|
|
94
|
+
</g>
|
|
95
|
+
</svg>
|
package/src/icons/index.ts
CHANGED
|
@@ -13,6 +13,7 @@ export { default as DashCircleFill } from './DashCircleFill.svg';
|
|
|
13
13
|
export { default as Eraser } from './Eraser.svg';
|
|
14
14
|
export { default as Flag } from './Flag.svg';
|
|
15
15
|
export { default as FlagEs } from './FlagEs.svg';
|
|
16
|
+
export { default as FlagFa } from './FlagFa.svg';
|
|
16
17
|
export { default as FlagFr } from './FlagFr.svg';
|
|
17
18
|
export { default as FlagGb } from './FlagGb.svg';
|
|
18
19
|
export { default as FlagPl } from './FlagPl.svg';
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { Comparator } from 'types';
|
|
2
|
+
|
|
3
|
+
import createStringComparator from './createStringComparator';
|
|
4
|
+
import numberComparator from './numberComparator';
|
|
5
|
+
|
|
6
|
+
const createComparator = <T>(locale: string): Comparator<T> => {
|
|
7
|
+
const stringComparator = createStringComparator(locale);
|
|
8
|
+
|
|
9
|
+
return (a: T, b: T): number => {
|
|
10
|
+
if (typeof a === 'string' && typeof b === 'string') {
|
|
11
|
+
return stringComparator(a, b);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
if (typeof a === 'number' && typeof b === 'number') {
|
|
15
|
+
return numberComparator(a, b);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
return 0;
|
|
19
|
+
};
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
export default createComparator;
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import { Comparator } from 'types';
|
|
2
2
|
|
|
3
|
+
import createStringComparator from './createStringComparator';
|
|
3
4
|
import numberComparator from './numberComparator';
|
|
4
|
-
import stringComparator from './stringComparator';
|
|
5
5
|
|
|
6
|
-
const createKeyComparator = <T extends Record<keyof T, unknown>>(key: keyof T): Comparator<T> => {
|
|
6
|
+
const createKeyComparator = <T extends Record<keyof T, unknown>>(key: keyof T, locale: string): Comparator<T> => {
|
|
7
|
+
const stringComparator = createStringComparator(locale);
|
|
8
|
+
|
|
7
9
|
return (a: T, b: T): number => {
|
|
8
10
|
const aValue = a[key];
|
|
9
11
|
const bValue = b[key];
|
package/src/lib/detectLocale.ts
CHANGED
|
@@ -9,6 +9,10 @@ const detectLocale = (): Locale => {
|
|
|
9
9
|
return Locale.EN_GB;
|
|
10
10
|
}
|
|
11
11
|
|
|
12
|
+
if (window.navigator.languages.includes('fa') || window.navigator.languages.includes('fa-IR')) {
|
|
13
|
+
return Locale.FA_IR;
|
|
14
|
+
}
|
|
15
|
+
|
|
12
16
|
if (window.navigator.languages.includes('fr-FR')) {
|
|
13
17
|
return Locale.FR_FR;
|
|
14
18
|
}
|
|
@@ -5,7 +5,7 @@ import { RemainingTile } from 'types';
|
|
|
5
5
|
|
|
6
6
|
import createKeyComparator from './createKeyComparator';
|
|
7
7
|
|
|
8
|
-
const getRemainingTiles = (config: Config, board: Board, characters: string[]): RemainingTile[] => {
|
|
8
|
+
const getRemainingTiles = (config: Config, board: Board, characters: string[], locale: string): RemainingTile[] => {
|
|
9
9
|
const nonEmptyCells = board.rows.flat().filter((cell) => !cell.isEmpty);
|
|
10
10
|
const letterCells = nonEmptyCells.filter((cell) => !cell.tile.isBlank);
|
|
11
11
|
const remainingTiles = Object.fromEntries(config.tiles.map((tile) => [tile.character, { ...tile, usedCount: 0 }]));
|
|
@@ -36,7 +36,9 @@ const getRemainingTiles = (config: Config, board: Board, characters: string[]):
|
|
|
36
36
|
++remainingTiles[letter].usedCount;
|
|
37
37
|
}
|
|
38
38
|
|
|
39
|
-
|
|
39
|
+
const comparator = createKeyComparator('character', locale);
|
|
40
|
+
|
|
41
|
+
return [...Object.values(remainingTiles).sort(comparator), blank];
|
|
40
42
|
};
|
|
41
43
|
|
|
42
44
|
export default getRemainingTiles;
|
|
@@ -5,39 +5,62 @@ import { RemainingTile, RemainingTilesGroup } from 'types';
|
|
|
5
5
|
import getRemainingTilesCount from './getRemainingTilesCount';
|
|
6
6
|
import getTotalRemainingTilesCount from './getTotalRemainingTilesCount';
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
const consonants = remainingTiles.filter(
|
|
10
|
-
const vowels = remainingTiles.filter(
|
|
11
|
-
const
|
|
12
|
-
const
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
8
|
+
const getRemainingTilesGroups = (remainingTiles: RemainingTile[]): RemainingTilesGroup[] => {
|
|
9
|
+
const consonants = remainingTiles.filter(isConsonant);
|
|
10
|
+
const vowels = remainingTiles.filter(isVowel);
|
|
11
|
+
const other = remainingTiles.filter(isOther);
|
|
12
|
+
const groups: RemainingTilesGroup[] = [];
|
|
13
|
+
|
|
14
|
+
groups.push({
|
|
15
|
+
remainingCount: getRemainingTilesCount(vowels),
|
|
16
|
+
tiles: vowels,
|
|
17
|
+
translationKey: 'common.vowels',
|
|
18
|
+
totalCount: getTotalRemainingTilesCount(vowels),
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
groups.push({
|
|
22
|
+
remainingCount: getRemainingTilesCount(consonants),
|
|
23
|
+
tiles: consonants,
|
|
24
|
+
translationKey: 'common.consonants',
|
|
25
|
+
totalCount: getTotalRemainingTilesCount(consonants),
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
groups.push({
|
|
29
|
+
remainingCount: getRemainingTilesCount(other),
|
|
30
|
+
tiles: other,
|
|
31
|
+
translationKey: 'common.tiles',
|
|
32
|
+
totalCount: getTotalRemainingTilesCount(other),
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
const twoCharacterTiles = remainingTiles.filter(isTwoCharacter);
|
|
36
|
+
const blanks = remainingTiles.filter(isBlank);
|
|
37
|
+
|
|
38
|
+
groups.push({
|
|
39
|
+
remainingCount: getRemainingTilesCount(twoCharacterTiles),
|
|
40
|
+
tiles: twoCharacterTiles,
|
|
41
|
+
translationKey: 'common.two-letter-tiles',
|
|
42
|
+
totalCount: getTotalRemainingTilesCount(twoCharacterTiles),
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
groups.push({
|
|
46
|
+
remainingCount: getRemainingTilesCount(blanks),
|
|
47
|
+
tiles: blanks,
|
|
48
|
+
translationKey: 'common.blanks',
|
|
49
|
+
totalCount: getTotalRemainingTilesCount(blanks),
|
|
50
|
+
});
|
|
39
51
|
|
|
40
52
|
return groups.filter(({ totalCount }) => totalCount > 0);
|
|
41
53
|
};
|
|
42
54
|
|
|
55
|
+
const isConsonant = (tile: RemainingTile): boolean => CONSONANTS.includes(tile.character);
|
|
56
|
+
|
|
57
|
+
const isVowel = (tile: RemainingTile): boolean => VOWELS.includes(tile.character);
|
|
58
|
+
|
|
59
|
+
const isTwoCharacter = (tile: RemainingTile): boolean => tile.character.length === 2;
|
|
60
|
+
|
|
61
|
+
const isBlank = (tile: RemainingTile): boolean => tile.character === BLANK;
|
|
62
|
+
|
|
63
|
+
const isOther = (tile: RemainingTile) =>
|
|
64
|
+
!isConsonant(tile) && !isVowel(tile) && !isBlank(tile) && !isTwoCharacter(tile);
|
|
65
|
+
|
|
43
66
|
export default getRemainingTilesGroups;
|
package/src/lib/index.ts
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
export { default as canUseDom } from './canUseDom';
|
|
2
|
-
export { default as comparator } from './comparator';
|
|
3
2
|
export { default as createArray } from './createArray';
|
|
3
|
+
export { default as createComparator } from './createComparator';
|
|
4
4
|
export { default as createGridOf } from './createGridOf';
|
|
5
5
|
export { default as createKeyboardNavigation } from './createKeyboardNavigation';
|
|
6
6
|
export { default as createKeyComparator } from './createKeyComparator';
|
|
7
7
|
export { default as createNullMovingComparator } from './createNullMovingComparator';
|
|
8
|
+
export { default as createStringComparator } from './createStringComparator';
|
|
8
9
|
export { default as detectLocale } from './detectLocale';
|
|
9
10
|
export { default as extractCharacters } from './extractCharacters';
|
|
10
11
|
export { default as extractInputValue } from './extractInputValue';
|
|
@@ -25,6 +26,5 @@ export { default as noop } from './noop';
|
|
|
25
26
|
export { default as numberComparator } from './numberComparator';
|
|
26
27
|
export { default as reverseComparator } from './reverseComparator';
|
|
27
28
|
export { default as sortResults } from './sortResults';
|
|
28
|
-
export { default as stringComparator } from './stringComparator';
|
|
29
29
|
export { default as unorderedArraysEqual } from './unorderedArraysEqual';
|
|
30
30
|
export { default as zipCharactersAndTiles } from './zipCharactersAndTiles';
|
package/src/lib/sortResults.ts
CHANGED
|
@@ -5,26 +5,28 @@ import { Comparator, ResultColumn, SortDirection } from 'types';
|
|
|
5
5
|
import createKeyComparator from './createKeyComparator';
|
|
6
6
|
import reverseComparator from './reverseComparator';
|
|
7
7
|
|
|
8
|
-
const comparators: Record<ResultColumn, Comparator<Result>> = {
|
|
9
|
-
[ResultColumn.BlanksCount]: createKeyComparator('blanksCount'),
|
|
10
|
-
[ResultColumn.ConsonantsCount]: createKeyComparator('consonantsCount'),
|
|
11
|
-
[ResultColumn.Points]: createKeyComparator('points'),
|
|
12
|
-
[ResultColumn.TilesCount]: createKeyComparator('tilesCount'),
|
|
13
|
-
[ResultColumn.VowelsCount]: createKeyComparator('vowelsCount'),
|
|
14
|
-
[ResultColumn.Word]: createKeyComparator('word'),
|
|
15
|
-
[ResultColumn.WordsCount]: createKeyComparator('wordsCount'),
|
|
8
|
+
const comparators: Record<ResultColumn, (locale: string) => Comparator<Result>> = {
|
|
9
|
+
[ResultColumn.BlanksCount]: (locale: string) => createKeyComparator('blanksCount', locale),
|
|
10
|
+
[ResultColumn.ConsonantsCount]: (locale: string) => createKeyComparator('consonantsCount', locale),
|
|
11
|
+
[ResultColumn.Points]: (locale: string) => createKeyComparator('points', locale),
|
|
12
|
+
[ResultColumn.TilesCount]: (locale: string) => createKeyComparator('tilesCount', locale),
|
|
13
|
+
[ResultColumn.VowelsCount]: (locale: string) => createKeyComparator('vowelsCount', locale),
|
|
14
|
+
[ResultColumn.Word]: (locale: string) => createKeyComparator('word', locale),
|
|
15
|
+
[ResultColumn.WordsCount]: (locale: string) => createKeyComparator('wordsCount', locale),
|
|
16
16
|
};
|
|
17
17
|
|
|
18
18
|
const sortResults = (
|
|
19
19
|
results: Result[] | undefined,
|
|
20
20
|
column: ResultColumn,
|
|
21
21
|
sortDirection: SortDirection,
|
|
22
|
+
locale: string,
|
|
22
23
|
): Result[] | undefined => {
|
|
23
24
|
if (typeof results === 'undefined') {
|
|
24
25
|
return results;
|
|
25
26
|
}
|
|
26
27
|
|
|
27
|
-
const
|
|
28
|
+
const createComparator = comparators[column];
|
|
29
|
+
const comparator = createComparator(locale);
|
|
28
30
|
const finalComparator = sortDirection === SortDirection.Descending ? reverseComparator(comparator) : comparator;
|
|
29
31
|
return [...results].sort(finalComparator);
|
|
30
32
|
};
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
import
|
|
1
|
+
import createComparator from './createComparator';
|
|
2
2
|
|
|
3
|
-
const unorderedArraysEqual = <T>(a: T[], b: T[]): boolean => {
|
|
3
|
+
const unorderedArraysEqual = <T>(a: T[], b: T[], locale: string): boolean => {
|
|
4
4
|
if (a.length !== b.length) {
|
|
5
5
|
return false;
|
|
6
6
|
}
|
|
7
7
|
|
|
8
|
+
const comparator = createComparator(locale);
|
|
8
9
|
const aSorted = [...a].sort(comparator);
|
|
9
10
|
const bSorted = [...b].sort(comparator);
|
|
10
11
|
return aSorted.every((character, index) => character === bSorted[index]);
|
package/src/pages/api/verify.ts
CHANGED
|
@@ -30,7 +30,7 @@ const verify = async (request: NextApiRequest, response: NextApiResponse): Promi
|
|
|
30
30
|
});
|
|
31
31
|
|
|
32
32
|
const trie = await dictionaries.get(locale);
|
|
33
|
-
const words = board.getWords().sort((a, b) => a.localeCompare(b));
|
|
33
|
+
const words = board.getWords().sort((a, b) => a.localeCompare(b, locale));
|
|
34
34
|
const invalidWords = words.filter((word) => !trie.has(word));
|
|
35
35
|
const validWords = words.filter((word) => trie.has(word));
|
|
36
36
|
response.status(200).send({ invalidWords, validWords });
|
|
@@ -58,6 +58,11 @@
|
|
|
58
58
|
align-items: center;
|
|
59
59
|
justify-content: center;
|
|
60
60
|
height: 100%;
|
|
61
|
+
gap: var(--spacing--xl);
|
|
62
|
+
|
|
63
|
+
@include tablet {
|
|
64
|
+
gap: var(--spacing--l);
|
|
65
|
+
}
|
|
61
66
|
}
|
|
62
67
|
|
|
63
68
|
.boardContainer {
|
|
@@ -68,27 +73,11 @@
|
|
|
68
73
|
.sidebar {
|
|
69
74
|
display: flex;
|
|
70
75
|
flex-direction: column;
|
|
71
|
-
padding-left: var(--spacing--xl);
|
|
72
76
|
flex: 0 0 var(--sidebar--width);
|
|
73
|
-
|
|
74
|
-
> * {
|
|
75
|
-
margin-bottom: var(--spacing--xl);
|
|
76
|
-
|
|
77
|
-
&:last-child {
|
|
78
|
-
margin-bottom: 0;
|
|
79
|
-
}
|
|
80
|
-
}
|
|
77
|
+
gap: var(--spacing--xl);
|
|
81
78
|
|
|
82
79
|
@include tablet {
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
> * {
|
|
86
|
-
margin-bottom: var(--spacing--l);
|
|
87
|
-
|
|
88
|
-
&:last-child {
|
|
89
|
-
margin-bottom: 0;
|
|
90
|
-
}
|
|
91
|
-
}
|
|
80
|
+
gap: var(--spacing--l);
|
|
92
81
|
}
|
|
93
82
|
}
|
|
94
83
|
|