scrabble-solver 2.10.2 → 2.10.4

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.
Files changed (235) hide show
  1. package/README.md +29 -18
  2. package/lerna.json +1 -1
  3. package/package.json +2 -2
  4. package/packages/configs/package-lock.json +4 -4
  5. package/packages/configs/package.json +3 -3
  6. package/packages/constants/package-lock.json +2 -2
  7. package/packages/constants/package.json +1 -1
  8. package/packages/dictionaries/package-lock.json +2 -2
  9. package/packages/dictionaries/package.json +4 -4
  10. package/packages/logger/package-lock.json +2 -2
  11. package/packages/logger/package.json +1 -1
  12. package/packages/scrabble-solver/.next/BUILD_ID +1 -1
  13. package/packages/scrabble-solver/.next/build-manifest.json +31 -19
  14. package/packages/scrabble-solver/.next/cache/.tsbuildinfo +1 -1
  15. package/packages/scrabble-solver/.next/cache/eslint/.cache_8dgz12 +1 -1
  16. package/packages/scrabble-solver/.next/cache/next-server.js.nft.json +1 -1
  17. package/packages/scrabble-solver/.next/cache/webpack/client-production/0.pack +0 -0
  18. package/packages/scrabble-solver/.next/cache/webpack/client-production/index.pack +0 -0
  19. package/packages/scrabble-solver/.next/cache/webpack/edge-server-production/0.pack +0 -0
  20. package/packages/scrabble-solver/.next/cache/webpack/edge-server-production/index.pack +0 -0
  21. package/packages/scrabble-solver/.next/cache/webpack/server-production/0.pack +0 -0
  22. package/packages/scrabble-solver/.next/cache/webpack/server-production/index.pack +0 -0
  23. package/packages/scrabble-solver/.next/next-server.js.nft.json +1 -1
  24. package/packages/scrabble-solver/.next/prerender-manifest.json +1 -1
  25. package/packages/scrabble-solver/.next/routes-manifest.json +1 -1
  26. package/packages/scrabble-solver/.next/server/chunks/176.js +1269 -1559
  27. package/packages/scrabble-solver/.next/server/chunks/579.js +50 -26
  28. package/packages/scrabble-solver/.next/server/middleware-build-manifest.js +1 -1
  29. package/packages/scrabble-solver/.next/server/middleware-react-loadable-manifest.js +1 -1
  30. package/packages/scrabble-solver/.next/server/pages/404.html +2 -2
  31. package/packages/scrabble-solver/.next/server/pages/404.js.nft.json +1 -1
  32. package/packages/scrabble-solver/.next/server/pages/500.html +2 -2
  33. package/packages/scrabble-solver/.next/server/pages/_app.js.nft.json +1 -1
  34. package/packages/scrabble-solver/.next/server/pages/api/dictionary/[locale]/[word].js +2 -1
  35. package/packages/scrabble-solver/.next/server/pages/api/solve.js +22 -6
  36. package/packages/scrabble-solver/.next/server/pages/index.html +2 -2
  37. package/packages/scrabble-solver/.next/server/pages/index.js +1539 -52
  38. package/packages/scrabble-solver/.next/server/pages/index.js.nft.json +1 -1
  39. package/packages/scrabble-solver/.next/server/pages/index.json +1 -1
  40. package/packages/scrabble-solver/.next/server/pages-manifest.json +1 -1
  41. package/packages/scrabble-solver/.next/static/P7XhuDLmwJJqC8kgPjX42/_buildManifest.js +1 -0
  42. package/packages/scrabble-solver/.next/static/{FjrbXpI5fkt4lmko-vL_7 → P7XhuDLmwJJqC8kgPjX42}/_ssgManifest.js +0 -0
  43. package/packages/scrabble-solver/.next/static/chunks/490-d29992f1c264d70e.js +5 -0
  44. package/packages/scrabble-solver/.next/static/chunks/528-9942ddad0031ff79.js +1 -0
  45. package/packages/scrabble-solver/.next/static/chunks/pages/{404-24f9617eeb8d6dc1.js → 404-6c99a0c91257c60b.js} +1 -1
  46. package/packages/scrabble-solver/.next/static/chunks/pages/_app-fa0661b072fc6af9.js +24 -0
  47. package/packages/scrabble-solver/.next/static/chunks/pages/index-d761f0af070273d2.js +1 -0
  48. package/packages/scrabble-solver/.next/static/css/78e42ad01f580f64.css +1 -0
  49. package/packages/scrabble-solver/.next/static/css/97eb6ee0c4300c83.css +1 -0
  50. package/packages/scrabble-solver/.next/static/css/dcca0c1a39cf5ef5.css +1 -0
  51. package/packages/scrabble-solver/.next/trace +55 -52
  52. package/packages/scrabble-solver/package-lock.json +27 -2
  53. package/packages/scrabble-solver/package.json +10 -8
  54. package/packages/scrabble-solver/src/components/Badge/Badge.module.scss +4 -5
  55. package/packages/scrabble-solver/src/components/Board/BoardPure.tsx +5 -5
  56. package/packages/scrabble-solver/src/components/Board/components/Cell/Cell.module.scss +15 -2
  57. package/packages/scrabble-solver/src/components/Button/Button.module.scss +10 -38
  58. package/packages/scrabble-solver/src/components/Button/Button.tsx +6 -5
  59. package/packages/scrabble-solver/src/components/Dictionary/Dictionary.module.scss +1 -2
  60. package/packages/scrabble-solver/src/components/Dictionary/Dictionary.tsx +2 -6
  61. package/packages/scrabble-solver/src/components/DictionaryInput/DictionaryInput.module.scss +1 -3
  62. package/packages/scrabble-solver/src/components/EmptyState/EmptyState.module.scss +6 -7
  63. package/packages/scrabble-solver/src/components/EmptyState/EmptyState.tsx +6 -6
  64. package/packages/scrabble-solver/src/components/Key/Key.module.scss +0 -1
  65. package/packages/scrabble-solver/src/components/{Splash/Splash.module.scss → LogoSplashScreen/LogoSplashScreen.module.scss} +1 -1
  66. package/packages/scrabble-solver/src/components/{Splash/Splash.tsx → LogoSplashScreen/LogoSplashScreen.tsx} +7 -7
  67. package/packages/scrabble-solver/src/components/LogoSplashScreen/index.ts +1 -0
  68. package/packages/scrabble-solver/src/components/{Sidebar/Sidebar.module.scss → Modal/Modal.module.scss} +25 -20
  69. package/packages/scrabble-solver/src/components/{Sidebar/Sidebar.tsx → Modal/Modal.tsx} +9 -9
  70. package/packages/scrabble-solver/src/components/{Sidebar → Modal}/components/Section/Section.module.scss +0 -0
  71. package/packages/scrabble-solver/src/components/{Sidebar → Modal}/components/Section/Section.tsx +0 -0
  72. package/packages/scrabble-solver/src/components/{Sidebar → Modal}/components/Section/index.ts +0 -0
  73. package/packages/scrabble-solver/src/components/{Sidebar → Modal}/components/index.ts +0 -0
  74. package/packages/scrabble-solver/src/components/Modal/index.ts +1 -0
  75. package/packages/scrabble-solver/src/components/NavButtons/NavButtons.tsx +22 -3
  76. package/packages/scrabble-solver/src/components/Progress/Progress.module.scss +9 -0
  77. package/packages/scrabble-solver/src/components/Progress/Progress.tsx +38 -0
  78. package/packages/scrabble-solver/src/components/Progress/index.ts +1 -0
  79. package/packages/scrabble-solver/src/components/Rack/Rack.module.scss +2 -0
  80. package/packages/scrabble-solver/src/components/Rack/Rack.tsx +3 -1
  81. package/packages/scrabble-solver/src/components/Rack/RackTile.tsx +3 -2
  82. package/packages/scrabble-solver/src/components/ResultCandidatePicker/ResultCandidatePicker.module.scss +76 -0
  83. package/packages/scrabble-solver/src/components/ResultCandidatePicker/ResultCandidatePicker.tsx +38 -0
  84. package/packages/scrabble-solver/src/components/ResultCandidatePicker/index.ts +1 -0
  85. package/packages/scrabble-solver/src/components/Results/Result.tsx +64 -43
  86. package/packages/scrabble-solver/src/components/Results/Results.module.scss +9 -16
  87. package/packages/scrabble-solver/src/components/Results/Results.tsx +45 -28
  88. package/packages/scrabble-solver/src/components/Results/SolveButton.tsx +9 -7
  89. package/packages/scrabble-solver/src/components/Results/{getColumns.ts → getLocaleColumns.ts} +2 -2
  90. package/packages/scrabble-solver/src/components/Results/types.ts +16 -0
  91. package/packages/scrabble-solver/src/components/Results/useColumns.ts +44 -0
  92. package/packages/scrabble-solver/src/components/ResultsInput/ResultsInput.module.scss +1 -3
  93. package/packages/scrabble-solver/src/components/Sizer/Sizer.module.scss +10 -0
  94. package/packages/scrabble-solver/src/components/Sizer/Sizer.tsx +10 -0
  95. package/packages/scrabble-solver/src/components/Sizer/index.ts +1 -0
  96. package/packages/scrabble-solver/src/components/Solver/Solver.module.scss +83 -27
  97. package/packages/scrabble-solver/src/components/Solver/Solver.tsx +157 -24
  98. package/packages/scrabble-solver/src/components/Solver/components/ApplyButton/ApplyButton.module.scss +5 -0
  99. package/packages/scrabble-solver/src/components/Solver/components/ApplyButton/ApplyButton.tsx +37 -0
  100. package/packages/scrabble-solver/src/components/Solver/components/ApplyButton/index.ts +1 -0
  101. package/packages/scrabble-solver/src/components/Solver/components/EmptyState/EmptyState.module.scss +59 -0
  102. package/packages/scrabble-solver/src/components/Solver/components/EmptyState/EmptyState.tsx +41 -0
  103. package/packages/scrabble-solver/src/components/Solver/components/EmptyState/index.ts +1 -0
  104. package/packages/scrabble-solver/src/components/Solver/components/SolveButton/SolveButton.module.scss +4 -0
  105. package/packages/scrabble-solver/src/components/Solver/components/SolveButton/SolveButton.tsx +42 -0
  106. package/packages/scrabble-solver/src/components/Solver/components/SolveButton/index.ts +1 -0
  107. package/packages/scrabble-solver/src/components/Solver/components/index.ts +3 -0
  108. package/packages/scrabble-solver/src/components/{Screen/Screen.module.scss → SplashScreen/SplashScreen.module.scss} +2 -12
  109. package/packages/scrabble-solver/src/components/{Screen/Screen.tsx → SplashScreen/SplashScreen.tsx} +4 -4
  110. package/packages/scrabble-solver/src/components/SplashScreen/index.ts +1 -0
  111. package/packages/scrabble-solver/src/components/SquareButton/SquareButton.module.scss +3 -3
  112. package/packages/scrabble-solver/src/components/Tile/Tile.module.scss +7 -15
  113. package/packages/scrabble-solver/src/components/Tooltip/Tooltip.module.scss +0 -1
  114. package/packages/scrabble-solver/src/components/index.ts +6 -7
  115. package/packages/scrabble-solver/src/hooks/index.ts +1 -1
  116. package/packages/scrabble-solver/src/hooks/useMediaQuery.ts +11 -0
  117. package/packages/scrabble-solver/src/hooks/usePortal.tsx +1 -1
  118. package/packages/scrabble-solver/src/i18n/de.json +2 -0
  119. package/packages/scrabble-solver/src/i18n/en.json +2 -0
  120. package/packages/scrabble-solver/src/i18n/es.json +2 -0
  121. package/packages/scrabble-solver/src/i18n/fa.json +2 -0
  122. package/packages/scrabble-solver/src/i18n/fr.json +2 -0
  123. package/packages/scrabble-solver/src/i18n/pl.json +2 -0
  124. package/packages/scrabble-solver/src/icons/CardChecklist.svg +5 -0
  125. package/packages/scrabble-solver/src/icons/Check.svg +2 -2
  126. package/packages/scrabble-solver/src/icons/ChevronDown.svg +4 -0
  127. package/packages/scrabble-solver/src/icons/CrossCircleFill.svg +4 -0
  128. package/packages/scrabble-solver/src/icons/{CrossFill.svg → CrossSquareFill.svg} +0 -0
  129. package/packages/scrabble-solver/src/icons/ExclamationTriangleFill.svg +4 -0
  130. package/packages/scrabble-solver/src/icons/InfoCircleFill.svg +4 -0
  131. package/packages/scrabble-solver/src/icons/List.svg +4 -0
  132. package/packages/scrabble-solver/src/icons/Search.svg +4 -0
  133. package/packages/scrabble-solver/src/icons/index.ts +8 -2
  134. package/packages/scrabble-solver/src/{components/KeyMap/KeyMap.tsx → modals/KeyMapModal/KeyMapModal.tsx} +11 -13
  135. package/packages/scrabble-solver/src/{components/KeyMap → modals/KeyMapModal}/components/Mapping/Mapping.module.scss +0 -0
  136. package/packages/scrabble-solver/src/{components/KeyMap → modals/KeyMapModal}/components/Mapping/Mapping.tsx +0 -0
  137. package/packages/scrabble-solver/src/{components/KeyMap → modals/KeyMapModal}/components/Mapping/index.ts +0 -0
  138. package/packages/scrabble-solver/src/{components/KeyMap → modals/KeyMapModal}/components/index.ts +0 -0
  139. package/packages/scrabble-solver/src/modals/KeyMapModal/index.ts +1 -0
  140. package/packages/scrabble-solver/src/{components/KeyMap → modals/KeyMapModal}/keys.tsx +1 -2
  141. package/packages/scrabble-solver/src/modals/MenuModal/MenuModal.module.scss +46 -0
  142. package/packages/scrabble-solver/src/modals/MenuModal/MenuModal.tsx +54 -0
  143. package/packages/scrabble-solver/src/modals/MenuModal/index.ts +1 -0
  144. package/packages/scrabble-solver/src/modals/RemainingTilesModal/RemainingTilesModal.module.scss +28 -0
  145. package/packages/scrabble-solver/src/{components/RemainingTiles/RemainingTiles.tsx → modals/RemainingTilesModal/RemainingTilesModal.tsx} +14 -12
  146. package/packages/scrabble-solver/src/{components/RemainingTiles → modals/RemainingTilesModal/components/Character}/Character.module.scss +6 -2
  147. package/packages/scrabble-solver/src/{components/RemainingTiles → modals/RemainingTilesModal/components/Character}/Character.tsx +11 -3
  148. package/packages/scrabble-solver/src/modals/RemainingTilesModal/components/Character/index.ts +1 -0
  149. package/packages/scrabble-solver/src/modals/RemainingTilesModal/components/index.ts +1 -0
  150. package/packages/scrabble-solver/src/modals/RemainingTilesModal/index.ts +1 -0
  151. package/packages/scrabble-solver/src/modals/ResultsModal/ResultsModal.module.scss +7 -0
  152. package/packages/scrabble-solver/src/modals/ResultsModal/ResultsModal.tsx +58 -0
  153. package/packages/scrabble-solver/src/modals/ResultsModal/index.ts +1 -0
  154. package/packages/scrabble-solver/src/modals/SettingsModal/SettingsModal.tsx +34 -0
  155. package/packages/scrabble-solver/src/{components/Settings → modals/SettingsModal}/components/AutoGroupTilesSetting/AutoGroupTilesSetting.module.scss +0 -0
  156. package/packages/scrabble-solver/src/{components/Settings → modals/SettingsModal}/components/AutoGroupTilesSetting/AutoGroupTilesSetting.tsx +1 -2
  157. package/packages/scrabble-solver/src/{components/Settings → modals/SettingsModal}/components/AutoGroupTilesSetting/constants.ts +0 -0
  158. package/packages/scrabble-solver/src/{components/Settings → modals/SettingsModal}/components/AutoGroupTilesSetting/index.ts +0 -0
  159. package/packages/scrabble-solver/src/{components/Settings → modals/SettingsModal}/components/AutoGroupTilesSetting/lib.ts +0 -0
  160. package/packages/scrabble-solver/src/{components/Settings → modals/SettingsModal}/components/ConfigSetting/ConfigSetting.module.scss +0 -0
  161. package/packages/scrabble-solver/src/{components/Settings → modals/SettingsModal}/components/ConfigSetting/ConfigSetting.tsx +1 -2
  162. package/packages/scrabble-solver/src/{components/Settings → modals/SettingsModal}/components/ConfigSetting/index.ts +0 -0
  163. package/packages/scrabble-solver/src/{components/Settings → modals/SettingsModal}/components/ConfigSetting/options.ts +0 -0
  164. package/packages/scrabble-solver/src/{components/Settings → modals/SettingsModal}/components/ConfigSetting/types.ts +0 -0
  165. package/packages/scrabble-solver/src/{components/Settings → modals/SettingsModal}/components/LocaleSetting/LocaleSetting.module.scss +0 -0
  166. package/packages/scrabble-solver/src/{components/Settings → modals/SettingsModal}/components/LocaleSetting/LocaleSetting.tsx +1 -2
  167. package/packages/scrabble-solver/src/{components/Settings → modals/SettingsModal}/components/LocaleSetting/index.ts +0 -0
  168. package/packages/scrabble-solver/src/{components/Settings → modals/SettingsModal}/components/LocaleSetting/options.ts +0 -0
  169. package/packages/scrabble-solver/src/{components/Settings → modals/SettingsModal}/components/LocaleSetting/types.ts +0 -0
  170. package/packages/scrabble-solver/src/{components/Settings → modals/SettingsModal}/components/index.ts +0 -0
  171. package/packages/scrabble-solver/src/modals/SettingsModal/index.ts +1 -0
  172. package/packages/scrabble-solver/src/{components/Words/Words.module.scss → modals/WordsModal/WordsModal.module.scss} +7 -1
  173. package/packages/scrabble-solver/src/{components/Words/Words.tsx → modals/WordsModal/WordsModal.tsx} +10 -12
  174. package/packages/scrabble-solver/src/modals/WordsModal/index.ts +1 -0
  175. package/packages/scrabble-solver/src/modals/index.ts +6 -0
  176. package/packages/scrabble-solver/src/pages/api/dictionary/[locale]/[word].ts +2 -1
  177. package/packages/scrabble-solver/src/pages/index.module.scss +6 -4
  178. package/packages/scrabble-solver/src/pages/index.tsx +63 -26
  179. package/packages/scrabble-solver/src/parameters/index.ts +28 -6
  180. package/packages/scrabble-solver/src/state/createAppStore.ts +7 -4
  181. package/packages/scrabble-solver/src/styles/mixins.scss +15 -13
  182. package/packages/scrabble-solver/src/styles/variables.scss +15 -17
  183. package/packages/scrabble-solver/src/types/index.ts +2 -0
  184. package/packages/scrabble-solver/tsconfig.json +1 -0
  185. package/packages/solver/package-lock.json +2 -2
  186. package/packages/solver/package.json +5 -5
  187. package/packages/types/package-lock.json +3 -3
  188. package/packages/types/package.json +2 -2
  189. package/packages/word-definitions/package-lock.json +8 -8
  190. package/packages/word-definitions/package.json +2 -2
  191. package/packages/word-lists/package-lock.json +2 -2
  192. package/packages/word-lists/package.json +2 -2
  193. package/packages/scrabble-solver/.next/cache/webpack/client-development/0.pack +0 -0
  194. package/packages/scrabble-solver/.next/cache/webpack/client-development/1.pack +0 -0
  195. package/packages/scrabble-solver/.next/cache/webpack/client-development/2.pack +0 -0
  196. package/packages/scrabble-solver/.next/cache/webpack/client-development/3.pack +0 -0
  197. package/packages/scrabble-solver/.next/cache/webpack/client-development/4.pack +0 -0
  198. package/packages/scrabble-solver/.next/cache/webpack/client-development/index.pack +0 -0
  199. package/packages/scrabble-solver/.next/cache/webpack/client-development/index.pack.old +0 -0
  200. package/packages/scrabble-solver/.next/cache/webpack/server-development/0.pack +0 -0
  201. package/packages/scrabble-solver/.next/cache/webpack/server-development/10.pack_ +0 -0
  202. package/packages/scrabble-solver/.next/cache/webpack/server-development/5.pack_ +0 -0
  203. package/packages/scrabble-solver/.next/cache/webpack/server-development/8.pack_ +0 -0
  204. package/packages/scrabble-solver/.next/cache/webpack/server-development/index.pack +0 -0
  205. package/packages/scrabble-solver/.next/static/FjrbXpI5fkt4lmko-vL_7/_buildManifest.js +0 -1
  206. package/packages/scrabble-solver/.next/static/chunks/361-d16f336a9752a55a.js +0 -1
  207. package/packages/scrabble-solver/.next/static/chunks/724-eb48df4d1ba3df8b.js +0 -5
  208. package/packages/scrabble-solver/.next/static/chunks/amp.js +0 -720
  209. package/packages/scrabble-solver/.next/static/chunks/main.js +0 -1076
  210. package/packages/scrabble-solver/.next/static/chunks/pages/_app-959e495f0f221247.js +0 -24
  211. package/packages/scrabble-solver/.next/static/chunks/pages/_app.js +0 -2121
  212. package/packages/scrabble-solver/.next/static/chunks/pages/_error.js +0 -28
  213. package/packages/scrabble-solver/.next/static/chunks/pages/index-1e30dafa41bddb80.js +0 -1
  214. package/packages/scrabble-solver/.next/static/chunks/pages/index.js +0 -5314
  215. package/packages/scrabble-solver/.next/static/chunks/react-refresh.js +0 -62
  216. package/packages/scrabble-solver/.next/static/chunks/webpack.js +0 -1237
  217. package/packages/scrabble-solver/.next/static/css/aafd07997120f1e4.css +0 -1
  218. package/packages/scrabble-solver/.next/static/css/c8d26240c04079b9.css +0 -1
  219. package/packages/scrabble-solver/.next/static/css/eb9d57f7103525ab.css +0 -1
  220. package/packages/scrabble-solver/.next/static/development/_buildManifest.js +0 -1
  221. package/packages/scrabble-solver/.next/static/development/_ssgManifest.js +0 -1
  222. package/packages/scrabble-solver/.next/static/webpack/fb4b50d5e70ee127.webpack.hot-update.json +0 -1
  223. package/packages/scrabble-solver/.next/static/webpack/pages/index.fb4b50d5e70ee127.hot-update.js +0 -171
  224. package/packages/scrabble-solver/.next/static/webpack/webpack.fb4b50d5e70ee127.hot-update.js +0 -18
  225. package/packages/scrabble-solver/src/components/KeyMap/index.ts +0 -1
  226. package/packages/scrabble-solver/src/components/RemainingTiles/RemainingTiles.module.scss +0 -16
  227. package/packages/scrabble-solver/src/components/RemainingTiles/index.ts +0 -1
  228. package/packages/scrabble-solver/src/components/Screen/index.ts +0 -1
  229. package/packages/scrabble-solver/src/components/Settings/Settings.tsx +0 -35
  230. package/packages/scrabble-solver/src/components/Settings/index.ts +0 -1
  231. package/packages/scrabble-solver/src/components/Sidebar/index.ts +0 -1
  232. package/packages/scrabble-solver/src/components/Splash/index.ts +0 -1
  233. package/packages/scrabble-solver/src/components/Words/index.ts +0 -1
  234. package/packages/scrabble-solver/src/hooks/useIsTablet.ts +0 -10
  235. package/packages/scrabble-solver/src/icons/Play.svg +0 -4
