absfuyu 5.2.0__py3-none-any.whl → 5.4.0__py3-none-any.whl

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.

Potentially problematic release.


This version of absfuyu might be problematic. Click here for more details.

Files changed (73) hide show
  1. absfuyu/__init__.py +1 -1
  2. absfuyu/__main__.py +2 -2
  3. absfuyu/cli/__init__.py +2 -2
  4. absfuyu/cli/color.py +2 -2
  5. absfuyu/cli/config_group.py +2 -2
  6. absfuyu/cli/do_group.py +12 -2
  7. absfuyu/cli/game_group.py +2 -2
  8. absfuyu/cli/tool_group.py +2 -2
  9. absfuyu/config/__init__.py +2 -2
  10. absfuyu/core/__init__.py +2 -2
  11. absfuyu/core/baseclass.py +32 -2
  12. absfuyu/core/baseclass2.py +2 -2
  13. absfuyu/core/decorator.py +2 -2
  14. absfuyu/core/docstring.py +2 -2
  15. absfuyu/core/dummy_cli.py +2 -2
  16. absfuyu/core/dummy_func.py +2 -2
  17. absfuyu/dxt/__init__.py +2 -2
  18. absfuyu/dxt/dictext.py +15 -6
  19. absfuyu/dxt/dxt_support.py +2 -2
  20. absfuyu/dxt/intext.py +51 -33
  21. absfuyu/dxt/listext.py +138 -10
  22. absfuyu/dxt/strext.py +2 -2
  23. absfuyu/extra/__init__.py +2 -2
  24. absfuyu/extra/beautiful.py +2 -2
  25. absfuyu/extra/da/__init__.py +2 -2
  26. absfuyu/extra/da/dadf.py +57 -41
  27. absfuyu/extra/da/dadf_base.py +2 -2
  28. absfuyu/extra/da/df_func.py +2 -2
  29. absfuyu/extra/da/mplt.py +2 -2
  30. absfuyu/extra/data_analysis.py +2 -2
  31. absfuyu/fun/__init__.py +7 -2
  32. absfuyu/fun/rubik.py +442 -0
  33. absfuyu/fun/tarot.py +2 -2
  34. absfuyu/game/__init__.py +2 -2
  35. absfuyu/game/game_stat.py +2 -2
  36. absfuyu/game/sudoku.py +2 -2
  37. absfuyu/game/tictactoe.py +2 -2
  38. absfuyu/game/wordle.py +2 -2
  39. absfuyu/general/__init__.py +2 -2
  40. absfuyu/general/content.py +2 -2
  41. absfuyu/general/human.py +2 -2
  42. absfuyu/general/shape.py +2 -2
  43. absfuyu/logger.py +2 -2
  44. absfuyu/pkg_data/__init__.py +2 -2
  45. absfuyu/pkg_data/deprecated.py +2 -2
  46. absfuyu/sort.py +2 -2
  47. absfuyu/tools/__init__.py +4 -4
  48. absfuyu/tools/checksum.py +2 -2
  49. absfuyu/tools/converter.py +2 -2
  50. absfuyu/tools/generator.py +2 -2
  51. absfuyu/tools/inspector.py +41 -6
  52. absfuyu/tools/keygen.py +2 -2
  53. absfuyu/tools/obfuscator.py +2 -2
  54. absfuyu/tools/passwordlib.py +2 -2
  55. absfuyu/tools/shutdownizer.py +2 -2
  56. absfuyu/tools/web.py +2 -2
  57. absfuyu/typings.py +7 -2
  58. absfuyu/util/__init__.py +57 -3
  59. absfuyu/util/api.py +2 -2
  60. absfuyu/util/json_method.py +2 -2
  61. absfuyu/util/lunar.py +2 -2
  62. absfuyu/util/path.py +158 -4
  63. absfuyu/util/performance.py +2 -2
  64. absfuyu/util/shorten_number.py +2 -2
  65. absfuyu/util/text_table.py +220 -64
  66. absfuyu/util/zipped.py +2 -2
  67. absfuyu/version.py +2 -2
  68. {absfuyu-5.2.0.dist-info → absfuyu-5.4.0.dist-info}/METADATA +1 -1
  69. absfuyu-5.4.0.dist-info/RECORD +77 -0
  70. absfuyu-5.2.0.dist-info/RECORD +0 -76
  71. {absfuyu-5.2.0.dist-info → absfuyu-5.4.0.dist-info}/WHEEL +0 -0
  72. {absfuyu-5.2.0.dist-info → absfuyu-5.4.0.dist-info}/entry_points.txt +0 -0
  73. {absfuyu-5.2.0.dist-info → absfuyu-5.4.0.dist-info}/licenses/LICENSE +0 -0
