pymdownx-mahjong 1.0.0__py3-none-any.whl → 1.1.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.
- pymdownx_mahjong/__init__.py +1 -1
- pymdownx_mahjong/assets/README.md +3 -0
- pymdownx_mahjong/css/mahjong.css +11 -12
- pymdownx_mahjong/inline.py +2 -2
- pymdownx_mahjong/parser.py +33 -2
- pymdownx_mahjong/renderer.py +39 -29
- pymdownx_mahjong/tiles.py +3 -3
- {pymdownx_mahjong-1.0.0.dist-info → pymdownx_mahjong-1.1.0.dist-info}/METADATA +8 -2
- {pymdownx_mahjong-1.0.0.dist-info → pymdownx_mahjong-1.1.0.dist-info}/RECORD +12 -11
- {pymdownx_mahjong-1.0.0.dist-info → pymdownx_mahjong-1.1.0.dist-info}/WHEEL +0 -0
- {pymdownx_mahjong-1.0.0.dist-info → pymdownx_mahjong-1.1.0.dist-info}/entry_points.txt +0 -0
- {pymdownx_mahjong-1.0.0.dist-info → pymdownx_mahjong-1.1.0.dist-info}/licenses/LICENSE +0 -0
pymdownx_mahjong/__init__.py
CHANGED
pymdownx_mahjong/css/mahjong.css
CHANGED
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
--mahjong-error-border: #dc2626;
|
|
24
24
|
--mahjong-error-color: #fca5a5;
|
|
25
25
|
--mahjong-tile-bg: #1e1e1e;
|
|
26
|
-
--mahjong-tile-border: #
|
|
26
|
+
--mahjong-tile-border: #47473e;
|
|
27
27
|
--mahjong-tile-shadow: rgba(0, 0, 0, 0.3);
|
|
28
28
|
}
|
|
29
29
|
|
|
@@ -48,7 +48,7 @@
|
|
|
48
48
|
display: contents;
|
|
49
49
|
}
|
|
50
50
|
|
|
51
|
-
/* Main container */
|
|
51
|
+
/* NOTE Main container */
|
|
52
52
|
.mahjong-hand {
|
|
53
53
|
display: block;
|
|
54
54
|
margin: 1em 0;
|
|
@@ -58,24 +58,24 @@
|
|
|
58
58
|
border-radius: 4px;
|
|
59
59
|
}
|
|
60
60
|
|
|
61
|
-
/* Override MkDocs Material theme figure margins */
|
|
61
|
+
/* NOTE Override MkDocs Material/Zensical theme figure margins */
|
|
62
62
|
.md-typeset .mahjong-hand {
|
|
63
63
|
margin-left: 1rem;
|
|
64
64
|
}
|
|
65
65
|
|
|
66
|
-
/* Hand row - contains left (tiles/melds), draw, and right (dora) sections */
|
|
66
|
+
/* NOTE Hand row - contains left (tiles/melds), draw, and right (dora) sections */
|
|
67
67
|
.mahjong-hand-row {
|
|
68
68
|
display: flex;
|
|
69
69
|
flex-wrap: nowrap;
|
|
70
70
|
align-items: flex-end;
|
|
71
71
|
}
|
|
72
72
|
|
|
73
|
-
/* Left section - closed tiles and melds */
|
|
73
|
+
/* NOTE Left section - closed tiles and melds */
|
|
74
74
|
.mahjong-hand-left {
|
|
75
75
|
flex: 0 0 auto;
|
|
76
76
|
}
|
|
77
77
|
|
|
78
|
-
/* Draw tile section
|
|
78
|
+
/* NOTE Draw tile section */
|
|
79
79
|
.mahjong-hand-draw {
|
|
80
80
|
flex: 0 0 auto;
|
|
81
81
|
margin-left: calc(var(--mahjong-meld-gap) * 0.75);
|
|
@@ -96,13 +96,13 @@
|
|
|
96
96
|
pointer-events: none;
|
|
97
97
|
}
|
|
98
98
|
|
|
99
|
-
/* Melds section - after draw tile */
|
|
99
|
+
/* NOTE Melds section - after draw tile */
|
|
100
100
|
.mahjong-hand-melds {
|
|
101
101
|
flex: 0 0 auto;
|
|
102
102
|
margin-left: calc(var(--mahjong-meld-gap) * 0.75);
|
|
103
103
|
}
|
|
104
104
|
|
|
105
|
-
/* Tiles container - flexbox layout */
|
|
105
|
+
/* NOTE Tiles container - flexbox layout */
|
|
106
106
|
.mahjong-tiles {
|
|
107
107
|
display: flex;
|
|
108
108
|
flex-wrap: wrap;
|
|
@@ -110,7 +110,7 @@
|
|
|
110
110
|
gap: var(--mahjong-tile-gap);
|
|
111
111
|
}
|
|
112
112
|
|
|
113
|
-
/* Individual tile - styled like physical riichi tiles */
|
|
113
|
+
/* NOTE Individual tile - styled like physical riichi tiles */
|
|
114
114
|
.mahjong-tile {
|
|
115
115
|
display: inline-flex;
|
|
116
116
|
align-items: center;
|
|
@@ -122,9 +122,6 @@
|
|
|
122
122
|
background: var(--mahjong-tile-bg);
|
|
123
123
|
border: 2px solid var(--mahjong-tile-border);
|
|
124
124
|
border-radius: 6px;
|
|
125
|
-
box-shadow:
|
|
126
|
-
1px 2px 3px var(--mahjong-tile-shadow),
|
|
127
|
-
inset 0 1px 0 rgba(255, 255, 255, 0.3);
|
|
128
125
|
padding: 2px;
|
|
129
126
|
box-sizing: border-box;
|
|
130
127
|
position: relative;
|
|
@@ -144,6 +141,8 @@
|
|
|
144
141
|
/* Rotated tile (called from another player) */
|
|
145
142
|
.mahjong-tile-rotated {
|
|
146
143
|
transform: rotate(90deg);
|
|
144
|
+
will-change: transform;
|
|
145
|
+
backface-visibility: hidden;
|
|
147
146
|
margin-left: calc(var(--mahjong-tile-gap) * 6);
|
|
148
147
|
margin-right: calc(var(--mahjong-tile-gap) * 6);
|
|
149
148
|
position: relative;
|
pymdownx_mahjong/inline.py
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
|
-
from typing import TYPE_CHECKING, Any
|
|
5
|
+
from typing import TYPE_CHECKING, Any, Final
|
|
6
6
|
|
|
7
7
|
from markdown.inlinepatterns import InlineProcessor
|
|
8
8
|
|
|
@@ -17,7 +17,7 @@ if TYPE_CHECKING:
|
|
|
17
17
|
# Pattern matches :123m:, :1z:, :0m: (red dora), etc.
|
|
18
18
|
# Must be valid MPSZ: one or more groups of digits followed by m/p/s/z
|
|
19
19
|
# Examples: :1m:, :123p:, :5z:, :0s:, :123m456p:
|
|
20
|
-
INLINE_TILE_PATTERN = r":([0-9]+[mpsz])+:"
|
|
20
|
+
INLINE_TILE_PATTERN: Final[str] = r":([0-9]+[mpsz])+:"
|
|
21
21
|
|
|
22
22
|
|
|
23
23
|
class MahjongInlineProcessor(InlineProcessor):
|
pymdownx_mahjong/parser.py
CHANGED
|
@@ -3,8 +3,10 @@
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
5
|
import re
|
|
6
|
+
from collections import Counter
|
|
6
7
|
from dataclasses import dataclass, field
|
|
7
8
|
from enum import Enum
|
|
9
|
+
from typing import Final, Pattern
|
|
8
10
|
|
|
9
11
|
from .tiles import TileInfo, get_tile_info, is_valid_tile
|
|
10
12
|
|
|
@@ -127,11 +129,11 @@ class MahjongParser:
|
|
|
127
129
|
"""
|
|
128
130
|
|
|
129
131
|
# Pattern for a group of numbers followed by a suit
|
|
130
|
-
TILE_GROUP_PATTERN = re.compile(r"([0-9]+)([mpsz])")
|
|
132
|
+
TILE_GROUP_PATTERN: Final[Pattern[str]] = re.compile(r"([0-9]+)([mpsz])")
|
|
131
133
|
|
|
132
134
|
# Pattern for melds: (tiles<) or [tiles] with optional source marker inside brackets
|
|
133
135
|
# For added kan, use + to mark the added tile: (111+1m<)
|
|
134
|
-
MELD_PATTERN = re.compile(r"(\[|\()([0-9]+)(\+)?([0-9])?([mpsz])([<^>])?(\]|\))")
|
|
136
|
+
MELD_PATTERN: Final[Pattern[str]] = re.compile(r"(\[|\()([0-9]+)(\+)?([0-9])?([mpsz])([<^>])?(\]|\))")
|
|
135
137
|
|
|
136
138
|
def __init__(self) -> None:
|
|
137
139
|
self.errors: list[str] = []
|
|
@@ -163,6 +165,9 @@ class MahjongParser:
|
|
|
163
165
|
# Parse closed tiles
|
|
164
166
|
hand.closed_tiles = self._parse_tiles(closed_part)
|
|
165
167
|
|
|
168
|
+
# Validate tile counts (max 4 of each tile type)
|
|
169
|
+
self._validate_tile_counts(hand)
|
|
170
|
+
|
|
166
171
|
if self.errors:
|
|
167
172
|
raise ParseError("; ".join(self.errors))
|
|
168
173
|
|
|
@@ -336,6 +341,32 @@ class MahjongParser:
|
|
|
336
341
|
|
|
337
342
|
return numbers[1] == numbers[0] + 1 and numbers[2] == numbers[1] + 1
|
|
338
343
|
|
|
344
|
+
def _validate_tile_counts(self, hand: Hand) -> None:
|
|
345
|
+
"""Validate that no tile appears more than 4 times.
|
|
346
|
+
|
|
347
|
+
In Mahjong, there are exactly 4 copies of each tile type.
|
|
348
|
+
Having more than 4 of the same tile is invalid.
|
|
349
|
+
|
|
350
|
+
Args:
|
|
351
|
+
hand: The Hand object to validate
|
|
352
|
+
"""
|
|
353
|
+
# Count all tiles including melds
|
|
354
|
+
# Note: Red 5 (0) and regular 5 are different tiles, so we count them separately
|
|
355
|
+
all_tiles = list(hand.closed_tiles)
|
|
356
|
+
for meld in hand.melds:
|
|
357
|
+
all_tiles.extend(meld.tiles)
|
|
358
|
+
if hand.draw_tile:
|
|
359
|
+
all_tiles.append(hand.draw_tile)
|
|
360
|
+
|
|
361
|
+
counts = Counter((t.suit, t.number) for t in all_tiles)
|
|
362
|
+
|
|
363
|
+
for (suit, number), count in counts.items():
|
|
364
|
+
if count > 4:
|
|
365
|
+
tile_notation = f"{number}{suit}"
|
|
366
|
+
self.errors.append(
|
|
367
|
+
f"Invalid tile count: {tile_notation} appears {count} times (max 4)"
|
|
368
|
+
)
|
|
369
|
+
|
|
339
370
|
|
|
340
371
|
def parse_hand(notation: str) -> Hand:
|
|
341
372
|
"""Convenience function to parse a hand notation.
|
pymdownx_mahjong/renderer.py
CHANGED
|
@@ -2,23 +2,47 @@
|
|
|
2
2
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
|
+
import functools
|
|
5
6
|
import html
|
|
6
7
|
import importlib.resources
|
|
7
8
|
import re
|
|
8
9
|
from pathlib import Path
|
|
10
|
+
from typing import Final, Pattern
|
|
9
11
|
|
|
10
12
|
from .parser import Hand, Meld, MeldType, Tile
|
|
11
13
|
from .tiles import TileInfo, get_special_tile
|
|
12
14
|
|
|
13
15
|
# Pre-compiled regex patterns for SVG processing
|
|
14
|
-
_RE_XML_DECL = re.compile(r"<\?xml[^?]*\?>")
|
|
15
|
-
_RE_SODIPODI_SELF = re.compile(r"<sodipodi:namedview[^>]*/>")
|
|
16
|
-
_RE_SODIPODI_FULL = re.compile(r"<sodipodi:namedview[^>]*>.*?</sodipodi:namedview>", re.DOTALL)
|
|
17
|
-
_RE_METADATA = re.compile(r"<metadata[^>]*>.*?</metadata>", re.DOTALL)
|
|
18
|
-
_RE_WIDTH = re.compile(r'width="[^"]*"')
|
|
19
|
-
_RE_HEIGHT = re.compile(r'height="[^"]*"')
|
|
16
|
+
_RE_XML_DECL: Final[Pattern[str]] = re.compile(r"<\?xml[^?]*\?>")
|
|
17
|
+
_RE_SODIPODI_SELF: Final[Pattern[str]] = re.compile(r"<sodipodi:namedview[^>]*/>")
|
|
18
|
+
_RE_SODIPODI_FULL: Final[Pattern[str]] = re.compile(r"<sodipodi:namedview[^>]*>.*?</sodipodi:namedview>", re.DOTALL)
|
|
19
|
+
_RE_METADATA: Final[Pattern[str]] = re.compile(r"<metadata[^>]*>.*?</metadata>", re.DOTALL)
|
|
20
|
+
_RE_WIDTH: Final[Pattern[str]] = re.compile(r'width="[^"]*"')
|
|
21
|
+
_RE_HEIGHT: Final[Pattern[str]] = re.compile(r'height="[^"]*"')
|
|
20
22
|
# Pattern to find IDs in SVGs
|
|
21
|
-
_RE_ID = re.compile(r'id="([^"]+)"')
|
|
23
|
+
_RE_ID: Final[Pattern[str]] = re.compile(r'id="([^"]+)"')
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
@functools.lru_cache(maxsize=128)
|
|
27
|
+
def _load_svg_from_package(asset_name: str, theme: str) -> str:
|
|
28
|
+
"""Load SVG content from package resources with caching.
|
|
29
|
+
|
|
30
|
+
This is a module-level cached function to avoid repeated file I/O
|
|
31
|
+
for the same tile assets across multiple renderer instances.
|
|
32
|
+
|
|
33
|
+
Args:
|
|
34
|
+
asset_name: Name of the asset (e.g., '1m', 'back')
|
|
35
|
+
theme: Theme to load ('light' or 'dark')
|
|
36
|
+
|
|
37
|
+
Returns:
|
|
38
|
+
Raw SVG content string
|
|
39
|
+
|
|
40
|
+
Raises:
|
|
41
|
+
FileNotFoundError: If the asset doesn't exist
|
|
42
|
+
"""
|
|
43
|
+
assets = importlib.resources.files("pymdownx_mahjong") / "assets" / theme
|
|
44
|
+
svg_file = assets / f"{asset_name}.svg"
|
|
45
|
+
return svg_file.read_text(encoding="utf-8")
|
|
22
46
|
|
|
23
47
|
|
|
24
48
|
class MahjongRenderer:
|
|
@@ -62,7 +86,6 @@ class MahjongRenderer:
|
|
|
62
86
|
self.show_labels = show_labels
|
|
63
87
|
self.inline_svg = inline_svg
|
|
64
88
|
self.assets_path = Path(assets_path) if assets_path else None
|
|
65
|
-
self._svg_cache: dict[tuple[str, str], str] = {}
|
|
66
89
|
self._svg_id_counter = 0
|
|
67
90
|
|
|
68
91
|
def render(
|
|
@@ -290,17 +313,12 @@ class MahjongRenderer:
|
|
|
290
313
|
SVG content string with unique IDs
|
|
291
314
|
"""
|
|
292
315
|
theme = theme or (self.theme if self.theme != "auto" else "light")
|
|
293
|
-
cache_key = (theme, info.asset_name)
|
|
294
316
|
|
|
295
|
-
#
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
# Process but don't add unique IDs yet - cache the base processed version
|
|
299
|
-
svg_content = self._process_svg(svg_content, unique_prefix=None)
|
|
300
|
-
self._svg_cache[cache_key] = svg_content
|
|
317
|
+
# Load and process SVG (package assets use module-level LRU cache)
|
|
318
|
+
svg_content = self._load_svg(info, theme)
|
|
319
|
+
svg_content = self._process_svg(svg_content)
|
|
301
320
|
|
|
302
|
-
#
|
|
303
|
-
svg_content = self._svg_cache[cache_key]
|
|
321
|
+
# Make IDs unique for this instance
|
|
304
322
|
self._svg_id_counter += 1
|
|
305
323
|
return self._make_ids_unique(svg_content, f"mj{self._svg_id_counter}_")
|
|
306
324
|
|
|
@@ -342,32 +360,28 @@ class MahjongRenderer:
|
|
|
342
360
|
"""
|
|
343
361
|
theme = theme or (self.theme if self.theme != "auto" else "light")
|
|
344
362
|
|
|
345
|
-
# Try custom assets path first
|
|
363
|
+
# Try custom assets path first (not cached since it's user-specific)
|
|
346
364
|
if self.assets_path:
|
|
347
365
|
svg_path = self.assets_path / theme / f"{info.asset_name}.svg"
|
|
348
366
|
if svg_path.exists():
|
|
349
367
|
return svg_path.read_text(encoding="utf-8")
|
|
350
368
|
|
|
351
|
-
# Fall back to package assets
|
|
369
|
+
# Fall back to package assets (uses module-level LRU cache)
|
|
352
370
|
try:
|
|
353
|
-
|
|
354
|
-
svg_file = assets / f"{info.asset_name}.svg"
|
|
355
|
-
return svg_file.read_text(encoding="utf-8")
|
|
371
|
+
return _load_svg_from_package(info.asset_name, theme)
|
|
356
372
|
except (FileNotFoundError, TypeError):
|
|
357
373
|
# Return a placeholder SVG
|
|
358
374
|
return self._placeholder_svg(info)
|
|
359
375
|
|
|
360
|
-
def _process_svg(self, svg_content: str
|
|
376
|
+
def _process_svg(self, svg_content: str) -> str:
|
|
361
377
|
"""Process SVG content for inline use.
|
|
362
378
|
|
|
363
379
|
- Removes XML declaration
|
|
364
380
|
- Removes unnecessary metadata
|
|
365
381
|
- Adds sizing attributes
|
|
366
|
-
- Makes IDs unique to avoid conflicts when multiple SVGs are on the same page
|
|
367
382
|
|
|
368
383
|
Args:
|
|
369
384
|
svg_content: Raw SVG content
|
|
370
|
-
unique_prefix: Optional prefix to make IDs unique
|
|
371
385
|
|
|
372
386
|
Returns:
|
|
373
387
|
Processed SVG content
|
|
@@ -384,10 +398,6 @@ class MahjongRenderer:
|
|
|
384
398
|
svg_content = _RE_WIDTH.sub(f'width="{self.tile_width}"', svg_content, count=1)
|
|
385
399
|
svg_content = _RE_HEIGHT.sub(f'height="{self.tile_height}"', svg_content, count=1)
|
|
386
400
|
|
|
387
|
-
# Make IDs unique if prefix is provided
|
|
388
|
-
if unique_prefix:
|
|
389
|
-
svg_content = self._make_ids_unique(svg_content, unique_prefix)
|
|
390
|
-
|
|
391
401
|
return svg_content.strip()
|
|
392
402
|
|
|
393
403
|
def _make_ids_unique(self, svg_content: str, prefix: str) -> str:
|
pymdownx_mahjong/tiles.py
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
|
-
from typing import NamedTuple
|
|
5
|
+
from typing import Final, NamedTuple
|
|
6
6
|
|
|
7
7
|
|
|
8
8
|
class TileInfo(NamedTuple):
|
|
@@ -12,7 +12,7 @@ class TileInfo(NamedTuple):
|
|
|
12
12
|
display_name: str
|
|
13
13
|
|
|
14
14
|
|
|
15
|
-
TILE_DATABASE: dict[tuple[str, int], TileInfo] = {
|
|
15
|
+
TILE_DATABASE: Final[dict[tuple[str, int], TileInfo]] = {
|
|
16
16
|
# Manzu
|
|
17
17
|
("m", 1): TileInfo("1m", "1 Man"),
|
|
18
18
|
("m", 2): TileInfo("2m", "2 Man"),
|
|
@@ -57,7 +57,7 @@ TILE_DATABASE: dict[tuple[str, int], TileInfo] = {
|
|
|
57
57
|
("z", 7): TileInfo("7z", "Red Dragon"),
|
|
58
58
|
}
|
|
59
59
|
|
|
60
|
-
SPECIAL_TILES: dict[str, TileInfo] = {
|
|
60
|
+
SPECIAL_TILES: Final[dict[str, TileInfo]] = {
|
|
61
61
|
"back": TileInfo("back", "Face Down"),
|
|
62
62
|
"blank": TileInfo("blank", "Blank"),
|
|
63
63
|
"front": TileInfo("front", "Front"),
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pymdownx-mahjong
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.1.0
|
|
4
4
|
Summary: Python Markdown extension to render and stylize Mahjong tiles.
|
|
5
5
|
Project-URL: Homepage, https://github.com/tylernguyen/pymdownx-mahjong
|
|
6
6
|
Project-URL: Documentation, https://github.com/tylernguyen/pymdownx-mahjong
|
|
@@ -35,9 +35,15 @@ Requires-Dist: mkdocs-material>=9.0; extra == 'mkdocs'
|
|
|
35
35
|
Requires-Dist: mkdocs>=1.4; extra == 'mkdocs'
|
|
36
36
|
Description-Content-Type: text/markdown
|
|
37
37
|
|
|
38
|
+

|
|
39
|
+
|
|
38
40
|
# PyMdown Mahjong
|
|
39
41
|
|
|
40
|
-
|
|
42
|
+
[Python Markdown](https://python-markdown.github.io) extension to render and stylize Mahjong tiles. Designed for use with [MkDocs](https://github.com/mkdocs/mkdocs) and [Zensical](https://github.com/zensical/zensical).
|
|
43
|
+
|
|
44
|
+
## Documentation
|
|
45
|
+
|
|
46
|
+
Demo and documentation can be found at [https://tylernguyen.github.io/pymdownx-mahjong/](https://tylernguyen.github.io/pymdownx-mahjong/).
|
|
41
47
|
|
|
42
48
|
## License
|
|
43
49
|
|
|
@@ -1,11 +1,12 @@
|
|
|
1
|
-
pymdownx_mahjong/__init__.py,sha256=
|
|
1
|
+
pymdownx_mahjong/__init__.py,sha256=mYyokR5i1zy1YoN3kFGPfL-VwlQgMH0yPyS12AT-Ki4,644
|
|
2
2
|
pymdownx_mahjong/extension.py,sha256=aCRMkMQ8c0eenpcyR5eyLdN_OND9JpYFeRxodOeJyGo,6688
|
|
3
|
-
pymdownx_mahjong/inline.py,sha256=
|
|
4
|
-
pymdownx_mahjong/parser.py,sha256=
|
|
5
|
-
pymdownx_mahjong/renderer.py,sha256=
|
|
3
|
+
pymdownx_mahjong/inline.py,sha256=QxnOmiZ-6cKjrLWsmNJwCCK3FVAjPvTgv97hfNnnnWg,2448
|
|
4
|
+
pymdownx_mahjong/parser.py,sha256=I8wDlZO6oPMhTCqC0NFmsZJOQZCCCXyc78mk3vmmwcQ,12396
|
|
5
|
+
pymdownx_mahjong/renderer.py,sha256=Lk52VCrULtwq9dGWr6J-E1_ZJAlO93nJDVSC0I_mhYI,16947
|
|
6
6
|
pymdownx_mahjong/superfences.py,sha256=LXzG6P2EB8dU9A_5ncFbTJEA4Jy6RLwjjYXZS2wSjhs,3099
|
|
7
|
-
pymdownx_mahjong/tiles.py,sha256=
|
|
7
|
+
pymdownx_mahjong/tiles.py,sha256=ltA1xJeS9fVcZQyUwaIjyl1mHEZ0Kr_QUKy1jhCapDM,2583
|
|
8
8
|
pymdownx_mahjong/utils.py,sha256=aHKX4wDCGM_rvaOwFIbd9qVJHpzzUjXWMviLxdwZrdo,2637
|
|
9
|
+
pymdownx_mahjong/assets/README.md,sha256=HDNhZZlt8ffTER1fVNcTayUnFqOmB3tXoocT8iZgCz0,179
|
|
9
10
|
pymdownx_mahjong/assets/dark/0m.svg,sha256=wTa3OxyZziCtsk5hqLpLJig-1IbQPo_XrMrox5wZFzU,18773
|
|
10
11
|
pymdownx_mahjong/assets/dark/0p.svg,sha256=Ge4V_vOYTJtqSOI89YmxP451WsNOL3Pv_A8-apdYrI8,23308
|
|
11
12
|
pymdownx_mahjong/assets/dark/0s.svg,sha256=mErmM8konoHN5XlNwuffYEJNczrawQo1800kQlAg1VA,32913
|
|
@@ -86,9 +87,9 @@ pymdownx_mahjong/assets/light/9s.svg,sha256=WjNpR3IUty3ccnEwq9CpcSbLr3A-ta0yJqWx
|
|
|
86
87
|
pymdownx_mahjong/assets/light/back.svg,sha256=HPAJfchslm_1uZQzpY8FUNF2s8hmbARGkhxNMlfnkQk,11245
|
|
87
88
|
pymdownx_mahjong/assets/light/blank.svg,sha256=uKGioQLfrCZsSbMr66iDXv4w9lKHEqGym1l098-q5DM,8499
|
|
88
89
|
pymdownx_mahjong/assets/light/front.svg,sha256=63TB5953_-10TDRd7K_kJnHoqt-6wd05MEGV2AcNsks,11906
|
|
89
|
-
pymdownx_mahjong/css/mahjong.css,sha256=
|
|
90
|
-
pymdownx_mahjong-1.
|
|
91
|
-
pymdownx_mahjong-1.
|
|
92
|
-
pymdownx_mahjong-1.
|
|
93
|
-
pymdownx_mahjong-1.
|
|
94
|
-
pymdownx_mahjong-1.
|
|
90
|
+
pymdownx_mahjong/css/mahjong.css,sha256=OpO9RR-UPFAbPF6Q8Wuz0Ak_Pg9rOrOsMAtnP0oj5LE,9307
|
|
91
|
+
pymdownx_mahjong-1.1.0.dist-info/METADATA,sha256=8uXHaggPvIhroHgD2VdYNfDiJdtmM99XXAgIGjnlslc,2213
|
|
92
|
+
pymdownx_mahjong-1.1.0.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
|
|
93
|
+
pymdownx_mahjong-1.1.0.dist-info/entry_points.txt,sha256=dEty6XpsYCWl45PeRYHiH9ORxwSZA64LQU8gWF1CuyU,72
|
|
94
|
+
pymdownx_mahjong-1.1.0.dist-info/licenses/LICENSE,sha256=Mnpx_G3eVz7AX5uTHGPaZWHJYiJYu4Y2_l01PsksHdg,19921
|
|
95
|
+
pymdownx_mahjong-1.1.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|