Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package python-bracex for openSUSE:Factory 
checked in at 2026-07-13 14:27:50
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-bracex (Old)
 and      /work/SRC/openSUSE:Factory/.python-bracex.new.1991 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-bracex"

Mon Jul 13 14:27:50 2026 rev:8 rq:1365235 version:3.0

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-bracex/python-bracex.changes      
2025-08-08 15:16:12.383052763 +0200
+++ /work/SRC/openSUSE:Factory/.python-bracex.new.1991/python-bracex.changes    
2026-07-13 14:28:32.888404148 +0200
@@ -1,0 +2,15 @@
+Sun Jul 12 14:12:35 UTC 2026 - Sebastian Wagner <[email protected]>
+
+- update to version 3.0:
+ - BREAK: If there are no expansions, `bracex` will not return an empty string 
by default in the list. This matches
+     Bash. To get the old behavior, enable the new `return_empty` parameter to 
always return at least an empty string if
+     expansion yields no expansions.
+ - FIX: To better match Bash, empty expansions are not returned as empty 
strings.
+ - FIX: No longer backtrack if a sequence is evaluated and is deemed to be 
invalid.
+- update to version 2.7:
+ - NEW: Drop support for Python 3.9.
+ - FIX: Fix issue where the parsing of literal strings was slow.
+ - FIX: Fix issue related to tracking the count of expansions when a set was 
specified with an empty slot.
+ - FIX: Fix issue related to chaining expansions.
+
+-------------------------------------------------------------------

Old:
----
  bracex-2.6.tar.gz

New:
----
  bracex-3.0.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python-bracex.spec ++++++
--- /var/tmp/diff_new_pack.duIthm/_old  2026-07-13 14:28:33.468423978 +0200
+++ /var/tmp/diff_new_pack.duIthm/_new  2026-07-13 14:28:33.468423978 +0200
@@ -1,7 +1,7 @@
 #
 # spec file for package python-bracex
 #
-# Copyright (c) 2024 SUSE LLC
+# Copyright (c) 2026 SUSE LLC and contributors
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -18,7 +18,7 @@
 
 %{?sle15_python_module_pythons}
 Name:           python-bracex
-Version:        2.6
+Version:        3.0
 Release:        0
 Summary:        Bash style brace expander
 License:        MIT

++++++ bracex-2.6.tar.gz -> bracex-3.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/bracex-2.6/.gitignore new/bracex-3.0/.gitignore
--- old/bracex-2.6/.gitignore   2020-02-02 01:00:00.000000000 +0100
+++ new/bracex-3.0/.gitignore   2020-02-02 01:00:00.000000000 +0100
@@ -1,5 +1,8 @@
 .DS_Store
 
+manifest-css.json
+manifest-js.json
+
 # Byte-compiled / optimized / DLL files
 __pycache__/
 *.py[cod]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/bracex-2.6/LICENSE.md new/bracex-3.0/LICENSE.md
--- old/bracex-2.6/LICENSE.md   2020-02-02 01:00:00.000000000 +0100
+++ new/bracex-3.0/LICENSE.md   2020-02-02 01:00:00.000000000 +0100
@@ -1,6 +1,6 @@
 MIT License
 
-Copyright (c) 2018 - 2025 Isaac Muse
+Copyright (c) 2018 - 2026 Isaac Muse
 
 Permission is hereby granted, free of charge, to any person obtaining a copy
 of this software and associated documentation files (the "Software"), to deal
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/bracex-2.6/PKG-INFO new/bracex-3.0/PKG-INFO
--- old/bracex-2.6/PKG-INFO     2020-02-02 01:00:00.000000000 +0100
+++ new/bracex-3.0/PKG-INFO     2020-02-02 01:00:00.000000000 +0100
@@ -1,6 +1,6 @@
 Metadata-Version: 2.4
 Name: bracex
-Version: 2.6
+Version: 3.0
 Summary: Bash style brace expander.
 Project-URL: Homepage, https://github.com/facelessuser/bracex
 Author-email: Isaac Muse <[email protected]>
@@ -13,7 +13,6 @@
 Classifier: License :: OSI Approved :: MIT License
 Classifier: Operating System :: OS Independent
 Classifier: Programming Language :: Python :: 3
-Classifier: Programming Language :: Python :: 3.9
 Classifier: Programming Language :: Python :: 3.10
 Classifier: Programming Language :: Python :: 3.11
 Classifier: Programming Language :: Python :: 3.12
@@ -21,11 +20,10 @@
 Classifier: Programming Language :: Python :: 3.14
 Classifier: Topic :: Software Development :: Libraries :: Python Modules
 Classifier: Typing :: Typed
-Requires-Python: >=3.9
+Requires-Python: >=3.10
 Description-Content-Type: text/markdown
 
 [![Donate via PayPal][donate-image]][donate-link]
-[![Build][github-ci-image]][github-ci-link]
 [![Coverage Status][codecov-image]][codecov-link]
 [![PyPI Version][pypi-image]][pypi-link]
 [![PyPI - Python Version][python-image]][pypi-link]
@@ -84,8 +82,6 @@
 
 MIT License
 
-[github-ci-image]: 
https://github.com/facelessuser/bracex/actions/workflows/build.yml/badge.svg
-[github-ci-link]: 
https://github.com/facelessuser/bracex/actions?query=workflow%3Abuild+branch%3Amaster
 [codecov-image]: 
https://img.shields.io/codecov/c/github/facelessuser/bracex/master.svg?logo=codecov&logoColor=aaaaaa&labelColor=333333
 [codecov-link]: https://codecov.io/github/facelessuser/bracex
 [pypi-image]: 
https://img.shields.io/pypi/v/bracex.svg?logo=pypi&logoColor=aaaaaa&labelColor=333333
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/bracex-2.6/README.md new/bracex-3.0/README.md
--- old/bracex-2.6/README.md    2020-02-02 01:00:00.000000000 +0100
+++ new/bracex-3.0/README.md    2020-02-02 01:00:00.000000000 +0100
@@ -1,5 +1,4 @@
 [![Donate via PayPal][donate-image]][donate-link]
-[![Build][github-ci-image]][github-ci-link]
 [![Coverage Status][codecov-image]][codecov-link]
 [![PyPI Version][pypi-image]][pypi-link]
 [![PyPI - Python Version][python-image]][pypi-link]
@@ -58,8 +57,6 @@
 
 MIT License
 
-[github-ci-image]: 
https://github.com/facelessuser/bracex/actions/workflows/build.yml/badge.svg
-[github-ci-link]: 
https://github.com/facelessuser/bracex/actions?query=workflow%3Abuild+branch%3Amaster
 [codecov-image]: 
https://img.shields.io/codecov/c/github/facelessuser/bracex/master.svg?logo=codecov&logoColor=aaaaaa&labelColor=333333
 [codecov-link]: https://codecov.io/github/facelessuser/bracex
 [pypi-image]: 
https://img.shields.io/pypi/v/bracex.svg?logo=pypi&logoColor=aaaaaa&labelColor=333333
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/bracex-2.6/bracex/__init__.py 
new/bracex-3.0/bracex/__init__.py
--- old/bracex-2.6/bracex/__init__.py   2020-02-02 01:00:00.000000000 +0100
+++ new/bracex-3.0/bracex/__init__.py   2020-02-02 01:00:00.000000000 +0100
@@ -22,10 +22,9 @@
 import itertools
 import math
 import re
-from typing import Iterator, Pattern, Match, Iterable, AnyStr
+from typing import Iterator, Pattern, Match, Iterable, AnyStr, Any
 from . import __meta__
 
-
 __all__ = ('expand', 'iexpand')
 
 __version__ = __meta__.__version__
@@ -40,24 +39,41 @@
 DEFAULT_LIMIT = 1000
 
 
+class Sentinel(str):
+    """A sentinel string value."""
+
+
+EMPTY = Sentinel('')
+
+
 class ExpansionLimitException(Exception):
     """Brace expansion limit exception."""
 
 
-def expand(string: AnyStr, keep_escapes: bool = False, limit: int = 
DEFAULT_LIMIT) -> list[AnyStr]:
+def expand(
+    string: AnyStr,
+    keep_escapes: bool = False,
+    limit: int = DEFAULT_LIMIT,
+    return_empty: bool = False
+) -> list[AnyStr]:
     """Expand braces."""
 
-    return list(iexpand(string, keep_escapes, limit))
+    return list(iexpand(string, keep_escapes, limit, return_empty))
 
 
-def iexpand(string: AnyStr, keep_escapes: bool = False, limit: int = 
DEFAULT_LIMIT) -> Iterator[AnyStr]:
+def iexpand(
+    string: AnyStr,
+    keep_escapes: bool = False,
+    limit: int = DEFAULT_LIMIT,
+    return_empty: bool = False
+) -> Iterator[AnyStr]:
     """Expand braces and return an iterator."""
 
     if isinstance(string, bytes):
-        for entry in ExpandBrace(keep_escapes, 
limit).expand(string.decode('latin-1')):
+        for entry in ExpandBrace(keep_escapes, limit, 
return_empty).expand(string.decode('latin-1')):
             yield entry.encode('latin-1')
     else:
-        for entry in ExpandBrace(keep_escapes, limit).expand(string):
+        for entry in ExpandBrace(keep_escapes, limit, 
return_empty).expand(string):
             yield entry
 
 
@@ -127,32 +143,27 @@
 class ExpandBrace:
     """Expand braces like in Bash."""
 
-    def __init__(self, keep_escapes: bool = False, limit: int = DEFAULT_LIMIT) 
-> None:
+    def __init__(
+        self,
+        keep_escapes: bool = False,
+        limit: int = DEFAULT_LIMIT,
+        return_empty: bool = False
+    ) -> None:
         """Initialize."""
 
         self.max_limit = limit
-        self.count = 0
         self.expanding = False
         self.keep_escapes = keep_escapes
+        self.return_empty = return_empty
 
-    def update_count_seq(self, count: list[int]) -> None:
-        """Update the count from a list after evaluating a brace sequence and 
assert if count exceeds the max limit."""
-
-        self.count -= sum(count)
-        prod = 1
-        for c in count:
-            prod *= c
-        self.update_count(prod)
-
-    def update_count(self, count: int) -> None:
-        """Update the count and assert if count exceeds the max limit."""
+    def account(self, count: int) -> int:
+        """Ensure count is not exceeding the expectation."""
 
-        self.count += count
-
-        if self.max_limit > 0 and self.count > self.max_limit:
+        if self.max_limit > 0 and count > self.max_limit:
             raise ExpansionLimitException(
                 f'Brace expansion has exceeded the limit of {self.max_limit:d}'
             )
+        return count
 
     def set_expanding(self) -> bool:
         """Set that we are expanding a sequence, and return whether a release 
is required by the caller."""
@@ -192,9 +203,33 @@
         """
 
         for x in itertools.product(a, b):
-            yield ''.join(x) if isinstance(x, tuple) else x
-
-    def get_literals(self, c: str, i: StringIter, depth: int) -> Iterator[str] 
| None:
+            if all(i is EMPTY for i in x):
+                yield EMPTY
+            else:
+                yield ''.join(x)
+
+    def chain(self, *iterables: Any) -> Iterator[str]:
+        """Chain iterables."""
+
+        for iterable in iterables:
+            yield from iterable
+
+    def flatten(self, iterables: Any) -> Iterator[str]:
+        """Flatten out results."""
+
+        for item in iterables:
+            if isinstance(item, list):
+                yield from self.flatten(item)
+                continue
+            yield item
+
+    def get_literals(
+        self,
+        c: str,
+        i: StringIter,
+        depth: int,
+        ignore_end: bool = False
+    ) -> tuple[list[str | Iterator[str]], int]:
         """
         Get a string literal.
 
@@ -202,66 +237,63 @@
         Also gather chars between braces and commas within a group 
(is_expanding).
         """
 
-        result = iter([''])
+        result = []  # type: list[str | Iterator[str]]
         is_dollar = False
-
-        count = True
-        seq_count = []
+        count = 1
+        literal = ''
 
         try:
             while c:
-                value = [c]  # type: Iterable[str]
                 ignore_brace = is_dollar
                 is_dollar = False
 
                 if c == '$':
                     is_dollar = True
+                    literal += c
 
                 elif c == '\\':
-                    value = [self.get_escape(c, i)]
+                    literal += self.get_escape(c, i)
 
                 elif not ignore_brace and c == '{':
+
+                    if literal:
+                        result.append(literal)
+                        literal = ''
+
                     # Try and get the group
-                    index = i.index
                     try:
-                        current_count = self.count
-                        seq = self.get_sequence(next(i), i, depth + 1)
-                        if seq:
-                            if self.max_limit > 0:
-                                diff = self.count - current_count
-                                seq_count.append(diff)
-                            count = False
-                            value = seq
+                        seq, scount = self.get_sequence(next(i), i, depth + 1)
+                        count *= scount
+                        result.append(seq)
                     except StopIteration:
-                        # Searched to end of string
-                        # and still didn't find it.
-                        i.rewind(i.index - index)
+                        # There are no characters after `{`
+                        # Save `{` and stop parsing.
+                        literal += c
+                        raise
 
-                elif self.is_expanding() and c in (',', '}'):
+                elif self.is_expanding() and (c == ',' or (c == '}' and not 
ignore_end)):
                     # We are Expanding within a group and found a group 
delimiter
                     # Return what we gathered before the group delimiters.
-                    i.rewind(1)
-                    if count:
-                        self.update_count(1)
-                    else:
-                        self.update_count_seq(seq_count)
-                    return result
 
-                # Squash the current set of literals.
-                result = self.squash(result, value)
+                    ignore_end = False
+
+                    if literal:
+                        result.append(literal)
+
+                    i.rewind(1)
+                    break
+                else:
+                    literal += c
 
                 c = next(i)
         except StopIteration:
-            if self.is_expanding():
-                return None
+            # Ensure we store any remaining literals
+            if literal:
+                result.append(literal)
 
-        if count:
-            self.update_count(1)
-        else:
-            self.update_count_seq(seq_count)
-        return result
+        return result, self.account(count)
 
-    def get_sequence(self, c: str, i: StringIter, depth: int) -> Iterator[str] 
| None:
+    def get_sequence(self, c: str, i: StringIter, depth: int) -> 
tuple[Iterator[str], int]:
         """
         Get the sequence.
 
@@ -269,69 +301,100 @@
         It will basically crawl to the end or find a valid series.
         """
 
-        result = iter([])  # type: Iterator[str]
+        result = []  # type: list[str | Iterator[str] | Iterable[str | 
Iterator[str]]]
         release = self.set_expanding()
         has_comma = False  # Used to indicate validity of group (`{1..2}` are 
an exception).
         is_empty = True  # Tracks whether the current slot is empty 
`{slot,slot,slot}`.
+        counts = []
 
         # Detect numerical and alphabetic series: `{1..2}` etc.
         i.rewind(1)
-        item = self.get_range(i)
+        item, count = self.get_range(i)
         i.advance(1)
         if item is not None:
             self.release_expanding(release)
-            return item
+            return item, self.account(count)
 
         try:
             while True:
                 # Bash has some special top level logic. if `}` follows `{` 
but hasn't matched
                 # a group yet, keep going except when the first 2 bytes are 
`{}` which gets
                 # completely ignored.
-                keep_looking = depth == 1 and not has_comma  # and i.index not 
in self.skip_index
+                keep_looking = depth == 1 and not has_comma
                 if (c == '}' and (not keep_looking or i.index == 2)):
-                    # If there is no comma, we know the sequence is bogus.
+                    self.release_expanding(release)
+
+                    # Handle empty slot
                     if is_empty:
-                        result = itertools.chain(result, [''])
+                        result.append(EMPTY)
+                        if has_comma:
+                            counts.append(1)
+
+                    # Sequence is not valid
                     if not has_comma:
-                        result = (''.join(['{', literal, '}']) for literal in 
result)
-                    self.release_expanding(release)
-                    return result
+                        count = 1
+                        temp = iter(['{'])
+                        for r in self.flatten(result):
+                            temp = self.squash(temp, [r] if isinstance(r, str) 
else r)
+                        temp = self.squash(temp, ['}'])
+                        return temp, self.account(math.prod(counts, start=1))
+
+                    # Format return for a sequence
+                    fin = iter([])  # type: Iterator[str]
+                    start = 0
+                    l = len(result)
+                    for e, x in enumerate(result):
+                        if not isinstance(x, str):
+                            if e != start:
+                                fin = self.chain(fin, result[start:e])
+                            if isinstance(x, list):
+                                temp = iter([EMPTY])
+                                for y in x:
+                                    temp = self.squash(temp, [y] if 
isinstance(y, str) else y)
+                                fin = self.chain(fin, temp)
+                            else:
+                                fin = self.chain(fin, result[e])
+                            start = e + 1
+                    if start < l:
+                        fin = self.chain(fin, result[start:])
+                    return fin, self.account(sum(counts))
 
                 elif c == ',':
                     # Must be the first element in the list.
                     has_comma = True
                     if is_empty:
-                        result = itertools.chain(result, [''])
+                        result.append(EMPTY)
+                        counts.append(1)
                     else:
                         is_empty = True
 
                 else:
-                    if c == '}':
-                        # Top level: If we didn't find a comma, we haven't
-                        # completed the top level group. Request more and
-                        # append to what we already have for the first slot.
-                        if is_empty and not has_comma:
-                            result = itertools.chain(result, [c])
+                    # Lower level: Try to find group, but give up if cannot 
acquire.
+                    value, lcount = self.get_literals(c, i, depth, 
keep_looking)
+                    counts.append(lcount)
+                    if value is not None:
+                        if len(value) > 1:
+                            result.append(value)
                         else:
-                            result = self.squash(result, [c])
-                        value = self.get_literals(next(i), i, depth)
-                        if value is not None:
-                            result = self.squash(result, value)
-                            is_empty = False
-                    else:
-                        # Lower level: Try to find group, but give up if 
cannot acquire.
-                        value = self.get_literals(c, i, depth)
-                        if value is not None:
-                            result = itertools.chain(result, value)
-                            is_empty = False
+                            result.extend(value)
+                        is_empty = False
 
                 c = next(i)
 
         except StopIteration:
             self.release_expanding(release)
-            raise
 
-    def get_range(self, i: StringIter) -> Iterator[str] | None:
+        # Sequence is not valid
+        temp2 = iter(['{'])  # type: Iterator[str]
+        l = len(result)
+        last_str = False
+        for r in self.flatten(result):
+            is_str = isinstance(r, str)
+            temp2 = self.squash(temp2, [(',' if last_str else '') + r] if 
is_str else r)
+            last_str = is_str
+        return temp2, self.account(math.prod(counts, start=1))
+
+    def get_range(self, i: StringIter) -> tuple[Iterator[str] | None, int]:
         """
         Check and retrieve range if value is a valid range.
 
@@ -347,8 +410,6 @@
             m = i.match(RE_CHR_ITER)
             if m:
                 return self.get_char_range(*m.groups())
-        except ExpansionLimitException:
-            raise
         except Exception:  # pragma: no cover
             # TODO: We really should never fail here,
             # but if we do, assume the sequence range
@@ -356,7 +417,7 @@
             # be removed in the future with more testing.
             pass
 
-        return None
+        return None, 0
 
     def format_values(self, values: Iterable[int], padding: int) -> 
Iterator[str]:
         """Get padding adjusting for negative values."""