absfuyu/fun/rubik.py ADDED
@@ -0,0 +1,442 @@
1
+ """
2
+ Absfuyu: Fun
3
+ ------------
4
+ Rubik
5
+
6
+ Version: 5.4.0
7
+ Date updated: 21/03/2025 (dd/mm/yyyy)
8
+
9
+
10
+ Version added: 5.4.0
11
+ """
12
+
13
+ # Module level
14
+ # ---------------------------------------------------------------------------
15
+ __all__ = ["RubikNotations", "Rubik3x3"]
16
+
17
+
18
+ # Library
19
+ # ---------------------------------------------------------------------------
20
+ from typing import ClassVar, Self, cast, final
21
+
22
+ # Data
23
+ # ---------------------------------------------------------------------------
24
+ PLL_PIC = {
25
+ "Aa": "iVBORw0KGgoAAAANSUhEUgAAAEkAAABJCAYAAABxcwvcAAAABGdBTUEAAK/INwWK6QAAAAlwSFlzAAAOxAAADsQBlSsOGwAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAICSURBVHhe7do9TsNAEIZhhwNQQEtJxf3PQkVJCwUXSPKFjFhZrD3e3/l7JUQiRFg9HlsOm9OyLOfrV7TRDen88/ukR6fH6x9Q/voP98fRRoHEyAXS99vr/VFZbiapBsoF0tP7x+17KZSbSaqBYt8C1J7X0iK0vdzeAnCBKDc3k3QmHAbyMkmlQNThScpdm3ILkDBJWHMxkJdJygEBL3fQ06qRsIDSo6SlaiTOkdBeMVI6PdahqibJC9RhpPU1yANU9TUJWYdqgoQsQzVDQlahmiIhi1DNkVAK9fWiH6rrvlsK9Pz5ByclWt/e2rr/qyQ95dIJa1XNG2ha29a6hrzBTY+S1mtUdySk/WI+BAlphhqGhLRCDUVCGqGGIyFtUFOQkCaoaUhIC9RUJKQBajoSkg4lAglJhhKDhKRCiUJCEqHEISFpUCKRkCQosUhICpRoJCQBSjwSmg2lAgnNhFKDhGZBqUJCM6DUIaEUasS+Xtd9t97V7uuJ2Xfr/cHS9JRLJ4wT/e7W75n4YOmIfT31SKj3xdwEEuoJZQYJ9YIyhYR6QJlDQq2hTCKhFKo2s0gIUOupyk3W1s9MI60jsDUGPc9Nn/o77pLX/29iskAW7rhLWoPkgCiXSIhg9oCQy9PtSG5Pt6MFEqNAYhRIjAKJUSAxCiRGgcQokBip3ncb07JcAGos+ItnN7h+AAAAAElFTkSuQmCC",
26
+ "Ab": "iVBORw0KGgoAAAANSUhEUgAAAEkAAABJCAYAAABxcwvcAAAABGdBTUEAAK/INwWK6QAAAAlwSFlzAAAOxAAADsQBlSsOGwAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAHuSURBVHhe7dtNTsMwEIbhlAOwgC1LVtz/LKxYsoUFFyj90o4URYkztmN7/l4JkQqlVE+dUVTDZZqm6+0rSjQjXf/uD1p0eb79AuXP//Q4jhIFEqNAYhRIjAKJUSAxCiRGgcQokBi5Rvr9eH8cpXOLREAcKJdIa5gjKHdIBPLy+TV/p1JQrpD2gOjxHpTpj0r2UKijnyPTH5WkLp/cTCItgVKrhJs5pLOBkCmkFkDIDFIrIGQCqSUQUo/089YWCKned1sCvX7nA9H5R+eqvZk84xKj50idr/ZmcglUsoJyU4fUekhvpQppBBBSgzQKCKlAGgmExCONBkKikSQAIbFIUoCQSCRJQEgckjQgJApJIhASgyQVCIlAkgyEhiNJB0JDkTQAoWFIWoDQECRNQKg7kjYg1BVJIxDqhqQVCHVB0gyEmiP12BdrXdN9t9p9sdYN33frdYnV7OvRa0y9vmb7bksgiSsot9ORtA/prU5FsgiETkOyCoROQbIMhLKRALJEsQ6EqlaSByBUjOQFCFXPJOtAqBppPaMsVo2kob03EVcB50ow/Q84FCGVjAa1fzOZG+GUjgX2SrI0d3JWlJuVtC73DXcxk6iS2eRqJdUMb1e3ACVAyM1KKgVCrmZSSa5mUk2BxGi+3O6H0XbT9A9hSvCXpdP6AwAAAABJRU5ErkJggg==",
27
+ "E": "iVBORw0KGgoAAAANSUhEUgAAAEkAAABJCAYAAABxcwvcAAAABGdBTUEAAK/INwWK6QAAAAlwSFlzAAAOxAAADsQBlSsOGwAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAFrSURBVHhe7dkxbsIwGEBhwwEYysrI1PufhYmxKx16gUCBf4mK8xwH1VbeJ1UlqhT/ehLUJpuU0nD7UcY90vDzuHiHze62QOf33z5fK8NIgJEAIwFGAowEFEX6/jw+X/Vp7vw4UizQa6ia+VGk8Y17C1U7/2SkuOHH6Xz/HXoJtcT82UivFojr1kMtNX/R2e3Vojktnd3mzl/0322tjAQYCTASYCTASICRACMBRgKMBBQ9d7scHtv6/Rff1rdk7vye3SZ4doOMBBgJMBJgJMBIgJEAIwFGAowEGAkwEmAkwEiAkQAjAUYCjAQYCTASYCTASIDP3QCfu03wuRtkJMBIgJEAIwFGAowEGAkwEpCN9LtDjV3qWO5vrVhq/myk2L6PbxbXJdv7/7DU/Ojs9ldxvEADZ7fa+dFn0viGdIFW1M6PP7jjxr0FCjXzF31VMkcLb7ca+O22dkYCjAQYCTASYCTASEDRc7d1SukKxuWXT5bSG9QAAAAASUVORK5CYII=",
28
+ "F": "iVBORw0KGgoAAAANSUhEUgAAAEkAAABJCAYAAABxcwvcAAAABGdBTUEAAK/INwWK6QAAAAlwSFlzAAAOxAAADsQBlSsOGwAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAF7SURBVHhe7dmxTcNAHEbxCwNQMAMVNQMwBUMyBQNQUzEDBQuEyPjK+N53EpL/zvtJKE5z+J590jk+tdbOlz9tWCKdf/6+/IfT/eUfFB//bj3WBiMBRgKMBBgJmIr0/fS4HtUzc+5xpMqBunQOUaQ++MPn1/JZUT/3JBSOdIRAXRoK7bjT27OarQuPd9xHuHuuIXOLnt1mltwen92SecTPbn3Qystv5kLHW4Bk8L1K5+BPJQPxcrtVRgKMBBgJMBJgJMBIgO/dADeTA24mISMBRgKMBBgJmIr08vqxHtUzc+5xpMqBunQOUaQ++Pvb8/JZUT/3JBSOdIRAXRoK7bjT27OarQuPd9xHuHuuIXOLnt1mltwen92SecTPbn3Qystv5kLHW4Bk8L1K5+BPJQPxcrtVRgKMBBgJMBJgJMBIgO/dADeTA24mISMBRgKMBBgJMBJgJMBIgJEAIwFGAowEGAkwEmAkwEiAkQAjAUYCjAQYCTAS4Hu3odZ+AfiyiXn4ccLwAAAAAElFTkSuQmCC",
29
+ "Ga": "iVBORw0KGgoAAAANSUhEUgAAAEkAAABJCAYAAABxcwvcAAAABGdBTUEAAK/INwWK6QAAAAlwSFlzAAAOxAAADsQBlSsOGwAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAALwSURBVHhe7Zq9jtQwFEazPAAFtJRUiHJ7KKkpEI+IKKgpoadEVFvSQsEL7O43k6u9O9jJ/bNjJz7Saj3SjJM5ud+Nk8zVNE2393+DBU6Sbv+dX5Tg6un9Bjqf/8k8HiwwJAkYkgQcQtLfVy/nkY3DVJJHVJNnt7cffsyjx3z7fD2PHpDOT5Ke/bo5/ZeC+U2SNEfl+e+b6c8L3VF8//rTPHrMl58f59EDlvk1orpZAkBOSpAVbfSaiRtFDJFKxS0VNaCJsyVyokryNDwpkh6Ue48Ua08Ci5Jo4pKi+JdPVUuEKI8gkI1bSoxlI0txWBPEyb1XEjd8F7OgXNxy5iMrSiMIeCrKKoj4T1JOEL2OEKUVRHhEeVg9u+WkSbmMg1UQh8/x/et1Nm7efQeis1skEYIA/+ybd+mKimwN1SRFCSKWoscFefsRqCIpWhCREhUtCBSXxOMQKYhATyL4wYgSBIpKKlVBl/C5cXEcKQgUk1RLEEDE+AUw33YERSTxneRxKE2qR0VwWiedh2noXg3u20jgPaimIE70PoQuJlMRk1xbWaD9wsFLzR8V99DFZNROSeCn+RyR0QuRtJWgteqOEuWW1KogIkKUShI2wjfUuiDCK8pcSb0IIjyiTJJ6E0RYRbl6Uk+CCMs+q9ZJOftLG7auk6SCSq3DiOo33aSUqCCg7UVE9du3a2gFaeYnSZrINVdJpSqIIDnaimpGUmlBhEWUOm7WXLfKWvSabdy1kPamTRt3RMS0JwZt8960kmr1II7l7AY2kbSFIEIrCFSX1JsgUFXSloI8VJPUqyBQRVLPgkBxSfznwz0KAqd10nmYRvvcjcMFWT7fCsUWk7Uipl1Maim2mOSCeq4gIlxS7006RaikPQoCYZL2KgiESNqzIKCWBCFcyt4FAVclHUEQMEs6iiDg7kl7FwTcki571B5xSzoCzT3B1dLttdveWK0kL6OSDsKQJGBIEjAkCRiSBAxJAoYkAUOSgNXnboNpugNSNscojmPPkQAAAABJRU5ErkJggg==",
30
+ "Gb": "iVBORw0KGgoAAAANSUhEUgAAAEkAAABJCAYAAABxcwvcAAAABGdBTUEAAK/INwWK6QAAAAlwSFlzAAAOxAAADsQBlSsOGwAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAALbSURBVHhe7ZqxbtwwDIadPECGZM3YqciYPR07dyj6iEWHzBmTvWORqWPWdugLXPJfTIAQTjZFUTLp6gMOp/MBsv2JpKXTnU3TdHh7DRY4Sjr8e//QgrOLtxME7/98bg8WGJIEDEkCqiT9/fhhbu0btaT/RRBQSSJBl8+/j+97p3gKED2CSge2eArQUtCXm+9zq4yrl/bRrI4k6YhIJnufvv6cW9P0+ON2br1D36XHCZeTSZJjFVVcEEg/E7njtUjuQ1W4rUSlN07Rwo/zCLIWRde/dh/qKUDtk41uOE2jXqJSMUuiXCxwc8JSTonT1KRUCAacjqWDr6pJW2IRUTkZSyWkWhI6PdVxK2pFQUYqiMh9ZxZJW4m6+2xTo5aolsTNR4qoEkwiae+izNJtK1FPD+1FmUkCe40oU0lgj6LMJQEu6s91fFFN9924oKWfNOgxzutLDXxaYNFn82UJTzkeYRwadR4JUnLLEh5JuX7p2nLXBbosS3gERa1RzSWB6MW8iyQQWVQ3SSCqqK6SgDdR2IBYE9ddEogWUZtIAlxUT7go6TbWZpKAB1ESNpUEeqce0qy0eG8uKaVnjZLiarfk/te34zuQpqJmt4SgAVk6l7vdkl6pV5py7tKttajSegTcSQKtRHFBJU84l5KAtSitIOBWErASVSMIuJYEakXVCgLuJQGtKAtBIIQkUCrKShAIIwlIRVkKAqEkgTVR1oJAOEmAi+K0EASa7rtJsdh3s95r44T6O+Ap0D8XVNIHpWsuMoG7Ba4GLoj/imBJaEm8BpGgknmUlLCS0iJdOo8qIaQkLogX6Vaiwklae8y3EBVK0pogIicKbY04t5IghEuRCiIsIypEJJUKIqxEuZekFURwUVrC1CSNIG0NSgkjKa1RPXGxdjtFTkgaUdr+AUXZUkqif7eSpAxJAnr0H6YmbcmQJGBIEjAkCRiSBAxJAoYkAUOSABf7br6ZpleZlqpZ7/HSYgAAAABJRU5ErkJggg==",
31
+ "Gc": "iVBORw0KGgoAAAANSUhEUgAAAEkAAABJCAYAAABxcwvcAAAABGdBTUEAAK/INwWK6QAAAAlwSFlzAAAOxAAADsQBlSsOGwAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAL8SURBVHhe7Zq/jtQwEIdzPAAFtJRUiJIeSmoKxCOerqCmhJ4SUVHSQsELHPvL7uhGudiZv9k48SetNtFqbefzzKyd7M0wDPenV6fCKOn+3/kkg5unpw4ab//J5bhToUsS0CUJ6JIEdEkCuiQBXZKALknAoqS/r16OryPTI0nA4raEoujZz1/jeymq6PMpfVtyENySEEGlKNoLbklHKOpmSTx69i7KFUlHEaWWNK1BRxDlrklg76JCJIE9iwqTBPYqKlQS2KOocEmAi/rzon1Ri8/d6CKf/364cClckOX7W0G9wdXCU87aRo1dbHB5BLVao9IlgdaL+SqSQMuiVpMEWhW1qiRwTVHvPn6/HOlYXRJoTdRVJIFriPp692Z814pSr5OsIbtFSFqNwz8IkE54+opbuiLmKafpy7LiJjnNRdJaNUojiNhUumWLsggCqnQr5XCtU0s6aFJP0z7Grxa0pXTjZEWUVhDhkoROrR0vkZl6iKhSVszhkqTpyEKGKMuYTZJ49LQkio9VkwHmSGpNlFUQcC8mlzq3/LqV4IJoPJL2XYIift22HlEeQYRbEtiqqAhBIEQSuJaoElGCwFiTzofzaJ+7vX3/MLhvX3yDsxI9hpS7AHwWMciowj0HCitNJMYYGUEgbVvCB8dnNZtoQUSKJLB2jfrw+vZyFisIpEkCa4nibX/+8Um8PJCSKgnwwpkhiqczn5RIUemSQFZE8baoD806SsoqkkC0qDlBRLSo1SSBKFH8u6V1kGbJssQjSTBfsl/7TIpXVC2CpkBUhKxHkqjRqQw6j+jUKkojKJLZdCuJihBEaEV5BHmjv1iTpkIiBRElUTienhPWCPKIqhZuEpMhiFiKqAhBNH6rqKokkCmIKF18hCDCI2rxLsAcmo5wi0X7X26+DwPYapSwtA+kk592FyAaSJuK86DNDlMkaZDcqJ8yV5vAXMpJ26foVws6tb9JSRok7VsFAbTfRLpFYBFEHCKSPBwqkjx0SQK6JAFjTTofduYZhv+H7r9QKUdxcgAAAABJRU5ErkJggg==",
32
+ "Gd": "iVBORw0KGgoAAAANSUhEUgAAAEkAAABJCAYAAABxcwvcAAAABGdBTUEAAK/INwWK6QAAAAlwSFlzAAAOxAAADsQBlSsOGwAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAALLSURBVHhe7dmxbtRAEMZxhweggJaSCqVMDyU1BeIREQU1ZdJTIipKWih4gSTfcSMNy+16ZnbWu2PvX0Lnu6AL/G68ts9Xy7LcP/6ZFToh3f/5+6RFV08ff0Hw939y3p4VmkiCJpKgQyD9fvXyvGXrMJNUA3UIpGfff5werVCmU4Da8e0doUna5BTg+U/5P4j37vrjecs/7Yfc9WTyzfuvp8fbTzenR4peR+nP0jQnk4TjPkmtdi0OwUtfz/09bRYgqohEb+wNlZsUer00WZZqgFAWKYXxgtIC0fNaKCsQurgmcfkUR/vL+JqRA7pUDi1NsyZZurgm5UaTnlsnSgM0Wv8hASM3LaWfleoFhA/U+qHyVo9utb1+2w/Iq6ZIPSeIskx+WjOkvQChJkgc6O5LbCDkjrSnCaJckfYIhNyQegH9etEWCLncd+OHea81iN6z9H4cyPqVjKTVr0polHOf0toEWS8b6H1zU9l6F6NEX5WUGmENajlBlBlpr4v0pUxIRwJCaqSjAaEiEkD4F/JHBELiSToqEBIh8WnaEojXCwip1qQjAiEVEnY5vtu1aoRdjKdC2iIONErVlyVraS5LOBCtg2u7eJe7Jbla72qj7WI89e7WAmpkICRG4mPvCTU6EFJNkjdUBCCk3t28oKIAITUSqoWKBIRMSMgKFQ0ImZGQFioiEKpCQlKoqECoGgmtQUUGQi5ISDJREYGQy303ntc9OMl9t61qcoHLJwn/yRb33aihLnA1ff724bz172RFzR2JJo9DlY56EXJFSo9i2vOoUXNDyh3m+cIbFcoFae08KPpEqZEAwlHWgKjIUFWTJAWiclDYHhnOjKQFoiJOVPWapAGiokFVI6VrlDQONXrVSJZGX4PSutyczAFZpmuLa7eh7uBaGgKptj0gdVmTojWRBE0kQRNJ0EQSNJEETSRBE0mQ+323/bUsD7Leq1kMq2/FAAAAAElFTkSuQmCC",
33
+ "H": "iVBORw0KGgoAAAANSUhEUgAAAEkAAABJCAYAAABxcwvcAAAABGdBTUEAAK/INwWK6QAAAAlwSFlzAAAOxAAADsQBlSsOGwAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAGJSURBVHhe7dlBboJAHEZx7AF6mu7bZU/QQ3oCl+2+p+kFrKizIYJvJlE+4L3EVNJE5ScY/syu67rj6WETnZGOf5eNR7R7Pb3Bwl//5frcJhIJJBJIJJBIIJFAUUgfX7/XZ1nFIBWgRKgIpCFMGtTsSAXke/92/ltKgpoVaQyobKdARc1uY2hTObuFJBJIJJBIIJFAIoFEAokEEgkkEihq3e398zKW/Bz4WPKMnN3u5OwGEwkkEkgkkEggkUAigaqRklYxamv97FVISwYqtewDRmq5Gk6rdakKjSVrOIJuRb5wNJasFaiP7lvVkdRyqiUOuDXvgwfc1nM5sZYvAv9wrwGqBaiv6hKg9sUTa9mHKqS+JUO1fvZqpC0mEkgkkEggkUCuu4Fcd7sTHku2nkggkUAigUQCiQQSCSQSSCTQrEj9FfbY7eCp/z27WZHK+DHEKNspd0EjZrdbRwwF2szsNgRJOYJKMT/cBSYNqC/qVklLmznd0hMJJBJIJJBIIJFAIoGi1t0y67p/nuaai10GTQQAAAAASUVORK5CYII=",
34
+ "Ja": "iVBORw0KGgoAAAANSUhEUgAAAEkAAABJCAYAAABxcwvcAAAABGdBTUEAAK/INwWK6QAAAAlwSFlzAAAOxAAADsQBlSsOGwAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAHlSURBVHhe7dkhT8NAGMbxjg+AAItEESQeJBpB+IgEgUaCRxLUJBYEX2Db07VJt2zrc2/fdnnvnl9COARt9+/ddllnVVUtVj9yQB1p8b/+Ywyz09UJgh//pBnLAYpEUCSCIhEUiaBIBEUimCL9XV02oxiGXm9ypGiBWkOuO2nH3Z7o7Hte/2b07YjvHj+b0ab3l5tmdBi747ZcO+D4dCTrnTj/mVe/F/v/9+H6uRltev16akb+Um8ytdzGXGKIMWaQXVJfT/JMskzXvuPvWnLeyw0sr4GeSdAe2HtWdQOxYSysNxmSPt28Q0UIBKbvk3BS9oT7loNXIGa5pVzvNhz/KF+6ec4gJtIQOL5pxz3EVEvM06SRIgaCySJFDQSTRIocCEaPdHsfOxDUn27rob9uoI+3mIFgtC3AVEss7BagGyjyDGq5R4r+Jr2La6QcA4FbpFwDgUuknAPB4Ei5B4JBkUoIBOZIpQQCKhKCdKOUFAiSZ1JpgSApUomBwPSeVFIgMEXafo/KnSlSaY7ytMRTlk9LIlIkgiIRFImgSARFIigSYdTnbrnQZrKHNpMkRSIoEkGRCIpEUCSCIhEUiaBIBEUiKBJBkQiKRFAkgiIRFImgSARFIigSQZEIikRQJIKeu/WqqiUCWr67jAaMcgAAAABJRU5ErkJggg==",
35
+ "Jb": "iVBORw0KGgoAAAANSUhEUgAAAEkAAABJCAYAAABxcwvcAAAABGdBTUEAAK/INwWK6QAAAAlwSFlzAAAOxAAADsQBlSsOGwAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAHJSURBVHhe7dsxTgMxEIXhDQeggJaSipoeSk6AOCMFNSX0lIiKkhYKLhAyiS0ZKzbPG5sdj98vIbyKBNIn72ayC6tpmtabL5Zpi7T+3h20aHW8+QWd//wjt2aZiAREJCAiAREJiEhARAIiEhCRgIZC+ro4d6uyhkHyQHOghkCKYUqhzCN5kJO39+13XwmUaaQUkD9GoYa6VZJCy8VbJWBEAiISEJGAiAREJCAiAQ313O3zbDcnnX7gc5LEYfKPOEyCEQmISEBEAiISEJGAiAREJCAiAZmfuK9vX9zqd0/3l26VjxM3mHkk2THorkk1xE5KnXJo5pFCoIfXO7cqyzRSCHTIKWf23W0fEO8nBdXaQT5zSLWBJFNILYAkM0itgCQTSC2BpO6Rrm7aAkldP3cLgZ4f2wBJ3c5Jc06xoeakEKjlDvJ1h9T6Ir2vrpCWAJK6QVoKSOoCaUkgST3S0kCSaiQNQJJaJC1AkgokAQlRNAFJ6nZSTSCZsP2UHZd7LU4VUu0dlPpHG3+MfjxReU2qeYqloEo+v6lEiq9RhxaDlABJKpFa5GFKgaSh/kR5TmYfKdWOSEBEAiISEJGAiAREJKCun7v9T9P0A4HGuqkeGiXTAAAAAElFTkSuQmCC",
36
+ "Na": "iVBORw0KGgoAAAANSUhEUgAAAEkAAABJCAYAAABxcwvcAAAABGdBTUEAAK/INwWK6QAAAAlwSFlzAAAOxAAADsQBlSsOGwAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAIqSURBVHhe7dsxTsQwEIXhLAeggJaSipoeSk7AITkBJfTUVJS0UHCBZR8kYojk7Njx2G8c/xIi0UogfbK9Sby7G4Zhf/jpLfSDtP/6PbFod3r4B87//sl43FuoIynqSIo6kqKOpKgjKepIilTXSZ9Xl+PR/85e38ajcLHXMbf3L8PTw/V4drzNXScBSP5mKQkJI0gzimKawzBBJSGFpl9qE8h8mrFARSHJ0ZMLKgQ0nTNARS3cE5IEOjbtUhZupF28aRbu+RpkMaKYS3532xJUMhLaCtQqJLQFqNVIqHWoLEioZahsSKhVqKxIqEWo7EhIQn1c+Icy3XeTQOfvf3BL3dz9XnE/P+ofl1hnvu8mp5wcYaHc3pasSY4gr2uUORLyvpgXQUKeoYohIa9QRZGQR6jiSMgbVBUk5AmqGhLyAlUVCXmAqo6EJBRjFEiIGYoGCbFOPSqkeSxQ1EiIAYoWiWnqUY8kFij66cYARY+EakO5QEI1odwgoVpQrpBQDSh3SEhCldjXM913Sylm3y1lXy8l8303648DyiknR1iuiuy7WVdiX889ErJezJtAQpZQzSAhK6imkJAFVHNIKDdUk0goJ1SzSCgEheMYuKaRUI4R1TwSWgtVHQm3IaGvay29FpuEiq06Uuh7bdO59h5uqdg1aB7FdAtB5QDKEdVTAImkBWri07cxTTAsI2iK7nlSbJsbSax1JEUdSVFHUtSRFHUkRXT7bnwNwzcsDAXYOLVy1wAAAABJRU5ErkJggg==",
37
+ "Nb": "iVBORw0KGgoAAAANSUhEUgAAAEkAAABJCAYAAABxcwvcAAAABGdBTUEAAK/INwWK6QAAAAlwSFlzAAAOxAAADsQBlSsOGwAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAIgSURBVHhe7dsxTsMwFMbxlAMwwMrIxMwOIyfgkJyAEXZmJkZWGLhA6UdjyURJ+uL42d9z3l+qSIoUpJ9sK8Htruu6/eHlzfSHtP85nmi0Oz/8AePXP+uPvZkcSZAjCXIkQY4kyJEEOZIguvuk+8e37uXptj87nfT63zfX/dH/Lt4/+qPx6O6TABT/ZIkGaQiTGwoj5tSomYoCaQgSpltuqKkpd6rqSAFiuA7lhoqBlo4oqoV7CmwuyfXHgMJ75hZujaZGEI6lI6pppDVTLK5ZpFxAqEmknECoOaTcQKgpJA0g1AySFhBqAkkTCJlH+rrSBUJU+253D8c77tdn2R13DHT5qQOEzD6WaE+xkNnHkhhIcwSFzCGVGkFxppBqACEzSLWAkAmkmkCIHqk2EKJGYgBCtEgsQIgSiQkIUU83BiBEi8QChGiQ2KZYHAVSDMRYdSR2IFQViXmKxVVDsgKEqiBZAkLFkawBoaJIFoFQMSSrQKgIkmUgpI5UYl9MO9V9t6X7Ykv33Uqltu+WMsW0Pg64JrV9txioxL6YdtmRrC/SY2VFahEIZUNqFQhlQWoZCK1Gah0IrULaAhASIwEkRtkKEEoaSVsCQouRtgaEktekXEB4FJn6utbc70qWjDRco1Kb+l5bOF/yHKdVMlLOhhBMQIjy07dICmT2vwCpBRiWERSiGkkpbW4kseZIghxJkCMJciRBjiRIdd+tjbruF/dWBdg2pAhsAAAAAElFTkSuQmCC",
38
+ "Ra": "iVBORw0KGgoAAAANSUhEUgAAAEkAAABJCAYAAABxcwvcAAAABGdBTUEAAK/INwWK6QAAAAlwSFlzAAAOxAAADsQBlSsOGwAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAHFSURBVHhe7do7UsMwFIVhhwVQsAYq6vRQsgIWyQoooadOxRoo2EDICfagMNg+V7ItXen8MwymIc6Xa+EHu67rjqcvNdEZ6fj188Ma7a5PL+D891/122oiIREJiUhIREIiEhKRkIiikD7vbvstH6XurxnJG9BQyn6bkIYXujl8nL97adjfWCj6ssTrBP2X5UOmL0tqAkLW92OeJOuhVtIFbsx7MF3gph7XuYv9kJFp4fYKlQKEzKcAsS+Uu5T91k23mUxrUssJiUhIREIiEhKRnrsR6RRgJp0CkAmJSEhEQiISEpGQiIRERJ0nPTy991uXvT7v+63xdJ7USFFImCBmimopCmns8Ks1E1I4PS1BmSepRajouwAh0NT61PRft5YmKhoJtQKVhIRagEpGQrVDLYKEaoZaDAnVCrUoEqoRanEkFELdP/qHWvW5Wwj09vIL563Vn7uFh1w4YUtVxf2kcIK8rlGrIyHvi/kmSMgz1GZIyCvUpkjII9TmSMgbVBYkNAaF7dLgsiEhLxOVFQl5gMqOhEKoEsuOVOIa9LciJqn09I+lM21ygVtDQiISEpGQiIREJCQiIREJiUhIRKs+d6ujrvsGdDW0Lec+UFYAAAAASUVORK5CYII=",
39
+ "Rb": "iVBORw0KGgoAAAANSUhEUgAAAEkAAABJCAYAAABxcwvcAAAABGdBTUEAAK/INwWK6QAAAAlwSFlzAAAOxAAADsQBlSsOGwAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAG9SURBVHhe7dqxUcNAEIVhmQIIqIGImBxCKqBIKiCEnJiIGghowPgZ3czhsa13K521e/f+GQaRIPnzSj4hNsMwbHdf6kx7pO3P3w812lzvdhD891+N2+pMQiISEpGQiIREJCQiIRHNQvq+ux23YmQ9XjNSNKCU5bhNSGlHN59f++9RSsdbClV8WxJ1go7FvMnFtyUtASH29ZgniT3VPN7glrwG0w2u9bz2UumbjEwX7qhQFiBkXgKU7shLluPWH90mMl2TekxIREIiEhKRkIj03I1IS4CJtAQgExKRkIiERCQkIiERCYmom3XS4/PHuPW/t5f7cet4WieRdYOEiZmamlN1NUmnTrmpukHKgUonqgukOUCo+U+32UCtf7rNBUo1i7QUEGoSaUkg1BzS0kCoKaQaQKgZpFpAqAmkmkAoPNLDU10gFPq5Ww70/loHCIVdcdc+xVJhV9w5UM0JSoVDutQE5YVCWgMIhUFaCwiFQFoTCLlHWhsIuUICSI7iAQi5nSQvQMglkicg5Pqa5AEIuUY6vEatlWskL+kfSydq/pHSUgmJSEhEQiISEpGQiIREJCQiIRGFfu52mYbhFyeGtC1UL+rcAAAAAElFTkSuQmCC",
40
+ "T": "iVBORw0KGgoAAAANSUhEUgAAAEkAAABJCAYAAABxcwvcAAAABGdBTUEAAK/INwWK6QAAAAlwSFlzAAAOxAAADsQBlSsOGwAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAGRSURBVHhe7dkxTsNAEEBRhwNQQEtJRc0BOAWH5BQcgDoVJS0UXCDETqaxYu+fFUh49z8pii0kR/tjI0+8G4bhcHxpxRTp8H3a+Qu76+MHbPz4V+dtrTASYCTASICRACMB3UT6erg/b+V1ESkC1YZqPtI8TE2opiNFkJv9+/QesqGajbQUKPYzobqZ3ZailTi7QUYCjAQYCTASYCTASICRACMBRgK6ee72eXcaS24/cmPJyNmtwNkNMhJgJMBIgJEAIwFVkZ6e385b20bXkY7USqBA1pOKFAd8fXmc3rcu1lEKhSO1FiiQUGgsIadkK+YnAR5LWjt7liytMzXg1lxy/33ALa0pPeDGgVq5/OiXnr4FyJxFW0DW4+9JBenLrVdGAowEGAkwEmAkwOdugPdJBd4nQUYCjAQYCTASYCTASICRACMBzUYa77DjLntu7W+XNBspxo95jNjPjCfNz26XzphUoB5mt3mQ7IA76uIfd4SpCTTq5qeSWl1cbr/BSICRACMBRgKMBBgJ6Oa5W71h+AGr6qDhlFnaCQAAAABJRU5ErkJggg==",
41
+ "Ua": "iVBORw0KGgoAAAANSUhEUgAAAEkAAABJCAYAAABxcwvcAAAABGdBTUEAAK/INwWK6QAAAAlwSFlzAAAOxAAADsQBlSsOGwAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAHySURBVHhe7dnLUcMwFIVhhwKohj0sqYAiqYAl7KmGBpIcJxo0mTg6V7562eebYXA2RPNbko19mKbpeP6RB+ZIx7/LhxIOz+cvGPzvP12P5QFFIigSQZEIikRQJIIiERSJoEgERSIoEkGRCIpEUCSCIhEUiaBIBEUiKBJBkQiKRFAkgt67EfTeLUHv3UiKRFAkgiIRsiK9ffxej/bBHGlvgcAUKQT6/nyZf+8FfZ+0pRlkOcn0fdIel1jMPJOsS21Xd9whjjbuhL2GyvoHF5HYZdd6uS2dUMv4zfdJYN2XRkdHwhkZcZnhhK49qeaZNGKotWM2X91gpFDxWHNnVNbVDUYI5REIsq9uQerLW13d3AJ5XN16nFFegYKsSNBrKO9AkB0JegtVIhDMe9LlMN/r+//gfr78BmdRcgxZG/c9S2exxsYdB/KcQZC9cd/TaumVDBS4RYLaoUrtQbdcI0GtULUCgXskiAcdLwcvcaAaF4oikaDUjKo5g4JikcA7VItAUDQSxMthTahWgaB4JFg7o1oGgiqRIDdU60BQLRJYQ/UQCKpGgqVQOL79HLQMBNUjQWpG9RQImkSCVCjoIRC4PQVYknoKcBvIGqbGU4ZmMwlxlmZQb5pFGknz5bbWppfbSBSJoEgERSIoEsHlvdu2TdMJn8jmJ8fDhbIAAAAASUVORK5CYII=",
42
+ "Ub": "iVBORw0KGgoAAAANSUhEUgAAAEkAAABJCAYAAABxcwvcAAAABGdBTUEAAK/INwWK6QAAAAlwSFlzAAAOxAAADsQBlSsOGwAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAHySURBVHhe7drBUcMwFIRhhwKohjscqYAiUwFHuFMNDYSsEw2aTGzvk/QkOdpvhsE5EIk/kmNiDtM0nc5fsmKOdPq9PPBweD4PsPPnf7oeywpFIigSQZEIikRQJIIiERSJoEgERSIoEkGRCIpEUCSCIhEUiaBIBEUiKBJBkQiKRFAkgu67EXTfbYPuu5EUiaBIBEUiDBXp7ePnemQz3EpKCTVUpK/jy/zdGsp8nZS6ZHsUoq0Z/jqJfcGHvOIOcbSSFlgCBUNeAlgCgWm7Le3htUF72m6YvznQaNvNGijIioRBUwduCStqaVfckxXJMlAvUuacFClePXsKFc/VsgOSV9LeQqUGguyLya3Be3h3ywpU4t2t9xWVEyjIjgS9hioRCIpEgt5ClQoE8znpcljG6/v/5L4/8yaXqvQcXD4FiF9FTLLmibvkCgK3P0viycWvqrfSgQKXSFD7HOUVCNwiQa1QnoHANRLEJ06PUPF29ggE7pHAa0V5r6CgSiQoHapWIKgWCUqFin+2xrVY1UiQG6rmCgqqR4LUUC0CQZNIYA3VKhA0iwRLoXB8+zioHQiaRoKtFdU6EDSPBEu/fA+BoMv/BbhdUWuBUp7fwu1TgNIQ7d5WrGUXkVrrcrtZaLt1QpEIikRQJIIiEYrfd3s80/QHRtfoJ68+66IAAAAASUVORK5CYII=",
43
+ "V": "iVBORw0KGgoAAAANSUhEUgAAAEkAAABJCAYAAABxcwvcAAAABGdBTUEAAK/INwWK6QAAAAlwSFlzAAAOxAAADsQBlSsOGwAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAIWSURBVHhe7doxTgMxEIXhDQeggJaSipoeSk7AITlBSuipqShpoeACIS/sKkPErsbrGXvGnl+KtDQgPo29FmYzDMNu/4kWOiDtvn+/0Ghzvv8Bzr//2fgcLRRIjAKJUSAxCiRGgcQokBiZOCfdP76OT397frodn+YzdU76urn+99NDJpcbJogzRaVajXTx9n74aDS3/Gq1GkljqdHpsQSVjESnpxco9tttApmQKNDSslv79qFAS/tTibdb1hGAA5XzS3CgSiBlvd16WXrZR4AeoLKRUOtQIkioZSgxJNQqlCgSahFKHAlRqM8rXai7B30o1Xs3CnT5cYSTigK9bI9w0qn/PYkuOTphUtElRydMquzDJCc6QRp7FJ0grT1KHQl538yLICHPUMWQkFeookjII1RxJOQNqgoS8gRVDQl5gaqKhGpB4ZkLVx0JWZ8oE0jIMpQZJFQSKiVTSEgLKmUPOs0cEtKeqNRM/OvNXBSIwtHM37tpZ2WiTCMhC1DmkVBtKBdIqCaUGyRUC8oVEqoB5Q4JUSiNe73TVO/dtNO+15syfZjkRJccnTCpzB8mOWnf6yH3SEh7M28CCWlCNYOEtKCaQkIaUM0hIWmoJpGQJFSzSEgKqmkkNAeFZy5c80god6K6QEI5UN0gIQqVUjdIKXvQaV1N0trc/6mk+3s3KwUSo0BiFEiMAolRIDEKJEau793KNAw/I0AwLpLA1aEAAAAASUVORK5CYII=",
44
+ "Y": "iVBORw0KGgoAAAANSUhEUgAAAEkAAABJCAYAAABxcwvcAAAABGdBTUEAAK/INwWK6QAAAAlwSFlzAAAOxAAADsQBlSsOGwAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAIvSURBVHhe7do9TsNAEIZhhwNQQEtJRU0PJSdAnJGCmhJ6SkRFSQsFFwj5gldMItuZ3ZnFM+t5pYilCdKj8fqPVdd1680nmmiLtP7+/aVGq+PNH3D+/Uf9OpookBgFEqNAYhRIjAKJUSAxYl0nfV2c96vdTt7e+9V43OuY69uXfrXb0/1lvxourpOMVISECeJMUU6YmENTM1dFSGOHn7SxQ27uspDo9GhDUSBrE5U9STWgLAOh4qcAFGhqfzp09pECmT67aUyU9QlKFSMhCZQXICRCQiVQnoCQGAnlQHkDQipIiAPlEQipIaEpKK9ASBUJDUF5BkLqSIhCXd34BkJV37tRoOdHn0Co2ns3eog9vN5tf9IJ08rt8yQKRCeIex1lLXWkoU2ac3lgOVWkqbOYZyg1JM5p3iuUChIHKOURSoyUA5TyBpWFBBCKUgKU8gRVPEkSoJQXqCIkDaCUByjRniQFSlmHEiHt71GSLEOJkLSzCmXyH0spEIUbyu0NrjRrE2USCVmCMouErECZRkIWoMwjobmhXCChOaHcIKG5oFwhoTmg3CEhCvV5Vh+q6nu32lGg048/OO1M3pbkRA85OmFamb0tyYlOUK09yj0Sqr2ZN4GEakI1g4RqQTWFhGpANYeEtKGaREKaUM0ioTEorHPgmkZCGhPVPBKSQi0CCVGo3BaBlLsH7beYSZLk/inAYl9OWiuQGAUSo0BiFEiMAolRIDEKJEau37v9T133A/cUFsjTSnS4AAAAAElFTkSuQmCC",
45
+ "Z": "iVBORw0KGgoAAAANSUhEUgAAAEkAAABJCAYAAABxcwvcAAAABGdBTUEAAK/INwWK6QAAAAlwSFlzAAAOxAAADsQBlSsOGwAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAHcSURBVHhe7drNTcNAEMVxhwKohjscqYAiqYAj3KmGBkJe4pUW5MQT79d74/lLSCYHY/0ytldaDtM0HU8/0Y3OSMefyy8tOjye/oD4+R/m4+hGgWQokAwFkqFAMhRIhgLJEM066eXtez762+f703y0XKyTSKJBwsSsTc2oqCbp2i03OhqkHIhtoiiQmIHQ8LdbKZD7txv7BKWGIakAoSFISkCoO5IaEOqKpAiEuiGpAqEuSMpAqDnS86s2EGq675YDfX1oAqFmK+5et5jsijsHUp6gVHUk9Yf0UlWRPAKhakhegVAVJM9AqBjJOxC6CwkgOcoegNBd66SEAhArUI91jOX8+fXmrX25m9dJe5mgVNEzSQkI17r1eouQMFHXxpixrdda/HZTqeQRQfMPE1uznH8JKH22Bobzu0cqmSCE87u+3UqBUm6RagEhl0g1gZA7pNpAyBVSCyDkBqkVEHKB1BIIySP12Ndruu/Wul77erIr7ta3WEp2xZ0D9djXk0PqNUF5UkgjgJAM0iggJIE0EgjRI40GQlRIAMlRGIAQ7SSxACFKJCYgRP1MYgBC1Ej/n1GjokZiaRf7biW531KqVSAZCiRDgWQokAwFkqFAMhRIhgLJkPS+W5+m6RfQoucBXsykVgAAAABJRU5ErkJggg==",
46
+ }
47
+
48
+
49
+ # Class
50
+ # ---------------------------------------------------------------------------
51
+ class RubikNotation:
52
+ """
53
+ Rubik Notation
54
+
55
+ Parameters
56
+ ----------
57
+ notation : str
58
+ Notation (abbreviated name)
59
+
60
+ is_counter_clockwise : bool | None, optional
61
+ Is counter clockwise, by default ``False``
62
+
63
+ note : str | None, optional
64
+ Note, by default ``None``
65
+ """
66
+
67
+ _BASIC_NOTATION: ClassVar[dict[str, str]] = {
68
+ "L": "Left",
69
+ "R": "Right",
70
+ "U": "Up",
71
+ "D": "Down",
72
+ "F": "Front",
73
+ "B": "Back",
74
+ "M": "Middle",
75
+ "E": "Equator",
76
+ "S": "Side",
77
+ "X": "x axis",
78
+ "Y": "y axis",
79
+ "Z": "z axis",
80
+ }
81
+ _COUNTER_CLOCKWISE_SYMBOL: ClassVar[str] = "'"
82
+
83
+ def __init__(
84
+ self,
85
+ notation: str,
86
+ is_counter_clockwise: bool = False,
87
+ /,
88
+ *,
89
+ note: str | None = None,
90
+ ) -> None:
91
+ """
92
+ Rubik Notation
93
+
94
+ Parameters
95
+ ----------
96
+ notation : str
97
+ Notation (abbreviated name)
98
+
99
+ is_counter_clockwise : bool | None, optional
100
+ Is counter clockwise, by default ``False``
101
+
102
+ note : str | None, optional
103
+ Note, by default ``None``
104
+ """
105
+
106
+ self.notation = notation.upper().strip()
107
+ self.is_counter_clockwise = is_counter_clockwise
108
+
109
+ self.direction = (
110
+ "Counter Clockwise" if self.is_counter_clockwise else "Clockwise"
111
+ )
112
+
113
+ long_notation_name = self._BASIC_NOTATION.get(self.notation[0], self.notation)
114
+ self.full_notation = long_notation_name + (
115
+ f" ({self.direction})" if is_counter_clockwise else ""
116
+ )
117
+
118
+ self.note = None if note is None else note
119
+
120
+ def __str__(self) -> str:
121
+ # return f"{self.__class__.__name__}({self.notation})"
122
+ notation = (
123
+ f"{self.notation}{self._COUNTER_CLOCKWISE_SYMBOL}"
124
+ if self.is_counter_clockwise
125
+ else self.notation
126
+ )
127
+ return notation
128
+
129
+ def __repr__(self) -> str:
130
+ return self.__str__()
131
+
132
+ @classmethod
133
+ def from_str(cls, string: str) -> Self:
134
+ if cls._COUNTER_CLOCKWISE_SYMBOL in string:
135
+ return cls(string[:-1].upper(), True)
136
+ return cls(string)
137
+
138
+
139
+ @final
140
+ class RubikNotations:
141
+ """
142
+ Constant Rubik Notations
143
+ """
144
+
145
+ U = RubikNotation("U")
146
+ D = RubikNotation("D")
147
+ L = RubikNotation("L")
148
+ R = RubikNotation("R")
149
+ F = RubikNotation("F")
150
+ B = RubikNotation("B")
151
+
152
+ M = RubikNotation("M", note=f"Rotate according to {L} face")
153
+ E = RubikNotation("E", note=f"Rotate according to {D} face")
154
+ S = RubikNotation("S", note=f"Rotate according to {F} face")
155
+
156
+ U_REV = RubikNotation("U", True)
157
+ D_REV = RubikNotation("D", True)
158
+ L_REV = RubikNotation("L", True)
159
+ R_REV = RubikNotation("R", True)
160
+ F_REV = RubikNotation("F", True)
161
+ B_REV = RubikNotation("B", True)
162
+
163
+ M_REV = RubikNotation("M", True, note=f"Rotate according to {L} face")
164
+ E_REV = RubikNotation("E", True, note=f"Rotate according to {D} face")
165
+ S_REV = RubikNotation("S", True, note=f"Rotate according to {F} face")
166
+
167
+ X = RubikNotation("x", note=f"Rotate according to {R} face")
168
+ Y = RubikNotation("y", note=f"Rotate according to {U} face")
169
+ Z = RubikNotation("z", note=f"Rotate according to {F} face")
170
+
171
+ X_REV = RubikNotation("x", True, note=f"Rotate according to {R} face")
172
+ Y_REV = RubikNotation("y", True, note=f"Rotate according to {U} face")
173
+ Z_REV = RubikNotation("z", True, note=f"Rotate according to {F} face")
174
+
175
+
176
+ class RubikAlgorithm:
177
+ """
178
+ Rubik Algorithm
179
+
180
+ Parameters
181
+ ----------
182
+ case : str
183
+ Case name
184
+
185
+ solution : str | list[str] | list[RubikNotation]
186
+ Solution/Algorithm
187
+
188
+ other_solutions : None | list[list[str]] | list[list[RubikNotation]] | list[Self], optional
189
+ Other Solution/Algorithm, by default ``None``
190
+
191
+ note : str | None, optional
192
+ Note, by default ``None``
193
+
194
+ picture : str | None, optional
195
+ Picture of case (in base64 format), by default ``None``
196
+ """
197
+
198
+ def __init__(
199
+ self,
200
+ case: str,
201
+ solution: str | list[str] | list[RubikNotation],
202
+ other_solutions: (
203
+ None | list[list[str]] | list[list[RubikNotation]] | list[Self]
204
+ ) = None,
205
+ note: str | None = None,
206
+ picture: str | None = None,
207
+ ) -> None:
208
+ """
209
+ Rubik Algorithm
210
+
211
+ Parameters
212
+ ----------
213
+ case : str
214
+ Case name
215
+
216
+ solution : str | list[str] | list[RubikNotation]
217
+ Solution/Algorithm
218
+
219
+ other_solutions : None | list[list[str]] | list[list[RubikNotation]] | list[Self], optional
220
+ Other Solution/Algorithm, by default ``None``
221
+
222
+ note : str | None, optional
223
+ Note, by default ``None``
224
+
225
+ picture : str | None, optional
226
+ Picture of case (in base64 format), by default ``None``
227
+ """
228
+
229
+ self.case = case.strip()
230
+ self.solution = self._convert_solution(solution)
231
+
232
+ self.other_solutions = other_solutions
233
+ self.note = note
234
+ self.picture = picture
235
+
236
+ def __str__(self) -> str:
237
+ # return f"{self.__class__.__name__}({self.case})"
238
+ # return f"{self.solution}"
239
+ return f"{self.__class__.__name__}({self.case} - {self.solution})"
240
+
241
+ def __repr__(self) -> str:
242
+ return self.__str__()
243
+
244
+ def _convert_solution(
245
+ self, solution: str | list[str] | list[RubikNotation], /
246
+ ) -> list[RubikNotation]:
247
+ if isinstance(solution, str):
248
+ sols: list[str] = solution.replace("(", "").replace(")", "").split()
249
+ return [RubikNotation.from_str(x) for x in sols]
250
+
251
+ if isinstance(solution, list) and len(solution) > 0:
252
+ if isinstance(solution[0], RubikNotation):
253
+ return cast(list[RubikNotation], solution)
254
+ else:
255
+ return [RubikNotation.from_str(x) for x in solution] # type: ignore[arg-type]
256
+
257
+ raise ValueError("Wrong value type")
258
+
259
+
260
+ class Cross(RubikAlgorithm):
261
+ """Cross Algorithm"""
262
+
263
+ pass
264
+
265
+
266
+ class F2L(RubikAlgorithm):
267
+ """F2L Algorithm"""
268
+
269
+ pass
270
+
271
+
272
+ class OLL(RubikAlgorithm):
273
+ """OLL Algorithm"""
274
+
275
+ pass
276
+
277
+
278
+ class PLL(RubikAlgorithm):
279
+ """PLL Algorithm"""
280
+
281
+ pass
282
+
283
+
284
+ class PLLs:
285
+ """
286
+ Collection of PLLs
287
+ """
288
+
289
+ Aa = PLL(
290
+ "Aa",
291
+ "x (R' U R') D2 (R U' R') D2 R2",
292
+ other_solutions=[
293
+ PLL(
294
+ "Aa",
295
+ "(r U r' U') (r' F r2 U') r' U' (r U r' F')",
296
+ note="Headlight at Left (solve like T perm but is `r` instead of `R`)",
297
+ )
298
+ ],
299
+ note="Headlight at Back",
300
+ picture=PLL_PIC["Aa"],
301
+ )
302
+
303
+ Ab = PLL(
304
+ "Ab",
305
+ "x (R2 D2) (R U R') D2 (R U' R)",
306
+ note="Headlight at Right",
307
+ picture=PLL_PIC["Ab"],
308
+ )
309
+
310
+ E = PLL(
311
+ "E", "x' (R U' R' D) (R U R' D') (R U R' D) (R U' R' D')", picture=PLL_PIC["E"]
312
+ )
313
+
314
+ Ua = PLL(
315
+ "Ua",
316
+ "(R U' R U) R U (R U' R' U') R2",
317
+ note="Finished face at Back",
318
+ picture=PLL_PIC["Ua"],
319
+ )
320
+
321
+ Ub = PLL(
322
+ "Ub",
323
+ "R2 U (R U R' U') R' U' (R' U R')",
324
+ note="Finished face at Back",
325
+ picture=PLL_PIC["Ub"],
326
+ )
327
+
328
+ Z = PLL(
329
+ "Z",
330
+ "M2 U' M2 U' M' U2 M2 U2 M' U2",
331
+ other_solutions=[
332
+ PLL(
333
+ "Z",
334
+ "M' U' M2 U' M2 U' M' U2 M2 U",
335
+ note="Switch edge at Right and Front",
336
+ )
337
+ ],
338
+ note="Switch edge at Left and Front",
339
+ picture=PLL_PIC["Z"],
340
+ )
341
+
342
+ H = PLL("H", "(M2 U' M2) U2 (M2 U' M2)", picture=PLL_PIC["H"])
343
+
344
+ T = PLL(
345
+ "T",
346
+ "(R U R' U') (R' F R2 U') R' U' (R U R' F')",
347
+ note="Headlight at Left",
348
+ picture=PLL_PIC["T"],
349
+ )
350
+
351
+ F = PLL(
352
+ "F",
353
+ "R' U' F' (R U R' U') (R' F R2 U') (R' U' R U) (R' U R)",
354
+ note="Finished face at Left",
355
+ picture=PLL_PIC["F"],
356
+ )
357
+
358
+ Ja = PLL(
359
+ "Ja",
360
+ "(R' U L' U2) (R U' R' U2 R) L U'",
361
+ note="Finished face at Front",
362
+ picture=PLL_PIC["Ja"],
363
+ )
364
+
365
+ Jb = PLL(
366
+ "Jb",
367
+ "(R U R' F') (R U R' U') R' F R2 U' R' U'",
368
+ note="Finished face at Left",
369
+ picture=PLL_PIC["Jb"],
370
+ )
371
+
372
+ Ra = PLL(
373
+ "Ra",
374
+ "(R U R' F') (R U2' R' U2') (R' F R U) (R U2 R' U')",
375
+ note="Headlight at Left",
376
+ picture=PLL_PIC["Ra"],
377
+ )
378
+
379
+ Rb = PLL(
380
+ "Rb",
381
+ "(R' U2 R U2') R' F (R U R' U') R' F' R2 U'",
382
+ note="Headlight at Front",
383
+ picture=PLL_PIC["Rb"],
384
+ )
385
+
386
+ V = PLL(
387
+ "V",
388
+ "(R' U R' d') (R' F' R2 U') (R' U R' F) R F",
389
+ note="Block at Left Front",
390
+ picture=PLL_PIC["V"],
391
+ )
392
+
393
+ Y = PLL(
394
+ "Y",
395
+ "F (R U' R' U') (R U R' F') (R U R' U') (R' F R F')",
396
+ note="2 pieces have same color at Front and Right",
397
+ picture=PLL_PIC["Y"],
398
+ )
399
+
400
+ Na = PLL(
401
+ "Na",
402
+ "(R U R' U) (R U R' F') (R U R' U') (R' F R2 U') R' U2 (R U' R')",
403
+ note="Edges need to swap at Left and Right",
404
+ picture=PLL_PIC["Na"],
405
+ )
406
+
407
+ Nb = PLL(
408
+ "Nb",
409
+ "z R' U' R D' R2 U R' D U' R D' R2 U R' D z'",
410
+ note="Edges need to swap at Left and Right",
411
+ picture=PLL_PIC["Nb"],
412
+ )
413
+
414
+ Ga = PLL("Ga", "R2 u R' U R' U' R u' R2 y' R' U R", picture=PLL_PIC["Ga"])
415
+
416
+ Gb = PLL(
417
+ "Gb",
418
+ "(R' U' R) y R2 u (R' U R U' R) u' R2",
419
+ other_solutions=[
420
+ PLL("Gb", "R' U' R U D' R2 U R' U R U' R U' R2 D", note="Headlight at Left")
421
+ ],
422
+ note="Headlight at Left",
423
+ picture=PLL_PIC["Gb"],
424
+ )
425
+
426
+ Gc = PLL(
427
+ "Gc",
428
+ "R2 F2 R U2 R U2 R' F (R U R' U') R' F R2",
429
+ note="Headlight at Right",
430
+ picture=PLL_PIC["Gc"],
431
+ )
432
+
433
+ Gd = PLL(
434
+ "Gd",
435
+ "R U R' U' D R2 U' R U' R' U R' U R2 D'",
436
+ note="Headlight at Left",
437
+ picture=PLL_PIC["Gd"],
438
+ )
439
+
440
+
441
+ class Rubik3x3:
442
+ PLL = PLLs()
absfuyu/fun/tarot.py CHANGED
@@ -4,8 +4,8 @@ Absfuyu: Tarot
4
4
  Tarot stuff