@@ -2,33 +2,42 @@ import classNames from 'classnames';
2
2
  import fs from 'fs';
3
3
  import path from 'path';
4
4
  import { AnimationEvent, FunctionComponent, useEffect, useState } from 'react';
5
- import Modal from 'react-modal';
5
+ import ReactModal from 'react-modal';
6
6
  import { useDispatch } from 'react-redux';
7
- import { useEffectOnce } from 'react-use';
7
+ import { useEffectOnce, useMeasure } from 'react-use';
8
8
 
9
- import { KeyMap, Logo, NavButtons, RemainingTiles, Settings, Solver, Splash, SvgFontFix, Words } from 'components';
10
- import { useDirection, useLanguage, useLocalStorage } from 'hooks';
9
+ import { Logo, LogoSplashScreen, NavButtons, Solver, SvgFontFix } from 'components';
10
+ import { useDirection, useLanguage, useLocalStorage, useMediaQuery } from 'hooks';
11
11
  import { LOCALE_FEATURES } from 'i18n';
12
+ import { KeyMapModal, MenuModal, RemainingTilesModal, ResultsModal, SettingsModal, WordsModal } from 'modals';
12
13
  import { INITIALIZATION_DURATION } from 'parameters';
13
14
  import { registerServiceWorker } from 'serviceWorkerManager';