@@ -364,7 +425,7 @@
         for value in values:
             yield "{:0{pad}d}".format(value, pad=padding) if padding else 
str(value)
 
-    def get_int_range(self, start: str, end: str, increment: str | None = 
None) -> Iterator[str]:
+    def get_int_range(self, start: str, end: str, increment: str | None = 
None) -> tuple[Iterator[str], int]:
         """Get an integer range between start and end and increments of 
increment."""
 
         first, last = int(start), int(end)
@@ -389,15 +450,15 @@
             padding = 0
 
         if first < last:
-            self.update_count(math.ceil(abs(((last + 1) - first) / inc)))
+            count = math.ceil(abs(((last + 1) - first) / inc))
             r = range(first, last + 1, -inc if inc < 0 else inc)
         else:
-            self.update_count(math.ceil(abs(((first + 1) - last) / inc)))
+            count = math.ceil(abs(((first + 1) - last) / inc))
             r = range(first, last - 1, inc if inc < 0 else -inc)
 
-        return self.format_values(r, padding)
+        return self.format_values(r, padding), count
 
-    def get_char_range(self, start: str, end: str, increment: str | None = 
None) -> Iterator[str]:
+    def get_char_range(self, start: str, end: str, increment: str | None = 
None) -> tuple[Iterator[str], int]:
         """Get a range of alphabetic characters."""
 
         inc = int(increment) if increment else 1
@@ -416,35 +477,34 @@
         last = alpha.index(end)
 
         if first < last:
-            self.update_count(math.ceil(((last + 1) - first) / inc))
-            return itertools.islice(alpha, first, last + 1, inc)
-
-        else:
-            self.update_count(math.ceil(((first + 1) - last) / inc))
-            return itertools.islice(alpha, last, first + 1, inc)
+            count = math.ceil(((last + 1) - first) / inc)
+            return itertools.islice(alpha, first, last + 1, inc), count
+        count = math.ceil(((first + 1) - last) / inc)
+        return itertools.islice(alpha, last, first + 1, inc), count
+
+    def expand_str(self, string: str) -> Iterator[str]:
+        """Expand the string."""
+
+        i = StringIter(string)
+        values, _ = self.get_literals(next(i), i, 0)
+
+        # Squash the nested list by calculating the combinations
+        results = iter([EMPTY])  # type: Iterator[str]
+        for v in values:
+            results = self.squash(results, [v] if isinstance(v, str) else v)
+        return results
 
     def expand(self, string: str) -> Iterator[str]:
         """Expand."""
 
         self.expanding = False
-        empties = []
         found_literal = False
         if string:
-            i = StringIter(string)
-            value = self.get_literals(next(i), i, 0)
-            if value is not None:
-                for x in value:
-                    # We don't want to return trailing empty strings.
-                    # Store empty strings and output only when followed by a 
literal.
-                    if not x:
-                        empties.append(x)
-                        continue
-                    found_literal = True
-                    while empties:
-                        yield empties.pop(0)
-                    yield x
-        empties = []
+            for x in self.expand_str(string):
+                if x is EMPTY:
+                    continue
+                found_literal = True
+                yield x
 
-        # We found no literals so return an empty string
-        if not found_literal:
+        if not found_literal and self.return_empty:
             yield ""
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/bracex-2.6/bracex/__meta__.py 
new/bracex-3.0/bracex/__meta__.py
--- old/bracex-2.6/bracex/__meta__.py   2020-02-02 01:00:00.000000000 +0100
+++ new/bracex-3.0/bracex/__meta__.py   2020-02-02 01:00:00.000000000 +0100
@@ -193,5 +193,5 @@
     return Version(major, minor, micro, release, pre, post, dev)
 
 
-__version_info__ = Version(2, 6, 0, "final")
+__version_info__ = Version(3, 0, 0, "final")
 __version__ = __version_info__._get_canonical()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/bracex-2.6/docs/src/markdown/about/changelog.md 
new/bracex-3.0/docs/src/markdown/about/changelog.md
--- old/bracex-2.6/docs/src/markdown/about/changelog.md 2020-02-02 
01:00:00.000000000 +0100
+++ new/bracex-3.0/docs/src/markdown/about/changelog.md 2020-02-02 
01:00:00.000000000 +0100
@@ -1,5 +1,20 @@
 # Changes
 
+## 3.0
+
+-   **BREAK**: If there are no expansions, `bracex` will not return an empty 
string by default in the list. This matches
+    Bash. To get the old behavior, enable the new `return_empty` parameter to 
always return at least an empty string if
+    expansion yields no expansions.
+-   **FIX**: To better match Bash, empty expansions are not returned as empty 
strings.
+-   **FIX**: No longer backtrack if a sequence is evaluated and is deemed to 
be invalid.
+
+## 2.7
+
+-   **NEW**: Drop support for Python 3.9.
+-   **FIX**: Fix issue where the parsing of literal strings was slow.
+-   **FIX**: Fix issue related to tracking the count of expansions when a set 
was specified with an empty slot.
+-   **FIX**: Fix issue related to chaining expansions.
+
 ## 2.6
 
 -   **NEW**: Drop support for Python 3.8.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/bracex-2.6/docs/src/markdown/about/development.md 
new/bracex-3.0/docs/src/markdown/about/development.md
--- old/bracex-2.6/docs/src/markdown/about/development.md       2020-02-02 
01:00:00.000000000 +0100
+++ new/bracex-3.0/docs/src/markdown/about/development.md       2020-02-02 
01:00:00.000000000 +0100
@@ -19,7 +19,7 @@
 --------------------- | -----------
 `docs/src/dictionary` | Contains the spell check wordlist(s) for the project.
 `docs/src/markdown`   | Contains the content for the documentation.
-`soupsieve`           | Contains the source code for the project.
+`bracex`              | Contains the source code for the project.
 `requirements`        | Contains files with lists of dependencies that are 
required for the project, and required for continuous integration.
 `tests`               | Contains unit test files.
 
@@ -37,8 +37,7 @@
 Markdown. If you would like to build and preview the documentation, you must 
have these packages installed:
 
 -   @Python-Markdown/markdown: the Markdown parser.
--   @mkdocs/mkdocs: the document site generator.
--   @squidfunk/mkdocs-material: a material theme for MkDocs.
+-   @zensical/zensical: the document site generator.
 -   @facelessuser/pymdown-extensions: this Python Markdown extension bundle.
 
 In order to build and preview the documents, just run the command below from 
the root of the project and you should be
@@ -46,7 +45,7 @@
 and have your browser preview update live.
 
 ```
-mkdocs serve
+zensical serve -f zensical.yml
 ```
 
 ## Spell Checking Documents
@@ -65,7 +64,7 @@
 You will need to make sure the documents are built first:
 
 ```
-mkdocs build --clean
+zensical build --clean -f zensical.yml
 ```
 
 And then run the spell checker.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/bracex-2.6/docs/src/markdown/index.md 
new/bracex-3.0/docs/src/markdown/index.md
--- old/bracex-2.6/docs/src/markdown/index.md   2020-02-02 01:00:00.000000000 
+0100
+++ new/bracex-3.0/docs/src/markdown/index.md   2020-02-02 01:00:00.000000000 
+0100
@@ -12,7 +12,7 @@
 
 Bracex adds this ability to Python:
 
-```pycon3
+```pycon
 >>> bracex.expand(r'file-{1,2,3}.txt')
 ['file-1.txt', 'file-2.txt', 'file-3.txt']
 ```
@@ -43,62 +43,62 @@
 
 More Examples:
 
-```pycon3
+```pycon
 >>> bracex.expand(r'-v{,,}')
 ['-v', '-v', '-v']
 ```
 
 Nested braces:
 
-```pycon3
+```pycon
 >>> bracex.expand(r'file-{{a,b},c}d.txt')
 ['file-ad.txt', 'file-bd.txt', 'file-cd.txt']
 ```
 
 Numerical sequences:
 
-```pycon3
+```pycon
 >>> bracex.expand(r'file{0..3}.txt')
 ['file0.txt', 'file1.txt', 'file2.txt', 'file3.txt']
 ```
 
-```pycon3
+```pycon
 >>> bracex.expand(r'file{0..6..2}.txt')
 ['file0.txt', 'file2.txt', 'file4.txt', 'file6.txt']
 ```
 
-```pycon3
+```pycon
 >>> bracex.expand(r'file{00..10..5}.jpg')
 ['file00.jpg', 'file05.jpg', 'file10.jpg']
 ```
 
 Alphabetic sequences:
 
-```pycon3
+```pycon
 >>> bracex.expand(r'file{A..D}.txt')
 ['fileA.txt', 'fileB.txt', 'fileC.txt', 'fileD.txt']
 ```
 
-```pycon3
+```pycon
 >>> bracex.expand(r'file{A..G..2}.txt')
 ['fileA.txt', 'fileC.txt', 'fileE.txt', 'fileG.txt']
 ```
 
 Allows escaping:
 
-```pycon3
+```pycon
 >>> bracex.expand(r'file\{00..10..5}.jpg')
 ['file{00..10..5}.jpg']
 ```
 
-```pycon3
+```pycon
 >>> bracex.expand(r'file\{00..10..5}.jpg', keep_escapes=True)
 ['file\\{00..10..5}.jpg']
 ```
 
 Bracex will **not** expand braces in the form of `${...}`:
 
-```pycon3
+```pycon
 >>> bracex.expand(r'file${a,b,c}.jpg')
 ['file${a,b,c}.jpg']
 ```
@@ -117,8 +117,15 @@
 def expand(string, keep_escapes=False, limit=1000):
 ```
 
-`expand` accepts a string and returns a list of expanded strings. It will 
always return at least a single empty string
-`[""]`. By default, escapes will be resolved and the backslashes reduced 
accordingly, but `keep_escapes` will process
+`expand` accepts a string and returns a list of expanded strings. It 
expansions are all empty, an empty array will be
+returned. If it is desired to always at least have an empty string, 
`return_empty` can be be enabled to always return
+at least `[""]`.
+
+> [!note] 3.0 Change in Behavior
+> Prior to 3.0, `expand` always returned at least `[""]`, even if all 
expansions were empty. Now `return_empty` must be
+> enabled to restore this behavior.
+
+By default, escapes will be resolved and the backslashes reduced accordingly, 
but `keep_escapes` will process
 the escapes without stripping them out.
 
 By default, brace expansion growth is limited to `1000`. This limit can be 
configured via the `limit` option. If you
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/bracex-2.6/docs/theme/announce.html 
new/bracex-3.0/docs/theme/announce.html
--- old/bracex-2.6/docs/theme/announce.html     2020-02-02 01:00:00.000000000 
+0100
+++ new/bracex-3.0/docs/theme/announce.html     2020-02-02 01:00:00.000000000 
+0100
@@ -1,5 +1,10 @@
-<a href="{{ 'about/contributing/#contributing--support' | url 
}}">Sponsorship</a>
+<span class="twemoji">
+{% set icon = "material/alert-decagram" %}
+{% include ".icons/" ~ icon ~ ".svg" %}
+</span>
+<a href="{{ 'about/contributing/#become-a-sponsor' | url }}">Sponsorship</a>
 is now available!
 <span class="twemoji heart-throb">
-  <svg xmlns="http://www.w3.org/2000/svg"; width="16" height="16" viewBox="0 0 
16 16"><path fill-rule="evenodd" d="M7.655 14.916L8 14.25l.345.666a.752.752 0 
01-.69 0zm0 0L8 14.25l.345.666.002-.001.006-.003.018-.01a7.643 7.643 0 
00.31-.17 22.08 22.08 0 003.433-2.414C13.956 10.731 16 8.35 16 5.5 16 2.836 
13.914 1 11.75 1 10.203 1 8.847 1.802 8 3.02 7.153 1.802 5.797 1 4.25 1 2.086 1 
0 2.836 0 5.5c0 2.85 2.045 5.231 3.885 6.818a22.075 22.075 0 003.744 
2.584l.018.01.006.003h.002z"/></svg>
+  {% set icon = "octicons/heart-fill-16" %}
+  {% include ".icons/" ~ icon ~ ".svg" %}
 </span>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/bracex-2.6/docs/theme/assets/pymdownx-extras/extra-95634471d6.css 
new/bracex-3.0/docs/theme/assets/pymdownx-extras/extra-95634471d6.css
--- old/bracex-2.6/docs/theme/assets/pymdownx-extras/extra-95634471d6.css       
1970-01-01 01:00:00.000000000 +0100
+++ new/bracex-3.0/docs/theme/assets/pymdownx-extras/extra-95634471d6.css       
2020-02-02 01:00:00.000000000 +0100
@@ -0,0 +1,2 @@
+:root>*{--md-default-bg-color--trans: rgb(100%, 100%, 100%, 
0);--md-tab-control-bg: var(--md-default-bg-color);--md-code-fg-color: 
#1F1F1F;--md-code-bg-color: #F5F5F5;--md-code-title-bg-color: 
#F5F5F5;--md-code-inline-bg-color: #F5F5F5;--md-code-hl-operator-color: 
#A3134D;--md-code-hl-punctuation-color: #1F1F1F;--md-code-hl-string-color: 
#836E15;--md-code-hl-special-color: #644AC9;--md-code-hl-number-color: 
#644AC9;--md-code-hl-keyword-color: #A3134D;--md-code-hl-name-color: 
#1F1F1F;--md-code-hl-constant-color: #644AC9;--md-code-hl-function-color: 
#14720A;--md-code-hl-comment-color: #635D97;--md-code-hl-variable-color: 
#A34D14;--md-code-hl-generic-color: #635D97;--md-code-hl-color: 
#CFCFDE;--md-code-hl-color--light: #DCDEEF;--md-typeset-table-color: rgb(0% 0% 
0% / 15%);--md-code-hl-entity-color: #14720A;--md-code-hl-tag-color: 
#A3134D;--md-code-hl-namespace-color: #1F1F1F;--md-code-hl-builtin-color: 
#036A96;--md-code-hl-class-color: #036A96;--md-code-special-bg-color: 
#DCDEEF;--md-s
 teps-bg-color: var(--md-code-bg-color);--md-steps-fg-color: 
var(--md-code-fg-color);--md-steps-border-color: hsla(0, 0%, 75%, 
1);--md-typeset-a-color: #00bcd4;--md-progress-stripe: 
var(--md-default-bg-color--lighter);--md-progress-100: 
#00e676;--md-progress-80: #00e676;--md-progress-60: #fbc02d;--md-progress-40: 
#ff9100;--md-progress-20: #ff5252;--md-progress-0: 
#ff1744;--md-typeset-kbd-color: rgb(228.3721025416, 228.3721025416, 
228.3721025416);--md-typeset-kbd-border-color: rgb(164.4010497691, 
164.4010497691, 164.4010497691);--md-typeset-kbd-accent-color: hsla(0, 100%, 
100%, 1)}:root>*[data-md-color-scheme=slate]{--md-default-fg-color: hsla(60, 
30%, 96.078%, 0.87);--md-default-fg-color--light: hsla(60, 30%, 96.078%, 
0.54);--md-default-fg-color--lighter: hsla(60, 30%, 96.078%, 
0.36);--md-default-fg-color--lightest: hsla(60, 30%, 96.078%, 
0.12);--md-default-autocomplete-fg-color: hsla(60, 30%, 96.078%, 
0.4);--md-footer-fg-color: var(--md-default-fg-color);--md-default-bg-color: 
var(-
 -md-default-bg-color--darkest);--md-default-bg-color--light: color(srgb 
0.0327882794 0.0359366892 0.0551574304 / 0.7);--md-default-bg-color--lighter: 
color(srgb 0.0327882794 0.0359366892 0.0551574304 / 
0.4);--md-default-bg-color--lightest: color(srgb 0.0327882794 0.0359366892 
0.0551574304 / 0.1);--md-default-bg-color--trans: color(srgb 0.0327882794 
0.0359366892 0.0551574304 / 0);--md-tab-control-bg: 
var(--md-default-bg-color--dark);--md-default-bg-color--dark: color(srgb 
0.1147606354 0.1213715063 0.1588331081);--md-default-bg-color--darker: 
color(srgb 0.0781790415 0.0833653407 
0.1127543696);--md-default-bg-color--darkest: color(srgb 0.0327882794 
0.0359366892 0.0551574304);--md-text-color: 
var(--md-default-fg-color);--md-typeset-color: 
var(--md-default-fg-color);--md-admonition-fg-color: 
var(--md-default-fg-color);--md-code-fg-color: hsl(60, 30%, 
96.078%);--md-code-bg-color: hsl(231, 15%, 18%);--md-code-title-bg-color: 
hsl(231, 15%, 18%);--md-code-inline-bg-color: hsl(231, 15%, 18%);
 --md-code-hl-operator-color: hsl(326, 100%, 
74%);--md-code-hl-punctuation-color: hsl(60, 30%, 
96.078%);--md-code-hl-string-color: hsl(65, 92%, 
76%);--md-code-hl-special-color: hsl(265, 89%, 78%);--md-code-hl-number-color: 
hsl(265, 89%, 78%);--md-code-hl-keyword-color: hsl(326, 100%, 
74%);--md-code-hl-name-color: hsl(60, 30%, 
96.078%);--md-code-hl-constant-color: hsl(265, 89%, 
78%);--md-code-hl-function-color: hsl(135, 94%, 
65%);--md-code-hl-comment-color: hsl(225, 27%, 
51%);--md-code-hl-variable-color: hsl(31, 100%, 
71%);--md-code-hl-generic-color: hsl(225, 27%, 51%);--md-code-hl-color: 
hsl(231, 15%, 30%);--md-code-hl-color--light: hsl(231, 25%, 
25%);--md-code-bg-color--light: hsla(231, 15%, 18%, 
0.9);--md-code-bg-color--lighter: hsla(231, 15%, 18%, 
0.5);--md-typeset-table-color: rgb(100% 100% 100% / 
15%);--md-code-hl-entity-color: hsl(135, 94%, 65%);--md-code-hl-tag-color: 
hsl(326, 100%, 74%);--md-code-hl-namespace-color: hsl(60, 30%, 
96.078%);--md-code-hl-builtin-color: hsl(191, 9
 7%, 77%);--md-code-hl-class-color: hsl(191, 97%, 
77%);--md-code-special-bg-color: hsl(231, 25%, 25%);--md-steps-border-color: 
hsl(230.6613379686, 10.4241713343%, 28.1575403575%);--md-typeset-a-color: 
hsl(191, 97%, 77%);--md-typeset-mark-color: hsl(75.3111515854, 11.5600114451%, 
37.8888925515%);--md-typeset-del-color: hsl(314.8219481072, 22.0434125534%, 
35.1703201111%);--md-typeset-ins-color: hsl(145.2334928709, 27.8121663576%, 
33.1574755691%);--md-progress-stripe: 
var(--md-default-bg-color--lightest);--md-progress-100: hsl(135, 94%, 
65%);--md-progress-80: hsl(96.9286079031, 93.5050765575%, 
74.7933068737%);--md-progress-60: hsl(65, 92%, 76%);--md-progress-40: hsl(31, 
100%, 71%);--md-progress-20: hsl(326, 100%, 74%);--md-progress-0: hsl(0, 100%, 
67%);--md-typeset-kbd-color: 
var(--md-default-fg-color--lightest);--md-typeset-kbd-border-color: 
var(--md-default-bg-color--dark);--md-typeset-kbd-accent-color: 
var(--md-default-fg-color--lighter)}[data-md-color-scheme=slate][data-md-color-pri
 mary=red],[data-md-color-scheme=slate] 