5
5
 
6
6
 
7
- Version: 5.2.0
8
- Date updated: 10/03/2025 (dd/mm/yyyy)
7
+ Version: 5.4.0
8
+ Date updated: 21/03/2025 (dd/mm/yyyy)
9
9
 
10
10
  Usage:
11
11
  ------
absfuyu/game/__init__.py CHANGED
@@ -3,8 +3,8 @@ Absfuyu: Game
3
3
  -------------
4
4
  Contain some game that can be played on terminal
5
5
 
6
- Version: 5.2.0
7
- Date updated: 10/03/2025 (dd/mm/yyyy)
6
+ Version: 5.4.0
7
+ Date updated: 21/03/2025 (dd/mm/yyyy)
8
8
  """
9
9
 
10
10
  # Module level
absfuyu/game/game_stat.py CHANGED
@@ -1,8 +1,8 @@
1
1
  """
2
2
  Game: Game Stat
3
3
 
4
- Version: 5.2.0
5
- Date updated: 10/03/2025 (dd/mm/yyyy)
4
+ Version: 5.4.0
5
+ Date updated: 21/03/2025 (dd/mm/yyyy)
6
6
  """
7
7
 
8
8
  # Module level
absfuyu/game/sudoku.py CHANGED
@@ -3,8 +3,8 @@ Game: Sudoku
3
3
  ------------
4
4
  Sudoku 9x9 Solver
5
5
 
6
- Version: 5.2.0
7
- Date updated: 10/03/2025 (dd/mm/yyyy)
6
+ Version: 5.4.0
7
+ Date updated: 21/03/2025 (dd/mm/yyyy)
8
8
 
9
9
  Credit:
10
10
  -------
absfuyu/game/tictactoe.py CHANGED
@@ -2,8 +2,8 @@
2
2
  Game: Tic Tac Toe
3
3
  -----------------
4
4
 
5
- Version: 5.2.0
6
- Date updated: 15/03/2025 (dd/mm/yyyy)
5
+ Version: 5.4.0
6
+ Date updated: 21/03/2025 (dd/mm/yyyy)
7
7
  """