14
15
  import { initialize, localStorage, reset, selectLocale, useTypedSelector } from 'state';
15
16
 
16
17
  import styles from './index.module.scss';
17
18
 
18
- Modal.setAppElement('#__next');
19
+ ReactModal.setAppElement('#__next');
19
20
 
20
21
  interface Props {
21
22
  version: string;
22
23
  }
23
24
 
25
+ // eslint-disable-next-line max-statements
24
26
  const Index: FunctionComponent<Props> = ({ version }) => {
25
27
  const dispatch = useDispatch();
26
28
  const locale = useTypedSelector(selectLocale);
29
+ const isLessThanL = useMediaQuery('<l');
27
30
  const [showKeyMap, setShowKeyMap] = useState(false);
31
+ const [showMenu, setShowMenu] = useState(false);
28
32
  const [showRemainingTiles, setShowRemainingTiles] = useState(false);
33
+ const [showResults, setShowResults] = useState(false);
29
34
  const [showSettings, setShowSettings] = useState(false);
30
35
  const [showWords, setShowWords] = useState(false);
31
36
  const [isInitialized, setIsInitialized] = useState(false);
37
+ const [indexRef, { height: indexHeight, width: indexWidth }] = useMeasure<HTMLDivElement>();
38
+ const [navRef, { height: navHeight }] = useMeasure<HTMLDivElement>();
39
+ const solverHeight = indexHeight - navHeight;
40
+ const solverWidth = indexWidth;
32
41
 
33
42
  const handleClear = () => {
34
43
  dispatch(reset());
@@ -48,11 +57,17 @@ const Index: FunctionComponent<Props> = ({ version }) => {
48
57
  useEffectOnce(() => {
49
58
  dispatch(initialize());
50
59
 
51
- setTimeout(() => {
60
+ globalThis.setTimeout(() => {
52
61
  setIsInitialized(true);
53
62
  }, INITIALIZATION_DURATION);
54
63
  });
55
64
 
65
+ useEffect(() => {
66
+ if (!isLessThanL) {
67
+ setShowResults(false);
68
+ }
69
+ }, [isLessThanL]);
70
+
56
71
  useEffect(() => {
57
72
  if (process.env.NODE_ENV === 'production') {
58
73
  registerServiceWorker();
@@ -63,31 +78,53 @@ const Index: FunctionComponent<Props> = ({ version }) => {
63
78
  <>
64
79
  <SvgFontFix />
65
80
 
66
- <div className={classNames(styles.index, { [styles.initialized]: isInitialized })}>
67
- <div className={styles.nav}>
68
- <div className={styles.navLogo}>
69
- <a className={styles.logoContainer} href="/" title={version}>
70
- <Logo className={styles.logo} />
71
- </a>
81
+ <div className={classNames(styles.index, { [styles.initialized]: isInitialized })} ref={indexRef}>
82
+ <div className={styles.nav} ref={navRef}>
83
+ <div className={styles.navContent}>
84
+ <div className={styles.navLogo}>
85
+ <a className={styles.logoContainer} href="/" title={version}>
86
+ <Logo className={styles.logo} />
87
+ </a>
88
+ </div>
89
+
90
+ <NavButtons
91
+ onClear={handleClear}
92
+ onShowKeyMap={() => setShowKeyMap(true)}
93
+ onShowMenu={() => setShowMenu(true)}
94
+ onShowRemainingTiles={() => setShowRemainingTiles(true)}
95
+ onShowSettings={() => setShowSettings(true)}
96
+ onShowWords={() => setShowWords(true)}
97
+ />
72
98
  </div>
73
-
74
- <NavButtons
75
- onClear={handleClear}
76
- onShowKeyMap={() => setShowKeyMap(true)}
77
- onShowRemainingTiles={() => setShowRemainingTiles(true)}
78
- onShowSettings={() => setShowSettings(true)}
79
- onShowWords={() => setShowWords(true)}
80
- />
81
99
  </div>
82
100
 
83
- <Solver className={styles.solver} />
101
+ <Solver
102
+ className={styles.solver}
103
+ height={solverHeight}
104
+ width={solverWidth}
105
+ onShowResults={() => setShowResults(true)}
106
+ />
84
107
  </div>
85
108
 
86
- <Settings isOpen={showSettings} onClose={() => setShowSettings(false)} />
87
- <KeyMap isOpen={showKeyMap} onClose={() => setShowKeyMap(false)} />
88
- <Words isOpen={showWords} onClose={() => setShowWords(false)} />
89
- <RemainingTiles isOpen={showRemainingTiles} onClose={() => setShowRemainingTiles(false)} />
90
- <Splash forceShow={!isInitialized} onAnimationEnd={handleSplashAnimationEnd} />
109
+ <MenuModal
110
+ isOpen={showMenu}
111
+ onClose={() => setShowMenu(false)}
112
+ onShowRemainingTiles={() => setShowRemainingTiles(true)}
113
+ onShowSettings={() => setShowSettings(true)}
114
+ onShowWords={() => setShowWords(true)}
115
+ />
116
+
117
+ <SettingsModal isOpen={showSettings} onClose={() => setShowSettings(false)} />
118
+
119
+ <KeyMapModal isOpen={showKeyMap} onClose={() => setShowKeyMap(false)} />
120
+
121
+ <WordsModal isOpen={showWords} onClose={() => setShowWords(false)} />
122
+
123
+ <RemainingTilesModal isOpen={showRemainingTiles} onClose={() => setShowRemainingTiles(false)} />
124
+
125
+ <ResultsModal isOpen={showResults} onClose={() => setShowResults(false)} />
126
+
127
+ <LogoSplashScreen forceShow={!isInitialized} onAnimationEnd={handleSplashAnimationEnd} />
91
128
  </>
92
129
  );
93
130
  };
@@ -1,3 +1,11 @@
1
+ export const BREAKPOINTS = {
2
+ xs: 480,
3
+ s: 768,
4
+ m: 992,
5
+ l: 1200,
6
+ xl: 1400,
7
+ };
8
+
1
9
  export const GITHUB_PROJECT_URL = 'https://github.com/kamilmielnik/scrabble-solver';
2
10
 
3
11
  export const INITIALIZATION_DURATION = 100;
@@ -11,15 +19,24 @@ export const COLOR_RED = '#f7c2aa';
11
19
  export const COLOR_YELLOW = '#efe3ae';
12
20
 
13
21
  export const COMPONENTS_SPACING = 40;
14
- export const COMPONENTS_SPACING_MOBILE = 20;
22
+ export const COMPONENTS_SPACING_SMALL = 20;
15
23
 
16
24
  export const BOARD_CELL_BORDER_WIDTH = 1;
17
25
  export const BOARD_TILE_FONT_SIZE_MIN = 14;
18
26
  export const BOARD_TILE_FONT_SIZE_POINTS_MIN = 10;
19
27
  export const BOARD_TILE_SIZE_MAX = 64;
20
- export const BOARD_TILE_SIZE_MIN = 32;
28
+ /**
29
+ * 20 - fits all board tiles without horizontal scrollbar on 360px viewport width (font-size: 14px)
30
+ * 21 - fits all board tiles without horizontal scrollbar on 375px viewport width (font-size: 14px)
31
+ * 26 - tiles start to look good (font-size: 16px)
32
+ */
33
+ export const BOARD_TILE_SIZE_MIN = 20;
34
+
35
+ export const BORDER_WIDTH = 1;
21
36
 
22
- export const DICTIONARY_HEIGHT = 220;
37
+ export const COLUMN_MIN_HEIGHT = 588.5;
38
+
39
+ export const DICTIONARY_HEIGHT = 260;
23
40
 
24
41
  export const TILE_SIZE = 80;
25
42
 
@@ -45,8 +62,13 @@ export const PLAIN_TILES_TILE_SIZE = 80;
45
62
  export const PLAIN_TILES_VERSION_TILE_COLOR = COLOR_GREEN;
46
63
  export const PLAIN_TILES_VERSION_TILE_SIZE = TILE_SIZE;
47
64
 
65
+ export const PROGRESS_COLOR_VALUE = 'var(--color--violet--light)';
66
+ export const PROGRESS_COLOR_BACKGROUND = 'var(--color--inactive)';
67
+
68
+ export const RACK_TILE_SIZE_MAX = 80;
69
+
48
70
  export const REMAINING_TILES_TILE_SIZE = 50;
49
71
 
50
- export const RESULTS_HEADER_HEIGHT = 35;
51
- export const RESULTS_ITEM_HEIGHT = 34;
52
- export const RESULTS_INPUT_HEIGHT = 43;
72
+ export const RESULTS_HEADER_HEIGHT = 34;
73
+ export const RESULTS_ITEM_HEIGHT = 40;
74
+ export const RESULTS_INPUT_HEIGHT = 40;
@@ -1,4 +1,4 @@
1
- import { createStore, applyMiddleware } from 'redux';
1
+ import { applyMiddleware, compose, createStore } from 'redux';
2
2
  import reduxSaga from 'redux-saga';
3
3
 
4
4
  import rootReducer from './rootReducer';
@@ -8,12 +8,15 @@ import { RootState } from './types';
8
8
  const sagaMiddleware = reduxSaga();
9
9
  const initialState: Partial<RootState> | undefined = undefined;
10
10
 
11
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
12
+ // @ts-ignore
13
+ // eslint-disable-next-line no-underscore-dangle
14
+ const composeEnhancers = globalThis.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
15
+
11
16
  const createAppStore = (): ReturnType<typeof createStore> => {
12
- const store = createStore(rootReducer, initialState, createEnhancer());
17
+ const store = createStore(rootReducer, initialState, composeEnhancers(applyMiddleware(sagaMiddleware)));
13
18
  sagaMiddleware.run(rootSaga);
14
19
  return store;
15
20
  };
16
21
 
17
- const createEnhancer = () => applyMiddleware(sagaMiddleware);
18
-
19
22
  export default createAppStore;
@@ -1,12 +1,16 @@
1
- @mixin tablet {
2
- @media (max-width: 1024px) {
3
- @content;
4
- }
1
+ @import 'include-media';
5
2
 
6
- @media (max-height: 800px) {
7
- @content;
8
- }
9
- }
3
+ $breakpoints: (
4
+ xs: 480px,
5
+ s: 768px,
6
+ m: 992px,
7
+ l: 1200px,
8
+ xl: 1400px,
9
+ );
10
+
11
+ $media-expressions: (
12
+ touch: '(hover: none)',
13
+ );
10
14
 
11
15
  /**
12
16
  * It does not work when applied on input elements.
@@ -24,7 +28,7 @@
24
28
  z-index: 1;
25
29
  transition: var(--transition);
26
30
  border-radius: var(--border--radius);
27
- box-shadow: 0 0 0 var(--focus--box-shadow--size) transparent;
31
+ box-shadow: 0 0 0 var(--box-shadow--focus--spread) transparent;
28
32
  pointer-events: none;
29
33
  }
30
34
 
@@ -35,7 +39,7 @@
35
39
  }
36
40
 
37
41
  &:after {
38
- box-shadow: 0 0 0 var(--focus--box-shadow--size) var(--color--focus);
42
+ box-shadow: 0 0 0 var(--box-shadow--focus--spread) var(--color--focus);
39
43
  }
40
44
  }
41
45
  }
@@ -65,12 +69,10 @@
65
69
 
66
70
  @mixin text-input {
67
71
  width: 100%;
68
- min-height: var(--text-input--height);
69
72
  height: var(--text-input--height);
70
- max-height: var(--text-input--height);
71
73
  padding: 0 var(--spacing--l);
72
74
  transition: var(--transition);
73
- font-size: var(--font--size--s);
75
+ font-size: var(--font--size--m);
74
76
  font-family: var(--font--family);
75
77
  }
76
78
 
@@ -13,24 +13,19 @@ $easeOutSine: cubic-bezier(0.61, 1, 0.88, 1);
13
13
  --box-shadow--offset--negative: calc(-1 * var(--box-shadow--offset));
14
14
  --box-shadow--color: #{rgba(#000, 0.15)};
15
15
  --box-shadow: 0 0 var(--box-shadow--blur) var(--box-shadow--spread) var(--box-shadow--color);
16
+ --box-shadow--focus--spread: 6px;
16
17
  --box-shadow--null: 0 0 var(--box-shadow--blur) var(--box-shadow--spread) transparent;
17
- --box-shadow--top: 0 var(--box-shadow--offset--negative) var(--box-shadow--blur) var(--box-shadow--spread)
18
- var(--box-shadow--color);
19
- --box-shadow--bottom: 0 var(--box-shadow--offset) var(--box-shadow--blur) var(--box-shadow--spread)
20
- var(--box-shadow--color);
21
- --box-shadow--left: var(--box-shadow--offset--negative) 0 var(--box-shadow--blur) var(--box-shadow--spread)
22
- var(--box-shadow--color);
23
- --box-shadow--right: var(--box-shadow--offset) 0 var(--box-shadow--blur) var(--box-shadow--spread)
24
- var(--box-shadow--color);
25
18
  --box-shadow--error: 0 0 var(--box-shadow--blur) var(--box-shadow--spread) var(--color--error);
26
19
 
27
20
  --color--background: #f4f4f4;
28
21
  --color--background--secondary: #111;
29
22
  --color--background--overlay: rgba(255, 255, 255, 0.65);
30
- --color--error: #fc3d3d;
23
+ --color--error: hsl(0deg, 92%, 62%);
31
24
  --color--success: #00a900;
25
+ --color--info: var(--color--dark-blue);
26
+ --color--warning: hsl(35deg, 90%, 60%);
32
27
  --color--focus: #{rgba(#268fff, 0.5)};
33
- --color--foreground: black;
28
+ --color--foreground: #222;
34
29
  --color--foreground--secondary: #444;
35
30
  --color--inactive: #cdcdcd;
36
31
  --color--primary: var(--color--violet);
@@ -59,11 +54,11 @@ $easeOutSine: cubic-bezier(0.61, 1, 0.88, 1);
59
54
  --font--size--h2: 22px;
60
55
  --font--size--h3: 18px;
61
56
  --font--size--m: 16px;
62
- --font--size--s: 14px;
63
- --font--size--xs: 12px;
64
57
 
65
58
  --line-height: 1.5;
66
59
 
60
+ --opacity--disabled: 0.3;
61
+
67
62
  --spacing--xs: 2px;
68
63
  --spacing--s: 5px;
69
64
  --spacing--m: 10px;
@@ -76,12 +71,15 @@ $easeOutSine: cubic-bezier(0.61, 1, 0.88, 1);
76
71
  --transition--easing: #{$easeOutSine};
77
72
  --transition: all var(--transition--duration) var(--transition--easing);
78
73
 
79
- --focus--box-shadow--size: 6px;
74
+ --z-index--modal: 100;
75
+ --z-index--close-button: 101;
80
76
 
81
- --sidebar--width: 580px;
82
- --dictionary--height: 220px;
83
- --square-button-size: 32px;
84
- --text-input--height: 42px;
77
+ --dictionary--height: 260px;
78
+ --modal--width: 370px;
79
+ --solver-column--width: 580px;
80
+ --square-button--size: 32px;
81
+ --button--icon--size: 24px;
82
+ --text-input--height: 40px;
85
83
  --tooltip--background: #222;
86
84
  --tooltip--foreground: #fff;
87
85
  }
@@ -68,8 +68,10 @@ export type TranslationKey =
68
68
  | 'keyMap.board-and-rack.submit'
69
69
  | 'keyMap.rack'
70
70
  | 'keyMap.rack.insert-blank'
71
+ | 'menu'
71
72
  | 'rack.placeholder'
72
73
  | 'remaining-tiles'
74
+ | 'results'
73
75
  | 'results.empty-state.no-filtered-results'
74
76
  | 'results.empty-state.no-results'
75
77
  | 'results.empty-state.outdated'
@@ -15,6 +15,7 @@
15
15
  "icons": ["./src/icons"],
16
16
  "i18n": ["./src/i18n"],
17
17
  "lib": ["./src/lib"],
18
+ "modals": ["./src/modals"],
18
19
  "pages": ["./src/pages"],
19
20
  "parameters": ["./src/parameters"],
20
21
  "sdk": ["./src/sdk"],
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@scrabble-solver/solver",
3
- "version": "2.10.2",
3
+ "version": "2.10.4",
4
4
  "lockfileVersion": 2,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "@scrabble-solver/solver",
9
- "version": "2.10.2",
9
+ "version": "2.10.4",
10
10
  "license": "CC-BY-NC-ND-4.0",
11
11
  "dependencies": {
12
12
  "@kamilmielnik/trie": "^2.0.1"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@scrabble-solver/solver",
3
- "version": "2.10.2",
3
+ "version": "2.10.4",
4
4
  "description": "Scrabble Solver 2 - Solver",
5
5
  "main": "build/index.js",
6
6
  "types": "build/index.d.ts",
@@ -25,12 +25,12 @@
25
25
  },
26
26
  "dependencies": {
27
27
  "@kamilmielnik/trie": "^2.0.1",
28
- "@scrabble-solver/types": "^2.10.2"
28
+ "@scrabble-solver/types": "^2.10.4"
29
29
  },
30
30
  "devDependencies": {
31
- "@scrabble-solver/configs": "^2.10.2",
32
- "@scrabble-solver/constants": "^2.10.2",
33
- "@scrabble-solver/dictionaries": "^2.10.2"
31
+ "@scrabble-solver/configs": "^2.10.4",
32
+ "@scrabble-solver/constants": "^2.10.4",
33
+ "@scrabble-solver/dictionaries": "^2.10.4"
34
34
  },
35
35
  "gitHead": "1e2d1ad49a288d4a44196d8e3336740da132c637"
36
36
  }
@@ -1,15 +1,15 @@
1
1
  {
2
2
  "name": "@scrabble-solver/types",
3
- "version": "2.10.2",
3
+ "version": "2.10.4",
4
4
  "lockfileVersion": 2,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "@scrabble-solver/types",
9
- "version": "2.10.2",
9
+ "version": "2.10.4",
10
10
  "license": "CC-BY-NC-ND-4.0",
11
11
  "dependencies": {
12
- "@scrabble-solver/constants": "^2.10.2"
12
+ "@scrabble-solver/constants": "^2.10.4"
13
13
  }
14
14
  },
15
15
  "node_modules/@scrabble-solver/constants": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@scrabble-solver/types",
3
- "version": "2.10.2",
3
+ "version": "2.10.4",
4
4
  "description": "Scrabble Solver 2 - Types",
5
5
  "main": "build/index.js",
6
6
  "types": "build/index.d.ts",
@@ -24,7 +24,7 @@
24
24
  "clean:force": "npm run clean && rimraf package-lock.json"
25
25
  },
26
26
  "dependencies": {
27
- "@scrabble-solver/constants": "^2.10.2"
27
+ "@scrabble-solver/constants": "^2.10.4"
28
28
  },
29
29
  "gitHead": "1e2d1ad49a288d4a44196d8e3336740da132c637"
30
30
  }
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@scrabble-solver/word-definitions",
3
- "version": "2.10.2",
3
+ "version": "2.10.4",
4
4
  "lockfileVersion": 2,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "@scrabble-solver/word-definitions",
9
- "version": "2.10.2",
9
+ "version": "2.10.4",
10
10
  "license": "CC-BY-NC-ND-4.0",
11
11
  "dependencies": {
12
12
  "cheerio": "^1.0.0-rc.12",
@@ -27,9 +27,9 @@
27
27
  }
28
28
  },
29
29
  "node_modules/@types/node": {
30
- "version": "18.11.18",
31
- "resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.18.tgz",
32
- "integrity": "sha512-DHQpWGjyQKSHj3ebjFI/wRKcqQcdR+MoFBygntYOZytCqNfkd2ZC4ARDJ2DQqhjH5p85Nnd3jhUJIXrszFX/JA==",
30
+ "version": "18.14.0",
31
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-18.14.0.tgz",
32
+ "integrity": "sha512-5EWrvLmglK+imbCJY0+INViFWUHg1AHel1sq4ZVSfdcNqGy9Edv3UB9IIzzg+xPaUcAgZYcfVs2fBcwDeZzU0A==",
33
33
  "dev": true
34
34
  },
35
35
  "node_modules/boolbase": {
@@ -249,9 +249,9 @@
249
249
  }
250
250
  },
251
251
  "@types/node": {
252
- "version": "18.11.18",
253
- "resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.18.tgz",
254
- "integrity": "sha512-DHQpWGjyQKSHj3ebjFI/wRKcqQcdR+MoFBygntYOZytCqNfkd2ZC4ARDJ2DQqhjH5p85Nnd3jhUJIXrszFX/JA==",
252
+ "version": "18.14.0",
253
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-18.14.0.tgz",
254
+ "integrity": "sha512-5EWrvLmglK+imbCJY0+INViFWUHg1AHel1sq4ZVSfdcNqGy9Edv3UB9IIzzg+xPaUcAgZYcfVs2fBcwDeZzU0A==",
255
255
  "dev": true
256
256
  },
257
257
  "boolbase": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@scrabble-solver/word-definitions",
3
- "version": "2.10.2",
3
+ "version": "2.10.4",
4
4
  "description": "Scrabble Solver 2 - Word definitions",
5
5
  "main": "build/index.js",
6
6
  "types": "build/index.d.ts",
@@ -23,7 +23,7 @@
23
23
  "clean": "rimraf build/ node_modules/ package-lock.json"
24
24
  },
25
25
  "dependencies": {
26
- "@scrabble-solver/types": "^2.10.2",
26
+ "@scrabble-solver/types": "^2.10.4",
27
27
  "cheerio": "^1.0.0-rc.12",
28
28
  "follow-redirects": "^1.15.2",
29
29
  "striptags": "^3.2.0"
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@scrabble-solver/word-lists",
3
- "version": "2.10.2",
3
+ "version": "2.10.4",
4
4
  "lockfileVersion": 2,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "@scrabble-solver/word-lists",
9
- "version": "2.10.2",
9
+ "version": "2.10.4",
10
10
  "license": "CC-BY-NC-ND-4.0",
11
11
  "dependencies": {
12
12
  "cheerio": "^1.0.0-rc.12",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@scrabble-solver/word-lists",
3
- "version": "2.10.2",
3
+ "version": "2.10.4",
4
4
  "description": "Scrabble Solver 2 - Word lists",
5
5
  "main": "build/index.js",
6
6
  "types": "build/index.d.ts",
@@ -24,7 +24,7 @@
24
24
  "clean:force": "npm run clean && rimraf package-lock.json"
25
25
  },
26
26
  "dependencies": {
27
- "@scrabble-solver/types": "^2.10.2",
27
+ "@scrabble-solver/types": "^2.10.4",
28
28
  "cheerio": "^1.0.0-rc.12",
29
29
  "follow-redirects": "^1.15.2",
30
30
  "unzipper": "^0.10.11"
@@ -1 +0,0 @@
1
- self.__BUILD_MANIFEST=function(s,e,a){return{__rewrites:{beforeFiles:[],afterFiles:[],fallback:[]},"/":[s,e,a,"static/css/aafd07997120f1e4.css","static/chunks/pages/index-1e30dafa41bddb80.js"],"/404":[s,e,a,"static/chunks/pages/404-24f9617eeb8d6dc1.js"],"/_error":["static/chunks/pages/_error-8353112a01355ec2.js"],sortedPages:["/","/404","/_app","/_error"]}}("static/chunks/724-eb48df4d1ba3df8b.js","static/css/c8d26240c04079b9.css","static/chunks/361-d16f336a9752a55a.js"),self.__BUILD_MANIFEST_CB&&self.__BUILD_MANIFEST_CB();