:not([data-md-color-scheme])[data-md-color-primary=red]{--md-primary-code-bg-color:
 hsl(332.2545890109, 15.8127407999%, 23.5759703429%);--md-primary-fg-color: 
hsla(0deg, 100%, 67%, 1);--md-primary-fg-color--transparent: hsla(0deg, 100%, 
67%, 0.2);--md-primary-fg-color--light: hsla(0deg, 100%, 72%, 
1);--md-primary-fg-color--dark: hsla(0deg, 100%, 62%, 1);--md-primary-bg-color: 
var(--md-default-bg-color);--md-primary-bg-color--light: 
var(--md-default-bg-color--light)}[data-md-color-scheme=slate][data-md-color-primary=pink],[data-md-color-scheme=slate]
 
:not([data-md-color-scheme])[data-md-color-primary=pink]{--md-primary-code-bg-color:
 hsl(288.4757168622, 14.8889902037%, 24.6712834924%);--md-primary-fg-color: 
hsla(326deg, 100%, 74%, 1);--md-primary-fg-color--transparent: hsla(326deg, 
100%, 74%, 0.2);--md-primary-fg-color--light: hsla(326deg, 100%, 79%, 
1);--md-primary-fg-color--dark: hsla(326deg, 100%, 69%, 
1);--md-primary-bg-color: var(--md-defau
 lt-bg-color);--md-primary-bg-color--light: 
var(--md-default-bg-color--light)}[data-md-color-scheme=slate][data-md-color-primary=purple],[data-md-color-scheme=slate]
 
:not([data-md-color-scheme])[data-md-color-primary=purple]{--md-primary-code-bg-color:
 hsl(248.4980702, 16.8923581309%, 26.4141657947%);--md-primary-fg-color: 
hsla(265deg, 89%, 78%, 1);--md-primary-fg-color--transparent: hsla(265deg, 89%, 
78%, 0.2);--md-primary-fg-color--light: hsla(265deg, 89%, 83%, 
1);--md-primary-fg-color--dark: hsla(265deg, 89%, 73%, 
1);--md-primary-bg-color: 
var(--md-default-bg-color);--md-primary-bg-color--light: 
var(--md-default-bg-color--light)}[data-md-color-scheme=slate][data-md-color-primary=deep-purple],[data-md-color-scheme=slate]
 
:not([data-md-color-scheme])[data-md-color-primary=deep-purple]{--md-primary-code-bg-color:
 hsl(248.4980702, 16.8923581309%, 26.4141657947%);--md-primary-fg-color: 
hsla(265deg, 89%, 78%, 1);--md-primary-fg-color--transparent: hsla(265deg, 89%, 
78%, 0.2);--md-primar
 y-fg-color--light: hsla(265deg, 89%, 83%, 1);--md-primary-fg-color--dark: 
hsla(265deg, 89%, 73%, 1);--md-primary-bg-color: 
var(--md-default-bg-color);--md-primary-bg-color--light: 
var(--md-default-bg-color--light)}[data-md-color-scheme=slate][data-md-color-primary=blue],[data-md-color-scheme=slate]
 
:not([data-md-color-scheme])[data-md-color-primary=blue]{--md-primary-code-bg-color:
 hsl(227.2638621359, 21.6677726002%, 25.6465952614%);--md-primary-fg-color: 
hsla(225deg, 100%, 75%, 1);--md-primary-fg-color--transparent: hsla(225deg, 
100%, 75%, 0.2);--md-primary-fg-color--light: hsla(225deg, 100%, 80%, 
1);--md-primary-fg-color--dark: hsla(225deg, 100%, 70%, 
1);--md-primary-bg-color: 
var(--md-default-bg-color);--md-primary-bg-color--light: 
var(--md-default-bg-color--light)}[data-md-color-scheme=slate][data-md-color-primary=indigo],[data-md-color-scheme=slate]
 
:not([data-md-color-scheme])[data-md-color-primary=indigo]{--md-primary-code-bg-color:
 hsl(227.2638621359, 21.6677726002%, 25.6465
 952614%);--md-primary-fg-color: hsla(225deg, 100%, 75%, 
1);--md-primary-fg-color--transparent: hsla(225deg, 100%, 75%, 
0.2);--md-primary-fg-color--light: hsla(225deg, 100%, 80%, 
1);--md-primary-fg-color--dark: hsla(225deg, 100%, 70%, 
1);--md-primary-bg-color: 
var(--md-default-bg-color);--md-primary-bg-color--light: 
var(--md-default-bg-color--light)}[data-md-color-scheme=slate][data-md-color-primary=light-blue],[data-md-color-scheme=slate]
 
:not([data-md-color-scheme])[data-md-color-primary=light-blue]{--md-primary-code-bg-color:
 hsl(227.2638621359, 21.6677726002%, 25.6465952614%);--md-primary-fg-color: 
hsla(225deg, 100%, 75%, 1);--md-primary-fg-color--transparent: hsla(225deg, 
100%, 75%, 0.2);--md-primary-fg-color--light: hsla(225deg, 100%, 80%, 
1);--md-primary-fg-color--dark: hsla(225deg, 100%, 70%, 
1);--md-primary-bg-color: 
var(--md-default-bg-color);--md-primary-bg-color--light: 
var(--md-default-bg-color--light)}[data-md-color-scheme=slate][data-md-color-primary=cyan],[data-md-col
 or-scheme=slate] 
:not([data-md-color-scheme])[data-md-color-primary=cyan]{--md-primary-code-bg-color:
 hsl(210.993928831, 19.0177068244%, 26.0788938803%);--md-primary-fg-color: 
hsla(191deg, 97%, 77%, 1);--md-primary-fg-color--transparent: hsla(191deg, 97%, 
77%, 0.2);--md-primary-fg-color--light: hsla(191deg, 97%, 82%, 
1);--md-primary-fg-color--dark: hsla(191deg, 97%, 72%, 
1);--md-primary-bg-color: 
var(--md-default-bg-color);--md-primary-bg-color--light: 
var(--md-default-bg-color--light)}[data-md-color-scheme=slate][data-md-color-primary=teal],[data-md-color-scheme=slate]
 
:not([data-md-color-scheme])[data-md-color-primary=teal]{--md-primary-code-bg-color:
 hsl(210.993928831, 19.0177068244%, 26.0788938803%);--md-primary-fg-color: 
hsla(191deg, 97%, 77%, 1);--md-primary-fg-color--transparent: hsla(191deg, 97%, 
77%, 0.2);--md-primary-fg-color--light: hsla(191deg, 97%, 82%, 
1);--md-primary-fg-color--dark: hsla(191deg, 97%, 72%, 
1);--md-primary-bg-color: var(--md-default-bg-color);--md-prima
 ry-bg-color--light: 
var(--md-default-bg-color--light)}[data-md-color-scheme=slate][data-md-color-primary=green],[data-md-color-scheme=slate]
 
:not([data-md-color-scheme])[data-md-color-primary=green]{--md-primary-code-bg-color:
 hsl(168.8720935496, 16.518720864%, 23.1930022147%);--md-primary-fg-color: 
hsla(135deg, 94%, 65%, 1);--md-primary-fg-color--transparent: hsla(135deg, 94%, 
65%, 0.2);--md-primary-fg-color--light: hsla(135deg, 94%, 70%, 
1);--md-primary-fg-color--dark: hsla(135deg, 94%, 60%, 
1);--md-primary-bg-color: 
var(--md-default-bg-color);--md-primary-bg-color--light: 
var(--md-default-bg-color--light)}[data-md-color-scheme=slate][data-md-color-primary=light-green],[data-md-color-scheme=slate]
 
:not([data-md-color-scheme])[data-md-color-primary=light-green]{--md-primary-code-bg-color:
 hsl(168.8720935496, 16.518720864%, 23.1930022147%);--md-primary-fg-color: 
hsla(135deg, 94%, 65%, 1);--md-primary-fg-color--transparent: hsla(135deg, 94%, 
65%, 0.2);--md-primary-fg-color--light: hs
 la(135deg, 94%, 70%, 1);--md-primary-fg-color--dark: hsla(135deg, 94%, 60%, 
1);--md-primary-bg-color: 
var(--md-default-bg-color);--md-primary-bg-color--light: 
var(--md-default-bg-color--light)}[data-md-color-scheme=slate][data-md-color-primary=lime],[data-md-color-scheme=slate]
 
:not([data-md-color-scheme])[data-md-color-primary=lime]{--md-primary-code-bg-color:
 hsl(168.8720935496, 16.518720864%, 23.1930022147%);--md-primary-fg-color: 
hsla(135deg, 94%, 65%, 1);--md-primary-fg-color--transparent: hsla(135deg, 94%, 
65%, 0.2);--md-primary-fg-color--light: hsla(135deg, 94%, 70%, 
1);--md-primary-fg-color--dark: hsla(135deg, 94%, 60%, 
1);--md-primary-bg-color: 
var(--md-default-bg-color);--md-primary-bg-color--light: 
var(--md-default-bg-color--light)}[data-md-color-scheme=slate][data-md-color-primary=yellow],[data-md-color-scheme=slate]
 
:not([data-md-color-scheme])[data-md-color-primary=yellow]{--md-primary-code-bg-color:
 hsl(159.3047128419, 2.986865819%, 26.1419609775%);--md-primary-fg-col
 or: hsla(65deg, 92%, 76%, 1);--md-primary-fg-color--transparent: hsla(65deg, 
92%, 76%, 0.2);--md-primary-fg-color--light: hsla(65deg, 92%, 81%, 
1);--md-primary-fg-color--dark: hsla(65deg, 92%, 71%, 1);--md-primary-bg-color: 
var(--md-default-bg-color);--md-primary-bg-color--light: 
var(--md-default-bg-color--light)}[data-md-color-scheme=slate][data-md-color-primary=amber],[data-md-color-scheme=slate]
 
:not([data-md-color-scheme])[data-md-color-primary=amber]{--md-primary-code-bg-color:
 hsl(159.3047128419, 2.986865819%, 26.1419609775%);--md-primary-fg-color: 
hsla(65deg, 92%, 76%, 1);--md-primary-fg-color--transparent: hsla(65deg, 92%, 
76%, 0.2);--md-primary-fg-color--light: hsla(65deg, 92%, 81%, 
1);--md-primary-fg-color--dark: hsla(65deg, 92%, 71%, 1);--md-primary-bg-color: 
var(--md-default-bg-color);--md-primary-bg-color--light: 
var(--md-default-bg-color--light)}[data-md-color-scheme=slate][data-md-color-primary=orange],[data-md-color-scheme=slate]
 :not([data-md-color-scheme])[data-md-
 color-primary=orange]{--md-primary-code-bg-color: hsl(338.2103998913, 
5.0960419739%, 25.1078079888%);--md-primary-fg-color: hsla(31deg, 100%, 71%, 
1);--md-primary-fg-color--transparent: hsla(31deg, 100%, 71%, 
0.2);--md-primary-fg-color--light: hsla(31deg, 100%, 76%, 
1);--md-primary-fg-color--dark: hsla(31deg, 100%, 66%, 
1);--md-primary-bg-color: 
var(--md-default-bg-color);--md-primary-bg-color--light: 
var(--md-default-bg-color--light)}[data-md-color-scheme=slate][data-md-color-primary=deep-orange],[data-md-color-scheme=slate]
 
:not([data-md-color-scheme])[data-md-color-primary=deep-orange]{--md-primary-code-bg-color:
 hsl(338.2103998913, 5.0960419739%, 25.1078079888%);--md-primary-fg-color: 
hsla(31deg, 100%, 71%, 1);--md-primary-fg-color--transparent: hsla(31deg, 100%, 
71%, 0.2);--md-primary-fg-color--light: hsla(31deg, 100%, 76%, 
1);--md-primary-fg-color--dark: hsla(31deg, 100%, 66%, 
1);--md-primary-bg-color: 
var(--md-default-bg-color);--md-primary-bg-color--light: var(--md-default-b
 
g-color--light)}[data-md-color-scheme=slate][data-md-color-accent=red],[data-md-color-scheme=slate]
 
:not([data-md-color-scheme])[data-md-color-primary=red]{--md-code-link-accent-bg-color:
 hsl(332.2545890109, 15.8127407999%, 23.5759703429%);--md-accent-fg-color: 
hsla(0deg, 100%, 67%, 1);--md-accent-fg-color--transparent: hsla(0deg, 100%, 
67%, 0.2);--md-accent-bg-color: 
var(--md-default-bg-color);--md-accent-bg-color--light: 
var(--md-default-bg-color--light)}[data-md-color-scheme=slate][data-md-color-accent=pink],[data-md-color-scheme=slate]
 
:not([data-md-color-scheme])[data-md-color-primary=pink]{--md-code-link-accent-bg-color:
 hsl(288.4757168622, 14.8889902037%, 24.6712834924%);--md-accent-fg-color: 
hsla(326deg, 100%, 74%, 1);--md-accent-fg-color--transparent: hsla(326deg, 
100%, 74%, 0.2);--md-accent-bg-color: 
var(--md-default-bg-color);--md-accent-bg-color--light: 
var(--md-default-bg-color--light)}[data-md-color-scheme=slate][data-md-color-accent=purple],[data-md-color-scheme=slate
 ] 
:not([data-md-color-scheme])[data-md-color-primary=purple]{--md-code-link-accent-bg-color:
 hsl(248.4980702, 16.8923581309%, 26.4141657947%);--md-accent-fg-color: 
hsla(265deg, 89%, 78%, 1);--md-accent-fg-color--transparent: hsla(265deg, 89%, 
78%, 0.2);--md-accent-bg-color: 
var(--md-default-bg-color);--md-accent-bg-color--light: 
var(--md-default-bg-color--light)}[data-md-color-scheme=slate][data-md-color-accent=deep-purple],[data-md-color-scheme=slate]
 
:not([data-md-color-scheme])[data-md-color-primary=deep-purple]{--md-code-link-accent-bg-color:
 hsl(248.4980702, 16.8923581309%, 26.4141657947%);--md-accent-fg-color: 
hsla(265deg, 89%, 78%, 1);--md-accent-fg-color--transparent: hsla(265deg, 89%, 
78%, 0.2);--md-accent-bg-color: 
var(--md-default-bg-color);--md-accent-bg-color--light: 
var(--md-default-bg-color--light)}[data-md-color-scheme=slate][data-md-color-accent=blue],[data-md-color-scheme=slate]
 
:not([data-md-color-scheme])[data-md-color-primary=blue]{--md-code-link-accent-bg-color
 : hsl(227.2638621359, 21.6677726002%, 25.6465952614%);--md-accent-fg-color: 
hsla(225deg, 100%, 75%, 1);--md-accent-fg-color--transparent: hsla(225deg, 
100%, 75%, 0.2);--md-accent-bg-color: 
var(--md-default-bg-color);--md-accent-bg-color--light: 
var(--md-default-bg-color--light)}[data-md-color-scheme=slate][data-md-color-accent=indigo],[data-md-color-scheme=slate]
 
:not([data-md-color-scheme])[data-md-color-primary=indigo]{--md-code-link-accent-bg-color:
 hsl(227.2638621359, 21.6677726002%, 25.6465952614%);--md-accent-fg-color: 
hsla(225deg, 100%, 75%, 1);--md-accent-fg-color--transparent: hsla(225deg, 
100%, 75%, 0.2);--md-accent-bg-color: 
var(--md-default-bg-color);--md-accent-bg-color--light: 
var(--md-default-bg-color--light)}[data-md-color-scheme=slate][data-md-color-accent=light-blue],[data-md-color-scheme=slate]
 
:not([data-md-color-scheme])[data-md-color-primary=light-blue]{--md-code-link-accent-bg-color:
 hsl(227.2638621359, 21.6677726002%, 25.6465952614%);--md-accent-fg-color: hsl
 a(225deg, 100%, 75%, 1);--md-accent-fg-color--transparent: hsla(225deg, 100%, 
75%, 0.2);--md-accent-bg-color: 
var(--md-default-bg-color);--md-accent-bg-color--light: 
var(--md-default-bg-color--light)}[data-md-color-scheme=slate][data-md-color-accent=cyan],[data-md-color-scheme=slate]
 
:not([data-md-color-scheme])[data-md-color-primary=cyan]{--md-code-link-accent-bg-color:
 hsl(210.993928831, 19.0177068244%, 26.0788938803%);--md-accent-fg-color: 
hsla(191deg, 97%, 77%, 1);--md-accent-fg-color--transparent: hsla(191deg, 97%, 
77%, 0.2);--md-accent-bg-color: 
var(--md-default-bg-color);--md-accent-bg-color--light: 
var(--md-default-bg-color--light)}[data-md-color-scheme=slate][data-md-color-accent=teal],[data-md-color-scheme=slate]
 
:not([data-md-color-scheme])[data-md-color-primary=teal]{--md-code-link-accent-bg-color:
 hsl(210.993928831, 19.0177068244%, 26.0788938803%);--md-accent-fg-color: 
hsla(191deg, 97%, 77%, 1);--md-accent-fg-color--transparent: hsla(191deg, 97%, 
77%, 0.2);--md-accent-b
 g-color: var(--md-default-bg-color);--md-accent-bg-color--light: 
var(--md-default-bg-color--light)}[data-md-color-scheme=slate][data-md-color-accent=green],[data-md-color-scheme=slate]
 
:not([data-md-color-scheme])[data-md-color-primary=green]{--md-code-link-accent-bg-color:
 hsl(168.8720935496, 16.518720864%, 23.1930022147%);--md-accent-fg-color: 
hsla(135deg, 94%, 65%, 1);--md-accent-fg-color--transparent: hsla(135deg, 94%, 
65%, 0.2);--md-accent-bg-color: 
var(--md-default-bg-color);--md-accent-bg-color--light: 
var(--md-default-bg-color--light)}[data-md-color-scheme=slate][data-md-color-accent=light-green],[data-md-color-scheme=slate]
 
:not([data-md-color-scheme])[data-md-color-primary=light-green]{--md-code-link-accent-bg-color:
 hsl(168.8720935496, 16.518720864%, 23.1930022147%);--md-accent-fg-color: 
hsla(135deg, 94%, 65%, 1);--md-accent-fg-color--transparent: hsla(135deg, 94%, 
65%, 0.2);--md-accent-bg-color: 
var(--md-default-bg-color);--md-accent-bg-color--light: var(--md-default-bg-
 
color--light)}[data-md-color-scheme=slate][data-md-color-accent=lime],[data-md-color-scheme=slate]
 
:not([data-md-color-scheme])[data-md-color-primary=lime]{--md-code-link-accent-bg-color:
 hsl(168.8720935496, 16.518720864%, 23.1930022147%);--md-accent-fg-color: 
hsla(135deg, 94%, 65%, 1);--md-accent-fg-color--transparent: hsla(135deg, 94%, 
65%, 0.2);--md-accent-bg-color: 
var(--md-default-bg-color);--md-accent-bg-color--light: 
var(--md-default-bg-color--light)}[data-md-color-scheme=slate][data-md-color-accent=yellow],[data-md-color-scheme=slate]
 