8
8
 
9
9
  # Module level
absfuyu/game/wordle.py CHANGED
@@ -2,8 +2,8 @@
2
2
  Game: Wordle Solver
3
3
  -------------------
4
4
 
5
- Version: 5.2.0
6
- Date updated: 10/03/2025 (dd/mm/yyyy)
5
+ Version: 5.4.0
6
+ Date updated: 21/03/2025 (dd/mm/yyyy)
7
7
 
8
8
  Usage:
9
9
  ------
@@ -3,8 +3,8 @@ Absfuyu: General
3
3
  ----------------
4
4
  Collection of useful classes
5
5
 
6
- Version: 5.2.0
7
- Date updated: 10/03/2025 (dd/mm/yyyy)
6
+ Version: 5.4.0
7
+ Date updated: 21/03/2025 (dd/mm/yyyy)
8
8
 
9
9
  Features:
10
10
  ---------
@@ -3,8 +3,8 @@ Absfuyu: Content
3
3
  ----------------
4
4
  Handle .txt file
5
5
 
6
- Version: 5.2.0
7
- Date updated: 15/03/2025 (dd/mm/yyyy)
6
+ Version: 5.4.0
7
+ Date updated: 21/03/2025 (dd/mm/yyyy)
8
8
 
9
9
  Usage:
10
10
  ------
absfuyu/general/human.py CHANGED
@@ -3,8 +3,8 @@ Absfuyu: Human
3
3
  --------------
4
4
  Human related stuff
5
5
 
6
- Version: 5.2.0
7
- Date updated: 10/03/2025 (dd/mm/yyyy)
6
+ Version: 5.4.0
7
+ Date updated: 21/03/2025 (dd/mm/yyyy)
8
8
  """
9
9
 
10
10
  # Module level
absfuyu/general/shape.py CHANGED
@@ -3,8 +3,8 @@ Absfuyu: Shape
3
3
  --------------
4
4
  Shapes
5
5
 
6
- Version: 5.2.0
7
- Date updated: 10/03/2025 (dd/mm/yyyy)
6
+ Version: 5.4.0
7
+ Date updated: 21/03/2025 (dd/mm/yyyy)
8
8
  """
9
9
 
10
10
  # Module level
absfuyu/logger.py CHANGED
@@ -3,8 +3,8 @@ Absfuyu: Logger
3
3
  ---------------
4
4
  Custom Logger Module
5
5
 
6
- Version: 5.2.0
7
- Date updated: 10/03/2025 (dd/mm/yyyy)
6
+ Version: 5.4.0
7
+ Date updated: 21/03/2025 (dd/mm/yyyy)
8
8
 