:not([data-md-color-scheme])[data-md-color-primary=yellow]{--md-code-link-accent-bg-color:
 hsl(159.3047128419, 2.986865819%, 26.1419609775%);--md-accent-fg-color: 
hsla(65deg, 92%, 76%, 1);--md-accent-fg-color--transparent: hsla(65deg, 92%, 
76%, 0.2);--md-accent-bg-color: 
var(--md-default-bg-color);--md-accent-bg-color--light: 
var(--md-default-bg-color--light)}[data-md-color-scheme=slate][data-md-color-accent=amber],[data-md-color-scheme=slate]
 
 
:not([data-md-color-scheme])[data-md-color-primary=amber]{--md-code-link-accent-bg-color:
 hsl(159.3047128419, 2.986865819%, 26.1419609775%);--md-accent-fg-color: 
hsla(65deg, 92%, 76%, 1);--md-accent-fg-color--transparent: hsla(65deg, 92%, 
76%, 0.2);--md-accent-bg-color: 
var(--md-default-bg-color);--md-accent-bg-color--light: 
var(--md-default-bg-color--light)}[data-md-color-scheme=slate][data-md-color-accent=orange],[data-md-color-scheme=slate]
 
:not([data-md-color-scheme])[data-md-color-primary=orange]{--md-code-link-accent-bg-color:
 hsl(338.2103998913, 5.0960419739%, 25.1078079888%);--md-accent-fg-color: 
hsla(31deg, 100%, 71%, 1);--md-accent-fg-color--transparent: hsla(31deg, 100%, 
71%, 0.2);--md-accent-bg-color: 
var(--md-default-bg-color);--md-accent-bg-color--light: 
var(--md-default-bg-color--light)}[data-md-color-scheme=slate][data-md-color-accent=deep-orange],[data-md-color-scheme=slate]
 
:not([data-md-color-scheme])[data-md-color-primary=deep-orange]{--md-code-link-accent-bg-col
 or: hsl(338.2103998913, 5.0960419739%, 25.1078079888%);--md-accent-fg-color: 
hsla(31deg, 100%, 71%, 1);--md-accent-fg-color--transparent: hsla(31deg, 100%, 
71%, 0.2);--md-accent-bg-color: 
var(--md-default-bg-color);--md-accent-bg-color--light: 
var(--md-default-bg-color--light)}:root{--md-heart: #ff5252;--md-heart-big: 
#ff1744}:root [data-md-color-scheme=slate]{--md-heart: hsl(0, 100%, 
67%);--md-heart-big: hsl(326, 100%, 74%)}.md-typeset 
a.source-link{position:relative;top:-0.6rem;float:right;color:var(--md-default-fg-color--lighter);transition:color
 125ms}.md-typeset 
a.source-link:hover{color:var(--md-accent-fg-color)}.md-typeset a.source-link 
.twemoji{height:1.2rem}.md-typeset a.source-link .twemoji 
svg{width:1.2rem;height:1.2rem}.md-typeset div.highlight.md-max-height 
pre>code{max-height:15rem}.twemoji.heart-throb svg,.twemoji.heart-throb-hover 
svg{position:relative;color:var(--md-heart);animation:pulse 1.5s ease 
infinite}@keyframes pulse{0%{transform:scale(1)}40%{color:var(--md-h
 
eart-big);transform:scale(1.3)}50%{transform:scale(1.2)}60%{color:var(--md-heart-big);transform:scale(1.3)}100%{transform:scale(1)}}footer.sponsorship{text-align:center}footer.sponsorship
 .twemoji{padding:.05rem}footer.sponsorship 
a{text-decoration:none}footer.sponsorship 
hr{display:inline-block;width:1.6rem;margin:0 
.7rem;vertical-align:middle;border-bottom:2px solid 
var(--md-default-fg-color--lighter)}footer.sponsorship:hover 
hr{border-color:var(--md-accent-fg-color)}footer.sponsorship:not(:hover) 
.twemoji.heart-throb-hover svg{color:var(--md-default-fg-color--lighter) 
!important}:root>*{--md-admonition-icon-color: 
#3654c2;--md-admonition-bg-color: rgba(54, 84, 194, 
0.1)}:root>*[data-md-color-scheme=slate]{--md-admonition-icon-color: hsl(225, 
100%, 75%);--md-admonition-bg-color: hsla(225, 100%, 75%, 
0.1)}:root>*{--md-admonition-icon--settings: 
url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg"; 
viewBox="0 0 24 24"><path d="M12 15.5A3.5 3.5 0 0 1 8.5 12 3.
 5 3.5 0 0 1 12 8.5a3.5 3.5 0 0 1 3.5 3.5 3.5 3.5 0 0 1-3.5 
3.5m7.43-2.53c.04-.32.07-.64.07-.97s-.03-.66-.07-1l2.11-1.63c.19-.15.24-.42.12-.64l-2-3.46c-.12-.22-.39-.31-.61-.22l-2.49
 1c-.52-.39-1.06-.73-1.69-.98l-.37-2.65A.506.506 0 0 0 14 2h-4c-.25 
0-.46.18-.5.42l-.37 2.65c-.63.25-1.17.59-1.69.98l-2.49-1c-.22-.09-.49 
0-.61.22l-2 3.46c-.13.22-.07.49.12.64L4.57 11c-.04.34-.07.67-.07 
1s.03.65.07.97l-2.11 1.66c-.19.15-.25.42-.12.64l2 
3.46c.12.22.39.3.61.22l2.49-1.01c.52.4 1.06.74 1.69.99l.37 
2.65c.04.24.25.42.5.42h4c.25 0 .46-.18.5-.42l.37-2.65c.63-.26 1.17-.59 
1.69-.99l2.49 1.01c.22.08.49 0 
.61-.22l2-3.46c.12-.22.07-.49-.12-.64z"/></svg>');--md-admonition-bg-color--settings:
 rgba(170, 0, 255, 0.1);--md-admonition-icon-color--settings: 
#aa00ff}:root>*[data-md-color-scheme=slate]{--md-admonition-bg-color--settings: 
hsla(326, 100%, 74%, 0.1);--md-admonition-icon-color--settings: hsl(326, 100%, 
74%)}:root>*{--md-admonition-icon--new: 
url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://
 www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="m23 
12-2.44-2.78.34-3.68-3.61-.82-1.89-3.18L12 3 8.6 1.54 6.71 4.72l-3.61.81.34 
3.68L1 12l2.44 2.78-.34 3.69 3.61.82 1.89 3.18L12 21l3.4 1.46 1.89-3.18 
3.61-.82-.34-3.68zm-10 
5h-2v-2h2zm0-4h-2V7h2z"/></svg>');--md-admonition-bg-color--new: rgba(255, 214, 
0, 0.1);--md-admonition-icon-color--new: 
#ffd600}:root>*[data-md-color-scheme=slate]{--md-admonition-bg-color--new: 
hsla(65, 92%, 76%, 0.1);--md-admonition-icon-color--new: hsl(65, 92%, 
76%)}:root>*{--md-admonition-icon--important: 
url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg"; 
viewBox="0 0 24 24"><path d="M9 22a1 1 0 0 1-1-1v-3H4a2 2 0 0 1-2-2V4a2 2 0 0 1 
2-2h16a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2h-6.1l-3.7 
3.71c-.2.19-.45.29-.7.29zm1-6v3.08L13.08 16H20V4H4v12zm3-6h-2V6h2zm0 
4h-2v-2h2z"/></svg>');--md-admonition-bg-color--important: rgba(124, 77, 255, 
0.1);--md-admonition-icon-color--important: 
#7c4dff}:root>*[data-md-color-scheme=slate]{--md-admonition-bg-
 color--important: hsla(300.507916868, 58.3554777078%, 71.0104358913%, 
0.1);--md-admonition-icon-color--important: hsl(300.507916868, 58.3554777078%, 
71.0104358913%)}:root>*{--md-admonition-bg-color--note: rgba(68, 138, 255, 
0.1);--md-admonition-icon-color--note: 
#448aff}:root>*[data-md-color-scheme=slate]{--md-admonition-bg-color--note: 
hsla(225, 100%, 75%, 0.1);--md-admonition-icon-color--note: hsl(225, 100%, 
75%)}:root>*{--md-admonition-bg-color--abstract: rgba(0, 176, 255, 
0.1);--md-admonition-icon-color--abstract: 
#00b0ff}:root>*[data-md-color-scheme=slate]{--md-admonition-bg-color--abstract: 
hsla(208.9651589316, 100.1516938638%, 76.1926610237%, 
0.1);--md-admonition-icon-color--abstract: hsl(208.9651589316, 100.1516938638%, 
76.1926610237%)}:root>*{--md-admonition-bg-color--info: rgba(0, 184, 212, 
0.1);--md-admonition-icon-color--info: 
#00b8d4}:root>*[data-md-color-scheme=slate]{--md-admonition-bg-color--info: 
hsla(191, 97%, 77%, 0.1);--md-admonition-icon-color--info: hsl(191, 97
 %, 77%)}:root>*{--md-admonition-bg-color--tip: rgba(0, 191, 165, 
0.1);--md-admonition-icon-color--tip: 
#00bfa5}:root>*[data-md-color-scheme=slate]{--md-admonition-bg-color--tip: 
hsla(157.7363570417, 83.7763520157%, 69.6636999884%, 
0.1);--md-admonition-icon-color--tip: hsl(157.7363570417, 83.7763520157%, 
69.6636999884%)}:root>*{--md-admonition-bg-color--success: rgba(0, 200, 83, 
0.1);--md-admonition-icon-color--success: 
#00c853}:root>*[data-md-color-scheme=slate]{--md-admonition-bg-color--success: 
hsla(135, 94%, 65%, 0.1);--md-admonition-icon-color--success: hsl(135, 94%, 
65%)}:root>*{--md-admonition-bg-color--question: rgba(100, 221, 23, 
0.1);--md-admonition-icon-color--question: 
#64dd17}:root>*[data-md-color-scheme=slate]{--md-admonition-bg-color--question: 
hsla(96.9286079031, 93.5050765575%, 74.7933068737%, 
0.1);--md-admonition-icon-color--question: hsl(96.9286079031, 93.5050765575%, 
74.7933068737%)}:root>*{--md-admonition-bg-color--warning: rgba(255, 145, 0, 
0.1);--md-admonition-
 icon-color--warning: 
#ff9100}:root>*[data-md-color-scheme=slate]{--md-admonition-bg-color--warning: 
hsla(31, 100%, 71%, 0.1);--md-admonition-icon-color--warning: hsl(31, 100%, 
71%)}:root>*{--md-admonition-bg-color--failure: rgba(255, 82, 82, 
0.1);--md-admonition-icon-color--failure: 
#ff5252}:root>*[data-md-color-scheme=slate]{--md-admonition-bg-color--failure: 
hsla(15.759766848, 102.8951066345%, 69.4486457644%, 
0.1);--md-admonition-icon-color--failure: hsl(15.759766848, 102.8951066345%, 
69.4486457644%)}:root>*{--md-admonition-bg-color--danger: rgba(255, 23, 68, 
0.1);--md-admonition-icon-color--danger: 
#ff1744}:root>*[data-md-color-scheme=slate]{--md-admonition-bg-color--danger: 
hsla(0, 100%, 67%, 0.1);--md-admonition-icon-color--danger: hsl(0, 100%, 
67%)}:root>*{--md-admonition-bg-color--bug: rgba(245, 0, 87, 
0.1);--md-admonition-icon-color--bug: 
#f50057}:root>*[data-md-color-scheme=slate]{--md-admonition-bg-color--bug: 
hsla(344.5737278948, 100.1359681762%, 71.0000228672%, 0.1);--md
 -admonition-icon-color--bug: hsl(344.5737278948, 100.1359681762%, 
71.0000228672%)}:root>*{--md-admonition-bg-color--example: rgba(98, 0, 234, 
0.1);--md-admonition-icon-color--example: 
#6200ea}:root>*[data-md-color-scheme=slate]{--md-admonition-bg-color--example: 
hsla(265, 89%, 78%, 0.1);--md-admonition-icon-color--example: hsl(265, 89%, 
78%)}:root>*{--md-admonition-bg-color--quote: rgba(158, 158, 158, 
0.1);--md-admonition-icon-color--quote: 
#9e9e9e}:root>*[data-md-color-scheme=slate]{--md-admonition-bg-color--quote: 
hsla(225, 8%, 51%, 0.1);--md-admonition-icon-color--quote: hsl(225, 8%, 
51%)}.md-typeset .admonition,.md-typeset 
details{font-size:inherit;background:var(--md-admonition-bg-color--note);border-width:0;border-left-width:4px}.md-typeset
 .admonition>.admonition-title::before,.md-typeset 
details>.admonition-title::before,.md-typeset 
details>summary::before{background-color:var(--md-admonition-icon-color--note)}.md-typeset
 .admonition>.admonition-title::after,.md-typeset deta
 ils>.admonition-title::after,.md-typeset 
details>summary::after{color:var(--md-admonition-icon-color--note)}.md-typeset 
.admonition.note,.md-typeset 
details.note{background:var(--md-admonition-bg-color--note)}.md-typeset 
.admonition.note>.admonition-title::before,.md-typeset 
details.note>.admonition-title::before,.md-typeset 
details.note>summary::before{background-color:var(--md-admonition-icon-color--note)}.md-typeset
 .admonition.note>.admonition-title::after,.md-typeset 
details.note>.admonition-title::after,.md-typeset 
details.note>summary::after{color:var(--md-admonition-icon-color--note)}.md-typeset
 .admonition.abstract,.md-typeset 
details.abstract{background:var(--md-admonition-bg-color--abstract)}.md-typeset 
.admonition.abstract>.admonition-title::before,.md-typeset 
details.abstract>.admonition-title::before,.md-typeset 
details.abstract>summary::before{background-color:var(--md-admonition-icon-color--abstract)}.md-typeset
 .admonition.abstract>.admonition-title::after,.md-types
 et details.abstract>.admonition-title::after,.md-typeset 
details.abstract>summary::after{color:var(--md-admonition-icon-color--abstract)}.md-typeset
 .admonition.info,.md-typeset 
details.info{background:var(--md-admonition-bg-color--info)}.md-typeset 
.admonition.info>.admonition-title::before,.md-typeset 
details.info>.admonition-title::before,.md-typeset 
details.info>summary::before{background-color:var(--md-admonition-icon-color--info)}.md-typeset
 .admonition.info>.admonition-title::after,.md-typeset 
details.info>.admonition-title::after,.md-typeset 
details.info>summary::after{color:var(--md-admonition-icon-color--info)}.md-typeset
 .admonition.tip,.md-typeset 
details.tip{background:var(--md-admonition-bg-color--tip)}.md-typeset 
.admonition.tip>.admonition-title::before,.md-typeset 
details.tip>.admonition-title::before,.md-typeset 
details.tip>summary::before{background-color:var(--md-admonition-icon-color--tip)}.md-typeset
 .admonition.tip>.admonition-title::after,.md-typeset details.
 tip>.admonition-title::after,.md-typeset 
details.tip>summary::after{color:var(--md-admonition-icon-color--tip)}.md-typeset
 .admonition.success,.md-typeset 
details.success{background:var(--md-admonition-bg-color--success)}.md-typeset 
.admonition.success>.admonition-title::before,.md-typeset 
details.success>.admonition-title::before,.md-typeset 
details.success>summary::before{background-color:var(--md-admonition-icon-color--success)}.md-typeset
 .admonition.success>.admonition-title::after,.md-typeset 
details.success>.admonition-title::after,.md-typeset 
details.success>summary::after{color:var(--md-admonition-icon-color--success)}.md-typeset
 .admonition.question,.md-typeset 
details.question{background:var(--md-admonition-bg-color--question)}.md-typeset 
.admonition.question>.admonition-title::before,.md-typeset 
details.question>.admonition-title::before,.md-typeset 
details.question>summary::before{background-color:var(--md-admonition-icon-color--question)}.md-typeset
 .admonition.questio
 n>.admonition-title::after,.md-typeset 
details.question>.admonition-title::after,.md-typeset 
details.question>summary::after{color:var(--md-admonition-icon-color--question)}.md-typeset
 .admonition.warning,.md-typeset 
details.warning{background:var(--md-admonition-bg-color--warning)}.md-typeset 
.admonition.warning>.admonition-title::before,.md-typeset 
details.warning>.admonition-title::before,.md-typeset 
details.warning>summary::before{background-color:var(--md-admonition-icon-color--warning)}.md-typeset
 .admonition.warning>.admonition-title::after,.md-typeset 
details.warning>.admonition-title::after,.md-typeset 
details.warning>summary::after{color:var(--md-admonition-icon-color--warning)}.md-typeset
 .admonition.failure,.md-typeset 
details.failure{background:var(--md-admonition-bg-color--failure)}.md-typeset 
.admonition.failure>.admonition-title::before,.md-typeset 
details.failure>.admonition-title::before,.md-typeset 
details.failure>summary::before{background-color:var(--md-admoniti
 on-icon-color--failure)}.md-typeset 
.admonition.failure>.admonition-title::after,.md-typeset 
details.failure>.admonition-title::after,.md-typeset 
details.failure>summary::after{color:var(--md-admonition-icon-color--failure)}.md-typeset
 .admonition.danger,.md-typeset 
details.danger{background:var(--md-admonition-bg-color--danger)}.md-typeset 
.admonition.danger>.admonition-title::before,.md-typeset 
details.danger>.admonition-title::before,.md-typeset 
details.danger>summary::before{background-color:var(--md-admonition-icon-color--danger)}.md-typeset
 .admonition.danger>.admonition-title::after,.md-typeset 
details.danger>.admonition-title::after,.md-typeset 
details.danger>summary::after{color:var(--md-admonition-icon-color--danger)}.md-typeset
 .admonition.bug,.md-typeset 
details.bug{background:var(--md-admonition-bg-color--bug)}.md-typeset 
.admonition.bug>.admonition-title::before,.md-typeset 
details.bug>.admonition-title::before,.md-typeset 
details.bug>summary::before{background-color:v
 ar(--md-admonition-icon-color--bug)}.md-typeset 
.admonition.bug>.admonition-title::after,.md-typeset 
details.bug>.admonition-title::after,.md-typeset 
details.bug>summary::after{color:var(--md-admonition-icon-color--bug)}.md-typeset
 .admonition.example,.md-typeset 
details.example{background:var(--md-admonition-bg-color--example)}.md-typeset 
.admonition.example>.admonition-title::before,.md-typeset 
details.example>.admonition-title::before,.md-typeset 
details.example>summary::before{background-color:var(--md-admonition-icon-color--example)}.md-typeset
 .admonition.example>.admonition-title::after,.md-typeset 
details.example>.admonition-title::after,.md-typeset 
details.example>summary::after{color:var(--md-admonition-icon-color--example)}.md-typeset
 .admonition.quote,.md-typeset 
details.quote{background:var(--md-admonition-bg-color--quote)}.md-typeset 
.admonition.quote>.admonition-title::before,.md-typeset 
details.quote>.admonition-title::before,.md-typeset 
details.quote>summary::before
 {background-color:var(--md-admonition-icon-color--quote)}.md-typeset 
.admonition.quote>.admonition-title::after,.md-typeset 
details.quote>.admonition-title::after,.md-typeset 
details.quote>summary::after{color:var(--md-admonition-icon-color--quote)}.md-typeset
 .admonition.settings,.md-typeset 