9
9
  Usage:
10
10
  ------
@@ -3,8 +3,8 @@ Absfuyu: Package data
3
3
  ---------------------
4
4
  Load package data
5
5
 
6
- Version: 5.2.0
7
- Date updated: 10/03/2025 (dd/mm/yyyy)
6
+ Version: 5.4.0
7
+ Date updated: 21/03/2025 (dd/mm/yyyy)
8
8
  """
9
9
 
10
10
  # Module level
@@ -3,8 +3,8 @@ Absfuyu: Package data
3
3
  ---------------------
4
4
  Deprecated (but might have some use)
5
5
 
6
- Version: 5.2.0
7
- Date updated: 10/03/2025 (dd/mm/yyyy)
6
+ Version: 5.4.0
7
+ Date updated: 21/03/2025 (dd/mm/yyyy)
8
8
  """
9
9
 
10
10
  # Library
absfuyu/sort.py CHANGED
@@ -3,8 +3,8 @@ Absfuyu: Sort
3
3
  -------------
4
4
  Sort Module
5
5
 
6
- Version: 5.2.0
7
- Date updated: 10/03/2025 (dd/mm/yyyy)
6
+ Version: 5.4.0
7
+ Date updated: 21/03/2025 (dd/mm/yyyy)
8
8
  """
9
9
 
10
10
  # Module level
absfuyu/tools/__init__.py CHANGED
@@ -3,8 +3,8 @@ Absfuyu: Tools
3
3
  --------------
4
4
  Some useful tools
5
5
 
6
- Version: 5.2.0
7
- Date updated: 16/03/2025 (dd/mm/yyyy)
6
+ Version: 5.4.0
7
+ Date updated: 21/03/2025 (dd/mm/yyyy)
8
8
  """
9
9
 
10
10
  # Module Package
@@ -12,7 +12,7 @@ Date updated: 16/03/2025 (dd/mm/yyyy)
12
12
  __all__ = [
13
13
  # # Main
14
14
  "Checksum",
15
- "Base64ED",
15
+ "B64",
16
16
  "T2C",
17
17
  # "Charset",
18
18
  # "Generator",
@@ -26,7 +26,7 @@ __all__ = [
26
26
  # Library
27
27
  # ---------------------------------------------------------------------------
28
28
  from absfuyu.tools.checksum import Checksum
29
- from absfuyu.tools.converter import Base64EncodeDecode as Base64ED
29
+ from absfuyu.tools.converter import Base64EncodeDecode as B64
30
30
  from absfuyu.tools.converter import Text2Chemistry as T2C
31
31
  from absfuyu.tools.inspector import Inspector, inspect_all
32
32