details.settings{background:var(--md-admonition-bg-color--settings)}.md-typeset 
.admonition.settings>.admonition-title::before,.md-typeset 
details.settings>.admonition-title::before,.md-typeset 
details.settings>summary::before{width:1rem;height:1rem;background-color:var(--md-admonition-icon-color--settings);background-size:1rem;-webkit-mask-image:var(--md-admonition-icon--settings);mask-image:var(--md-admonition-icon--settings);content:"
 "}.md-typeset .admonition.settings>.admonition-title::after,.md-typeset 
details.settings>.admonition-title::after,.md-typeset 
details.settings>summary::after{color:var(--md-admonition-icon-color--settings)}.md-typeset
 .admonition.new,.md-typeset details.new{ba
 ckground:var(--md-admonition-bg-color--new)}.md-typeset 
.admonition.new>.admonition-title::before,.md-typeset 
details.new>.admonition-title::before,.md-typeset 
details.new>summary::before{width:1rem;height:1rem;background-color:var(--md-admonition-icon-color--new);background-size:1rem;-webkit-mask-image:var(--md-admonition-icon--new);mask-image:var(--md-admonition-icon--new);content:"
 "}.md-typeset .admonition.new>.admonition-title::after,.md-typeset 
details.new>.admonition-title::after,.md-typeset 
details.new>summary::after{color:var(--md-admonition-icon-color--new)}.md-typeset
 .admonition.important,.md-typeset 
details.important{background:var(--md-admonition-bg-color--important)}.md-typeset
 .admonition.important>.admonition-title::before,.md-typeset 
details.important>.admonition-title::before,.md-typeset 
details.important>summary::before{width:1rem;height:1rem;background-color:var(--md-admonition-icon-color--important);background-size:1rem;-webkit-mask-image:var(--md-admonition-i
 con--important);mask-image:var(--md-admonition-icon--important);content:" 
"}.md-typeset .admonition.important>.admonition-title::after,.md-typeset 
details.important>.admonition-title::after,.md-typeset 
details.important>summary::after{color:var(--md-admonition-icon-color--important)}mjx-container[display=true]{font-size:120%
 !important}mjx-container:not([display]){font-size:100% !important}.md-typeset 
.arithmatex{overflow-x:auto !important;overflow-y:hidden 
!important}.katex-display .katex-html{display:flex 
!important;flex-direction:row;flex-wrap:nowrap;align-items:baseline;justify-content:space-between}.katex-display
 .katex-html .base{display:inline !important}.katex-display .katex-html 
.tag{position:relative !important;display:inline 
!important;margin-left:var(--margin-small)}.CtxtMenu_InfoClose{top:.2em;right:.2em}.CtxtMenu_InfoContent{overflow:auto;text-align:left;font-size:80%;padding:.4em
 .6em;border:1px inset;margin:1em 
0px;max-height:20em;max-width:30em;background-color:#ee
 
e;white-space:normal}.CtxtMenu_Info.CtxtMenu_MousePost{outline:none}.CtxtMenu_Info{position:fixed;left:50%;width:auto;text-align:center;border:3px
 outset;padding:1em 
2em;background-color:#ddd;color:#000;cursor:default;font-family:message-box;font-size:120%;font-style:normal;text-indent:0;text-transform:none;line-height:normal;letter-spacing:normal;word-spacing:normal;word-wrap:normal;white-space:nowrap;float:none;z-index:201;border-radius:15px;-webkit-border-radius:15px;-moz-border-radius:15px;-khtml-border-radius:15px;box-shadow:0px
 10px 20px gray;-webkit-box-shadow:0px 10px 20px gray;-moz-box-shadow:0px 10px 
20px gray;-khtml-box-shadow:0px 10px 20px 
gray;filter:progid:DXImageTransform.Microsoft.dropshadow(OffX=2, OffY=2, 
Color="gray", 
Positive="true")}.CtxtMenu_MenuClose{position:absolute;cursor:pointer;display:inline-block;border:2px
 solid 
#aaa;border-radius:18px;-webkit-border-radius:18px;-moz-border-radius:18px;-khtml-border-radius:18px;font-family:"Courier
 New",Courier;font-si
 ze:24px;color:#f0f0f0}.CtxtMenu_MenuClose 
span{display:block;background-color:#aaa;border:1.5px 
solid;border-radius:18px;-webkit-border-radius:18px;-moz-border-radius:18px;-khtml-border-radius:18px;line-height:0;padding:8px
 0 6px}.CtxtMenu_MenuClose:hover{color:#fff !important;border:2px solid #ccc 
!important}.CtxtMenu_MenuClose:hover span{background-color:#ccc 
!important}.CtxtMenu_MenuClose:hover:focus{outline:none}.CtxtMenu_Menu{position:absolute;background-color:#fff;color:#000;width:auto;padding:5px
 0px;border:1px solid 
#ccc;margin:0;cursor:default;font:menu;text-align:left;text-indent:0;text-transform:none;line-height:normal;letter-spacing:normal;word-spacing:normal;word-wrap:normal;white-space:nowrap;float:none;z-index:201;border-radius:5px;-webkit-border-radius:5px;-moz-border-radius:5px;-khtml-border-radius:5px;box-shadow:0px
 10px 20px gray;-webkit-box-shadow:0px 10px 20px gray;-moz-box-shadow:0px 10px 
20px gray;-khtml-box-shadow:0px 10px 20px gray}.CtxtMenu_MenuItem{padding
 :1px 
2em;background:rgba(0,0,0,0)}.CtxtMenu_MenuArrow{position:absolute;right:.5em;padding-top:.25em;color:#666;font-size:.75em}.CtxtMenu_MenuActive
 
.CtxtMenu_MenuArrow{color:#fff}.CtxtMenu_MenuArrow.CtxtMenu_RTL{left:.5em;right:auto}.CtxtMenu_MenuCheck{position:absolute;left:.7em}.CtxtMenu_MenuCheck.CtxtMenu_RTL{right:.7em;left:auto}.CtxtMenu_MenuRadioCheck{position:absolute;left:.7em}.CtxtMenu_MenuRadioCheck.CtxtMenu_RTL{right:.7em;left:auto}.CtxtMenu_MenuInputBox{padding-left:1em;right:.5em;color:#666}.CtxtMenu_MenuInputBox.CtxtMenu_RTL{left:.1em}.CtxtMenu_MenuComboBox{left:.1em;padding-bottom:.5em}.CtxtMenu_MenuSlider{left:.1em}.CtxtMenu_SliderValue{position:absolute;right:.1em;padding-top:.25em;color:#333;font-size:.75em}.CtxtMenu_SliderBar{outline:none;background:#d3d3d3}.CtxtMenu_MenuLabel{padding:1px
 2em 3px 1.33em;font-style:italic}.CtxtMenu_MenuRule{border-top:1px solid 
#ddd;margin:4px 
3px}.CtxtMenu_MenuDisabled{color:GrayText}.CtxtMenu_MenuActive{background-color:#606872;
 
color:#fff}.CtxtMenu_MenuDisabled:focus{background-color:#e8e8e8}.CtxtMenu_MenuLabel:focus{background-color:#e8e8e8}.CtxtMenu_ContextMenu:focus{outline:none}.CtxtMenu_ContextMenu
 
.CtxtMenu_MenuItem:focus{outline:none}.CtxtMenu_SelectionMenu{position:relative;float:left;border-bottom:none;-webkit-box-shadow:none;-webkit-border-radius:0px}.CtxtMenu_SelectionItem{padding-right:1em}.CtxtMenu_Selection{right:40%;width:50%}.CtxtMenu_SelectionBox{padding:0em;max-height:20em;max-width:none;background-color:#fff}.CtxtMenu_SelectionDivider{clear:both;border-top:2px
 solid #000}.CtxtMenu_Menu 
.CtxtMenu_MenuClose{top:-10px;left:-10px}[data-md-color-scheme=slate] 
.CtxtMenu_InfoSignature input,[data-md-color-scheme=slate] 
.CtxtMenu_InfoContent pre{color:#000}[data-md-color-scheme=slate] 
.CtxtMenu_Info,[data-md-color-scheme=slate] .CtxtMenu_Menu{box-shadow:0px 10px 
20px rgba(0,0,0,.5)}.md-typeset del.critic,.md-typeset ins.critic,.md-typeset 
mark.critic{padding:0 .25em;color:unset;box-shadow:none}.
 md-typeset .critic.break{margin:0}.md-typeset 
details{overflow:hidden}.md-typeset 
details>summary:focus{outline-style:none}:root>*{--highlight-svg-console: 
url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg"; 
viewBox="0 0 24 24"><path d="M20 19V7H4v12zm0-16a2 2 0 0 1 2 2v14a2 2 0 0 1-2 
2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2zm-7 14v-2h5v2zm-3.42-4L5.57 9H8.4l3.3 
3.3c.39.39.39 1.03 0 1.42L8.42 
17H5.59z"/></svg>');--highlight-svg-arrow-expand: 
url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg"; 
viewBox="0 0 24 24"><path d="M10 21v-2H6.41l4.5-4.5-1.41-1.41-4.5 
4.5V14H3v7zm4.5-10.09 4.5-4.5V10h2V3h-7v2h3.59l-4.5 
4.5z"/></svg>');--highlight-svg-arrow-collapse: 
url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg"; 
viewBox="0 0 24 24"><path d="M19.5 3.09 15 7.59V4h-2v7h7V9h-3.59l4.5-4.5zM4 
13v2h3.59l-4.5 4.5 1.41 1.41 4.5-4.5V20h2v-7z"/></svg>')}.highlight 
.hll{box-shadow:2px 0 0 0 var(--md-accent-fg-color) inset}.highlig
 ht .kc{color:var(--md-code-hl-constant-color)}.highlight .nc,.highlight 
.ne{color:var(--md-code-hl-class-color)}.highlight 
.mb{color:var(--md-code-hl-number-color)}.highlight .nb,.highlight 
.bp{color:var(--md-code-hl-builtin-color)}.highlight 
.nn{color:var(--md-code-hl-namespace-color)}.highlight .na,.highlight 
.nd,.highlight .ni{color:var(--md-code-hl-entity-color)}.highlight 
.nl,.highlight .nt{color:var(--md-code-hl-tag-color)}.md-typeset 
*:not(pre)>code{margin:0;padding:.1654411765em 
.3125em;color:var(--md-code-fg-color);background-color:var(--md-code-inline-bg-color);border-radius:.2rem;box-shadow:none}.md-typeset
 pre>code{display:grid}.md-typeset td code{word-break:normal}.md-typeset 
.highlight{-moz-tab-size:8;-o-tab-size:8;tab-size:8}.md-typeset .highlight 
[data-linenos]:hover::before{color:var(--md-accent-fg-color);font-weight:700}.md-typeset
 .highlight 
[data-linenos].special::before{background-color:var(--md-code-special-bg-color)}.md-typeset
 .highlight .hll [data-linenos]::
 before{box-shadow:-2px 0 var(--md-accent-fg-color) inset}.md-typeset 
.highlighttable .linenodiv 
.special{margin-right:-.5882352941em;margin-left:-1.1764705882em;padding-right:.5882352941em;padding-left:1.1764705882em;background-color:var(--md-code-special-bg-color)}.md-typeset
 .highlight 
span.filename{position:relative;display:block;margin-top:1em;padding:.5em 
1.1764705882em .5em 
2.9411764706em;font-weight:700;font-size:.68rem;background-color:var(--md-code-title-bg-color);border-top-left-radius:.48rem;border-top-right-radius:.48rem}.md-typeset
 .highlight span.filename+pre{margin-top:0}.md-typeset .highlight 
span.filename+pre 
code{border-top-left-radius:0;border-top-right-radius:0}.md-typeset .highlight 
span.filename::before{position:absolute;left:.8823529412em;width:1.4705882353em;height:1.4705882353em;background-color:var(--md-default-fg-color);-webkit-mask-image:var(--highlight-svg-console);mask-image:var(--highlight-svg-console);-webkit-mask-repeat:no-repeat;mask-repeat:no-repea
 t;-webkit-mask-size:contain;mask-size:contain;content:""}.md-typeset 
.collapse-code{position:relative;margin-top:1em;margin-bottom:1em}.md-typeset 
.collapse-code pre{margin-top:0;margin-bottom:0}.md-typeset .collapse-code 
input{display:none}.md-typeset .collapse-code 
input~.code-footer{width:100%;margin:0;padding:.25em .5em .25em 0em}.md-typeset 
.collapse-code input~.code-footer 
label{position:relative;margin:.05em;padding:.15em 
.8em;color:var(--md-primary-bg-color);font-size:90%;background-color:var(--md-accent-fg-color);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;border-radius:.1rem;cursor:pointer;content:""}.md-typeset
 .collapse-code input~.code-footer 
label:hover{background-color:var(--md-accent-fg-color)}.md-typeset 
.collapse-code input~.code-footer 
label::before{position:absolute;top:.15em;left:.15em;display:block;box-sizing:border-box;width:1.25em;height:1.25em;background-color:var(--md-primary-bg-color);background-size:1.25
 em;content:""}.md-typeset .collapse-code input~.code-footer 
label.expand{display:none}.md-typeset .collapse-code input~.code-footer 
label.expand::before{-webkit-mask-image:var(--highlight-svg-arrow-expand);mask-image:var(--highlight-svg-arrow-expand)}.md-typeset
 .collapse-code input~.code-footer 
label.collapse::before{-webkit-mask-image:var(--highlight-svg-arrow-collapse);mask-image:var(--highlight-svg-arrow-collapse)}.md-typeset
 .collapse-code input:checked~.code-footer 
label.expand{display:inline}.md-typeset .collapse-code 
input:checked~.code-footer label.collapse{display:none}.md-typeset 
.collapse-code input:checked+div.highlight 
code{max-height:9.375em;overflow:hidden}.md-typeset .collapse-code 
input:checked~.code-footer{position:relative;bottom:4.3em;left:0;margin-bottom:-4.3em;padding:2em
 .5em .5em .8rem;background-image:linear-gradient(to bottom, transparent, 
var(--md-default-bg-color) 80% 
100%);border-bottom-right-radius:.48rem;border-bottom-left-radius:.48rem}.md-typeset
 .h
 
ighlight+.result{border-right-width:.1rem;border-bottom-width:.1rem;border-left-width:.1rem}.md-typeset
 .keys .key-power::before{padding-right:.4em;content:"⏻"}.md-typeset .keys 
.key-fingerprint::before{padding-right:.4em;content:"☝"}:root>*{--magiclink-email-icon:
 url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg"; 
viewBox="0 0 24 24"><path d="M20 4H4c-1.11 0-2 .89-2 2v12a2 2 0 0 0 2 2h16a2 2 
0 0 0 2-2V6a2 2 0 0 0-2-2m-3 
13H7v-2h10m0-2H7v-2h10m3-2h-3V6h3"/></svg>');--magiclink-github-icon: 
url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg"; 
viewBox="0 0 24 24"><path d="M12 2A10 10 0 0 0 2 12c0 4.42 2.87 8.17 6.84 
9.5.5.08.66-.23.66-.5v-1.69c-2.77.6-3.36-1.34-3.36-1.34-.46-1.16-1.11-1.47-1.11-1.47-.91-.62.07-.6.07-.6
 1 .07 1.53 1.03 1.53 1.03.87 1.52 2.34 1.07 
2.91.83.09-.65.35-1.09.63-1.34-2.22-.25-4.55-1.11-4.55-4.92 0-1.11.38-2 
1.03-2.71-.1-.25-.45-1.29.1-2.64 0 0 .84-.27 2.75 1.02.79-.22 1.65-.33 
2.5-.33s1.71.11 2.5.33c1.91
 -1.29 2.75-1.02 2.75-1.02.55 1.35.2 2.39.1 2.64.65.71 1.03 1.6 1.03 2.71 0 
3.82-2.34 4.66-4.57 4.91.36.31.69.92.69 1.85V21c0 .27.16.59.67.5C19.14 20.16 22 
16.42 22 12A10 10 0 0 0 12 2"/></svg>');--magiclink-bitbucket-icon: 
url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg"; 
viewBox="0 0 24 24"><path d="M2.65 3C2.3 3 2 3.3 2 3.65v.12l2.73 
16.5c.07.42.43.73.85.73h13.05c.31 0 .59-.22.64-.54L22 3.77a.643.643 0 0 
0-.54-.73c-.03-.01-.07-.01-.11-.01zM14.1 14.95H9.94L8.81 
9.07h6.3z"/></svg>');--magiclink-gitlab-icon: 
url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg"; 
viewBox="0 0 24 24"><path d="m21.94 
13.11-1.05-3.22c0-.03-.01-.06-.02-.09l-2.11-6.48a.86.86 0 0 0-.8-.57c-.36 
0-.68.25-.79.58l-2 6.17H8.84L6.83 3.33a.85.85 0 0 0-.79-.58c-.37 
0-.69.25-.8.58L3.13 9.82v.01l-1.07 3.28c-.16.5.01 1.04.44 1.34l9.22 
6.71c.17.12.39.12.56-.01l9.22-6.7c.43-.3.6-.84.44-1.34M8.15 10.45l2.57 
7.91-6.17-7.91m8.73 7.92 2.47-7.59.1-.33h3.61l-5.59 7.16m4.1-13.
 67 1.81 5.56h-3.62m-1.3.95-1.79 5.51L12 19.24l-2.86-8.79M6.03 3.94 7.84 
9.5H4.23m-1.18 4.19c-.09-.07-.13-.19-.09-.29l.79-2.43 5.82 7.45m11.38-4.73-6.51 
4.73.02-.03 5.79-7.42.79 2.43c.04.1 0 
.22-.09.29"/></svg>');--magiclink-commit-icon: 
url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg"; 
viewBox="0 0 24 24"><path d="M16.944 11h4.306a.75.75 0 0 1 0 1.5h-4.306a5.001 
5.001 0 0 1-9.888 0H2.75a.75.75 0 0 1 0-1.5h4.306a5.001 5.001 0 0 1 9.888 
0m-1.444.75a3.5 3.5 0 1 0-7 0 3.5 3.5 0 0 0 7 
0"/></svg>');--magiclink-compare-icon: 
url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg"; 
viewBox="0 0 24 24"><path d="M12.5 6.75a.75.75 0 0 0-1.5 0V9H8.75a.75.75 0 0 0 
0 1.5H11v2.25a.75.75 0 0 0 1.5 0V10.5h2.25a.75.75 0 0 0 0-1.5H12.5zM8.75 
16a.75.75 0 0 0 0 1.5h6a.75.75 0 0 0 0-1.5z"/><path d="M5 1h9.982a2 2 0 0 1 
1.414.586l4.018 4.018A2 2 0 0 1 21 7.018V21a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V3a2 2 
0 0 1 2-2m-.5 2v18a.5.5 0 0 0 .5.5h14a.5.5 0 0 0 .5-.5V7.01
 8a.5.5 0 0 0-.146-.354l-4.018-4.018a.5.5 0 0 0-.354-.146H5a.5.5 0 0 
0-.5.5"/></svg>');--magiclink-pull-icon: 
url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg"; 
viewBox="0 0 24 24"><path d="M16 19.25a3.25 3.25 0 1 1 6.5 0 3.25 3.25 0 0 
1-6.5 0m-14.5 0a3.25 3.25 0 1 1 6.5 0 3.25 3.25 0 0 1-6.5 0m0-14.5a3.25 3.25 0 
1 1 6.5 0 3.25 3.25 0 0 1-6.5 0M4.75 3a1.75 1.75 0 1 0 .001 3.501A1.75 1.75 0 0 
0 4.75 3m0 14.5a1.75 1.75 0 1 0 .001 3.501A1.75 1.75 0 0 0 4.75 17.5m14.5 
0a1.75 1.75 0 1 0 .001 3.501 1.75 1.75 0 0 0-.001-3.501"/><path d="M13.405 
1.72a.75.75 0 0 1 0 1.06L12.185 4h4.065A3.75 3.75 0 0 1 20 7.75v8.75a.75.75 0 0 
1-1.5 0V7.75a2.25 2.25 0 0 0-2.25-2.25h-4.064l1.22 1.22a.75.75 0 0 1-1.061 
1.06l-2.5-2.5a.75.75 0 0 1 0-1.06l2.5-2.5a.75.75 0 0 1 1.06 0M4.75 7.25A.75.75 
0 0 1 5.5 8v8A.75.75 0 0 1 4 16V8a.75.75 0 0 1 
.75-.75"/></svg>');--magiclink-issue-icon: 
url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg"; 
viewBox="0 0 24 24"><path
  d="M12 1c6.075 0 11 4.925 11 11s-4.925 11-11 11S1 18.075 1 12 5.925 1 12 
1M2.5 12a9.5 9.5 0 0 0 9.5 9.5 9.5 9.5 0 0 0 9.5-9.5A9.5 9.5 0 0 0 12 2.5 9.5 
9.5 0 0 0 2.5 12m9.5 2a2 2 0 1 1-.001-3.999A2 2 0 0 1 12 
14"/></svg>');--magiclink-discussion-icon: 
url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg"; 
viewBox="0 0 24 24"><path d="M1.75 1h12.5c.966 0 1.75.784 1.75 1.75v9.5A1.75 
1.75 0 0 1 14.25 14H8.061l-2.574 2.573A1.458 1.458 0 0 1 3 15.543V14H1.75A1.75 
1.75 0 0 1 0 12.25v-9.5C0 1.784.784 1 1.75 1M1.5 2.75v9.5c0 
.138.112.25.25.25h2a.75.75 0 0 1 .75.75v2.19l2.72-2.72a.75.75 0 0 1 
.53-.22h6.5a.25.25 0 0 0 .25-.25v-9.5a.25.25 0 0 0-.25-.25H1.75a.25.25 0 0 
0-.25.25"/><path d="M22.5 8.75a.25.25 0 0 0-.25-.25h-3.5a.75.75 0 0 1 
0-1.5h3.5c.966 0 1.75.784 1.75 1.75v9.5A1.75 1.75 0 0 1 22.25 20H21v1.543a1.457 
1.457 0 0 1-2.487 1.03L15.939 20H10.75A1.75 1.75 0 0 1 9 18.25v-1.465a.75.75 0 
0 1 1.5 0v1.465c0 .138.112.25.25.25h5.5a.75.75 0 0 1 .53.22l2.72 2.72v-2.19a.75
 .75 0 0 1 .75-.75h2a.25.25 0 0 0 .25-.25z"/></svg>')}.md-typeset 
a[href^="mailto:"]:not(.magiclink-ignore)::before{-webkit-mask-image:var(--magiclink-email-icon);mask-image:var(--magiclink-email-icon)}.md-typeset
 .magiclink-repository:not(.magiclink-ignore),.md-typeset 
.magiclink-compare:not(.magiclink-ignore),.md-typeset 
.magiclink-commit:not(.magiclink-ignore),.md-typeset 
.magiclink-pull:not(.magiclink-ignore),.md-typeset 
.magiclink-issue:not(.magiclink-ignore),.md-typeset 
.magiclink-discussion:not(.magiclink-ignore),.md-typeset 
a[href^="mailto:"]:not(.magiclink-ignore){position:relative;padding-left:1.375em}.md-typeset
 .magiclink-repository:not(.magiclink-ignore)::before,.md-typeset 
.magiclink-compare:not(.magiclink-ignore)::before,.md-typeset 
.magiclink-commit:not(.magiclink-ignore)::before,.md-typeset 
.magiclink-pull:not(.magiclink-ignore)::before,.md-typeset 
.magiclink-issue:not(.magiclink-ignore)::before,.md-typeset 
.magiclink-discussion:not(.magiclink-ignore)::before,.md-typ
 eset 
a[href^="mailto:"]:not(.magiclink-ignore)::before{position:absolute;top:0;left:0;display:block;box-sizing:border-box;width:1.25em;height:1.25em;background-color:var(--md-typeset-a-color);background-size:1.25em;transition:background-color
 
125ms;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;content:""}.md-typeset
 .magiclink-repository:not(.magiclink-ignore):hover::before,.md-typeset 
.magiclink-compare:not(.magiclink-ignore):hover::before,.md-typeset 
.magiclink-commit:not(.magiclink-ignore):hover::before,.md-typeset 
.magiclink-pull:not(.magiclink-ignore):hover::before,.md-typeset 
.magiclink-issue:not(.magiclink-ignore):hover::before,.md-typeset 
.magiclink-discussion:not(.magiclink-ignore):hover::before,.md-typeset 
a[href^="mailto:"]:not(.magiclink-ignore):hover::before{background-color:var(--md-accent-fg-color)}.md-typeset
 
.magiclink-commit:not(.magiclink-ignore)::before{-webkit-mask-image:var(--magiclink-commit-icon);mask-image:va
 r(--magiclink-commit-icon)}.md-typeset 
.magiclink-compare:not(.magiclink-ignore)::before{-webkit-mask-image:var(--magiclink-compare-icon);mask-image:var(--magiclink-compare-icon)}.md-typeset
 
.magiclink-pull:not(.magiclink-ignore)::before{-webkit-mask-image:var(--magiclink-pull-icon);mask-image:var(--magiclink-pull-icon)}.md-typeset
 
.magiclink-issue:not(.magiclink-ignore)::before{-webkit-mask-image:var(--magiclink-issue-icon);mask-image:var(--magiclink-issue-icon)}.md-typeset
 
.magiclink-discussion:not(.magiclink-ignore)::before{-webkit-mask-image:var(--magiclink-discussion-icon);mask-image:var(--magiclink-discussion-icon)}.md-typeset
 
.magiclink-repository.magiclink-github:not(.magiclink-ignore)::before{-webkit-mask-image:var(--magiclink-github-icon);mask-image:var(--magiclink-github-icon)}.md-typeset
 
.magiclink-repository.magiclink-gitlab:not(.magiclink-ignore)::before{-webkit-mask-image:var(--magiclink-gitlab-icon);mask-image:var(--magiclink-gitlab-icon)}.md-typeset
 .magiclink-repos
 
itory.magiclink-bitbucket:not(.magiclink-ignore)::before{-webkit-mask-image:var(--magiclink-bitbucket-icon);mask-image:var(--magiclink-bitbucket-icon)}.md-typeset
 mark:not(.critic){box-shadow:none}.md-typeset 
.progress-label{position:absolute;width:100%;margin:0;color:var(--md-text-color);font-weight:700;line-height:1.4rem;white-space:nowrap;text-align:center;text-shadow:-0.0625em
 -0.0625em .375em var(--md-default-bg-color--light),.0625em -0.0625em .375em 
var(--md-default-bg-color--light),-0.0625em .0625em .375em 
var(--md-default-bg-color--light),.0625em .0625em .375em 
var(--md-default-bg-color--light)}.md-typeset 
.progress-bar{float:left;height:1.2rem;background-color:#2979ff}.md-typeset 
.candystripe-animate .progress-bar{animation:animate-stripes 3s linear 
infinite}.md-typeset 
.progress{position:relative;display:block;width:100%;height:1.2rem;margin:.5rem 
0;background-color:var(--md-default-fg-color--lightest)}.md-typeset 
.progress.thin{height:.4rem;margin-top:.9rem}.md-typeset .p
 rogress.thin .progress-label{margin-top:-0.4rem}.md-typeset .progress.thin 
.progress-bar{height:.4rem}.md-typeset .progress.candystripe 
.progress-bar{background-image:linear-gradient(135deg, 
var(--md-progress-stripe) 27%, transparent 27%, transparent 52%, 
var(--md-progress-stripe) 52%, var(--md-progress-stripe) 77%, transparent 77%, 
transparent);background-size:2rem 2rem}.md-typeset .progress-100plus 
.progress-bar{background-color:var(--md-progress-100)}.md-typeset 
.progress-80plus 
.progress-bar{background-color:var(--md-progress-80)}.md-typeset 
.progress-60plus 
.progress-bar{background-color:var(--md-progress-60)}.md-typeset 
.progress-40plus 
.progress-bar{background-color:var(--md-progress-40)}.md-typeset 
.progress-20plus 
.progress-bar{background-color:var(--md-progress-20)}.md-typeset 
.progress-0plus .progress-bar{background-color:var(--md-progress-0)}@keyframes 
animate-stripes{0%{background-position:0 0}100%{background-position:6rem 
0}}.md-typeset .tabbed-control button:hover{col
 or:var(--md-default-bg-color);background:var(--md-accent-fg-color)}.md-typeset 
.tabbed-control--next 
button:hover{color:var(--md-default-bg-color);background:var(--md-accent-fg-color)}.js
 .md-typeset 
.tabbed-labels::before{background-color:var(--md-accent-fg-color)}.md-typeset 
.tabbed-alternate.tabbed-set .tabbed-control{width:2rem}.md-typeset 
.tabbed-alternate.tabbed-set 
.tabbed-control[hidden]{width:1.2rem;opacity:0}.md-typeset 
.tabbed-alternate.tabbed-set>.tabbed-content>.tabbed-block{padding:0 
.6rem}.md-typeset 
.tabbed-alternate.tabbed-set>.tabbed-content>.tabbed-block>pre:first-child,.md-typeset
 
.tabbed-alternate.tabbed-set>.tabbed-content>.tabbed-block>.codehilite:first-child,.md-typeset
 
.tabbed-alternate.tabbed-set>.tabbed-content>.tabbed-block>.codehilitetable:first-child,.md-typeset
 
.tabbed-alternate.tabbed-set>.tabbed-content>.tabbed-block>.highlight:first-child,.md-typeset
 
.tabbed-alternate.tabbed-set>.tabbed-content>.tabbed-block>.highlighttable:first-child{margin-top:.9
 375em}.md-typeset 
.tabbed-alternate.tabbed-set>.tabbed-content>.tabbed-block>pre:first-child 
code,.md-typeset 
.tabbed-alternate.tabbed-set>.tabbed-content>.tabbed-block>.codehilite:first-child
 code,.md-typeset 
.tabbed-alternate.tabbed-set>.tabbed-content>.tabbed-block>.codehilitetable:first-child
 code,.md-typeset 
.tabbed-alternate.tabbed-set>.tabbed-content>.tabbed-block>.highlight:first-child
 code,.md-typeset 
.tabbed-alternate.tabbed-set>.tabbed-content>.tabbed-block>.highlighttable:first-child
 code{border-top-left-radius:.48rem;border-top-right-radius:.48rem}.md-typeset 
.tabbed-alternate.tabbed-set>.tabbed-content>.tabbed-block>pre:only-child,.md-typeset
 
.tabbed-alternate.tabbed-set>.tabbed-content>.tabbed-block>.codehilite:only-child,.md-typeset
 
.tabbed-alternate.tabbed-set>.tabbed-content>.tabbed-block>.codehilitetable:only-child,.md-typeset
 
.tabbed-alternate.tabbed-set>.tabbed-content>.tabbed-block>.highlight:only-child,.md-typeset
 .tabbed-alternate.tabbed-set>.tabbed-content>.
 
tabbed-block>.highlighttable:only-child{margin-top:0;margin-right:-1.2rem;margin-left:-1.2rem;padding-right:.6rem;padding-left:.6rem}.md-typeset
 .tabbed-alternate.tabbed-set>.tabbed-content>.tabbed-block>pre:only-child 
code,.md-typeset 
.tabbed-alternate.tabbed-set>.tabbed-content>.tabbed-block>.codehilite:only-child
 code,.md-typeset 
.tabbed-alternate.tabbed-set>.tabbed-content>.tabbed-block>.codehilitetable:only-child
 code,.md-typeset 
.tabbed-alternate.tabbed-set>.tabbed-content>.tabbed-block>.highlight:only-child
 code,.md-typeset 
.tabbed-alternate.tabbed-set>.tabbed-content>.tabbed-block>.highlighttable:only-child
 code{border-top-left-radius:0;border-top-right-radius:0}.md-typeset 
.tabbed-alternate.tabbed-set>.tabbed-content>.tabbed-block>pre:only-child 
span.filename,.md-typeset 
.tabbed-alternate.tabbed-set>.tabbed-content>.tabbed-block>.codehilite:only-child
 span.filename,.md-typeset 
.tabbed-alternate.tabbed-set>.tabbed-content>.tabbed-block>.codehilitetable:only-child
 span.filena
 me,.md-typeset 
.tabbed-alternate.tabbed-set>.tabbed-content>.tabbed-block>.highlight:only-child
 span.filename,.md-typeset 
.tabbed-alternate.tabbed-set>.tabbed-content>.tabbed-block>.highlighttable:only-child
 span.filename{margin-top:0}.md-typeset 
.tabbed-alternate.tabbed-set>.tabbed-content>.tabbed-block>.collapse-code:only-child{margin-top:0;margin-right:-1.2rem;margin-left:-1.2rem;padding-right:.6rem;padding-left:.6rem}.md-typeset
 
.tabbed-alternate.tabbed-set>.tabbed-content>.tabbed-block>.collapse-code:only-child
 pre code,.md-typeset 
.tabbed-alternate.tabbed-set>.tabbed-content>.tabbed-block>.collapse-code:only-child
 .codehilite code,.md-typeset 
.tabbed-alternate.tabbed-set>.tabbed-content>.tabbed-block>.collapse-code:only-child
 .codehilitetable code,.md-typeset 
.tabbed-alternate.tabbed-set>.tabbed-content>.tabbed-block>.collapse-code:only-child
 .highlight code,.md-typeset 
.tabbed-alternate.tabbed-set>.tabbed-content>.tabbed-block>.collapse-code:only-child
 .highlighttable code{bo
 rder-top-left-radius:0;border-top-right-radius:0}.md-typeset 
.tabbed-alternate.tabbed-set>.tabbed-content>.tabbed-block>diagram-div:only-child{margin-right:-1.2rem;margin-left:-1.2rem;padding-right:.6rem;padding-left:.6rem}[data-md-color-scheme=slate]
 .md-typeset .task-list-control 
.task-list-indicator::before{background-color:var(--md-default-fg-color--lighter)}[data-md-color-scheme=slate]
 .md-typeset .task-list-control 
[type=checkbox]:checked+.task-list-indicator::before{background-color:hsl(135,94%,65%)}:root>*{--toc-svg-link:
 url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg"; 
viewBox="0 0 24 24"><path d="M3.9 12c0-1.71 1.39-3.1 3.1-3.1h4V7H7a5 5 0 0 0-5 
5 5 5 0 0 0 5 5h4v-1.9H7c-1.71 0-3.1-1.39-3.1-3.1M8 
13h8v-2H8zm9-6h-4v1.9h4c1.71 0 3.1 1.39 3.1 3.1s-1.39 3.1-3.1 3.1h-4V17h4a5 5 0 
0 0 5-5 5 5 0 0 0-5-5"/></svg>')}.md-typeset 
.headerlink{width:1em;height:1em;vertical-align:middle;background-color:var(--md-default-fg-color--lighter);background-size:1em
 
;-webkit-mask-size:1em;mask-size:1em;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;visibility:visible;-webkit-mask-image:var(--toc-svg-link);mask-image:var(--toc-svg-link)}.md-typeset
 .headerlink:hover,.md-typeset [id]:target 
.headerlink{background-color:var(--md-accent-fg-color)}diagram-div{overflow:auto}.md-typeset
 div.steps>ol{counter-reset:item}.md-typeset 
div.steps>ol>li{position:relative;padding-left:1em;list-style:none}.md-typeset 
div.steps>ol>li::before{position:absolute;top:0;left:0;z-index:-1;display:block;width:1.75em;height:1.75em;margin-left:-1.25em;color:var(--md-steps-fg-color);font-weight:600;font-size:.9em;text-align:center;background-color:var(--md-steps-bg-color);border:1px
 solid 
var(--md-steps-border-color);border-radius:100px;content:counter(item);counter-increment:item}.md-typeset
 
div.steps>ol>li::after{position:absolute;top:0;bottom:0;left:-0.36em;display:block;width:1px;margin-top:2em;border-left:1px
 solid var(--md-steps-border-color);content:""}.md-typ
 eset table:not([class]){background:none;border-radius:.4rem}.md-typeset 
table:not([class]) th{border-bottom:.1rem solid 
var(--md-accent-fg-color)}html{background-color:rgba(0,0,0,0)}[data-md-component=announce]
 .twemoji{color:var(--md-primary-fg-color)}.md-container .md-tabs 
.md-tabs__item--active{border-bottom:.1rem solid 
var(--md-accent-fg-color)}.md-nav--secondary>ul{border-left:.1rem solid 
var(--md-default-fg-color--lightest)}.md-nav--secondary ul .md-nav__item 
.md-nav__link--active{margin-left:-0.1rem;padding-left:.8rem}.md-nav--secondary 
ul .md-nav__item ul .md-nav__item 
.md-nav__link--active{margin-left:-0.7rem;padding-left:1.4rem}.md-nav--secondary
 ul .md-nav__item ul .md-nav__item ul .md-nav__item 
.md-nav__link--active{margin-left:-1.3rem;padding-left:2rem}.md-nav--secondary 
ul .md-nav__item ul .md-nav__item ul .md-nav__item ul .md-nav__item 
.md-nav__link--active{margin-left:-1.9rem;padding-left:2.6rem}.md-nav--secondary
 ul .md-nav__item ul .md-nav__item ul .md-nav__item ul
  .md-nav__item ul .md-nav__item 
.md-nav__link--active{margin-left:-2.5rem;padding-left:3.2rem}.md-nav--secondary
 .md-nav__item{color:var(--md-default-fg-color--light)}.md-nav--secondary 
.md-nav__item 
.md-nav__link--active{color:var(--md-default-fg-color);border-left:.1rem solid 
var(--md-accent-fg-color);border-top-left-radius:0;border-bottom-left-radius:0}.md-nav--secondary
 .md-nav__item .md-nav__link:focus,.md-nav--secondary .md-nav__item 
.md-nav__link:hover{color:var(--md-default-fg-color)}.md-nav--primary 
.md-nav__item{color:var(--md-default-fg-color--light)}.md-nav__source{color:var(--md-text-color)}.md-nav__link[data-md-state=blur]{color:var(--md-default-fg-color--light)}.md-typeset
 
h5{color:var(--md-text-color);text-transform:none}.md-typeset__scrollwrap,.md-sidebar__scrollwrap,.md-search__scrollwrap,.md-typeset
 pre>code,.md-typeset div.mermaid,.md-typeset div.diagram,.md-typeset 
mermaid-div,.md-typeset diagram-div,.md-typeset pre.arithmatex,.md-typeset 
div.arithmatex{scrollba
 r-color:var(--md-default-fg-color--lighter) 
rgba(0,0,0,0);scrollbar-width:thin}.md-typeset__scrollwrap:hover,.md-sidebar__scrollwrap:hover,.md-search__scrollwrap:hover,.md-typeset
 pre>code:hover,.md-typeset div.mermaid:hover,.md-typeset 
div.diagram:hover,.md-typeset mermaid-div:hover,.md-typeset 
diagram-div:hover,.md-typeset pre.arithmatex:hover,.md-typeset 
div.arithmatex:hover{scrollbar-color:var(--md-accent-fg-color) 
rgba(0,0,0,0)}.md-typeset__scrollwrap::-webkit-scrollbar,.md-sidebar__scrollwrap::-webkit-scrollbar,.md-search__scrollwrap::-webkit-scrollbar,.md-typeset
 pre>code::-webkit-scrollbar,.md-typeset 
div.mermaid::-webkit-scrollbar,.md-typeset 
div.diagram::-webkit-scrollbar,.md-typeset 
mermaid-div::-webkit-scrollbar,.md-typeset 
diagram-div::-webkit-scrollbar,.md-typeset 
pre.arithmatex::-webkit-scrollbar,.md-typeset 
div.arithmatex::-webkit-scrollbar{width:.2rem;height:.2rem}.md-typeset__scrollwrap::-webkit-scrollbar-corner,.md-sidebar__scrollwrap::-webkit-scrollbar-corner,.md
 -search__scrollwrap::-webkit-scrollbar-corner,.md-typeset 
pre>code::-webkit-scrollbar-corner,.md-typeset 
div.mermaid::-webkit-scrollbar-corner,.md-typeset 
div.diagram::-webkit-scrollbar-corner,.md-typeset 
mermaid-div::-webkit-scrollbar-corner,.md-typeset 
diagram-div::-webkit-scrollbar-corner,.md-typeset 
pre.arithmatex::-webkit-scrollbar-corner,.md-typeset 
div.arithmatex::-webkit-scrollbar-corner{background-color:rgba(0,0,0,0)}.md-typeset__scrollwrap::-webkit-scrollbar-thumb,.md-sidebar__scrollwrap::-webkit-scrollbar-thumb,.md-search__scrollwrap::-webkit-scrollbar-thumb,.md-typeset
 pre>code::-webkit-scrollbar-thumb,.md-typeset 
div.mermaid::-webkit-scrollbar-thumb,.md-typeset 
div.diagram::-webkit-scrollbar-thumb,.md-typeset 
mermaid-div::-webkit-scrollbar-thumb,.md-typeset 
diagram-div::-webkit-scrollbar-thumb,.md-typeset 
pre.arithmatex::-webkit-scrollbar-thumb,.md-typeset 
div.arithmatex::-webkit-scrollbar-thumb{background-color:var(--md-default-fg-color--lighter)}.md-typeset__scrollwra
 
p::-webkit-scrollbar-thumb:hover,.md-sidebar__scrollwrap::-webkit-scrollbar-thumb:hover,.md-search__scrollwrap::-webkit-scrollbar-thumb:hover,.md-typeset
 pre>code::-webkit-scrollbar-thumb:hover,.md-typeset 
div.mermaid::-webkit-scrollbar-thumb:hover,.md-typeset 
div.diagram::-webkit-scrollbar-thumb:hover,.md-typeset 
mermaid-div::-webkit-scrollbar-thumb:hover,.md-typeset 
diagram-div::-webkit-scrollbar-thumb:hover,.md-typeset 
pre.arithmatex::-webkit-scrollbar-thumb:hover,.md-typeset 
div.arithmatex::-webkit-scrollbar-thumb:hover{background-color:var(--md-accent-fg-color)}@media
 screen and (max-width: 
44.9375em){.md-content__inner>diagram-div{margin-right:-0.8rem;margin-left:-0.8rem}.md-content__inner>.highlight
 
span.filename{border-top-left-radius:0;border-top-right-radius:0}.md-content__inner>.collapse-code{margin-right:-0.8rem;margin-left:-0.8rem}.md-content__inner>.collapse-code
 label.collapse{left:.8rem}[dir=ltr] .md-content__inner>.tabbed-set 
.tabbed-labels{padding-left:0}.md-conten
 t__inner>.tabbed-set 
.tabbed-labels{max-width:100%;margin:0;padding-inline-start:0;scroll-padding-inline-start:0}.md-content__inner>.tabbed-set
 
.tabbed-labels::after{padding-inline-end:0;content:none}.md-content__inner>.tabbed-set
 
.tabbed-labels~.tabbed-control--prev{margin-inline-start:0;padding-inline-start:0}.md-content__inner>.tabbed-set
 .tabbed-labels~.tabbed-control--next{margin-inline-end:0;padding-inline-end:0}}
+/*# sourceMappingURL=extra-95634471d6.css.map */
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/bracex-2.6/docs/theme/assets/pymdownx-extras/extra-loader-Ccztcqfq.js 
new/bracex-3.0/docs/theme/assets/pymdownx-extras/extra-loader-Ccztcqfq.js
--- old/bracex-2.6/docs/theme/assets/pymdownx-extras/extra-loader-Ccztcqfq.js   
1970-01-01 01:00:00.000000000 +0100
+++ new/bracex-3.0/docs/theme/assets/pymdownx-extras/extra-loader-Ccztcqfq.js   
2020-02-02 01:00:00.000000000 +0100
@@ -0,0 +1,4 @@
+function _typeof(t){return _typeof="function"==typeof Symbol&&"symbol"==typeof 
Symbol.iterator?function(t){return typeof t}:function(t){return 
t&&"function"==typeof 
Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof 
t},_typeof(t)}!function(){"use strict";function t(t,e,r,o,a,n,i){try{var 
c=t[n](i),l=c.value}catch(t){return void 
r(t)}c.done?e(l):Promise.resolve(l).then(o,a)}function e(t,e,r){return 
e=o(e),function(t,e){if(e&&("object"==_typeof(e)||"function"==typeof e))return 
e;if(void 0!==e)throw new TypeError("Derived constructors may only return 
object or undefined");return function(t){if(void 0===t)throw new 
ReferenceError("this hasn't been initialised - super() hasn't been 
called");return 
t}(t)}(t,n()?Reflect.construct(e,[],o(t).constructor):e.apply(t,r))}function 
r(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a 
function")}function o(t){return 
o=Object.setPrototypeOf?Object.getPrototypeOf.bind():function(t){return 
t.__proto__||Object.ge
 tPrototypeOf(t)},o(t)}function a(t,e){if("function"!=typeof e&&null!==e)throw 
new TypeError("Super expression must either be null or a 
function");t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,writable:!0,configurable:!0}}),Object.defineProperty(t,"prototype",{writable:!1}),e&&l(t,e)}function
 n(){try{var 
t=!Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],function(){}))}catch(t){}return(n=function(){return!!t})()}function
 i(){
+/*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- 
license (MIT): 
https://github.com/babel/babel/blob/main/packages/babel-helpers/LICENSE */
+var t,e,r="function"==typeof 
Symbol?Symbol:{},o=r.iterator||"@@iterator",a=r.toStringTag||"@@toStringTag";function
 n(r,o,a,n){var i=o&&o.prototype instanceof 
f?o:f,d=Object.create(i.prototype);return c(d,"_invoke",function(r,o,a){var 
n,i,c,f=0,d=a||[],u=!1,p={p:0,n:0,v:t,a:s,f:s.bind(t,4),d:function(e,r){return 
n=e,i=0,c=t,p.n=r,l}};function 
s(r,o){for(i=r,c=o,e=0;!u&&f&&!a&&e<d.length;e++){var 
a,n=d[e],s=p.p,m=n[2];r>3?(a=m===o)&&(c=n[(i=n[4])?5:(i=3,3)],n[4]=n[5]=t):n[0]<=s&&((a=r<2&&s<n[1])?(i=0,p.v=o,p.n=n[1]):s<m&&(a=r<3||n[0]>o||o>m)&&(n[4]=r,n[5]=o,p.n=m,i=0))}if(a||r>1)return
 l;throw u=!0,o}return function(a,d,m){if(f>1)throw TypeError("Generator is 
already 
running");for(u&&1===d&&s(d,m),i=d,c=m;(e=i<2?t:c)||!u;){n||(i?i<3?(i>1&&(p.n=-1),s(i,c)):p.n=c:p.v=c);try{if(f=2,n){if(i||(a="next"),e=n[a]){if(!(e=e.call(n,c)))throw
 TypeError("iterator result is not an object");if(!e.done)return 
e;c=e.value,i<2&&(i=0)}else 
1===i&&(e=n.return)&&e.call(n),i<2&&(c=TypeError("The iterator 
 does not provide a '"+a+"' method"),i=1);n=t}else 
if((e=(u=p.n<0)?c:r.call(o,p))!==l)break}catch(e){n=t,i=1,c=e}finally{f=1}}return{value:e,done:u}}}(r,a,n),!0),d}var
 l={};function f(){}function d(){}function u(){}e=Object.getPrototypeOf;var 
p=[][o]?e(e([][o]())):(c(e={},o,function(){return 
this}),e),s=u.prototype=f.prototype=Object.create(p);function m(t){return 
Object.setPrototypeOf?Object.setPrototypeOf(t,u):(t.__proto__=u,c(t,a,"GeneratorFunction")),t.prototype=Object.create(s),t}return
 
d.prototype=u,c(s,"constructor",u),c(u,"constructor",d),d.displayName="GeneratorFunction",c(u,a,"GeneratorFunction"),c(s),c(s,a,"Generator"),c(s,o,function(){return
 this}),c(s,"toString",function(){return"[object 
Generator]"}),(i=function(){return{w:n,m:m}})()}function c(t,e,r,o){var 
a=Object.defineProperty;try{a({},"",{})}catch(t){a=0}c=function(t,e,r,o){function
 n(e,r){c(t,e,function(t){return 
this._invoke(e,r,t)})}e?a?a(t,e,{value:r,enumerable:!o,configurable:!o,writable:!o}):t[e]=r:(n("next",
 0),n("throw",1),n("return",2))},c(t,e,r,o)}function l(t,e){return 
l=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(t,e){return 
t.__proto__=e,t},l(t,e)}function f(t){var e="function"==typeof Map?new Map:void 
0;return 
f=function(t){if(null===t||!function(t){try{return-1!==Function.toString.call(t).indexOf("[native
 code]")}catch(e){return"function"==typeof t}}(t))return 
t;if("function"!=typeof t)throw new TypeError("Super expression must either be 
null or a function");if(void 0!==e){if(e.has(t))return 
e.get(t);e.set(t,r)}function r(){return function(t,e,r){if(n())return 
Reflect.construct.apply(null,arguments);var o=[null];o.push.apply(o,e);var 
a=new(t.bind.apply(t,o));return 
r&&l(a,r.prototype),a}(t,arguments,o(this).constructor)}return 
r.prototype=Object.create(t.prototype,{constructor:{value:r,enumerable:!1,writable:!0,configurable:!0}}),l(r,t)},f(t)}var
 d,u,p,s=function(){var o,n=(o=i().m(function t(o){var 
n,c,l,d,u,p,s,m,g,h,b,y,v,x,k,O;return i().w(function(t){for(;;)
 switch(t.p=t.n){case 0:n=function(t){function o(){var t;r(this,o);var 
a=(t=e(this,o)).attachShadow({mode:"open"}),n=document.createElement("style");return
 n.textContent="\n      :host {\n        display: block;\n        line-height: 
initial;\n        font-size: 16px;\n      }\n      div.diagram {\n        
margin: 0;\n        overflow: visible;\n      }",a.appendChild(n),t}return 
a(o,t),n=o,Object.defineProperty(n,"prototype",{writable:!1}),n;var 
n}(f(HTMLElement)),void 
0===customElements.get("diagram-div")&&customElements.define("diagram-div",n),c=function(t){for(var
 e="",r=0;r<t.childNodes.length;r++){var 
o=t.childNodes[r];if("code"===o.tagName.toLowerCase())for(var 
a=0;a<o.childNodes.length;a++){var 
n=o.childNodes[a];if("#text"===n.nodeName&&!/^\s*$/.test(n.nodeValue)){e=n.nodeValue;break}}}return
 
e},l={startOnLoad:!1,theme:"default",flowchart:{useMaxWidth:!1},er:{useMaxWidth:!1},sequence:{useMaxWidth:!1,noteFontWeight:"14px",actorFontSize:"14px",messageFontSize:"16px"}},mermaid.m
 
ermaidAPI.globalReset(),d=null;try{d=document.querySelector("[data-md-color-scheme]").getAttribute("data-md-color-scheme")}catch(t){d="slate"}u="undefined"==typeof
 
mermaidConfig?l:mermaidConfig[d]||mermaidConfig.default||l,mermaid.initialize(u),p=document.querySelectorAll("pre.".concat(o,",
 diagram-div")),s=document.querySelector("html body"),m=0;case 
1:if(!(m<p.length)){t.n=7;break}return 
g=p[m],h="diagram-div"===g.tagName.toLowerCase()?g.shadowRoot.querySelector("pre.".concat(o)):g,(b=document.createElement("div")).style.visibility="hidden",b.style.display="display",b.style.padding="0",b.style.margin="0",b.style.lineHeight="initial",b.style.fontSize="16px",s.appendChild(b),t.p=2,t.n=3,mermaid.render("_diagram_".concat(m),c(h),b);case
 
3:y=t.v,v=y.svg,x=y.bindFunctions,(k=document.createElement("div")).className=o,k.innerHTML=v,x&&x(k),(O=document.createElement("diagram-div")).shadowRoot.appendChild(k),g.parentNode.insertBefore(O,g),h.style.display="none",O.shadowRoot.appendChild(h)
 ,h!==g&&g.parentNode.removeChild(g),t.n=5;break;case 4:t.p=4,t.v;case 
5:s.contains(b)&&s.removeChild(b);case 6:m++,t.n=1;break;case 7:return 
t.a(2)}},t,null,[[2,4]])}),function(){var e=this,r=arguments;return new 
Promise(function(a,n){var i=o.apply(e,r);function 
c(e){t(i,a,n,c,l,"next",e)}function l(e){t(i,a,n,c,l,"throw",e)}c(void 
0)})});return function(t){return 
n.apply(this,arguments)}}(),m=function(t,e){if("katex"===e)for(var 
r=document.querySelectorAll(".".concat(t)),o=0;o<r.length;o++){var 
a=r[o].textContent||r[o].innerText;a.startsWith("\\(")&&a.endsWith("\\)")?katex.render(a.slice(2,-2),r[o],{displayMode:!1}):a.startsWith("\\[")&&a.endsWith("\\]")&&katex.render(a.slice(2,-2),r[o],{displayMode:!0})}else"mathjax"===e&&(void
 
0!==MathJax.startup.output.clearCache&&MathJax.startup.output.clearCache(),MathJax.typesetClear(),MathJax.texReset(),MathJax.typesetPromise())};"mathjaxConfig"in
 
window||(window.MathJax={tex:{inlineMath:[["\\(","\\)"]],displayMath:[["\\[","\\]"]],processEsc
 
apes:!0,processEnvironments:!0,tagSide:"right",tagIndent:".8em",multlineWidth:"85%",tags:"ams"},options:{ignoreHtmlClass:".*",processHtmlClass:"arithmatex"}}),"mermaidConfig"in
 window||(window.mermaidConfig={slate:{startOnLoad:!1,theme:"base",themeCSS:"   
     * {          --drac-page-bg: hsl(233, 15%, 23%);          --drac-white-fg: 
hsl(60, 30%, 96%);          --drac-purple-fg: hsl(265, 89%, 78%);          
--drac-purple-bg: hsl(265, 25%, 39%);          --drac-yellow-fg: hsl(65, 92%, 
76%);          --drac-blue-fg: hsl(225, 27%, 51%);        }                /* 
General */        [id^='_diagram'] {          background-color: 
var(--drac-page-bg);        }                /* Entity Relationship */        
rect.relationshipLabelBox {          opacity: 0.75 !important;          fill: 
var(--drac-purple-bg) !important;        }        defs marker#ZERO_OR_MORE_END 
circle {          fill: var(--drac-page-bg) !important;          stroke: 
var(--drac-purple-fg) !important;        }        defs mar
 ker#ZERO_OR_MORE_END path {          stroke: var(--drac-purple-fg) !important; 
       }        defs marker#ZERO_OR_MORE_START circle{          fill: 
var(--drac-page-bg) !important;          stroke: var(--drac-purple-fg) 
!important;        }        defs marker#ZERO_OR_MORE_START path {          
stroke: var(--drac-purple-fg) !important;        }        defs 
marker#ONLY_ONE_START path {          stroke: var(--drac-purple-fg) !important; 
       }        defs marker#ONLY_ONE_END path {          stroke: 
var(--drac-purple-fg) !important;        }        defs marker#ZERO_OR_ONE_START 
path {          stroke: var(--drac-purple-fg) !important;        }        defs 
marker#ZERO_OR_ONE_END path {          stroke: var(--drac-purple-fg) 
!important;        }        defs marker#ONE_OR_MORE_START path {          
stroke: var(--drac-purple-fg) !important;        }        defs 
marker#ONE_OR_MORE_END path {          stroke: var(--drac-purple-fg) 
!important;        }                /* Flowchart */        .
 labelText,        :not(.branchLabel) > .label text {          fill: 
var(--drac-purple-fg);        }        .edgeLabel text {          fill: 
var(--drac-purple-fg) !important;        }        .edgeLabel rect {          
opacity: 0.75 !important;          fill: var(--drac-purple-bg) !important;      
  }                .grey rect.label-container {           fill: 
var(--drac-purple-bg) !important;          stroke: var(--drac-purple-fg) 
!important;        }         /* Sequence */        line[id^='actor'] {          
stroke: var(--drac-blue-fg);        }        .noteText {          fill: 
var(--drac-yellow-fg);        }                /* Gantt */        .sectionTitle 
{          fill: var(--drac-purple-fg) !important;        }                
.grid .tick line {          stroke: var(--drac-blue-fg) !important;        }    
            .grid .tick text {          fill: var(--drac-purple-fg);        }   
             /* Class Diagram */        .statediagram-state rect.divider {      
    fill: transp
 arent !important;        }                /* State Diagram */        
.stateGroup circle[style$=\"fill: black;\"] {          fill: 
var(--drac-purple-bg) !important;          stroke: var(--drac-purple-bg) 
!important;        }                .stateGroup circle[style$=\"fill: white;\"] 
{          fill: var(--drac-purple-bg) !important;          stroke: 
var(--drac-purple-fg) !important;        }                .stateGroup .composit 
{          fill: var(--drac-page-bg);        }        /* Pie */        
text.slice {          fill: var(--drac-white-fg) !important;        }        /* 
Git Graph */        .commit-bullets .commit-reverse,        .commit-bullets 
.commit-merge,         .commit-bullets .commit-highlight-inner {          fill: 
var(--drac-page-bg) !important;          stroke: var(--drac-page-bg) 
!important;        }        
",themeVariables:{darkMode:!0,background:"#323443",mainBkg:"#604b7d",textColor:"#bf95f9",lineColor:"#bf95f9",errorBkgColor:"#802c2c",errorTextColor:"#ff5757",prim
 
aryColor:"#604b7d",primaryTextColor:"#bf95f9",primaryBorderColor:"#bf95f9",secondaryColor:"#297d3e",secondaryTextColor:"#52fa7c",secondaryBorderColor:"#52fa7c",tertiaryColor:"#303952",tertiaryTextColor:"#6071a4",tertiaryBorderColor:"#6071a4",noteBkgColor:"#797d45",noteTextColor:"#f1fa89",noteBorderColor:"#f1fa89",edgeLabelBackground:"#604b7d",edgeLabelText:"#604b7d",actorLineColor:"#6071a4",activeTaskBkgColor:"#803d63",activeTaskBorderColor:"#ff7ac6",doneTaskBkgColor:"#297d3e",doneTaskBorderColor:"#52fa7c",critBkgColor:"#802c2c",critBorderColor:"#ff5757",taskTextColor:"#bf95f9",taskTextOutsideColor:"#bf95f9",taskTextLightColor:"#bf95f9",sectionBkgColor:"#bf95f9b3",sectionBkgColor2:"#bf95f966",altSectionBkgColor:"#323443",todayLineColor:"#ff7ac6",gridColor:"#6071a4",defaultLinkColor:"#8be8fd",altBackground:"#bf95f9",classText:"#bf95f9",fillType0:"#406080",fillType1:"#46747f",fillType2:"#297d3e",fillType3:"#805c36",fillType4:"#803d63",fillType5:"#604b7d",fillType6:"#802c2c",fillType7:
 
"#797d45",fillType8:"#7c7c79",git0:"#ff5555",git1:"#ffb86c",git2:"#f1fa8c",git3:"#50fa7b",git4:"#8be9fd",git5:"#809fff",git6:"#ff79c6",git7:"#bd93f9",gitInv0:"#ff5555",gitInv1:"#ffb86c",gitInv2:"#f1fa8c",gitInv3:"#50fa7b",gitInv4:"#8be9fd",gitInv5:"#809fff",gitInv6:"#ff79c6",gitInv7:"#bd93f9",gitBranchLabel0:"#323443",gitBranchLabel1:"#323443",gitBranchLabel2:"#323443",gitBranchLabel3:"#323443",gitBranchLabel4:"#323443",gitBranchLabel5:"#323443",gitBranchLabel6:"#323443",gitBranchLabel7:"#323443",commitLabelColor:"#52fa7c",commitLabelBackground:"#297d3e"},flowchart:{useMaxWidth:!1},er:{useMaxWidth:!1},sequence:{useMaxWidth:!1,noteFontWeight:"14px",actorFontSize:"14px",messageFontSize:"16px"},journey:{useMaxWidth:!1},pie:{useMaxWidth:!1},gantt:{useMaxWidth:!1},gitGraph:{useMaxWidth:!1}},default:{startOnLoad:!1,theme:"default",flowchart:{useMaxWidth:!1},er:{useMaxWidth:!1},sequence:{useMaxWidth:!1,noteFontWeight:"14px",actorFontSize:"14px",messageFontSize:"16px"},journey:{useMaxWidth:
 
!1},pie:{useMaxWidth:!1},gantt:{useMaxWidth:!1},gitGraph:{useMaxWidth:!1}}}),d=Promise.resolve(),u=Promise.resolve(),p=new
 
MutationObserver(function(t){t.forEach(function(t){"attributes"===t.type&&(t.target.getAttribute("data-md-color-scheme"),"undefined"!=typeof
 
mermaid&&s("diagram"))})}),window.document$.subscribe(function(){p.observe(document.querySelector("body"),{attributeFilter:["data-md-color-scheme"]}),"undefined"!=typeof
 
mermaid&&(d=d.then(function(){s("diagram")}).catch(function(t){console.log("UML 
loading failed...".concat(t))})),"undefined"!=typeof 
katex?u=u.then(function(){m("arithmatex","katex")}).catch(function(t){console.log("Math
 loading failed...".concat(t))}):"undefined"!=typeof 
MathJax&&"typesetPromise"in 
MathJax&&(u=u.then(function(){m("arithmatex","mathjax")}).catch(function(t){console.log("Math
 loading failed...".concat(t))}))})}();
+//# sourceMappingURL=extra-loader-Ccztcqfq.js.map
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/bracex-2.6/docs/theme/main.html 
new/bracex-3.0/docs/theme/main.html
--- old/bracex-2.6/docs/theme/main.html 1970-01-01 01:00:00.000000000 +0100
+++ new/bracex-3.0/docs/theme/main.html 2020-02-02 01:00:00.000000000 +0100
@@ -0,0 +1,17 @@
+{% extends "base.html" %}
+
+{% block announce %}{% include "announce.html" ignore missing %}{% endblock %}
+
+{% block content %}
+  {{ super() }}
+  <footer class="sponsorship">
+    <hr>
+    <a href="https://github.com/sponsors/facelessuser"; title="Become a 
sponsor">
+      <span class="twemoji heart-throb-hover">
+        {% set icon = "octicons/heart-fill-16" %}
+        {% include ".icons/" ~ icon ~ ".svg" %}
+      </span>
+    </a>
+    <hr>
+  </footer>
+{% endblock %}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/bracex-2.6/hatch_build.py 
new/bracex-3.0/hatch_build.py
--- old/bracex-2.6/hatch_build.py       2020-02-02 01:00:00.000000000 +0100
+++ new/bracex-3.0/hatch_build.py       2020-02-02 01:00:00.000000000 +0100
@@ -28,7 +28,6 @@
             'License :: OSI Approved :: MIT License',
             'Operating System :: OS Independent',
             'Programming Language :: Python :: 3',
-            'Programming Language :: Python :: 3.9',
             'Programming Language :: Python :: 3.10',
             'Programming Language :: Python :: 3.11',
             'Programming Language :: Python :: 3.12',
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/bracex-2.6/mkdocs.yml new/bracex-3.0/mkdocs.yml
--- old/bracex-2.6/mkdocs.yml   2020-02-02 01:00:00.000000000 +0100
+++ new/bracex-3.0/mkdocs.yml   1970-01-01 01:00:00.000000000 +0100
@@ -1,157 +0,0 @@
-site_name: Bracex
-site_url: https://facelessuser.github.io/bracex
-repo_url: https://github.com/facelessuser/bracex
-edit_uri: tree/master/docs/src/markdown
-site_description: Python spell checker.
-copyright: |
-  Copyright &copy; 2018 - 2025 <a href="https://github.com/facelessuser";  
target="_blank" rel="noopener">Isaac Muse</a>
-
-docs_dir: docs/src/markdown
-theme:
-  name: material
-  custom_dir: docs/theme
-  icon:
-    logo: material/book-open-page-variant
-  palette:
-    primary: deep purple
-    accent: deep purple
-  font:
-    text: Roboto
-    code: Roboto Mono
-  features:
-    - navigation.tabs
-    - navigation.top
-    - navigation.instant
-    - navigation.indexes
-    - toc.follow
-    - content.code.copy
-    - navigation.footer
-    - search.share
-    - search.highlight
-    - search.suggest
-  pymdownx:
-    sponsor: "https://github.com/sponsors/facelessuser";
-
-nav:
-  - Home:
-    - Usage: index.md
-  - About:
-    - Contributing &amp; Support: about/contributing.md
-    - Development: about/development.md
-    - Changelog: about/changelog.md
-    - License: about/license.md
-
-markdown_extensions:
-  - markdown.extensions.toc:
-      slugify: !!python/object/apply:pymdownx.slugs.slugify {kwds: {case: 
lower}}
-      permalink: ""
-  - markdown.extensions.smarty:
-      smart_quotes: false
-  - pymdownx.betterem:
-  - markdown.extensions.attr_list:
-  - markdown.extensions.tables:
-  - markdown.extensions.abbr:
-  - markdown.extensions.footnotes:
-  - markdown.extensions.md_in_html:
-  - pymdownx.superfences:
-      preserve_tabs: true
-  - pymdownx.highlight:
-      extend_pygments_lang:
-        - name: pycon3
-          lang: pycon
-          options:
-            python3: true
-  - pymdownx.inlinehilite:
-  - pymdownx.magiclink:
-      repo_url_shortener: true
-      repo_url_shorthand: true
-      social_url_shorthand: true
-      user: facelessuser
-      repo: bracex
-  - pymdownx.tilde:
-  - pymdownx.caret:
-  - pymdownx.smartsymbols:
-  - pymdownx.emoji:
-      emoji_index: !!python/name:material.extensions.emoji.twemoji
-      emoji_generator: !!python/name:material.extensions.emoji.to_svg
-  - pymdownx.escapeall:
-      hardbreak: True
-      nbsp: True
-  - pymdownx.tasklist:
-      custom_checkbox: true
-  - pymdownx.progressbar:
-  - pymdownx.striphtml:
-  - pymdownx.snippets:
-      base_path:
-      - docs/src/markdown/.snippets
-      - LICENSE.md
-      auto_append:
-      - refs.md
-  - pymdownx.keys:
-      separator: "\uff0b"
-  - pymdownx.saneheaders:
-  - pymdownx.blocks.admonition:
-      types:
-      - new
-      - settings
-      - note
-      - abstract
-      - info
-      - tip
-      - success
-      - question
-      - warning
-      - failure
-      - danger
-      - bug
-      - example
-      - quote
-  - pymdownx.blocks.details:
-      types:
-      - name: details-new
-        class: new
-      - name: details-settings
-        class: settings
-      - name: details-note
-        class: note
-      - name: details-abstract
-        class: abstract
-      - name: details-info
-        class: info
-      - name: details-tip
-        class: tip
-      - name: details-success
-        class: success
-      - name: details-question
-        class: question
-      - name: details-warning
-        class: warning
-      - name: details-failure
-        class: failure
-      - name: details-danger
-        class: danger
-      - name: details-bug
-        class: bug
-      - name: details-example
-        class: example
-      - name: details-quote
-        class: quote
-  - pymdownx.blocks.html:
-  - pymdownx.blocks.definition:
-  - pymdownx.blocks.tab:
-      alternate_style: True
-      combine_header_slug: True
-      slugify: !!python/object/apply:pymdownx.slugs.slugify {kwds: {case: 
lower}}
-
-extra:
-  social:
-    - icon: fontawesome/brands/github
-      link: https://github.com/facelessuser
-
-plugins:
-  - search
-  - git-revision-date-localized:
-      fallback_to_build_date: true
-  - mkdocs_pymdownx_material_extras
-  - minify:
-      minify_html: true
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/bracex-2.6/pyproject.toml 
new/bracex-3.0/pyproject.toml
--- old/bracex-2.6/pyproject.toml       2020-02-02 01:00:00.000000000 +0100
+++ new/bracex-3.0/pyproject.toml       2020-02-02 01:00:00.000000000 +0100
@@ -9,7 +9,7 @@
 description = "Bash style brace expander."
 readme = "README.md"
 license = "MIT"
-requires-python = ">=3.9"
+requires-python = ">=3.10"
 authors = [
     { name = "Isaac Muse", email = "[email protected]" },
 ]
@@ -133,6 +133,6 @@
 deps=
     -rrequirements/docs.txt
 commands=
-    mkdocs build --clean --verbose --strict
-    pyspelling
+    "{envpython}" -m zensical.main build -f zensical.yml --clean --strict
+    "{envpython}" -m pyspelling
 """
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/bracex-2.6/requirements/docs.txt 
new/bracex-3.0/requirements/docs.txt
--- old/bracex-2.6/requirements/docs.txt        2020-02-02 01:00:00.000000000 
+0100
+++ new/bracex-3.0/requirements/docs.txt        2020-02-02 01:00:00.000000000 
+0100
@@ -1,4 +1,4 @@
-mkdocs_pymdownx_material_extras>=2.0
-mkdocs-git-revision-date-localized-plugin
-mkdocs-minify-plugin
+zensical
+pymdown_lexers @ git+https://github.com/facelessuser/pymdown-lexers.git
 pyspelling
+build
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/bracex-2.6/tests/brace-cases.txt 
new/bracex-3.0/tests/brace-cases.txt
--- old/bracex-2.6/tests/brace-cases.txt        2020-02-02 01:00:00.000000000 
+0100
+++ new/bracex-3.0/tests/brace-cases.txt        2020-02-02 01:00:00.000000000 
+0100
@@ -191,3 +191,10 @@
 {1..10..-0}
 {a..d..0}
 {a..d..-0}
+# empty slot cases
+{,a,b}
+{a,b,}
+{a,,b}
+# Open braces
+x{
+x{{
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/bracex-2.6/tests/brace-results.txt 
new/bracex-3.0/tests/brace-results.txt
--- old/bracex-2.6/tests/brace-results.txt      2020-02-02 01:00:00.000000000 
+0100
+++ new/bracex-3.0/tests/brace-results.txt      2020-02-02 01:00:00.000000000 
+0100
@@ -1109,4 +1109,12 @@
 [a]
 [b]
 [c]
-[d]><><><><
\ No newline at end of file
+[d]><><><><{,a,b}
+[a]
+[b]><><><><{a,b,}
+[a]
+[b]><><><><{a,,b}
+[a]
+[b]><><><><x{
+[x{]><><><><x{{
+[x{{]><><><><
\ No newline at end of file
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/bracex-2.6/tests/generate.sh 
new/bracex-3.0/tests/generate.sh
--- old/bracex-2.6/tests/generate.sh    2020-02-02 01:00:00.000000000 +0100
+++ new/bracex-3.0/tests/generate.sh    2020-02-02 01:00:00.000000000 +0100
@@ -3,7 +3,7 @@
 set -e
 
 # Bash 4.3 - 5.0 because of arbitrary need to pick a single standard.
-if ! [[ "${BASH_VERSINFO[0]}.${BASH_VERSINFO[1]}" =~ 
(4\.[^1-2]|5\.[0-2])(\.\d+)? ]]; then
+if ! [[ "${BASH_VERSINFO[0]}.${BASH_VERSINFO[1]}" =~ 
(4\.[^1-2]|5\.[0-3])(\.\d+)? ]]; then
   echo "this script requires bash 4.3, 4.4, or 5.0" >&2
   exit 1
 fi
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/bracex-2.6/tests/test_brace.py 
new/bracex-3.0/tests/test_brace.py
--- old/bracex-2.6/tests/test_brace.py  2020-02-02 01:00:00.000000000 +0100
+++ new/bracex-3.0/tests/test_brace.py  2020-02-02 01:00:00.000000000 +0100
@@ -5,11 +5,14 @@
 The project contained great tests that mirror Bash 4.3's behavior.  And while 
this library
 was written independently, we used their test sweet to bring this up to Bash 
4.3 standard.
 """
+import sys
 import unittest
 import pytest
 import bracex
 import ast
 import re
+import subprocess
+import textwrap
 
 RE_REMOVE = re.compile(r'^\[|\]$')
 BRE_REMOVE = re.compile(br'^\[|\]$')
@@ -52,8 +55,8 @@
 
     empty_cases = [
         ['-v{,,,,}', ['-v', '-v', '-v', '-v', '-v']],
-        ['{,,}', ['']],
-        ['', ['']]
+        ['{,,}', []],
+        ['', []]
     ]
 
     negative_incr_cases = [
@@ -206,6 +209,49 @@
                 index += 1
 
 
+class TestMisc(unittest.TestCase):
+    """Test miscellaneous cases."""
+
+    def test_brace_free_string_returns_itself(self):
+        """A string with no brace meta-characters must expand to [itself] 
regardless of length (no recursion error)."""
+
+        old = sys.getrecursionlimit()
+        sys.setrecursionlimit(1000)
+        try:
+            s = "a" * 4000
+            assert bracex.expand(s) == [s]
+        finally:
+            sys.setrecursionlimit(old)
+
+    def test_unbalanced_braces_parse_is_not_exponential(self):
+        """
+        Parsing N unmatched '{' must not invoke the parser 2**(N-1) times.
+
+        A bounded parser is roughly linear in input length.
+        """
+
+        EB = bracex.ExpandBrace
+        original = EB.get_sequence
+        calls = [0]
+
+        def counting(self, *args, **kwargs):
+            calls[0] += 1
+            return original(self, *args, **kwargs)
+
+        EB.get_sequence = counting
+        try:
+            n = 16
+            bracex.expand("{" * n)
+            assert calls[0] < 100 * n, calls[0]  # 2**15 == 32768 on a 
vulnerable build
+        finally:
+            EB.get_sequence = original
+
+    def test_empty_return(self):
+        """Return at least `[""]` if there are no expansions."""
+
+        self.assertEqual(bracex.expand('{,,,}', return_empty=True), [''])
+
+
 class TestExpansionLimit(unittest.TestCase):
     """Test brace expansion limit."""
 
@@ -402,3 +448,78 @@
         self.assertEqual(len(bracex.expand('{-11..-11..-7}', limit=1)), 1)
         with self.assertRaises(bracex.ExpansionLimitException):
             bracex.expand('{-11..-1..-7}', limit=1)
+
+    def test_empty_start_slot(self):
+        """Test when starting slot is empty."""
+
+        self.assertEqual(len(bracex.expand('a{1,2,}', limit=3)), 3)
+        with self.assertRaises(bracex.ExpansionLimitException):
+            bracex.expand('a{,1,2}', limit=2)
+
+    def test_empty_end_slot(self):
+        """Test when ending slot is empty."""
+
+        self.assertEqual(len(bracex.expand('a{1,2,}', limit=3)), 3)
+        with self.assertRaises(bracex.ExpansionLimitException):
+            bracex.expand('a{1,2,}', limit=2)
+
+    def test_empty_middle_slot(self):
+        """Test when middle slot is empty."""
+
+        self.assertEqual(len(bracex.expand('a{1,,2}', limit=3)), 3)
+        with self.assertRaises(bracex.ExpansionLimitException):
+            bracex.expand('a{1,,2}', limit=2)
+
+    def test_empty_braces(self):
+        """Test empty braces."""
+
+        self.assertEqual(len(bracex.expand('{}{}{}', limit=1)), 1)
+
+    def test_limit_is_enforced_for_empty_slots(self):
+        """
+        Empty comma slots must be counted.
+
+        An input that yields 5001 results under limit=1000 must raise, not 
return silently.
+        """
+
+        with self.assertRaises(bracex.ExpansionLimitException):
+            bracex.expand("-v{" + "," * 5000 + "}", limit=1000)
+
+    def test_empty_group_does_not_zero_a_counted_sibling(self):
+        """An empty group must not multiply a counted range down to zero."""
+
+        with self.assertRaises(bracex.ExpansionLimitException):
+            bracex.expand("{1..50}{" + "," * 30 + "}", limit=1000)  # 1550 > 
1000
+
+    def test_bogus_group_does_not_bypass_limit(self):
+        """64 expansions at limit=63 must raise despite bogus group."""
+
+        self.assertEqual(len(bracex.expand("{12..9}{b}{3..6}{e..b}", 
limit=64)), 64)
+        with pytest.raises(bracex.ExpansionLimitException):
+            bracex.expand("{12..9}{b}{3..6}{e..b}", limit=63)
+
+    def test_many_commas_do_not_crash_the_interpreter(self):
+        """
+        A deeply nested `itertools.chain` must not overflow the C stack.
+
+        Run in a child interpreter with a 256 KiB thread stack; an uncatchable
+        crash shows up as a negative return code. limit=1 demonstrates that the
+        empty-slot count bypass defeats the limit entirely.
+        """
+
+        code = textwrap.dedent(
+            """
+            import threading, bracex
+            threading.stack_size(256 * 1024)
+            def run():
+                try:
+                    bracex.expand('{' + ',' * 40000 + '}', limit=1)
+                except bracex.ExpansionLimitException:
+                    pass
+            t = threading.Thread(target=run)
+            t.start(); t.join()
+            """
+        )
+
+        cp = subprocess.run([sys.executable, "-c", code], capture_output=True, 
timeout=60)
+        assert cp.returncode == 0, f"interpreter crashed: 
returncode={cp.returncode}"

Reply via email to