a|b|rc)(?P\d+))?
+ (?:\.post(?P\d+))?
+ (?:\.dev(?P\d+))?
+ '''
+)
+
+REL_MAP = {
+ ".dev": "",
+ ".dev-alpha": "a",
+ ".dev-beta": "b",
+ ".dev-candidate": "rc",
+ "alpha": "a",
+ "beta": "b",
+ "candidate": "rc",
+ "final": ""
+}
+
+DEV_STATUS = {
+ ".dev": "2 - Pre-Alpha",
+ ".dev-alpha": "2 - Pre-Alpha",
+ ".dev-beta": "2 - Pre-Alpha",
+ ".dev-candidate": "2 - Pre-Alpha",
+ "alpha": "3 - Alpha",
+ "beta": "4 - Beta",
+ "candidate": "4 - Beta",
+ "final": "5 - Production/Stable"
+}
+
+PRE_REL_MAP = {"a": 'alpha', "b": 'beta', "rc": 'candidate'}
+
+
+class Version(namedtuple("Version", ["major", "minor", "micro", "release", "pre", "post", "dev"])):
+ """
+ Get the version (PEP 440).
+
+ A biased approach to the PEP 440 semantic version.
+
+ Provides a tuple structure which is sorted for comparisons `v1 > v2` etc.
+ (major, minor, micro, release type, pre-release build, post-release build, development release build)
+ Release types are named in is such a way they are comparable with ease.
+ Accessors to check if a development, pre-release, or post-release build. Also provides accessor to get
+ development status for setup files.
+
+ How it works (currently):
+
+ - You must specify a release type as either `final`, `alpha`, `beta`, or `candidate`.
+ - To define a development release, you can use either `.dev`, `.dev-alpha`, `.dev-beta`, or `.dev-candidate`.
+ The dot is used to ensure all development specifiers are sorted before `alpha`.
+ You can specify a `dev` number for development builds, but do not have to as implicit development releases
+ are allowed.
+ - You must specify a `pre` value greater than zero if using a prerelease as this project (not PEP 440) does not
+ allow implicit prereleases.
+ - You can optionally set `post` to a value greater than zero to make the build a post release. While post releases
+ are technically allowed in prereleases, it is strongly discouraged, so we are rejecting them. It should be
+ noted that we do not allow `post0` even though PEP 440 does not restrict this. This project specifically
+ does not allow implicit post releases.
+ - It should be noted that we do not support epochs `1!` or local versions `+some-custom.version-1`.
+
+ Acceptable version releases:
+
+ ```
+ Version(1, 0, 0, "final") 1.0
+ Version(1, 2, 0, "final") 1.2
+ Version(1, 2, 3, "final") 1.2.3
+ Version(1, 2, 0, ".dev-alpha", pre=4) 1.2a4
+ Version(1, 2, 0, ".dev-beta", pre=4) 1.2b4
+ Version(1, 2, 0, ".dev-candidate", pre=4) 1.2rc4
+ Version(1, 2, 0, "final", post=1) 1.2.post1
+ Version(1, 2, 3, ".dev") 1.2.3.dev0
+ Version(1, 2, 3, ".dev", dev=1) 1.2.3.dev1
+ ```
+
+ """
+
+ def __new__(cls, major, minor, micro, release="final", pre=0, post=0, dev=0):
+ """Validate version info."""
+
+ # Ensure all parts are positive integers.
+ for value in (major, minor, micro, pre, post):
+ if not (isinstance(value, int) and value >= 0):
+ raise ValueError("All version parts except 'release' should be integers.")
+
+ if release not in REL_MAP:
+ raise ValueError("'{}' is not a valid release type.".format(release))
+
+ # Ensure valid pre-release (we do not allow implicit pre-releases).
+ if ".dev-candidate" < release < "final":
+ if pre == 0:
+ raise ValueError("Implicit pre-releases not allowed.")
+ elif dev:
+ raise ValueError("Version is not a development release.")
+ elif post:
+ raise ValueError("Post-releases are not allowed with pre-releases.")
+
+ # Ensure valid development or development/pre release
+ elif release < "alpha":
+ if release > ".dev" and pre == 0:
+ raise ValueError("Implicit pre-release not allowed.")
+ elif post:
+ raise ValueError("Post-releases are not allowed with pre-releases.")
+
+ # Ensure a valid normal release
+ else:
+ if pre:
+ raise ValueError("Version is not a pre-release.")
+ elif dev:
+ raise ValueError("Version is not a development release.")
+
+ return super().__new__(cls, major, minor, micro, release, pre, post, dev)
+
+ def _is_pre(self):
+ """Is prerelease."""
+
+ return self.pre > 0
+
+ def _is_dev(self):
+ """Is development."""
+
+ return bool(self.release < "alpha")
+
+ def _is_post(self):
+ """Is post."""
+
+ return self.post > 0
+
+ def _get_dev_status(self): # pragma: no cover
+ """Get development status string."""
+
+ return DEV_STATUS[self.release]
+
+ def _get_canonical(self):
+ """Get the canonical output string."""
+
+ # Assemble major, minor, micro version and append `pre`, `post`, or `dev` if needed..
+ if self.micro == 0:
+ ver = "{}.{}".format(self.major, self.minor)
+ else:
+ ver = "{}.{}.{}".format(self.major, self.minor, self.micro)
+ if self._is_pre():
+ ver += '{}{}'.format(REL_MAP[self.release], self.pre)
+ if self._is_post():
+ ver += ".post{}".format(self.post)
+ if self._is_dev():
+ ver += ".dev{}".format(self.dev)
+
+ return ver
+
+
+def parse_version(ver, pre=False):
+ """Parse version into a comparable Version tuple."""
+
+ m = RE_VER.match(ver)
+
+ # Handle major, minor, micro
+ major = int(m.group('major'))
+ minor = int(m.group('minor')) if m.group('minor') else 0
+ micro = int(m.group('micro')) if m.group('micro') else 0
+
+ # Handle pre releases
+ if m.group('type'):
+ release = PRE_REL_MAP[m.group('type')]
+ pre = int(m.group('pre'))
+ else:
+ release = "final"
+ pre = 0
+
+ # Handle development releases
+ dev = m.group('dev') if m.group('dev') else 0
+ if m.group('dev'):
+ dev = int(m.group('dev'))
+ release = '.dev-' + release if pre else '.dev'
+ else:
+ dev = 0
+
+ # Handle post
+ post = int(m.group('post')) if m.group('post') else 0
+
+ return Version(major, minor, micro, release, pre, post, dev)
+
+
+class Pep562:
+ """
+ Backport of PEP 562 .
+
+ Wraps the module in a class that exposes the mechanics to override `__dir__` and `__getattr__`.
+ The given module will be searched for overrides of `__dir__` and `__getattr__` and use them when needed.
+ """
+
+ def __init__(self, name):
+ """Acquire `__getattr__` and `__dir__`, but only replace module for versions less than Python 3.7."""
+
+ self._module = sys.modules[name]
+ self._get_attr = getattr(self._module, '__getattr__', None)
+ self._get_dir = getattr(self._module, '__dir__', None)
+ sys.modules[name] = self
+
+ def __dir__(self):
+ """Return the overridden `dir` if one was provided, else apply `dir` to the module."""
+
+ return self._get_dir() if self._get_dir else dir(self._module)
+
+ def __getattr__(self, name):
+ """Attempt to retrieve the attribute from the module, and if missing, use the overridden function if present."""
+
+ try:
+ return getattr(self._module, name)
+ except AttributeError:
+ if self._get_attr:
+ return self._get_attr(name)
+ raise
+
+
+__version_info__ = Version(1, 0, 0, "final")
+__version__ = __version_info__._get_canonical()
diff --git a/venv/lib/python3.11/site-packages/markdown/postprocessors.py b/venv/lib/python3.11/site-packages/markdown/postprocessors.py
new file mode 100644
index 0000000..f4fb924
--- /dev/null
+++ b/venv/lib/python3.11/site-packages/markdown/postprocessors.py
@@ -0,0 +1,134 @@
+"""
+Python Markdown
+
+A Python implementation of John Gruber's Markdown.
+
+Documentation: https://python-markdown.github.io/
+GitHub: https://github.com/Python-Markdown/markdown/
+PyPI: https://pypi.org/project/Markdown/
+
+Started by Manfred Stienstra (http://www.dwerg.net/).
+Maintained for a few years by Yuri Takhteyev (http://www.freewisdom.org).
+Currently maintained by Waylan Limberg (https://github.com/waylan),
+Dmitry Shachnev (https://github.com/mitya57) and Isaac Muse (https://github.com/facelessuser).
+
+Copyright 2007-2018 The Python Markdown Project (v. 1.7 and later)
+Copyright 2004, 2005, 2006 Yuri Takhteyev (v. 0.2-1.6b)
+Copyright 2004 Manfred Stienstra (the original version)
+
+License: BSD (see LICENSE.md for details).
+
+POST-PROCESSORS
+=============================================================================
+
+Markdown also allows post-processors, which are similar to preprocessors in
+that they need to implement a "run" method. However, they are run after core
+processing.
+
+"""
+
+from collections import OrderedDict
+from . import util
+import re
+
+
+def build_postprocessors(md, **kwargs):
+ """ Build the default postprocessors for Markdown. """
+ postprocessors = util.Registry()
+ postprocessors.register(RawHtmlPostprocessor(md), 'raw_html', 30)
+ postprocessors.register(AndSubstitutePostprocessor(), 'amp_substitute', 20)
+ postprocessors.register(UnescapePostprocessor(), 'unescape', 10)
+ return postprocessors
+
+
+class Postprocessor(util.Processor):
+ """
+ Postprocessors are run after the ElementTree it converted back into text.
+
+ Each Postprocessor implements a "run" method that takes a pointer to a
+ text string, modifies it as necessary and returns a text string.
+
+ Postprocessors must extend markdown.Postprocessor.
+
+ """
+
+ def run(self, text):
+ """
+ Subclasses of Postprocessor should implement a `run` method, which
+ takes the html document as a single text string and returns a
+ (possibly modified) string.
+
+ """
+ pass # pragma: no cover
+
+
+class RawHtmlPostprocessor(Postprocessor):
+ """ Restore raw html to the document. """
+
+ BLOCK_LEVEL_REGEX = re.compile(r'^\<\/?([^ >]+)')
+
+ def run(self, text):
+ """ Iterate over html stash and restore html. """
+ replacements = OrderedDict()
+ for i in range(self.md.htmlStash.html_counter):
+ html = self.stash_to_string(self.md.htmlStash.rawHtmlBlocks[i])
+ if self.isblocklevel(html):
+ replacements["{}
".format(
+ self.md.htmlStash.get_placeholder(i))] = html
+ replacements[self.md.htmlStash.get_placeholder(i)] = html
+
+ def substitute_match(m):
+ key = m.group(0)
+
+ if key not in replacements:
+ if key[3:-4] in replacements:
+ return f'{ replacements[key[3:-4]] }
'
+ else:
+ return key
+
+ return replacements[key]
+
+ if replacements:
+ base_placeholder = util.HTML_PLACEHOLDER % r'([0-9]+)'
+ pattern = re.compile(f'{ base_placeholder }
|{ base_placeholder }')
+ processed_text = pattern.sub(substitute_match, text)
+ else:
+ return text
+
+ if processed_text == text:
+ return processed_text
+ else:
+ return self.run(processed_text)
+
+ def isblocklevel(self, html):
+ m = self.BLOCK_LEVEL_REGEX.match(html)
+ if m:
+ if m.group(1)[0] in ('!', '?', '@', '%'):
+ # Comment, php etc...
+ return True
+ return self.md.is_block_level(m.group(1))
+ return False
+
+ def stash_to_string(self, text):
+ """ Convert a stashed object to a string. """
+ return str(text)
+
+
+class AndSubstitutePostprocessor(Postprocessor):
+ """ Restore valid entities """
+
+ def run(self, text):
+ text = text.replace(util.AMP_SUBSTITUTE, "&")
+ return text
+
+
+class UnescapePostprocessor(Postprocessor):
+ """ Restore escaped chars """
+
+ RE = re.compile(r'{}(\d+){}'.format(util.STX, util.ETX))
+
+ def unescape(self, m):
+ return chr(int(m.group(1)))
+
+ def run(self, text):
+ return self.RE.sub(self.unescape, text)
diff --git a/venv/lib/python3.11/site-packages/markdown/preprocessors.py b/venv/lib/python3.11/site-packages/markdown/preprocessors.py
new file mode 100644
index 0000000..e1023c5
--- /dev/null
+++ b/venv/lib/python3.11/site-packages/markdown/preprocessors.py
@@ -0,0 +1,82 @@
+"""
+Python Markdown
+
+A Python implementation of John Gruber's Markdown.
+
+Documentation: https://python-markdown.github.io/
+GitHub: https://github.com/Python-Markdown/markdown/
+PyPI: https://pypi.org/project/Markdown/
+
+Started by Manfred Stienstra (http://www.dwerg.net/).
+Maintained for a few years by Yuri Takhteyev (http://www.freewisdom.org).
+Currently maintained by Waylan Limberg (https://github.com/waylan),
+Dmitry Shachnev (https://github.com/mitya57) and Isaac Muse (https://github.com/facelessuser).
+
+Copyright 2007-2018 The Python Markdown Project (v. 1.7 and later)
+Copyright 2004, 2005, 2006 Yuri Takhteyev (v. 0.2-1.6b)
+Copyright 2004 Manfred Stienstra (the original version)
+
+License: BSD (see LICENSE.md for details).
+
+PRE-PROCESSORS
+=============================================================================
+
+Preprocessors work on source text before we start doing anything too
+complicated.
+"""
+
+from . import util
+from .htmlparser import HTMLExtractor
+import re
+
+
+def build_preprocessors(md, **kwargs):
+ """ Build the default set of preprocessors used by Markdown. """
+ preprocessors = util.Registry()
+ preprocessors.register(NormalizeWhitespace(md), 'normalize_whitespace', 30)
+ preprocessors.register(HtmlBlockPreprocessor(md), 'html_block', 20)
+ return preprocessors
+
+
+class Preprocessor(util.Processor):
+ """
+ Preprocessors are run after the text is broken into lines.
+
+ Each preprocessor implements a "run" method that takes a pointer to a
+ list of lines of the document, modifies it as necessary and returns
+ either the same pointer or a pointer to a new list.
+
+ Preprocessors must extend markdown.Preprocessor.
+
+ """
+ def run(self, lines):
+ """
+ Each subclass of Preprocessor should override the `run` method, which
+ takes the document as a list of strings split by newlines and returns
+ the (possibly modified) list of lines.
+
+ """
+ pass # pragma: no cover
+
+
+class NormalizeWhitespace(Preprocessor):
+ """ Normalize whitespace for consistent parsing. """
+
+ def run(self, lines):
+ source = '\n'.join(lines)
+ source = source.replace(util.STX, "").replace(util.ETX, "")
+ source = source.replace("\r\n", "\n").replace("\r", "\n") + "\n\n"
+ source = source.expandtabs(self.md.tab_length)
+ source = re.sub(r'(?<=\n) +\n', '\n', source)
+ return source.split('\n')
+
+
+class HtmlBlockPreprocessor(Preprocessor):
+ """Remove html blocks from the text and store them for later retrieval."""
+
+ def run(self, lines):
+ source = '\n'.join(lines)
+ parser = HTMLExtractor(self.md)
+ parser.feed(source)
+ parser.close()
+ return ''.join(parser.cleandoc).split('\n')
diff --git a/venv/lib/python3.11/site-packages/markdown/serializers.py b/venv/lib/python3.11/site-packages/markdown/serializers.py
new file mode 100644
index 0000000..59bab18
--- /dev/null
+++ b/venv/lib/python3.11/site-packages/markdown/serializers.py
@@ -0,0 +1,189 @@
+# markdown/searializers.py
+#
+# Add x/html serialization to Elementree
+# Taken from ElementTree 1.3 preview with slight modifications
+#
+# Copyright (c) 1999-2007 by Fredrik Lundh. All rights reserved.
+#
+# fredrik@pythonware.com
+# https://www.pythonware.com/
+#
+# --------------------------------------------------------------------
+# The ElementTree toolkit is
+#
+# Copyright (c) 1999-2007 by Fredrik Lundh
+#
+# By obtaining, using, and/or copying this software and/or its
+# associated documentation, you agree that you have read, understood,
+# and will comply with the following terms and conditions:
+#
+# Permission to use, copy, modify, and distribute this software and
+# its associated documentation for any purpose and without fee is
+# hereby granted, provided that the above copyright notice appears in
+# all copies, and that both that copyright notice and this permission
+# notice appear in supporting documentation, and that the name of
+# Secret Labs AB or the author not be used in advertising or publicity
+# pertaining to distribution of the software without specific, written
+# prior permission.
+#
+# SECRET LABS AB AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD
+# TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANT-
+# ABILITY AND FITNESS. IN NO EVENT SHALL SECRET LABS AB OR THE AUTHOR
+# BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
+# DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+# WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+# OF THIS SOFTWARE.
+# --------------------------------------------------------------------
+
+
+from xml.etree.ElementTree import ProcessingInstruction
+from xml.etree.ElementTree import Comment, ElementTree, QName
+import re
+
+__all__ = ['to_html_string', 'to_xhtml_string']
+
+HTML_EMPTY = ("area", "base", "basefont", "br", "col", "frame", "hr",
+ "img", "input", "isindex", "link", "meta", "param")
+RE_AMP = re.compile(r'&(?!(?:\#[0-9]+|\#x[0-9a-f]+|[0-9a-z]+);)', re.I)
+
+try:
+ HTML_EMPTY = set(HTML_EMPTY)
+except NameError: # pragma: no cover
+ pass
+
+
+def _raise_serialization_error(text): # pragma: no cover
+ raise TypeError(
+ "cannot serialize {!r} (type {})".format(text, type(text).__name__)
+ )
+
+
+def _escape_cdata(text):
+ # escape character data
+ try:
+ # it's worth avoiding do-nothing calls for strings that are
+ # shorter than 500 character, or so. assume that's, by far,
+ # the most common case in most applications.
+ if "&" in text:
+ # Only replace & when not part of an entity
+ text = RE_AMP.sub('&', text)
+ if "<" in text:
+ text = text.replace("<", "<")
+ if ">" in text:
+ text = text.replace(">", ">")
+ return text
+ except (TypeError, AttributeError): # pragma: no cover
+ _raise_serialization_error(text)
+
+
+def _escape_attrib(text):
+ # escape attribute value
+ try:
+ if "&" in text:
+ # Only replace & when not part of an entity
+ text = RE_AMP.sub('&', text)
+ if "<" in text:
+ text = text.replace("<", "<")
+ if ">" in text:
+ text = text.replace(">", ">")
+ if "\"" in text:
+ text = text.replace("\"", """)
+ if "\n" in text:
+ text = text.replace("\n", "
")
+ return text
+ except (TypeError, AttributeError): # pragma: no cover
+ _raise_serialization_error(text)
+
+
+def _escape_attrib_html(text):
+ # escape attribute value
+ try:
+ if "&" in text:
+ # Only replace & when not part of an entity
+ text = RE_AMP.sub('&', text)
+ if "<" in text:
+ text = text.replace("<", "<")
+ if ">" in text:
+ text = text.replace(">", ">")
+ if "\"" in text:
+ text = text.replace("\"", """)
+ return text
+ except (TypeError, AttributeError): # pragma: no cover
+ _raise_serialization_error(text)
+
+
+def _serialize_html(write, elem, format):
+ tag = elem.tag
+ text = elem.text
+ if tag is Comment:
+ write("" % _escape_cdata(text))
+ elif tag is ProcessingInstruction:
+ write("%s?>" % _escape_cdata(text))
+ elif tag is None:
+ if text:
+ write(_escape_cdata(text))
+ for e in elem:
+ _serialize_html(write, e, format)
+ else:
+ namespace_uri = None
+ if isinstance(tag, QName):
+ # QNAME objects store their data as a string: `{uri}tag`
+ if tag.text[:1] == "{":
+ namespace_uri, tag = tag.text[1:].split("}", 1)
+ else:
+ raise ValueError('QName objects must define a tag.')
+ write("<" + tag)
+ items = elem.items()
+ if items:
+ items = sorted(items) # lexical order
+ for k, v in items:
+ if isinstance(k, QName):
+ # Assume a text only QName
+ k = k.text
+ if isinstance(v, QName):
+ # Assume a text only QName
+ v = v.text
+ else:
+ v = _escape_attrib_html(v)
+ if k == v and format == 'html':
+ # handle boolean attributes
+ write(" %s" % v)
+ else:
+ write(' {}="{}"'.format(k, v))
+ if namespace_uri:
+ write(' xmlns="%s"' % (_escape_attrib(namespace_uri)))
+ if format == "xhtml" and tag.lower() in HTML_EMPTY:
+ write(" />")
+ else:
+ write(">")
+ if text:
+ if tag.lower() in ["script", "style"]:
+ write(text)
+ else:
+ write(_escape_cdata(text))
+ for e in elem:
+ _serialize_html(write, e, format)
+ if tag.lower() not in HTML_EMPTY:
+ write("" + tag + ">")
+ if elem.tail:
+ write(_escape_cdata(elem.tail))
+
+
+def _write_html(root, format="html"):
+ assert root is not None
+ data = []
+ write = data.append
+ _serialize_html(write, root, format)
+ return "".join(data)
+
+
+# --------------------------------------------------------------------
+# public functions
+
+def to_html_string(element):
+ return _write_html(ElementTree(element).getroot(), format="html")
+
+
+def to_xhtml_string(element):
+ return _write_html(ElementTree(element).getroot(), format="xhtml")
diff --git a/venv/lib/python3.11/site-packages/markdown/test_tools.py b/venv/lib/python3.11/site-packages/markdown/test_tools.py
new file mode 100644
index 0000000..2ce0e74
--- /dev/null
+++ b/venv/lib/python3.11/site-packages/markdown/test_tools.py
@@ -0,0 +1,220 @@
+"""
+Python Markdown
+
+A Python implementation of John Gruber's Markdown.
+
+Documentation: https://python-markdown.github.io/
+GitHub: https://github.com/Python-Markdown/markdown/
+PyPI: https://pypi.org/project/Markdown/
+
+Started by Manfred Stienstra (http://www.dwerg.net/).
+Maintained for a few years by Yuri Takhteyev (http://www.freewisdom.org).
+Currently maintained by Waylan Limberg (https://github.com/waylan),
+Dmitry Shachnev (https://github.com/mitya57) and Isaac Muse (https://github.com/facelessuser).
+
+Copyright 2007-2018 The Python Markdown Project (v. 1.7 and later)
+Copyright 2004, 2005, 2006 Yuri Takhteyev (v. 0.2-1.6b)
+Copyright 2004 Manfred Stienstra (the original version)
+
+License: BSD (see LICENSE.md for details).
+"""
+
+import os
+import sys
+import unittest
+import textwrap
+from . import markdown, Markdown, util
+
+try:
+ import tidylib
+except ImportError:
+ tidylib = None
+
+__all__ = ['TestCase', 'LegacyTestCase', 'Kwargs']
+
+
+class TestCase(unittest.TestCase):
+ """
+ A unittest.TestCase subclass with helpers for testing Markdown output.
+
+ Define `default_kwargs` as a dict of keywords to pass to Markdown for each
+ test. The defaults can be overridden on individual tests.
+
+ The `assertMarkdownRenders` method accepts the source text, the expected
+ output, and any keywords to pass to Markdown. The `default_kwargs` are used
+ except where overridden by `kwargs`. The output and expected output are passed
+ to `TestCase.assertMultiLineEqual`. An AssertionError is raised with a diff
+ if the actual output does not equal the expected output.
+
+ The `dedent` method is available to dedent triple-quoted strings if
+ necessary.
+
+ In all other respects, behaves as unittest.TestCase.
+ """
+
+ default_kwargs = {}
+
+ def assertMarkdownRenders(self, source, expected, expected_attrs=None, **kwargs):
+ """
+ Test that source Markdown text renders to expected output with given keywords.
+
+ `expected_attrs` accepts a dict. Each key should be the name of an attribute
+ on the `Markdown` instance and the value should be the expected value after
+ the source text is parsed by Markdown. After the expected output is tested,
+ the expected value for each attribute is compared against the actual
+ attribute of the `Markdown` instance using `TestCase.assertEqual`.
+ """
+
+ expected_attrs = expected_attrs or {}
+ kws = self.default_kwargs.copy()
+ kws.update(kwargs)
+ md = Markdown(**kws)
+ output = md.convert(source)
+ self.assertMultiLineEqual(output, expected)
+ for key, value in expected_attrs.items():
+ self.assertEqual(getattr(md, key), value)
+
+ def dedent(self, text):
+ """
+ Dedent text.
+ """
+
+ # TODO: If/when actual output ends with a newline, then use:
+ # return textwrap.dedent(text.strip('/n'))
+ return textwrap.dedent(text).strip()
+
+
+class recursionlimit:
+ """
+ A context manager which temporarily modifies the Python recursion limit.
+
+ The testing framework, coverage, etc. may add an arbitrary number of levels to the depth. To maintain consistency
+ in the tests, the current stack depth is determined when called, then added to the provided limit.
+
+ Example usage:
+
+ with recursionlimit(20):
+ # test code here
+
+ See https://stackoverflow.com/a/50120316/866026
+ """
+
+ def __init__(self, limit):
+ self.limit = util._get_stack_depth() + limit
+ self.old_limit = sys.getrecursionlimit()
+
+ def __enter__(self):
+ sys.setrecursionlimit(self.limit)
+
+ def __exit__(self, type, value, tb):
+ sys.setrecursionlimit(self.old_limit)
+
+
+#########################
+# Legacy Test Framework #
+#########################
+
+
+class Kwargs(dict):
+ """ A dict like class for holding keyword arguments. """
+ pass
+
+
+def _normalize_whitespace(text):
+ """ Normalize whitespace for a string of html using tidylib. """
+ output, errors = tidylib.tidy_fragment(text, options={
+ 'drop_empty_paras': 0,
+ 'fix_backslash': 0,
+ 'fix_bad_comments': 0,
+ 'fix_uri': 0,
+ 'join_styles': 0,
+ 'lower_literals': 0,
+ 'merge_divs': 0,
+ 'output_xhtml': 1,
+ 'quote_ampersand': 0,
+ 'newline': 'LF'
+ })
+ return output
+
+
+class LegacyTestMeta(type):
+ def __new__(cls, name, bases, dct):
+
+ def generate_test(infile, outfile, normalize, kwargs):
+ def test(self):
+ with open(infile, encoding="utf-8") as f:
+ input = f.read()
+ with open(outfile, encoding="utf-8") as f:
+ # Normalize line endings
+ # (on Windows, git may have altered line endings).
+ expected = f.read().replace("\r\n", "\n")
+ output = markdown(input, **kwargs)
+ if tidylib and normalize:
+ try:
+ expected = _normalize_whitespace(expected)
+ output = _normalize_whitespace(output)
+ except OSError:
+ self.skipTest("Tidylib's c library not available.")
+ elif normalize:
+ self.skipTest('Tidylib not available.')
+ self.assertMultiLineEqual(output, expected)
+ return test
+
+ location = dct.get('location', '')
+ exclude = dct.get('exclude', [])
+ normalize = dct.get('normalize', False)
+ input_ext = dct.get('input_ext', '.txt')
+ output_ext = dct.get('output_ext', '.html')
+ kwargs = dct.get('default_kwargs', Kwargs())
+
+ if os.path.isdir(location):
+ for file in os.listdir(location):
+ infile = os.path.join(location, file)
+ if os.path.isfile(infile):
+ tname, ext = os.path.splitext(file)
+ if ext == input_ext:
+ outfile = os.path.join(location, tname + output_ext)
+ tname = tname.replace(' ', '_').replace('-', '_')
+ kws = kwargs.copy()
+ if tname in dct:
+ kws.update(dct[tname])
+ test_name = 'test_%s' % tname
+ if tname not in exclude:
+ dct[test_name] = generate_test(infile, outfile, normalize, kws)
+ else:
+ dct[test_name] = unittest.skip('Excluded')(lambda: None)
+
+ return type.__new__(cls, name, bases, dct)
+
+
+class LegacyTestCase(unittest.TestCase, metaclass=LegacyTestMeta):
+ """
+ A `unittest.TestCase` subclass for running Markdown's legacy file-based tests.
+
+ A subclass should define various properties which point to a directory of
+ text-based test files and define various behaviors/defaults for those tests.
+ The following properties are supported:
+
+ location: A path to the directory of test files. An absolute path is preferred.
+ exclude: A list of tests to exclude. Each test name should comprise the filename
+ without an extension.
+ normalize: A boolean value indicating if the HTML should be normalized.
+ Default: `False`.
+ input_ext: A string containing the file extension of input files. Default: `.txt`.
+ ouput_ext: A string containing the file extension of expected output files.
+ Default: `html`.
+ default_kwargs: A `Kwargs` instance which stores the default set of keyword
+ arguments for all test files in the directory.
+
+ In addition, properties can be defined for each individual set of test files within
+ the directory. The property should be given the name of the file without the file
+ extension. Any spaces and dashes in the filename should be replaced with
+ underscores. The value of the property should be a `Kwargs` instance which
+ contains the keyword arguments that should be passed to `Markdown` for that
+ test file. The keyword arguments will "update" the `default_kwargs`.
+
+ When the class instance is created, it will walk the given directory and create
+ a separate unitttest for each set of test files using the naming scheme:
+ `test_filename`. One unittest will be run for each set of input and output files.
+ """
+ pass
diff --git a/venv/lib/python3.11/site-packages/markdown/treeprocessors.py b/venv/lib/python3.11/site-packages/markdown/treeprocessors.py
new file mode 100644
index 0000000..a475fde
--- /dev/null
+++ b/venv/lib/python3.11/site-packages/markdown/treeprocessors.py
@@ -0,0 +1,436 @@
+"""
+Python Markdown
+
+A Python implementation of John Gruber's Markdown.
+
+Documentation: https://python-markdown.github.io/
+GitHub: https://github.com/Python-Markdown/markdown/
+PyPI: https://pypi.org/project/Markdown/
+
+Started by Manfred Stienstra (http://www.dwerg.net/).
+Maintained for a few years by Yuri Takhteyev (http://www.freewisdom.org).
+Currently maintained by Waylan Limberg (https://github.com/waylan),
+Dmitry Shachnev (https://github.com/mitya57) and Isaac Muse (https://github.com/facelessuser).
+
+Copyright 2007-2018 The Python Markdown Project (v. 1.7 and later)
+Copyright 2004, 2005, 2006 Yuri Takhteyev (v. 0.2-1.6b)
+Copyright 2004 Manfred Stienstra (the original version)
+
+License: BSD (see LICENSE.md for details).
+"""
+
+import xml.etree.ElementTree as etree
+from . import util
+from . import inlinepatterns
+
+
+def build_treeprocessors(md, **kwargs):
+ """ Build the default treeprocessors for Markdown. """
+ treeprocessors = util.Registry()
+ treeprocessors.register(InlineProcessor(md), 'inline', 20)
+ treeprocessors.register(PrettifyTreeprocessor(md), 'prettify', 10)
+ return treeprocessors
+
+
+def isString(s):
+ """ Check if it's string """
+ if not isinstance(s, util.AtomicString):
+ return isinstance(s, str)
+ return False
+
+
+class Treeprocessor(util.Processor):
+ """
+ Treeprocessors are run on the ElementTree object before serialization.
+
+ Each Treeprocessor implements a "run" method that takes a pointer to an
+ ElementTree, modifies it as necessary and returns an ElementTree
+ object.
+
+ Treeprocessors must extend markdown.Treeprocessor.
+
+ """
+ def run(self, root):
+ """
+ Subclasses of Treeprocessor should implement a `run` method, which
+ takes a root ElementTree. This method can return another ElementTree
+ object, and the existing root ElementTree will be replaced, or it can
+ modify the current tree and return None.
+ """
+ pass # pragma: no cover
+
+
+class InlineProcessor(Treeprocessor):
+ """
+ A Treeprocessor that traverses a tree, applying inline patterns.
+ """
+
+ def __init__(self, md):
+ self.__placeholder_prefix = util.INLINE_PLACEHOLDER_PREFIX
+ self.__placeholder_suffix = util.ETX
+ self.__placeholder_length = 4 + len(self.__placeholder_prefix) \
+ + len(self.__placeholder_suffix)
+ self.__placeholder_re = util.INLINE_PLACEHOLDER_RE
+ self.md = md
+ self.inlinePatterns = md.inlinePatterns
+ self.ancestors = []
+
+ @property
+ @util.deprecated("Use 'md' instead.")
+ def markdown(self):
+ # TODO: remove this later
+ return self.md
+
+ def __makePlaceholder(self, type):
+ """ Generate a placeholder """
+ id = "%04d" % len(self.stashed_nodes)
+ hash = util.INLINE_PLACEHOLDER % id
+ return hash, id
+
+ def __findPlaceholder(self, data, index):
+ """
+ Extract id from data string, start from index
+
+ Keyword arguments:
+
+ * data: string
+ * index: index, from which we start search
+
+ Returns: placeholder id and string index, after the found placeholder.
+
+ """
+ m = self.__placeholder_re.search(data, index)
+ if m:
+ return m.group(1), m.end()
+ else:
+ return None, index + 1
+
+ def __stashNode(self, node, type):
+ """ Add node to stash """
+ placeholder, id = self.__makePlaceholder(type)
+ self.stashed_nodes[id] = node
+ return placeholder
+
+ def __handleInline(self, data, patternIndex=0):
+ """
+ Process string with inline patterns and replace it
+ with placeholders
+
+ Keyword arguments:
+
+ * data: A line of Markdown text
+ * patternIndex: The index of the inlinePattern to start with
+
+ Returns: String with placeholders.
+
+ """
+ if not isinstance(data, util.AtomicString):
+ startIndex = 0
+ count = len(self.inlinePatterns)
+ while patternIndex < count:
+ data, matched, startIndex = self.__applyPattern(
+ self.inlinePatterns[patternIndex], data, patternIndex, startIndex
+ )
+ if not matched:
+ patternIndex += 1
+ return data
+
+ def __processElementText(self, node, subnode, isText=True):
+ """
+ Process placeholders in Element.text or Element.tail
+ of Elements popped from self.stashed_nodes.
+
+ Keywords arguments:
+
+ * node: parent node
+ * subnode: processing node
+ * isText: bool variable, True - it's text, False - it's tail
+
+ Returns: None
+
+ """
+ if isText:
+ text = subnode.text
+ subnode.text = None
+ else:
+ text = subnode.tail
+ subnode.tail = None
+
+ childResult = self.__processPlaceholders(text, subnode, isText)
+
+ if not isText and node is not subnode:
+ pos = list(node).index(subnode) + 1
+ else:
+ pos = 0
+
+ childResult.reverse()
+ for newChild in childResult:
+ node.insert(pos, newChild[0])
+
+ def __processPlaceholders(self, data, parent, isText=True):
+ """
+ Process string with placeholders and generate ElementTree tree.
+
+ Keyword arguments:
+
+ * data: string with placeholders instead of ElementTree elements.
+ * parent: Element, which contains processing inline data
+
+ Returns: list with ElementTree elements with applied inline patterns.
+
+ """
+ def linkText(text):
+ if text:
+ if result:
+ if result[-1][0].tail:
+ result[-1][0].tail += text
+ else:
+ result[-1][0].tail = text
+ elif not isText:
+ if parent.tail:
+ parent.tail += text
+ else:
+ parent.tail = text
+ else:
+ if parent.text:
+ parent.text += text
+ else:
+ parent.text = text
+ result = []
+ strartIndex = 0
+ while data:
+ index = data.find(self.__placeholder_prefix, strartIndex)
+ if index != -1:
+ id, phEndIndex = self.__findPlaceholder(data, index)
+
+ if id in self.stashed_nodes:
+ node = self.stashed_nodes.get(id)
+
+ if index > 0:
+ text = data[strartIndex:index]
+ linkText(text)
+
+ if not isString(node): # it's Element
+ for child in [node] + list(node):
+ if child.tail:
+ if child.tail.strip():
+ self.__processElementText(
+ node, child, False
+ )
+ if child.text:
+ if child.text.strip():
+ self.__processElementText(child, child)
+ else: # it's just a string
+ linkText(node)
+ strartIndex = phEndIndex
+ continue
+
+ strartIndex = phEndIndex
+ result.append((node, self.ancestors[:]))
+
+ else: # wrong placeholder
+ end = index + len(self.__placeholder_prefix)
+ linkText(data[strartIndex:end])
+ strartIndex = end
+ else:
+ text = data[strartIndex:]
+ if isinstance(data, util.AtomicString):
+ # We don't want to loose the AtomicString
+ text = util.AtomicString(text)
+ linkText(text)
+ data = ""
+
+ return result
+
+ def __applyPattern(self, pattern, data, patternIndex, startIndex=0):
+ """
+ Check if the line fits the pattern, create the necessary
+ elements, add it to stashed_nodes.
+
+ Keyword arguments:
+
+ * data: the text to be processed
+ * pattern: the pattern to be checked
+ * patternIndex: index of current pattern
+ * startIndex: string index, from which we start searching
+
+ Returns: String with placeholders instead of ElementTree elements.
+
+ """
+ new_style = isinstance(pattern, inlinepatterns.InlineProcessor)
+
+ for exclude in pattern.ANCESTOR_EXCLUDES:
+ if exclude.lower() in self.ancestors:
+ return data, False, 0
+
+ if new_style:
+ match = None
+ # Since handleMatch may reject our first match,
+ # we iterate over the buffer looking for matches
+ # until we can't find any more.
+ for match in pattern.getCompiledRegExp().finditer(data, startIndex):
+ node, start, end = pattern.handleMatch(match, data)
+ if start is None or end is None:
+ startIndex += match.end(0)
+ match = None
+ continue
+ break
+ else: # pragma: no cover
+ match = pattern.getCompiledRegExp().match(data[startIndex:])
+ leftData = data[:startIndex]
+
+ if not match:
+ return data, False, 0
+
+ if not new_style: # pragma: no cover
+ node = pattern.handleMatch(match)
+ start = match.start(0)
+ end = match.end(0)
+
+ if node is None:
+ return data, True, end
+
+ if not isString(node):
+ if not isinstance(node.text, util.AtomicString):
+ # We need to process current node too
+ for child in [node] + list(node):
+ if not isString(node):
+ if child.text:
+ self.ancestors.append(child.tag.lower())
+ child.text = self.__handleInline(
+ child.text, patternIndex + 1
+ )
+ self.ancestors.pop()
+ if child.tail:
+ child.tail = self.__handleInline(
+ child.tail, patternIndex
+ )
+
+ placeholder = self.__stashNode(node, pattern.type())
+
+ if new_style:
+ return "{}{}{}".format(data[:start],
+ placeholder, data[end:]), True, 0
+ else: # pragma: no cover
+ return "{}{}{}{}".format(leftData,
+ match.group(1),
+ placeholder, match.groups()[-1]), True, 0
+
+ def __build_ancestors(self, parent, parents):
+ """Build the ancestor list."""
+ ancestors = []
+ while parent is not None:
+ if parent is not None:
+ ancestors.append(parent.tag.lower())
+ parent = self.parent_map.get(parent)
+ ancestors.reverse()
+ parents.extend(ancestors)
+
+ def run(self, tree, ancestors=None):
+ """Apply inline patterns to a parsed Markdown tree.
+
+ Iterate over ElementTree, find elements with inline tag, apply inline
+ patterns and append newly created Elements to tree. If you don't
+ want to process your data with inline patterns, instead of normal
+ string, use subclass AtomicString:
+
+ node.text = markdown.AtomicString("This will not be processed.")
+
+ Arguments:
+
+ * tree: ElementTree object, representing Markdown tree.
+ * ancestors: List of parent tag names that precede the tree node (if needed).
+
+ Returns: ElementTree object with applied inline patterns.
+
+ """
+ self.stashed_nodes = {}
+
+ # Ensure a valid parent list, but copy passed in lists
+ # to ensure we don't have the user accidentally change it on us.
+ tree_parents = [] if ancestors is None else ancestors[:]
+
+ self.parent_map = {c: p for p in tree.iter() for c in p}
+ stack = [(tree, tree_parents)]
+
+ while stack:
+ currElement, parents = stack.pop()
+
+ self.ancestors = parents
+ self.__build_ancestors(currElement, self.ancestors)
+
+ insertQueue = []
+ for child in currElement:
+ if child.text and not isinstance(
+ child.text, util.AtomicString
+ ):
+ self.ancestors.append(child.tag.lower())
+ text = child.text
+ child.text = None
+ lst = self.__processPlaceholders(
+ self.__handleInline(text), child
+ )
+ for item in lst:
+ self.parent_map[item[0]] = child
+ stack += lst
+ insertQueue.append((child, lst))
+ self.ancestors.pop()
+ if child.tail:
+ tail = self.__handleInline(child.tail)
+ dumby = etree.Element('d')
+ child.tail = None
+ tailResult = self.__processPlaceholders(tail, dumby, False)
+ if dumby.tail:
+ child.tail = dumby.tail
+ pos = list(currElement).index(child) + 1
+ tailResult.reverse()
+ for newChild in tailResult:
+ self.parent_map[newChild[0]] = currElement
+ currElement.insert(pos, newChild[0])
+ if len(child):
+ self.parent_map[child] = currElement
+ stack.append((child, self.ancestors[:]))
+
+ for element, lst in insertQueue:
+ for i, obj in enumerate(lst):
+ newChild = obj[0]
+ element.insert(i, newChild)
+ return tree
+
+
+class PrettifyTreeprocessor(Treeprocessor):
+ """ Add linebreaks to the html document. """
+
+ def _prettifyETree(self, elem):
+ """ Recursively add linebreaks to ElementTree children. """
+
+ i = "\n"
+ if self.md.is_block_level(elem.tag) and elem.tag not in ['code', 'pre']:
+ if (not elem.text or not elem.text.strip()) \
+ and len(elem) and self.md.is_block_level(elem[0].tag):
+ elem.text = i
+ for e in elem:
+ if self.md.is_block_level(e.tag):
+ self._prettifyETree(e)
+ if not elem.tail or not elem.tail.strip():
+ elem.tail = i
+ if not elem.tail or not elem.tail.strip():
+ elem.tail = i
+
+ def run(self, root):
+ """ Add linebreaks to ElementTree root object. """
+
+ self._prettifyETree(root)
+ # Do
's separately as they are often in the middle of
+ # inline content and missed by _prettifyETree.
+ brs = root.iter('br')
+ for br in brs:
+ if not br.tail or not br.tail.strip():
+ br.tail = '\n'
+ else:
+ br.tail = '\n%s' % br.tail
+ # Clean up extra empty lines at end of code blocks.
+ pres = root.iter('pre')
+ for pre in pres:
+ if len(pre) and pre[0].tag == 'code':
+ pre[0].text = util.AtomicString(pre[0].text.rstrip() + '\n')
diff --git a/venv/lib/python3.11/site-packages/markdown/util.py b/venv/lib/python3.11/site-packages/markdown/util.py
new file mode 100644
index 0000000..46cfe68
--- /dev/null
+++ b/venv/lib/python3.11/site-packages/markdown/util.py
@@ -0,0 +1,485 @@
+"""
+Python Markdown
+
+A Python implementation of John Gruber's Markdown.
+
+Documentation: https://python-markdown.github.io/
+GitHub: https://github.com/Python-Markdown/markdown/
+PyPI: https://pypi.org/project/Markdown/
+
+Started by Manfred Stienstra (http://www.dwerg.net/).
+Maintained for a few years by Yuri Takhteyev (http://www.freewisdom.org).
+Currently maintained by Waylan Limberg (https://github.com/waylan),
+Dmitry Shachnev (https://github.com/mitya57) and Isaac Muse (https://github.com/facelessuser).
+
+Copyright 2007-2018 The Python Markdown Project (v. 1.7 and later)
+Copyright 2004, 2005, 2006 Yuri Takhteyev (v. 0.2-1.6b)
+Copyright 2004 Manfred Stienstra (the original version)
+
+License: BSD (see LICENSE.md for details).
+"""
+
+import re
+import sys
+import warnings
+import xml.etree.ElementTree
+from collections import namedtuple
+from functools import wraps
+from itertools import count
+
+from .pep562 import Pep562
+
+if sys.version_info >= (3, 10):
+ from importlib import metadata
+else:
+ # ` tag.
+ # See https://w3c.github.io/html/grouping-content.html#the-p-element
+ 'address', 'article', 'aside', 'blockquote', 'details', 'div', 'dl',
+ 'fieldset', 'figcaption', 'figure', 'footer', 'form', 'h1', 'h2', 'h3',
+ 'h4', 'h5', 'h6', 'header', 'hgroup', 'hr', 'main', 'menu', 'nav', 'ol',
+ 'p', 'pre', 'section', 'table', 'ul',
+ # Other elements which Markdown should not be mucking up the contents of.
+ 'canvas', 'colgroup', 'dd', 'body', 'dt', 'group', 'iframe', 'li', 'legend',
+ 'math', 'map', 'noscript', 'output', 'object', 'option', 'progress', 'script',
+ 'style', 'tbody', 'td', 'textarea', 'tfoot', 'th', 'thead', 'tr', 'video'
+]
+
+# Placeholders
+STX = '\u0002' # Use STX ("Start of text") for start-of-placeholder
+ETX = '\u0003' # Use ETX ("End of text") for end-of-placeholder
+INLINE_PLACEHOLDER_PREFIX = STX+"klzzwxh:"
+INLINE_PLACEHOLDER = INLINE_PLACEHOLDER_PREFIX + "%s" + ETX
+INLINE_PLACEHOLDER_RE = re.compile(INLINE_PLACEHOLDER % r'([0-9]+)')
+AMP_SUBSTITUTE = STX+"amp"+ETX
+HTML_PLACEHOLDER = STX + "wzxhzdk:%s" + ETX
+HTML_PLACEHOLDER_RE = re.compile(HTML_PLACEHOLDER % r'([0-9]+)')
+TAG_PLACEHOLDER = STX + "hzzhzkh:%s" + ETX
+
+
+"""
+Constants you probably do not need to change
+-----------------------------------------------------------------------------
+"""
+
+# Only load extension entry_points once.
+INSTALLED_EXTENSIONS = metadata.entry_points(group='markdown.extensions')
+RTL_BIDI_RANGES = (
+ ('\u0590', '\u07FF'),
+ # Hebrew (0590-05FF), Arabic (0600-06FF),
+ # Syriac (0700-074F), Arabic supplement (0750-077F),
+ # Thaana (0780-07BF), Nko (07C0-07FF).
+ ('\u2D30', '\u2D7F') # Tifinagh
+)
+
+
+"""
+AUXILIARY GLOBAL FUNCTIONS
+=============================================================================
+"""
+
+
+def deprecated(message, stacklevel=2):
+ """
+ Raise a DeprecationWarning when wrapped function/method is called.
+
+ Usage:
+ @deprecated("This method will be removed in version X; use Y instead.")
+ def some_method()"
+ pass
+ """
+ def wrapper(func):
+ @wraps(func)
+ def deprecated_func(*args, **kwargs):
+ warnings.warn(
+ f"'{func.__name__}' is deprecated. {message}",
+ category=DeprecationWarning,
+ stacklevel=stacklevel
+ )
+ return func(*args, **kwargs)
+ return deprecated_func
+ return wrapper
+
+
+@deprecated("Use 'Markdown.is_block_level' instead.")
+def isBlockLevel(tag):
+ """Check if the tag is a block level HTML tag."""
+ if isinstance(tag, str):
+ return tag.lower().rstrip('/') in BLOCK_LEVEL_ELEMENTS
+ # Some ElementTree tags are not strings, so return False.
+ return False
+
+
+def parseBoolValue(value, fail_on_errors=True, preserve_none=False):
+ """Parses a string representing bool value. If parsing was successful,
+ returns True or False. If preserve_none=True, returns True, False,
+ or None. If parsing was not successful, raises ValueError, or, if
+ fail_on_errors=False, returns None."""
+ if not isinstance(value, str):
+ if preserve_none and value is None:
+ return value
+ return bool(value)
+ elif preserve_none and value.lower() == 'none':
+ return None
+ elif value.lower() in ('true', 'yes', 'y', 'on', '1'):
+ return True
+ elif value.lower() in ('false', 'no', 'n', 'off', '0', 'none'):
+ return False
+ elif fail_on_errors:
+ raise ValueError('Cannot parse bool value: %r' % value)
+
+
+def code_escape(text):
+ """Escape code."""
+ if "&" in text:
+ text = text.replace("&", "&")
+ if "<" in text:
+ text = text.replace("<", "<")
+ if ">" in text:
+ text = text.replace(">", ">")
+ return text
+
+
+def _get_stack_depth(size=2):
+ """Get current stack depth, performantly.
+ """
+ frame = sys._getframe(size)
+
+ for size in count(size):
+ frame = frame.f_back
+ if not frame:
+ return size
+
+
+def nearing_recursion_limit():
+ """Return true if current stack depth is within 100 of maximum limit."""
+ return sys.getrecursionlimit() - _get_stack_depth() < 100
+
+
+"""
+MISC AUXILIARY CLASSES
+=============================================================================
+"""
+
+
+class AtomicString(str):
+ """A string which should not be further processed."""
+ pass
+
+
+class Processor:
+ def __init__(self, md=None):
+ self.md = md
+
+ @property
+ @deprecated("Use 'md' instead.")
+ def markdown(self):
+ # TODO: remove this later
+ return self.md
+
+
+class HtmlStash:
+ """
+ This class is used for stashing HTML objects that we extract
+ in the beginning and replace with place-holders.
+ """
+
+ def __init__(self):
+ """ Create a HtmlStash. """
+ self.html_counter = 0 # for counting inline html segments
+ self.rawHtmlBlocks = []
+ self.tag_counter = 0
+ self.tag_data = [] # list of dictionaries in the order tags appear
+
+ def store(self, html):
+ """
+ Saves an HTML segment for later reinsertion. Returns a
+ placeholder string that needs to be inserted into the
+ document.
+
+ Keyword arguments:
+
+ * html: an html segment
+
+ Returns : a placeholder string
+
+ """
+ self.rawHtmlBlocks.append(html)
+ placeholder = self.get_placeholder(self.html_counter)
+ self.html_counter += 1
+ return placeholder
+
+ def reset(self):
+ self.html_counter = 0
+ self.rawHtmlBlocks = []
+
+ def get_placeholder(self, key):
+ return HTML_PLACEHOLDER % key
+
+ def store_tag(self, tag, attrs, left_index, right_index):
+ """Store tag data and return a placeholder."""
+ self.tag_data.append({'tag': tag, 'attrs': attrs,
+ 'left_index': left_index,
+ 'right_index': right_index})
+ placeholder = TAG_PLACEHOLDER % str(self.tag_counter)
+ self.tag_counter += 1 # equal to the tag's index in self.tag_data
+ return placeholder
+
+
+# Used internally by `Registry` for each item in its sorted list.
+# Provides an easier to read API when editing the code later.
+# For example, `item.name` is more clear than `item[0]`.
+_PriorityItem = namedtuple('PriorityItem', ['name', 'priority'])
+
+
+class Registry:
+ """
+ A priority sorted registry.
+
+ A `Registry` instance provides two public methods to alter the data of the
+ registry: `register` and `deregister`. Use `register` to add items and
+ `deregister` to remove items. See each method for specifics.
+
+ When registering an item, a "name" and a "priority" must be provided. All
+ items are automatically sorted by "priority" from highest to lowest. The
+ "name" is used to remove ("deregister") and get items.
+
+ A `Registry` instance it like a list (which maintains order) when reading
+ data. You may iterate over the items, get an item and get a count (length)
+ of all items. You may also check that the registry contains an item.
+
+ When getting an item you may use either the index of the item or the
+ string-based "name". For example:
+
+ registry = Registry()
+ registry.register(SomeItem(), 'itemname', 20)
+ # Get the item by index
+ item = registry[0]
+ # Get the item by name
+ item = registry['itemname']
+
+ When checking that the registry contains an item, you may use either the
+ string-based "name", or a reference to the actual item. For example:
+
+ someitem = SomeItem()
+ registry.register(someitem, 'itemname', 20)
+ # Contains the name
+ assert 'itemname' in registry
+ # Contains the item instance
+ assert someitem in registry
+
+ The method `get_index_for_name` is also available to obtain the index of
+ an item using that item's assigned "name".
+ """
+
+ def __init__(self):
+ self._data = {}
+ self._priority = []
+ self._is_sorted = False
+
+ def __contains__(self, item):
+ if isinstance(item, str):
+ # Check if an item exists by this name.
+ return item in self._data.keys()
+ # Check if this instance exists.
+ return item in self._data.values()
+
+ def __iter__(self):
+ self._sort()
+ return iter([self._data[k] for k, p in self._priority])
+
+ def __getitem__(self, key):
+ self._sort()
+ if isinstance(key, slice):
+ data = Registry()
+ for k, p in self._priority[key]:
+ data.register(self._data[k], k, p)
+ return data
+ if isinstance(key, int):
+ return self._data[self._priority[key].name]
+ return self._data[key]
+
+ def __len__(self):
+ return len(self._priority)
+
+ def __repr__(self):
+ return '<{}({})>'.format(self.__class__.__name__, list(self))
+
+ def get_index_for_name(self, name):
+ """
+ Return the index of the given name.
+ """
+ if name in self:
+ self._sort()
+ return self._priority.index(
+ [x for x in self._priority if x.name == name][0]
+ )
+ raise ValueError('No item named "{}" exists.'.format(name))
+
+ def register(self, item, name, priority):
+ """
+ Add an item to the registry with the given name and priority.
+
+ Parameters:
+
+ * `item`: The item being registered.
+ * `name`: A string used to reference the item.
+ * `priority`: An integer or float used to sort against all items.
+
+ If an item is registered with a "name" which already exists, the
+ existing item is replaced with the new item. Treat carefully as the
+ old item is lost with no way to recover it. The new item will be
+ sorted according to its priority and will **not** retain the position
+ of the old item.
+ """
+ if name in self:
+ # Remove existing item of same name first
+ self.deregister(name)
+ self._is_sorted = False
+ self._data[name] = item
+ self._priority.append(_PriorityItem(name, priority))
+
+ def deregister(self, name, strict=True):
+ """
+ Remove an item from the registry.
+
+ Set `strict=False` to fail silently.
+ """
+ try:
+ index = self.get_index_for_name(name)
+ del self._priority[index]
+ del self._data[name]
+ except ValueError:
+ if strict:
+ raise
+
+ def _sort(self):
+ """
+ Sort the registry by priority from highest to lowest.
+
+ This method is called internally and should never be explicitly called.
+ """
+ if not self._is_sorted:
+ self._priority.sort(key=lambda item: item.priority, reverse=True)
+ self._is_sorted = True
+
+ # Deprecated Methods which provide a smooth transition from OrderedDict
+
+ def __setitem__(self, key, value):
+ """ Register item with priority 5 less than lowest existing priority. """
+ if isinstance(key, str):
+ warnings.warn(
+ 'Using setitem to register a processor or pattern is deprecated. '
+ 'Use the `register` method instead.',
+ DeprecationWarning,
+ stacklevel=2,
+ )
+ if key in self:
+ # Key already exists, replace without altering priority
+ self._data[key] = value
+ return
+ if len(self) == 0:
+ # This is the first item. Set priority to 50.
+ priority = 50
+ else:
+ self._sort()
+ priority = self._priority[-1].priority - 5
+ self.register(value, key, priority)
+ else:
+ raise TypeError
+
+ def __delitem__(self, key):
+ """ Deregister an item by name. """
+ if key in self:
+ self.deregister(key)
+ warnings.warn(
+ 'Using del to remove a processor or pattern is deprecated. '
+ 'Use the `deregister` method instead.',
+ DeprecationWarning,
+ stacklevel=2,
+ )
+ else:
+ raise KeyError('Cannot delete key {}, not registered.'.format(key))
+
+ def add(self, key, value, location):
+ """ Register a key by location. """
+ if len(self) == 0:
+ # This is the first item. Set priority to 50.
+ priority = 50
+ elif location == '_begin':
+ self._sort()
+ # Set priority 5 greater than highest existing priority
+ priority = self._priority[0].priority + 5
+ elif location == '_end':
+ self._sort()
+ # Set priority 5 less than lowest existing priority
+ priority = self._priority[-1].priority - 5
+ elif location.startswith('<') or location.startswith('>'):
+ # Set priority halfway between existing priorities.
+ i = self.get_index_for_name(location[1:])
+ if location.startswith('<'):
+ after = self._priority[i].priority
+ if i > 0:
+ before = self._priority[i-1].priority
+ else:
+ # Location is first item`
+ before = after + 10
+ else:
+ # location.startswith('>')
+ before = self._priority[i].priority
+ if i < len(self) - 1:
+ after = self._priority[i+1].priority
+ else:
+ # location is last item
+ after = before - 10
+ priority = before - ((before - after) / 2)
+ else:
+ raise ValueError('Not a valid location: "%s". Location key '
+ 'must start with a ">" or "<".' % location)
+ self.register(value, key, priority)
+ warnings.warn(
+ 'Using the add method to register a processor or pattern is deprecated. '
+ 'Use the `register` method instead.',
+ DeprecationWarning,
+ stacklevel=2,
+ )
+
+
+def __getattr__(name):
+ """Get attribute."""
+
+ deprecated = __deprecated__.get(name)
+ if deprecated:
+ warnings.warn(
+ "'{}' is deprecated. Use '{}' instead.".format(name, deprecated[0]),
+ category=DeprecationWarning,
+ stacklevel=(3 if PY37 else 4)
+ )
+ return deprecated[1]
+ raise AttributeError("module '{}' has no attribute '{}'".format(__name__, name))
+
+
+if not PY37:
+ Pep562(__name__)
diff --git a/venv/lib/python3.11/site-packages/mergedeep-1.3.4.dist-info/INSTALLER b/venv/lib/python3.11/site-packages/mergedeep-1.3.4.dist-info/INSTALLER
new file mode 100644
index 0000000..a1b589e
--- /dev/null
+++ b/venv/lib/python3.11/site-packages/mergedeep-1.3.4.dist-info/INSTALLER
@@ -0,0 +1 @@
+pip
diff --git a/venv/lib/python3.11/site-packages/mergedeep-1.3.4.dist-info/LICENSE b/venv/lib/python3.11/site-packages/mergedeep-1.3.4.dist-info/LICENSE
new file mode 100644
index 0000000..45c6440
--- /dev/null
+++ b/venv/lib/python3.11/site-packages/mergedeep-1.3.4.dist-info/LICENSE
@@ -0,0 +1,21 @@
+The MIT License (MIT)
+
+Copyright (c) 2019 Travis Clarke (https://www.travismclarke.com/)
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/venv/lib/python3.11/site-packages/mergedeep-1.3.4.dist-info/METADATA b/venv/lib/python3.11/site-packages/mergedeep-1.3.4.dist-info/METADATA
new file mode 100644
index 0000000..23452d7
--- /dev/null
+++ b/venv/lib/python3.11/site-packages/mergedeep-1.3.4.dist-info/METADATA
@@ -0,0 +1,154 @@
+Metadata-Version: 2.1
+Name: mergedeep
+Version: 1.3.4
+Summary: A deep merge function for 🐍.
+Home-page: https://github.com/clarketm/mergedeep
+Author: Travis Clarke
+Author-email: travis.m.clarke@gmail.com
+License: UNKNOWN
+Platform: UNKNOWN
+Classifier: Programming Language :: Python :: 3
+Classifier: Programming Language :: Python :: 3.6
+Classifier: Programming Language :: Python :: 3.7
+Classifier: Programming Language :: Python :: 3.8
+Classifier: Programming Language :: Python :: 3.9
+Classifier: License :: OSI Approved :: MIT License
+Classifier: Operating System :: OS Independent
+Requires-Python: >=3.6
+Description-Content-Type: text/markdown
+
+# [mergedeep](https://mergedeep.readthedocs.io/en/latest/)
+
+[](https://pypi.org/project/mergedeep/)
+[](https://pypi.org/project/mergedeep/)
+[](https://pepy.tech/project/mergedeep)
+[](https://anaconda.org/conda-forge/mergedeep)
+[](https://anaconda.org/conda-forge/mergedeep)
+[](https://mergedeep.readthedocs.io/en/latest/?badge=latest)
+
+A deep merge function for 🐍.
+
+[Check out the mergedeep docs](https://mergedeep.readthedocs.io/en/latest/)
+
+## Installation
+
+```bash
+$ pip install mergedeep
+```
+
+## Usage
+
+```text
+merge(destination: MutableMapping, *sources: Mapping, strategy: Strategy = Strategy.REPLACE) -> MutableMapping
+```
+
+Deep merge without mutating the source dicts.
+
+```python3
+from mergedeep import merge
+
+a = {"keyA": 1}
+b = {"keyB": {"sub1": 10}}
+c = {"keyB": {"sub2": 20}}
+
+merged = merge({}, a, b, c)
+
+print(merged)
+# {"keyA": 1, "keyB": {"sub1": 10, "sub2": 20}}
+```
+
+Deep merge into an existing dict.
+```python3
+from mergedeep import merge
+
+a = {"keyA": 1}
+b = {"keyB": {"sub1": 10}}
+c = {"keyB": {"sub2": 20}}
+
+merge(a, b, c)
+
+print(a)
+# {"keyA": 1, "keyB": {"sub1": 10, "sub2": 20}}
+```
+
+### Merge strategies:
+
+1. Replace (*default*)
+
+> `Strategy.REPLACE`
+
+```python3
+# When `destination` and `source` keys are the same, replace the `destination` value with one from `source` (default).
+
+# Note: with multiple sources, the `last` (i.e. rightmost) source value will be what appears in the merged result.
+
+from mergedeep import merge, Strategy
+
+dst = {"key": [1, 2]}
+src = {"key": [3, 4]}
+
+merge(dst, src, strategy=Strategy.REPLACE)
+# same as: merge(dst, src)
+
+print(dst)
+# {"key": [3, 4]}
+```
+
+2. Additive
+
+> `Strategy.ADDITIVE`
+
+```python3
+# When `destination` and `source` values are both the same additive collection type, extend `destination` by adding values from `source`.
+# Additive collection types include: `list`, `tuple`, `set`, and `Counter`
+
+# Note: if the values are not additive collections of the same type, then fallback to a `REPLACE` merge.
+
+from mergedeep import merge, Strategy
+
+dst = {"key": [1, 2], "count": Counter({"a": 1, "b": 1})}
+src = {"key": [3, 4], "count": Counter({"a": 1, "c": 1})}
+
+merge(dst, src, strategy=Strategy.ADDITIVE)
+
+print(dst)
+# {"key": [1, 2, 3, 4], "count": Counter({"a": 2, "b": 1, "c": 1})}
+```
+
+3. Typesafe replace
+
+> `Strategy.TYPESAFE_REPLACE` or `Strategy.TYPESAFE`
+
+```python3
+# When `destination` and `source` values are of different types, raise `TypeError`. Otherwise, perform a `REPLACE` merge.
+
+from mergedeep import merge, Strategy
+
+dst = {"key": [1, 2]}
+src = {"key": {3, 4}}
+
+merge(dst, src, strategy=Strategy.TYPESAFE_REPLACE) # same as: `Strategy.TYPESAFE`
+# TypeError: destination type: differs from source type: for key: "key"
+```
+
+4. Typesafe additive
+
+> `Strategy.TYPESAFE_ADDITIVE`
+
+```python3
+# When `destination` and `source` values are of different types, raise `TypeError`. Otherwise, perform a `ADDITIVE` merge.
+
+from mergedeep import merge, Strategy
+
+dst = {"key": [1, 2]}
+src = {"key": {3, 4}}
+
+merge(dst, src, strategy=Strategy.TYPESAFE_ADDITIVE)
+# TypeError: destination type: differs from source type: for key: "key"
+```
+
+## License
+
+MIT © [**Travis Clarke**](https://blog.travismclarke.com/)
+
+
diff --git a/venv/lib/python3.11/site-packages/mergedeep-1.3.4.dist-info/RECORD b/venv/lib/python3.11/site-packages/mergedeep-1.3.4.dist-info/RECORD
new file mode 100644
index 0000000..f094f16
--- /dev/null
+++ b/venv/lib/python3.11/site-packages/mergedeep-1.3.4.dist-info/RECORD
@@ -0,0 +1,12 @@
+mergedeep-1.3.4.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
+mergedeep-1.3.4.dist-info/LICENSE,sha256=EVkr2dVmk8mH2oScB11jZpCRbQGkfKI0oUu88P4Xazc,1141
+mergedeep-1.3.4.dist-info/METADATA,sha256=8nHkB_zwURM7GrtHZfTUu9tjADgXfoka1G16_Uh_ubk,4336
+mergedeep-1.3.4.dist-info/RECORD,,
+mergedeep-1.3.4.dist-info/WHEEL,sha256=g4nMs7d-Xl9-xC9XovUrsDHGXt-FT0E17Yqo92DEfvY,92
+mergedeep-1.3.4.dist-info/top_level.txt,sha256=DbDDz9xNUAr-N7GSK2lAKoFC_aGex_L53GXDt0910AE,10
+mergedeep/__init__.py,sha256=quQFNpN7nAbu7UqS3VsfmRlXu89vC8RGH3Whr51IH1I,104
+mergedeep/__pycache__/__init__.cpython-311.pyc,,
+mergedeep/__pycache__/mergedeep.cpython-311.pyc,,
+mergedeep/__pycache__/test_mergedeep.cpython-311.pyc,,
+mergedeep/mergedeep.py,sha256=Lys3btFLe9hIKHsj9IgXPki0dahBeCnNmILqPTOckK4,4360
+mergedeep/test_mergedeep.py,sha256=R9B2GY9ZkCkhWKb6J4MEQsycyLnUUPqnDCr1_x7LJL8,13618
diff --git a/venv/lib/python3.11/site-packages/mergedeep-1.3.4.dist-info/WHEEL b/venv/lib/python3.11/site-packages/mergedeep-1.3.4.dist-info/WHEEL
new file mode 100644
index 0000000..b552003
--- /dev/null
+++ b/venv/lib/python3.11/site-packages/mergedeep-1.3.4.dist-info/WHEEL
@@ -0,0 +1,5 @@
+Wheel-Version: 1.0
+Generator: bdist_wheel (0.34.2)
+Root-Is-Purelib: true
+Tag: py3-none-any
+
diff --git a/venv/lib/python3.11/site-packages/mergedeep-1.3.4.dist-info/top_level.txt b/venv/lib/python3.11/site-packages/mergedeep-1.3.4.dist-info/top_level.txt
new file mode 100644
index 0000000..5413932
--- /dev/null
+++ b/venv/lib/python3.11/site-packages/mergedeep-1.3.4.dist-info/top_level.txt
@@ -0,0 +1 @@
+mergedeep
diff --git a/venv/lib/python3.11/site-packages/mergedeep/__init__.py b/venv/lib/python3.11/site-packages/mergedeep/__init__.py
new file mode 100644
index 0000000..92d12f6
--- /dev/null
+++ b/venv/lib/python3.11/site-packages/mergedeep/__init__.py
@@ -0,0 +1,5 @@
+__version__ = "1.3.4"
+
+from mergedeep.mergedeep import merge, Strategy
+
+__all__ = ["merge", "Strategy"]
diff --git a/venv/lib/python3.11/site-packages/mergedeep/__pycache__/__init__.cpython-311.pyc b/venv/lib/python3.11/site-packages/mergedeep/__pycache__/__init__.cpython-311.pyc
new file mode 100644
index 0000000..c5a2cf1
Binary files /dev/null and b/venv/lib/python3.11/site-packages/mergedeep/__pycache__/__init__.cpython-311.pyc differ
diff --git a/venv/lib/python3.11/site-packages/mergedeep/__pycache__/mergedeep.cpython-311.pyc b/venv/lib/python3.11/site-packages/mergedeep/__pycache__/mergedeep.cpython-311.pyc
new file mode 100644
index 0000000..1e2531e
Binary files /dev/null and b/venv/lib/python3.11/site-packages/mergedeep/__pycache__/mergedeep.cpython-311.pyc differ
diff --git a/venv/lib/python3.11/site-packages/mergedeep/__pycache__/test_mergedeep.cpython-311.pyc b/venv/lib/python3.11/site-packages/mergedeep/__pycache__/test_mergedeep.cpython-311.pyc
new file mode 100644
index 0000000..4b392bf
Binary files /dev/null and b/venv/lib/python3.11/site-packages/mergedeep/__pycache__/test_mergedeep.cpython-311.pyc differ
diff --git a/venv/lib/python3.11/site-packages/mergedeep/mergedeep.py b/venv/lib/python3.11/site-packages/mergedeep/mergedeep.py
new file mode 100644
index 0000000..6dda8e8
--- /dev/null
+++ b/venv/lib/python3.11/site-packages/mergedeep/mergedeep.py
@@ -0,0 +1,100 @@
+from collections import Counter
+from collections.abc import Mapping
+from copy import deepcopy
+from enum import Enum
+from functools import reduce, partial
+from typing import MutableMapping
+
+
+class Strategy(Enum):
+ # Replace `destination` item with one from `source` (default).
+ REPLACE = 0
+ # Combine `list`, `tuple`, `set`, or `Counter` types into one collection.
+ ADDITIVE = 1
+ # Alias to: `TYPESAFE_REPLACE`
+ TYPESAFE = 2
+ # Raise `TypeError` when `destination` and `source` types differ. Otherwise, perform a `REPLACE` merge.
+ TYPESAFE_REPLACE = 3
+ # Raise `TypeError` when `destination` and `source` types differ. Otherwise, perform a `ADDITIVE` merge.
+ TYPESAFE_ADDITIVE = 4
+
+
+def _handle_merge_replace(destination, source, key):
+ if isinstance(destination[key], Counter) and isinstance(source[key], Counter):
+ # Merge both destination and source `Counter` as if they were a standard dict.
+ _deepmerge(destination[key], source[key])
+ else:
+ # If a key exists in both objects and the values are `different`, the value from the `source` object will be used.
+ destination[key] = deepcopy(source[key])
+
+
+def _handle_merge_additive(destination, source, key):
+ # Values are combined into one long collection.
+ if isinstance(destination[key], list) and isinstance(source[key], list):
+ # Extend destination if both destination and source are `list` type.
+ destination[key].extend(deepcopy(source[key]))
+ elif isinstance(destination[key], set) and isinstance(source[key], set):
+ # Update destination if both destination and source are `set` type.
+ destination[key].update(deepcopy(source[key]))
+ elif isinstance(destination[key], tuple) and isinstance(source[key], tuple):
+ # Update destination if both destination and source are `tuple` type.
+ destination[key] = destination[key] + deepcopy(source[key])
+ elif isinstance(destination[key], Counter) and isinstance(source[key], Counter):
+ # Update destination if both destination and source are `Counter` type.
+ destination[key].update(deepcopy(source[key]))
+ else:
+ _handle_merge[Strategy.REPLACE](destination, source, key)
+
+
+def _handle_merge_typesafe(destination, source, key, strategy):
+ # Raise a TypeError if the destination and source types differ.
+ if type(destination[key]) is not type(source[key]):
+ raise TypeError(
+ f'destination type: {type(destination[key])} differs from source type: {type(source[key])} for key: "{key}"'
+ )
+ else:
+ _handle_merge[strategy](destination, source, key)
+
+
+_handle_merge = {
+ Strategy.REPLACE: _handle_merge_replace,
+ Strategy.ADDITIVE: _handle_merge_additive,
+ Strategy.TYPESAFE: partial(_handle_merge_typesafe, strategy=Strategy.REPLACE),
+ Strategy.TYPESAFE_REPLACE: partial(_handle_merge_typesafe, strategy=Strategy.REPLACE),
+ Strategy.TYPESAFE_ADDITIVE: partial(_handle_merge_typesafe, strategy=Strategy.ADDITIVE),
+}
+
+
+def _is_recursive_merge(a, b):
+ both_mapping = isinstance(a, Mapping) and isinstance(b, Mapping)
+ both_counter = isinstance(a, Counter) and isinstance(b, Counter)
+ return both_mapping and not both_counter
+
+
+def _deepmerge(dst, src, strategy=Strategy.REPLACE):
+ for key in src:
+ if key in dst:
+ if _is_recursive_merge(dst[key], src[key]):
+ # If the key for both `dst` and `src` are both Mapping types (e.g. dict), then recurse.
+ _deepmerge(dst[key], src[key], strategy)
+ elif dst[key] is src[key]:
+ # If a key exists in both objects and the values are `same`, the value from the `dst` object will be used.
+ pass
+ else:
+ _handle_merge.get(strategy)(dst, src, key)
+ else:
+ # If the key exists only in `src`, the value from the `src` object will be used.
+ dst[key] = deepcopy(src[key])
+ return dst
+
+
+def merge(destination: MutableMapping, *sources: Mapping, strategy: Strategy = Strategy.REPLACE) -> MutableMapping:
+ """
+ A deep merge function for 🐍.
+
+ :param destination: The destination mapping.
+ :param sources: The source mappings.
+ :param strategy: The merge strategy.
+ :return:
+ """
+ return reduce(partial(_deepmerge, strategy=strategy), sources, destination)
diff --git a/venv/lib/python3.11/site-packages/mergedeep/test_mergedeep.py b/venv/lib/python3.11/site-packages/mergedeep/test_mergedeep.py
new file mode 100644
index 0000000..ef39728
--- /dev/null
+++ b/venv/lib/python3.11/site-packages/mergedeep/test_mergedeep.py
@@ -0,0 +1,397 @@
+"""mergedeep test module"""
+import inspect
+import unittest
+from collections import Counter
+from copy import deepcopy
+
+from mergedeep import merge, Strategy
+
+
+class test_mergedeep(unittest.TestCase):
+ """mergedeep function tests."""
+
+ ##############################################################################################################################
+ # REPLACE
+ ##############################################################################################################################
+
+ def test_should_merge_3_dicts_into_new_dict_using_replace_strategy_and_only_mutate_target(self,):
+ expected = {
+ "a": {"b": {"c": 5, "_c": 15}, "B": {"C": 10}},
+ "d": 3,
+ "e": {1: 2, "a": {"f": 2}},
+ "f": [4, 5, 6],
+ "g": (100, 200),
+ "h": Counter({"a": 5, "b": 1, "c": 1}),
+ "i": 2,
+ "j": Counter({"z": 2}),
+ "z": Counter({"a": 2}),
+ }
+
+ a = {
+ "a": {"b": {"c": 5}},
+ "d": 1,
+ "e": {2: 3},
+ "f": [1, 2, 3],
+ "g": (2, 4, 6),
+ "h": Counter({"a": 1, "b": 1}),
+ "j": 1,
+ }
+ a_copy = deepcopy(a)
+
+ b = {
+ "a": {"B": {"C": 10}},
+ "d": 2,
+ "e": 2,
+ "f": [4, 5, 6],
+ "g": (100, 200),
+ "h": Counter({"a": 5, "c": 1}),
+ "i": Counter({"a": 1}),
+ "z": Counter({"a": 2}),
+ }
+ b_copy = deepcopy(b)
+
+ c = {
+ "a": {"b": {"_c": 15}},
+ "d": 3,
+ "e": {1: 2, "a": {"f": 2}},
+ "i": 2,
+ "j": Counter({"z": 2}),
+ "z": Counter({"a": 2}),
+ }
+ c_copy = deepcopy(c)
+
+ actual = merge({}, a, b, c, strategy=Strategy.REPLACE)
+
+ self.assertEqual(actual, expected)
+ self.assertEqual(a, a_copy)
+ self.assertEqual(b, b_copy)
+ self.assertEqual(c, c_copy)
+
+ def test_should_merge_2_dicts_into_existing_dict_using_replace_strategy_and_only_mutate_target(self,):
+ expected = {
+ "a": {"b": {"c": 5, "_c": 15}, "B": {"C": 10}},
+ "d": 3,
+ "e": {1: 2, "a": {"f": 2}},
+ "f": [4, 5, 6],
+ "g": (100, 200),
+ "h": Counter({"a": 1, "b": 1, "c": 1}),
+ "i": 2,
+ "j": Counter({"z": 2}),
+ }
+
+ a = {
+ "a": {"b": {"c": 5}},
+ "d": 1,
+ "e": {2: 3},
+ "f": [1, 2, 3],
+ "g": (2, 4, 6),
+ "h": Counter({"a": 1, "b": 1}),
+ "j": 1,
+ }
+ a_copy = deepcopy(a)
+
+ b = {
+ "a": {"B": {"C": 10}},
+ "d": 2,
+ "e": 2,
+ "f": [4, 5, 6],
+ "g": (100, 200),
+ "h": Counter({"a": 1, "c": 1}),
+ "i": Counter({"a": 1}),
+ }
+ b_copy = deepcopy(b)
+
+ c = {"a": {"b": {"_c": 15}}, "d": 3, "e": {1: 2, "a": {"f": 2}}, "i": 2, "j": Counter({"z": 2})}
+ c_copy = deepcopy(c)
+
+ actual = merge(a, b, c, strategy=Strategy.REPLACE)
+
+ self.assertEqual(actual, expected)
+ self.assertEqual(actual, a)
+ self.assertNotEqual(a, a_copy)
+ self.assertEqual(b, b_copy)
+ self.assertEqual(c, c_copy)
+
+ def test_should_have_default_strategy_of_replace(self):
+ func_spec = inspect.getfullargspec(merge)
+ default_strategy = Strategy.REPLACE
+
+ self.assertEqual(func_spec.kwonlydefaults.get("strategy"), default_strategy)
+
+ # mock_merge.method.assert_called_with(target, source, strategy=Strategy.REPLACE)
+
+ ##############################################################################################################################
+ # ADDITIVE
+ ##############################################################################################################################
+
+ def test_should_merge_3_dicts_into_new_dict_using_additive_strategy_on_lists_and_only_mutate_target(self,):
+ expected = {
+ "a": {"b": {"c": 5, "_c": 15}, "B": {"C": 10}},
+ "d": 3,
+ "e": {1: 2, "a": {"f": 2}},
+ "f": [1, 2, 3, 4, 5, 6],
+ }
+
+ a = {"a": {"b": {"c": 5}}, "d": 1, "e": {2: 3}, "f": [1, 2, 3]}
+ a_copy = deepcopy(a)
+
+ b = {"a": {"B": {"C": 10}}, "d": 2, "e": 2, "f": [4, 5, 6]}
+ b_copy = deepcopy(b)
+
+ c = {"a": {"b": {"_c": 15}}, "d": 3, "e": {1: 2, "a": {"f": 2}}}
+ c_copy = deepcopy(c)
+
+ actual = merge({}, a, b, c, strategy=Strategy.ADDITIVE)
+
+ self.assertEqual(actual, expected)
+ self.assertEqual(a, a_copy)
+ self.assertEqual(b, b_copy)
+ self.assertEqual(c, c_copy)
+
+ def test_should_merge_3_dicts_into_new_dict_using_additive_strategy_on_sets_and_only_mutate_target(self,):
+ expected = {
+ "a": {"b": {"c": 5, "_c": 15}, "B": {"C": 10}},
+ "d": 3,
+ "e": {1: 2, "a": {"f": 2}},
+ "f": {1, 2, 3, 4, 5, 6},
+ }
+
+ a = {"a": {"b": {"c": 5}}, "d": 1, "e": {2: 3}, "f": {1, 2, 3}}
+ a_copy = deepcopy(a)
+
+ b = {"a": {"B": {"C": 10}}, "d": 2, "e": 2, "f": {4, 5, 6}}
+ b_copy = deepcopy(b)
+
+ c = {"a": {"b": {"_c": 15}}, "d": 3, "e": {1: 2, "a": {"f": 2}}}
+ c_copy = deepcopy(c)
+
+ actual = merge({}, a, b, c, strategy=Strategy.ADDITIVE)
+
+ self.assertEqual(actual, expected)
+ self.assertEqual(a, a_copy)
+ self.assertEqual(b, b_copy)
+ self.assertEqual(c, c_copy)
+
+ def test_should_merge_3_dicts_into_new_dict_using_additive_strategy_on_tuples_and_only_mutate_target(self,):
+ expected = {
+ "a": {"b": {"c": 5, "_c": 15}, "B": {"C": 10}},
+ "d": 3,
+ "e": {1: 2, "a": {"f": 2}},
+ "f": (1, 2, 3, 4, 5, 6),
+ }
+
+ a = {"a": {"b": {"c": 5}}, "d": 1, "e": {2: 3}, "f": (1, 2, 3)}
+ a_copy = deepcopy(a)
+
+ b = {"a": {"B": {"C": 10}}, "d": 2, "e": 2, "f": (4, 5, 6)}
+ b_copy = deepcopy(b)
+
+ c = {"a": {"b": {"_c": 15}}, "d": 3, "e": {1: 2, "a": {"f": 2}}}
+ c_copy = deepcopy(c)
+
+ actual = merge({}, a, b, c, strategy=Strategy.ADDITIVE)
+
+ self.assertEqual(actual, expected)
+ self.assertEqual(a, a_copy)
+ self.assertEqual(b, b_copy)
+ self.assertEqual(c, c_copy)
+
+ def test_should_merge_3_dicts_into_new_dict_using_additive_strategy_on_counters_and_only_mutate_target(self,):
+ expected = {
+ "a": {"b": {"c": 5, "_c": 15}, "B": {"C": 10}},
+ "d": 3,
+ "e": {1: 2, "a": {"f": 2}},
+ "f": Counter({"a": 2, "c": 1, "b": 1}),
+ "i": 2,
+ "j": Counter({"z": 2}),
+ "z": Counter({"a": 4}),
+ }
+
+ a = {
+ "a": {"b": {"c": 5}},
+ "d": 1,
+ "e": {2: 3},
+ "f": Counter({"a": 1, "c": 1}),
+ "i": Counter({"f": 9}),
+ "j": Counter({"a": 1, "z": 4}),
+ }
+ a_copy = deepcopy(a)
+
+ b = {
+ "a": {"B": {"C": 10}},
+ "d": 2,
+ "e": 2,
+ "f": Counter({"a": 1, "b": 1}),
+ "j": [1, 2, 3],
+ "z": Counter({"a": 2}),
+ }
+ b_copy = deepcopy(b)
+
+ c = {
+ "a": {"b": {"_c": 15}},
+ "d": 3,
+ "e": {1: 2, "a": {"f": 2}},
+ "i": 2,
+ "j": Counter({"z": 2}),
+ "z": Counter({"a": 2}),
+ }
+ c_copy = deepcopy(c)
+
+ actual = merge({}, a, b, c, strategy=Strategy.ADDITIVE)
+
+ self.assertEqual(actual, expected)
+ self.assertEqual(a, a_copy)
+ self.assertEqual(b, b_copy)
+ self.assertEqual(c, c_copy)
+
+ def test_should_not_copy_references(self):
+ before = 1
+ after = 99
+
+ o1 = {"key1": before}
+ o2 = {"key2": before}
+
+ expected = {"list": deepcopy([o1, o2]), "tuple": deepcopy((o1, o2))}
+
+ a = {"list": [o1], "tuple": (o1,)}
+ b = {"list": [o2], "tuple": (o2,)}
+
+ actual = merge({}, a, b, strategy=Strategy.ADDITIVE)
+
+ o1["key1"] = after
+ o2["key2"] = after
+
+ self.assertEqual(actual, expected)
+
+ # Copied dicts should `not` mutate
+ self.assertEqual(actual["list"][0]["key1"], before)
+ self.assertEqual(actual["list"][1]["key2"], before)
+ self.assertEqual(actual["tuple"][0]["key1"], before)
+ self.assertEqual(actual["tuple"][1]["key2"], before)
+
+ # Non-copied dicts should mutate
+ self.assertEqual(a["list"][0]["key1"], after)
+ self.assertEqual(b["list"][0]["key2"], after)
+ self.assertEqual(a["tuple"][0]["key1"], after)
+ self.assertEqual(b["tuple"][0]["key2"], after)
+
+ ##############################################################################################################################
+ # TYPESAFE
+ # TYPESAFE_REPLACE
+ ##############################################################################################################################
+
+ def test_should_raise_TypeError_using_typesafe_strategy_if_types_differ(self):
+ a = {"a": {"b": {"c": 5}}, "d": 1, "e": {2: 3}, "f": [1, 2, 3]}
+ b = {"a": {"B": {"C": 10}}, "d": 2, "e": 2, "f": [4, 5, 6]}
+ c = {"a": {"b": {"_c": 15}}, "d": 3, "e": {1: 2, "a": {"f": 2}}}
+
+ with self.assertRaises(TypeError):
+ merge({}, a, b, c, strategy=Strategy.TYPESAFE)
+
+ def test_should_raise_TypeError_using_typesafe_replace_strategy_if_types_differ(self,):
+ a = {"a": {"b": {"c": 5}}, "d": 1, "e": {2: 3}, "f": [1, 2, 3]}
+ b = {"a": {"B": {"C": 10}}, "d": 2, "e": 2, "f": [4, 5, 6]}
+ c = {"a": {"b": {"_c": 15}}, "d": 3, "e": {1: 2, "a": {"f": 2}}}
+
+ with self.assertRaises(TypeError):
+ merge({}, a, b, c, strategy=Strategy.TYPESAFE_REPLACE)
+
+ def test_should_merge_3_dicts_into_new_dict_using_typesafe_strategy_and_only_mutate_target_if_types_are_compatible(
+ self,
+ ):
+ expected = {
+ "a": {"b": {"c": 5, "_c": 15}, "B": {"C": 10}},
+ "d": 3,
+ "f": [4, 5, 6],
+ "g": {2, 3, 4},
+ "h": (1, 3),
+ "z": Counter({"a": 1, "b": 1, "c": 1}),
+ }
+
+ a = {"a": {"b": {"c": 5}}, "d": 1, "f": [1, 2, 3], "g": {1, 2, 3}, "z": Counter({"a": 1, "b": 1})}
+ a_copy = deepcopy(a)
+
+ b = {"a": {"B": {"C": 10}}, "d": 2, "f": [4, 5, 6], "g": {2, 3, 4}, "h": (1,)}
+ b_copy = deepcopy(b)
+
+ c = {"a": {"b": {"_c": 15}}, "d": 3, "h": (1, 3), "z": Counter({"a": 1, "c": 1})}
+ c_copy = deepcopy(c)
+
+ actual = merge({}, a, b, c, strategy=Strategy.TYPESAFE)
+
+ self.assertEqual(actual, expected)
+ self.assertEqual(a, a_copy)
+ self.assertEqual(b, b_copy)
+ self.assertEqual(c, c_copy)
+
+ def test_should_merge_3_dicts_into_new_dict_using_typesafe_replace_strategy_and_only_mutate_target_if_types_are_compatible(
+ self,
+ ):
+ expected = {
+ "a": {"b": {"c": 5, "_c": 15}, "B": {"C": 10}},
+ "d": 3,
+ "f": [4, 5, 6],
+ "g": {2, 3, 4},
+ "h": (1, 3),
+ "z": Counter({"a": 1, "b": 1, "c": 1}),
+ }
+
+ a = {"a": {"b": {"c": 5}}, "d": 1, "f": [1, 2, 3], "g": {1, 2, 3}, "z": Counter({"a": 1, "b": 1})}
+ a_copy = deepcopy(a)
+
+ b = {"a": {"B": {"C": 10}}, "d": 2, "f": [4, 5, 6], "g": {2, 3, 4}, "h": (1,)}
+ b_copy = deepcopy(b)
+
+ c = {"a": {"b": {"_c": 15}}, "d": 3, "h": (1, 3), "z": Counter({"a": 1, "c": 1})}
+ c_copy = deepcopy(c)
+
+ actual = merge({}, a, b, c, strategy=Strategy.TYPESAFE_REPLACE)
+
+ self.assertEqual(actual, expected)
+ self.assertEqual(a, a_copy)
+ self.assertEqual(b, b_copy)
+ self.assertEqual(c, c_copy)
+
+ ##############################################################################################################################
+ # TYPESAFE_ADDITIVE
+ ##############################################################################################################################
+
+ def test_should_raise_TypeError_using_typesafe_additive_strategy_if_types_differ(self,):
+ a = {"a": {"b": {"c": 5}}, "d": 1, "e": {2: 3}, "f": [1, 2, 3]}
+ b = {"a": {"B": {"C": 10}}, "d": 2, "e": 2, "f": [4, 5, 6]}
+ c = {"a": {"b": {"_c": 15}}, "d": 3, "e": {1: 2, "a": {"f": 2}}}
+
+ with self.assertRaises(TypeError):
+ merge({}, a, b, c, strategy=Strategy.TYPESAFE_ADDITIVE)
+
+ def test_should_merge_3_dicts_into_new_dict_using_typesafe_additive_strategy_and_only_mutate_target_if_types_are_compatible(
+ self,
+ ):
+ expected = {
+ "a": {"b": {"c": 5, "_c": 15}, "B": {"C": 10}},
+ "d": 3,
+ "f": [1, 2, 3, 4, 5, 6],
+ "g": {1, 2, 3, 4},
+ "h": (1, 1, 3),
+ "z": Counter({"a": 2, "b": 1, "c": 1}),
+ }
+
+ a = {"a": {"b": {"c": 5}}, "d": 1, "f": [1, 2, 3], "g": {1, 2, 3}, "z": Counter({"a": 1, "b": 1})}
+ a_copy = deepcopy(a)
+
+ b = {"a": {"B": {"C": 10}}, "d": 2, "f": [4, 5, 6], "g": {2, 3, 4}, "h": (1,)}
+ b_copy = deepcopy(b)
+
+ c = {"a": {"b": {"_c": 15}}, "d": 3, "h": (1, 3), "z": Counter({"a": 1, "c": 1})}
+ c_copy = deepcopy(c)
+
+ actual = merge({}, a, b, c, strategy=Strategy.TYPESAFE_ADDITIVE)
+
+ self.assertEqual(actual, expected)
+ self.assertEqual(a, a_copy)
+ self.assertEqual(b, b_copy)
+ self.assertEqual(c, c_copy)
+
+
+if __name__ == "__main__":
+ unittest.main()
diff --git a/venv/lib/python3.11/site-packages/mkdocs-1.4.2.dist-info/INSTALLER b/venv/lib/python3.11/site-packages/mkdocs-1.4.2.dist-info/INSTALLER
new file mode 100644
index 0000000..a1b589e
--- /dev/null
+++ b/venv/lib/python3.11/site-packages/mkdocs-1.4.2.dist-info/INSTALLER
@@ -0,0 +1 @@
+pip
diff --git a/venv/lib/python3.11/site-packages/mkdocs-1.4.2.dist-info/METADATA b/venv/lib/python3.11/site-packages/mkdocs-1.4.2.dist-info/METADATA
new file mode 100644
index 0000000..014896d
--- /dev/null
+++ b/venv/lib/python3.11/site-packages/mkdocs-1.4.2.dist-info/METADATA
@@ -0,0 +1,141 @@
+Metadata-Version: 2.1
+Name: mkdocs
+Version: 1.4.2
+Summary: Project documentation with Markdown.
+Project-URL: Documentation, https://www.mkdocs.org/
+Project-URL: Source, https://github.com/mkdocs/mkdocs
+Project-URL: Issues, https://github.com/mkdocs/mkdocs/issues
+Project-URL: History, https://www.mkdocs.org/about/release-notes/
+Author-email: Tom Christie
+License-File: LICENSE
+Classifier: Development Status :: 5 - Production/Stable
+Classifier: Environment :: Console
+Classifier: Environment :: Web Environment
+Classifier: Intended Audience :: Developers
+Classifier: License :: OSI Approved :: BSD License
+Classifier: Operating System :: OS Independent
+Classifier: Programming Language :: Python
+Classifier: Programming Language :: Python :: 3
+Classifier: Programming Language :: Python :: 3 :: Only
+Classifier: Programming Language :: Python :: 3.7
+Classifier: Programming Language :: Python :: 3.8
+Classifier: Programming Language :: Python :: 3.9
+Classifier: Programming Language :: Python :: 3.10
+Classifier: Programming Language :: Python :: 3.11
+Classifier: Programming Language :: Python :: Implementation :: CPython
+Classifier: Programming Language :: Python :: Implementation :: PyPy
+Classifier: Topic :: Documentation
+Classifier: Topic :: Text Processing
+Requires-Python: >=3.7
+Requires-Dist: click>=7.0
+Requires-Dist: colorama>=0.4; platform_system == 'Windows'
+Requires-Dist: ghp-import>=1.0
+Requires-Dist: importlib-metadata>=4.3; python_version < '3.10'
+Requires-Dist: jinja2>=2.11.1
+Requires-Dist: markdown<3.4,>=3.2.1
+Requires-Dist: mergedeep>=1.3.4
+Requires-Dist: packaging>=20.5
+Requires-Dist: pyyaml-env-tag>=0.1
+Requires-Dist: pyyaml>=5.1
+Requires-Dist: typing-extensions>=3.10; python_version < '3.8'
+Requires-Dist: watchdog>=2.0
+Provides-Extra: i18n
+Requires-Dist: babel>=2.9.0; extra == 'i18n'
+Provides-Extra: min-versions
+Requires-Dist: babel==2.9.0; extra == 'min-versions'
+Requires-Dist: click==7.0; extra == 'min-versions'
+Requires-Dist: colorama==0.4; platform_system == 'Windows' and extra == 'min-versions'
+Requires-Dist: ghp-import==1.0; extra == 'min-versions'
+Requires-Dist: importlib-metadata==4.3; python_version < '3.10' and extra == 'min-versions'
+Requires-Dist: jinja2==2.11.1; extra == 'min-versions'
+Requires-Dist: markdown==3.2.1; extra == 'min-versions'
+Requires-Dist: markupsafe==2.0.1; extra == 'min-versions'
+Requires-Dist: mergedeep==1.3.4; extra == 'min-versions'
+Requires-Dist: packaging==20.5; extra == 'min-versions'
+Requires-Dist: pyyaml-env-tag==0.1; extra == 'min-versions'
+Requires-Dist: pyyaml==5.1; extra == 'min-versions'
+Requires-Dist: typing-extensions==3.10; python_version < '3.8' and extra == 'min-versions'
+Requires-Dist: watchdog==2.0; extra == 'min-versions'
+Description-Content-Type: text/markdown
+
+# MkDocs
+
+> *Project documentation with Markdown*
+
+[![PyPI Version][pypi-v-image]][pypi-v-link]
+[![Build Status][GHAction-image]][GHAction-link]
+[![Coverage Status][codecov-image]][codecov-link]
+
+MkDocs is a **fast**, **simple** and **downright gorgeous** static site
+generator that's geared towards building project documentation. Documentation
+source files are written in Markdown, and configured with a single YAML
+configuration file. It is designed to be easy to use and can be extended with
+third-party themes, plugins, and Markdown extensions.
+
+Please see the [Documentation][mkdocs] for an introductory tutorial and a full
+user guide.
+
+## Features
+
+- Build static HTML files from Markdown files.
+- Use Plugins and Markdown Extensions to enhance MkDocs.
+- Use the built-in themes, third party themes or create your own.
+- Publish your documentation anywhere that static files can be served.
+- Much more!
+
+## Support
+
+If you need help with MkDocs, do not hesitate to get in contact with us!
+
+- For questions and high-level discussions, use **[Discussions]** on GitHub.
+ - For small questions, a good alternative is the **[Chat room]** on
+ Gitter/Matrix (**new!**)
+- To report a bug or make a feature request, open an **[Issue]** on GitHub.
+
+Please note that we may only provide
+support for problems/questions regarding core features of MkDocs. Any
+questions or bug reports about features of third-party themes, plugins,
+extensions or similar should be made to their respective projects.
+But, such questions are *not* banned from the [chat room].
+
+Make sure to stick around to answer some questions as well!
+
+## Links
+
+- [Official Documentation][mkdocs]
+- [Latest Release Notes][release-notes]
+- [MkDocs Wiki][wiki] (Third-party themes, recipes, plugins and more)
+- [Best-of-MkDocs][best-of] (Curated list of themes, plugins and more)
+
+## Contributing to MkDocs
+
+The MkDocs project welcomes, and depends on, contributions from developers and
+users in the open source community. Please see the [Contributing Guide] for
+information on how you can help.
+
+## Code of Conduct
+
+Everyone interacting in the MkDocs project's codebases, issue trackers, and
+discussion forums is expected to follow the [PyPA Code of Conduct].
+
+
+[codecov-image]: https://codecov.io/github/mkdocs/mkdocs/coverage.svg?branch=master
+[codecov-link]: https://codecov.io/github/mkdocs/mkdocs?branch=master
+[pypi-v-image]: https://img.shields.io/pypi/v/mkdocs.svg
+[pypi-v-link]: https://pypi.org/project/mkdocs/
+[GHAction-image]: https://github.com/mkdocs/mkdocs/workflows/CI/badge.svg?branch=master&event=push
+[GHAction-link]: https://github.com/mkdocs/mkdocs/actions?query=event%3Apush+branch%3Amaster
+
+[mkdocs]: https://www.mkdocs.org
+[Issue]: https://github.com/mkdocs/mkdocs/issues
+[Discussions]: https://github.com/mkdocs/mkdocs/discussions
+[Chat room]: https://gitter.im/mkdocs/community
+[release-notes]: https://www.mkdocs.org/about/release-notes/
+[wiki]: https://github.com/mkdocs/mkdocs/wiki
+[Contributing Guide]: https://www.mkdocs.org/about/contributing/
+[PyPA Code of Conduct]: https://www.pypa.io/en/latest/code-of-conduct/
+[best-of]: https://github.com/pawamoy/best-of-mkdocs
+
+## License
+
+[BSD-2-Clause](https://github.com/mkdocs/mkdocs/blob/master/LICENSE)
diff --git a/venv/lib/python3.11/site-packages/mkdocs-1.4.2.dist-info/RECORD b/venv/lib/python3.11/site-packages/mkdocs-1.4.2.dist-info/RECORD
new file mode 100644
index 0000000..397dfb0
--- /dev/null
+++ b/venv/lib/python3.11/site-packages/mkdocs-1.4.2.dist-info/RECORD
@@ -0,0 +1,234 @@
+../../../bin/mkdocs,sha256=XMlor_tXglN08NwHY2lJnIIuzH6zOpvX7KuC7WZgNhE,258
+mkdocs-1.4.2.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
+mkdocs-1.4.2.dist-info/METADATA,sha256=FG-DeWPymgLeTS90OjN5ZWcEUZfSqnSlDjcLv6N05qM,6077
+mkdocs-1.4.2.dist-info/RECORD,,
+mkdocs-1.4.2.dist-info/REQUESTED,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
+mkdocs-1.4.2.dist-info/WHEEL,sha256=NaLmgHHW_f9jTvv_wRh9vcK7c7EK9o5fwsIXMOzoGgM,87
+mkdocs-1.4.2.dist-info/entry_points.txt,sha256=olJ3d1HkCNSrkbCAKE5Rtk3y3YaJKBLqmK04Q_JtH18,196
+mkdocs-1.4.2.dist-info/licenses/LICENSE,sha256=JgQb1iX8OUEdxLMnSCFiNpMckErbkMKz4LppcJCl1U4,1292
+mkdocs/__init__.py,sha256=a8ZVS1HFkIubjWsQnxLW6qywf-DWspL-PCsP6FW2etQ,126
+mkdocs/__main__.py,sha256=_4amY4Cp24t4oanG_hax9wxK7ZqkK8R-x5cpNt4-91g,10053
+mkdocs/__pycache__/__init__.cpython-311.pyc,,
+mkdocs/__pycache__/__main__.cpython-311.pyc,,
+mkdocs/__pycache__/exceptions.cpython-311.pyc,,
+mkdocs/__pycache__/localization.cpython-311.pyc,,
+mkdocs/__pycache__/plugins.cpython-311.pyc,,
+mkdocs/__pycache__/theme.cpython-311.pyc,,
+mkdocs/commands/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
+mkdocs/commands/__pycache__/__init__.cpython-311.pyc,,
+mkdocs/commands/__pycache__/babel.cpython-311.pyc,,
+mkdocs/commands/__pycache__/build.cpython-311.pyc,,
+mkdocs/commands/__pycache__/gh_deploy.cpython-311.pyc,,
+mkdocs/commands/__pycache__/new.cpython-311.pyc,,
+mkdocs/commands/__pycache__/serve.cpython-311.pyc,,
+mkdocs/commands/__pycache__/setup.cpython-311.pyc,,
+mkdocs/commands/babel.py,sha256=2XShMkMCivg08KDR1PuClAkAgPbwJnTu6lirbuxnDZQ,4248
+mkdocs/commands/build.py,sha256=ppoB9iaSMVQtHcUoRBtmJS2DIJJlY4VfKVcVQMPC76A,12419
+mkdocs/commands/gh_deploy.py,sha256=q4R10QlPgZD_OsQTWba7bvXoWNxCBfA2WM7xE5w97FQ,5210
+mkdocs/commands/new.py,sha256=ZUAvcu8wSGsA3-5MPUPQ-xvmSFmaY8zrmz5HpfUU1SA,1454
+mkdocs/commands/serve.py,sha256=hWUMNPvOwY0XmJVuGC6JvpGCK9yHgOaV4fqPq6a3wq8,3920
+mkdocs/commands/setup.py,sha256=NbmuDGA27lAmt5S4JkQ47Cvu08QMhuJoA-HfjsAIHPc,525
+mkdocs/config/__init__.py,sha256=QWZu_iAoCERFc8db2BPveqifk9S0JP5EvflVFMjTSew,88
+mkdocs/config/__pycache__/__init__.cpython-311.pyc,,
+mkdocs/config/__pycache__/base.cpython-311.pyc,,
+mkdocs/config/__pycache__/config_options.cpython-311.pyc,,
+mkdocs/config/__pycache__/defaults.cpython-311.pyc,,
+mkdocs/config/base.py,sha256=rtsLpJceF_fAGX_QAVE-neBnGNdUs53lqZE5sZSBWfY,12679
+mkdocs/config/config_options.py,sha256=ZQyLud49NBIK1aZGmYag1LH2S5Y3amerMRIeRU2xIgs,37863
+mkdocs/config/defaults.py,sha256=rspVI6z0_7xFmymkNiY69S2FPQBL-DMDD1wHW0GQ1z0,5201
+mkdocs/contrib/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
+mkdocs/contrib/__pycache__/__init__.cpython-311.pyc,,
+mkdocs/contrib/search/__init__.py,sha256=B2T2PyrpggW0sPyzPzpUMxkQ9YNUWk35C9MjUc9ynSE,5189
+mkdocs/contrib/search/__pycache__/__init__.cpython-311.pyc,,
+mkdocs/contrib/search/__pycache__/search_index.cpython-311.pyc,,
+mkdocs/contrib/search/lunr-language/lunr.ar.js,sha256=KWIZhaTQM_htkigvG7aGTJEhHnb87NuVaEVh_4h88AI,24525
+mkdocs/contrib/search/lunr-language/lunr.da.js,sha256=s84Yrl2YBCFKkFiK5dvQBAqn9dldJr0kZM4OcE6BZ3c,10349
+mkdocs/contrib/search/lunr-language/lunr.de.js,sha256=aevkyhNU6cajut4vKiZxAoN6qceloNScot33X7WiFJ4,13949
+mkdocs/contrib/search/lunr-language/lunr.du.js,sha256=aLTkKil4PTimWAt06TcRpQRvOTEoG94fcrfIjz5hR_U,15330
+mkdocs/contrib/search/lunr-language/lunr.es.js,sha256=ZFlaaT3mAopuxvTWOGa4oCactnwa2tGeeWTOnrTSs9Y,24406
+mkdocs/contrib/search/lunr-language/lunr.fi.js,sha256=P_a2VUvpcNtFWbAd2yAT74QB0UP1hdlFJTeGbnHkB5c,20949
+mkdocs/contrib/search/lunr-language/lunr.fr.js,sha256=PrfCmo7XIjiA2G6Y19F-3xTIVg2_Gj5mUHY2cOq_CzQ,25654
+mkdocs/contrib/search/lunr-language/lunr.hu.js,sha256=431FjR-fL4jZf8i5Wih_d3zgGZU4euhAJLHBrihfw0g,21265
+mkdocs/contrib/search/lunr-language/lunr.it.js,sha256=pZdx24ksoGISiknws_6_nnHcuKYIzEOTLOQm60m4hA0,24077
+mkdocs/contrib/search/lunr-language/lunr.ja.js,sha256=gxodamZbyDrCP71-5ohunytnmXJZSgB-li9A5rf82pE,6125
+mkdocs/contrib/search/lunr-language/lunr.jp.js,sha256=6e9YiYWoxsFIKK0KE3veDFCEyYt5RsblRgwQzCuzoOs,273
+mkdocs/contrib/search/lunr-language/lunr.multi.js,sha256=sJag6Ct5xV3IO511BuuHHAxO-VMk4ksdmFgz3aLg-zk,3288
+mkdocs/contrib/search/lunr-language/lunr.nl.js,sha256=cvDNRkgL63I6RYCmwD8ZCL3XbXsvwWMDUv8wBqYi5sU,15134
+mkdocs/contrib/search/lunr-language/lunr.no.js,sha256=fOCrIH96sO-ij_Cqa68ZhIIntjZCoM_C5c2uVTwByvg,9947
+mkdocs/contrib/search/lunr-language/lunr.pt.js,sha256=82C6R_9_IUNBzg3yBYQQSInn-tz9GTk5AhOtOQcxtY4,22141
+mkdocs/contrib/search/lunr-language/lunr.ro.js,sha256=ia0RlHT_yWoXEZP3iFOPqOWr5w25X-AsH6oOWKEbSlg,23151
+mkdocs/contrib/search/lunr-language/lunr.ru.js,sha256=VbLHc0n3DxJ4JNFYOehAMx5d3QjCg6YFCXTZ7tUMFYo,19108
+mkdocs/contrib/search/lunr-language/lunr.stemmer.support.js,sha256=ms-xIarhB4KNxU8Vz3ee9KFRzaqt4Vi-cFom5uluxhg,13504
+mkdocs/contrib/search/lunr-language/lunr.sv.js,sha256=fJp5i-qIwJ2SNHt6bNIV5jBTfN-CPxr87703UbKYsYc,9635
+mkdocs/contrib/search/lunr-language/lunr.th.js,sha256=9BSwInusveB68Zv-7_-nC_-hcDYEWyUHTSjBK4xdApM,3111
+mkdocs/contrib/search/lunr-language/lunr.tr.js,sha256=TkDHrtJbAm8hhr8Wg4nS0HQp7hnAM0eX2mCSJTL2azU,38283
+mkdocs/contrib/search/lunr-language/lunr.vi.js,sha256=c9PegCJZRrb-FfGDBUEY1qEgXPk1auWM8Imj9que5S0,2558
+mkdocs/contrib/search/lunr-language/tinyseg.js,sha256=GwRMI5YQ72X87_YDlWdEK7FpLUE_Xuhob-6BsaMGd2E,22878
+mkdocs/contrib/search/prebuild-index.js,sha256=uZ2PjuhG4_wowoQeM2yGAWozPXqosQSCNQYlS_YQ5d8,1496
+mkdocs/contrib/search/search_index.py,sha256=KKDzSuetllPTJ8AZE7M19Op-bcBzpdmlwPeWs8wD7n0,7971
+mkdocs/contrib/search/templates/search/lunr.js,sha256=waKNnpUWMpL7zAf_eU8fDhreh0HFE6_pbVsQRqGBELw,99805
+mkdocs/contrib/search/templates/search/main.js,sha256=IpYbNFzrqbOpFGV3GQZyp7HGiBu4TAW-weLQ86MxI4k,3206
+mkdocs/contrib/search/templates/search/worker.js,sha256=tIbqtmgtArfG7HvclluwUWYe4sakK7NEK1Wcssbixzw,3724
+mkdocs/exceptions.py,sha256=OOxORb7vnJsovyB6Ug1NQBEeK__uX9DGsHuSWjaLrHg,944
+mkdocs/livereload/__init__.py,sha256=75i28ybEMZur50z2KWvj4jiGqlRn2CoZUiPxTATHp68,12427
+mkdocs/livereload/__pycache__/__init__.cpython-311.pyc,,
+mkdocs/localization.py,sha256=5amL-uXGZAViPKxn1XR_yF6kTXbwrC_Rgxf9jCcK1yE,2837
+mkdocs/plugins.py,sha256=lpaXqkezv_jfUvAdVdKhL4vsEXMgXkvj0-DV4iXUqI0,18066
+mkdocs/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
+mkdocs/structure/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
+mkdocs/structure/__pycache__/__init__.cpython-311.pyc,,
+mkdocs/structure/__pycache__/files.cpython-311.pyc,,
+mkdocs/structure/__pycache__/nav.cpython-311.pyc,,
+mkdocs/structure/__pycache__/pages.cpython-311.pyc,,
+mkdocs/structure/__pycache__/toc.cpython-311.pyc,,
+mkdocs/structure/files.py,sha256=w-0dYN2hl0IF1k5rQsd1AndW6DG5zNZJnBMkL5i8_OU,12620
+mkdocs/structure/nav.py,sha256=1OM28KRS0M8WSHqw8B0IzflmngfsGXAQMfolL8cv-cY,8411
+mkdocs/structure/pages.py,sha256=E2I1rOt4QMCJjGszShsn1COsGOVXasBg42alDr5ujCg,12516
+mkdocs/structure/toc.py,sha256=H78Q4dleJs_GPchhIG8Yh82kO8Mf_AKnM_OKPqqjafo,2059
+mkdocs/templates/sitemap.xml,sha256=gk83OIsq3F-b2mE_nLE-wg4j0NbiihLi9n3XIATtM8E,488
+mkdocs/tests/__init__.py,sha256=nyiYo2lVWVolGmS_g8LiaCNv4gv5Y67aFjNg0qk2y_g,390
+mkdocs/tests/__pycache__/__init__.cpython-311.pyc,,
+mkdocs/tests/__pycache__/base.cpython-311.pyc,,
+mkdocs/tests/__pycache__/build_tests.cpython-311.pyc,,
+mkdocs/tests/__pycache__/cli_tests.cpython-311.pyc,,
+mkdocs/tests/__pycache__/gh_deploy_tests.cpython-311.pyc,,
+mkdocs/tests/__pycache__/integration.cpython-311.pyc,,
+mkdocs/tests/__pycache__/livereload_tests.cpython-311.pyc,,
+mkdocs/tests/__pycache__/localization_tests.cpython-311.pyc,,
+mkdocs/tests/__pycache__/new_tests.cpython-311.pyc,,
+mkdocs/tests/__pycache__/plugin_tests.cpython-311.pyc,,
+mkdocs/tests/__pycache__/search_tests.cpython-311.pyc,,
+mkdocs/tests/__pycache__/theme_tests.cpython-311.pyc,,
+mkdocs/tests/base.py,sha256=OXB-556EaQqyY8WDgM-8kMkj51FdmeqZAMBItBrMKsI,4823
+mkdocs/tests/build_tests.py,sha256=AN92Vt8jDqUs-wjFj0n6e5nOQ2JMUOcZ5Vz8qwynWcs,24365
+mkdocs/tests/cli_tests.py,sha256=LZZuEPT126U7U5-h_jcYDuf2TEDNEnloF1ji7Z94X3Y,24797
+mkdocs/tests/config/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
+mkdocs/tests/config/__pycache__/__init__.cpython-311.pyc,,
+mkdocs/tests/config/__pycache__/base_tests.cpython-311.pyc,,
+mkdocs/tests/config/__pycache__/config_options_legacy_tests.cpython-311.pyc,,
+mkdocs/tests/config/__pycache__/config_options_tests.cpython-311.pyc,,
+mkdocs/tests/config/__pycache__/config_tests.cpython-311.pyc,,
+mkdocs/tests/config/base_tests.py,sha256=fDDlSt_ngrSq85AIFYssTsrGgOt4qez631BvBcMkBGI,10661
+mkdocs/tests/config/config_options_legacy_tests.py,sha256=Hxy87ZidvCWDEVh72V4W0t5Bv9ARdrmpnBq9y7avkkk,54779
+mkdocs/tests/config/config_options_tests.py,sha256=7AfvPBfYU0IFh4ZPu2hxTSZUG6mXW6L68kBBx50eWDU,71711
+mkdocs/tests/config/config_tests.py,sha256=Td3Y6DBiRnQOpifhztEzyfBG2XHOw8fgB9BQG84g1Fw,10923
+mkdocs/tests/gh_deploy_tests.py,sha256=Db5xXwm_rTxg-LM_bMqaX7kICL_ODPhOp5IX5D3yjds,7562
+mkdocs/tests/integration.py,sha256=ECRcpx4MymxMekJzhnjpU6TRefwdoUsxupcnirpv1pM,2091
+mkdocs/tests/livereload_tests.py,sha256=CEHl8cP-yZohpd3Z20k8oWYj6kPoDS11xnKfAXs5pMw,24185
+mkdocs/tests/localization_tests.py,sha256=bbugTLthpQ0Cj56JGjtZQOgs0-pSZq0B5OTxznzUNCE,2643
+mkdocs/tests/new_tests.py,sha256=dP2Biob1Xt9yMoFtgqd-SzeVEvFAkpr2ii0yCClvMEI,699
+mkdocs/tests/plugin_tests.py,sha256=eiWvmFqsDcWDhmgXI9Rfla1WZqHtwpRTLoY3F6mvvlw,10621
+mkdocs/tests/search_tests.py,sha256=hY9Y9LRNGa5qopQXW3ImtwwtBaC9iDXxG9mDn3DaTCw,24519
+mkdocs/tests/structure/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
+mkdocs/tests/structure/__pycache__/__init__.cpython-311.pyc,,
+mkdocs/tests/structure/__pycache__/file_tests.cpython-311.pyc,,
+mkdocs/tests/structure/__pycache__/nav_tests.cpython-311.pyc,,
+mkdocs/tests/structure/__pycache__/page_tests.cpython-311.pyc,,
+mkdocs/tests/structure/__pycache__/toc_tests.cpython-311.pyc,,
+mkdocs/tests/structure/file_tests.py,sha256=CmTHjpZZTVfUHEOoCkBWn59YsLtZIaMdOFSA71X_-WE,34583
+mkdocs/tests/structure/nav_tests.py,sha256=gJxy575NWweLfyWMKw4BW00Rt4TVYsQ80m8FfeSLFJg,19542
+mkdocs/tests/structure/page_tests.py,sha256=mDXJBaryDIuQz8nUFYp-fthCR5uSOz-DFA1VZgflLcQ,35316
+mkdocs/tests/structure/toc_tests.py,sha256=htRucdDv02kw8LGofTZBgfOS9OlP5S5lUqUWswRCDhA,5255
+mkdocs/tests/theme_tests.py,sha256=VUzdiwdoW3-RHkoFlYFSwtMC3uns8CxMJiMZJ6LKFqU,3587
+mkdocs/tests/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
+mkdocs/tests/utils/__pycache__/__init__.cpython-311.pyc,,
+mkdocs/tests/utils/__pycache__/babel_stub_tests.cpython-311.pyc,,
+mkdocs/tests/utils/__pycache__/utils_tests.cpython-311.pyc,,
+mkdocs/tests/utils/babel_stub_tests.py,sha256=_SXcWCDSWMM8Obf3K0FVvxCRrUHfeRrnw39dgaFgOps,1931
+mkdocs/tests/utils/utils_tests.py,sha256=v156b8OM3orwDTNVR9UM_Ko3ksTOxUY8ebTDOfHGfDA,24084
+mkdocs/theme.py,sha256=Bxvw_WTTyPUd2WYLCYjfKTVnFI8RAJ8i4oiOAC3BhyI,4190
+mkdocs/themes/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
+mkdocs/themes/__pycache__/__init__.cpython-311.pyc,,
+mkdocs/themes/mkdocs/404.html,sha256=D6zQ5J04vvm4V58PBOCdCvyCuLcEZ9w7svhEDmRYfTE,332
+mkdocs/themes/mkdocs/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
+mkdocs/themes/mkdocs/__pycache__/__init__.cpython-311.pyc,,
+mkdocs/themes/mkdocs/base.html,sha256=xIU7GJZRnWoK20fMjQdrTvLnBUbRbrc_GuuOJ9bsLr0,10923
+mkdocs/themes/mkdocs/content.html,sha256=5y0Am5t8KXfR7lG9eBowCLc-xgXTl6VIpVFLH1VgK_I,204
+mkdocs/themes/mkdocs/css/base.css,sha256=nWGvsZMANRX-SYcCxZm5N5r7ruoKtgiueSQjnmAA5nk,6746
+mkdocs/themes/mkdocs/css/bootstrap.min.css,sha256=xruBsld6Jatcc6F_apXkADl-PVaUqUopEohlYxlDgdo,163091
+mkdocs/themes/mkdocs/css/font-awesome.min.css,sha256=eZrrJcwDc_3uDhsdt61sL2oOBY362qM3lon1gyExkL0,31000
+mkdocs/themes/mkdocs/fonts/fontawesome-webfont.eot,sha256=e_yrbbmdXPvxcFygU23ceFhUMsxfpBu9etDwCQM7KXk,165742
+mkdocs/themes/mkdocs/fonts/fontawesome-webfont.svg,sha256=rWFXkmwWIrpOHQPUePFUE2hSS_xG9R5C_g2UX37zI-Q,444379
+mkdocs/themes/mkdocs/fonts/fontawesome-webfont.ttf,sha256=qljzPyOaD7AvXHpsRcBD16msmgkzNYBmlOzW1O3A1qg,165548
+mkdocs/themes/mkdocs/fonts/fontawesome-webfont.woff,sha256=ugxZ3rVFD1y0Gz-TYJ7i0NmVQVh33foiPoqKdTNHTwc,98024
+mkdocs/themes/mkdocs/fonts/fontawesome-webfont.woff2,sha256=Kt78vAQefRj88tQXh53FoJmXqmTWdbejxLbOM9oT8_4,77160
+mkdocs/themes/mkdocs/img/favicon.ico,sha256=8WtFvVP7rKos2PIuhILbXFngzvm9ITlEdKQpoYqY_9A,1150
+mkdocs/themes/mkdocs/img/grid.png,sha256=bipYUDSUpwgQWsZG069cCMjIkDJbt4GiV9EPkf-Wipw,1458
+mkdocs/themes/mkdocs/js/base.js,sha256=hISFsIgpzIOhFxU6WbxLxSosJm_qWQhVbcDydvruHco,7725
+mkdocs/themes/mkdocs/js/bootstrap.min.js,sha256=4YT0BjgBCO15e_nQ7r1JsxTTYPiYgq7jaudxkkpBLn0,58073
+mkdocs/themes/mkdocs/js/jquery-1.10.2.min.js,sha256=C6CB9UYIS9UJeqinPHWTHVqh_E1uhG5Twh-Y5qFQmYg,93107
+mkdocs/themes/mkdocs/keyboard-modal.html,sha256=BrP91HXs2LnaVyo4yZbsoG0McjMdMLCwWv5WH0tJmbU,1749
+mkdocs/themes/mkdocs/locales/de/LC_MESSAGES/messages.mo,sha256=yegi12BDlTk_ZWDmkBRJzyN99YvJKDHCjZS7eI1XEOU,1519
+mkdocs/themes/mkdocs/locales/es/LC_MESSAGES/messages.mo,sha256=jBb0DyCdb29LzfUN4ahCdsJW4aBbhi15hjLFA9smwco,1515
+mkdocs/themes/mkdocs/locales/fa/LC_MESSAGES/messages.mo,sha256=lsk9r5-h41VnhF7PAatW3dy0fZjSrzHvRJlGyjLaqP0,1619
+mkdocs/themes/mkdocs/locales/fr/LC_MESSAGES/messages.mo,sha256=63Co-bSNiqF0gpBgRsp59iORXOveYrmAX9LpSCM2-ro,1436
+mkdocs/themes/mkdocs/locales/it/LC_MESSAGES/messages.mo,sha256=C64siaQL0zyxh3gQU4qVwVwgnoDyQUUm2jpon-8nrYQ,1496
+mkdocs/themes/mkdocs/locales/ja/LC_MESSAGES/messages.mo,sha256=myh3yQpfOgrTNN3yoXBLYmlmRkj-Ez2KUsGx98PHBOw,1548
+mkdocs/themes/mkdocs/locales/nb/LC_MESSAGES/messages.mo,sha256=umBQPQ00MtXG_lMFWBAG6OAVJN1vAyjklPKCS3AR43o,1452
+mkdocs/themes/mkdocs/locales/nn/LC_MESSAGES/messages.mo,sha256=zjvg4NI9is9OxSljFwdk4I8lNH-w-LLGwg89iD2UYJU,1433
+mkdocs/themes/mkdocs/locales/pt_BR/LC_MESSAGES/messages.mo,sha256=OJZcWoVPq_mOOQ2sYrmmi3hFDbaKdaeQC06Cmi_04wo,1503
+mkdocs/themes/mkdocs/locales/ru/LC_MESSAGES/messages.mo,sha256=PeiYA5onGuY-o8poquD_Ou5DmaFsgpoZErHtQuShKWU,1842
+mkdocs/themes/mkdocs/locales/tr_TR/LC_MESSAGES/messages.mo,sha256=WGRfVTj3AKXuNubSes2djRhd6hWzbqa5jVKH26CPuXA,1461
+mkdocs/themes/mkdocs/locales/uk/LC_MESSAGES/messages.mo,sha256=2Ps7hvqeocC6xcLfgiP55Z47u2_adyIJ2juzdaSGqnI,1767
+mkdocs/themes/mkdocs/locales/zh_CN/LC_MESSAGES/messages.mo,sha256=IrypOJJwdjZwhgncB46A_RH15wC8XY8L4Qez9mGf-7Y,1449
+mkdocs/themes/mkdocs/main.html,sha256=vjPt1rM1f5zFcD_eOLeXAMaaxqA30qUp2UKE5ydTa70,379
+mkdocs/themes/mkdocs/mkdocs_theme.yml,sha256=a0CO9AhzeKgmaYOVlYhsNmVHc8q9SDC15qE7Ew3bnA0,353
+mkdocs/themes/mkdocs/nav-sub.html,sha256=5urEtZ7CAT-n9icHlwmNthEwUVJZ0837KtaBJ3EEWMg,450
+mkdocs/themes/mkdocs/search-modal.html,sha256=blFGknDHm2iXmBWkPb9mrJtGGXO9LjDvs8Dsropylgs,1244
+mkdocs/themes/mkdocs/toc.html,sha256=3_w6LQcnvQVs3IW7B92VjtToExsXrt1q0K1rnAqy93g,1077
+mkdocs/themes/readthedocs/404.html,sha256=YvoXdUQRPCqPIvhZFc8QwS3HxeKycu7Ddv8hErcQ2so,170
+mkdocs/themes/readthedocs/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
+mkdocs/themes/readthedocs/__pycache__/__init__.cpython-311.pyc,,
+mkdocs/themes/readthedocs/base.html,sha256=u7__I3IqCKtECIA_ljgChPVTwVKyU-K2oZo-prS-gFQ,7479
+mkdocs/themes/readthedocs/breadcrumbs.html,sha256=6Zt71e7VIX-aAhyIYB3QCtlVLV8GHAsHsFeiZmC0H3U,2425
+mkdocs/themes/readthedocs/css/fonts/Roboto-Slab-Bold.woff,sha256=n-yHytviQTslXx7Fd1c6g_HKLhw3qgI9vrzTp7hkY2o,87624
+mkdocs/themes/readthedocs/css/fonts/Roboto-Slab-Bold.woff2,sha256=GgwCTdGiZ8UtVXVGn_6FcNHoQWTefTk880FLr9F9egw,67312
+mkdocs/themes/readthedocs/css/fonts/Roboto-Slab-Regular.woff,sha256=nzJjDiwMUTW_HobjbLZbOTLkQQZEI1vCvZlenH9v8Rc,86288
+mkdocs/themes/readthedocs/css/fonts/Roboto-Slab-Regular.woff2,sha256=h05CIihW168Ds_Q40h2SOkKA1H_mfEhRDiF0oVeXle8,66444
+mkdocs/themes/readthedocs/css/fonts/fontawesome-webfont.eot,sha256=e_yrbbmdXPvxcFygU23ceFhUMsxfpBu9etDwCQM7KXk,165742
+mkdocs/themes/readthedocs/css/fonts/fontawesome-webfont.svg,sha256=rWFXkmwWIrpOHQPUePFUE2hSS_xG9R5C_g2UX37zI-Q,444379
+mkdocs/themes/readthedocs/css/fonts/fontawesome-webfont.ttf,sha256=qljzPyOaD7AvXHpsRcBD16msmgkzNYBmlOzW1O3A1qg,165548
+mkdocs/themes/readthedocs/css/fonts/fontawesome-webfont.woff,sha256=ugxZ3rVFD1y0Gz-TYJ7i0NmVQVh33foiPoqKdTNHTwc,98024
+mkdocs/themes/readthedocs/css/fonts/fontawesome-webfont.woff2,sha256=Kt78vAQefRj88tQXh53FoJmXqmTWdbejxLbOM9oT8_4,77160
+mkdocs/themes/readthedocs/css/fonts/lato-bold-italic.woff,sha256=mAyFkuVIjfJWGSyZnpLbj9MC24zYkJt_omamhON-Rfg,323344
+mkdocs/themes/readthedocs/css/fonts/lato-bold-italic.woff2,sha256=wJFqMzQNBj97BWeeCAMecp0YiERHBvBIBHBdpZZtiV0,193308
+mkdocs/themes/readthedocs/css/fonts/lato-bold.woff,sha256=DlaxfRQus2bIAHAx0U402kjHC0qdmgykkuaWp7rkXh4,309728
+mkdocs/themes/readthedocs/css/fonts/lato-bold.woff2,sha256=roj8DXqWGDL4CVJ9ML05g6aGbUL2alat4j9UNoFZTbY,184912
+mkdocs/themes/readthedocs/css/fonts/lato-normal-italic.woff,sha256=JjGKFGel5crxCwTPqULQeWMlYM16Kc7FZf0dyffsUIE,328412
+mkdocs/themes/readthedocs/css/fonts/lato-normal-italic.woff2,sha256=RGV2Xy9u3c2tNP_XyrVZ5WvA515F4ZL4XpVisHcUgdw,195704
+mkdocs/themes/readthedocs/css/fonts/lato-normal.woff,sha256=W5Al3aTXaI4zEbDBft3FARM7gH3vM-_672WThDz1QW4,309192
+mkdocs/themes/readthedocs/css/fonts/lato-normal.woff2,sha256=mDsMrzNuhUIhT8FwGaT8XgNghkuSgGyhTVXB_BwsWg8,182708
+mkdocs/themes/readthedocs/css/theme.css,sha256=OCpMJySY2Vaqcf3Am8UOoCjkOwzFL6m58j6ztpVF_cU,129978
+mkdocs/themes/readthedocs/css/theme_extra.css,sha256=H7gaSznvkQvlZl-rlqDeDfX8eBpS4ZX4Fr2LfwKh6P4,4597
+mkdocs/themes/readthedocs/footer.html,sha256=shbgVOV5yIMWGSImSbQAskQ-5XjJcV0f0NM3qUOJZ2s,1327
+mkdocs/themes/readthedocs/img/favicon.ico,sha256=8WtFvVP7rKos2PIuhILbXFngzvm9ITlEdKQpoYqY_9A,1150
+mkdocs/themes/readthedocs/js/html5shiv.min.js,sha256=PUWPUbxVn3hVmV4h_SIlwy9mDWA5cCZ7N2wje-wIIy8,2731
+mkdocs/themes/readthedocs/js/jquery-3.6.0.min.js,sha256=_xUj-3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej_m4,89501
+mkdocs/themes/readthedocs/js/theme.js,sha256=D3YjS4pbI9hqQZNUCZY9HiAkamKY7gv8cfiAyDDugNY,5075
+mkdocs/themes/readthedocs/js/theme_extra.js,sha256=e3_jPqSn2juCqhUfdHo6RUnV8dgbtXdnWbyQmdm1C0Y,195
+mkdocs/themes/readthedocs/locales/de/LC_MESSAGES/messages.mo,sha256=GVQKBnC7M6L6F0fIKfsO5xZ8rHkgqZIf5LZ3E6zZmhs,1500
+mkdocs/themes/readthedocs/locales/es/LC_MESSAGES/messages.mo,sha256=uB6KMkg_bhk-x6yaQP7qbEqO_9BXCJwMC6R1EPYIILs,1540
+mkdocs/themes/readthedocs/locales/fa/LC_MESSAGES/messages.mo,sha256=NjDrnWNa2C_x0LIHj2wZt1oxFvFhs8TFYLOVUFxNKtk,1605
+mkdocs/themes/readthedocs/locales/fr/LC_MESSAGES/messages.mo,sha256=ESKwH_RbRRKlV1KVvyvdODrw4KkKV-m4k9Y2Moo5G-E,1513
+mkdocs/themes/readthedocs/locales/it/LC_MESSAGES/messages.mo,sha256=4nT9acx9se8CIkdQO00eHQtMKUYRPC9-yPf3uS7MhJI,1521
+mkdocs/themes/readthedocs/locales/ja/LC_MESSAGES/messages.mo,sha256=_gMLKgaRmtFYomFrgge4KEhAntR4UrZTldGscXlCnKM,1605
+mkdocs/themes/readthedocs/locales/pt_BR/LC_MESSAGES/messages.mo,sha256=iqR0a7FCRFg9kaM6KVqDYTQASB27PQSSu6ILYy27g0A,1496
+mkdocs/themes/readthedocs/locales/ru/LC_MESSAGES/messages.mo,sha256=IM6oWSqlvhjp9JhUmNMB6t87s5LX6hRRTI9-xiDG9Y4,1836
+mkdocs/themes/readthedocs/locales/tr_TR/LC_MESSAGES/messages.mo,sha256=vYR4fGVphoZh37QTU7YNM--rI5VCmtbmVPBTekNTVUY,1496
+mkdocs/themes/readthedocs/locales/uk/LC_MESSAGES/messages.mo,sha256=SYmZBwtaxGHcrpA1IlIWEXKIrXPZTZWQUPeYhO_p5pU,1791
+mkdocs/themes/readthedocs/locales/zh_CN/LC_MESSAGES/messages.mo,sha256=ATf3Nn0zk4_Gob4Aa_a0MF-fYaA_ob1rmWLvX0zWLfc,1448
+mkdocs/themes/readthedocs/main.html,sha256=1nUyTMexotyrwn-qGEO4cWfocvcDwbGj0wIWAUOaNkU,384
+mkdocs/themes/readthedocs/mkdocs_theme.yml,sha256=jEdSVjqXCjJs7SAE65UkrYW3MhRQOiz8ZKGLr6AtLxE,394
+mkdocs/themes/readthedocs/nav.html,sha256=7IRI2_Lr3GQy5zM4L86cz4A3es7hm7LhzDO_7FnJlt8,1127
+mkdocs/themes/readthedocs/search.html,sha256=c0QtnLvaqGsIr0-Au35rM-7EEB5RseGGaKK90PtdyWM,703
+mkdocs/themes/readthedocs/searchbox.html,sha256=773WSXL3Pjhw6KtS51hAaP5O-Tsij9obyKCOjD0kOkM,276
+mkdocs/themes/readthedocs/toc.html,sha256=lpYBKPgs-3vLAqpbXHHi-fvjIg84TeXMcoYleNEUjp4,486
+mkdocs/themes/readthedocs/versions.html,sha256=ELq1eNLG4nQA1Re9yYFsOgFfFrIm3dPqxiPEujMcFjw,1070
+mkdocs/utils/__init__.py,sha256=YF21KpzGiV7Fj9O6N6ZI7QKBU4XD5fgVgpmtm0Qw0fw,13718
+mkdocs/utils/__pycache__/__init__.cpython-311.pyc,,
+mkdocs/utils/__pycache__/babel_stub.cpython-311.pyc,,
+mkdocs/utils/__pycache__/filters.cpython-311.pyc,,
+mkdocs/utils/__pycache__/meta.cpython-311.pyc,,
+mkdocs/utils/babel_stub.py,sha256=m27PHctJhwsjPlesAlE5l9ovZlw47MKsNvWi1QuAuW8,860
+mkdocs/utils/filters.py,sha256=7PRrYsdOAuau6gnspqzOH4sZWNqoZFAAxDHkMkSizA4,411
+mkdocs/utils/meta.py,sha256=CzTlsjEmITGDvu0xhjqsZX_sQyi1hI_cg4kZd8hmPFM,3673
diff --git a/venv/lib/python3.11/site-packages/mkdocs-1.4.2.dist-info/REQUESTED b/venv/lib/python3.11/site-packages/mkdocs-1.4.2.dist-info/REQUESTED
new file mode 100644
index 0000000..e69de29
diff --git a/venv/lib/python3.11/site-packages/mkdocs-1.4.2.dist-info/WHEEL b/venv/lib/python3.11/site-packages/mkdocs-1.4.2.dist-info/WHEEL
new file mode 100644
index 0000000..6d80365
--- /dev/null
+++ b/venv/lib/python3.11/site-packages/mkdocs-1.4.2.dist-info/WHEEL
@@ -0,0 +1,4 @@
+Wheel-Version: 1.0
+Generator: hatchling 1.11.1
+Root-Is-Purelib: true
+Tag: py3-none-any
diff --git a/venv/lib/python3.11/site-packages/mkdocs-1.4.2.dist-info/entry_points.txt b/venv/lib/python3.11/site-packages/mkdocs-1.4.2.dist-info/entry_points.txt
new file mode 100644
index 0000000..7404b2b
--- /dev/null
+++ b/venv/lib/python3.11/site-packages/mkdocs-1.4.2.dist-info/entry_points.txt
@@ -0,0 +1,9 @@
+[console_scripts]
+mkdocs = mkdocs.__main__:cli
+
+[mkdocs.plugins]
+search = mkdocs.contrib.search:SearchPlugin
+
+[mkdocs.themes]
+mkdocs = mkdocs.themes.mkdocs
+readthedocs = mkdocs.themes.readthedocs
diff --git a/venv/lib/python3.11/site-packages/mkdocs-1.4.2.dist-info/licenses/LICENSE b/venv/lib/python3.11/site-packages/mkdocs-1.4.2.dist-info/licenses/LICENSE
new file mode 100644
index 0000000..7bb5073
--- /dev/null
+++ b/venv/lib/python3.11/site-packages/mkdocs-1.4.2.dist-info/licenses/LICENSE
@@ -0,0 +1,26 @@
+Copyright © 2014-present, Tom Christie. All rights reserved.
+
+Redistribution and use in source and binary forms, with or
+without modification, are permitted provided that the following
+conditions are met:
+
+Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+Redistributions in binary form must reproduce the above copyright
+notice, this list of conditions and the following disclaimer in
+the documentation and/or other materials provided with the
+distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
diff --git a/venv/lib/python3.11/site-packages/mkdocs/__init__.py b/venv/lib/python3.11/site-packages/mkdocs/__init__.py
new file mode 100644
index 0000000..2c22232
--- /dev/null
+++ b/venv/lib/python3.11/site-packages/mkdocs/__init__.py
@@ -0,0 +1,5 @@
+#!/usr/bin/env python
+
+
+# For acceptable version formats, see https://www.python.org/dev/peps/pep-0440/
+__version__ = '1.4.2'
diff --git a/venv/lib/python3.11/site-packages/mkdocs/__main__.py b/venv/lib/python3.11/site-packages/mkdocs/__main__.py
new file mode 100644
index 0000000..84e7d3f
--- /dev/null
+++ b/venv/lib/python3.11/site-packages/mkdocs/__main__.py
@@ -0,0 +1,301 @@
+#!/usr/bin/env python
+
+from __future__ import annotations
+
+import logging
+import os
+import shutil
+import sys
+import textwrap
+import traceback
+import warnings
+
+import click
+
+from mkdocs import __version__, config, utils
+
+if sys.platform.startswith("win"):
+ try:
+ import colorama
+ except ImportError:
+ pass
+ else:
+ colorama.init()
+
+log = logging.getLogger(__name__)
+
+
+def _showwarning(message, category, filename, lineno, file=None, line=None):
+ try:
+ # Last stack frames:
+ # * ...
+ # * Location of call to deprecated function <-- include this
+ # * Location of call to warn() <-- include this
+ # * (stdlib) Location of call to showwarning function
+ # * (this function) Location of call to extract_stack()
+ stack = [frame for frame in traceback.extract_stack() if frame.line][-4:-2]
+ # Make sure the actual affected file's name is still present (the case of syntax warning):
+ if not any(frame.filename == filename for frame in stack):
+ stack = stack[-1:] + [traceback.FrameSummary(filename, lineno, '')]
+
+ tb = ''.join(traceback.format_list(stack))
+ except Exception:
+ tb = f' File "{filename}", line {lineno}'
+
+ log.info(f'{category.__name__}: {message}\n{tb}')
+
+
+def _enable_warnings():
+ warnings.simplefilter('module', DeprecationWarning)
+ warnings.showwarning = _showwarning
+
+
+class ColorFormatter(logging.Formatter):
+ colors = {
+ 'CRITICAL': 'red',
+ 'ERROR': 'red',
+ 'WARNING': 'yellow',
+ 'DEBUG': 'blue',
+ }
+
+ text_wrapper = textwrap.TextWrapper(
+ width=shutil.get_terminal_size(fallback=(0, 0)).columns,
+ replace_whitespace=False,
+ break_long_words=False,
+ break_on_hyphens=False,
+ initial_indent=' ' * 12,
+ subsequent_indent=' ' * 12,
+ )
+
+ def format(self, record):
+ message = super().format(record)
+ prefix = f'{record.levelname:<8} - '
+ if record.levelname in self.colors:
+ prefix = click.style(prefix, fg=self.colors[record.levelname])
+ if self.text_wrapper.width:
+ # Only wrap text if a terminal width was detected
+ msg = '\n'.join(self.text_wrapper.fill(line) for line in message.splitlines())
+ # Prepend prefix after wrapping so that color codes don't affect length
+ return prefix + msg[12:]
+ return prefix + message
+
+
+class State:
+ """Maintain logging level."""
+
+ def __init__(self, log_name='mkdocs', level=logging.INFO):
+ self.logger = logging.getLogger(log_name)
+ # Don't restrict level on logger; use handler
+ self.logger.setLevel(1)
+ self.logger.propagate = False
+
+ self.stream = logging.StreamHandler()
+ self.stream.setFormatter(ColorFormatter())
+ self.stream.setLevel(level)
+ self.stream.name = 'MkDocsStreamHandler'
+ self.logger.addHandler(self.stream)
+
+ def __del__(self):
+ self.logger.removeHandler(self.stream)
+
+
+pass_state = click.make_pass_decorator(State, ensure=True)
+
+clean_help = "Remove old files from the site_dir before building (the default)."
+config_help = "Provide a specific MkDocs config"
+dev_addr_help = "IP address and port to serve documentation locally (default: localhost:8000)"
+strict_help = "Enable strict mode. This will cause MkDocs to abort the build on any warnings."
+theme_help = "The theme to use when building your documentation."
+theme_choices = sorted(utils.get_theme_names())
+site_dir_help = "The directory to output the result of the documentation build."
+use_directory_urls_help = "Use directory URLs when building pages (the default)."
+reload_help = "Enable the live reloading in the development server (this is the default)"
+no_reload_help = "Disable the live reloading in the development server."
+dirty_reload_help = (
+ "Enable the live reloading in the development server, but only re-build files that have changed"
+)
+commit_message_help = (
+ "A commit message to use when committing to the "
+ "GitHub Pages remote branch. Commit {sha} and MkDocs {version} are available as expansions"
+)
+remote_branch_help = (
+ "The remote branch to commit to for GitHub Pages. This "
+ "overrides the value specified in config"
+)
+remote_name_help = (
+ "The remote name to commit to for GitHub Pages. This overrides the value specified in config"
+)
+force_help = "Force the push to the repository."
+no_history_help = "Replace the whole Git history with one new commit."
+ignore_version_help = (
+ "Ignore check that build is not being deployed with an older version of MkDocs."
+)
+watch_theme_help = (
+ "Include the theme in list of files to watch for live reloading. "
+ "Ignored when live reload is not used."
+)
+shell_help = "Use the shell when invoking Git."
+watch_help = "A directory or file to watch for live reloading. Can be supplied multiple times."
+
+
+def add_options(*opts):
+ def inner(f):
+ for i in reversed(opts):
+ f = i(f)
+ return f
+
+ return inner
+
+
+def verbose_option(f):
+ def callback(ctx, param, value):
+ state = ctx.ensure_object(State)
+ if value:
+ state.stream.setLevel(logging.DEBUG)
+
+ return click.option(
+ '-v',
+ '--verbose',
+ is_flag=True,
+ expose_value=False,
+ help='Enable verbose output',
+ callback=callback,
+ )(f)
+
+
+def quiet_option(f):
+ def callback(ctx, param, value):
+ state = ctx.ensure_object(State)
+ if value:
+ state.stream.setLevel(logging.ERROR)
+
+ return click.option(
+ '-q',
+ '--quiet',
+ is_flag=True,
+ expose_value=False,
+ help='Silence warnings',
+ callback=callback,
+ )(f)
+
+
+common_options = add_options(quiet_option, verbose_option)
+common_config_options = add_options(
+ click.option('-f', '--config-file', type=click.File('rb'), help=config_help),
+ # Don't override config value if user did not specify --strict flag
+ # Conveniently, load_config drops None values
+ click.option('-s', '--strict', is_flag=True, default=None, help=strict_help),
+ click.option('-t', '--theme', type=click.Choice(theme_choices), help=theme_help),
+ # As with --strict, set the default to None so that this doesn't incorrectly
+ # override the config file
+ click.option(
+ '--use-directory-urls/--no-directory-urls',
+ is_flag=True,
+ default=None,
+ help=use_directory_urls_help,
+ ),
+)
+
+PYTHON_VERSION = f"{sys.version_info.major}.{sys.version_info.minor}"
+
+PKG_DIR = os.path.dirname(os.path.abspath(__file__))
+
+
+@click.group(context_settings={'help_option_names': ['-h', '--help']})
+@click.version_option(
+ __version__,
+ '-V',
+ '--version',
+ message=f'%(prog)s, version %(version)s from { PKG_DIR } (Python { PYTHON_VERSION })',
+)
+@common_options
+def cli():
+ """
+ MkDocs - Project documentation with Markdown.
+ """
+
+
+@cli.command(name="serve")
+@click.option('-a', '--dev-addr', help=dev_addr_help, metavar='')
+@click.option('--livereload', 'livereload', flag_value='livereload', help=reload_help, default=True)
+@click.option('--no-livereload', 'livereload', flag_value='no-livereload', help=no_reload_help)
+@click.option('--dirtyreload', 'livereload', flag_value='dirty', help=dirty_reload_help)
+@click.option('--watch-theme', help=watch_theme_help, is_flag=True)
+@click.option(
+ '-w', '--watch', help=watch_help, type=click.Path(exists=True), multiple=True, default=[]
+)
+@common_config_options
+@common_options
+def serve_command(dev_addr, livereload, watch, **kwargs):
+ """Run the builtin development server"""
+ from mkdocs.commands import serve
+
+ _enable_warnings()
+ serve.serve(dev_addr=dev_addr, livereload=livereload, watch=watch, **kwargs)
+
+
+@cli.command(name="build")
+@click.option('-c', '--clean/--dirty', is_flag=True, default=True, help=clean_help)
+@common_config_options
+@click.option('-d', '--site-dir', type=click.Path(), help=site_dir_help)
+@common_options
+def build_command(clean, **kwargs):
+ """Build the MkDocs documentation"""
+ from mkdocs.commands import build
+
+ _enable_warnings()
+ cfg = config.load_config(**kwargs)
+ cfg['plugins'].run_event('startup', command='build', dirty=not clean)
+ try:
+ build.build(cfg, dirty=not clean)
+ finally:
+ cfg['plugins'].run_event('shutdown')
+
+
+@cli.command(name="gh-deploy")
+@click.option('-c', '--clean/--dirty', is_flag=True, default=True, help=clean_help)
+@click.option('-m', '--message', help=commit_message_help)
+@click.option('-b', '--remote-branch', help=remote_branch_help)
+@click.option('-r', '--remote-name', help=remote_name_help)
+@click.option('--force', is_flag=True, help=force_help)
+@click.option('--no-history', is_flag=True, help=no_history_help)
+@click.option('--ignore-version', is_flag=True, help=ignore_version_help)
+@click.option('--shell', is_flag=True, help=shell_help)
+@common_config_options
+@click.option('-d', '--site-dir', type=click.Path(), help=site_dir_help)
+@common_options
+def gh_deploy_command(
+ clean, message, remote_branch, remote_name, force, no_history, ignore_version, shell, **kwargs
+):
+ """Deploy your documentation to GitHub Pages"""
+ from mkdocs.commands import build, gh_deploy
+
+ _enable_warnings()
+ cfg = config.load_config(remote_branch=remote_branch, remote_name=remote_name, **kwargs)
+ cfg['plugins'].run_event('startup', command='gh-deploy', dirty=not clean)
+ try:
+ build.build(cfg, dirty=not clean)
+ finally:
+ cfg['plugins'].run_event('shutdown')
+ gh_deploy.gh_deploy(
+ cfg,
+ message=message,
+ force=force,
+ no_history=no_history,
+ ignore_version=ignore_version,
+ shell=shell,
+ )
+
+
+@cli.command(name="new")
+@click.argument("project_directory")
+@common_options
+def new_command(project_directory):
+ """Create a new MkDocs project"""
+ from mkdocs.commands import new
+
+ new.new(project_directory)
+
+
+if __name__ == '__main__': # pragma: no cover
+ cli()
diff --git a/venv/lib/python3.11/site-packages/mkdocs/__pycache__/__init__.cpython-311.pyc b/venv/lib/python3.11/site-packages/mkdocs/__pycache__/__init__.cpython-311.pyc
new file mode 100644
index 0000000..dd588a4
Binary files /dev/null and b/venv/lib/python3.11/site-packages/mkdocs/__pycache__/__init__.cpython-311.pyc differ
diff --git a/venv/lib/python3.11/site-packages/mkdocs/__pycache__/__main__.cpython-311.pyc b/venv/lib/python3.11/site-packages/mkdocs/__pycache__/__main__.cpython-311.pyc
new file mode 100644
index 0000000..f707bcd
Binary files /dev/null and b/venv/lib/python3.11/site-packages/mkdocs/__pycache__/__main__.cpython-311.pyc differ
diff --git a/venv/lib/python3.11/site-packages/mkdocs/__pycache__/exceptions.cpython-311.pyc b/venv/lib/python3.11/site-packages/mkdocs/__pycache__/exceptions.cpython-311.pyc
new file mode 100644
index 0000000..84813b8
Binary files /dev/null and b/venv/lib/python3.11/site-packages/mkdocs/__pycache__/exceptions.cpython-311.pyc differ
diff --git a/venv/lib/python3.11/site-packages/mkdocs/__pycache__/localization.cpython-311.pyc b/venv/lib/python3.11/site-packages/mkdocs/__pycache__/localization.cpython-311.pyc
new file mode 100644
index 0000000..cee596c
Binary files /dev/null and b/venv/lib/python3.11/site-packages/mkdocs/__pycache__/localization.cpython-311.pyc differ
diff --git a/venv/lib/python3.11/site-packages/mkdocs/__pycache__/plugins.cpython-311.pyc b/venv/lib/python3.11/site-packages/mkdocs/__pycache__/plugins.cpython-311.pyc
new file mode 100644
index 0000000..98a300e
Binary files /dev/null and b/venv/lib/python3.11/site-packages/mkdocs/__pycache__/plugins.cpython-311.pyc differ
diff --git a/venv/lib/python3.11/site-packages/mkdocs/__pycache__/theme.cpython-311.pyc b/venv/lib/python3.11/site-packages/mkdocs/__pycache__/theme.cpython-311.pyc
new file mode 100644
index 0000000..20365c7
Binary files /dev/null and b/venv/lib/python3.11/site-packages/mkdocs/__pycache__/theme.cpython-311.pyc differ
diff --git a/venv/lib/python3.11/site-packages/mkdocs/commands/__init__.py b/venv/lib/python3.11/site-packages/mkdocs/commands/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/venv/lib/python3.11/site-packages/mkdocs/commands/__pycache__/__init__.cpython-311.pyc b/venv/lib/python3.11/site-packages/mkdocs/commands/__pycache__/__init__.cpython-311.pyc
new file mode 100644
index 0000000..d2d1c40
Binary files /dev/null and b/venv/lib/python3.11/site-packages/mkdocs/commands/__pycache__/__init__.cpython-311.pyc differ
diff --git a/venv/lib/python3.11/site-packages/mkdocs/commands/__pycache__/babel.cpython-311.pyc b/venv/lib/python3.11/site-packages/mkdocs/commands/__pycache__/babel.cpython-311.pyc
new file mode 100644
index 0000000..2789564
Binary files /dev/null and b/venv/lib/python3.11/site-packages/mkdocs/commands/__pycache__/babel.cpython-311.pyc differ
diff --git a/venv/lib/python3.11/site-packages/mkdocs/commands/__pycache__/build.cpython-311.pyc b/venv/lib/python3.11/site-packages/mkdocs/commands/__pycache__/build.cpython-311.pyc
new file mode 100644
index 0000000..4f04777
Binary files /dev/null and b/venv/lib/python3.11/site-packages/mkdocs/commands/__pycache__/build.cpython-311.pyc differ
diff --git a/venv/lib/python3.11/site-packages/mkdocs/commands/__pycache__/gh_deploy.cpython-311.pyc b/venv/lib/python3.11/site-packages/mkdocs/commands/__pycache__/gh_deploy.cpython-311.pyc
new file mode 100644
index 0000000..744653d
Binary files /dev/null and b/venv/lib/python3.11/site-packages/mkdocs/commands/__pycache__/gh_deploy.cpython-311.pyc differ
diff --git a/venv/lib/python3.11/site-packages/mkdocs/commands/__pycache__/new.cpython-311.pyc b/venv/lib/python3.11/site-packages/mkdocs/commands/__pycache__/new.cpython-311.pyc
new file mode 100644
index 0000000..a906c01
Binary files /dev/null and b/venv/lib/python3.11/site-packages/mkdocs/commands/__pycache__/new.cpython-311.pyc differ
diff --git a/venv/lib/python3.11/site-packages/mkdocs/commands/__pycache__/serve.cpython-311.pyc b/venv/lib/python3.11/site-packages/mkdocs/commands/__pycache__/serve.cpython-311.pyc
new file mode 100644
index 0000000..1c5360c
Binary files /dev/null and b/venv/lib/python3.11/site-packages/mkdocs/commands/__pycache__/serve.cpython-311.pyc differ
diff --git a/venv/lib/python3.11/site-packages/mkdocs/commands/__pycache__/setup.cpython-311.pyc b/venv/lib/python3.11/site-packages/mkdocs/commands/__pycache__/setup.cpython-311.pyc
new file mode 100644
index 0000000..3629d22
Binary files /dev/null and b/venv/lib/python3.11/site-packages/mkdocs/commands/__pycache__/setup.cpython-311.pyc differ
diff --git a/venv/lib/python3.11/site-packages/mkdocs/commands/babel.py b/venv/lib/python3.11/site-packages/mkdocs/commands/babel.py
new file mode 100644
index 0000000..b858e84
--- /dev/null
+++ b/venv/lib/python3.11/site-packages/mkdocs/commands/babel.py
@@ -0,0 +1,118 @@
+from __future__ import annotations
+
+import sys
+import warnings
+from distutils.errors import DistutilsOptionError
+from os import path
+
+from babel.messages import frontend as babel
+from pkg_resources import EntryPoint
+
+warnings.warn(
+ "mkdocs.commands.babel is never used in MkDocs and will be removed soon.", DeprecationWarning
+)
+
+DEFAULT_MAPPING_FILE = path.normpath(
+ path.join(path.abspath(path.dirname(__file__)), '../themes/babel.cfg')
+)
+
+
+class ThemeMixin:
+ def get_theme_dir(self):
+ """Validate theme option and return path to theme's root obtained from entry point."""
+ entry_points = EntryPoint.parse_map(self.distribution.entry_points, self.distribution)
+ if 'mkdocs.themes' not in entry_points:
+ raise DistutilsOptionError("no mkdocs.themes are defined in entry_points")
+ if self.theme is None and len(entry_points['mkdocs.themes']) == 1:
+ # Default to the only theme defined in entry_points as none specified.
+ self.theme = tuple(entry_points['mkdocs.themes'].keys())[0]
+ if self.theme not in entry_points['mkdocs.themes']:
+ raise DistutilsOptionError("you must specify a valid theme name to work on")
+ theme = entry_points['mkdocs.themes'][self.theme]
+ return path.dirname(theme.resolve().__file__)
+
+
+class compile_catalog(babel.compile_catalog, ThemeMixin):
+ user_options = babel.compile_catalog.user_options + [
+ ("theme=", "t", "theme name to work on"),
+ ]
+
+ def run(self):
+ # Possible bug in Babel - produces unused return value:
+ # https://github.com/python-babel/babel/blob/v2.10.3/babel/messages/frontend.py#L194
+ if super().run():
+ sys.exit(1)
+
+ def initialize_options(self):
+ super().initialize_options()
+ self.theme = None
+
+ def finalize_options(self):
+ if not self.directory:
+ theme_dir = self.get_theme_dir()
+ self.directory = f"{theme_dir}/locales"
+ super().finalize_options()
+
+
+class extract_messages(babel.extract_messages, ThemeMixin):
+ user_options = babel.extract_messages.user_options + [
+ ("domain=", "d", "domains of the POT output file"),
+ ("theme=", "t", "theme name to work on"),
+ ]
+
+ def initialize_options(self):
+ super().initialize_options()
+ self.domain = "messages"
+ self.theme = None
+
+ def finalize_options(self):
+ if not self.version:
+ version = self.distribution.get_version()
+ self.version = ".".join(i for i in version.split(".") if "dev" not in i)
+ if not self.mapping_file:
+ self.mapping_file = DEFAULT_MAPPING_FILE
+ if not self.input_paths or not self.output_file:
+ theme_dir = self.get_theme_dir()
+ if not self.input_paths:
+ self.input_paths = theme_dir
+ if not self.output_file:
+ self.output_file = f"{theme_dir}/{self.domain}.pot"
+ super().finalize_options()
+
+
+class init_catalog(babel.init_catalog, ThemeMixin):
+ user_options = babel.init_catalog.user_options + [
+ ("theme=", "t", "theme name to work on"),
+ ]
+
+ def initialize_options(self):
+ super().initialize_options()
+ self.theme = None
+
+ def finalize_options(self):
+ if not self.input_file or not self.output_dir:
+ theme_dir = self.get_theme_dir()
+ if not self.input_file:
+ self.input_file = f"{theme_dir}/{self.domain}.pot"
+ if not self.output_dir:
+ self.output_dir = f"{theme_dir}/locales"
+ super().finalize_options()
+
+
+class update_catalog(babel.update_catalog, ThemeMixin):
+ user_options = babel.update_catalog.user_options + [
+ ("theme=", "t", "theme name to work on"),
+ ]
+
+ def initialize_options(self):
+ super().initialize_options()
+ self.theme = None
+
+ def finalize_options(self):
+ if not self.input_file or not self.output_dir:
+ theme_dir = self.get_theme_dir()
+ if not self.input_file:
+ self.input_file = f"{theme_dir}/{self.domain}.pot"
+ if not self.output_dir:
+ self.output_dir = f"{theme_dir}/locales"
+ super().finalize_options()
diff --git a/venv/lib/python3.11/site-packages/mkdocs/commands/build.py b/venv/lib/python3.11/site-packages/mkdocs/commands/build.py
new file mode 100644
index 0000000..6071665
--- /dev/null
+++ b/venv/lib/python3.11/site-packages/mkdocs/commands/build.py
@@ -0,0 +1,356 @@
+from __future__ import annotations
+
+import gzip
+import logging
+import os
+import time
+from typing import Any, Dict, Optional, Sequence, Set, Union
+from urllib.parse import urlsplit
+
+import jinja2
+from jinja2.exceptions import TemplateNotFound
+
+import mkdocs
+from mkdocs import utils
+from mkdocs.config.defaults import MkDocsConfig
+from mkdocs.exceptions import Abort, BuildError
+from mkdocs.structure.files import File, Files, get_files
+from mkdocs.structure.nav import Navigation, get_navigation
+from mkdocs.structure.pages import Page
+
+
+class DuplicateFilter:
+ """Avoid logging duplicate messages."""
+
+ def __init__(self) -> None:
+ self.msgs: Set[str] = set()
+
+ def __call__(self, record: logging.LogRecord) -> bool:
+ rv = record.msg not in self.msgs
+ self.msgs.add(record.msg)
+ return rv
+
+
+log = logging.getLogger(__name__)
+log.addFilter(DuplicateFilter())
+
+
+def get_context(
+ nav: Navigation,
+ files: Union[Sequence[File], Files],
+ config: MkDocsConfig,
+ page: Optional[Page] = None,
+ base_url: str = '',
+) -> Dict[str, Any]:
+ """
+ Return the template context for a given page or template.
+ """
+ if page is not None:
+ base_url = utils.get_relative_url('.', page.url)
+
+ extra_javascript = utils.create_media_urls(config.extra_javascript, page, base_url)
+
+ extra_css = utils.create_media_urls(config.extra_css, page, base_url)
+
+ if isinstance(files, Files):
+ files = files.documentation_pages()
+
+ return {
+ 'nav': nav,
+ 'pages': files,
+ 'base_url': base_url,
+ 'extra_css': extra_css,
+ 'extra_javascript': extra_javascript,
+ 'mkdocs_version': mkdocs.__version__,
+ 'build_date_utc': utils.get_build_datetime(),
+ 'config': config,
+ 'page': page,
+ }
+
+
+def _build_template(
+ name: str, template: jinja2.Template, files: Files, config: MkDocsConfig, nav: Navigation
+) -> str:
+ """
+ Return rendered output for given template as a string.
+ """
+ # Run `pre_template` plugin events.
+ template = config.plugins.run_event('pre_template', template, template_name=name, config=config)
+
+ if utils.is_error_template(name):
+ # Force absolute URLs in the nav of error pages and account for the
+ # possibility that the docs root might be different than the server root.
+ # See https://github.com/mkdocs/mkdocs/issues/77.
+ # However, if site_url is not set, assume the docs root and server root
+ # are the same. See https://github.com/mkdocs/mkdocs/issues/1598.
+ base_url = urlsplit(config.site_url or '/').path
+ else:
+ base_url = utils.get_relative_url('.', name)
+
+ context = get_context(nav, files, config, base_url=base_url)
+
+ # Run `template_context` plugin events.
+ context = config.plugins.run_event(
+ 'template_context', context, template_name=name, config=config
+ )
+
+ output = template.render(context)
+
+ # Run `post_template` plugin events.
+ output = config.plugins.run_event('post_template', output, template_name=name, config=config)
+
+ return output
+
+
+def _build_theme_template(
+ template_name: str, env: jinja2.Environment, files: Files, config: MkDocsConfig, nav: Navigation
+) -> None:
+ """Build a template using the theme environment."""
+
+ log.debug(f"Building theme template: {template_name}")
+
+ try:
+ template = env.get_template(template_name)
+ except TemplateNotFound:
+ log.warning(f"Template skipped: '{template_name}' not found in theme directories.")
+ return
+
+ output = _build_template(template_name, template, files, config, nav)
+
+ if output.strip():
+ output_path = os.path.join(config.site_dir, template_name)
+ utils.write_file(output.encode('utf-8'), output_path)
+
+ if template_name == 'sitemap.xml':
+ log.debug(f"Gzipping template: {template_name}")
+ gz_filename = f'{output_path}.gz'
+ with open(gz_filename, 'wb') as f:
+ timestamp = utils.get_build_timestamp()
+ with gzip.GzipFile(
+ fileobj=f, filename=gz_filename, mode='wb', mtime=timestamp
+ ) as gz_buf:
+ gz_buf.write(output.encode('utf-8'))
+ else:
+ log.info(f"Template skipped: '{template_name}' generated empty output.")
+
+
+def _build_extra_template(template_name: str, files: Files, config: MkDocsConfig, nav: Navigation):
+ """Build user templates which are not part of the theme."""
+
+ log.debug(f"Building extra template: {template_name}")
+
+ file = files.get_file_from_path(template_name)
+ if file is None:
+ log.warning(f"Template skipped: '{template_name}' not found in docs_dir.")
+ return
+
+ try:
+ with open(file.abs_src_path, encoding='utf-8', errors='strict') as f:
+ template = jinja2.Template(f.read())
+ except Exception as e:
+ log.warning(f"Error reading template '{template_name}': {e}")
+ return
+
+ output = _build_template(template_name, template, files, config, nav)
+
+ if output.strip():
+ utils.write_file(output.encode('utf-8'), file.abs_dest_path)
+ else:
+ log.info(f"Template skipped: '{template_name}' generated empty output.")
+
+
+def _populate_page(page: Page, config: MkDocsConfig, files: Files, dirty: bool = False) -> None:
+ """Read page content from docs_dir and render Markdown."""
+
+ try:
+ # When --dirty is used, only read the page if the file has been modified since the
+ # previous build of the output.
+ if dirty and not page.file.is_modified():
+ return
+
+ # Run the `pre_page` plugin event
+ page = config.plugins.run_event('pre_page', page, config=config, files=files)
+
+ page.read_source(config)
+
+ # Run `page_markdown` plugin events.
+ page.markdown = config.plugins.run_event(
+ 'page_markdown', page.markdown, page=page, config=config, files=files
+ )
+
+ page.render(config, files)
+
+ # Run `page_content` plugin events.
+ page.content = config.plugins.run_event(
+ 'page_content', page.content, page=page, config=config, files=files
+ )
+ except Exception as e:
+ message = f"Error reading page '{page.file.src_uri}':"
+ # Prevent duplicated the error message because it will be printed immediately afterwards.
+ if not isinstance(e, BuildError):
+ message += f" {e}"
+ log.error(message)
+ raise
+
+
+def _build_page(
+ page: Page,
+ config: MkDocsConfig,
+ doc_files: Sequence[File],
+ nav: Navigation,
+ env: jinja2.Environment,
+ dirty: bool = False,
+) -> None:
+ """Pass a Page to theme template and write output to site_dir."""
+
+ try:
+ # When --dirty is used, only build the page if the file has been modified since the
+ # previous build of the output.
+ if dirty and not page.file.is_modified():
+ return
+
+ log.debug(f"Building page {page.file.src_uri}")
+
+ # Activate page. Signals to theme that this is the current page.
+ page.active = True
+
+ context = get_context(nav, doc_files, config, page)
+
+ # Allow 'template:' override in md source files.
+ if 'template' in page.meta:
+ template = env.get_template(page.meta['template'])
+ else:
+ template = env.get_template('main.html')
+
+ # Run `page_context` plugin events.
+ context = config.plugins.run_event(
+ 'page_context', context, page=page, config=config, nav=nav
+ )
+
+ # Render the template.
+ output = template.render(context)
+
+ # Run `post_page` plugin events.
+ output = config.plugins.run_event('post_page', output, page=page, config=config)
+
+ # Write the output file.
+ if output.strip():
+ utils.write_file(
+ output.encode('utf-8', errors='xmlcharrefreplace'), page.file.abs_dest_path
+ )
+ else:
+ log.info(f"Page skipped: '{page.file.src_uri}'. Generated empty output.")
+
+ # Deactivate page
+ page.active = False
+ except Exception as e:
+ message = f"Error building page '{page.file.src_uri}':"
+ # Prevent duplicated the error message because it will be printed immediately afterwards.
+ if not isinstance(e, BuildError):
+ message += f" {e}"
+ log.error(message)
+ raise
+
+
+def build(config: MkDocsConfig, live_server: bool = False, dirty: bool = False) -> None:
+ """Perform a full site build."""
+
+ logger = logging.getLogger('mkdocs')
+
+ # Add CountHandler for strict mode
+ warning_counter = utils.CountHandler()
+ warning_counter.setLevel(logging.WARNING)
+ if config.strict:
+ logging.getLogger('mkdocs').addHandler(warning_counter)
+
+ try:
+ start = time.monotonic()
+
+ # Run `config` plugin events.
+ config = config.plugins.run_event('config', config)
+
+ # Run `pre_build` plugin events.
+ config.plugins.run_event('pre_build', config=config)
+
+ if not dirty:
+ log.info("Cleaning site directory")
+ utils.clean_directory(config.site_dir)
+ else: # pragma: no cover
+ # Warn user about problems that may occur with --dirty option
+ log.warning(
+ "A 'dirty' build is being performed, this will likely lead to inaccurate navigation and other"
+ " links within your site. This option is designed for site development purposes only."
+ )
+
+ if not live_server: # pragma: no cover
+ log.info(f"Building documentation to directory: {config.site_dir}")
+ if dirty and site_directory_contains_stale_files(config.site_dir):
+ log.info("The directory contains stale files. Use --clean to remove them.")
+
+ # First gather all data from all files/pages to ensure all data is consistent across all pages.
+
+ files = get_files(config)
+ env = config.theme.get_env()
+ files.add_files_from_theme(env, config)
+
+ # Run `files` plugin events.
+ files = config.plugins.run_event('files', files, config=config)
+
+ nav = get_navigation(files, config)
+
+ # Run `nav` plugin events.
+ nav = config.plugins.run_event('nav', nav, config=config, files=files)
+
+ log.debug("Reading markdown pages.")
+ for file in files.documentation_pages():
+ log.debug(f"Reading: {file.src_uri}")
+ assert file.page is not None
+ _populate_page(file.page, config, files, dirty)
+
+ # Run `env` plugin events.
+ env = config.plugins.run_event('env', env, config=config, files=files)
+
+ # Start writing files to site_dir now that all data is gathered. Note that order matters. Files
+ # with lower precedence get written first so that files with higher precedence can overwrite them.
+
+ log.debug("Copying static assets.")
+ files.copy_static_files(dirty=dirty)
+
+ for template in config.theme.static_templates:
+ _build_theme_template(template, env, files, config, nav)
+
+ for template in config.extra_templates:
+ _build_extra_template(template, files, config, nav)
+
+ log.debug("Building markdown pages.")
+ doc_files = files.documentation_pages()
+ for file in doc_files:
+ assert file.page is not None
+ _build_page(file.page, config, doc_files, nav, env, dirty)
+
+ # Run `post_build` plugin events.
+ config.plugins.run_event('post_build', config=config)
+
+ counts = warning_counter.get_counts()
+ if counts:
+ msg = ', '.join(f'{v} {k.lower()}s' for k, v in counts)
+ raise Abort(f'\nAborted with {msg} in strict mode!')
+
+ log.info('Documentation built in %.2f seconds', time.monotonic() - start)
+
+ except Exception as e:
+ # Run `build_error` plugin events.
+ config.plugins.run_event('build_error', error=e)
+ if isinstance(e, BuildError):
+ log.error(str(e))
+ raise Abort('\nAborted with a BuildError!')
+ raise
+
+ finally:
+ logger.removeHandler(warning_counter)
+
+
+def site_directory_contains_stale_files(site_directory: str) -> bool:
+ """Check if the site directory contains stale files from a previous build."""
+
+ return True if os.path.exists(site_directory) and os.listdir(site_directory) else False
diff --git a/venv/lib/python3.11/site-packages/mkdocs/commands/gh_deploy.py b/venv/lib/python3.11/site-packages/mkdocs/commands/gh_deploy.py
new file mode 100644
index 0000000..9f7bcae
--- /dev/null
+++ b/venv/lib/python3.11/site-packages/mkdocs/commands/gh_deploy.py
@@ -0,0 +1,167 @@
+from __future__ import annotations
+
+import logging
+import os
+import re
+import subprocess
+from typing import Optional, Tuple, Union
+
+import ghp_import
+from packaging import version
+
+import mkdocs
+from mkdocs.config.defaults import MkDocsConfig
+from mkdocs.exceptions import Abort
+
+log = logging.getLogger(__name__)
+
+default_message = """Deployed {sha} with MkDocs version: {version}"""
+
+
+def _is_cwd_git_repo() -> bool:
+ try:
+ proc = subprocess.Popen(
+ ['git', 'rev-parse', '--is-inside-work-tree'],
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE,
+ )
+ except FileNotFoundError:
+ log.error("Could not find git - is it installed and on your path?")
+ raise Abort('Deployment Aborted!')
+ proc.communicate()
+ return proc.wait() == 0
+
+
+def _get_current_sha(repo_path) -> str:
+ proc = subprocess.Popen(
+ ['git', 'rev-parse', '--short', 'HEAD'],
+ cwd=repo_path or None,
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE,
+ )
+
+ stdout, _ = proc.communicate()
+ sha = stdout.decode('utf-8').strip()
+ return sha
+
+
+def _get_remote_url(remote_name: str) -> Union[Tuple[str, str], Tuple[None, None]]:
+ # No CNAME found. We will use the origin URL to determine the GitHub
+ # pages location.
+ remote = f"remote.{remote_name}.url"
+ proc = subprocess.Popen(
+ ["git", "config", "--get", remote],
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE,
+ )
+
+ stdout, _ = proc.communicate()
+ url = stdout.decode('utf-8').strip()
+
+ if 'github.com/' in url:
+ host, path = url.split('github.com/', 1)
+ elif 'github.com:' in url:
+ host, path = url.split('github.com:', 1)
+ else:
+ return None, None
+ return host, path
+
+
+def _check_version(branch: str) -> None:
+ proc = subprocess.Popen(
+ ['git', 'show', '-s', '--format=%s', f'refs/heads/{branch}'],
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE,
+ )
+
+ stdout, _ = proc.communicate()
+ msg = stdout.decode('utf-8').strip()
+ m = re.search(r'\d+(\.\d+)+((a|b|rc)\d+)?(\.post\d+)?(\.dev\d+)?', msg, re.X | re.I)
+ previousv = version.parse(m.group()) if m else None
+ currentv = version.parse(mkdocs.__version__)
+ if not previousv:
+ log.warning('Version check skipped: No version specified in previous deployment.')
+ elif currentv > previousv:
+ log.info(
+ f'Previous deployment was done with MkDocs version {previousv}; '
+ f'you are deploying with a newer version ({currentv})'
+ )
+ elif currentv < previousv:
+ log.error(
+ f'Deployment terminated: Previous deployment was made with MkDocs version {previousv}; '
+ f'you are attempting to deploy with an older version ({currentv}). Use --ignore-version '
+ 'to deploy anyway.'
+ )
+ raise Abort('Deployment Aborted!')
+
+
+def gh_deploy(
+ config: MkDocsConfig,
+ message: Optional[str] = None,
+ force=False,
+ no_history=False,
+ ignore_version=False,
+ shell=False,
+) -> None:
+ if not _is_cwd_git_repo():
+ log.error('Cannot deploy - this directory does not appear to be a git repository')
+
+ remote_branch = config.remote_branch
+ remote_name = config.remote_name
+
+ if not ignore_version:
+ _check_version(remote_branch)
+
+ if message is None:
+ message = default_message
+ sha = _get_current_sha(os.path.dirname(config.config_file_path))
+ message = message.format(version=mkdocs.__version__, sha=sha)
+
+ log.info(
+ "Copying '%s' to '%s' branch and pushing to GitHub.",
+ config.site_dir,
+ config.remote_branch,
+ )
+
+ try:
+ ghp_import.ghp_import(
+ config.site_dir,
+ mesg=message,
+ remote=remote_name,
+ branch=remote_branch,
+ push=True,
+ force=force,
+ use_shell=shell,
+ no_history=no_history,
+ nojekyll=True,
+ )
+ except ghp_import.GhpError as e:
+ log.error(f"Failed to deploy to GitHub with error: \n{e.message}")
+ raise Abort('Deployment Aborted!')
+
+ cname_file = os.path.join(config.site_dir, 'CNAME')
+ # Does this repository have a CNAME set for GitHub pages?
+ if os.path.isfile(cname_file):
+ # This GitHub pages repository has a CNAME configured.
+ with open(cname_file) as f:
+ cname_host = f.read().strip()
+ log.info(
+ f'Based on your CNAME file, your documentation should be '
+ f'available shortly at: http://{cname_host}'
+ )
+ log.info(
+ 'NOTE: Your DNS records must be configured appropriately for your CNAME URL to work.'
+ )
+ return
+
+ host, path = _get_remote_url(remote_name)
+
+ if host is None or path is None:
+ # This could be a GitHub Enterprise deployment.
+ log.info('Your documentation should be available shortly.')
+ else:
+ username, repo = path.split('/', 1)
+ if repo.endswith('.git'):
+ repo = repo[: -len('.git')]
+ url = f'https://{username}.github.io/{repo}/'
+ log.info(f"Your documentation should shortly be available at: {url}")
diff --git a/venv/lib/python3.11/site-packages/mkdocs/commands/new.py b/venv/lib/python3.11/site-packages/mkdocs/commands/new.py
new file mode 100644
index 0000000..38c3068
--- /dev/null
+++ b/venv/lib/python3.11/site-packages/mkdocs/commands/new.py
@@ -0,0 +1,53 @@
+from __future__ import annotations
+
+import logging
+import os
+
+config_text = 'site_name: My Docs\n'
+index_text = """# Welcome to MkDocs
+
+For full documentation visit [mkdocs.org](https://www.mkdocs.org).
+
+## Commands
+
+* `mkdocs new [dir-name]` - Create a new project.
+* `mkdocs serve` - Start the live-reloading docs server.
+* `mkdocs build` - Build the documentation site.
+* `mkdocs -h` - Print help message and exit.
+
+## Project layout
+
+ mkdocs.yml # The configuration file.
+ docs/
+ index.md # The documentation homepage.
+ ... # Other markdown pages, images and other files.
+"""
+
+log = logging.getLogger(__name__)
+
+
+def new(output_dir: str) -> None:
+ docs_dir = os.path.join(output_dir, 'docs')
+ config_path = os.path.join(output_dir, 'mkdocs.yml')
+ index_path = os.path.join(docs_dir, 'index.md')
+
+ if os.path.exists(config_path):
+ log.info('Project already exists.')
+ return
+
+ if not os.path.exists(output_dir):
+ log.info(f'Creating project directory: {output_dir}')
+ os.mkdir(output_dir)
+
+ log.info(f'Writing config file: {config_path}')
+ with open(config_path, 'w', encoding='utf-8') as f:
+ f.write(config_text)
+
+ if os.path.exists(index_path):
+ return
+
+ log.info(f'Writing initial docs: {index_path}')
+ if not os.path.exists(docs_dir):
+ os.mkdir(docs_dir)
+ with open(index_path, 'w', encoding='utf-8') as f:
+ f.write(index_text)
diff --git a/venv/lib/python3.11/site-packages/mkdocs/commands/serve.py b/venv/lib/python3.11/site-packages/mkdocs/commands/serve.py
new file mode 100644
index 0000000..58bf04a
--- /dev/null
+++ b/venv/lib/python3.11/site-packages/mkdocs/commands/serve.py
@@ -0,0 +1,130 @@
+from __future__ import annotations
+
+import functools
+import logging
+import shutil
+import tempfile
+from os.path import isdir, isfile, join
+from typing import Optional
+from urllib.parse import urlsplit
+
+import jinja2.exceptions
+
+from mkdocs.commands.build import build
+from mkdocs.config import load_config
+from mkdocs.config.defaults import MkDocsConfig
+from mkdocs.exceptions import Abort
+from mkdocs.livereload import LiveReloadServer
+
+log = logging.getLogger(__name__)
+
+
+def serve(
+ config_file=None,
+ dev_addr=None,
+ strict=None,
+ theme=None,
+ theme_dir=None,
+ livereload='livereload',
+ watch_theme=False,
+ watch=[],
+ **kwargs,
+):
+ """
+ Start the MkDocs development server
+
+ By default it will serve the documentation on http://localhost:8000/ and
+ it will rebuild the documentation and refresh the page automatically
+ whenever a file is edited.
+ """
+ # Create a temporary build directory, and set some options to serve it
+ # PY2 returns a byte string by default. The Unicode prefix ensures a Unicode
+ # string is returned. And it makes MkDocs temp dirs easier to identify.
+ site_dir = tempfile.mkdtemp(prefix='mkdocs_')
+
+ def mount_path(config: MkDocsConfig):
+ return urlsplit(config.site_url or '/').path
+
+ get_config = functools.partial(
+ load_config,
+ config_file=config_file,
+ dev_addr=dev_addr,
+ strict=strict,
+ theme=theme,
+ theme_dir=theme_dir,
+ site_dir=site_dir,
+ **kwargs,
+ )
+
+ live_server = livereload in ('dirty', 'livereload')
+ dirty = livereload == 'dirty'
+
+ def builder(config: Optional[MkDocsConfig] = None):
+ log.info("Building documentation...")
+ if config is None:
+ config = get_config()
+
+ # combine CLI watch arguments with config file values
+ if config.watch is None:
+ config.watch = watch
+ else:
+ config.watch.extend(watch)
+
+ # Override a few config settings after validation
+ config.site_url = f'http://{config.dev_addr}{mount_path(config)}'
+
+ build(config, live_server=live_server, dirty=dirty)
+
+ config = get_config()
+ config['plugins'].run_event('startup', command='serve', dirty=dirty)
+
+ try:
+ # Perform the initial build
+ builder(config)
+
+ host, port = config.dev_addr
+ server = LiveReloadServer(
+ builder=builder, host=host, port=port, root=site_dir, mount_path=mount_path(config)
+ )
+
+ def error_handler(code) -> Optional[bytes]:
+ if code in (404, 500):
+ error_page = join(site_dir, f'{code}.html')
+ if isfile(error_page):
+ with open(error_page, 'rb') as f:
+ return f.read()
+ return None
+
+ server.error_handler = error_handler
+
+ if live_server:
+ # Watch the documentation files, the config file and the theme files.
+ server.watch(config.docs_dir)
+ server.watch(config.config_file_path)
+
+ if watch_theme:
+ for d in config.theme.dirs:
+ server.watch(d)
+
+ # Run `serve` plugin events.
+ server = config.plugins.run_event('serve', server, config=config, builder=builder)
+
+ for item in config.watch:
+ server.watch(item)
+
+ try:
+ server.serve()
+ except KeyboardInterrupt:
+ log.info("Shutting down...")
+ finally:
+ server.shutdown()
+ except jinja2.exceptions.TemplateError:
+ # This is a subclass of OSError, but shouldn't be suppressed.
+ raise
+ except OSError as e: # pragma: no cover
+ # Avoid ugly, unhelpful traceback
+ raise Abort(f'{type(e).__name__}: {e}')
+ finally:
+ config['plugins'].run_event('shutdown')
+ if isdir(site_dir):
+ shutil.rmtree(site_dir)
diff --git a/venv/lib/python3.11/site-packages/mkdocs/commands/setup.py b/venv/lib/python3.11/site-packages/mkdocs/commands/setup.py
new file mode 100644
index 0000000..4e85e1e
--- /dev/null
+++ b/venv/lib/python3.11/site-packages/mkdocs/commands/setup.py
@@ -0,0 +1,22 @@
+import warnings
+
+warnings.warn(
+ "mkdocs.commands.setup is never used in MkDocs and will be removed soon.", DeprecationWarning
+)
+
+try:
+ from mkdocs.commands.babel import (
+ compile_catalog,
+ extract_messages,
+ init_catalog,
+ update_catalog,
+ )
+
+ babel_cmdclass = {
+ 'compile_catalog': compile_catalog,
+ 'extract_messages': extract_messages,
+ 'init_catalog': init_catalog,
+ 'update_catalog': update_catalog,
+ }
+except ImportError:
+ babel_cmdclass = {}
diff --git a/venv/lib/python3.11/site-packages/mkdocs/config/__init__.py b/venv/lib/python3.11/site-packages/mkdocs/config/__init__.py
new file mode 100644
index 0000000..3fa69c6
--- /dev/null
+++ b/venv/lib/python3.11/site-packages/mkdocs/config/__init__.py
@@ -0,0 +1,3 @@
+from mkdocs.config.base import Config, load_config
+
+__all__ = ['load_config', 'Config']
diff --git a/venv/lib/python3.11/site-packages/mkdocs/config/__pycache__/__init__.cpython-311.pyc b/venv/lib/python3.11/site-packages/mkdocs/config/__pycache__/__init__.cpython-311.pyc
new file mode 100644
index 0000000..19923b7
Binary files /dev/null and b/venv/lib/python3.11/site-packages/mkdocs/config/__pycache__/__init__.cpython-311.pyc differ
diff --git a/venv/lib/python3.11/site-packages/mkdocs/config/__pycache__/base.cpython-311.pyc b/venv/lib/python3.11/site-packages/mkdocs/config/__pycache__/base.cpython-311.pyc
new file mode 100644
index 0000000..7c79a05
Binary files /dev/null and b/venv/lib/python3.11/site-packages/mkdocs/config/__pycache__/base.cpython-311.pyc differ
diff --git a/venv/lib/python3.11/site-packages/mkdocs/config/__pycache__/config_options.cpython-311.pyc b/venv/lib/python3.11/site-packages/mkdocs/config/__pycache__/config_options.cpython-311.pyc
new file mode 100644
index 0000000..fd130d7
Binary files /dev/null and b/venv/lib/python3.11/site-packages/mkdocs/config/__pycache__/config_options.cpython-311.pyc differ
diff --git a/venv/lib/python3.11/site-packages/mkdocs/config/__pycache__/defaults.cpython-311.pyc b/venv/lib/python3.11/site-packages/mkdocs/config/__pycache__/defaults.cpython-311.pyc
new file mode 100644
index 0000000..64b2e65
Binary files /dev/null and b/venv/lib/python3.11/site-packages/mkdocs/config/__pycache__/defaults.cpython-311.pyc differ
diff --git a/venv/lib/python3.11/site-packages/mkdocs/config/base.py b/venv/lib/python3.11/site-packages/mkdocs/config/base.py
new file mode 100644
index 0000000..9c99018
--- /dev/null
+++ b/venv/lib/python3.11/site-packages/mkdocs/config/base.py
@@ -0,0 +1,381 @@
+from __future__ import annotations
+
+import functools
+import logging
+import os
+import sys
+from collections import UserDict
+from contextlib import contextmanager
+from typing import (
+ IO,
+ TYPE_CHECKING,
+ Generic,
+ Iterator,
+ List,
+ Optional,
+ Sequence,
+ Tuple,
+ TypeVar,
+ Union,
+ overload,
+)
+
+from yaml import YAMLError
+
+from mkdocs import exceptions, utils
+
+if TYPE_CHECKING:
+ from mkdocs.config.defaults import MkDocsConfig
+
+
+log = logging.getLogger('mkdocs.config')
+
+
+T = TypeVar('T')
+
+
+class BaseConfigOption(Generic[T]):
+ def __init__(self):
+ self.warnings: List[str] = []
+ self.default = None
+
+ @property
+ def default(self):
+ try:
+ # ensure no mutable values are assigned
+ return self._default.copy()
+ except AttributeError:
+ return self._default
+
+ @default.setter
+ def default(self, value):
+ self._default = value
+
+ def validate(self, value: object) -> T:
+ return self.run_validation(value)
+
+ def reset_warnings(self) -> None:
+ self.warnings = []
+
+ def pre_validation(self, config: Config, key_name: str) -> None:
+ """
+ Before all options are validated, perform a pre-validation process.
+
+ The pre-validation process method should be implemented by subclasses.
+ """
+
+ def run_validation(self, value: object):
+ """
+ Perform validation for a value.
+
+ The run_validation method should be implemented by subclasses.
+ """
+ return value
+
+ def post_validation(self, config: Config, key_name: str) -> None:
+ """
+ After all options have passed validation, perform a post-validation
+ process to do any additional changes dependent on other config values.
+
+ The post-validation process method should be implemented by subclasses.
+ """
+
+ def __set_name__(self, owner, name):
+ self._name = name
+
+ @overload
+ def __get__(self, obj: Config, type=None) -> T:
+ ...
+
+ @overload
+ def __get__(self, obj, type=None) -> BaseConfigOption:
+ ...
+
+ def __get__(self, obj, type=None):
+ if not isinstance(obj, Config):
+ return self
+ return obj[self._name]
+
+ def __set__(self, obj, value: T):
+ if not isinstance(obj, Config):
+ raise AttributeError(
+ f"can't set attribute ({self._name}) because the parent is a {type(obj)} not a {Config}"
+ )
+ obj[self._name] = value
+
+
+class ValidationError(Exception):
+ """Raised during the validation process of the config on errors."""
+
+ def __eq__(self, other):
+ return type(self) is type(other) and str(self) == str(other)
+
+
+PlainConfigSchemaItem = Tuple[str, BaseConfigOption]
+PlainConfigSchema = Sequence[PlainConfigSchemaItem]
+
+ConfigErrors = List[Tuple[str, Exception]]
+ConfigWarnings = List[Tuple[str, str]]
+
+
+class Config(UserDict):
+ """
+ Base class for MkDocs configuration, plugin configuration (and sub-configuration) objects.
+
+ It should be subclassed and have `ConfigOption`s defined as attributes.
+ For examples, see mkdocs/contrib/search/__init__.py and mkdocs/config/defaults.py.
+
+ Behavior as it was prior to MkDocs 1.4 is now handled by LegacyConfig.
+ """
+
+ _schema: PlainConfigSchema
+ config_file_path: Optional[str]
+
+ def __init_subclass__(cls):
+ schema = dict(getattr(cls, '_schema', ()))
+ for attr_name, attr in cls.__dict__.items():
+ if isinstance(attr, BaseConfigOption):
+ schema[attr_name] = attr
+ cls._schema = tuple(schema.items())
+
+ for attr_name, attr in cls._schema:
+ attr.required = True
+ if getattr(attr, '_legacy_required', None) is not None:
+ raise TypeError(
+ f"{cls.__name__}.{attr_name}: "
+ "Setting 'required' is unsupported in class-based configs. "
+ "All values are required, or can be wrapped into config_options.Optional"
+ )
+
+ def __new__(cls, *args, **kwargs) -> Config:
+ """Compatibility: allow referring to `LegacyConfig(...)` constructor as `Config(...)`."""
+ if cls is Config:
+ return LegacyConfig(*args, **kwargs)
+ return super().__new__(cls)
+
+ def __init__(self, config_file_path: Optional[Union[str, bytes]] = None):
+ super().__init__()
+ self.user_configs: List[dict] = []
+ self.set_defaults()
+
+ self._schema_keys = {k for k, v in self._schema}
+ # Ensure config_file_path is a Unicode string
+ if config_file_path is not None and not isinstance(config_file_path, str):
+ try:
+ # Assume config_file_path is encoded with the file system encoding.
+ config_file_path = config_file_path.decode(encoding=sys.getfilesystemencoding())
+ except UnicodeDecodeError:
+ raise ValidationError("config_file_path is not a Unicode string.")
+ self.config_file_path = config_file_path
+
+ def set_defaults(self) -> None:
+ """
+ Set the base config by going through each validator and getting the
+ default if it has one.
+ """
+ for key, config_option in self._schema:
+ self[key] = config_option.default
+
+ def _validate(self) -> Tuple[ConfigErrors, ConfigWarnings]:
+ failed: ConfigErrors = []
+ warnings: ConfigWarnings = []
+
+ for key, config_option in self._schema:
+ try:
+ value = self.get(key)
+ self[key] = config_option.validate(value)
+ warnings.extend((key, w) for w in config_option.warnings)
+ config_option.reset_warnings()
+ except ValidationError as e:
+ failed.append((key, e))
+
+ for key in set(self.keys()) - self._schema_keys:
+ warnings.append((key, f"Unrecognised configuration name: {key}"))
+
+ return failed, warnings
+
+ def _pre_validate(self) -> Tuple[ConfigErrors, ConfigWarnings]:
+ failed: ConfigErrors = []
+ warnings: ConfigWarnings = []
+
+ for key, config_option in self._schema:
+ try:
+ config_option.pre_validation(self, key_name=key)
+ warnings.extend((key, w) for w in config_option.warnings)
+ config_option.reset_warnings()
+ except ValidationError as e:
+ failed.append((key, e))
+
+ return failed, warnings
+
+ def _post_validate(self) -> Tuple[ConfigErrors, ConfigWarnings]:
+ failed: ConfigErrors = []
+ warnings: ConfigWarnings = []
+
+ for key, config_option in self._schema:
+ try:
+ config_option.post_validation(self, key_name=key)
+ warnings.extend((key, w) for w in config_option.warnings)
+ config_option.reset_warnings()
+ except ValidationError as e:
+ failed.append((key, e))
+
+ return failed, warnings
+
+ def validate(self) -> Tuple[ConfigErrors, ConfigWarnings]:
+ failed, warnings = self._pre_validate()
+
+ run_failed, run_warnings = self._validate()
+
+ failed.extend(run_failed)
+ warnings.extend(run_warnings)
+
+ # Only run the post validation steps if there are no failures, warnings
+ # are okay.
+ if len(failed) == 0:
+ post_failed, post_warnings = self._post_validate()
+ failed.extend(post_failed)
+ warnings.extend(post_warnings)
+
+ return failed, warnings
+
+ def load_dict(self, patch: Optional[dict]) -> None:
+ """Load config options from a dictionary."""
+
+ if not isinstance(patch, dict):
+ raise exceptions.ConfigurationError(
+ "The configuration is invalid. The expected type was a key "
+ "value mapping (a python dict) but we got an object of type: "
+ f"{type(patch)}"
+ )
+
+ self.user_configs.append(patch)
+ self.update(patch)
+
+ def load_file(self, config_file: IO) -> None:
+ """Load config options from the open file descriptor of a YAML file."""
+ try:
+ return self.load_dict(utils.yaml_load(config_file))
+ except YAMLError as e:
+ # MkDocs knows and understands ConfigurationErrors
+ raise exceptions.ConfigurationError(
+ f"MkDocs encountered an error parsing the configuration file: {e}"
+ )
+
+
+@functools.lru_cache(maxsize=None)
+def get_schema(cls: type) -> PlainConfigSchema:
+ """
+ Extract ConfigOptions defined in a class (used just as a container) and put them into a schema tuple.
+ """
+ if issubclass(cls, Config):
+ return cls._schema
+ return tuple((k, v) for k, v in cls.__dict__.items() if isinstance(v, BaseConfigOption))
+
+
+class LegacyConfig(Config):
+ """
+ A configuration object for plugins, as just a dict without type-safe attribute access.
+ """
+
+ def __init__(self, schema: PlainConfigSchema, config_file_path: Optional[str] = None):
+ self._schema = tuple((k, v) for k, v in schema) # Re-create just for validation
+ super().__init__(config_file_path)
+
+
+@contextmanager
+def _open_config_file(config_file: Optional[Union[str, IO]]) -> Iterator[IO]:
+ """
+ A context manager which yields an open file descriptor ready to be read.
+
+ Accepts a filename as a string, an open or closed file descriptor, or None.
+ When None, it defaults to `mkdocs.yml` in the CWD. If a closed file descriptor
+ is received, a new file descriptor is opened for the same file.
+
+ The file descriptor is automatically closed when the context manager block is existed.
+ """
+ # Default to the standard config filename.
+ if config_file is None:
+ paths_to_try = ['mkdocs.yml', 'mkdocs.yaml']
+ # If it is a string, we can assume it is a path and attempt to open it.
+ elif isinstance(config_file, str):
+ paths_to_try = [config_file]
+ # If closed file descriptor, get file path to reopen later.
+ elif getattr(config_file, 'closed', False):
+ paths_to_try = [config_file.name]
+ else:
+ result_config_file = config_file
+ paths_to_try = None
+
+ if paths_to_try:
+ # config_file is not a file descriptor, so open it as a path.
+ for path in paths_to_try:
+ path = os.path.abspath(path)
+ log.debug(f"Loading configuration file: {path}")
+ try:
+ result_config_file = open(path, 'rb')
+ break
+ except FileNotFoundError:
+ continue
+ else:
+ raise exceptions.ConfigurationError(f"Config file '{paths_to_try[0]}' does not exist.")
+ else:
+ log.debug(f"Loading configuration file: {result_config_file}")
+ # Ensure file descriptor is at beginning
+ result_config_file.seek(0)
+
+ try:
+ yield result_config_file
+ finally:
+ if hasattr(result_config_file, 'close'):
+ result_config_file.close()
+
+
+def load_config(config_file: Optional[Union[str, IO]] = None, **kwargs) -> MkDocsConfig:
+ """
+ Load the configuration for a given file object or name
+
+ The config_file can either be a file object, string or None. If it is None
+ the default `mkdocs.yml` filename will loaded.
+
+ Extra kwargs are passed to the configuration to replace any default values
+ unless they themselves are None.
+ """
+ options = kwargs.copy()
+
+ # Filter None values from the options. This usually happens with optional
+ # parameters from Click.
+ for key, value in options.copy().items():
+ if value is None:
+ options.pop(key)
+
+ with _open_config_file(config_file) as fd:
+ # Initialize the config with the default schema.
+ from mkdocs.config.defaults import MkDocsConfig
+
+ cfg = MkDocsConfig(config_file_path=getattr(fd, 'name', ''))
+ # load the config file
+ cfg.load_file(fd)
+
+ # Then load the options to overwrite anything in the config.
+ cfg.load_dict(options)
+
+ errors, warnings = cfg.validate()
+
+ for config_name, warning in warnings:
+ log.warning(f"Config value '{config_name}': {warning}")
+
+ for config_name, error in errors:
+ log.error(f"Config value '{config_name}': {error}")
+
+ for key, value in cfg.items():
+ log.debug(f"Config value '{key}' = {value!r}")
+
+ if len(errors) > 0:
+ raise exceptions.Abort(f"Aborted with {len(errors)} Configuration Errors!")
+ elif cfg['strict'] and len(warnings) > 0:
+ raise exceptions.Abort(
+ f"Aborted with {len(warnings)} Configuration Warnings in 'strict' mode!"
+ )
+
+ return cfg
diff --git a/venv/lib/python3.11/site-packages/mkdocs/config/config_options.py b/venv/lib/python3.11/site-packages/mkdocs/config/config_options.py
new file mode 100644
index 0000000..1a035d1
--- /dev/null
+++ b/venv/lib/python3.11/site-packages/mkdocs/config/config_options.py
@@ -0,0 +1,1067 @@
+from __future__ import annotations
+
+import functools
+import ipaddress
+import os
+import string
+import sys
+import traceback
+import types
+import typing as t
+import warnings
+from collections import Counter, UserString
+from typing import (
+ Any,
+ Collection,
+ Dict,
+ Generic,
+ Iterator,
+ List,
+ Mapping,
+ MutableMapping,
+ NamedTuple,
+ Tuple,
+ TypeVar,
+ Union,
+ overload,
+)
+from urllib.parse import quote as urlquote
+from urllib.parse import urlsplit, urlunsplit
+
+import markdown
+
+from mkdocs import plugins, theme, utils
+from mkdocs.config.base import (
+ BaseConfigOption,
+ Config,
+ LegacyConfig,
+ PlainConfigSchemaItem,
+ ValidationError,
+)
+from mkdocs.exceptions import ConfigurationError
+
+T = TypeVar('T')
+SomeConfig = TypeVar('SomeConfig', bound=Config)
+
+
+class SubConfig(Generic[SomeConfig], BaseConfigOption[SomeConfig]):
+ """
+ Subconfig Config Option
+
+ New: If targeting MkDocs 1.4+, please pass a subclass of Config to the
+ constructor, instead of the old style of a sequence of ConfigOption instances.
+ Validation is then enabled by default.
+
+ A set of `config_options` grouped under a single config option.
+ By default, validation errors and warnings resulting from validating
+ `config_options` are ignored (`validate=False`). Users should typically
+ enable validation with `validate=True`.
+ """
+
+ @overload
+ def __init__(
+ self: SubConfig[SomeConfig], config_class: t.Type[SomeConfig], *, validate: bool = True
+ ):
+ """Create a sub-config in a type-safe way, using fields defined in a Config subclass."""
+
+ @overload
+ def __init__(
+ self: SubConfig[LegacyConfig],
+ *config_options: PlainConfigSchemaItem,
+ validate: bool = False,
+ ):
+ """Create an untyped sub-config, using directly passed fields."""
+
+ def __init__(self, *config_options, validate=None):
+ super().__init__()
+ self.default = {}
+ if (
+ len(config_options) == 1
+ and isinstance(config_options[0], type)
+ and issubclass(config_options[0], Config)
+ ):
+ if validate is None:
+ validate = True
+ (self._make_config,) = config_options
+ else:
+ self._make_config = functools.partial(LegacyConfig, config_options)
+ self._do_validation = bool(validate)
+
+ def run_validation(self, value: object) -> SomeConfig:
+ config = self._make_config()
+ try:
+ config.load_dict(value)
+ failed, warnings = config.validate()
+ except ConfigurationError as e:
+ raise ValidationError(str(e))
+
+ if self._do_validation:
+ # Capture errors and warnings
+ self.warnings = [f"Sub-option '{key}': {msg}" for key, msg in warnings]
+ if failed:
+ # Get the first failing one
+ key, err = failed[0]
+ raise ValidationError(f"Sub-option '{key}': {err}")
+
+ return config
+
+
+class OptionallyRequired(Generic[T], BaseConfigOption[T]):
+ """
+ Soft-deprecated, do not use.
+
+ A subclass of BaseConfigOption that adds support for default values and
+ required values. It is a base class for config options.
+ """
+
+ @overload
+ def __init__(self, default=None):
+ ...
+
+ @overload
+ def __init__(self, default=None, *, required: bool):
+ ...
+
+ def __init__(self, default=None, required=None):
+ super().__init__()
+ self.default = default
+ self._legacy_required = required
+ self.required = bool(required)
+
+ def validate(self, value):
+ """
+ Perform some initial validation.
+
+ If the option is empty (None) and isn't required, leave it as such. If
+ it is empty but has a default, use that. Finally, call the
+ run_validation method on the subclass unless.
+ """
+ if value is None:
+ if self.default is not None:
+ value = self.default
+ elif not self.required:
+ return None
+ elif self.required:
+ raise ValidationError("Required configuration not provided.")
+
+ return self.run_validation(value)
+
+
+class ListOfItems(Generic[T], BaseConfigOption[List[T]]):
+ """
+ Validates a homogeneous list of items.
+
+ E.g. for `config_options.ListOfItems(config_options.Type(int))` a valid item is `[1, 2, 3]`.
+ """
+
+ required: Union[bool, None] = None # Only for subclasses to set.
+
+ def __init__(self, option_type: BaseConfigOption[T], default=None) -> None:
+ super().__init__()
+ self.default = default
+ self.option_type = option_type
+ self.option_type.warnings = self.warnings
+
+ def __repr__(self) -> str:
+ return f'{type(self).__name__}: {self.option_type}'
+
+ def pre_validation(self, config: Config, key_name: str):
+ self._config = config
+ self._key_name = key_name
+
+ def run_validation(self, value: object) -> List[T]:
+ if value is None:
+ if self.required or self.default is None:
+ raise ValidationError("Required configuration not provided.")
+ value = self.default
+ if not isinstance(value, list):
+ raise ValidationError(f'Expected a list of items, but a {type(value)} was given.')
+ if not value: # Optimization for empty list
+ return value
+
+ fake_config = LegacyConfig(())
+ try:
+ fake_config.config_file_path = self._config.config_file_path
+ except AttributeError:
+ pass
+
+ # Emulate a config-like environment for pre_validation and post_validation.
+ parent_key_name = getattr(self, '_key_name', '')
+ fake_keys = [f'{parent_key_name}[{i}]' for i in range(len(value))]
+ fake_config.data = dict(zip(fake_keys, value))
+
+ for key_name in fake_config:
+ self.option_type.pre_validation(fake_config, key_name)
+ for key_name in fake_config:
+ # Specifically not running `validate` to avoid the OptionallyRequired effect.
+ fake_config[key_name] = self.option_type.run_validation(fake_config[key_name])
+ for key_name in fake_config:
+ self.option_type.post_validation(fake_config, key_name)
+
+ return [fake_config[k] for k in fake_keys]
+
+
+class ConfigItems(ListOfItems[LegacyConfig]):
+ """
+ Deprecated: Use `ListOfItems(SubConfig(...))` instead of `ConfigItems(...)`.
+
+ Validates a list of mappings that all must match the same set of
+ options.
+ """
+
+ @overload
+ def __init__(self, *config_options: PlainConfigSchemaItem):
+ ...
+
+ @overload
+ def __init__(self, *config_options: PlainConfigSchemaItem, required: bool):
+ ...
+
+ def __init__(self, *config_options: PlainConfigSchemaItem, required=None) -> None:
+ super().__init__(SubConfig(*config_options), default=[])
+ self._legacy_required = required
+ self.required = bool(required)
+
+
+class Type(Generic[T], OptionallyRequired[T]):
+ """
+ Type Config Option
+
+ Validate the type of a config option against a given Python type.
+ """
+
+ @overload
+ def __init__(self, type_: t.Type[T], length: t.Optional[int] = None, **kwargs):
+ ...
+
+ @overload
+ def __init__(self, type_: Tuple[t.Type[T], ...], length: t.Optional[int] = None, **kwargs):
+ ...
+
+ def __init__(self, type_, length=None, **kwargs) -> None:
+ super().__init__(**kwargs)
+ self._type = type_
+ self.length = length
+
+ def run_validation(self, value: object) -> T:
+ if not isinstance(value, self._type):
+ msg = f"Expected type: {self._type} but received: {type(value)}"
+ elif self.length is not None and len(value) != self.length:
+ msg = (
+ f"Expected type: {self._type} with length {self.length}"
+ f" but received: {value!r} with length {len(value)}"
+ )
+ else:
+ return value
+
+ raise ValidationError(msg)
+
+
+class Choice(Generic[T], OptionallyRequired[T]):
+ """
+ Choice Config Option
+
+ Validate the config option against a strict set of values.
+ """
+
+ def __init__(self, choices: Collection[T], default: t.Optional[T] = None, **kwargs) -> None:
+ super().__init__(default=default, **kwargs)
+ try:
+ length = len(choices)
+ except TypeError:
+ length = 0
+
+ if not length or isinstance(choices, str):
+ raise ValueError(f'Expected iterable of choices, got {choices}')
+ if default is not None and default not in choices:
+ raise ValueError(f'{default!r} is not one of {choices!r}')
+
+ self.choices = choices
+
+ def run_validation(self, value: object) -> T:
+ if value not in self.choices:
+ raise ValidationError(f"Expected one of: {self.choices} but received: {value!r}")
+ return value # type: ignore
+
+
+class Deprecated(BaseConfigOption):
+ """
+ Deprecated Config Option
+
+ Raises a warning as the option is deprecated. Uses `message` for the
+ warning. If `move_to` is set to the name of a new config option, the value
+ is moved to the new option on pre_validation. If `option_type` is set to a
+ ConfigOption instance, then the value is validated against that type.
+ """
+
+ def __init__(
+ self,
+ moved_to: t.Optional[str] = None,
+ message: t.Optional[str] = None,
+ removed: bool = False,
+ option_type: t.Optional[BaseConfigOption] = None,
+ ) -> None:
+ super().__init__()
+ self.default = None
+ self.moved_to = moved_to
+ if not message:
+ if removed:
+ message = "The configuration option '{}' was removed from MkDocs."
+ else:
+ message = (
+ "The configuration option '{}' has been deprecated and "
+ "will be removed in a future release."
+ )
+ if moved_to:
+ message += f" Use '{moved_to}' instead."
+
+ self.message = message
+ self.removed = removed
+ self.option = option_type or BaseConfigOption()
+
+ self.warnings = self.option.warnings
+
+ def pre_validation(self, config: Config, key_name: str):
+ self.option.pre_validation(config, key_name)
+
+ if config.get(key_name) is not None:
+ if self.removed:
+ raise ValidationError(self.message.format(key_name))
+ self.warnings.append(self.message.format(key_name))
+
+ if self.moved_to is not None:
+ *parent_keys, target_key = self.moved_to.split('.')
+ target: Any = config
+
+ for key in parent_keys:
+ if target.get(key) is None:
+ target[key] = {}
+ target = target[key]
+
+ if not isinstance(target, dict):
+ # We can't move it for the user
+ return
+
+ target[target_key] = config.pop(key_name)
+
+ def validate(self, value):
+ return self.option.validate(value)
+
+ def post_validation(self, config: Config, key_name: str):
+ self.option.post_validation(config, key_name)
+
+ def reset_warnings(self):
+ self.option.reset_warnings()
+ self.warnings = self.option.warnings
+
+
+class _IpAddressValue(NamedTuple):
+ host: str
+ port: int
+
+ def __str__(self) -> str:
+ return f'{self.host}:{self.port}'
+
+
+class IpAddress(OptionallyRequired[_IpAddressValue]):
+ """
+ IpAddress Config Option
+
+ Validate that an IP address is in an appropriate format
+ """
+
+ def run_validation(self, value: object) -> _IpAddressValue:
+ if not isinstance(value, str) or ':' not in value:
+ raise ValidationError("Must be a string of format 'IP:PORT'")
+ host, port_str = value.rsplit(':', 1)
+
+ if host != 'localhost':
+ if host.startswith('[') and host.endswith(']'):
+ host = host[1:-1]
+ try:
+ # Validate and normalize IP Address
+ host = str(ipaddress.ip_address(host))
+ except ValueError as e:
+ raise ValidationError(e)
+
+ try:
+ port = int(port_str)
+ except Exception:
+ raise ValidationError(f"'{port_str}' is not a valid port")
+
+ return _IpAddressValue(host, port)
+
+ def post_validation(self, config: Config, key_name: str):
+ host = config[key_name].host
+ if key_name == 'dev_addr' and host in ['0.0.0.0', '::']:
+ self.warnings.append(
+ f"The use of the IP address '{host}' suggests a production environment "
+ "or the use of a proxy to connect to the MkDocs server. However, "
+ "the MkDocs' server is intended for local development purposes only. "
+ "Please use a third party production-ready server instead."
+ )
+
+
+class URL(OptionallyRequired[str]):
+ """
+ URL Config Option
+
+ Validate a URL by requiring a scheme is present.
+ """
+
+ @overload
+ def __init__(self, default=None, *, is_dir: bool = False):
+ ...
+
+ @overload
+ def __init__(self, default=None, *, required: bool, is_dir: bool = False):
+ ...
+
+ def __init__(self, default=None, required=None, is_dir: bool = False) -> None:
+ self.is_dir = is_dir
+ super().__init__(default, required=required)
+
+ def run_validation(self, value: object) -> str:
+ if not isinstance(value, str):
+ raise ValidationError(f"Expected a string, got {type(value)}")
+ if value == '':
+ return value
+ try:
+ parsed_url = urlsplit(value)
+ except (AttributeError, TypeError):
+ raise ValidationError("Unable to parse the URL.")
+
+ if parsed_url.scheme and parsed_url.netloc:
+ if self.is_dir and not parsed_url.path.endswith('/'):
+ parsed_url = parsed_url._replace(path=f'{parsed_url.path}/')
+ return urlunsplit(parsed_url)
+
+ raise ValidationError("The URL isn't valid, it should include the http:// (scheme)")
+
+
+class Optional(Generic[T], BaseConfigOption[Union[T, None]]):
+ """Wraps a field and makes a None value possible for it when no value is set.
+
+ E.g. `my_field = config_options.Optional(config_options.Type(str))`
+ """
+
+ def __init__(self, config_option: BaseConfigOption[T]) -> None:
+ if config_option.default is not None:
+ raise ValueError(
+ f"This option already has a default ({config_option.default!r}) "
+ f"and doesn't need to be wrapped into Optional"
+ )
+ super().__init__()
+ self.option = config_option
+ self.warnings = config_option.warnings
+
+ def __getattr__(self, key):
+ if key in ('option', 'warnings'):
+ raise AttributeError
+ return getattr(self.option, key)
+
+ def pre_validation(self, config: Config, key_name: str):
+ return self.option.pre_validation(config, key_name)
+
+ def run_validation(self, value: object) -> Union[T, None]:
+ if value is None:
+ return None
+ return self.option.validate(value)
+
+ def post_validation(self, config: Config, key_name: str):
+ result = self.option.post_validation(config, key_name) # type: ignore
+ self.warnings = self.option.warnings
+ return result
+
+ def reset_warnings(self):
+ self.option.reset_warnings()
+ self.warnings = self.option.warnings
+
+
+class RepoURL(URL):
+ def __init__(self, *args, **kwargs):
+ warnings.warn(
+ "RepoURL is no longer used in MkDocs and will be removed.", DeprecationWarning
+ )
+ super().__init__(*args, **kwargs)
+
+ def post_validation(self, config: Config, key_name: str):
+ repo_host = urlsplit(config['repo_url']).netloc.lower()
+ edit_uri = config.get('edit_uri')
+
+ # derive repo_name from repo_url if unset
+ if config['repo_url'] is not None and config.get('repo_name') is None:
+ if repo_host == 'github.com':
+ config['repo_name'] = 'GitHub'
+ elif repo_host == 'bitbucket.org':
+ config['repo_name'] = 'Bitbucket'
+ elif repo_host == 'gitlab.com':
+ config['repo_name'] = 'GitLab'
+ else:
+ config['repo_name'] = repo_host.split('.')[0].title()
+
+ # derive edit_uri from repo_name if unset
+ if config['repo_url'] is not None and edit_uri is None:
+ if repo_host == 'github.com' or repo_host == 'gitlab.com':
+ edit_uri = 'edit/master/docs/'
+ elif repo_host == 'bitbucket.org':
+ edit_uri = 'src/default/docs/'
+ else:
+ edit_uri = ''
+
+ # ensure a well-formed edit_uri
+ if edit_uri and not edit_uri.endswith('/'):
+ edit_uri += '/'
+
+ config['edit_uri'] = edit_uri
+
+
+class EditURI(Type[str]):
+ def __init__(self, repo_url_key: str) -> None:
+ super().__init__(str)
+ self.repo_url_key = repo_url_key
+
+ def post_validation(self, config: Config, key_name: str):
+ edit_uri = config.get(key_name)
+ repo_url = config.get(self.repo_url_key)
+
+ if edit_uri is None and repo_url is not None:
+ repo_host = urlsplit(repo_url).netloc.lower()
+ if repo_host == 'github.com' or repo_host == 'gitlab.com':
+ edit_uri = 'edit/master/docs/'
+ elif repo_host == 'bitbucket.org':
+ edit_uri = 'src/default/docs/'
+
+ # ensure a well-formed edit_uri
+ if edit_uri and not edit_uri.endswith('/'):
+ edit_uri += '/'
+
+ config[key_name] = edit_uri
+
+
+class EditURITemplate(BaseConfigOption[str]):
+ class Formatter(string.Formatter):
+ def convert_field(self, value, conversion):
+ if conversion == 'q':
+ return urlquote(value, safe='')
+ return super().convert_field(value, conversion)
+
+ class Template(UserString):
+ def __init__(self, formatter, data) -> None:
+ super().__init__(data)
+ self.formatter = formatter
+ try:
+ self.format('', '')
+ except KeyError as e:
+ raise ValueError(f"Unknown template substitute: {e}")
+
+ def format(self, path, path_noext):
+ return self.formatter.format(self.data, path=path, path_noext=path_noext)
+
+ def __init__(self, edit_uri_key: t.Optional[str] = None) -> None:
+ super().__init__()
+ self.edit_uri_key = edit_uri_key
+
+ def run_validation(self, value: object):
+ try:
+ return self.Template(self.Formatter(), value)
+ except Exception as e:
+ raise ValidationError(e)
+
+ def post_validation(self, config: Config, key_name: str):
+ if self.edit_uri_key and config.get(key_name) and config.get(self.edit_uri_key):
+ self.warnings.append(
+ f"The option '{self.edit_uri_key}' has no effect when '{key_name}' is set."
+ )
+
+
+class RepoName(Type[str]):
+ def __init__(self, repo_url_key: str) -> None:
+ super().__init__(str)
+ self.repo_url_key = repo_url_key
+
+ def post_validation(self, config: Config, key_name: str):
+ repo_name = config.get(key_name)
+ repo_url = config.get(self.repo_url_key)
+
+ # derive repo_name from repo_url if unset
+ if repo_url is not None and repo_name is None:
+ repo_host = urlsplit(config['repo_url']).netloc.lower()
+ if repo_host == 'github.com':
+ repo_name = 'GitHub'
+ elif repo_host == 'bitbucket.org':
+ repo_name = 'Bitbucket'
+ elif repo_host == 'gitlab.com':
+ repo_name = 'GitLab'
+ else:
+ repo_name = repo_host.split('.')[0].title()
+ config[key_name] = repo_name
+
+
+class FilesystemObject(Type[str]):
+ """
+ Base class for options that point to filesystem objects.
+ """
+
+ existence_test = staticmethod(os.path.exists)
+ name = 'file or directory'
+
+ def __init__(self, exists: bool = False, **kwargs) -> None:
+ super().__init__(type_=str, **kwargs)
+ self.exists = exists
+ self.config_dir: t.Optional[str] = None
+
+ def pre_validation(self, config: Config, key_name: str):
+ self.config_dir = (
+ os.path.dirname(config.config_file_path) if config.config_file_path else None
+ )
+
+ def run_validation(self, value: object) -> str:
+ value = super().run_validation(value)
+ if self.config_dir and not os.path.isabs(value):
+ value = os.path.join(self.config_dir, value)
+ if self.exists and not self.existence_test(value):
+ raise ValidationError(f"The path '{value}' isn't an existing {self.name}.")
+ return os.path.abspath(value)
+
+
+class Dir(FilesystemObject):
+ """
+ Dir Config Option
+
+ Validate a path to a directory, optionally verifying that it exists.
+ """
+
+ existence_test = staticmethod(os.path.isdir)
+ name = 'directory'
+
+
+class DocsDir(Dir):
+ def post_validation(self, config: Config, key_name: str):
+ if config.config_file_path is None:
+ return
+
+ # Validate that the dir is not the parent dir of the config file.
+ if os.path.dirname(config.config_file_path) == config[key_name]:
+ raise ValidationError(
+ f"The '{key_name}' should not be the parent directory of the"
+ f" config file. Use a child directory instead so that the"
+ f" '{key_name}' is a sibling of the config file."
+ )
+
+
+class File(FilesystemObject):
+ """
+ File Config Option
+
+ Validate a path to a file, optionally verifying that it exists.
+ """
+
+ existence_test = staticmethod(os.path.isfile)
+ name = 'file'
+
+
+class ListOfPaths(ListOfItems[str]):
+ """
+ List of Paths Config Option
+
+ A list of file system paths. Raises an error if one of the paths does not exist.
+
+ For greater flexibility, prefer ListOfItems, e.g. to require files specifically:
+
+ config_options.ListOfItems(config_options.File(exists=True))
+ """
+
+ @overload
+ def __init__(self, default=[]):
+ ...
+
+ @overload
+ def __init__(self, default=[], *, required: bool):
+ ...
+
+ def __init__(self, default=[], required=None) -> None:
+ super().__init__(FilesystemObject(exists=True), default)
+ self.required = required
+
+
+class SiteDir(Dir):
+ """
+ SiteDir Config Option
+
+ Validates the site_dir and docs_dir directories do not contain each other.
+ """
+
+ def post_validation(self, config: Config, key_name: str):
+ super().post_validation(config, key_name)
+ docs_dir = config['docs_dir']
+ site_dir = config['site_dir']
+
+ # Validate that the docs_dir and site_dir don't contain the
+ # other as this will lead to copying back and forth on each
+ # and eventually make a deep nested mess.
+ if (docs_dir + os.sep).startswith(site_dir.rstrip(os.sep) + os.sep):
+ raise ValidationError(
+ f"The 'docs_dir' should not be within the 'site_dir' as this "
+ f"can mean the source files are overwritten by the output or "
+ f"it will be deleted if --clean is passed to mkdocs build. "
+ f"(site_dir: '{site_dir}', docs_dir: '{docs_dir}')"
+ )
+ elif (site_dir + os.sep).startswith(docs_dir.rstrip(os.sep) + os.sep):
+ raise ValidationError(
+ f"The 'site_dir' should not be within the 'docs_dir' as this "
+ f"leads to the build directory being copied into itself and "
+ f"duplicate nested files in the 'site_dir'. "
+ f"(site_dir: '{site_dir}', docs_dir: '{docs_dir}')"
+ )
+
+
+class Theme(BaseConfigOption[theme.Theme]):
+ """
+ Theme Config Option
+
+ Validate that the theme exists and build Theme instance.
+ """
+
+ def __init__(self, default=None) -> None:
+ super().__init__()
+ self.default = default
+
+ def pre_validation(self, config: Config, key_name: str):
+ self.config_file_path = config.config_file_path
+
+ def run_validation(self, value: object) -> theme.Theme:
+ if value is None and self.default is not None:
+ theme_config = {'name': self.default}
+ elif isinstance(value, str):
+ theme_config = {'name': value}
+ elif isinstance(value, dict):
+ if 'name' not in value:
+ raise ValidationError("No theme name set.")
+ theme_config = value
+ else:
+ raise ValidationError(
+ f'Invalid type {type(value)}. Expected a string or key/value pairs.'
+ )
+
+ themes = utils.get_theme_names()
+ if theme_config['name'] is not None and theme_config['name'] not in themes:
+ raise ValidationError(
+ f"Unrecognised theme name: '{theme_config['name']}'. "
+ f"The available installed themes are: {', '.join(themes)}"
+ )
+
+ if not theme_config['name'] and 'custom_dir' not in theme_config:
+ raise ValidationError("At least one of 'name' or 'custom_dir' must be defined.")
+
+ # Ensure custom_dir is an absolute path
+ if 'custom_dir' in theme_config and not os.path.isabs(theme_config['custom_dir']):
+ assert self.config_file_path is not None
+ config_dir = os.path.dirname(self.config_file_path)
+ theme_config['custom_dir'] = os.path.join(config_dir, theme_config['custom_dir'])
+
+ if 'custom_dir' in theme_config and not os.path.isdir(theme_config['custom_dir']):
+ raise ValidationError(
+ "The path set in custom_dir ('{path}') does not exist.".format(
+ path=theme_config['custom_dir']
+ )
+ )
+
+ if 'locale' in theme_config and not isinstance(theme_config['locale'], str):
+ raise ValidationError("'locale' must be a string.")
+
+ return theme.Theme(**theme_config)
+
+
+class Nav(OptionallyRequired):
+ """
+ Nav Config Option
+
+ Validate the Nav config.
+ """
+
+ def run_validation(self, value: object, *, top=True):
+ if isinstance(value, list):
+ for subitem in value:
+ self._validate_nav_item(subitem)
+ if top and not value:
+ value = None
+ elif isinstance(value, dict) and value and not top:
+ # TODO: this should be an error.
+ self.warnings.append(f"Expected nav to be a list, got {self._repr_item(value)}")
+ for subitem in value.values():
+ self.run_validation(subitem, top=False)
+ elif isinstance(value, str) and not top:
+ pass
+ else:
+ raise ValidationError(f"Expected nav to be a list, got {self._repr_item(value)}")
+ return value
+
+ def _validate_nav_item(self, value):
+ if isinstance(value, str):
+ pass
+ elif isinstance(value, dict):
+ if len(value) != 1:
+ raise ValidationError(
+ f"Expected nav item to be a dict of size 1, got {self._repr_item(value)}"
+ )
+ for subnav in value.values():
+ self.run_validation(subnav, top=False)
+ else:
+ raise ValidationError(
+ f"Expected nav item to be a string or dict, got {self._repr_item(value)}"
+ )
+
+ @classmethod
+ def _repr_item(cls, value) -> str:
+ if isinstance(value, dict) and value:
+ return f"dict with keys {tuple(value.keys())}"
+ elif isinstance(value, (str, type(None))):
+ return repr(value)
+ else:
+ return f"a {type(value).__name__}: {value!r}"
+
+
+class Private(BaseConfigOption):
+ """
+ Private Config Option
+
+ A config option only for internal use. Raises an error if set by the user.
+ """
+
+ def run_validation(self, value: object):
+ if value is not None:
+ raise ValidationError('For internal use only.')
+
+
+class MarkdownExtensions(OptionallyRequired[List[str]]):
+ """
+ Markdown Extensions Config Option
+
+ A list or dict of extensions. Each list item may contain either a string or a one item dict.
+ A string must be a valid Markdown extension name with no config options defined. The key of
+ a dict item must be a valid Markdown extension name and the value must be a dict of config
+ options for that extension. Extension configs are set on the private setting passed to
+ `configkey`. The `builtins` keyword accepts a list of extensions which cannot be overridden by
+ the user. However, builtins can be duplicated to define config options for them if desired."""
+
+ def __init__(
+ self,
+ builtins: t.Optional[List[str]] = None,
+ configkey: str = 'mdx_configs',
+ default: List[str] = [],
+ **kwargs,
+ ) -> None:
+ super().__init__(default=default, **kwargs)
+ self.builtins = builtins or []
+ self.configkey = configkey
+
+ def validate_ext_cfg(self, ext, cfg):
+ if not isinstance(ext, str):
+ raise ValidationError(f"'{ext}' is not a valid Markdown Extension name.")
+ if not cfg:
+ return
+ if not isinstance(cfg, dict):
+ raise ValidationError(f"Invalid config options for Markdown Extension '{ext}'.")
+ self.configdata[ext] = cfg
+
+ def run_validation(self, value: object):
+ self.configdata: Dict[str, dict] = {}
+ if not isinstance(value, (list, tuple, dict)):
+ raise ValidationError('Invalid Markdown Extensions configuration')
+ extensions = []
+ if isinstance(value, dict):
+ for ext, cfg in value.items():
+ self.validate_ext_cfg(ext, cfg)
+ extensions.append(ext)
+ else:
+ for item in value:
+ if isinstance(item, dict):
+ if len(item) > 1:
+ raise ValidationError('Invalid Markdown Extensions configuration')
+ ext, cfg = item.popitem()
+ self.validate_ext_cfg(ext, cfg)
+ extensions.append(ext)
+ elif isinstance(item, str):
+ extensions.append(item)
+ else:
+ raise ValidationError('Invalid Markdown Extensions configuration')
+
+ extensions = utils.reduce_list(self.builtins + extensions)
+
+ # Confirm that Markdown considers extensions to be valid
+ md = markdown.Markdown()
+ for ext in extensions:
+ try:
+ md.registerExtensions((ext,), self.configdata)
+ except Exception as e:
+ stack: list = []
+ for frame in reversed(traceback.extract_tb(sys.exc_info()[2])):
+ if not frame.line: # Ignore frames before
+ break
+ stack.insert(0, frame)
+ tb = ''.join(traceback.format_list(stack))
+
+ raise ValidationError(
+ f"Failed to load extension '{ext}'.\n{tb}{type(e).__name__}: {e}"
+ )
+
+ return extensions
+
+ def post_validation(self, config: Config, key_name: str):
+ config[self.configkey] = self.configdata
+
+
+class Plugins(OptionallyRequired[plugins.PluginCollection]):
+ """
+ Plugins config option.
+
+ A list or dict of plugins. If a plugin defines config options those are used when
+ initializing the plugin class.
+ """
+
+ def __init__(self, theme_key: t.Optional[str] = None, **kwargs) -> None:
+ super().__init__(**kwargs)
+ self.installed_plugins = plugins.get_plugins()
+ self.theme_key = theme_key
+ self._config: t.Optional[Config] = None
+ self.plugin_cache: Dict[str, plugins.BasePlugin] = {}
+
+ def pre_validation(self, config, key_name):
+ self._config = config
+
+ def run_validation(self, value: object) -> plugins.PluginCollection:
+ if not isinstance(value, (list, tuple, dict)):
+ raise ValidationError('Invalid Plugins configuration. Expected a list or dict.')
+ self.plugins = plugins.PluginCollection()
+ self._instance_counter: MutableMapping[str, int] = Counter()
+ for name, cfg in self._parse_configs(value):
+ self.load_plugin_with_namespace(name, cfg)
+ return self.plugins
+
+ @classmethod
+ def _parse_configs(cls, value: Union[list, tuple, dict]) -> Iterator[Tuple[str, dict]]:
+ if isinstance(value, dict):
+ for name, cfg in value.items():
+ if not isinstance(name, str):
+ raise ValidationError(f"'{name}' is not a valid plugin name.")
+ yield name, cfg
+ else:
+ for item in value:
+ if isinstance(item, dict):
+ if len(item) != 1:
+ raise ValidationError('Invalid Plugins configuration')
+ name, cfg = item.popitem()
+ else:
+ name = item
+ cfg = {}
+ if not isinstance(name, str):
+ raise ValidationError(f"'{name}' is not a valid plugin name.")
+ yield name, cfg
+
+ def load_plugin_with_namespace(self, name: str, config) -> Tuple[str, plugins.BasePlugin]:
+ if '/' in name: # It's already specified with a namespace.
+ # Special case: allow to explicitly skip namespaced loading:
+ if name.startswith('/'):
+ name = name[1:]
+ else:
+ # Attempt to load with prepended namespace for the current theme.
+ if self.theme_key and self._config:
+ current_theme = self._config[self.theme_key]['name']
+ if current_theme:
+ expanded_name = f'{current_theme}/{name}'
+ if expanded_name in self.installed_plugins:
+ name = expanded_name
+ return (name, self.load_plugin(name, config))
+
+ def load_plugin(self, name: str, config) -> plugins.BasePlugin:
+ if name not in self.installed_plugins:
+ raise ValidationError(f'The "{name}" plugin is not installed')
+
+ config = config or {} # Users may define a null (None) config
+ if not isinstance(config, dict):
+ raise ValidationError(f"Invalid config options for the '{name}' plugin.")
+
+ self._instance_counter[name] += 1
+ inst_number = self._instance_counter[name]
+ inst_name = name
+ if inst_number > 1:
+ inst_name += f' #{inst_number}'
+
+ plugin = self.plugin_cache.get(inst_name)
+ if plugin is None:
+ plugin_cls = self.installed_plugins[name].load()
+
+ if not issubclass(plugin_cls, plugins.BasePlugin):
+ raise ValidationError(
+ f'{plugin_cls.__module__}.{plugin_cls.__name__} must be a subclass of'
+ f' {plugins.BasePlugin.__module__}.{plugins.BasePlugin.__name__}'
+ )
+
+ plugin = plugin_cls()
+
+ if hasattr(plugin, 'on_startup') or hasattr(plugin, 'on_shutdown'):
+ self.plugin_cache[inst_name] = plugin
+
+ if inst_number > 1 and not getattr(plugin, 'supports_multiple_instances', False):
+ self.warnings.append(
+ f"Plugin '{name}' was specified multiple times - this is likely a mistake, "
+ "because the plugin doesn't declare `supports_multiple_instances`."
+ )
+
+ errors, warns = plugin.load_config(
+ config, self._config.config_file_path if self._config else None
+ )
+ for warning in warns:
+ if isinstance(warning, str):
+ self.warnings.append(f"Plugin '{inst_name}': {warning}")
+ else:
+ key, msg = warning
+ self.warnings.append(f"Plugin '{inst_name}' option '{key}': {msg}")
+
+ errors_message = '\n'.join(f"Plugin '{name}' option '{key}': {msg}" for key, msg in errors)
+ if errors_message:
+ raise ValidationError(errors_message)
+ self.plugins[inst_name] = plugin
+ return plugin
+
+
+class Hooks(BaseConfigOption[List[types.ModuleType]]):
+ """A list of Python scripts to be treated as instances of plugins."""
+
+ def __init__(self, plugins_key: str) -> None:
+ super().__init__()
+ self.default = []
+ self.plugins_key = plugins_key
+
+ def pre_validation(self, config: Config, key_name: str):
+ self._base_option = ListOfItems(File(exists=True))
+ self._base_option.pre_validation(config, key_name)
+
+ def run_validation(self, value: object) -> Mapping[str, Any]:
+ paths = self._base_option.validate(value)
+ self.warnings.extend(self._base_option.warnings)
+ value = t.cast(List[str], value)
+
+ hooks = {}
+ for name, path in zip(value, paths):
+ hooks[name] = self._load_hook(name, path)
+ return hooks
+
+ @functools.lru_cache(maxsize=None)
+ def _load_hook(self, name, path):
+ import importlib.util
+
+ spec = importlib.util.spec_from_file_location(name, path)
+ if spec is None:
+ raise ValidationError(f"Cannot import path '{path}' as a Python module")
+ module = importlib.util.module_from_spec(spec)
+ if spec.loader is None:
+ raise ValidationError(f"Cannot import path '{path}' as a Python module")
+ spec.loader.exec_module(module)
+ return module
+
+ def post_validation(self, config: Config, key_name: str):
+ plugins = config[self.plugins_key]
+ for name, hook in config[key_name].items():
+ plugins[name] = hook
diff --git a/venv/lib/python3.11/site-packages/mkdocs/config/defaults.py b/venv/lib/python3.11/site-packages/mkdocs/config/defaults.py
new file mode 100644
index 0000000..9590ace
--- /dev/null
+++ b/venv/lib/python3.11/site-packages/mkdocs/config/defaults.py
@@ -0,0 +1,130 @@
+from __future__ import annotations
+
+from mkdocs.config import base
+from mkdocs.config import config_options as c
+
+
+def get_schema() -> base.PlainConfigSchema:
+ return MkDocsConfig._schema
+
+
+# NOTE: The order here is important. During validation some config options
+# depend on others. So, if config option A depends on B, then A should be
+# listed higher in the schema.
+class MkDocsConfig(base.Config):
+ """The configuration of MkDocs itself (the root object of mkdocs.yml)."""
+
+ config_file_path: str = c.Optional(c.Type(str)) # type: ignore[assignment]
+ """Reserved for internal use, stores the mkdocs.yml config file."""
+
+ site_name = c.Type(str)
+ """The title to use for the documentation."""
+
+ nav = c.Optional(c.Nav())
+ """Defines the structure of the navigation."""
+ pages = c.Deprecated(removed=True, moved_to='nav')
+
+ site_url = c.Optional(c.URL(is_dir=True))
+ """The full URL to where the documentation will be hosted."""
+
+ site_description = c.Optional(c.Type(str))
+ """A description for the documentation project that will be added to the
+ HTML meta tags."""
+ site_author = c.Optional(c.Type(str))
+ """The name of the author to add to the HTML meta tags."""
+
+ theme = c.Theme(default='mkdocs')
+ """The MkDocs theme for the documentation."""
+
+ docs_dir = c.DocsDir(default='docs', exists=True)
+ """The directory containing the documentation markdown."""
+
+ site_dir = c.SiteDir(default='site')
+ """The directory where the site will be built to"""
+
+ copyright = c.Optional(c.Type(str))
+ """A copyright notice to add to the footer of documentation."""
+
+ google_analytics = c.Deprecated(
+ message=(
+ 'The configuration option {} has been deprecated and '
+ 'will be removed in a future release of MkDocs. See the '
+ 'options available on your theme for an alternative.'
+ ),
+ option_type=c.Type(list, length=2),
+ )
+ """set of values for Google analytics containing the account IO and domain
+ this should look like, ['UA-27795084-5', 'mkdocs.org']"""
+
+ dev_addr = c.IpAddress(default='127.0.0.1:8000')
+ """The address on which to serve the live reloading docs server."""
+
+ use_directory_urls = c.Type(bool, default=True)
+ """If `True`, use `/index.hmtl` style files with hyperlinks to
+ the directory.If `False`, use `.html style file with
+ hyperlinks to the file.
+ True generates nicer URLs, but False is useful if browsing the output on
+ a filesystem."""
+
+ repo_url = c.Optional(c.URL())
+ """Specify a link to the project source repo to be included
+ in the documentation pages."""
+
+ repo_name = c.Optional(c.RepoName('repo_url'))
+ """A name to use for the link to the project source repo.
+ Default, If repo_url is unset then None, otherwise
+ "GitHub", "Bitbucket" or "GitLab" for known url or Hostname
+ for unknown urls."""
+
+ edit_uri_template = c.Optional(c.EditURITemplate('edit_uri'))
+ edit_uri = c.Optional(c.EditURI('repo_url'))
+ """Specify a URI to the docs dir in the project source repo, relative to the
+ repo_url. When set, a link directly to the page in the source repo will
+ be added to the generated HTML. If repo_url is not set also, this option
+ is ignored."""
+
+ extra_css = c.Type(list, default=[])
+ extra_javascript = c.Type(list, default=[])
+ """Specify which css or javascript files from the docs directory should be
+ additionally included in the site."""
+
+ extra_templates = c.Type(list, default=[])
+ """Similar to the above, but each template (HTML or XML) will be build with
+ Jinja2 and the global context."""
+
+ markdown_extensions = c.MarkdownExtensions(
+ builtins=['toc', 'tables', 'fenced_code'], configkey='mdx_configs'
+ )
+ """PyMarkdown extension names."""
+
+ mdx_configs = c.Private()
+ """PyMarkdown Extension Configs. For internal use only."""
+
+ strict = c.Type(bool, default=False)
+ """Enabling strict mode causes MkDocs to stop the build when a problem is
+ encountered rather than display an error."""
+
+ remote_branch = c.Type(str, default='gh-pages')
+ """The remote branch to commit to when using gh-deploy."""
+
+ remote_name = c.Type(str, default='origin')
+ """The remote name to push to when using gh-deploy."""
+
+ extra = c.SubConfig()
+ """extra is a mapping/dictionary of data that is passed to the template.
+ This allows template authors to require extra configuration that not
+ relevant to all themes and doesn't need to be explicitly supported by
+ MkDocs itself. A good example here would be including the current
+ project version."""
+
+ plugins = c.Plugins(theme_key='theme', default=['search'])
+ """A list of plugins. Each item may contain a string name or a key value pair.
+ A key value pair should be the string name (as the key) and a dict of config
+ options (as the value)."""
+
+ hooks = c.Hooks('plugins')
+ """A list of filenames that will be imported as Python modules and used as
+ an instance of a plugin each."""
+
+ watch = c.ListOfPaths(default=[])
+ """A list of extra paths to watch while running `mkdocs serve`."""
diff --git a/venv/lib/python3.11/site-packages/mkdocs/contrib/__init__.py b/venv/lib/python3.11/site-packages/mkdocs/contrib/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/venv/lib/python3.11/site-packages/mkdocs/contrib/__pycache__/__init__.cpython-311.pyc b/venv/lib/python3.11/site-packages/mkdocs/contrib/__pycache__/__init__.cpython-311.pyc
new file mode 100644
index 0000000..e8cc234
Binary files /dev/null and b/venv/lib/python3.11/site-packages/mkdocs/contrib/__pycache__/__init__.cpython-311.pyc differ
diff --git a/venv/lib/python3.11/site-packages/mkdocs/contrib/search/__init__.py b/venv/lib/python3.11/site-packages/mkdocs/contrib/search/__init__.py
new file mode 100644
index 0000000..a6f26ab
--- /dev/null
+++ b/venv/lib/python3.11/site-packages/mkdocs/contrib/search/__init__.py
@@ -0,0 +1,115 @@
+from __future__ import annotations
+
+import logging
+import os
+from typing import Any, Dict, List
+
+from mkdocs import utils
+from mkdocs.config import base
+from mkdocs.config import config_options as c
+from mkdocs.config.defaults import MkDocsConfig
+from mkdocs.contrib.search.search_index import SearchIndex
+from mkdocs.plugins import BasePlugin
+
+log = logging.getLogger(__name__)
+base_path = os.path.dirname(os.path.abspath(__file__))
+
+
+class LangOption(c.OptionallyRequired[List[str]]):
+ """Validate Language(s) provided in config are known languages."""
+
+ def get_lunr_supported_lang(self, lang):
+ fallback = {'uk': 'ru'}
+ for lang_part in lang.split("_"):
+ lang_part = lang_part.lower()
+ lang_part = fallback.get(lang_part, lang_part)
+ if os.path.isfile(os.path.join(base_path, 'lunr-language', f'lunr.{lang_part}.js')):
+ return lang_part
+
+ def run_validation(self, value: object):
+ if isinstance(value, str):
+ value = [value]
+ if not isinstance(value, list):
+ raise c.ValidationError('Expected a list of language codes.')
+ for lang in list(value):
+ if lang != 'en':
+ lang_detected = self.get_lunr_supported_lang(lang)
+ if not lang_detected:
+ log.info(f"Option search.lang '{lang}' is not supported, falling back to 'en'")
+ value.remove(lang)
+ if 'en' not in value:
+ value.append('en')
+ elif lang_detected != lang:
+ value.remove(lang)
+ value.append(lang_detected)
+ log.info(f"Option search.lang '{lang}' switched to '{lang_detected}'")
+ return value
+
+
+class _PluginConfig(base.Config):
+ lang = c.Optional(LangOption())
+ separator = c.Type(str, default=r'[\s\-]+')
+ min_search_length = c.Type(int, default=3)
+ prebuild_index = c.Choice((False, True, 'node', 'python'), default=False)
+ indexing = c.Choice(('full', 'sections', 'titles'), default='full')
+
+
+class SearchPlugin(BasePlugin[_PluginConfig]):
+ """Add a search feature to MkDocs."""
+
+ def on_config(self, config: MkDocsConfig, **kwargs) -> MkDocsConfig:
+ "Add plugin templates and scripts to config."
+ if 'include_search_page' in config.theme and config.theme['include_search_page']:
+ config.theme.static_templates.add('search.html')
+ if not ('search_index_only' in config.theme and config.theme['search_index_only']):
+ path = os.path.join(base_path, 'templates')
+ config.theme.dirs.append(path)
+ if 'search/main.js' not in config.extra_javascript:
+ config.extra_javascript.append('search/main.js')
+ if self.config.lang is None:
+ # lang setting undefined. Set default based on theme locale
+ validate = _PluginConfig.lang.run_validation
+ self.config.lang = validate(config.theme['locale'].language)
+ # The `python` method of `prebuild_index` is pending deprecation as of version 1.2.
+ # TODO: Raise a deprecation warning in a future release (1.3?).
+ if self.config.prebuild_index == 'python':
+ log.info(
+ "The 'python' method of the search plugin's 'prebuild_index' config option "
+ "is pending deprecation and will not be supported in a future release."
+ )
+ return config
+
+ def on_pre_build(self, config: MkDocsConfig, **kwargs) -> None:
+ "Create search index instance for later use."
+ self.search_index = SearchIndex(**self.config)
+
+ def on_page_context(self, context: Dict[str, Any], **kwargs) -> None:
+ "Add page to search index."
+ self.search_index.add_entry_from_context(context['page'])
+
+ def on_post_build(self, config: MkDocsConfig, **kwargs) -> None:
+ "Build search index."
+ output_base_path = os.path.join(config.site_dir, 'search')
+ search_index = self.search_index.generate_search_index()
+ json_output_path = os.path.join(output_base_path, 'search_index.json')
+ utils.write_file(search_index.encode('utf-8'), json_output_path)
+
+ assert self.config.lang is not None
+ if not ('search_index_only' in config.theme and config.theme['search_index_only']):
+ # Include language support files in output. Copy them directly
+ # so that only the needed files are included.
+ files = []
+ if len(self.config.lang) > 1 or 'en' not in self.config.lang:
+ files.append('lunr.stemmer.support.js')
+ if len(self.config.lang) > 1:
+ files.append('lunr.multi.js')
+ if 'ja' in self.config.lang or 'jp' in self.config.lang:
+ files.append('tinyseg.js')
+ for lang in self.config.lang:
+ if lang != 'en':
+ files.append(f'lunr.{lang}.js')
+
+ for filename in files:
+ from_path = os.path.join(base_path, 'lunr-language', filename)
+ to_path = os.path.join(output_base_path, filename)
+ utils.copy_file(from_path, to_path)
diff --git a/venv/lib/python3.11/site-packages/mkdocs/contrib/search/__pycache__/__init__.cpython-311.pyc b/venv/lib/python3.11/site-packages/mkdocs/contrib/search/__pycache__/__init__.cpython-311.pyc
new file mode 100644
index 0000000..8fd0fa0
Binary files /dev/null and b/venv/lib/python3.11/site-packages/mkdocs/contrib/search/__pycache__/__init__.cpython-311.pyc differ
diff --git a/venv/lib/python3.11/site-packages/mkdocs/contrib/search/__pycache__/search_index.cpython-311.pyc b/venv/lib/python3.11/site-packages/mkdocs/contrib/search/__pycache__/search_index.cpython-311.pyc
new file mode 100644
index 0000000..177cd36
Binary files /dev/null and b/venv/lib/python3.11/site-packages/mkdocs/contrib/search/__pycache__/search_index.cpython-311.pyc differ
diff --git a/venv/lib/python3.11/site-packages/mkdocs/contrib/search/lunr-language/lunr.ar.js b/venv/lib/python3.11/site-packages/mkdocs/contrib/search/lunr-language/lunr.ar.js
new file mode 100644
index 0000000..c5450f1
--- /dev/null
+++ b/venv/lib/python3.11/site-packages/mkdocs/contrib/search/lunr-language/lunr.ar.js
@@ -0,0 +1,381 @@
+/*!
+ * Lunr languages, `Arabic` language
+ * https://github.com/MihaiValentin/lunr-languages
+ *
+ * Copyright 2018, Dalia Al-Shahrabi
+ * http://www.mozilla.org/MPL/
+ */
+/*!
+ * based on
+ * Kazem Taghva, Rania Elkhoury, and Jeffrey Coombs (2005)
+ * Meryeme Hadni, Abdelmonaime Lachkar, and S. Alaoui Ouatik (2012)
+ *
+ * Snowball JavaScript Library v0.3
+ * http://code.google.com/p/urim/
+ * http://snowball.tartarus.org/
+ *
+ * Copyright 2010, Oleg Mazko
+ * http://www.mozilla.org/MPL/
+ */
+
+/**
+ * export the module via AMD, CommonJS or as a browser global
+ * Export code from https://github.com/umdjs/umd/blob/master/returnExports.js
+ */
+;
+(function(root, factory) {
+ if (typeof define === 'function' && define.amd) {
+ // AMD. Register as an anonymous module.
+ define(factory)
+ } else if (typeof exports === 'object') {
+ /**
+ * Node. Does not work with strict CommonJS, but
+ * only CommonJS-like environments that support module.exports,
+ * like Node.
+ */
+ module.exports = factory()
+ } else {
+ // Browser globals (root is window)
+ factory()(root.lunr);
+ }
+}(this, function() {
+ /**
+ * Just return a value to define the module export.
+ * This example returns an object, but the module
+ * can return a function as the exported value.
+ */
+ return function(lunr) {
+ /* throw error if lunr is not yet included */
+ if ('undefined' === typeof lunr) {
+ throw new Error('Lunr is not present. Please include / require Lunr before this script.');
+ }
+
+ /* throw error if lunr stemmer support is not yet included */
+ if ('undefined' === typeof lunr.stemmerSupport) {
+ throw new Error('Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.');
+ }
+
+ /* register specific locale function */
+ lunr.ar = function() {
+ this.pipeline.reset();
+ this.pipeline.add(
+ lunr.ar.trimmer,
+ lunr.ar.stopWordFilter,
+ lunr.ar.stemmer
+ );
+
+ // for lunr version 2
+ // this is necessary so that every searched word is also stemmed before
+ // in lunr <= 1 this is not needed, as it is done using the normal pipeline
+ if (this.searchPipeline) {
+ this.searchPipeline.reset();
+ this.searchPipeline.add(lunr.ar.stemmer)
+ }
+ };
+
+ /* lunr trimmer function */
+ lunr.ar.wordCharacters = "\u0621-\u065b\u0671\u0640";
+ lunr.ar.trimmer = lunr.trimmerSupport.generateTrimmer(lunr.ar.wordCharacters);
+
+ lunr.Pipeline.registerFunction(lunr.ar.trimmer, 'trimmer-ar');
+
+ /* lunr stemmer function */
+ lunr.ar.stemmer = (function() {
+ var self = this;
+ var word = '';
+ self.result = false;
+ self.preRemoved = false;
+ self.sufRemoved = false;
+
+ //prefix data
+ self.pre = {
+ pre1: 'ف ك ب و س ل ن ا ي ت',
+ pre2: 'ال لل',
+ pre3: 'بال وال فال تال كال ولل',
+ pre4: 'فبال كبال وبال وكال'
+ };
+
+ //suffix data
+ self.suf = {
+ suf1: 'ه ك ت ن ا ي',
+ suf2: 'نك نه ها وك يا اه ون ين تن تم نا وا ان كم كن ني نن ما هم هن تك ته ات يه',
+ suf3: 'تين كهم نيه نهم ونه وها يهم ونا ونك وني وهم تكم تنا تها تني تهم كما كها ناه نكم هنا تان يها',
+ suf4: 'كموه ناها ونني ونهم تكما تموه تكاه كماه ناكم ناهم نيها وننا'
+ }
+
+ //arabic language patterns and alternative mapping for patterns
+ self.patterns = JSON.parse('{"pt43":[{"pt":[{"c":"ا","l":1}]},{"pt":[{"c":"ا,ت,ن,ي","l":0}],"mPt":[{"c":"ف","l":0,"m":1},{"c":"ع","l":1,"m":2},{"c":"ل","l":2,"m":3}]},{"pt":[{"c":"و","l":2}],"mPt":[{"c":"ف","l":0,"m":0},{"c":"ع","l":1,"m":1},{"c":"ل","l":2,"m":3}]},{"pt":[{"c":"ا","l":2}]},{"pt":[{"c":"ي","l":2}],"mPt":[{"c":"ف","l":0,"m":0},{"c":"ع","l":1,"m":1},{"c":"ا","l":2},{"c":"ل","l":3,"m":3}]},{"pt":[{"c":"م","l":0}]}],"pt53":[{"pt":[{"c":"ت","l":0},{"c":"ا","l":2}]},{"pt":[{"c":"ا,ن,ت,ي","l":0},{"c":"ت","l":2}],"mPt":[{"c":"ا","l":0},{"c":"ف","l":1,"m":1},{"c":"ت","l":2},{"c":"ع","l":3,"m":3},{"c":"ا","l":4},{"c":"ل","l":5,"m":4}]},{"pt":[{"c":"ا","l":0},{"c":"ا","l":2}],"mPt":[{"c":"ا","l":0},{"c":"ف","l":1,"m":1},{"c":"ع","l":2,"m":3},{"c":"ل","l":3,"m":4},{"c":"ا","l":4},{"c":"ل","l":5,"m":4}]},{"pt":[{"c":"ا","l":0},{"c":"ا","l":3}],"mPt":[{"c":"ف","l":0,"m":1},{"c":"ع","l":1,"m":2},{"c":"ل","l":2,"m":4}]},{"pt":[{"c":"ا","l":3},{"c":"ن","l":4}]},{"pt":[{"c":"ت","l":0},{"c":"ي","l":3}]},{"pt":[{"c":"م","l":0},{"c":"و","l":3}]},{"pt":[{"c":"ا","l":1},{"c":"و","l":3}]},{"pt":[{"c":"و","l":1},{"c":"ا","l":2}]},{"pt":[{"c":"م","l":0},{"c":"ا","l":3}]},{"pt":[{"c":"م","l":0},{"c":"ي","l":3}]},{"pt":[{"c":"ا","l":2},{"c":"ن","l":3}]},{"pt":[{"c":"م","l":0},{"c":"ن","l":1}],"mPt":[{"c":"ا","l":0},{"c":"ن","l":1},{"c":"ف","l":2,"m":2},{"c":"ع","l":3,"m":3},{"c":"ا","l":4},{"c":"ل","l":5,"m":4}]},{"pt":[{"c":"م","l":0},{"c":"ت","l":2}],"mPt":[{"c":"ا","l":0},{"c":"ف","l":1,"m":1},{"c":"ت","l":2},{"c":"ع","l":3,"m":3},{"c":"ا","l":4},{"c":"ل","l":5,"m":4}]},{"pt":[{"c":"م","l":0},{"c":"ا","l":2}]},{"pt":[{"c":"م","l":1},{"c":"ا","l":3}]},{"pt":[{"c":"ي,ت,ا,ن","l":0},{"c":"ت","l":1}],"mPt":[{"c":"ف","l":0,"m":2},{"c":"ع","l":1,"m":3},{"c":"ا","l":2},{"c":"ل","l":3,"m":4}]},{"pt":[{"c":"ت,ي,ا,ن","l":0},{"c":"ت","l":2}],"mPt":[{"c":"ا","l":0},{"c":"ف","l":1,"m":1},{"c":"ت","l":2},{"c":"ع","l":3,"m":3},{"c":"ا","l":4},{"c":"ل","l":5,"m":4}]},{"pt":[{"c":"ا","l":2},{"c":"ي","l":3}]},{"pt":[{"c":"ا,ي,ت,ن","l":0},{"c":"ن","l":1}],"mPt":[{"c":"ا","l":0},{"c":"ن","l":1},{"c":"ف","l":2,"m":2},{"c":"ع","l":3,"m":3},{"c":"ا","l":4},{"c":"ل","l":5,"m":4}]},{"pt":[{"c":"ا","l":3},{"c":"ء","l":4}]}],"pt63":[{"pt":[{"c":"ا","l":0},{"c":"ت","l":2},{"c":"ا","l":4}]},{"pt":[{"c":"ا,ت,ن,ي","l":0},{"c":"س","l":1},{"c":"ت","l":2}],"mPt":[{"c":"ا","l":0},{"c":"س","l":1},{"c":"ت","l":2},{"c":"ف","l":3,"m":3},{"c":"ع","l":4,"m":4},{"c":"ا","l":5},{"c":"ل","l":6,"m":5}]},{"pt":[{"c":"ا,ن,ت,ي","l":0},{"c":"و","l":3}]},{"pt":[{"c":"م","l":0},{"c":"س","l":1},{"c":"ت","l":2}],"mPt":[{"c":"ا","l":0},{"c":"س","l":1},{"c":"ت","l":2},{"c":"ف","l":3,"m":3},{"c":"ع","l":4,"m":4},{"c":"ا","l":5},{"c":"ل","l":6,"m":5}]},{"pt":[{"c":"ي","l":1},{"c":"ي","l":3},{"c":"ا","l":4},{"c":"ء","l":5}]},{"pt":[{"c":"ا","l":0},{"c":"ن","l":1},{"c":"ا","l":4}]}],"pt54":[{"pt":[{"c":"ت","l":0}]},{"pt":[{"c":"ا,ي,ت,ن","l":0}],"mPt":[{"c":"ا","l":0},{"c":"ف","l":1,"m":1},{"c":"ع","l":2,"m":2},{"c":"ل","l":3,"m":3},{"c":"ر","l":4,"m":4},{"c":"ا","l":5},{"c":"ر","l":6,"m":4}]},{"pt":[{"c":"م","l":0}],"mPt":[{"c":"ا","l":0},{"c":"ف","l":1,"m":1},{"c":"ع","l":2,"m":2},{"c":"ل","l":3,"m":3},{"c":"ر","l":4,"m":4},{"c":"ا","l":5},{"c":"ر","l":6,"m":4}]},{"pt":[{"c":"ا","l":2}]},{"pt":[{"c":"ا","l":0},{"c":"ن","l":2}]}],"pt64":[{"pt":[{"c":"ا","l":0},{"c":"ا","l":4}]},{"pt":[{"c":"م","l":0},{"c":"ت","l":1}]}],"pt73":[{"pt":[{"c":"ا","l":0},{"c":"س","l":1},{"c":"ت","l":2},{"c":"ا","l":5}]}],"pt75":[{"pt":[{"c":"ا","l":0},{"c":"ا","l":5}]}]}');
+
+ self.execArray = [
+ 'cleanWord',
+ 'removeDiacritics',
+ 'cleanAlef',
+ 'removeStopWords',
+ 'normalizeHamzaAndAlef',
+ 'removeStartWaw',
+ 'removePre432',
+ 'removeEndTaa',
+ 'wordCheck'
+ ];
+
+ self.stem = function() {
+ var counter = 0;
+ self.result = false;
+ self.preRemoved = false;
+ self.sufRemoved = false;
+ while (counter < self.execArray.length && self.result != true) {
+ self.result = self[self.execArray[counter]]();
+ counter++;
+ }
+ }
+
+ self.setCurrent = function(word) {
+ self.word = word;
+ }
+
+ self.getCurrent = function() {
+ return self.word
+ }
+
+ /*remove elongating character and test that the word does not contain non-arabic characters.
+ If the word contains special characters, don't stem. */
+ self.cleanWord = function() {
+ var wordCharacters = "\u0621-\u065b\u0671\u0640";
+ var testRegex = new RegExp("[^" + wordCharacters + "]");
+ self.word = self.word
+ .replace('\u0640', '');
+ if (testRegex.test(word)) {
+ return true;
+ }
+ return false;
+ }
+
+ self.removeDiacritics = function() {
+ var diacriticsRegex = new RegExp("[\u064b-\u065b]");
+ self.word = self.word.replace(/[\u064b-\u065b]/gi, '');
+ return false;
+ }
+
+ /*Replace all variations of alef (آأإٱى) to a plain alef (ا)*/
+ self.cleanAlef = function() {
+ var alefRegex = new RegExp("[\u0622\u0623\u0625\u0671\u0649]");
+ self.word = self.word.replace(alefRegex, "\u0627");
+ return false;
+ }
+
+ /* if the word is a stop word, don't stem*/
+ self.removeStopWords = function() {
+ var stopWords = '، اض امين اه اها اي ا اب اجل اجمع اخ اخذ اصبح اضحى اقبل اقل اكثر الا ام اما امامك امامك امسى اما ان انا انت انتم انتما انتن انت انشا انى او اوشك اولئك اولئكم اولاء اولالك اوه اي ايا اين اينما اي ان اي اف اذ اذا اذا اذما اذن الى اليكم اليكما اليكن اليك اليك الا اما ان انما اي اياك اياكم اياكما اياكن ايانا اياه اياها اياهم اياهما اياهن اياي ايه ان ا ابتدا اثر اجل احد اخرى اخلولق اذا اربعة ارتد استحال اطار اعادة اعلنت اف اكثر اكد الالاء الالى الا الاخيرة الان الاول الاولى التى التي الثاني الثانية الذاتي الذى الذي الذين السابق الف اللائي اللاتي اللتان اللتيا اللتين اللذان اللذين اللواتي الماضي المقبل الوقت الى اليوم اما امام امس ان انبرى انقلب انه انها او اول اي ايار ايام ايضا ب بات باسم بان بخ برس بسبب بس بشكل بضع بطان بعد بعض بك بكم بكما بكن بل بلى بما بماذا بمن بن بنا به بها بي بيد بين بس بله بئس تان تانك تبدل تجاه تحول تلقاء تلك تلكم تلكما تم تينك تين ته تي ثلاثة ثم ثم ثمة ثم جعل جلل جميع جير حار حاشا حاليا حاي حتى حرى حسب حم حوالى حول حيث حيثما حين حي حبذا حتى حذار خلا خلال دون دونك ذا ذات ذاك ذانك ذان ذلك ذلكم ذلكما ذلكن ذو ذوا ذواتا ذواتي ذيت ذينك ذين ذه ذي راح رجع رويدك ريث رب زيارة سبحان سرعان سنة سنوات سوف سوى ساء ساءما شبه شخصا شرع شتان صار صباح صفر صه صه ضد ضمن طاق طالما طفق طق ظل عاد عام عاما عامة عدا عدة عدد عدم عسى عشر عشرة علق على عليك عليه عليها عل عن عند عندما عوض عين عدس عما غدا غير ف فان فلان فو فى في فيم فيما فيه فيها قال قام قبل قد قط قلما قوة كانما كاين كاي كاين كاد كان كانت كذا كذلك كرب كل كلا كلاهما كلتا كلم كليكما كليهما كلما كلا كم كما كي كيت كيف كيفما كان كخ لئن لا لات لاسيما لدن لدى لعمر لقاء لك لكم لكما لكن لكنما لكي لكيلا للامم لم لما لما لن لنا له لها لو لوكالة لولا لوما لي لست لست لستم لستما لستن لست لسن لعل لكن ليت ليس ليسا ليستا ليست ليسوا لسنا ما ماانفك مابرح مادام ماذا مازال مافتئ مايو متى مثل مذ مساء مع معاذ مقابل مكانكم مكانكما مكانكن مكانك مليار مليون مما ممن من منذ منها مه مهما من من نحن نحو نعم نفس نفسه نهاية نخ نعما نعم ها هاؤم هاك هاهنا هب هذا هذه هكذا هل هلم هلا هم هما هن هنا هناك هنالك هو هي هيا هيت هيا هؤلاء هاتان هاتين هاته هاتي هج هذا هذان هذين هذه هذي هيهات و وا واحد واضاف واضافت واكد وان واها واوضح وراءك وفي وقال وقالت وقد وقف وكان وكانت ولا ولم ومن وهو وهي ويكان وي وشكان يكون يمكن يوم ايان'.split(' ');
+ if (stopWords.indexOf(self.word) >= 0) {
+ return true;
+ }
+ }
+
+ /* changes ؤ ئ to ء and removes alef if at the end of the word*/
+ self.normalizeHamzaAndAlef = function() {
+ self.word = self.word.replace('\u0624', '\u0621');
+ self.word = self.word.replace('\u0626', '\u0621');
+ self.word = self.word.replace(/([\u0627])\1+/gi, '\u0627');
+ return false;
+ }
+
+ /*remove end taa marboota ة*/
+ self.removeEndTaa = function() {
+ if (self.word.length > 2) {
+ self.word = self.word.replace(/[\u0627]$/, '');
+ self.word = self.word.replace('\u0629', '');
+ return false;
+ } else return true;
+ }
+
+ /* if the word starts with double waw وو keep only one of them */
+ self.removeStartWaw = function() {
+ if (self.word.length > 3 && self.word[0] == '\u0648' && self.word[1] == '\u0648') {
+ self.word = self.word.slice(1);
+ }
+ return false;
+ }
+
+ /* remove prefixes of size 4, 3 and 2 characters */
+ self.removePre432 = function() {
+ var word = self.word;
+ if (self.word.length >= 7) {
+ var pre4Regex = new RegExp('^(' + self.pre.pre4.split(' ').join('|') + ')')
+ self.word = self.word.replace(pre4Regex, '');
+ }
+ if (self.word == word && self.word.length >= 6) {
+ var pre3Regex = new RegExp('^(' + self.pre.pre3.split(' ').join('|') + ')')
+ self.word = self.word.replace(pre3Regex, '');
+ }
+ if (self.word == word && self.word.length >= 5) {
+ var pre2Regex = new RegExp('^(' + self.pre.pre2.split(' ').join('|') + ')')
+ self.word = self.word.replace(pre2Regex, '');
+ }
+ if (word != self.word) self.preRemoved = true;
+ return false;
+ }
+
+ /* check the word against word patterns. If the word matches a pattern, map it to the
+ alternative pattern if available then stop stemming. */
+ self.patternCheck = function(pattern) {
+ var patternMatch = false;
+ for (var i = 0; i < pattern.length; i++) {
+ var currentPatternCheck = true;
+ for (var j = 0; j < pattern[i].pt.length; j++) {
+ var chars = pattern[i].pt[j].c.split(',');
+ var charMatch = false;
+ chars.forEach(function(el) {
+ if (self.word[pattern[i].pt[j].l] == el) {
+ charMatch = true;
+ }
+ })
+ if (!charMatch) {
+ currentPatternCheck = false;
+ break;
+ }
+ }
+ if (currentPatternCheck == true) {
+ if (pattern[i].mPt) {
+ var newWord = [];
+ for (var k = 0; k < pattern[i].mPt.length; k++) {
+ if (pattern[i].mPt[k].m != null) {
+ newWord[pattern[i].mPt[k].l] = self.word[pattern[i].mPt[k].m]
+ } else {
+ newWord[pattern[i].mPt[k].l] = pattern[i].mPt[k].c
+ }
+ }
+ self.word = newWord.join('');
+ }
+ self.result = true;
+ break;
+ }
+ }
+ }
+
+ /* remove prefixes of size 1 char*/
+ self.removePre1 = function() {
+ var word = self.word;
+ if (self.preRemoved == false)
+ if (self.word.length > 3) {
+ var pre1Regex = new RegExp('^(' + self.pre.pre1.split(' ').join('|') + ')')
+ self.word = self.word.replace(pre1Regex, '');
+ }
+ if (word != self.word) self.preRemoved = true;
+ return false;
+ }
+
+ /*remove suffixes of size 1 char */
+ self.removeSuf1 = function() {
+ var word = self.word;
+ if (self.sufRemoved == false)
+ if (self.word.length > 3) {
+ var suf1Regex = new RegExp('(' + self.suf.suf1.split(' ').join('|') + ')$')
+ self.word = self.word.replace(suf1Regex, '');
+ }
+ if (word != self.word) self.sufRemoved = true;
+ return false;
+ }
+
+ /*remove suffixes of size 4, 3 and 2 chars*/
+ self.removeSuf432 = function() {
+ var word = self.word;
+ if (self.word.length >= 6) {
+ var suf4Regex = new RegExp('(' + self.suf.suf4.split(' ').join('|') + ')$')
+ self.word = self.word.replace(suf4Regex, '');
+ }
+ if (self.word == word && self.word.length >= 5) {
+ var suf3Regex = new RegExp('(' + self.suf.suf3.split(' ').join('|') + ')$')
+ self.word = self.word.replace(suf3Regex, '');
+ }
+ if (self.word == word && self.word.length >= 4) {
+ var suf2Regex = new RegExp('(' + self.suf.suf2.split(' ').join('|') + ')$')
+ self.word = self.word.replace(suf2Regex, '');
+ }
+ if (word != self.word) self.sufRemoved = true;
+ return false;
+ }
+
+ /*check the word length and decide what is the next step accordingly*/
+ self.wordCheck = function() {
+ var word = self.word;
+ var word7Exec = [self.removeSuf432, self.removeSuf1, self.removePre1]
+ var counter = 0;
+ var patternChecked = false;
+ while (self.word.length >= 7 && !self.result && counter < word7Exec.length) {
+ if (self.word.length == 7 && !patternChecked) {
+ self.checkPattern73();
+ patternChecked = true;
+ } else {
+ word7Exec[counter]();
+ counter++;
+ patternChecked = false;
+ }
+ }
+
+ var word6Exec = [self.checkPattern63, self.removeSuf432, self.removeSuf1, self.removePre1, self.checkPattern64];
+ counter = 0;
+ while (self.word.length == 6 && !self.result && counter < word6Exec.length) {
+ word6Exec[counter]();
+ counter++;
+ }
+
+ var word5Exec = [self.checkPattern53, self.removeSuf432, self.removeSuf1, self.removePre1, self.checkPattern54];
+ counter = 0;
+ while (self.word.length == 5 && !self.result && counter < word5Exec.length) {
+ word5Exec[counter]();
+ counter++;
+ }
+
+ var word4Exec = [self.checkPattern43, self.removeSuf1, self.removePre1, self.removeSuf432];
+ counter = 0;
+ while (self.word.length == 4 && !self.result && counter < word4Exec.length) {
+ word4Exec[counter]();
+ counter++;
+ }
+ return true;
+ }
+
+ self.checkPattern43 = function() {
+ self.patternCheck(self.patterns.pt43)
+ }
+ self.checkPattern53 = function() {
+ self.patternCheck(self.patterns.pt53)
+ }
+ self.checkPattern54 = function() {
+ self.patternCheck(self.patterns.pt54)
+ }
+ self.checkPattern63 = function() {
+ self.patternCheck(self.patterns.pt63)
+ }
+ self.checkPattern64 = function() {
+ self.patternCheck(self.patterns.pt64)
+ }
+ self.checkPattern73 = function() {
+ self.patternCheck(self.patterns.pt73)
+ }
+
+ /* and return a function that stems a word for the current locale */
+ return function(token) {
+ // for lunr version 2
+ if (typeof token.update === "function") {
+ return token.update(function(word) {
+ self.setCurrent(word);
+ self.stem();
+ return self.getCurrent();
+ })
+ } else { // for lunr version <= 1
+ self.setCurrent(token);
+ self.stem();
+ return self.getCurrent();
+ }
+
+ }
+ })();
+
+ lunr.Pipeline.registerFunction(lunr.ar.stemmer, 'stemmer-ar');
+
+ lunr.ar.stopWordFilter = lunr.generateStopWordFilter('، اض امين اه اها اي ا اب اجل اجمع اخ اخذ اصبح اضحى اقبل اقل اكثر الا ام اما امامك امامك امسى اما ان انا انت انتم انتما انتن انت انشا انى او اوشك اولئك اولئكم اولاء اولالك اوه اي ايا اين اينما اي ان اي اف اذ اذا اذا اذما اذن الى اليكم اليكما اليكن اليك اليك الا اما ان انما اي اياك اياكم اياكما اياكن ايانا اياه اياها اياهم اياهما اياهن اياي ايه ان ا ابتدا اثر اجل احد اخرى اخلولق اذا اربعة ارتد استحال اطار اعادة اعلنت اف اكثر اكد الالاء الالى الا الاخيرة الان الاول الاولى التى التي الثاني الثانية الذاتي الذى الذي الذين السابق الف اللائي اللاتي اللتان اللتيا اللتين اللذان اللذين اللواتي الماضي المقبل الوقت الى اليوم اما امام امس ان انبرى انقلب انه انها او اول اي ايار ايام ايضا ب بات باسم بان بخ برس بسبب بس بشكل بضع بطان بعد بعض بك بكم بكما بكن بل بلى بما بماذا بمن بن بنا به بها بي بيد بين بس بله بئس تان تانك تبدل تجاه تحول تلقاء تلك تلكم تلكما تم تينك تين ته تي ثلاثة ثم ثم ثمة ثم جعل جلل جميع جير حار حاشا حاليا حاي حتى حرى حسب حم حوالى حول حيث حيثما حين حي حبذا حتى حذار خلا خلال دون دونك ذا ذات ذاك ذانك ذان ذلك ذلكم ذلكما ذلكن ذو ذوا ذواتا ذواتي ذيت ذينك ذين ذه ذي راح رجع رويدك ريث رب زيارة سبحان سرعان سنة سنوات سوف سوى ساء ساءما شبه شخصا شرع شتان صار صباح صفر صه صه ضد ضمن طاق طالما طفق طق ظل عاد عام عاما عامة عدا عدة عدد عدم عسى عشر عشرة علق على عليك عليه عليها عل عن عند عندما عوض عين عدس عما غدا غير ف فان فلان فو فى في فيم فيما فيه فيها قال قام قبل قد قط قلما قوة كانما كاين كاي كاين كاد كان كانت كذا كذلك كرب كل كلا كلاهما كلتا كلم كليكما كليهما كلما كلا كم كما كي كيت كيف كيفما كان كخ لئن لا لات لاسيما لدن لدى لعمر لقاء لك لكم لكما لكن لكنما لكي لكيلا للامم لم لما لما لن لنا له لها لو لوكالة لولا لوما لي لست لست لستم لستما لستن لست لسن لعل لكن ليت ليس ليسا ليستا ليست ليسوا لسنا ما ماانفك مابرح مادام ماذا مازال مافتئ مايو متى مثل مذ مساء مع معاذ مقابل مكانكم مكانكما مكانكن مكانك مليار مليون مما ممن من منذ منها مه مهما من من نحن نحو نعم نفس نفسه نهاية نخ نعما نعم ها هاؤم هاك هاهنا هب هذا هذه هكذا هل هلم هلا هم هما هن هنا هناك هنالك هو هي هيا هيت هيا هؤلاء هاتان هاتين هاته هاتي هج هذا هذان هذين هذه هذي هيهات وا واحد واضاف واضافت واكد وان واها واوضح وراءك وفي وقال وقالت وقد وقف وكان وكانت ولا ولم ومن وهو وهي ويكان وي وشكان يكون يمكن يوم ايان'.split(' '));
+
+ lunr.Pipeline.registerFunction(lunr.ar.stopWordFilter, 'stopWordFilter-ar');
+ };
+}))
\ No newline at end of file
diff --git a/venv/lib/python3.11/site-packages/mkdocs/contrib/search/lunr-language/lunr.da.js b/venv/lib/python3.11/site-packages/mkdocs/contrib/search/lunr-language/lunr.da.js
new file mode 100644
index 0000000..28b5c2d
--- /dev/null
+++ b/venv/lib/python3.11/site-packages/mkdocs/contrib/search/lunr-language/lunr.da.js
@@ -0,0 +1,284 @@
+/*!
+ * Lunr languages, `Danish` language
+ * https://github.com/MihaiValentin/lunr-languages
+ *
+ * Copyright 2014, Mihai Valentin
+ * http://www.mozilla.org/MPL/
+ */
+/*!
+ * based on
+ * Snowball JavaScript Library v0.3
+ * http://code.google.com/p/urim/
+ * http://snowball.tartarus.org/
+ *
+ * Copyright 2010, Oleg Mazko
+ * http://www.mozilla.org/MPL/
+ */
+
+/**
+ * export the module via AMD, CommonJS or as a browser global
+ * Export code from https://github.com/umdjs/umd/blob/master/returnExports.js
+ */
+;
+(function(root, factory) {
+ if (typeof define === 'function' && define.amd) {
+ // AMD. Register as an anonymous module.
+ define(factory)
+ } else if (typeof exports === 'object') {
+ /**
+ * Node. Does not work with strict CommonJS, but
+ * only CommonJS-like environments that support module.exports,
+ * like Node.
+ */
+ module.exports = factory()
+ } else {
+ // Browser globals (root is window)
+ factory()(root.lunr);
+ }
+}(this, function() {
+ /**
+ * Just return a value to define the module export.
+ * This example returns an object, but the module
+ * can return a function as the exported value.
+ */
+ return function(lunr) {
+ /* throw error if lunr is not yet included */
+ if ('undefined' === typeof lunr) {
+ throw new Error('Lunr is not present. Please include / require Lunr before this script.');
+ }
+
+ /* throw error if lunr stemmer support is not yet included */
+ if ('undefined' === typeof lunr.stemmerSupport) {
+ throw new Error('Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.');
+ }
+
+ /* register specific locale function */
+ lunr.da = function() {
+ this.pipeline.reset();
+ this.pipeline.add(
+ lunr.da.trimmer,
+ lunr.da.stopWordFilter,
+ lunr.da.stemmer
+ );
+
+ // for lunr version 2
+ // this is necessary so that every searched word is also stemmed before
+ // in lunr <= 1 this is not needed, as it is done using the normal pipeline
+ if (this.searchPipeline) {
+ this.searchPipeline.reset();
+ this.searchPipeline.add(lunr.da.stemmer)
+ }
+ };
+
+ /* lunr trimmer function */
+ lunr.da.wordCharacters = "A-Za-z\xAA\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02B8\u02E0-\u02E4\u1D00-\u1D25\u1D2C-\u1D5C\u1D62-\u1D65\u1D6B-\u1D77\u1D79-\u1DBE\u1E00-\u1EFF\u2071\u207F\u2090-\u209C\u212A\u212B\u2132\u214E\u2160-\u2188\u2C60-\u2C7F\uA722-\uA787\uA78B-\uA7AD\uA7B0-\uA7B7\uA7F7-\uA7FF\uAB30-\uAB5A\uAB5C-\uAB64\uFB00-\uFB06\uFF21-\uFF3A\uFF41-\uFF5A";
+ lunr.da.trimmer = lunr.trimmerSupport.generateTrimmer(lunr.da.wordCharacters);
+
+ lunr.Pipeline.registerFunction(lunr.da.trimmer, 'trimmer-da');
+
+ /* lunr stemmer function */
+ lunr.da.stemmer = (function() {
+ /* create the wrapped stemmer object */
+ var Among = lunr.stemmerSupport.Among,
+ SnowballProgram = lunr.stemmerSupport.SnowballProgram,
+ st = new function DanishStemmer() {
+ var a_0 = [new Among("hed", -1, 1), new Among("ethed", 0, 1),
+ new Among("ered", -1, 1), new Among("e", -1, 1),
+ new Among("erede", 3, 1), new Among("ende", 3, 1),
+ new Among("erende", 5, 1), new Among("ene", 3, 1),
+ new Among("erne", 3, 1), new Among("ere", 3, 1),
+ new Among("en", -1, 1), new Among("heden", 10, 1),
+ new Among("eren", 10, 1), new Among("er", -1, 1),
+ new Among("heder", 13, 1), new Among("erer", 13, 1),
+ new Among("s", -1, 2), new Among("heds", 16, 1),
+ new Among("es", 16, 1), new Among("endes", 18, 1),
+ new Among("erendes", 19, 1), new Among("enes", 18, 1),
+ new Among("ernes", 18, 1), new Among("eres", 18, 1),
+ new Among("ens", 16, 1), new Among("hedens", 24, 1),
+ new Among("erens", 24, 1), new Among("ers", 16, 1),
+ new Among("ets", 16, 1), new Among("erets", 28, 1),
+ new Among("et", -1, 1), new Among("eret", 30, 1)
+ ],
+ a_1 = [
+ new Among("gd", -1, -1), new Among("dt", -1, -1),
+ new Among("gt", -1, -1), new Among("kt", -1, -1)
+ ],
+ a_2 = [
+ new Among("ig", -1, 1), new Among("lig", 0, 1),
+ new Among("elig", 1, 1), new Among("els", -1, 1),
+ new Among("l\u00F8st", -1, 2)
+ ],
+ g_v = [17, 65, 16, 1, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 48, 0, 128
+ ],
+ g_s_ending = [239, 254, 42, 3,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16
+ ],
+ I_x, I_p1, S_ch, sbp = new SnowballProgram();
+ this.setCurrent = function(word) {
+ sbp.setCurrent(word);
+ };
+ this.getCurrent = function() {
+ return sbp.getCurrent();
+ };
+
+ function r_mark_regions() {
+ var v_1, c = sbp.cursor + 3;
+ I_p1 = sbp.limit;
+ if (0 <= c && c <= sbp.limit) {
+ I_x = c;
+ while (true) {
+ v_1 = sbp.cursor;
+ if (sbp.in_grouping(g_v, 97, 248)) {
+ sbp.cursor = v_1;
+ break;
+ }
+ sbp.cursor = v_1;
+ if (v_1 >= sbp.limit)
+ return;
+ sbp.cursor++;
+ }
+ while (!sbp.out_grouping(g_v, 97, 248)) {
+ if (sbp.cursor >= sbp.limit)
+ return;
+ sbp.cursor++;
+ }
+ I_p1 = sbp.cursor;
+ if (I_p1 < I_x)
+ I_p1 = I_x;
+ }
+ }
+
+ function r_main_suffix() {
+ var among_var, v_1;
+ if (sbp.cursor >= I_p1) {
+ v_1 = sbp.limit_backward;
+ sbp.limit_backward = I_p1;
+ sbp.ket = sbp.cursor;
+ among_var = sbp.find_among_b(a_0, 32);
+ sbp.limit_backward = v_1;
+ if (among_var) {
+ sbp.bra = sbp.cursor;
+ switch (among_var) {
+ case 1:
+ sbp.slice_del();
+ break;
+ case 2:
+ if (sbp.in_grouping_b(g_s_ending, 97, 229))
+ sbp.slice_del();
+ break;
+ }
+ }
+ }
+ }
+
+ function r_consonant_pair() {
+ var v_1 = sbp.limit - sbp.cursor,
+ v_2;
+ if (sbp.cursor >= I_p1) {
+ v_2 = sbp.limit_backward;
+ sbp.limit_backward = I_p1;
+ sbp.ket = sbp.cursor;
+ if (sbp.find_among_b(a_1, 4)) {
+ sbp.bra = sbp.cursor;
+ sbp.limit_backward = v_2;
+ sbp.cursor = sbp.limit - v_1;
+ if (sbp.cursor > sbp.limit_backward) {
+ sbp.cursor--;
+ sbp.bra = sbp.cursor;
+ sbp.slice_del();
+ }
+ } else
+ sbp.limit_backward = v_2;
+ }
+ }
+
+ function r_other_suffix() {
+ var among_var, v_1 = sbp.limit - sbp.cursor,
+ v_2, v_3;
+ sbp.ket = sbp.cursor;
+ if (sbp.eq_s_b(2, "st")) {
+ sbp.bra = sbp.cursor;
+ if (sbp.eq_s_b(2, "ig"))
+ sbp.slice_del();
+ }
+ sbp.cursor = sbp.limit - v_1;
+ if (sbp.cursor >= I_p1) {
+ v_2 = sbp.limit_backward;
+ sbp.limit_backward = I_p1;
+ sbp.ket = sbp.cursor;
+ among_var = sbp.find_among_b(a_2, 5);
+ sbp.limit_backward = v_2;
+ if (among_var) {
+ sbp.bra = sbp.cursor;
+ switch (among_var) {
+ case 1:
+ sbp.slice_del();
+ v_3 = sbp.limit - sbp.cursor;
+ r_consonant_pair();
+ sbp.cursor = sbp.limit - v_3;
+ break;
+ case 2:
+ sbp.slice_from("l\u00F8s");
+ break;
+ }
+ }
+ }
+ }
+
+ function r_undouble() {
+ var v_1;
+ if (sbp.cursor >= I_p1) {
+ v_1 = sbp.limit_backward;
+ sbp.limit_backward = I_p1;
+ sbp.ket = sbp.cursor;
+ if (sbp.out_grouping_b(g_v, 97, 248)) {
+ sbp.bra = sbp.cursor;
+ S_ch = sbp.slice_to(S_ch);
+ sbp.limit_backward = v_1;
+ if (sbp.eq_v_b(S_ch))
+ sbp.slice_del();
+ } else
+ sbp.limit_backward = v_1;
+ }
+ }
+ this.stem = function() {
+ var v_1 = sbp.cursor;
+ r_mark_regions();
+ sbp.limit_backward = v_1;
+ sbp.cursor = sbp.limit;
+ r_main_suffix();
+ sbp.cursor = sbp.limit;
+ r_consonant_pair();
+ sbp.cursor = sbp.limit;
+ r_other_suffix();
+ sbp.cursor = sbp.limit;
+ r_undouble();
+ return true;
+ }
+ };
+
+ /* and return a function that stems a word for the current locale */
+ return function(token) {
+ // for lunr version 2
+ if (typeof token.update === "function") {
+ return token.update(function(word) {
+ st.setCurrent(word);
+ st.stem();
+ return st.getCurrent();
+ })
+ } else { // for lunr version <= 1
+ st.setCurrent(token);
+ st.stem();
+ return st.getCurrent();
+ }
+ }
+ })();
+
+ lunr.Pipeline.registerFunction(lunr.da.stemmer, 'stemmer-da');
+
+ lunr.da.stopWordFilter = lunr.generateStopWordFilter('ad af alle alt anden at blev blive bliver da de dem den denne der deres det dette dig din disse dog du efter eller en end er et for fra ham han hans har havde have hende hendes her hos hun hvad hvis hvor i ikke ind jeg jer jo kunne man mange med meget men mig min mine mit mod ned noget nogle nu når og også om op os over på selv sig sin sine sit skal skulle som sådan thi til ud under var vi vil ville vor være været'.split(' '));
+
+ lunr.Pipeline.registerFunction(lunr.da.stopWordFilter, 'stopWordFilter-da');
+ };
+}))
\ No newline at end of file
diff --git a/venv/lib/python3.11/site-packages/mkdocs/contrib/search/lunr-language/lunr.de.js b/venv/lib/python3.11/site-packages/mkdocs/contrib/search/lunr-language/lunr.de.js
new file mode 100644
index 0000000..9e32b0c
--- /dev/null
+++ b/venv/lib/python3.11/site-packages/mkdocs/contrib/search/lunr-language/lunr.de.js
@@ -0,0 +1,384 @@
+/*!
+ * Lunr languages, `German` language
+ * https://github.com/MihaiValentin/lunr-languages
+ *
+ * Copyright 2014, Mihai Valentin
+ * http://www.mozilla.org/MPL/
+ */
+/*!
+ * based on
+ * Snowball JavaScript Library v0.3
+ * http://code.google.com/p/urim/
+ * http://snowball.tartarus.org/
+ *
+ * Copyright 2010, Oleg Mazko
+ * http://www.mozilla.org/MPL/
+ */
+
+/**
+ * export the module via AMD, CommonJS or as a browser global
+ * Export code from https://github.com/umdjs/umd/blob/master/returnExports.js
+ */
+;
+(function(root, factory) {
+ if (typeof define === 'function' && define.amd) {
+ // AMD. Register as an anonymous module.
+ define(factory)
+ } else if (typeof exports === 'object') {
+ /**
+ * Node. Does not work with strict CommonJS, but
+ * only CommonJS-like environments that support module.exports,
+ * like Node.
+ */
+ module.exports = factory()
+ } else {
+ // Browser globals (root is window)
+ factory()(root.lunr);
+ }
+}(this, function() {
+ /**
+ * Just return a value to define the module export.
+ * This example returns an object, but the module
+ * can return a function as the exported value.
+ */
+ return function(lunr) {
+ /* throw error if lunr is not yet included */
+ if ('undefined' === typeof lunr) {
+ throw new Error('Lunr is not present. Please include / require Lunr before this script.');
+ }
+
+ /* throw error if lunr stemmer support is not yet included */
+ if ('undefined' === typeof lunr.stemmerSupport) {
+ throw new Error('Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.');
+ }
+
+ /* register specific locale function */
+ lunr.de = function() {
+ this.pipeline.reset();
+ this.pipeline.add(
+ lunr.de.trimmer,
+ lunr.de.stopWordFilter,
+ lunr.de.stemmer
+ );
+
+ // for lunr version 2
+ // this is necessary so that every searched word is also stemmed before
+ // in lunr <= 1 this is not needed, as it is done using the normal pipeline
+ if (this.searchPipeline) {
+ this.searchPipeline.reset();
+ this.searchPipeline.add(lunr.de.stemmer)
+ }
+ };
+
+ /* lunr trimmer function */
+ lunr.de.wordCharacters = "A-Za-z\xAA\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02B8\u02E0-\u02E4\u1D00-\u1D25\u1D2C-\u1D5C\u1D62-\u1D65\u1D6B-\u1D77\u1D79-\u1DBE\u1E00-\u1EFF\u2071\u207F\u2090-\u209C\u212A\u212B\u2132\u214E\u2160-\u2188\u2C60-\u2C7F\uA722-\uA787\uA78B-\uA7AD\uA7B0-\uA7B7\uA7F7-\uA7FF\uAB30-\uAB5A\uAB5C-\uAB64\uFB00-\uFB06\uFF21-\uFF3A\uFF41-\uFF5A";
+ lunr.de.trimmer = lunr.trimmerSupport.generateTrimmer(lunr.de.wordCharacters);
+
+ lunr.Pipeline.registerFunction(lunr.de.trimmer, 'trimmer-de');
+
+ /* lunr stemmer function */
+ lunr.de.stemmer = (function() {
+ /* create the wrapped stemmer object */
+ var Among = lunr.stemmerSupport.Among,
+ SnowballProgram = lunr.stemmerSupport.SnowballProgram,
+ st = new function GermanStemmer() {
+ var a_0 = [new Among("", -1, 6), new Among("U", 0, 2),
+ new Among("Y", 0, 1), new Among("\u00E4", 0, 3),
+ new Among("\u00F6", 0, 4), new Among("\u00FC", 0, 5)
+ ],
+ a_1 = [
+ new Among("e", -1, 2), new Among("em", -1, 1),
+ new Among("en", -1, 2), new Among("ern", -1, 1),
+ new Among("er", -1, 1), new Among("s", -1, 3),
+ new Among("es", 5, 2)
+ ],
+ a_2 = [new Among("en", -1, 1),
+ new Among("er", -1, 1), new Among("st", -1, 2),
+ new Among("est", 2, 1)
+ ],
+ a_3 = [new Among("ig", -1, 1),
+ new Among("lich", -1, 1)
+ ],
+ a_4 = [new Among("end", -1, 1),
+ new Among("ig", -1, 2), new Among("ung", -1, 1),
+ new Among("lich", -1, 3), new Among("isch", -1, 2),
+ new Among("ik", -1, 2), new Among("heit", -1, 3),
+ new Among("keit", -1, 4)
+ ],
+ g_v = [17, 65, 16, 1, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 8, 0, 32, 8
+ ],
+ g_s_ending = [117, 30, 5],
+ g_st_ending = [
+ 117, 30, 4
+ ],
+ I_x, I_p2, I_p1, sbp = new SnowballProgram();
+ this.setCurrent = function(word) {
+ sbp.setCurrent(word);
+ };
+ this.getCurrent = function() {
+ return sbp.getCurrent();
+ };
+
+ function habr1(c1, c2, v_1) {
+ if (sbp.eq_s(1, c1)) {
+ sbp.ket = sbp.cursor;
+ if (sbp.in_grouping(g_v, 97, 252)) {
+ sbp.slice_from(c2);
+ sbp.cursor = v_1;
+ return true;
+ }
+ }
+ return false;
+ }
+
+ function r_prelude() {
+ var v_1 = sbp.cursor,
+ v_2, v_3, v_4, v_5;
+ while (true) {
+ v_2 = sbp.cursor;
+ sbp.bra = v_2;
+ if (sbp.eq_s(1, "\u00DF")) {
+ sbp.ket = sbp.cursor;
+ sbp.slice_from("ss");
+ } else {
+ if (v_2 >= sbp.limit)
+ break;
+ sbp.cursor = v_2 + 1;
+ }
+ }
+ sbp.cursor = v_1;
+ while (true) {
+ v_3 = sbp.cursor;
+ while (true) {
+ v_4 = sbp.cursor;
+ if (sbp.in_grouping(g_v, 97, 252)) {
+ v_5 = sbp.cursor;
+ sbp.bra = v_5;
+ if (habr1("u", "U", v_4))
+ break;
+ sbp.cursor = v_5;
+ if (habr1("y", "Y", v_4))
+ break;
+ }
+ if (v_4 >= sbp.limit) {
+ sbp.cursor = v_3;
+ return;
+ }
+ sbp.cursor = v_4 + 1;
+ }
+ }
+ }
+
+ function habr2() {
+ while (!sbp.in_grouping(g_v, 97, 252)) {
+ if (sbp.cursor >= sbp.limit)
+ return true;
+ sbp.cursor++;
+ }
+ while (!sbp.out_grouping(g_v, 97, 252)) {
+ if (sbp.cursor >= sbp.limit)
+ return true;
+ sbp.cursor++;
+ }
+ return false;
+ }
+
+ function r_mark_regions() {
+ I_p1 = sbp.limit;
+ I_p2 = I_p1;
+ var c = sbp.cursor + 3;
+ if (0 <= c && c <= sbp.limit) {
+ I_x = c;
+ if (!habr2()) {
+ I_p1 = sbp.cursor;
+ if (I_p1 < I_x)
+ I_p1 = I_x;
+ if (!habr2())
+ I_p2 = sbp.cursor;
+ }
+ }
+ }
+
+ function r_postlude() {
+ var among_var, v_1;
+ while (true) {
+ v_1 = sbp.cursor;
+ sbp.bra = v_1;
+ among_var = sbp.find_among(a_0, 6);
+ if (!among_var)
+ return;
+ sbp.ket = sbp.cursor;
+ switch (among_var) {
+ case 1:
+ sbp.slice_from("y");
+ break;
+ case 2:
+ case 5:
+ sbp.slice_from("u");
+ break;
+ case 3:
+ sbp.slice_from("a");
+ break;
+ case 4:
+ sbp.slice_from("o");
+ break;
+ case 6:
+ if (sbp.cursor >= sbp.limit)
+ return;
+ sbp.cursor++;
+ break;
+ }
+ }
+ }
+
+ function r_R1() {
+ return I_p1 <= sbp.cursor;
+ }
+
+ function r_R2() {
+ return I_p2 <= sbp.cursor;
+ }
+
+ function r_standard_suffix() {
+ var among_var, v_1 = sbp.limit - sbp.cursor,
+ v_2, v_3, v_4;
+ sbp.ket = sbp.cursor;
+ among_var = sbp.find_among_b(a_1, 7);
+ if (among_var) {
+ sbp.bra = sbp.cursor;
+ if (r_R1()) {
+ switch (among_var) {
+ case 1:
+ sbp.slice_del();
+ break;
+ case 2:
+ sbp.slice_del();
+ sbp.ket = sbp.cursor;
+ if (sbp.eq_s_b(1, "s")) {
+ sbp.bra = sbp.cursor;
+ if (sbp.eq_s_b(3, "nis"))
+ sbp.slice_del();
+ }
+ break;
+ case 3:
+ if (sbp.in_grouping_b(g_s_ending, 98, 116))
+ sbp.slice_del();
+ break;
+ }
+ }
+ }
+ sbp.cursor = sbp.limit - v_1;
+ sbp.ket = sbp.cursor;
+ among_var = sbp.find_among_b(a_2, 4);
+ if (among_var) {
+ sbp.bra = sbp.cursor;
+ if (r_R1()) {
+ switch (among_var) {
+ case 1:
+ sbp.slice_del();
+ break;
+ case 2:
+ if (sbp.in_grouping_b(g_st_ending, 98, 116)) {
+ var c = sbp.cursor - 3;
+ if (sbp.limit_backward <= c && c <= sbp.limit) {
+ sbp.cursor = c;
+ sbp.slice_del();
+ }
+ }
+ break;
+ }
+ }
+ }
+ sbp.cursor = sbp.limit - v_1;
+ sbp.ket = sbp.cursor;
+ among_var = sbp.find_among_b(a_4, 8);
+ if (among_var) {
+ sbp.bra = sbp.cursor;
+ if (r_R2()) {
+ switch (among_var) {
+ case 1:
+ sbp.slice_del();
+ sbp.ket = sbp.cursor;
+ if (sbp.eq_s_b(2, "ig")) {
+ sbp.bra = sbp.cursor;
+ v_2 = sbp.limit - sbp.cursor;
+ if (!sbp.eq_s_b(1, "e")) {
+ sbp.cursor = sbp.limit - v_2;
+ if (r_R2())
+ sbp.slice_del();
+ }
+ }
+ break;
+ case 2:
+ v_3 = sbp.limit - sbp.cursor;
+ if (!sbp.eq_s_b(1, "e")) {
+ sbp.cursor = sbp.limit - v_3;
+ sbp.slice_del();
+ }
+ break;
+ case 3:
+ sbp.slice_del();
+ sbp.ket = sbp.cursor;
+ v_4 = sbp.limit - sbp.cursor;
+ if (!sbp.eq_s_b(2, "er")) {
+ sbp.cursor = sbp.limit - v_4;
+ if (!sbp.eq_s_b(2, "en"))
+ break;
+ }
+ sbp.bra = sbp.cursor;
+ if (r_R1())
+ sbp.slice_del();
+ break;
+ case 4:
+ sbp.slice_del();
+ sbp.ket = sbp.cursor;
+ among_var = sbp.find_among_b(a_3, 2);
+ if (among_var) {
+ sbp.bra = sbp.cursor;
+ if (r_R2() && among_var == 1)
+ sbp.slice_del();
+ }
+ break;
+ }
+ }
+ }
+ }
+ this.stem = function() {
+ var v_1 = sbp.cursor;
+ r_prelude();
+ sbp.cursor = v_1;
+ r_mark_regions();
+ sbp.limit_backward = v_1;
+ sbp.cursor = sbp.limit;
+ r_standard_suffix();
+ sbp.cursor = sbp.limit_backward;
+ r_postlude();
+ return true;
+ }
+ };
+
+ /* and return a function that stems a word for the current locale */
+ return function(token) {
+ // for lunr version 2
+ if (typeof token.update === "function") {
+ return token.update(function(word) {
+ st.setCurrent(word);
+ st.stem();
+ return st.getCurrent();
+ })
+ } else { // for lunr version <= 1
+ st.setCurrent(token);
+ st.stem();
+ return st.getCurrent();
+ }
+ }
+ })();
+
+ lunr.Pipeline.registerFunction(lunr.de.stemmer, 'stemmer-de');
+
+ lunr.de.stopWordFilter = lunr.generateStopWordFilter('aber alle allem allen aller alles als also am an ander andere anderem anderen anderer anderes anderm andern anderr anders auch auf aus bei bin bis bist da damit dann das dasselbe dazu daß dein deine deinem deinen deiner deines dem demselben den denn denselben der derer derselbe derselben des desselben dessen dich die dies diese dieselbe dieselben diesem diesen dieser dieses dir doch dort du durch ein eine einem einen einer eines einig einige einigem einigen einiger einiges einmal er es etwas euch euer eure eurem euren eurer eures für gegen gewesen hab habe haben hat hatte hatten hier hin hinter ich ihm ihn ihnen ihr ihre ihrem ihren ihrer ihres im in indem ins ist jede jedem jeden jeder jedes jene jenem jenen jener jenes jetzt kann kein keine keinem keinen keiner keines können könnte machen man manche manchem manchen mancher manches mein meine meinem meinen meiner meines mich mir mit muss musste nach nicht nichts noch nun nur ob oder ohne sehr sein seine seinem seinen seiner seines selbst sich sie sind so solche solchem solchen solcher solches soll sollte sondern sonst um und uns unse unsem unsen unser unses unter viel vom von vor war waren warst was weg weil weiter welche welchem welchen welcher welches wenn werde werden wie wieder will wir wird wirst wo wollen wollte während würde würden zu zum zur zwar zwischen über'.split(' '));
+
+ lunr.Pipeline.registerFunction(lunr.de.stopWordFilter, 'stopWordFilter-de');
+ };
+}))
\ No newline at end of file
diff --git a/venv/lib/python3.11/site-packages/mkdocs/contrib/search/lunr-language/lunr.du.js b/venv/lib/python3.11/site-packages/mkdocs/contrib/search/lunr-language/lunr.du.js
new file mode 100644
index 0000000..18edeb8
--- /dev/null
+++ b/venv/lib/python3.11/site-packages/mkdocs/contrib/search/lunr-language/lunr.du.js
@@ -0,0 +1,450 @@
+/*!
+ * Lunr languages, `Dutch` language
+ * https://github.com/MihaiValentin/lunr-languages
+ *
+ * Copyright 2014, Mihai Valentin
+ * http://www.mozilla.org/MPL/
+ */
+/*!
+ * based on
+ * Snowball JavaScript Library v0.3
+ * http://code.google.com/p/urim/
+ * http://snowball.tartarus.org/
+ *
+ * Copyright 2010, Oleg Mazko
+ * http://www.mozilla.org/MPL/
+ */
+
+/**
+ * export the module via AMD, CommonJS or as a browser global
+ * Export code from https://github.com/umdjs/umd/blob/master/returnExports.js
+ */
+;
+(function(root, factory) {
+ if (typeof define === 'function' && define.amd) {
+ // AMD. Register as an anonymous module.
+ define(factory)
+ } else if (typeof exports === 'object') {
+ /**
+ * Node. Does not work with strict CommonJS, but
+ * only CommonJS-like environments that support module.exports,
+ * like Node.
+ */
+ module.exports = factory()
+ } else {
+ // Browser globals (root is window)
+ factory()(root.lunr);
+ }
+}(this, function() {
+ /**
+ * Just return a value to define the module export.
+ * This example returns an object, but the module
+ * can return a function as the exported value.
+ */
+ return function(lunr) {
+ /* throw error if lunr is not yet included */
+ if ('undefined' === typeof lunr) {
+ throw new Error('Lunr is not present. Please include / require Lunr before this script.');
+ }
+
+ /* throw error if lunr stemmer support is not yet included */
+ if ('undefined' === typeof lunr.stemmerSupport) {
+ throw new Error('Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.');
+ }
+
+ console.warn("[Lunr Languages] Please use the \"nl\" instead of the \"du\". The \"nl\" code is the standard code for Dutch language, and \"du\" will be removed in the next major versions.");
+
+ /* register specific locale function */
+ lunr.du = function() {
+ this.pipeline.reset();
+ this.pipeline.add(
+ lunr.du.trimmer,
+ lunr.du.stopWordFilter,
+ lunr.du.stemmer
+ );
+
+ // for lunr version 2
+ // this is necessary so that every searched word is also stemmed before
+ // in lunr <= 1 this is not needed, as it is done using the normal pipeline
+ if (this.searchPipeline) {
+ this.searchPipeline.reset();
+ this.searchPipeline.add(lunr.du.stemmer)
+ }
+ };
+
+ /* lunr trimmer function */
+ lunr.du.wordCharacters = "A-Za-z\xAA\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02B8\u02E0-\u02E4\u1D00-\u1D25\u1D2C-\u1D5C\u1D62-\u1D65\u1D6B-\u1D77\u1D79-\u1DBE\u1E00-\u1EFF\u2071\u207F\u2090-\u209C\u212A\u212B\u2132\u214E\u2160-\u2188\u2C60-\u2C7F\uA722-\uA787\uA78B-\uA7AD\uA7B0-\uA7B7\uA7F7-\uA7FF\uAB30-\uAB5A\uAB5C-\uAB64\uFB00-\uFB06\uFF21-\uFF3A\uFF41-\uFF5A";
+ lunr.du.trimmer = lunr.trimmerSupport.generateTrimmer(lunr.du.wordCharacters);
+
+ lunr.Pipeline.registerFunction(lunr.du.trimmer, 'trimmer-du');
+
+ /* lunr stemmer function */
+ lunr.du.stemmer = (function() {
+ /* create the wrapped stemmer object */
+ var Among = lunr.stemmerSupport.Among,
+ SnowballProgram = lunr.stemmerSupport.SnowballProgram,
+ st = new function DutchStemmer() {
+ var a_0 = [new Among("", -1, 6), new Among("\u00E1", 0, 1),
+ new Among("\u00E4", 0, 1), new Among("\u00E9", 0, 2),
+ new Among("\u00EB", 0, 2), new Among("\u00ED", 0, 3),
+ new Among("\u00EF", 0, 3), new Among("\u00F3", 0, 4),
+ new Among("\u00F6", 0, 4), new Among("\u00FA", 0, 5),
+ new Among("\u00FC", 0, 5)
+ ],
+ a_1 = [new Among("", -1, 3),
+ new Among("I", 0, 2), new Among("Y", 0, 1)
+ ],
+ a_2 = [
+ new Among("dd", -1, -1), new Among("kk", -1, -1),
+ new Among("tt", -1, -1)
+ ],
+ a_3 = [new Among("ene", -1, 2),
+ new Among("se", -1, 3), new Among("en", -1, 2),
+ new Among("heden", 2, 1), new Among("s", -1, 3)
+ ],
+ a_4 = [
+ new Among("end", -1, 1), new Among("ig", -1, 2),
+ new Among("ing", -1, 1), new Among("lijk", -1, 3),
+ new Among("baar", -1, 4), new Among("bar", -1, 5)
+ ],
+ a_5 = [
+ new Among("aa", -1, -1), new Among("ee", -1, -1),
+ new Among("oo", -1, -1), new Among("uu", -1, -1)
+ ],
+ g_v = [17, 65,
+ 16, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128
+ ],
+ g_v_I = [1, 0, 0,
+ 17, 65, 16, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128
+ ],
+ g_v_j = [
+ 17, 67, 16, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128
+ ],
+ I_p2, I_p1, B_e_found, sbp = new SnowballProgram();
+ this.setCurrent = function(word) {
+ sbp.setCurrent(word);
+ };
+ this.getCurrent = function() {
+ return sbp.getCurrent();
+ };
+
+ function r_prelude() {
+ var among_var, v_1 = sbp.cursor,
+ v_2, v_3;
+ while (true) {
+ sbp.bra = sbp.cursor;
+ among_var = sbp.find_among(a_0, 11);
+ if (among_var) {
+ sbp.ket = sbp.cursor;
+ switch (among_var) {
+ case 1:
+ sbp.slice_from("a");
+ continue;
+ case 2:
+ sbp.slice_from("e");
+ continue;
+ case 3:
+ sbp.slice_from("i");
+ continue;
+ case 4:
+ sbp.slice_from("o");
+ continue;
+ case 5:
+ sbp.slice_from("u");
+ continue;
+ case 6:
+ if (sbp.cursor >= sbp.limit)
+ break;
+ sbp.cursor++;
+ continue;
+ }
+ }
+ break;
+ }
+ sbp.cursor = v_1;
+ sbp.bra = v_1;
+ if (sbp.eq_s(1, "y")) {
+ sbp.ket = sbp.cursor;
+ sbp.slice_from("Y");
+ } else
+ sbp.cursor = v_1;
+ while (true) {
+ v_2 = sbp.cursor;
+ if (sbp.in_grouping(g_v, 97, 232)) {
+ v_3 = sbp.cursor;
+ sbp.bra = v_3;
+ if (sbp.eq_s(1, "i")) {
+ sbp.ket = sbp.cursor;
+ if (sbp.in_grouping(g_v, 97, 232)) {
+ sbp.slice_from("I");
+ sbp.cursor = v_2;
+ }
+ } else {
+ sbp.cursor = v_3;
+ if (sbp.eq_s(1, "y")) {
+ sbp.ket = sbp.cursor;
+ sbp.slice_from("Y");
+ sbp.cursor = v_2;
+ } else if (habr1(v_2))
+ break;
+ }
+ } else if (habr1(v_2))
+ break;
+ }
+ }
+
+ function habr1(v_1) {
+ sbp.cursor = v_1;
+ if (v_1 >= sbp.limit)
+ return true;
+ sbp.cursor++;
+ return false;
+ }
+
+ function r_mark_regions() {
+ I_p1 = sbp.limit;
+ I_p2 = I_p1;
+ if (!habr2()) {
+ I_p1 = sbp.cursor;
+ if (I_p1 < 3)
+ I_p1 = 3;
+ if (!habr2())
+ I_p2 = sbp.cursor;
+ }
+ }
+
+ function habr2() {
+ while (!sbp.in_grouping(g_v, 97, 232)) {
+ if (sbp.cursor >= sbp.limit)
+ return true;
+ sbp.cursor++;
+ }
+ while (!sbp.out_grouping(g_v, 97, 232)) {
+ if (sbp.cursor >= sbp.limit)
+ return true;
+ sbp.cursor++;
+ }
+ return false;
+ }
+
+ function r_postlude() {
+ var among_var;
+ while (true) {
+ sbp.bra = sbp.cursor;
+ among_var = sbp.find_among(a_1, 3);
+ if (among_var) {
+ sbp.ket = sbp.cursor;
+ switch (among_var) {
+ case 1:
+ sbp.slice_from("y");
+ break;
+ case 2:
+ sbp.slice_from("i");
+ break;
+ case 3:
+ if (sbp.cursor >= sbp.limit)
+ return;
+ sbp.cursor++;
+ break;
+ }
+ }
+ }
+ }
+
+ function r_R1() {
+ return I_p1 <= sbp.cursor;
+ }
+
+ function r_R2() {
+ return I_p2 <= sbp.cursor;
+ }
+
+ function r_undouble() {
+ var v_1 = sbp.limit - sbp.cursor;
+ if (sbp.find_among_b(a_2, 3)) {
+ sbp.cursor = sbp.limit - v_1;
+ sbp.ket = sbp.cursor;
+ if (sbp.cursor > sbp.limit_backward) {
+ sbp.cursor--;
+ sbp.bra = sbp.cursor;
+ sbp.slice_del();
+ }
+ }
+ }
+
+ function r_e_ending() {
+ var v_1;
+ B_e_found = false;
+ sbp.ket = sbp.cursor;
+ if (sbp.eq_s_b(1, "e")) {
+ sbp.bra = sbp.cursor;
+ if (r_R1()) {
+ v_1 = sbp.limit - sbp.cursor;
+ if (sbp.out_grouping_b(g_v, 97, 232)) {
+ sbp.cursor = sbp.limit - v_1;
+ sbp.slice_del();
+ B_e_found = true;
+ r_undouble();
+ }
+ }
+ }
+ }
+
+ function r_en_ending() {
+ var v_1;
+ if (r_R1()) {
+ v_1 = sbp.limit - sbp.cursor;
+ if (sbp.out_grouping_b(g_v, 97, 232)) {
+ sbp.cursor = sbp.limit - v_1;
+ if (!sbp.eq_s_b(3, "gem")) {
+ sbp.cursor = sbp.limit - v_1;
+ sbp.slice_del();
+ r_undouble();
+ }
+ }
+ }
+ }
+
+ function r_standard_suffix() {
+ var among_var, v_1 = sbp.limit - sbp.cursor,
+ v_2, v_3, v_4, v_5, v_6;
+ sbp.ket = sbp.cursor;
+ among_var = sbp.find_among_b(a_3, 5);
+ if (among_var) {
+ sbp.bra = sbp.cursor;
+ switch (among_var) {
+ case 1:
+ if (r_R1())
+ sbp.slice_from("heid");
+ break;
+ case 2:
+ r_en_ending();
+ break;
+ case 3:
+ if (r_R1() && sbp.out_grouping_b(g_v_j, 97, 232))
+ sbp.slice_del();
+ break;
+ }
+ }
+ sbp.cursor = sbp.limit - v_1;
+ r_e_ending();
+ sbp.cursor = sbp.limit - v_1;
+ sbp.ket = sbp.cursor;
+ if (sbp.eq_s_b(4, "heid")) {
+ sbp.bra = sbp.cursor;
+ if (r_R2()) {
+ v_2 = sbp.limit - sbp.cursor;
+ if (!sbp.eq_s_b(1, "c")) {
+ sbp.cursor = sbp.limit - v_2;
+ sbp.slice_del();
+ sbp.ket = sbp.cursor;
+ if (sbp.eq_s_b(2, "en")) {
+ sbp.bra = sbp.cursor;
+ r_en_ending();
+ }
+ }
+ }
+ }
+ sbp.cursor = sbp.limit - v_1;
+ sbp.ket = sbp.cursor;
+ among_var = sbp.find_among_b(a_4, 6);
+ if (among_var) {
+ sbp.bra = sbp.cursor;
+ switch (among_var) {
+ case 1:
+ if (r_R2()) {
+ sbp.slice_del();
+ v_3 = sbp.limit - sbp.cursor;
+ sbp.ket = sbp.cursor;
+ if (sbp.eq_s_b(2, "ig")) {
+ sbp.bra = sbp.cursor;
+ if (r_R2()) {
+ v_4 = sbp.limit - sbp.cursor;
+ if (!sbp.eq_s_b(1, "e")) {
+ sbp.cursor = sbp.limit - v_4;
+ sbp.slice_del();
+ break;
+ }
+ }
+ }
+ sbp.cursor = sbp.limit - v_3;
+ r_undouble();
+ }
+ break;
+ case 2:
+ if (r_R2()) {
+ v_5 = sbp.limit - sbp.cursor;
+ if (!sbp.eq_s_b(1, "e")) {
+ sbp.cursor = sbp.limit - v_5;
+ sbp.slice_del();
+ }
+ }
+ break;
+ case 3:
+ if (r_R2()) {
+ sbp.slice_del();
+ r_e_ending();
+ }
+ break;
+ case 4:
+ if (r_R2())
+ sbp.slice_del();
+ break;
+ case 5:
+ if (r_R2() && B_e_found)
+ sbp.slice_del();
+ break;
+ }
+ }
+ sbp.cursor = sbp.limit - v_1;
+ if (sbp.out_grouping_b(g_v_I, 73, 232)) {
+ v_6 = sbp.limit - sbp.cursor;
+ if (sbp.find_among_b(a_5, 4) && sbp.out_grouping_b(g_v, 97, 232)) {
+ sbp.cursor = sbp.limit - v_6;
+ sbp.ket = sbp.cursor;
+ if (sbp.cursor > sbp.limit_backward) {
+ sbp.cursor--;
+ sbp.bra = sbp.cursor;
+ sbp.slice_del();
+ }
+ }
+ }
+ }
+ this.stem = function() {
+ var v_1 = sbp.cursor;
+ r_prelude();
+ sbp.cursor = v_1;
+ r_mark_regions();
+ sbp.limit_backward = v_1;
+ sbp.cursor = sbp.limit;
+ r_standard_suffix();
+ sbp.cursor = sbp.limit_backward;
+ r_postlude();
+ return true;
+ }
+ };
+
+ /* and return a function that stems a word for the current locale */
+ return function(token) {
+ // for lunr version 2
+ if (typeof token.update === "function") {
+ return token.update(function(word) {
+ st.setCurrent(word);
+ st.stem();
+ return st.getCurrent();
+ })
+ } else { // for lunr version <= 1
+ st.setCurrent(token);
+ st.stem();
+ return st.getCurrent();
+ }
+ }
+ })();
+
+ lunr.Pipeline.registerFunction(lunr.du.stemmer, 'stemmer-du');
+
+ lunr.du.stopWordFilter = lunr.generateStopWordFilter(' aan al alles als altijd andere ben bij daar dan dat de der deze die dit doch doen door dus een eens en er ge geen geweest haar had heb hebben heeft hem het hier hij hoe hun iemand iets ik in is ja je kan kon kunnen maar me meer men met mij mijn moet na naar niet niets nog nu of om omdat onder ons ook op over reeds te tegen toch toen tot u uit uw van veel voor want waren was wat werd wezen wie wil worden wordt zal ze zelf zich zij zijn zo zonder zou'.split(' '));
+
+ lunr.Pipeline.registerFunction(lunr.du.stopWordFilter, 'stopWordFilter-du');
+ };
+}))
\ No newline at end of file
diff --git a/venv/lib/python3.11/site-packages/mkdocs/contrib/search/lunr-language/lunr.es.js b/venv/lib/python3.11/site-packages/mkdocs/contrib/search/lunr-language/lunr.es.js
new file mode 100644
index 0000000..46cbc36
--- /dev/null
+++ b/venv/lib/python3.11/site-packages/mkdocs/contrib/search/lunr-language/lunr.es.js
@@ -0,0 +1,599 @@
+/*!
+ * Lunr languages, `Spanish` language
+ * https://github.com/MihaiValentin/lunr-languages
+ *
+ * Copyright 2014, Mihai Valentin
+ * http://www.mozilla.org/MPL/
+ */
+/*!
+ * based on
+ * Snowball JavaScript Library v0.3
+ * http://code.google.com/p/urim/
+ * http://snowball.tartarus.org/
+ *
+ * Copyright 2010, Oleg Mazko
+ * http://www.mozilla.org/MPL/
+ */
+
+/**
+ * export the module via AMD, CommonJS or as a browser global
+ * Export code from https://github.com/umdjs/umd/blob/master/returnExports.js
+ */
+;
+(function(root, factory) {
+ if (typeof define === 'function' && define.amd) {
+ // AMD. Register as an anonymous module.
+ define(factory)
+ } else if (typeof exports === 'object') {
+ /**
+ * Node. Does not work with strict CommonJS, but
+ * only CommonJS-like environments that support module.exports,
+ * like Node.
+ */
+ module.exports = factory()
+ } else {
+ // Browser globals (root is window)
+ factory()(root.lunr);
+ }
+}(this, function() {
+ /**
+ * Just return a value to define the module export.
+ * This example returns an object, but the module
+ * can return a function as the exported value.
+ */
+ return function(lunr) {
+ /* throw error if lunr is not yet included */
+ if ('undefined' === typeof lunr) {
+ throw new Error('Lunr is not present. Please include / require Lunr before this script.');
+ }
+
+ /* throw error if lunr stemmer support is not yet included */
+ if ('undefined' === typeof lunr.stemmerSupport) {
+ throw new Error('Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.');
+ }
+
+ /* register specific locale function */
+ lunr.es = function() {
+ this.pipeline.reset();
+ this.pipeline.add(
+ lunr.es.trimmer,
+ lunr.es.stopWordFilter,
+ lunr.es.stemmer
+ );
+
+ // for lunr version 2
+ // this is necessary so that every searched word is also stemmed before
+ // in lunr <= 1 this is not needed, as it is done using the normal pipeline
+ if (this.searchPipeline) {
+ this.searchPipeline.reset();
+ this.searchPipeline.add(lunr.es.stemmer)
+ }
+ };
+
+ /* lunr trimmer function */
+ lunr.es.wordCharacters = "A-Za-z\xAA\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02B8\u02E0-\u02E4\u1D00-\u1D25\u1D2C-\u1D5C\u1D62-\u1D65\u1D6B-\u1D77\u1D79-\u1DBE\u1E00-\u1EFF\u2071\u207F\u2090-\u209C\u212A\u212B\u2132\u214E\u2160-\u2188\u2C60-\u2C7F\uA722-\uA787\uA78B-\uA7AD\uA7B0-\uA7B7\uA7F7-\uA7FF\uAB30-\uAB5A\uAB5C-\uAB64\uFB00-\uFB06\uFF21-\uFF3A\uFF41-\uFF5A";
+ lunr.es.trimmer = lunr.trimmerSupport.generateTrimmer(lunr.es.wordCharacters);
+
+ lunr.Pipeline.registerFunction(lunr.es.trimmer, 'trimmer-es');
+
+ /* lunr stemmer function */
+ lunr.es.stemmer = (function() {
+ /* create the wrapped stemmer object */
+ var Among = lunr.stemmerSupport.Among,
+ SnowballProgram = lunr.stemmerSupport.SnowballProgram,
+ st = new function SpanishStemmer() {
+ var a_0 = [new Among("", -1, 6), new Among("\u00E1", 0, 1),
+ new Among("\u00E9", 0, 2), new Among("\u00ED", 0, 3),
+ new Among("\u00F3", 0, 4), new Among("\u00FA", 0, 5)
+ ],
+ a_1 = [
+ new Among("la", -1, -1), new Among("sela", 0, -1),
+ new Among("le", -1, -1), new Among("me", -1, -1),
+ new Among("se", -1, -1), new Among("lo", -1, -1),
+ new Among("selo", 5, -1), new Among("las", -1, -1),
+ new Among("selas", 7, -1), new Among("les", -1, -1),
+ new Among("los", -1, -1), new Among("selos", 10, -1),
+ new Among("nos", -1, -1)
+ ],
+ a_2 = [new Among("ando", -1, 6),
+ new Among("iendo", -1, 6), new Among("yendo", -1, 7),
+ new Among("\u00E1ndo", -1, 2), new Among("i\u00E9ndo", -1, 1),
+ new Among("ar", -1, 6), new Among("er", -1, 6),
+ new Among("ir", -1, 6), new Among("\u00E1r", -1, 3),
+ new Among("\u00E9r", -1, 4), new Among("\u00EDr", -1, 5)
+ ],
+ a_3 = [
+ new Among("ic", -1, -1), new Among("ad", -1, -1),
+ new Among("os", -1, -1), new Among("iv", -1, 1)
+ ],
+ a_4 = [
+ new Among("able", -1, 1), new Among("ible", -1, 1),
+ new Among("ante", -1, 1)
+ ],
+ a_5 = [new Among("ic", -1, 1),
+ new Among("abil", -1, 1), new Among("iv", -1, 1)
+ ],
+ a_6 = [
+ new Among("ica", -1, 1), new Among("ancia", -1, 2),
+ new Among("encia", -1, 5), new Among("adora", -1, 2),
+ new Among("osa", -1, 1), new Among("ista", -1, 1),
+ new Among("iva", -1, 9), new Among("anza", -1, 1),
+ new Among("log\u00EDa", -1, 3), new Among("idad", -1, 8),
+ new Among("able", -1, 1), new Among("ible", -1, 1),
+ new Among("ante", -1, 2), new Among("mente", -1, 7),
+ new Among("amente", 13, 6), new Among("aci\u00F3n", -1, 2),
+ new Among("uci\u00F3n", -1, 4), new Among("ico", -1, 1),
+ new Among("ismo", -1, 1), new Among("oso", -1, 1),
+ new Among("amiento", -1, 1), new Among("imiento", -1, 1),
+ new Among("ivo", -1, 9), new Among("ador", -1, 2),
+ new Among("icas", -1, 1), new Among("ancias", -1, 2),
+ new Among("encias", -1, 5), new Among("adoras", -1, 2),
+ new Among("osas", -1, 1), new Among("istas", -1, 1),
+ new Among("ivas", -1, 9), new Among("anzas", -1, 1),
+ new Among("log\u00EDas", -1, 3), new Among("idades", -1, 8),
+ new Among("ables", -1, 1), new Among("ibles", -1, 1),
+ new Among("aciones", -1, 2), new Among("uciones", -1, 4),
+ new Among("adores", -1, 2), new Among("antes", -1, 2),
+ new Among("icos", -1, 1), new Among("ismos", -1, 1),
+ new Among("osos", -1, 1), new Among("amientos", -1, 1),
+ new Among("imientos", -1, 1), new Among("ivos", -1, 9)
+ ],
+ a_7 = [
+ new Among("ya", -1, 1), new Among("ye", -1, 1),
+ new Among("yan", -1, 1), new Among("yen", -1, 1),
+ new Among("yeron", -1, 1), new Among("yendo", -1, 1),
+ new Among("yo", -1, 1), new Among("yas", -1, 1),
+ new Among("yes", -1, 1), new Among("yais", -1, 1),
+ new Among("yamos", -1, 1), new Among("y\u00F3", -1, 1)
+ ],
+ a_8 = [
+ new Among("aba", -1, 2), new Among("ada", -1, 2),
+ new Among("ida", -1, 2), new Among("ara", -1, 2),
+ new Among("iera", -1, 2), new Among("\u00EDa", -1, 2),
+ new Among("ar\u00EDa", 5, 2), new Among("er\u00EDa", 5, 2),
+ new Among("ir\u00EDa", 5, 2), new Among("ad", -1, 2),
+ new Among("ed", -1, 2), new Among("id", -1, 2),
+ new Among("ase", -1, 2), new Among("iese", -1, 2),
+ new Among("aste", -1, 2), new Among("iste", -1, 2),
+ new Among("an", -1, 2), new Among("aban", 16, 2),
+ new Among("aran", 16, 2), new Among("ieran", 16, 2),
+ new Among("\u00EDan", 16, 2), new Among("ar\u00EDan", 20, 2),
+ new Among("er\u00EDan", 20, 2), new Among("ir\u00EDan", 20, 2),
+ new Among("en", -1, 1), new Among("asen", 24, 2),
+ new Among("iesen", 24, 2), new Among("aron", -1, 2),
+ new Among("ieron", -1, 2), new Among("ar\u00E1n", -1, 2),
+ new Among("er\u00E1n", -1, 2), new Among("ir\u00E1n", -1, 2),
+ new Among("ado", -1, 2), new Among("ido", -1, 2),
+ new Among("ando", -1, 2), new Among("iendo", -1, 2),
+ new Among("ar", -1, 2), new Among("er", -1, 2),
+ new Among("ir", -1, 2), new Among("as", -1, 2),
+ new Among("abas", 39, 2), new Among("adas", 39, 2),
+ new Among("idas", 39, 2), new Among("aras", 39, 2),
+ new Among("ieras", 39, 2), new Among("\u00EDas", 39, 2),
+ new Among("ar\u00EDas", 45, 2), new Among("er\u00EDas", 45, 2),
+ new Among("ir\u00EDas", 45, 2), new Among("es", -1, 1),
+ new Among("ases", 49, 2), new Among("ieses", 49, 2),
+ new Among("abais", -1, 2), new Among("arais", -1, 2),
+ new Among("ierais", -1, 2), new Among("\u00EDais", -1, 2),
+ new Among("ar\u00EDais", 55, 2), new Among("er\u00EDais", 55, 2),
+ new Among("ir\u00EDais", 55, 2), new Among("aseis", -1, 2),
+ new Among("ieseis", -1, 2), new Among("asteis", -1, 2),
+ new Among("isteis", -1, 2), new Among("\u00E1is", -1, 2),
+ new Among("\u00E9is", -1, 1), new Among("ar\u00E9is", 64, 2),
+ new Among("er\u00E9is", 64, 2), new Among("ir\u00E9is", 64, 2),
+ new Among("ados", -1, 2), new Among("idos", -1, 2),
+ new Among("amos", -1, 2), new Among("\u00E1bamos", 70, 2),
+ new Among("\u00E1ramos", 70, 2), new Among("i\u00E9ramos", 70, 2),
+ new Among("\u00EDamos", 70, 2), new Among("ar\u00EDamos", 74, 2),
+ new Among("er\u00EDamos", 74, 2), new Among("ir\u00EDamos", 74, 2),
+ new Among("emos", -1, 1), new Among("aremos", 78, 2),
+ new Among("eremos", 78, 2), new Among("iremos", 78, 2),
+ new Among("\u00E1semos", 78, 2), new Among("i\u00E9semos", 78, 2),
+ new Among("imos", -1, 2), new Among("ar\u00E1s", -1, 2),
+ new Among("er\u00E1s", -1, 2), new Among("ir\u00E1s", -1, 2),
+ new Among("\u00EDs", -1, 2), new Among("ar\u00E1", -1, 2),
+ new Among("er\u00E1", -1, 2), new Among("ir\u00E1", -1, 2),
+ new Among("ar\u00E9", -1, 2), new Among("er\u00E9", -1, 2),
+ new Among("ir\u00E9", -1, 2), new Among("i\u00F3", -1, 2)
+ ],
+ a_9 = [
+ new Among("a", -1, 1), new Among("e", -1, 2),
+ new Among("o", -1, 1), new Among("os", -1, 1),
+ new Among("\u00E1", -1, 1), new Among("\u00E9", -1, 2),
+ new Among("\u00ED", -1, 1), new Among("\u00F3", -1, 1)
+ ],
+ g_v = [17,
+ 65, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 17, 4, 10
+ ],
+ I_p2, I_p1, I_pV, sbp = new SnowballProgram();
+ this.setCurrent = function(word) {
+ sbp.setCurrent(word);
+ };
+ this.getCurrent = function() {
+ return sbp.getCurrent();
+ };
+
+ function habr1() {
+ if (sbp.out_grouping(g_v, 97, 252)) {
+ while (!sbp.in_grouping(g_v, 97, 252)) {
+ if (sbp.cursor >= sbp.limit)
+ return true;
+ sbp.cursor++;
+ }
+ return false;
+ }
+ return true;
+ }
+
+ function habr2() {
+ if (sbp.in_grouping(g_v, 97, 252)) {
+ var v_1 = sbp.cursor;
+ if (habr1()) {
+ sbp.cursor = v_1;
+ if (!sbp.in_grouping(g_v, 97, 252))
+ return true;
+ while (!sbp.out_grouping(g_v, 97, 252)) {
+ if (sbp.cursor >= sbp.limit)
+ return true;
+ sbp.cursor++;
+ }
+ }
+ return false;
+ }
+ return true;
+ }
+
+ function habr3() {
+ var v_1 = sbp.cursor,
+ v_2;
+ if (habr2()) {
+ sbp.cursor = v_1;
+ if (!sbp.out_grouping(g_v, 97, 252))
+ return;
+ v_2 = sbp.cursor;
+ if (habr1()) {
+ sbp.cursor = v_2;
+ if (!sbp.in_grouping(g_v, 97, 252) || sbp.cursor >= sbp.limit)
+ return;
+ sbp.cursor++;
+ }
+ }
+ I_pV = sbp.cursor;
+ }
+
+ function habr4() {
+ while (!sbp.in_grouping(g_v, 97, 252)) {
+ if (sbp.cursor >= sbp.limit)
+ return false;
+ sbp.cursor++;
+ }
+ while (!sbp.out_grouping(g_v, 97, 252)) {
+ if (sbp.cursor >= sbp.limit)
+ return false;
+ sbp.cursor++;
+ }
+ return true;
+ }
+
+ function r_mark_regions() {
+ var v_1 = sbp.cursor;
+ I_pV = sbp.limit;
+ I_p1 = I_pV;
+ I_p2 = I_pV;
+ habr3();
+ sbp.cursor = v_1;
+ if (habr4()) {
+ I_p1 = sbp.cursor;
+ if (habr4())
+ I_p2 = sbp.cursor;
+ }
+ }
+
+ function r_postlude() {
+ var among_var;
+ while (true) {
+ sbp.bra = sbp.cursor;
+ among_var = sbp.find_among(a_0, 6);
+ if (among_var) {
+ sbp.ket = sbp.cursor;
+ switch (among_var) {
+ case 1:
+ sbp.slice_from("a");
+ continue;
+ case 2:
+ sbp.slice_from("e");
+ continue;
+ case 3:
+ sbp.slice_from("i");
+ continue;
+ case 4:
+ sbp.slice_from("o");
+ continue;
+ case 5:
+ sbp.slice_from("u");
+ continue;
+ case 6:
+ if (sbp.cursor >= sbp.limit)
+ break;
+ sbp.cursor++;
+ continue;
+ }
+ }
+ break;
+ }
+ }
+
+ function r_RV() {
+ return I_pV <= sbp.cursor;
+ }
+
+ function r_R1() {
+ return I_p1 <= sbp.cursor;
+ }
+
+ function r_R2() {
+ return I_p2 <= sbp.cursor;
+ }
+
+ function r_attached_pronoun() {
+ var among_var;
+ sbp.ket = sbp.cursor;
+ if (sbp.find_among_b(a_1, 13)) {
+ sbp.bra = sbp.cursor;
+ among_var = sbp.find_among_b(a_2, 11);
+ if (among_var && r_RV())
+ switch (among_var) {
+ case 1:
+ sbp.bra = sbp.cursor;
+ sbp.slice_from("iendo");
+ break;
+ case 2:
+ sbp.bra = sbp.cursor;
+ sbp.slice_from("ando");
+ break;
+ case 3:
+ sbp.bra = sbp.cursor;
+ sbp.slice_from("ar");
+ break;
+ case 4:
+ sbp.bra = sbp.cursor;
+ sbp.slice_from("er");
+ break;
+ case 5:
+ sbp.bra = sbp.cursor;
+ sbp.slice_from("ir");
+ break;
+ case 6:
+ sbp.slice_del();
+ break;
+ case 7:
+ if (sbp.eq_s_b(1, "u"))
+ sbp.slice_del();
+ break;
+ }
+ }
+ }
+
+ function habr5(a, n) {
+ if (!r_R2())
+ return true;
+ sbp.slice_del();
+ sbp.ket = sbp.cursor;
+ var among_var = sbp.find_among_b(a, n);
+ if (among_var) {
+ sbp.bra = sbp.cursor;
+ if (among_var == 1 && r_R2())
+ sbp.slice_del();
+ }
+ return false;
+ }
+
+ function habr6(c1) {
+ if (!r_R2())
+ return true;
+ sbp.slice_del();
+ sbp.ket = sbp.cursor;
+ if (sbp.eq_s_b(2, c1)) {
+ sbp.bra = sbp.cursor;
+ if (r_R2())
+ sbp.slice_del();
+ }
+ return false;
+ }
+
+ function r_standard_suffix() {
+ var among_var;
+ sbp.ket = sbp.cursor;
+ among_var = sbp.find_among_b(a_6, 46);
+ if (among_var) {
+ sbp.bra = sbp.cursor;
+ switch (among_var) {
+ case 1:
+ if (!r_R2())
+ return false;
+ sbp.slice_del();
+ break;
+ case 2:
+ if (habr6("ic"))
+ return false;
+ break;
+ case 3:
+ if (!r_R2())
+ return false;
+ sbp.slice_from("log");
+ break;
+ case 4:
+ if (!r_R2())
+ return false;
+ sbp.slice_from("u");
+ break;
+ case 5:
+ if (!r_R2())
+ return false;
+ sbp.slice_from("ente");
+ break;
+ case 6:
+ if (!r_R1())
+ return false;
+ sbp.slice_del();
+ sbp.ket = sbp.cursor;
+ among_var = sbp.find_among_b(a_3, 4);
+ if (among_var) {
+ sbp.bra = sbp.cursor;
+ if (r_R2()) {
+ sbp.slice_del();
+ if (among_var == 1) {
+ sbp.ket = sbp.cursor;
+ if (sbp.eq_s_b(2, "at")) {
+ sbp.bra = sbp.cursor;
+ if (r_R2())
+ sbp.slice_del();
+ }
+ }
+ }
+ }
+ break;
+ case 7:
+ if (habr5(a_4, 3))
+ return false;
+ break;
+ case 8:
+ if (habr5(a_5, 3))
+ return false;
+ break;
+ case 9:
+ if (habr6("at"))
+ return false;
+ break;
+ }
+ return true;
+ }
+ return false;
+ }
+
+ function r_y_verb_suffix() {
+ var among_var, v_1;
+ if (sbp.cursor >= I_pV) {
+ v_1 = sbp.limit_backward;
+ sbp.limit_backward = I_pV;
+ sbp.ket = sbp.cursor;
+ among_var = sbp.find_among_b(a_7, 12);
+ sbp.limit_backward = v_1;
+ if (among_var) {
+ sbp.bra = sbp.cursor;
+ if (among_var == 1) {
+ if (!sbp.eq_s_b(1, "u"))
+ return false;
+ sbp.slice_del();
+ }
+ return true;
+ }
+ }
+ return false;
+ }
+
+ function r_verb_suffix() {
+ var among_var, v_1, v_2, v_3;
+ if (sbp.cursor >= I_pV) {
+ v_1 = sbp.limit_backward;
+ sbp.limit_backward = I_pV;
+ sbp.ket = sbp.cursor;
+ among_var = sbp.find_among_b(a_8, 96);
+ sbp.limit_backward = v_1;
+ if (among_var) {
+ sbp.bra = sbp.cursor;
+ switch (among_var) {
+ case 1:
+ v_2 = sbp.limit - sbp.cursor;
+ if (sbp.eq_s_b(1, "u")) {
+ v_3 = sbp.limit - sbp.cursor;
+ if (sbp.eq_s_b(1, "g"))
+ sbp.cursor = sbp.limit - v_3;
+ else
+ sbp.cursor = sbp.limit - v_2;
+ } else
+ sbp.cursor = sbp.limit - v_2;
+ sbp.bra = sbp.cursor;
+ case 2:
+ sbp.slice_del();
+ break;
+ }
+ }
+ }
+ }
+
+ function r_residual_suffix() {
+ var among_var, v_1;
+ sbp.ket = sbp.cursor;
+ among_var = sbp.find_among_b(a_9, 8);
+ if (among_var) {
+ sbp.bra = sbp.cursor;
+ switch (among_var) {
+ case 1:
+ if (r_RV())
+ sbp.slice_del();
+ break;
+ case 2:
+ if (r_RV()) {
+ sbp.slice_del();
+ sbp.ket = sbp.cursor;
+ if (sbp.eq_s_b(1, "u")) {
+ sbp.bra = sbp.cursor;
+ v_1 = sbp.limit - sbp.cursor;
+ if (sbp.eq_s_b(1, "g")) {
+ sbp.cursor = sbp.limit - v_1;
+ if (r_RV())
+ sbp.slice_del();
+ }
+ }
+ }
+ break;
+ }
+ }
+ }
+ this.stem = function() {
+ var v_1 = sbp.cursor;
+ r_mark_regions();
+ sbp.limit_backward = v_1;
+ sbp.cursor = sbp.limit;
+ r_attached_pronoun();
+ sbp.cursor = sbp.limit;
+ if (!r_standard_suffix()) {
+ sbp.cursor = sbp.limit;
+ if (!r_y_verb_suffix()) {
+ sbp.cursor = sbp.limit;
+ r_verb_suffix();
+ }
+ }
+ sbp.cursor = sbp.limit;
+ r_residual_suffix();
+ sbp.cursor = sbp.limit_backward;
+ r_postlude();
+ return true;
+ }
+ };
+
+ /* and return a function that stems a word for the current locale */
+ return function(token) {
+ // for lunr version 2
+ if (typeof token.update === "function") {
+ return token.update(function(word) {
+ st.setCurrent(word);
+ st.stem();
+ return st.getCurrent();
+ })
+ } else { // for lunr version <= 1
+ st.setCurrent(token);
+ st.stem();
+ return st.getCurrent();
+ }
+ }
+ })();
+
+ lunr.Pipeline.registerFunction(lunr.es.stemmer, 'stemmer-es');
+
+ lunr.es.stopWordFilter = lunr.generateStopWordFilter('a al algo algunas algunos ante antes como con contra cual cuando de del desde donde durante e el ella ellas ellos en entre era erais eran eras eres es esa esas ese eso esos esta estaba estabais estaban estabas estad estada estadas estado estados estamos estando estar estaremos estará estarán estarás estaré estaréis estaría estaríais estaríamos estarían estarías estas este estemos esto estos estoy estuve estuviera estuvierais estuvieran estuvieras estuvieron estuviese estuvieseis estuviesen estuvieses estuvimos estuviste estuvisteis estuviéramos estuviésemos estuvo está estábamos estáis están estás esté estéis estén estés fue fuera fuerais fueran fueras fueron fuese fueseis fuesen fueses fui fuimos fuiste fuisteis fuéramos fuésemos ha habida habidas habido habidos habiendo habremos habrá habrán habrás habré habréis habría habríais habríamos habrían habrías habéis había habíais habíamos habían habías han has hasta hay haya hayamos hayan hayas hayáis he hemos hube hubiera hubierais hubieran hubieras hubieron hubiese hubieseis hubiesen hubieses hubimos hubiste hubisteis hubiéramos hubiésemos hubo la las le les lo los me mi mis mucho muchos muy más mí mía mías mío míos nada ni no nos nosotras nosotros nuestra nuestras nuestro nuestros o os otra otras otro otros para pero poco por porque que quien quienes qué se sea seamos sean seas seremos será serán serás seré seréis sería seríais seríamos serían serías seáis sido siendo sin sobre sois somos son soy su sus suya suyas suyo suyos sí también tanto te tendremos tendrá tendrán tendrás tendré tendréis tendría tendríais tendríamos tendrían tendrías tened tenemos tenga tengamos tengan tengas tengo tengáis tenida tenidas tenido tenidos teniendo tenéis tenía teníais teníamos tenían tenías ti tiene tienen tienes todo todos tu tus tuve tuviera tuvierais tuvieran tuvieras tuvieron tuviese tuvieseis tuviesen tuvieses tuvimos tuviste tuvisteis tuviéramos tuviésemos tuvo tuya tuyas tuyo tuyos tú un una uno unos vosotras vosotros vuestra vuestras vuestro vuestros y ya yo él éramos'.split(' '));
+
+ lunr.Pipeline.registerFunction(lunr.es.stopWordFilter, 'stopWordFilter-es');
+ };
+}))
\ No newline at end of file
diff --git a/venv/lib/python3.11/site-packages/mkdocs/contrib/search/lunr-language/lunr.fi.js b/venv/lib/python3.11/site-packages/mkdocs/contrib/search/lunr-language/lunr.fi.js
new file mode 100644
index 0000000..7ce9515
--- /dev/null
+++ b/venv/lib/python3.11/site-packages/mkdocs/contrib/search/lunr-language/lunr.fi.js
@@ -0,0 +1,541 @@
+/*!
+ * Lunr languages, `Finnish` language
+ * https://github.com/MihaiValentin/lunr-languages
+ *
+ * Copyright 2014, Mihai Valentin
+ * http://www.mozilla.org/MPL/
+ */
+/*!
+ * based on
+ * Snowball JavaScript Library v0.3
+ * http://code.google.com/p/urim/
+ * http://snowball.tartarus.org/
+ *
+ * Copyright 2010, Oleg Mazko
+ * http://www.mozilla.org/MPL/
+ */
+
+/**
+ * export the module via AMD, CommonJS or as a browser global
+ * Export code from https://github.com/umdjs/umd/blob/master/returnExports.js
+ */
+;
+(function(root, factory) {
+ if (typeof define === 'function' && define.amd) {
+ // AMD. Register as an anonymous module.
+ define(factory)
+ } else if (typeof exports === 'object') {
+ /**
+ * Node. Does not work with strict CommonJS, but
+ * only CommonJS-like environments that support module.exports,
+ * like Node.
+ */
+ module.exports = factory()
+ } else {
+ // Browser globals (root is window)
+ factory()(root.lunr);
+ }
+}(this, function() {
+ /**
+ * Just return a value to define the module export.
+ * This example returns an object, but the module
+ * can return a function as the exported value.
+ */
+ return function(lunr) {
+ /* throw error if lunr is not yet included */
+ if ('undefined' === typeof lunr) {
+ throw new Error('Lunr is not present. Please include / require Lunr before this script.');
+ }
+
+ /* throw error if lunr stemmer support is not yet included */
+ if ('undefined' === typeof lunr.stemmerSupport) {
+ throw new Error('Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.');
+ }
+
+ /* register specific locale function */
+ lunr.fi = function() {
+ this.pipeline.reset();
+ this.pipeline.add(
+ lunr.fi.trimmer,
+ lunr.fi.stopWordFilter,
+ lunr.fi.stemmer
+ );
+
+ // for lunr version 2
+ // this is necessary so that every searched word is also stemmed before
+ // in lunr <= 1 this is not needed, as it is done using the normal pipeline
+ if (this.searchPipeline) {
+ this.searchPipeline.reset();
+ this.searchPipeline.add(lunr.fi.stemmer)
+ }
+ };
+
+ /* lunr trimmer function */
+ lunr.fi.wordCharacters = "A-Za-z\xAA\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02B8\u02E0-\u02E4\u1D00-\u1D25\u1D2C-\u1D5C\u1D62-\u1D65\u1D6B-\u1D77\u1D79-\u1DBE\u1E00-\u1EFF\u2071\u207F\u2090-\u209C\u212A\u212B\u2132\u214E\u2160-\u2188\u2C60-\u2C7F\uA722-\uA787\uA78B-\uA7AD\uA7B0-\uA7B7\uA7F7-\uA7FF\uAB30-\uAB5A\uAB5C-\uAB64\uFB00-\uFB06\uFF21-\uFF3A\uFF41-\uFF5A";
+ lunr.fi.trimmer = lunr.trimmerSupport.generateTrimmer(lunr.fi.wordCharacters);
+
+ lunr.Pipeline.registerFunction(lunr.fi.trimmer, 'trimmer-fi');
+
+ /* lunr stemmer function */
+ lunr.fi.stemmer = (function() {
+ /* create the wrapped stemmer object */
+ var Among = lunr.stemmerSupport.Among,
+ SnowballProgram = lunr.stemmerSupport.SnowballProgram,
+ st = new function FinnishStemmer() {
+ var a_0 = [new Among("pa", -1, 1), new Among("sti", -1, 2),
+ new Among("kaan", -1, 1), new Among("han", -1, 1),
+ new Among("kin", -1, 1), new Among("h\u00E4n", -1, 1),
+ new Among("k\u00E4\u00E4n", -1, 1), new Among("ko", -1, 1),
+ new Among("p\u00E4", -1, 1), new Among("k\u00F6", -1, 1)
+ ],
+ a_1 = [
+ new Among("lla", -1, -1), new Among("na", -1, -1),
+ new Among("ssa", -1, -1), new Among("ta", -1, -1),
+ new Among("lta", 3, -1), new Among("sta", 3, -1)
+ ],
+ a_2 = [
+ new Among("ll\u00E4", -1, -1), new Among("n\u00E4", -1, -1),
+ new Among("ss\u00E4", -1, -1), new Among("t\u00E4", -1, -1),
+ new Among("lt\u00E4", 3, -1), new Among("st\u00E4", 3, -1)
+ ],
+ a_3 = [
+ new Among("lle", -1, -1), new Among("ine", -1, -1)
+ ],
+ a_4 = [
+ new Among("nsa", -1, 3), new Among("mme", -1, 3),
+ new Among("nne", -1, 3), new Among("ni", -1, 2),
+ new Among("si", -1, 1), new Among("an", -1, 4),
+ new Among("en", -1, 6), new Among("\u00E4n", -1, 5),
+ new Among("ns\u00E4", -1, 3)
+ ],
+ a_5 = [new Among("aa", -1, -1),
+ new Among("ee", -1, -1), new Among("ii", -1, -1),
+ new Among("oo", -1, -1), new Among("uu", -1, -1),
+ new Among("\u00E4\u00E4", -1, -1),
+ new Among("\u00F6\u00F6", -1, -1)
+ ],
+ a_6 = [new Among("a", -1, 8),
+ new Among("lla", 0, -1), new Among("na", 0, -1),
+ new Among("ssa", 0, -1), new Among("ta", 0, -1),
+ new Among("lta", 4, -1), new Among("sta", 4, -1),
+ new Among("tta", 4, 9), new Among("lle", -1, -1),
+ new Among("ine", -1, -1), new Among("ksi", -1, -1),
+ new Among("n", -1, 7), new Among("han", 11, 1),
+ new Among("den", 11, -1, r_VI), new Among("seen", 11, -1, r_LONG),
+ new Among("hen", 11, 2), new Among("tten", 11, -1, r_VI),
+ new Among("hin", 11, 3), new Among("siin", 11, -1, r_VI),
+ new Among("hon", 11, 4), new Among("h\u00E4n", 11, 5),
+ new Among("h\u00F6n", 11, 6), new Among("\u00E4", -1, 8),
+ new Among("ll\u00E4", 22, -1), new Among("n\u00E4", 22, -1),
+ new Among("ss\u00E4", 22, -1), new Among("t\u00E4", 22, -1),
+ new Among("lt\u00E4", 26, -1), new Among("st\u00E4", 26, -1),
+ new Among("tt\u00E4", 26, 9)
+ ],
+ a_7 = [new Among("eja", -1, -1),
+ new Among("mma", -1, 1), new Among("imma", 1, -1),
+ new Among("mpa", -1, 1), new Among("impa", 3, -1),
+ new Among("mmi", -1, 1), new Among("immi", 5, -1),
+ new Among("mpi", -1, 1), new Among("impi", 7, -1),
+ new Among("ej\u00E4", -1, -1), new Among("mm\u00E4", -1, 1),
+ new Among("imm\u00E4", 10, -1), new Among("mp\u00E4", -1, 1),
+ new Among("imp\u00E4", 12, -1)
+ ],
+ a_8 = [new Among("i", -1, -1),
+ new Among("j", -1, -1)
+ ],
+ a_9 = [new Among("mma", -1, 1),
+ new Among("imma", 0, -1)
+ ],
+ g_AEI = [17, 1, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 8
+ ],
+ g_V1 = [17, 65, 16, 1, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 8, 0, 32
+ ],
+ g_V2 = [17, 65, 16, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 8, 0, 32
+ ],
+ g_particle_end = [17, 97, 24, 1, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 32
+ ],
+ B_ending_removed, S_x, I_p2, I_p1, sbp = new SnowballProgram();
+ this.setCurrent = function(word) {
+ sbp.setCurrent(word);
+ };
+ this.getCurrent = function() {
+ return sbp.getCurrent();
+ };
+
+ function r_mark_regions() {
+ I_p1 = sbp.limit;
+ I_p2 = I_p1;
+ if (!habr1()) {
+ I_p1 = sbp.cursor;
+ if (!habr1())
+ I_p2 = sbp.cursor;
+ }
+ }
+
+ function habr1() {
+ var v_1;
+ while (true) {
+ v_1 = sbp.cursor;
+ if (sbp.in_grouping(g_V1, 97, 246))
+ break;
+ sbp.cursor = v_1;
+ if (v_1 >= sbp.limit)
+ return true;
+ sbp.cursor++;
+ }
+ sbp.cursor = v_1;
+ while (!sbp.out_grouping(g_V1, 97, 246)) {
+ if (sbp.cursor >= sbp.limit)
+ return true;
+ sbp.cursor++;
+ }
+ return false;
+ }
+
+ function r_R2() {
+ return I_p2 <= sbp.cursor;
+ }
+
+ function r_particle_etc() {
+ var among_var, v_1;
+ if (sbp.cursor >= I_p1) {
+ v_1 = sbp.limit_backward;
+ sbp.limit_backward = I_p1;
+ sbp.ket = sbp.cursor;
+ among_var = sbp.find_among_b(a_0, 10);
+ if (among_var) {
+ sbp.bra = sbp.cursor;
+ sbp.limit_backward = v_1;
+ switch (among_var) {
+ case 1:
+ if (!sbp.in_grouping_b(g_particle_end, 97, 246))
+ return;
+ break;
+ case 2:
+ if (!r_R2())
+ return;
+ break;
+ }
+ sbp.slice_del();
+ } else
+ sbp.limit_backward = v_1;
+ }
+ }
+
+ function r_possessive() {
+ var among_var, v_1, v_2;
+ if (sbp.cursor >= I_p1) {
+ v_1 = sbp.limit_backward;
+ sbp.limit_backward = I_p1;
+ sbp.ket = sbp.cursor;
+ among_var = sbp.find_among_b(a_4, 9);
+ if (among_var) {
+ sbp.bra = sbp.cursor;
+ sbp.limit_backward = v_1;
+ switch (among_var) {
+ case 1:
+ v_2 = sbp.limit - sbp.cursor;
+ if (!sbp.eq_s_b(1, "k")) {
+ sbp.cursor = sbp.limit - v_2;
+ sbp.slice_del();
+ }
+ break;
+ case 2:
+ sbp.slice_del();
+ sbp.ket = sbp.cursor;
+ if (sbp.eq_s_b(3, "kse")) {
+ sbp.bra = sbp.cursor;
+ sbp.slice_from("ksi");
+ }
+ break;
+ case 3:
+ sbp.slice_del();
+ break;
+ case 4:
+ if (sbp.find_among_b(a_1, 6))
+ sbp.slice_del();
+ break;
+ case 5:
+ if (sbp.find_among_b(a_2, 6))
+ sbp.slice_del();
+ break;
+ case 6:
+ if (sbp.find_among_b(a_3, 2))
+ sbp.slice_del();
+ break;
+ }
+ } else
+ sbp.limit_backward = v_1;
+ }
+ }
+
+ function r_LONG() {
+ return sbp.find_among_b(a_5, 7);
+ }
+
+ function r_VI() {
+ return sbp.eq_s_b(1, "i") && sbp.in_grouping_b(g_V2, 97, 246);
+ }
+
+ function r_case_ending() {
+ var among_var, v_1, v_2;
+ if (sbp.cursor >= I_p1) {
+ v_1 = sbp.limit_backward;
+ sbp.limit_backward = I_p1;
+ sbp.ket = sbp.cursor;
+ among_var = sbp.find_among_b(a_6, 30);
+ if (among_var) {
+ sbp.bra = sbp.cursor;
+ sbp.limit_backward = v_1;
+ switch (among_var) {
+ case 1:
+ if (!sbp.eq_s_b(1, "a"))
+ return;
+ break;
+ case 2:
+ case 9:
+ if (!sbp.eq_s_b(1, "e"))
+ return;
+ break;
+ case 3:
+ if (!sbp.eq_s_b(1, "i"))
+ return;
+ break;
+ case 4:
+ if (!sbp.eq_s_b(1, "o"))
+ return;
+ break;
+ case 5:
+ if (!sbp.eq_s_b(1, "\u00E4"))
+ return;
+ break;
+ case 6:
+ if (!sbp.eq_s_b(1, "\u00F6"))
+ return;
+ break;
+ case 7:
+ v_2 = sbp.limit - sbp.cursor;
+ if (!r_LONG()) {
+ sbp.cursor = sbp.limit - v_2;
+ if (!sbp.eq_s_b(2, "ie")) {
+ sbp.cursor = sbp.limit - v_2;
+ break;
+ }
+ }
+ sbp.cursor = sbp.limit - v_2;
+ if (sbp.cursor <= sbp.limit_backward) {
+ sbp.cursor = sbp.limit - v_2;
+ break;
+ }
+ sbp.cursor--;
+ sbp.bra = sbp.cursor;
+ break;
+ case 8:
+ if (!sbp.in_grouping_b(g_V1, 97, 246) ||
+ !sbp.out_grouping_b(g_V1, 97, 246))
+ return;
+ break;
+ }
+ sbp.slice_del();
+ B_ending_removed = true;
+ } else
+ sbp.limit_backward = v_1;
+ }
+ }
+
+ function r_other_endings() {
+ var among_var, v_1, v_2;
+ if (sbp.cursor >= I_p2) {
+ v_1 = sbp.limit_backward;
+ sbp.limit_backward = I_p2;
+ sbp.ket = sbp.cursor;
+ among_var = sbp.find_among_b(a_7, 14);
+ if (among_var) {
+ sbp.bra = sbp.cursor;
+ sbp.limit_backward = v_1;
+ if (among_var == 1) {
+ v_2 = sbp.limit - sbp.cursor;
+ if (sbp.eq_s_b(2, "po"))
+ return;
+ sbp.cursor = sbp.limit - v_2;
+ }
+ sbp.slice_del();
+ } else
+ sbp.limit_backward = v_1;
+ }
+ }
+
+ function r_i_plural() {
+ var v_1;
+ if (sbp.cursor >= I_p1) {
+ v_1 = sbp.limit_backward;
+ sbp.limit_backward = I_p1;
+ sbp.ket = sbp.cursor;
+ if (sbp.find_among_b(a_8, 2)) {
+ sbp.bra = sbp.cursor;
+ sbp.limit_backward = v_1;
+ sbp.slice_del();
+ } else
+ sbp.limit_backward = v_1;
+ }
+ }
+
+ function r_t_plural() {
+ var among_var, v_1, v_2, v_3, v_4, v_5;
+ if (sbp.cursor >= I_p1) {
+ v_1 = sbp.limit_backward;
+ sbp.limit_backward = I_p1;
+ sbp.ket = sbp.cursor;
+ if (sbp.eq_s_b(1, "t")) {
+ sbp.bra = sbp.cursor;
+ v_2 = sbp.limit - sbp.cursor;
+ if (sbp.in_grouping_b(g_V1, 97, 246)) {
+ sbp.cursor = sbp.limit - v_2;
+ sbp.slice_del();
+ sbp.limit_backward = v_1;
+ v_3 = sbp.limit - sbp.cursor;
+ if (sbp.cursor >= I_p2) {
+ sbp.cursor = I_p2;
+ v_4 = sbp.limit_backward;
+ sbp.limit_backward = sbp.cursor;
+ sbp.cursor = sbp.limit - v_3;
+ sbp.ket = sbp.cursor;
+ among_var = sbp.find_among_b(a_9, 2);
+ if (among_var) {
+ sbp.bra = sbp.cursor;
+ sbp.limit_backward = v_4;
+ if (among_var == 1) {
+ v_5 = sbp.limit - sbp.cursor;
+ if (sbp.eq_s_b(2, "po"))
+ return;
+ sbp.cursor = sbp.limit - v_5;
+ }
+ sbp.slice_del();
+ return;
+ }
+ }
+ }
+ }
+ sbp.limit_backward = v_1;
+ }
+ }
+
+ function r_tidy() {
+ var v_1, v_2, v_3, v_4;
+ if (sbp.cursor >= I_p1) {
+ v_1 = sbp.limit_backward;
+ sbp.limit_backward = I_p1;
+ v_2 = sbp.limit - sbp.cursor;
+ if (r_LONG()) {
+ sbp.cursor = sbp.limit - v_2;
+ sbp.ket = sbp.cursor;
+ if (sbp.cursor > sbp.limit_backward) {
+ sbp.cursor--;
+ sbp.bra = sbp.cursor;
+ sbp.slice_del();
+ }
+ }
+ sbp.cursor = sbp.limit - v_2;
+ sbp.ket = sbp.cursor;
+ if (sbp.in_grouping_b(g_AEI, 97, 228)) {
+ sbp.bra = sbp.cursor;
+ if (sbp.out_grouping_b(g_V1, 97, 246))
+ sbp.slice_del();
+ }
+ sbp.cursor = sbp.limit - v_2;
+ sbp.ket = sbp.cursor;
+ if (sbp.eq_s_b(1, "j")) {
+ sbp.bra = sbp.cursor;
+ v_3 = sbp.limit - sbp.cursor;
+ if (!sbp.eq_s_b(1, "o")) {
+ sbp.cursor = sbp.limit - v_3;
+ if (sbp.eq_s_b(1, "u"))
+ sbp.slice_del();
+ } else
+ sbp.slice_del();
+ }
+ sbp.cursor = sbp.limit - v_2;
+ sbp.ket = sbp.cursor;
+ if (sbp.eq_s_b(1, "o")) {
+ sbp.bra = sbp.cursor;
+ if (sbp.eq_s_b(1, "j"))
+ sbp.slice_del();
+ }
+ sbp.cursor = sbp.limit - v_2;
+ sbp.limit_backward = v_1;
+ while (true) {
+ v_4 = sbp.limit - sbp.cursor;
+ if (sbp.out_grouping_b(g_V1, 97, 246)) {
+ sbp.cursor = sbp.limit - v_4;
+ break;
+ }
+ sbp.cursor = sbp.limit - v_4;
+ if (sbp.cursor <= sbp.limit_backward)
+ return;
+ sbp.cursor--;
+ }
+ sbp.ket = sbp.cursor;
+ if (sbp.cursor > sbp.limit_backward) {
+ sbp.cursor--;
+ sbp.bra = sbp.cursor;
+ S_x = sbp.slice_to();
+ if (sbp.eq_v_b(S_x))
+ sbp.slice_del();
+ }
+ }
+ }
+ this.stem = function() {
+ var v_1 = sbp.cursor;
+ r_mark_regions();
+ B_ending_removed = false;
+ sbp.limit_backward = v_1;
+ sbp.cursor = sbp.limit;
+ r_particle_etc();
+ sbp.cursor = sbp.limit;
+ r_possessive();
+ sbp.cursor = sbp.limit;
+ r_case_ending();
+ sbp.cursor = sbp.limit;
+ r_other_endings();
+ sbp.cursor = sbp.limit;
+ if (B_ending_removed) {
+ r_i_plural();
+ sbp.cursor = sbp.limit;
+ } else {
+ sbp.cursor = sbp.limit;
+ r_t_plural();
+ sbp.cursor = sbp.limit;
+ }
+ r_tidy();
+ return true;
+ }
+ };
+
+ /* and return a function that stems a word for the current locale */
+ return function(token) {
+ // for lunr version 2
+ if (typeof token.update === "function") {
+ return token.update(function(word) {
+ st.setCurrent(word);
+ st.stem();
+ return st.getCurrent();
+ })
+ } else { // for lunr version <= 1
+ st.setCurrent(token);
+ st.stem();
+ return st.getCurrent();
+ }
+ }
+ })();
+
+ lunr.Pipeline.registerFunction(lunr.fi.stemmer, 'stemmer-fi');
+
+ lunr.fi.stopWordFilter = lunr.generateStopWordFilter('ei eivät emme en et ette että he heidän heidät heihin heille heillä heiltä heissä heistä heitä hän häneen hänelle hänellä häneltä hänen hänessä hänestä hänet häntä itse ja johon joiden joihin joiksi joilla joille joilta joina joissa joista joita joka joksi jolla jolle jolta jona jonka jos jossa josta jota jotka kanssa keiden keihin keiksi keille keillä keiltä keinä keissä keistä keitä keneen keneksi kenelle kenellä keneltä kenen kenenä kenessä kenestä kenet ketkä ketkä ketä koska kuin kuka kun me meidän meidät meihin meille meillä meiltä meissä meistä meitä mihin miksi mikä mille millä miltä minkä minkä minua minulla minulle minulta minun minussa minusta minut minuun minä minä missä mistä mitkä mitä mukaan mutta ne niiden niihin niiksi niille niillä niiltä niin niin niinä niissä niistä niitä noiden noihin noiksi noilla noille noilta noin noina noissa noista noita nuo nyt näiden näihin näiksi näille näillä näiltä näinä näissä näistä näitä nämä ole olemme olen olet olette oli olimme olin olisi olisimme olisin olisit olisitte olisivat olit olitte olivat olla olleet ollut on ovat poikki se sekä sen siihen siinä siitä siksi sille sillä sillä siltä sinua sinulla sinulle sinulta sinun sinussa sinusta sinut sinuun sinä sinä sitä tai te teidän teidät teihin teille teillä teiltä teissä teistä teitä tuo tuohon tuoksi tuolla tuolle tuolta tuon tuona tuossa tuosta tuota tähän täksi tälle tällä tältä tämä tämän tänä tässä tästä tätä vaan vai vaikka yli'.split(' '));
+
+ lunr.Pipeline.registerFunction(lunr.fi.stopWordFilter, 'stopWordFilter-fi');
+ };
+}))
\ No newline at end of file
diff --git a/venv/lib/python3.11/site-packages/mkdocs/contrib/search/lunr-language/lunr.fr.js b/venv/lib/python3.11/site-packages/mkdocs/contrib/search/lunr-language/lunr.fr.js
new file mode 100644
index 0000000..2de6d46
--- /dev/null
+++ b/venv/lib/python3.11/site-packages/mkdocs/contrib/search/lunr-language/lunr.fr.js
@@ -0,0 +1,703 @@
+/*!
+ * Lunr languages, `French` language
+ * https://github.com/MihaiValentin/lunr-languages
+ *
+ * Copyright 2014, Mihai Valentin
+ * http://www.mozilla.org/MPL/
+ */
+/*!
+ * based on
+ * Snowball JavaScript Library v0.3
+ * http://code.google.com/p/urim/
+ * http://snowball.tartarus.org/
+ *
+ * Copyright 2010, Oleg Mazko
+ * http://www.mozilla.org/MPL/
+ */
+
+/**
+ * export the module via AMD, CommonJS or as a browser global
+ * Export code from https://github.com/umdjs/umd/blob/master/returnExports.js
+ */
+;
+(function(root, factory) {
+ if (typeof define === 'function' && define.amd) {
+ // AMD. Register as an anonymous module.
+ define(factory)
+ } else if (typeof exports === 'object') {
+ /**
+ * Node. Does not work with strict CommonJS, but
+ * only CommonJS-like environments that support module.exports,
+ * like Node.
+ */
+ module.exports = factory()
+ } else {
+ // Browser globals (root is window)
+ factory()(root.lunr);
+ }
+}(this, function() {
+ /**
+ * Just return a value to define the module export.
+ * This example returns an object, but the module
+ * can return a function as the exported value.
+ */
+ return function(lunr) {
+ /* throw error if lunr is not yet included */
+ if ('undefined' === typeof lunr) {
+ throw new Error('Lunr is not present. Please include / require Lunr before this script.');
+ }
+
+ /* throw error if lunr stemmer support is not yet included */
+ if ('undefined' === typeof lunr.stemmerSupport) {
+ throw new Error('Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.');
+ }
+
+ /* register specific locale function */
+ lunr.fr = function() {
+ this.pipeline.reset();
+ this.pipeline.add(
+ lunr.fr.trimmer,
+ lunr.fr.stopWordFilter,
+ lunr.fr.stemmer
+ );
+
+ // for lunr version 2
+ // this is necessary so that every searched word is also stemmed before
+ // in lunr <= 1 this is not needed, as it is done using the normal pipeline
+ if (this.searchPipeline) {
+ this.searchPipeline.reset();
+ this.searchPipeline.add(lunr.fr.stemmer)
+ }
+ };
+
+ /* lunr trimmer function */
+ lunr.fr.wordCharacters = "A-Za-z\xAA\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02B8\u02E0-\u02E4\u1D00-\u1D25\u1D2C-\u1D5C\u1D62-\u1D65\u1D6B-\u1D77\u1D79-\u1DBE\u1E00-\u1EFF\u2071\u207F\u2090-\u209C\u212A\u212B\u2132\u214E\u2160-\u2188\u2C60-\u2C7F\uA722-\uA787\uA78B-\uA7AD\uA7B0-\uA7B7\uA7F7-\uA7FF\uAB30-\uAB5A\uAB5C-\uAB64\uFB00-\uFB06\uFF21-\uFF3A\uFF41-\uFF5A";
+ lunr.fr.trimmer = lunr.trimmerSupport.generateTrimmer(lunr.fr.wordCharacters);
+
+ lunr.Pipeline.registerFunction(lunr.fr.trimmer, 'trimmer-fr');
+
+ /* lunr stemmer function */
+ lunr.fr.stemmer = (function() {
+ /* create the wrapped stemmer object */
+ var Among = lunr.stemmerSupport.Among,
+ SnowballProgram = lunr.stemmerSupport.SnowballProgram,
+ st = new function FrenchStemmer() {
+ var a_0 = [new Among("col", -1, -1), new Among("par", -1, -1),
+ new Among("tap", -1, -1)
+ ],
+ a_1 = [new Among("", -1, 4),
+ new Among("I", 0, 1), new Among("U", 0, 2), new Among("Y", 0, 3)
+ ],
+ a_2 = [
+ new Among("iqU", -1, 3), new Among("abl", -1, 3),
+ new Among("I\u00E8r", -1, 4), new Among("i\u00E8r", -1, 4),
+ new Among("eus", -1, 2), new Among("iv", -1, 1)
+ ],
+ a_3 = [
+ new Among("ic", -1, 2), new Among("abil", -1, 1),
+ new Among("iv", -1, 3)
+ ],
+ a_4 = [new Among("iqUe", -1, 1),
+ new Among("atrice", -1, 2), new Among("ance", -1, 1),
+ new Among("ence", -1, 5), new Among("logie", -1, 3),
+ new Among("able", -1, 1), new Among("isme", -1, 1),
+ new Among("euse", -1, 11), new Among("iste", -1, 1),
+ new Among("ive", -1, 8), new Among("if", -1, 8),
+ new Among("usion", -1, 4), new Among("ation", -1, 2),
+ new Among("ution", -1, 4), new Among("ateur", -1, 2),
+ new Among("iqUes", -1, 1), new Among("atrices", -1, 2),
+ new Among("ances", -1, 1), new Among("ences", -1, 5),
+ new Among("logies", -1, 3), new Among("ables", -1, 1),
+ new Among("ismes", -1, 1), new Among("euses", -1, 11),
+ new Among("istes", -1, 1), new Among("ives", -1, 8),
+ new Among("ifs", -1, 8), new Among("usions", -1, 4),
+ new Among("ations", -1, 2), new Among("utions", -1, 4),
+ new Among("ateurs", -1, 2), new Among("ments", -1, 15),
+ new Among("ements", 30, 6), new Among("issements", 31, 12),
+ new Among("it\u00E9s", -1, 7), new Among("ment", -1, 15),
+ new Among("ement", 34, 6), new Among("issement", 35, 12),
+ new Among("amment", 34, 13), new Among("emment", 34, 14),
+ new Among("aux", -1, 10), new Among("eaux", 39, 9),
+ new Among("eux", -1, 1), new Among("it\u00E9", -1, 7)
+ ],
+ a_5 = [
+ new Among("ira", -1, 1), new Among("ie", -1, 1),
+ new Among("isse", -1, 1), new Among("issante", -1, 1),
+ new Among("i", -1, 1), new Among("irai", 4, 1),
+ new Among("ir", -1, 1), new Among("iras", -1, 1),
+ new Among("ies", -1, 1), new Among("\u00EEmes", -1, 1),
+ new Among("isses", -1, 1), new Among("issantes", -1, 1),
+ new Among("\u00EEtes", -1, 1), new Among("is", -1, 1),
+ new Among("irais", 13, 1), new Among("issais", 13, 1),
+ new Among("irions", -1, 1), new Among("issions", -1, 1),
+ new Among("irons", -1, 1), new Among("issons", -1, 1),
+ new Among("issants", -1, 1), new Among("it", -1, 1),
+ new Among("irait", 21, 1), new Among("issait", 21, 1),
+ new Among("issant", -1, 1), new Among("iraIent", -1, 1),
+ new Among("issaIent", -1, 1), new Among("irent", -1, 1),
+ new Among("issent", -1, 1), new Among("iront", -1, 1),
+ new Among("\u00EEt", -1, 1), new Among("iriez", -1, 1),
+ new Among("issiez", -1, 1), new Among("irez", -1, 1),
+ new Among("issez", -1, 1)
+ ],
+ a_6 = [new Among("a", -1, 3),
+ new Among("era", 0, 2), new Among("asse", -1, 3),
+ new Among("ante", -1, 3), new Among("\u00E9e", -1, 2),
+ new Among("ai", -1, 3), new Among("erai", 5, 2),
+ new Among("er", -1, 2), new Among("as", -1, 3),
+ new Among("eras", 8, 2), new Among("\u00E2mes", -1, 3),
+ new Among("asses", -1, 3), new Among("antes", -1, 3),
+ new Among("\u00E2tes", -1, 3), new Among("\u00E9es", -1, 2),
+ new Among("ais", -1, 3), new Among("erais", 15, 2),
+ new Among("ions", -1, 1), new Among("erions", 17, 2),
+ new Among("assions", 17, 3), new Among("erons", -1, 2),
+ new Among("ants", -1, 3), new Among("\u00E9s", -1, 2),
+ new Among("ait", -1, 3), new Among("erait", 23, 2),
+ new Among("ant", -1, 3), new Among("aIent", -1, 3),
+ new Among("eraIent", 26, 2), new Among("\u00E8rent", -1, 2),
+ new Among("assent", -1, 3), new Among("eront", -1, 2),
+ new Among("\u00E2t", -1, 3), new Among("ez", -1, 2),
+ new Among("iez", 32, 2), new Among("eriez", 33, 2),
+ new Among("assiez", 33, 3), new Among("erez", 32, 2),
+ new Among("\u00E9", -1, 2)
+ ],
+ a_7 = [new Among("e", -1, 3),
+ new Among("I\u00E8re", 0, 2), new Among("i\u00E8re", 0, 2),
+ new Among("ion", -1, 1), new Among("Ier", -1, 2),
+ new Among("ier", -1, 2), new Among("\u00EB", -1, 4)
+ ],
+ a_8 = [
+ new Among("ell", -1, -1), new Among("eill", -1, -1),
+ new Among("enn", -1, -1), new Among("onn", -1, -1),
+ new Among("ett", -1, -1)
+ ],
+ g_v = [17, 65, 16, 1, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 128, 130, 103, 8, 5
+ ],
+ g_keep_with_s = [1, 65, 20, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128
+ ],
+ I_p2, I_p1, I_pV, sbp = new SnowballProgram();
+ this.setCurrent = function(word) {
+ sbp.setCurrent(word);
+ };
+ this.getCurrent = function() {
+ return sbp.getCurrent();
+ };
+
+ function habr1(c1, c2, v_1) {
+ if (sbp.eq_s(1, c1)) {
+ sbp.ket = sbp.cursor;
+ if (sbp.in_grouping(g_v, 97, 251)) {
+ sbp.slice_from(c2);
+ sbp.cursor = v_1;
+ return true;
+ }
+ }
+ return false;
+ }
+
+ function habr2(c1, c2, v_1) {
+ if (sbp.eq_s(1, c1)) {
+ sbp.ket = sbp.cursor;
+ sbp.slice_from(c2);
+ sbp.cursor = v_1;
+ return true;
+ }
+ return false;
+ }
+
+ function r_prelude() {
+ var v_1, v_2;
+ while (true) {
+ v_1 = sbp.cursor;
+ if (sbp.in_grouping(g_v, 97, 251)) {
+ sbp.bra = sbp.cursor;
+ v_2 = sbp.cursor;
+ if (habr1("u", "U", v_1))
+ continue;
+ sbp.cursor = v_2;
+ if (habr1("i", "I", v_1))
+ continue;
+ sbp.cursor = v_2;
+ if (habr2("y", "Y", v_1))
+ continue;
+ }
+ sbp.cursor = v_1;
+ sbp.bra = v_1;
+ if (!habr1("y", "Y", v_1)) {
+ sbp.cursor = v_1;
+ if (sbp.eq_s(1, "q")) {
+ sbp.bra = sbp.cursor;
+ if (habr2("u", "U", v_1))
+ continue;
+ }
+ sbp.cursor = v_1;
+ if (v_1 >= sbp.limit)
+ return;
+ sbp.cursor++;
+ }
+ }
+ }
+
+ function habr3() {
+ while (!sbp.in_grouping(g_v, 97, 251)) {
+ if (sbp.cursor >= sbp.limit)
+ return true;
+ sbp.cursor++;
+ }
+ while (!sbp.out_grouping(g_v, 97, 251)) {
+ if (sbp.cursor >= sbp.limit)
+ return true;
+ sbp.cursor++;
+ }
+ return false;
+ }
+
+ function r_mark_regions() {
+ var v_1 = sbp.cursor;
+ I_pV = sbp.limit;
+ I_p1 = I_pV;
+ I_p2 = I_pV;
+ if (sbp.in_grouping(g_v, 97, 251) && sbp.in_grouping(g_v, 97, 251) &&
+ sbp.cursor < sbp.limit)
+ sbp.cursor++;
+ else {
+ sbp.cursor = v_1;
+ if (!sbp.find_among(a_0, 3)) {
+ sbp.cursor = v_1;
+ do {
+ if (sbp.cursor >= sbp.limit) {
+ sbp.cursor = I_pV;
+ break;
+ }
+ sbp.cursor++;
+ } while (!sbp.in_grouping(g_v, 97, 251));
+ }
+ }
+ I_pV = sbp.cursor;
+ sbp.cursor = v_1;
+ if (!habr3()) {
+ I_p1 = sbp.cursor;
+ if (!habr3())
+ I_p2 = sbp.cursor;
+ }
+ }
+
+ function r_postlude() {
+ var among_var, v_1;
+ while (true) {
+ v_1 = sbp.cursor;
+ sbp.bra = v_1;
+ among_var = sbp.find_among(a_1, 4);
+ if (!among_var)
+ break;
+ sbp.ket = sbp.cursor;
+ switch (among_var) {
+ case 1:
+ sbp.slice_from("i");
+ break;
+ case 2:
+ sbp.slice_from("u");
+ break;
+ case 3:
+ sbp.slice_from("y");
+ break;
+ case 4:
+ if (sbp.cursor >= sbp.limit)
+ return;
+ sbp.cursor++;
+ break;
+ }
+ }
+ }
+
+ function r_RV() {
+ return I_pV <= sbp.cursor;
+ }
+
+ function r_R1() {
+ return I_p1 <= sbp.cursor;
+ }
+
+ function r_R2() {
+ return I_p2 <= sbp.cursor;
+ }
+
+ function r_standard_suffix() {
+ var among_var, v_1;
+ sbp.ket = sbp.cursor;
+ among_var = sbp.find_among_b(a_4, 43);
+ if (among_var) {
+ sbp.bra = sbp.cursor;
+ switch (among_var) {
+ case 1:
+ if (!r_R2())
+ return false;
+ sbp.slice_del();
+ break;
+ case 2:
+ if (!r_R2())
+ return false;
+ sbp.slice_del();
+ sbp.ket = sbp.cursor;
+ if (sbp.eq_s_b(2, "ic")) {
+ sbp.bra = sbp.cursor;
+ if (!r_R2())
+ sbp.slice_from("iqU");
+ else
+ sbp.slice_del();
+ }
+ break;
+ case 3:
+ if (!r_R2())
+ return false;
+ sbp.slice_from("log");
+ break;
+ case 4:
+ if (!r_R2())
+ return false;
+ sbp.slice_from("u");
+ break;
+ case 5:
+ if (!r_R2())
+ return false;
+ sbp.slice_from("ent");
+ break;
+ case 6:
+ if (!r_RV())
+ return false;
+ sbp.slice_del();
+ sbp.ket = sbp.cursor;
+ among_var = sbp.find_among_b(a_2, 6);
+ if (among_var) {
+ sbp.bra = sbp.cursor;
+ switch (among_var) {
+ case 1:
+ if (r_R2()) {
+ sbp.slice_del();
+ sbp.ket = sbp.cursor;
+ if (sbp.eq_s_b(2, "at")) {
+ sbp.bra = sbp.cursor;
+ if (r_R2())
+ sbp.slice_del();
+ }
+ }
+ break;
+ case 2:
+ if (r_R2())
+ sbp.slice_del();
+ else if (r_R1())
+ sbp.slice_from("eux");
+ break;
+ case 3:
+ if (r_R2())
+ sbp.slice_del();
+ break;
+ case 4:
+ if (r_RV())
+ sbp.slice_from("i");
+ break;
+ }
+ }
+ break;
+ case 7:
+ if (!r_R2())
+ return false;
+ sbp.slice_del();
+ sbp.ket = sbp.cursor;
+ among_var = sbp.find_among_b(a_3, 3);
+ if (among_var) {
+ sbp.bra = sbp.cursor;
+ switch (among_var) {
+ case 1:
+ if (r_R2())
+ sbp.slice_del();
+ else
+ sbp.slice_from("abl");
+ break;
+ case 2:
+ if (r_R2())
+ sbp.slice_del();
+ else
+ sbp.slice_from("iqU");
+ break;
+ case 3:
+ if (r_R2())
+ sbp.slice_del();
+ break;
+ }
+ }
+ break;
+ case 8:
+ if (!r_R2())
+ return false;
+ sbp.slice_del();
+ sbp.ket = sbp.cursor;
+ if (sbp.eq_s_b(2, "at")) {
+ sbp.bra = sbp.cursor;
+ if (r_R2()) {
+ sbp.slice_del();
+ sbp.ket = sbp.cursor;
+ if (sbp.eq_s_b(2, "ic")) {
+ sbp.bra = sbp.cursor;
+ if (r_R2())
+ sbp.slice_del();
+ else
+ sbp.slice_from("iqU");
+ break;
+ }
+ }
+ }
+ break;
+ case 9:
+ sbp.slice_from("eau");
+ break;
+ case 10:
+ if (!r_R1())
+ return false;
+ sbp.slice_from("al");
+ break;
+ case 11:
+ if (r_R2())
+ sbp.slice_del();
+ else if (!r_R1())
+ return false;
+ else
+ sbp.slice_from("eux");
+ break;
+ case 12:
+ if (!r_R1() || !sbp.out_grouping_b(g_v, 97, 251))
+ return false;
+ sbp.slice_del();
+ break;
+ case 13:
+ if (r_RV())
+ sbp.slice_from("ant");
+ return false;
+ case 14:
+ if (r_RV())
+ sbp.slice_from("ent");
+ return false;
+ case 15:
+ v_1 = sbp.limit - sbp.cursor;
+ if (sbp.in_grouping_b(g_v, 97, 251) && r_RV()) {
+ sbp.cursor = sbp.limit - v_1;
+ sbp.slice_del();
+ }
+ return false;
+ }
+ return true;
+ }
+ return false;
+ }
+
+ function r_i_verb_suffix() {
+ var among_var, v_1;
+ if (sbp.cursor < I_pV)
+ return false;
+ v_1 = sbp.limit_backward;
+ sbp.limit_backward = I_pV;
+ sbp.ket = sbp.cursor;
+ among_var = sbp.find_among_b(a_5, 35);
+ if (!among_var) {
+ sbp.limit_backward = v_1;
+ return false;
+ }
+ sbp.bra = sbp.cursor;
+ if (among_var == 1) {
+ if (!sbp.out_grouping_b(g_v, 97, 251)) {
+ sbp.limit_backward = v_1;
+ return false;
+ }
+ sbp.slice_del();
+ }
+ sbp.limit_backward = v_1;
+ return true;
+ }
+
+ function r_verb_suffix() {
+ var among_var, v_2, v_3;
+ if (sbp.cursor < I_pV)
+ return false;
+ v_2 = sbp.limit_backward;
+ sbp.limit_backward = I_pV;
+ sbp.ket = sbp.cursor;
+ among_var = sbp.find_among_b(a_6, 38);
+ if (!among_var) {
+ sbp.limit_backward = v_2;
+ return false;
+ }
+ sbp.bra = sbp.cursor;
+ switch (among_var) {
+ case 1:
+ if (!r_R2()) {
+ sbp.limit_backward = v_2;
+ return false;
+ }
+ sbp.slice_del();
+ break;
+ case 2:
+ sbp.slice_del();
+ break;
+ case 3:
+ sbp.slice_del();
+ v_3 = sbp.limit - sbp.cursor;
+ sbp.ket = sbp.cursor;
+ if (sbp.eq_s_b(1, "e")) {
+ sbp.bra = sbp.cursor;
+ sbp.slice_del();
+ } else
+ sbp.cursor = sbp.limit - v_3;
+ break;
+ }
+ sbp.limit_backward = v_2;
+ return true;
+ }
+
+ function r_residual_suffix() {
+ var among_var, v_1 = sbp.limit - sbp.cursor,
+ v_2, v_4, v_5;
+ sbp.ket = sbp.cursor;
+ if (sbp.eq_s_b(1, "s")) {
+ sbp.bra = sbp.cursor;
+ v_2 = sbp.limit - sbp.cursor;
+ if (sbp.out_grouping_b(g_keep_with_s, 97, 232)) {
+ sbp.cursor = sbp.limit - v_2;
+ sbp.slice_del();
+ } else
+ sbp.cursor = sbp.limit - v_1;
+ } else
+ sbp.cursor = sbp.limit - v_1;
+ if (sbp.cursor >= I_pV) {
+ v_4 = sbp.limit_backward;
+ sbp.limit_backward = I_pV;
+ sbp.ket = sbp.cursor;
+ among_var = sbp.find_among_b(a_7, 7);
+ if (among_var) {
+ sbp.bra = sbp.cursor;
+ switch (among_var) {
+ case 1:
+ if (r_R2()) {
+ v_5 = sbp.limit - sbp.cursor;
+ if (!sbp.eq_s_b(1, "s")) {
+ sbp.cursor = sbp.limit - v_5;
+ if (!sbp.eq_s_b(1, "t"))
+ break;
+ }
+ sbp.slice_del();
+ }
+ break;
+ case 2:
+ sbp.slice_from("i");
+ break;
+ case 3:
+ sbp.slice_del();
+ break;
+ case 4:
+ if (sbp.eq_s_b(2, "gu"))
+ sbp.slice_del();
+ break;
+ }
+ }
+ sbp.limit_backward = v_4;
+ }
+ }
+
+ function r_un_double() {
+ var v_1 = sbp.limit - sbp.cursor;
+ if (sbp.find_among_b(a_8, 5)) {
+ sbp.cursor = sbp.limit - v_1;
+ sbp.ket = sbp.cursor;
+ if (sbp.cursor > sbp.limit_backward) {
+ sbp.cursor--;
+ sbp.bra = sbp.cursor;
+ sbp.slice_del();
+ }
+ }
+ }
+
+ function r_un_accent() {
+ var v_1, v_2 = 1;
+ while (sbp.out_grouping_b(g_v, 97, 251))
+ v_2--;
+ if (v_2 <= 0) {
+ sbp.ket = sbp.cursor;
+ v_1 = sbp.limit - sbp.cursor;
+ if (!sbp.eq_s_b(1, "\u00E9")) {
+ sbp.cursor = sbp.limit - v_1;
+ if (!sbp.eq_s_b(1, "\u00E8"))
+ return;
+ }
+ sbp.bra = sbp.cursor;
+ sbp.slice_from("e");
+ }
+ }
+
+ function habr5() {
+ if (!r_standard_suffix()) {
+ sbp.cursor = sbp.limit;
+ if (!r_i_verb_suffix()) {
+ sbp.cursor = sbp.limit;
+ if (!r_verb_suffix()) {
+ sbp.cursor = sbp.limit;
+ r_residual_suffix();
+ return;
+ }
+ }
+ }
+ sbp.cursor = sbp.limit;
+ sbp.ket = sbp.cursor;
+ if (sbp.eq_s_b(1, "Y")) {
+ sbp.bra = sbp.cursor;
+ sbp.slice_from("i");
+ } else {
+ sbp.cursor = sbp.limit;
+ if (sbp.eq_s_b(1, "\u00E7")) {
+ sbp.bra = sbp.cursor;
+ sbp.slice_from("c");
+ }
+ }
+ }
+ this.stem = function() {
+ var v_1 = sbp.cursor;
+ r_prelude();
+ sbp.cursor = v_1;
+ r_mark_regions();
+ sbp.limit_backward = v_1;
+ sbp.cursor = sbp.limit;
+ habr5();
+ sbp.cursor = sbp.limit;
+ r_un_double();
+ sbp.cursor = sbp.limit;
+ r_un_accent();
+ sbp.cursor = sbp.limit_backward;
+ r_postlude();
+ return true;
+ }
+ };
+
+ /* and return a function that stems a word for the current locale */
+ return function(token) {
+ // for lunr version 2
+ if (typeof token.update === "function") {
+ return token.update(function(word) {
+ st.setCurrent(word);
+ st.stem();
+ return st.getCurrent();
+ })
+ } else { // for lunr version <= 1
+ st.setCurrent(token);
+ st.stem();
+ return st.getCurrent();
+ }
+ }
+ })();
+
+ lunr.Pipeline.registerFunction(lunr.fr.stemmer, 'stemmer-fr');
+
+ lunr.fr.stopWordFilter = lunr.generateStopWordFilter('ai aie aient aies ait as au aura aurai auraient aurais aurait auras aurez auriez aurions aurons auront aux avaient avais avait avec avez aviez avions avons ayant ayez ayons c ce ceci celà ces cet cette d dans de des du elle en es est et eu eue eues eurent eus eusse eussent eusses eussiez eussions eut eux eûmes eût eûtes furent fus fusse fussent fusses fussiez fussions fut fûmes fût fûtes ici il ils j je l la le les leur leurs lui m ma mais me mes moi mon même n ne nos notre nous on ont ou par pas pour qu que quel quelle quelles quels qui s sa sans se sera serai seraient serais serait seras serez seriez serions serons seront ses soi soient sois soit sommes son sont soyez soyons suis sur t ta te tes toi ton tu un une vos votre vous y à étaient étais était étant étiez étions été étée étées étés êtes'.split(' '));
+
+ lunr.Pipeline.registerFunction(lunr.fr.stopWordFilter, 'stopWordFilter-fr');
+ };
+}))
\ No newline at end of file
diff --git a/venv/lib/python3.11/site-packages/mkdocs/contrib/search/lunr-language/lunr.hu.js b/venv/lib/python3.11/site-packages/mkdocs/contrib/search/lunr-language/lunr.hu.js
new file mode 100644
index 0000000..c52219f
--- /dev/null
+++ b/venv/lib/python3.11/site-packages/mkdocs/contrib/search/lunr-language/lunr.hu.js
@@ -0,0 +1,565 @@
+/*!
+ * Lunr languages, `Hungarian` language
+ * https://github.com/MihaiValentin/lunr-languages
+ *
+ * Copyright 2014, Mihai Valentin
+ * http://www.mozilla.org/MPL/
+ */
+/*!
+ * based on
+ * Snowball JavaScript Library v0.3
+ * http://code.google.com/p/urim/
+ * http://snowball.tartarus.org/
+ *
+ * Copyright 2010, Oleg Mazko
+ * http://www.mozilla.org/MPL/
+ */
+
+/**
+ * export the module via AMD, CommonJS or as a browser global
+ * Export code from https://github.com/umdjs/umd/blob/master/returnExports.js
+ */
+;
+(function(root, factory) {
+ if (typeof define === 'function' && define.amd) {
+ // AMD. Register as an anonymous module.
+ define(factory)
+ } else if (typeof exports === 'object') {
+ /**
+ * Node. Does not work with strict CommonJS, but
+ * only CommonJS-like environments that support module.exports,
+ * like Node.
+ */
+ module.exports = factory()
+ } else {
+ // Browser globals (root is window)
+ factory()(root.lunr);
+ }
+}(this, function() {
+ /**
+ * Just return a value to define the module export.
+ * This example returns an object, but the module
+ * can return a function as the exported value.
+ */
+ return function(lunr) {
+ /* throw error if lunr is not yet included */
+ if ('undefined' === typeof lunr) {
+ throw new Error('Lunr is not present. Please include / require Lunr before this script.');
+ }
+
+ /* throw error if lunr stemmer support is not yet included */
+ if ('undefined' === typeof lunr.stemmerSupport) {
+ throw new Error('Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.');
+ }
+
+ /* register specific locale function */
+ lunr.hu = function() {
+ this.pipeline.reset();
+ this.pipeline.add(
+ lunr.hu.trimmer,
+ lunr.hu.stopWordFilter,
+ lunr.hu.stemmer
+ );
+
+ // for lunr version 2
+ // this is necessary so that every searched word is also stemmed before
+ // in lunr <= 1 this is not needed, as it is done using the normal pipeline
+ if (this.searchPipeline) {
+ this.searchPipeline.reset();
+ this.searchPipeline.add(lunr.hu.stemmer)
+ }
+ };
+
+ /* lunr trimmer function */
+ lunr.hu.wordCharacters = "A-Za-z\xAA\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02B8\u02E0-\u02E4\u1D00-\u1D25\u1D2C-\u1D5C\u1D62-\u1D65\u1D6B-\u1D77\u1D79-\u1DBE\u1E00-\u1EFF\u2071\u207F\u2090-\u209C\u212A\u212B\u2132\u214E\u2160-\u2188\u2C60-\u2C7F\uA722-\uA787\uA78B-\uA7AD\uA7B0-\uA7B7\uA7F7-\uA7FF\uAB30-\uAB5A\uAB5C-\uAB64\uFB00-\uFB06\uFF21-\uFF3A\uFF41-\uFF5A";
+ lunr.hu.trimmer = lunr.trimmerSupport.generateTrimmer(lunr.hu.wordCharacters);
+
+ lunr.Pipeline.registerFunction(lunr.hu.trimmer, 'trimmer-hu');
+
+ /* lunr stemmer function */
+ lunr.hu.stemmer = (function() {
+ /* create the wrapped stemmer object */
+ var Among = lunr.stemmerSupport.Among,
+ SnowballProgram = lunr.stemmerSupport.SnowballProgram,
+ st = new function HungarianStemmer() {
+ var a_0 = [new Among("cs", -1, -1), new Among("dzs", -1, -1),
+ new Among("gy", -1, -1), new Among("ly", -1, -1),
+ new Among("ny", -1, -1), new Among("sz", -1, -1),
+ new Among("ty", -1, -1), new Among("zs", -1, -1)
+ ],
+ a_1 = [
+ new Among("\u00E1", -1, 1), new Among("\u00E9", -1, 2)
+ ],
+ a_2 = [
+ new Among("bb", -1, -1), new Among("cc", -1, -1),
+ new Among("dd", -1, -1), new Among("ff", -1, -1),
+ new Among("gg", -1, -1), new Among("jj", -1, -1),
+ new Among("kk", -1, -1), new Among("ll", -1, -1),
+ new Among("mm", -1, -1), new Among("nn", -1, -1),
+ new Among("pp", -1, -1), new Among("rr", -1, -1),
+ new Among("ccs", -1, -1), new Among("ss", -1, -1),
+ new Among("zzs", -1, -1), new Among("tt", -1, -1),
+ new Among("vv", -1, -1), new Among("ggy", -1, -1),
+ new Among("lly", -1, -1), new Among("nny", -1, -1),
+ new Among("tty", -1, -1), new Among("ssz", -1, -1),
+ new Among("zz", -1, -1)
+ ],
+ a_3 = [new Among("al", -1, 1),
+ new Among("el", -1, 2)
+ ],
+ a_4 = [new Among("ba", -1, -1),
+ new Among("ra", -1, -1), new Among("be", -1, -1),
+ new Among("re", -1, -1), new Among("ig", -1, -1),
+ new Among("nak", -1, -1), new Among("nek", -1, -1),
+ new Among("val", -1, -1), new Among("vel", -1, -1),
+ new Among("ul", -1, -1), new Among("n\u00E1l", -1, -1),
+ new Among("n\u00E9l", -1, -1), new Among("b\u00F3l", -1, -1),
+ new Among("r\u00F3l", -1, -1), new Among("t\u00F3l", -1, -1),
+ new Among("b\u00F5l", -1, -1), new Among("r\u00F5l", -1, -1),
+ new Among("t\u00F5l", -1, -1), new Among("\u00FCl", -1, -1),
+ new Among("n", -1, -1), new Among("an", 19, -1),
+ new Among("ban", 20, -1), new Among("en", 19, -1),
+ new Among("ben", 22, -1), new Among("k\u00E9ppen", 22, -1),
+ new Among("on", 19, -1), new Among("\u00F6n", 19, -1),
+ new Among("k\u00E9pp", -1, -1), new Among("kor", -1, -1),
+ new Among("t", -1, -1), new Among("at", 29, -1),
+ new Among("et", 29, -1), new Among("k\u00E9nt", 29, -1),
+ new Among("ank\u00E9nt", 32, -1), new Among("enk\u00E9nt", 32, -1),
+ new Among("onk\u00E9nt", 32, -1), new Among("ot", 29, -1),
+ new Among("\u00E9rt", 29, -1), new Among("\u00F6t", 29, -1),
+ new Among("hez", -1, -1), new Among("hoz", -1, -1),
+ new Among("h\u00F6z", -1, -1), new Among("v\u00E1", -1, -1),
+ new Among("v\u00E9", -1, -1)
+ ],
+ a_5 = [new Among("\u00E1n", -1, 2),
+ new Among("\u00E9n", -1, 1), new Among("\u00E1nk\u00E9nt", -1, 3)
+ ],
+ a_6 = [
+ new Among("stul", -1, 2), new Among("astul", 0, 1),
+ new Among("\u00E1stul", 0, 3), new Among("st\u00FCl", -1, 2),
+ new Among("est\u00FCl", 3, 1), new Among("\u00E9st\u00FCl", 3, 4)
+ ],
+ a_7 = [
+ new Among("\u00E1", -1, 1), new Among("\u00E9", -1, 2)
+ ],
+ a_8 = [
+ new Among("k", -1, 7), new Among("ak", 0, 4),
+ new Among("ek", 0, 6), new Among("ok", 0, 5),
+ new Among("\u00E1k", 0, 1), new Among("\u00E9k", 0, 2),
+ new Among("\u00F6k", 0, 3)
+ ],
+ a_9 = [new Among("\u00E9i", -1, 7),
+ new Among("\u00E1\u00E9i", 0, 6), new Among("\u00E9\u00E9i", 0, 5),
+ new Among("\u00E9", -1, 9), new Among("k\u00E9", 3, 4),
+ new Among("ak\u00E9", 4, 1), new Among("ek\u00E9", 4, 1),
+ new Among("ok\u00E9", 4, 1), new Among("\u00E1k\u00E9", 4, 3),
+ new Among("\u00E9k\u00E9", 4, 2), new Among("\u00F6k\u00E9", 4, 1),
+ new Among("\u00E9\u00E9", 3, 8)
+ ],
+ a_10 = [new Among("a", -1, 18),
+ new Among("ja", 0, 17), new Among("d", -1, 16),
+ new Among("ad", 2, 13), new Among("ed", 2, 13),
+ new Among("od", 2, 13), new Among("\u00E1d", 2, 14),
+ new Among("\u00E9d", 2, 15), new Among("\u00F6d", 2, 13),
+ new Among("e", -1, 18), new Among("je", 9, 17),
+ new Among("nk", -1, 4), new Among("unk", 11, 1),
+ new Among("\u00E1nk", 11, 2), new Among("\u00E9nk", 11, 3),
+ new Among("\u00FCnk", 11, 1), new Among("uk", -1, 8),
+ new Among("juk", 16, 7), new Among("\u00E1juk", 17, 5),
+ new Among("\u00FCk", -1, 8), new Among("j\u00FCk", 19, 7),
+ new Among("\u00E9j\u00FCk", 20, 6), new Among("m", -1, 12),
+ new Among("am", 22, 9), new Among("em", 22, 9),
+ new Among("om", 22, 9), new Among("\u00E1m", 22, 10),
+ new Among("\u00E9m", 22, 11), new Among("o", -1, 18),
+ new Among("\u00E1", -1, 19), new Among("\u00E9", -1, 20)
+ ],
+ a_11 = [
+ new Among("id", -1, 10), new Among("aid", 0, 9),
+ new Among("jaid", 1, 6), new Among("eid", 0, 9),
+ new Among("jeid", 3, 6), new Among("\u00E1id", 0, 7),
+ new Among("\u00E9id", 0, 8), new Among("i", -1, 15),
+ new Among("ai", 7, 14), new Among("jai", 8, 11),
+ new Among("ei", 7, 14), new Among("jei", 10, 11),
+ new Among("\u00E1i", 7, 12), new Among("\u00E9i", 7, 13),
+ new Among("itek", -1, 24), new Among("eitek", 14, 21),
+ new Among("jeitek", 15, 20), new Among("\u00E9itek", 14, 23),
+ new Among("ik", -1, 29), new Among("aik", 18, 26),
+ new Among("jaik", 19, 25), new Among("eik", 18, 26),
+ new Among("jeik", 21, 25), new Among("\u00E1ik", 18, 27),
+ new Among("\u00E9ik", 18, 28), new Among("ink", -1, 20),
+ new Among("aink", 25, 17), new Among("jaink", 26, 16),
+ new Among("eink", 25, 17), new Among("jeink", 28, 16),
+ new Among("\u00E1ink", 25, 18), new Among("\u00E9ink", 25, 19),
+ new Among("aitok", -1, 21), new Among("jaitok", 32, 20),
+ new Among("\u00E1itok", -1, 22), new Among("im", -1, 5),
+ new Among("aim", 35, 4), new Among("jaim", 36, 1),
+ new Among("eim", 35, 4), new Among("jeim", 38, 1),
+ new Among("\u00E1im", 35, 2), new Among("\u00E9im", 35, 3)
+ ],
+ g_v = [
+ 17, 65, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 17, 52, 14
+ ],
+ I_p1, sbp = new SnowballProgram();
+ this.setCurrent = function(word) {
+ sbp.setCurrent(word);
+ };
+ this.getCurrent = function() {
+ return sbp.getCurrent();
+ };
+
+ function r_mark_regions() {
+ var v_1 = sbp.cursor,
+ v_2;
+ I_p1 = sbp.limit;
+ if (sbp.in_grouping(g_v, 97, 252)) {
+ while (true) {
+ v_2 = sbp.cursor;
+ if (sbp.out_grouping(g_v, 97, 252)) {
+ sbp.cursor = v_2;
+ if (!sbp.find_among(a_0, 8)) {
+ sbp.cursor = v_2;
+ if (v_2 < sbp.limit)
+ sbp.cursor++;
+ }
+ I_p1 = sbp.cursor;
+ return;
+ }
+ sbp.cursor = v_2;
+ if (v_2 >= sbp.limit) {
+ I_p1 = v_2;
+ return;
+ }
+ sbp.cursor++;
+ }
+ }
+ sbp.cursor = v_1;
+ if (sbp.out_grouping(g_v, 97, 252)) {
+ while (!sbp.in_grouping(g_v, 97, 252)) {
+ if (sbp.cursor >= sbp.limit)
+ return;
+ sbp.cursor++;
+ }
+ I_p1 = sbp.cursor;
+ }
+ }
+
+ function r_R1() {
+ return I_p1 <= sbp.cursor;
+ }
+
+ function r_v_ending() {
+ var among_var;
+ sbp.ket = sbp.cursor;
+ among_var = sbp.find_among_b(a_1, 2);
+ if (among_var) {
+ sbp.bra = sbp.cursor;
+ if (r_R1()) {
+ switch (among_var) {
+ case 1:
+ sbp.slice_from("a");
+ break;
+ case 2:
+ sbp.slice_from("e");
+ break;
+ }
+ }
+ }
+ }
+
+ function r_double() {
+ var v_1 = sbp.limit - sbp.cursor;
+ if (!sbp.find_among_b(a_2, 23))
+ return false;
+ sbp.cursor = sbp.limit - v_1;
+ return true;
+ }
+
+ function r_undouble() {
+ if (sbp.cursor > sbp.limit_backward) {
+ sbp.cursor--;
+ sbp.ket = sbp.cursor;
+ var c = sbp.cursor - 1;
+ if (sbp.limit_backward <= c && c <= sbp.limit) {
+ sbp.cursor = c;
+ sbp.bra = c;
+ sbp.slice_del();
+ }
+ }
+ }
+
+ function r_instrum() {
+ var among_var;
+ sbp.ket = sbp.cursor;
+ among_var = sbp.find_among_b(a_3, 2);
+ if (among_var) {
+ sbp.bra = sbp.cursor;
+ if (r_R1()) {
+ if (among_var == 1 || among_var == 2)
+ if (!r_double())
+ return;
+ sbp.slice_del();
+ r_undouble();
+ }
+ }
+ }
+
+ function r_case() {
+ sbp.ket = sbp.cursor;
+ if (sbp.find_among_b(a_4, 44)) {
+ sbp.bra = sbp.cursor;
+ if (r_R1()) {
+ sbp.slice_del();
+ r_v_ending();
+ }
+ }
+ }
+
+ function r_case_special() {
+ var among_var;
+ sbp.ket = sbp.cursor;
+ among_var = sbp.find_among_b(a_5, 3);
+ if (among_var) {
+ sbp.bra = sbp.cursor;
+ if (r_R1()) {
+ switch (among_var) {
+ case 1:
+ sbp.slice_from("e");
+ break;
+ case 2:
+ case 3:
+ sbp.slice_from("a");
+ break;
+ }
+ }
+ }
+ }
+
+ function r_case_other() {
+ var among_var;
+ sbp.ket = sbp.cursor;
+ among_var = sbp.find_among_b(a_6, 6);
+ if (among_var) {
+ sbp.bra = sbp.cursor;
+ if (r_R1()) {
+ switch (among_var) {
+ case 1:
+ case 2:
+ sbp.slice_del();
+ break;
+ case 3:
+ sbp.slice_from("a");
+ break;
+ case 4:
+ sbp.slice_from("e");
+ break;
+ }
+ }
+ }
+ }
+
+ function r_factive() {
+ var among_var;
+ sbp.ket = sbp.cursor;
+ among_var = sbp.find_among_b(a_7, 2);
+ if (among_var) {
+ sbp.bra = sbp.cursor;
+ if (r_R1()) {
+ if (among_var == 1 || among_var == 2)
+ if (!r_double())
+ return;
+ sbp.slice_del();
+ r_undouble()
+ }
+ }
+ }
+
+ function r_plural() {
+ var among_var;
+ sbp.ket = sbp.cursor;
+ among_var = sbp.find_among_b(a_8, 7);
+ if (among_var) {
+ sbp.bra = sbp.cursor;
+ if (r_R1()) {
+ switch (among_var) {
+ case 1:
+ sbp.slice_from("a");
+ break;
+ case 2:
+ sbp.slice_from("e");
+ break;
+ case 3:
+ case 4:
+ case 5:
+ case 6:
+ case 7:
+ sbp.slice_del();
+ break;
+ }
+ }
+ }
+ }
+
+ function r_owned() {
+ var among_var;
+ sbp.ket = sbp.cursor;
+ among_var = sbp.find_among_b(a_9, 12);
+ if (among_var) {
+ sbp.bra = sbp.cursor;
+ if (r_R1()) {
+ switch (among_var) {
+ case 1:
+ case 4:
+ case 7:
+ case 9:
+ sbp.slice_del();
+ break;
+ case 2:
+ case 5:
+ case 8:
+ sbp.slice_from("e");
+ break;
+ case 3:
+ case 6:
+ sbp.slice_from("a");
+ break;
+ }
+ }
+ }
+ }
+
+ function r_sing_owner() {
+ var among_var;
+ sbp.ket = sbp.cursor;
+ among_var = sbp.find_among_b(a_10, 31);
+ if (among_var) {
+ sbp.bra = sbp.cursor;
+ if (r_R1()) {
+ switch (among_var) {
+ case 1:
+ case 4:
+ case 7:
+ case 8:
+ case 9:
+ case 12:
+ case 13:
+ case 16:
+ case 17:
+ case 18:
+ sbp.slice_del();
+ break;
+ case 2:
+ case 5:
+ case 10:
+ case 14:
+ case 19:
+ sbp.slice_from("a");
+ break;
+ case 3:
+ case 6:
+ case 11:
+ case 15:
+ case 20:
+ sbp.slice_from("e");
+ break;
+ }
+ }
+ }
+ }
+
+ function r_plur_owner() {
+ var among_var;
+ sbp.ket = sbp.cursor;
+ among_var = sbp.find_among_b(a_11, 42);
+ if (among_var) {
+ sbp.bra = sbp.cursor;
+ if (r_R1()) {
+ switch (among_var) {
+ case 1:
+ case 4:
+ case 5:
+ case 6:
+ case 9:
+ case 10:
+ case 11:
+ case 14:
+ case 15:
+ case 16:
+ case 17:
+ case 20:
+ case 21:
+ case 24:
+ case 25:
+ case 26:
+ case 29:
+ sbp.slice_del();
+ break;
+ case 2:
+ case 7:
+ case 12:
+ case 18:
+ case 22:
+ case 27:
+ sbp.slice_from("a");
+ break;
+ case 3:
+ case 8:
+ case 13:
+ case 19:
+ case 23:
+ case 28:
+ sbp.slice_from("e");
+ break;
+ }
+ }
+ }
+ }
+ this.stem = function() {
+ var v_1 = sbp.cursor;
+ r_mark_regions();
+ sbp.limit_backward = v_1;
+ sbp.cursor = sbp.limit;
+ r_instrum();
+ sbp.cursor = sbp.limit;
+ r_case();
+ sbp.cursor = sbp.limit;
+ r_case_special();
+ sbp.cursor = sbp.limit;
+ r_case_other();
+ sbp.cursor = sbp.limit;
+ r_factive();
+ sbp.cursor = sbp.limit;
+ r_owned();
+ sbp.cursor = sbp.limit;
+ r_sing_owner();
+ sbp.cursor = sbp.limit;
+ r_plur_owner();
+ sbp.cursor = sbp.limit;
+ r_plural();
+ return true;
+ }
+ };
+
+ /* and return a function that stems a word for the current locale */
+ return function(token) {
+ // for lunr version 2
+ if (typeof token.update === "function") {
+ return token.update(function(word) {
+ st.setCurrent(word);
+ st.stem();
+ return st.getCurrent();
+ })
+ } else { // for lunr version <= 1
+ st.setCurrent(token);
+ st.stem();
+ return st.getCurrent();
+ }
+ }
+ })();
+
+ lunr.Pipeline.registerFunction(lunr.hu.stemmer, 'stemmer-hu');
+
+ lunr.hu.stopWordFilter = lunr.generateStopWordFilter('a abban ahhoz ahogy ahol aki akik akkor alatt amely amelyek amelyekben amelyeket amelyet amelynek ami amikor amit amolyan amíg annak arra arról az azok azon azonban azt aztán azután azzal azért be belül benne bár cikk cikkek cikkeket csak de e ebben eddig egy egyes egyetlen egyik egyre egyéb egész ehhez ekkor el ellen elsõ elég elõ elõször elõtt emilyen ennek erre ez ezek ezen ezt ezzel ezért fel felé hanem hiszen hogy hogyan igen ill ill. illetve ilyen ilyenkor ismét ison itt jobban jó jól kell kellett keressünk keresztül ki kívül között közül legalább legyen lehet lehetett lenne lenni lesz lett maga magát majd majd meg mellett mely melyek mert mi mikor milyen minden mindenki mindent mindig mint mintha mit mivel miért most már más másik még míg nagy nagyobb nagyon ne nekem neki nem nincs néha néhány nélkül olyan ott pedig persze rá s saját sem semmi sok sokat sokkal szemben szerint szinte számára talán tehát teljes tovább továbbá több ugyanis utolsó után utána vagy vagyis vagyok valaki valami valamint való van vannak vele vissza viszont volna volt voltak voltam voltunk által általában át én éppen és így õ õk õket össze úgy új újabb újra'.split(' '));
+
+ lunr.Pipeline.registerFunction(lunr.hu.stopWordFilter, 'stopWordFilter-hu');
+ };
+}))
\ No newline at end of file
diff --git a/venv/lib/python3.11/site-packages/mkdocs/contrib/search/lunr-language/lunr.it.js b/venv/lib/python3.11/site-packages/mkdocs/contrib/search/lunr-language/lunr.it.js
new file mode 100644
index 0000000..676863b
--- /dev/null
+++ b/venv/lib/python3.11/site-packages/mkdocs/contrib/search/lunr-language/lunr.it.js
@@ -0,0 +1,617 @@
+/*!
+ * Lunr languages, `Italian` language
+ * https://github.com/MihaiValentin/lunr-languages
+ *
+ * Copyright 2014, Mihai Valentin
+ * http://www.mozilla.org/MPL/
+ */
+/*!
+ * based on
+ * Snowball JavaScript Library v0.3
+ * http://code.google.com/p/urim/
+ * http://snowball.tartarus.org/
+ *
+ * Copyright 2010, Oleg Mazko
+ * http://www.mozilla.org/MPL/
+ */
+
+/**
+ * export the module via AMD, CommonJS or as a browser global
+ * Export code from https://github.com/umdjs/umd/blob/master/returnExports.js
+ */
+;
+(function(root, factory) {
+ if (typeof define === 'function' && define.amd) {
+ // AMD. Register as an anonymous module.
+ define(factory)
+ } else if (typeof exports === 'object') {
+ /**
+ * Node. Does not work with strict CommonJS, but
+ * only CommonJS-like environments that support module.exports,
+ * like Node.
+ */
+ module.exports = factory()
+ } else {
+ // Browser globals (root is window)
+ factory()(root.lunr);
+ }
+}(this, function() {
+ /**
+ * Just return a value to define the module export.
+ * This example returns an object, but the module
+ * can return a function as the exported value.
+ */
+ return function(lunr) {
+ /* throw error if lunr is not yet included */
+ if ('undefined' === typeof lunr) {
+ throw new Error('Lunr is not present. Please include / require Lunr before this script.');
+ }
+
+ /* throw error if lunr stemmer support is not yet included */
+ if ('undefined' === typeof lunr.stemmerSupport) {
+ throw new Error('Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.');
+ }
+
+ /* register specific locale function */
+ lunr.it = function() {
+ this.pipeline.reset();
+ this.pipeline.add(
+ lunr.it.trimmer,
+ lunr.it.stopWordFilter,
+ lunr.it.stemmer
+ );
+
+ // for lunr version 2
+ // this is necessary so that every searched word is also stemmed before
+ // in lunr <= 1 this is not needed, as it is done using the normal pipeline
+ if (this.searchPipeline) {
+ this.searchPipeline.reset();
+ this.searchPipeline.add(lunr.it.stemmer)
+ }
+ };
+
+ /* lunr trimmer function */
+ lunr.it.wordCharacters = "A-Za-z\xAA\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02B8\u02E0-\u02E4\u1D00-\u1D25\u1D2C-\u1D5C\u1D62-\u1D65\u1D6B-\u1D77\u1D79-\u1DBE\u1E00-\u1EFF\u2071\u207F\u2090-\u209C\u212A\u212B\u2132\u214E\u2160-\u2188\u2C60-\u2C7F\uA722-\uA787\uA78B-\uA7AD\uA7B0-\uA7B7\uA7F7-\uA7FF\uAB30-\uAB5A\uAB5C-\uAB64\uFB00-\uFB06\uFF21-\uFF3A\uFF41-\uFF5A";
+ lunr.it.trimmer = lunr.trimmerSupport.generateTrimmer(lunr.it.wordCharacters);
+
+ lunr.Pipeline.registerFunction(lunr.it.trimmer, 'trimmer-it');
+
+ /* lunr stemmer function */
+ lunr.it.stemmer = (function() {
+ /* create the wrapped stemmer object */
+ var Among = lunr.stemmerSupport.Among,
+ SnowballProgram = lunr.stemmerSupport.SnowballProgram,
+ st = new function ItalianStemmer() {
+ var a_0 = [new Among("", -1, 7), new Among("qu", 0, 6),
+ new Among("\u00E1", 0, 1), new Among("\u00E9", 0, 2),
+ new Among("\u00ED", 0, 3), new Among("\u00F3", 0, 4),
+ new Among("\u00FA", 0, 5)
+ ],
+ a_1 = [new Among("", -1, 3),
+ new Among("I", 0, 1), new Among("U", 0, 2)
+ ],
+ a_2 = [
+ new Among("la", -1, -1), new Among("cela", 0, -1),
+ new Among("gliela", 0, -1), new Among("mela", 0, -1),
+ new Among("tela", 0, -1), new Among("vela", 0, -1),
+ new Among("le", -1, -1), new Among("cele", 6, -1),
+ new Among("gliele", 6, -1), new Among("mele", 6, -1),
+ new Among("tele", 6, -1), new Among("vele", 6, -1),
+ new Among("ne", -1, -1), new Among("cene", 12, -1),
+ new Among("gliene", 12, -1), new Among("mene", 12, -1),
+ new Among("sene", 12, -1), new Among("tene", 12, -1),
+ new Among("vene", 12, -1), new Among("ci", -1, -1),
+ new Among("li", -1, -1), new Among("celi", 20, -1),
+ new Among("glieli", 20, -1), new Among("meli", 20, -1),
+ new Among("teli", 20, -1), new Among("veli", 20, -1),
+ new Among("gli", 20, -1), new Among("mi", -1, -1),
+ new Among("si", -1, -1), new Among("ti", -1, -1),
+ new Among("vi", -1, -1), new Among("lo", -1, -1),
+ new Among("celo", 31, -1), new Among("glielo", 31, -1),
+ new Among("melo", 31, -1), new Among("telo", 31, -1),
+ new Among("velo", 31, -1)
+ ],
+ a_3 = [new Among("ando", -1, 1),
+ new Among("endo", -1, 1), new Among("ar", -1, 2),
+ new Among("er", -1, 2), new Among("ir", -1, 2)
+ ],
+ a_4 = [
+ new Among("ic", -1, -1), new Among("abil", -1, -1),
+ new Among("os", -1, -1), new Among("iv", -1, 1)
+ ],
+ a_5 = [
+ new Among("ic", -1, 1), new Among("abil", -1, 1),
+ new Among("iv", -1, 1)
+ ],
+ a_6 = [new Among("ica", -1, 1),
+ new Among("logia", -1, 3), new Among("osa", -1, 1),
+ new Among("ista", -1, 1), new Among("iva", -1, 9),
+ new Among("anza", -1, 1), new Among("enza", -1, 5),
+ new Among("ice", -1, 1), new Among("atrice", 7, 1),
+ new Among("iche", -1, 1), new Among("logie", -1, 3),
+ new Among("abile", -1, 1), new Among("ibile", -1, 1),
+ new Among("usione", -1, 4), new Among("azione", -1, 2),
+ new Among("uzione", -1, 4), new Among("atore", -1, 2),
+ new Among("ose", -1, 1), new Among("ante", -1, 1),
+ new Among("mente", -1, 1), new Among("amente", 19, 7),
+ new Among("iste", -1, 1), new Among("ive", -1, 9),
+ new Among("anze", -1, 1), new Among("enze", -1, 5),
+ new Among("ici", -1, 1), new Among("atrici", 25, 1),
+ new Among("ichi", -1, 1), new Among("abili", -1, 1),
+ new Among("ibili", -1, 1), new Among("ismi", -1, 1),
+ new Among("usioni", -1, 4), new Among("azioni", -1, 2),
+ new Among("uzioni", -1, 4), new Among("atori", -1, 2),
+ new Among("osi", -1, 1), new Among("anti", -1, 1),
+ new Among("amenti", -1, 6), new Among("imenti", -1, 6),
+ new Among("isti", -1, 1), new Among("ivi", -1, 9),
+ new Among("ico", -1, 1), new Among("ismo", -1, 1),
+ new Among("oso", -1, 1), new Among("amento", -1, 6),
+ new Among("imento", -1, 6), new Among("ivo", -1, 9),
+ new Among("it\u00E0", -1, 8), new Among("ist\u00E0", -1, 1),
+ new Among("ist\u00E8", -1, 1), new Among("ist\u00EC", -1, 1)
+ ],
+ a_7 = [
+ new Among("isca", -1, 1), new Among("enda", -1, 1),
+ new Among("ata", -1, 1), new Among("ita", -1, 1),
+ new Among("uta", -1, 1), new Among("ava", -1, 1),
+ new Among("eva", -1, 1), new Among("iva", -1, 1),
+ new Among("erebbe", -1, 1), new Among("irebbe", -1, 1),
+ new Among("isce", -1, 1), new Among("ende", -1, 1),
+ new Among("are", -1, 1), new Among("ere", -1, 1),
+ new Among("ire", -1, 1), new Among("asse", -1, 1),
+ new Among("ate", -1, 1), new Among("avate", 16, 1),
+ new Among("evate", 16, 1), new Among("ivate", 16, 1),
+ new Among("ete", -1, 1), new Among("erete", 20, 1),
+ new Among("irete", 20, 1), new Among("ite", -1, 1),
+ new Among("ereste", -1, 1), new Among("ireste", -1, 1),
+ new Among("ute", -1, 1), new Among("erai", -1, 1),
+ new Among("irai", -1, 1), new Among("isci", -1, 1),
+ new Among("endi", -1, 1), new Among("erei", -1, 1),
+ new Among("irei", -1, 1), new Among("assi", -1, 1),
+ new Among("ati", -1, 1), new Among("iti", -1, 1),
+ new Among("eresti", -1, 1), new Among("iresti", -1, 1),
+ new Among("uti", -1, 1), new Among("avi", -1, 1),
+ new Among("evi", -1, 1), new Among("ivi", -1, 1),
+ new Among("isco", -1, 1), new Among("ando", -1, 1),
+ new Among("endo", -1, 1), new Among("Yamo", -1, 1),
+ new Among("iamo", -1, 1), new Among("avamo", -1, 1),
+ new Among("evamo", -1, 1), new Among("ivamo", -1, 1),
+ new Among("eremo", -1, 1), new Among("iremo", -1, 1),
+ new Among("assimo", -1, 1), new Among("ammo", -1, 1),
+ new Among("emmo", -1, 1), new Among("eremmo", 54, 1),
+ new Among("iremmo", 54, 1), new Among("immo", -1, 1),
+ new Among("ano", -1, 1), new Among("iscano", 58, 1),
+ new Among("avano", 58, 1), new Among("evano", 58, 1),
+ new Among("ivano", 58, 1), new Among("eranno", -1, 1),
+ new Among("iranno", -1, 1), new Among("ono", -1, 1),
+ new Among("iscono", 65, 1), new Among("arono", 65, 1),
+ new Among("erono", 65, 1), new Among("irono", 65, 1),
+ new Among("erebbero", -1, 1), new Among("irebbero", -1, 1),
+ new Among("assero", -1, 1), new Among("essero", -1, 1),
+ new Among("issero", -1, 1), new Among("ato", -1, 1),
+ new Among("ito", -1, 1), new Among("uto", -1, 1),
+ new Among("avo", -1, 1), new Among("evo", -1, 1),
+ new Among("ivo", -1, 1), new Among("ar", -1, 1),
+ new Among("ir", -1, 1), new Among("er\u00E0", -1, 1),
+ new Among("ir\u00E0", -1, 1), new Among("er\u00F2", -1, 1),
+ new Among("ir\u00F2", -1, 1)
+ ],
+ g_v = [17, 65, 16, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 128, 128, 8, 2, 1
+ ],
+ g_AEIO = [17, 65, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 8, 2
+ ],
+ g_CG = [17],
+ I_p2, I_p1, I_pV, sbp = new SnowballProgram();
+ this.setCurrent = function(word) {
+ sbp.setCurrent(word);
+ };
+ this.getCurrent = function() {
+ return sbp.getCurrent();
+ };
+
+ function habr1(c1, c2, v_1) {
+ if (sbp.eq_s(1, c1)) {
+ sbp.ket = sbp.cursor;
+ if (sbp.in_grouping(g_v, 97, 249)) {
+ sbp.slice_from(c2);
+ sbp.cursor = v_1;
+ return true;
+ }
+ }
+ return false;
+ }
+
+ function r_prelude() {
+ var among_var, v_1 = sbp.cursor,
+ v_2, v_3, v_4;
+ while (true) {
+ sbp.bra = sbp.cursor;
+ among_var = sbp.find_among(a_0, 7);
+ if (among_var) {
+ sbp.ket = sbp.cursor;
+ switch (among_var) {
+ case 1:
+ sbp.slice_from("\u00E0");
+ continue;
+ case 2:
+ sbp.slice_from("\u00E8");
+ continue;
+ case 3:
+ sbp.slice_from("\u00EC");
+ continue;
+ case 4:
+ sbp.slice_from("\u00F2");
+ continue;
+ case 5:
+ sbp.slice_from("\u00F9");
+ continue;
+ case 6:
+ sbp.slice_from("qU");
+ continue;
+ case 7:
+ if (sbp.cursor >= sbp.limit)
+ break;
+ sbp.cursor++;
+ continue;
+ }
+ }
+ break;
+ }
+ sbp.cursor = v_1;
+ while (true) {
+ v_2 = sbp.cursor;
+ while (true) {
+ v_3 = sbp.cursor;
+ if (sbp.in_grouping(g_v, 97, 249)) {
+ sbp.bra = sbp.cursor;
+ v_4 = sbp.cursor;
+ if (habr1("u", "U", v_3))
+ break;
+ sbp.cursor = v_4;
+ if (habr1("i", "I", v_3))
+ break;
+ }
+ sbp.cursor = v_3;
+ if (sbp.cursor >= sbp.limit) {
+ sbp.cursor = v_2;
+ return;
+ }
+ sbp.cursor++;
+ }
+ }
+ }
+
+ function habr2(v_1) {
+ sbp.cursor = v_1;
+ if (!sbp.in_grouping(g_v, 97, 249))
+ return false;
+ while (!sbp.out_grouping(g_v, 97, 249)) {
+ if (sbp.cursor >= sbp.limit)
+ return false;
+ sbp.cursor++;
+ }
+ return true;
+ }
+
+ function habr3() {
+ if (sbp.in_grouping(g_v, 97, 249)) {
+ var v_1 = sbp.cursor;
+ if (sbp.out_grouping(g_v, 97, 249)) {
+ while (!sbp.in_grouping(g_v, 97, 249)) {
+ if (sbp.cursor >= sbp.limit)
+ return habr2(v_1);
+ sbp.cursor++;
+ }
+ return true;
+ }
+ return habr2(v_1);
+ }
+ return false;
+ }
+
+ function habr4() {
+ var v_1 = sbp.cursor,
+ v_2;
+ if (!habr3()) {
+ sbp.cursor = v_1;
+ if (!sbp.out_grouping(g_v, 97, 249))
+ return;
+ v_2 = sbp.cursor;
+ if (sbp.out_grouping(g_v, 97, 249)) {
+ while (!sbp.in_grouping(g_v, 97, 249)) {
+ if (sbp.cursor >= sbp.limit) {
+ sbp.cursor = v_2;
+ if (sbp.in_grouping(g_v, 97, 249) &&
+ sbp.cursor < sbp.limit)
+ sbp.cursor++;
+ return;
+ }
+ sbp.cursor++;
+ }
+ I_pV = sbp.cursor;
+ return;
+ }
+ sbp.cursor = v_2;
+ if (!sbp.in_grouping(g_v, 97, 249) || sbp.cursor >= sbp.limit)
+ return;
+ sbp.cursor++;
+ }
+ I_pV = sbp.cursor;
+ }
+
+ function habr5() {
+ while (!sbp.in_grouping(g_v, 97, 249)) {
+ if (sbp.cursor >= sbp.limit)
+ return false;
+ sbp.cursor++;
+ }
+ while (!sbp.out_grouping(g_v, 97, 249)) {
+ if (sbp.cursor >= sbp.limit)
+ return false;
+ sbp.cursor++;
+ }
+ return true;
+ }
+
+ function r_mark_regions() {
+ var v_1 = sbp.cursor;
+ I_pV = sbp.limit;
+ I_p1 = I_pV;
+ I_p2 = I_pV;
+ habr4();
+ sbp.cursor = v_1;
+ if (habr5()) {
+ I_p1 = sbp.cursor;
+ if (habr5())
+ I_p2 = sbp.cursor;
+ }
+ }
+
+ function r_postlude() {
+ var among_var;
+ while (true) {
+ sbp.bra = sbp.cursor;
+ among_var = sbp.find_among(a_1, 3);
+ if (!among_var)
+ break;
+ sbp.ket = sbp.cursor;
+ switch (among_var) {
+ case 1:
+ sbp.slice_from("i");
+ break;
+ case 2:
+ sbp.slice_from("u");
+ break;
+ case 3:
+ if (sbp.cursor >= sbp.limit)
+ return;
+ sbp.cursor++;
+ break;
+ }
+ }
+ }
+
+ function r_RV() {
+ return I_pV <= sbp.cursor;
+ }
+
+ function r_R1() {
+ return I_p1 <= sbp.cursor;
+ }
+
+ function r_R2() {
+ return I_p2 <= sbp.cursor;
+ }
+
+ function r_attached_pronoun() {
+ var among_var;
+ sbp.ket = sbp.cursor;
+ if (sbp.find_among_b(a_2, 37)) {
+ sbp.bra = sbp.cursor;
+ among_var = sbp.find_among_b(a_3, 5);
+ if (among_var && r_RV()) {
+ switch (among_var) {
+ case 1:
+ sbp.slice_del();
+ break;
+ case 2:
+ sbp.slice_from("e");
+ break;
+ }
+ }
+ }
+ }
+
+ function r_standard_suffix() {
+ var among_var;
+ sbp.ket = sbp.cursor;
+ among_var = sbp.find_among_b(a_6, 51);
+ if (!among_var)
+ return false;
+ sbp.bra = sbp.cursor;
+ switch (among_var) {
+ case 1:
+ if (!r_R2())
+ return false;
+ sbp.slice_del();
+ break;
+ case 2:
+ if (!r_R2())
+ return false;
+ sbp.slice_del();
+ sbp.ket = sbp.cursor;
+ if (sbp.eq_s_b(2, "ic")) {
+ sbp.bra = sbp.cursor;
+ if (r_R2())
+ sbp.slice_del();
+ }
+ break;
+ case 3:
+ if (!r_R2())
+ return false;
+ sbp.slice_from("log");
+ break;
+ case 4:
+ if (!r_R2())
+ return false;
+ sbp.slice_from("u");
+ break;
+ case 5:
+ if (!r_R2())
+ return false;
+ sbp.slice_from("ente");
+ break;
+ case 6:
+ if (!r_RV())
+ return false;
+ sbp.slice_del();
+ break;
+ case 7:
+ if (!r_R1())
+ return false;
+ sbp.slice_del();
+ sbp.ket = sbp.cursor;
+ among_var = sbp.find_among_b(a_4, 4);
+ if (among_var) {
+ sbp.bra = sbp.cursor;
+ if (r_R2()) {
+ sbp.slice_del();
+ if (among_var == 1) {
+ sbp.ket = sbp.cursor;
+ if (sbp.eq_s_b(2, "at")) {
+ sbp.bra = sbp.cursor;
+ if (r_R2())
+ sbp.slice_del();
+ }
+ }
+ }
+ }
+ break;
+ case 8:
+ if (!r_R2())
+ return false;
+ sbp.slice_del();
+ sbp.ket = sbp.cursor;
+ among_var = sbp.find_among_b(a_5, 3);
+ if (among_var) {
+ sbp.bra = sbp.cursor;
+ if (among_var == 1)
+ if (r_R2())
+ sbp.slice_del();
+ }
+ break;
+ case 9:
+ if (!r_R2())
+ return false;
+ sbp.slice_del();
+ sbp.ket = sbp.cursor;
+ if (sbp.eq_s_b(2, "at")) {
+ sbp.bra = sbp.cursor;
+ if (r_R2()) {
+ sbp.slice_del();
+ sbp.ket = sbp.cursor;
+ if (sbp.eq_s_b(2, "ic")) {
+ sbp.bra = sbp.cursor;
+ if (r_R2())
+ sbp.slice_del();
+ }
+ }
+ }
+ break;
+ }
+ return true;
+ }
+
+ function r_verb_suffix() {
+ var among_var, v_1;
+ if (sbp.cursor >= I_pV) {
+ v_1 = sbp.limit_backward;
+ sbp.limit_backward = I_pV;
+ sbp.ket = sbp.cursor;
+ among_var = sbp.find_among_b(a_7, 87);
+ if (among_var) {
+ sbp.bra = sbp.cursor;
+ if (among_var == 1)
+ sbp.slice_del();
+ }
+ sbp.limit_backward = v_1;
+ }
+ }
+
+ function habr6() {
+ var v_1 = sbp.limit - sbp.cursor;
+ sbp.ket = sbp.cursor;
+ if (sbp.in_grouping_b(g_AEIO, 97, 242)) {
+ sbp.bra = sbp.cursor;
+ if (r_RV()) {
+ sbp.slice_del();
+ sbp.ket = sbp.cursor;
+ if (sbp.eq_s_b(1, "i")) {
+ sbp.bra = sbp.cursor;
+ if (r_RV()) {
+ sbp.slice_del();
+ return;
+ }
+ }
+ }
+ }
+ sbp.cursor = sbp.limit - v_1;
+ }
+
+ function r_vowel_suffix() {
+ habr6();
+ sbp.ket = sbp.cursor;
+ if (sbp.eq_s_b(1, "h")) {
+ sbp.bra = sbp.cursor;
+ if (sbp.in_grouping_b(g_CG, 99, 103))
+ if (r_RV())
+ sbp.slice_del();
+ }
+ }
+ this.stem = function() {
+ var v_1 = sbp.cursor;
+ r_prelude();
+ sbp.cursor = v_1;
+ r_mark_regions();
+ sbp.limit_backward = v_1;
+ sbp.cursor = sbp.limit;
+ r_attached_pronoun();
+ sbp.cursor = sbp.limit;
+ if (!r_standard_suffix()) {
+ sbp.cursor = sbp.limit;
+ r_verb_suffix();
+ }
+ sbp.cursor = sbp.limit;
+ r_vowel_suffix();
+ sbp.cursor = sbp.limit_backward;
+ r_postlude();
+ return true;
+ }
+ };
+
+ /* and return a function that stems a word for the current locale */
+ return function(token) {
+ // for lunr version 2
+ if (typeof token.update === "function") {
+ return token.update(function(word) {
+ st.setCurrent(word);
+ st.stem();
+ return st.getCurrent();
+ })
+ } else { // for lunr version <= 1
+ st.setCurrent(token);
+ st.stem();
+ return st.getCurrent();
+ }
+ }
+ })();
+
+ lunr.Pipeline.registerFunction(lunr.it.stemmer, 'stemmer-it');
+
+ lunr.it.stopWordFilter = lunr.generateStopWordFilter('a abbia abbiamo abbiano abbiate ad agl agli ai al all alla alle allo anche avemmo avendo avesse avessero avessi avessimo aveste avesti avete aveva avevamo avevano avevate avevi avevo avrai avranno avrebbe avrebbero avrei avremmo avremo avreste avresti avrete avrà avrò avuta avute avuti avuto c che chi ci coi col come con contro cui da dagl dagli dai dal dall dalla dalle dallo degl degli dei del dell della delle dello di dov dove e ebbe ebbero ebbi ed era erano eravamo eravate eri ero essendo faccia facciamo facciano facciate faccio facemmo facendo facesse facessero facessi facessimo faceste facesti faceva facevamo facevano facevate facevi facevo fai fanno farai faranno farebbe farebbero farei faremmo faremo fareste faresti farete farà farò fece fecero feci fosse fossero fossi fossimo foste fosti fu fui fummo furono gli ha hai hanno ho i il in io l la le lei li lo loro lui ma mi mia mie miei mio ne negl negli nei nel nell nella nelle nello noi non nostra nostre nostri nostro o per perché più quale quanta quante quanti quanto quella quelle quelli quello questa queste questi questo sarai saranno sarebbe sarebbero sarei saremmo saremo sareste saresti sarete sarà sarò se sei si sia siamo siano siate siete sono sta stai stando stanno starai staranno starebbe starebbero starei staremmo staremo stareste staresti starete starà starò stava stavamo stavano stavate stavi stavo stemmo stesse stessero stessi stessimo steste stesti stette stettero stetti stia stiamo stiano stiate sto su sua sue sugl sugli sui sul sull sulla sulle sullo suo suoi ti tra tu tua tue tuo tuoi tutti tutto un una uno vi voi vostra vostre vostri vostro è'.split(' '));
+
+ lunr.Pipeline.registerFunction(lunr.it.stopWordFilter, 'stopWordFilter-it');
+ };
+}))
\ No newline at end of file
diff --git a/venv/lib/python3.11/site-packages/mkdocs/contrib/search/lunr-language/lunr.ja.js b/venv/lib/python3.11/site-packages/mkdocs/contrib/search/lunr-language/lunr.ja.js
new file mode 100644
index 0000000..44eb411
--- /dev/null
+++ b/venv/lib/python3.11/site-packages/mkdocs/contrib/search/lunr-language/lunr.ja.js
@@ -0,0 +1,188 @@
+/*!
+ * Lunr languages, `Japanese` language
+ * https://github.com/MihaiValentin/lunr-languages
+ *
+ * Copyright 2014, Chad Liu
+ * http://www.mozilla.org/MPL/
+ */
+/*!
+ * based on
+ * Snowball JavaScript Library v0.3
+ * http://code.google.com/p/urim/
+ * http://snowball.tartarus.org/
+ *
+ * Copyright 2010, Oleg Mazko
+ * http://www.mozilla.org/MPL/
+ */
+
+/**
+ * export the module via AMD, CommonJS or as a browser global
+ * Export code from https://github.com/umdjs/umd/blob/master/returnExports.js
+ */
+;
+(function(root, factory) {
+ if (typeof define === 'function' && define.amd) {
+ // AMD. Register as an anonymous module.
+ define(factory)
+ } else if (typeof exports === 'object') {
+ /**
+ * Node. Does not work with strict CommonJS, but
+ * only CommonJS-like environments that support module.exports,
+ * like Node.
+ */
+ module.exports = factory()
+ } else {
+ // Browser globals (root is window)
+ factory()(root.lunr);
+ }
+}(this, function() {
+ /**
+ * Just return a value to define the module export.
+ * This example returns an object, but the module
+ * can return a function as the exported value.
+ */
+ return function(lunr) {
+ /* throw error if lunr is not yet included */
+ if ('undefined' === typeof lunr) {
+ throw new Error('Lunr is not present. Please include / require Lunr before this script.');
+ }
+
+ /* throw error if lunr stemmer support is not yet included */
+ if ('undefined' === typeof lunr.stemmerSupport) {
+ throw new Error('Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.');
+ }
+
+ /*
+ Japanese tokenization is trickier, since it does not
+ take into account spaces.
+ Since the tokenization function is represented different
+ internally for each of the Lunr versions, this had to be done
+ in order to try to try to pick the best way of doing this based
+ on the Lunr version
+ */
+ var isLunr2 = lunr.version[0] == "2";
+
+ /* register specific locale function */
+ lunr.ja = function() {
+ this.pipeline.reset();
+ this.pipeline.add(
+ lunr.ja.trimmer,
+ lunr.ja.stopWordFilter,
+ lunr.ja.stemmer
+ );
+
+ // change the tokenizer for japanese one
+ if (isLunr2) { // for lunr version 2.0.0
+ this.tokenizer = lunr.ja.tokenizer;
+ } else {
+ if (lunr.tokenizer) { // for lunr version 0.6.0
+ lunr.tokenizer = lunr.ja.tokenizer;
+ }
+ if (this.tokenizerFn) { // for lunr version 0.7.0 -> 1.0.0
+ this.tokenizerFn = lunr.ja.tokenizer;
+ }
+ }
+ };
+ var segmenter = new lunr.TinySegmenter(); // インスタンス生成
+
+ lunr.ja.tokenizer = function(obj) {
+ var i;
+ var str;
+ var len;
+ var segs;
+ var tokens;
+ var char;
+ var sliceLength;
+ var sliceStart;
+ var sliceEnd;
+ var segStart;
+
+ if (!arguments.length || obj == null || obj == undefined)
+ return [];
+
+ if (Array.isArray(obj)) {
+ return obj.map(
+ function(t) {
+ return isLunr2 ? new lunr.Token(t.toLowerCase()) : t.toLowerCase();
+ }
+ );
+ }
+
+ str = obj.toString().toLowerCase().replace(/^\s+/, '');
+ for (i = str.length - 1; i >= 0; i--) {
+ if (/\S/.test(str.charAt(i))) {
+ str = str.substring(0, i + 1);
+ break;
+ }
+ }
+
+ tokens = [];
+ len = str.length;
+ for (sliceEnd = 0, sliceStart = 0; sliceEnd <= len; sliceEnd++) {
+ char = str.charAt(sliceEnd);
+ sliceLength = sliceEnd - sliceStart;
+
+ if ((char.match(/\s/) || sliceEnd == len)) {
+ if (sliceLength > 0) {
+ segs = segmenter.segment(str.slice(sliceStart, sliceEnd)).filter(
+ function(token) {
+ return !!token;
+ }
+ );
+
+ segStart = sliceStart;
+ for (i = 0; i < segs.length; i++) {
+ if (isLunr2) {
+ tokens.push(
+ new lunr.Token(
+ segs[i], {
+ position: [segStart, segs[i].length],
+ index: tokens.length
+ }
+ )
+ );
+ } else {
+ tokens.push(segs[i]);
+ }
+ segStart += segs[i].length;
+ }
+ }
+
+ sliceStart = sliceEnd + 1;
+ }
+ }
+
+ return tokens;
+ }
+
+ /* lunr stemmer function */
+ lunr.ja.stemmer = (function() {
+
+ /* TODO japanese stemmer */
+ return function(word) {
+ return word;
+ }
+ })();
+ lunr.Pipeline.registerFunction(lunr.ja.stemmer, 'stemmer-ja');
+
+ /* lunr trimmer function */
+ lunr.ja.wordCharacters = "一二三四五六七八九十百千万億兆一-龠々〆ヵヶぁ-んァ-ヴーア-ン゙a-zA-Za-zA-Z0-90-9";
+ lunr.ja.trimmer = lunr.trimmerSupport.generateTrimmer(lunr.ja.wordCharacters);
+ lunr.Pipeline.registerFunction(lunr.ja.trimmer, 'trimmer-ja');
+
+ /* lunr stop word filter. see http://www.ranks.nl/stopwords/japanese */
+ lunr.ja.stopWordFilter = lunr.generateStopWordFilter(
+ 'これ それ あれ この その あの ここ そこ あそこ こちら どこ だれ なに なん 何 私 貴方 貴方方 我々 私達 あの人 あのかた 彼女 彼 です あります おります います は が の に を で え から まで より も どの と し それで しかし'.split(' '));
+ lunr.Pipeline.registerFunction(lunr.ja.stopWordFilter, 'stopWordFilter-ja');
+
+ // alias ja => jp for backward-compatibility.
+ // jp is the country code, while ja is the language code
+ // a new lunr.ja.js has been created, but in order to
+ // keep the backward compatibility, we'll leave the lunr.jp.js
+ // here for a while, and just make it use the new lunr.ja.js
+ lunr.jp = lunr.ja;
+ lunr.Pipeline.registerFunction(lunr.jp.stemmer, 'stemmer-jp');
+ lunr.Pipeline.registerFunction(lunr.jp.trimmer, 'trimmer-jp');
+ lunr.Pipeline.registerFunction(lunr.jp.stopWordFilter, 'stopWordFilter-jp');
+ };
+}))
\ No newline at end of file
diff --git a/venv/lib/python3.11/site-packages/mkdocs/contrib/search/lunr-language/lunr.jp.js b/venv/lib/python3.11/site-packages/mkdocs/contrib/search/lunr-language/lunr.jp.js
new file mode 100644
index 0000000..73ebff1
--- /dev/null
+++ b/venv/lib/python3.11/site-packages/mkdocs/contrib/search/lunr-language/lunr.jp.js
@@ -0,0 +1,5 @@
+// jp is the country code, while ja is the language code
+// a new lunr.ja.js has been created, but in order to
+// keep the backward compatibility, we'll leave the lunr.jp.js
+// here for a while, and just make it use the new lunr.ja.js
+module.exports = require('./lunr.ja');
\ No newline at end of file
diff --git a/venv/lib/python3.11/site-packages/mkdocs/contrib/search/lunr-language/lunr.multi.js b/venv/lib/python3.11/site-packages/mkdocs/contrib/search/lunr-language/lunr.multi.js
new file mode 100644
index 0000000..4e921e0
--- /dev/null
+++ b/venv/lib/python3.11/site-packages/mkdocs/contrib/search/lunr-language/lunr.multi.js
@@ -0,0 +1,79 @@
+/**
+ * export the module via AMD, CommonJS or as a browser global
+ * Export code from https://github.com/umdjs/umd/blob/master/returnExports.js
+ */
+;(function (root, factory) {
+ if (typeof define === 'function' && define.amd) {
+ // AMD. Register as an anonymous module.
+ define(factory)
+ } else if (typeof exports === 'object') {
+ /**
+ * Node. Does not work with strict CommonJS, but
+ * only CommonJS-like environments that support module.exports,
+ * like Node.
+ */
+ module.exports = factory()
+ } else {
+ // Browser globals (root is window)
+ factory()(root.lunr);
+ }
+}(this, function () {
+ /**
+ * Just return a value to define the module export.
+ * This example returns an object, but the module
+ * can return a function as the exported value.
+ */
+ return function(lunr) {
+ /* Set up the pipeline for indexing content in multiple languages. The
+ corresponding lunr.{lang} files must be loaded before calling this
+ function; English ('en') is built in.
+
+ Returns: a lunr plugin for use in your indexer.
+
+ Known drawback: every word will be stemmed with stemmers for every
+ language. This could mean that sometimes words that have the same
+ stemming root will not be stemmed as such.
+ */
+ lunr.multiLanguage = function(/* lang1, lang2, ... */) {
+ var languages = Array.prototype.slice.call(arguments);
+ var nameSuffix = languages.join('-');
+ var wordCharacters = "";
+ var pipeline = [];
+ var searchPipeline = [];
+ for (var i = 0; i < languages.length; ++i) {
+ if (languages[i] == 'en') {
+ wordCharacters += '\\w';
+ pipeline.unshift(lunr.stopWordFilter);
+ pipeline.push(lunr.stemmer);
+ searchPipeline.push(lunr.stemmer);
+ } else {
+ wordCharacters += lunr[languages[i]].wordCharacters;
+ if (lunr[languages[i]].stopWordFilter) {
+ pipeline.unshift(lunr[languages[i]].stopWordFilter);
+ }
+ if (lunr[languages[i]].stemmer) {
+ pipeline.push(lunr[languages[i]].stemmer);
+ searchPipeline.push(lunr[languages[i]].stemmer);
+ }
+ }
+ };
+ var multiTrimmer = lunr.trimmerSupport.generateTrimmer(wordCharacters);
+ lunr.Pipeline.registerFunction(multiTrimmer, 'lunr-multi-trimmer-' + nameSuffix);
+ pipeline.unshift(multiTrimmer);
+
+ return function() {
+ this.pipeline.reset();
+
+ this.pipeline.add.apply(this.pipeline, pipeline);
+
+ // for lunr version 2
+ // this is necessary so that every searched word is also stemmed before
+ // in lunr <= 1 this is not needed, as it is done using the normal pipeline
+ if (this.searchPipeline) {
+ this.searchPipeline.reset();
+ this.searchPipeline.add.apply(this.searchPipeline, searchPipeline);
+ }
+ };
+ }
+ }
+}));
diff --git a/venv/lib/python3.11/site-packages/mkdocs/contrib/search/lunr-language/lunr.nl.js b/venv/lib/python3.11/site-packages/mkdocs/contrib/search/lunr-language/lunr.nl.js
new file mode 100644
index 0000000..55b43ff
--- /dev/null
+++ b/venv/lib/python3.11/site-packages/mkdocs/contrib/search/lunr-language/lunr.nl.js
@@ -0,0 +1,448 @@
+/*!
+ * Lunr languages, `Dutch` language
+ * https://github.com/MihaiValentin/lunr-languages
+ *
+ * Copyright 2014, Mihai Valentin
+ * http://www.mozilla.org/MPL/
+ */
+/*!
+ * based on
+ * Snowball JavaScript Library v0.3
+ * http://code.google.com/p/urim/
+ * http://snowball.tartarus.org/
+ *
+ * Copyright 2010, Oleg Mazko
+ * http://www.mozilla.org/MPL/
+ */
+
+/**
+ * export the module via AMD, CommonJS or as a browser global
+ * Export code from https://github.com/umdjs/umd/blob/master/returnExports.js
+ */
+;
+(function(root, factory) {
+ if (typeof define === 'function' && define.amd) {
+ // AMD. Register as an anonymous module.
+ define(factory)
+ } else if (typeof exports === 'object') {
+ /**
+ * Node. Does not work with strict CommonJS, but
+ * only CommonJS-like environments that support module.exports,
+ * like Node.
+ */
+ module.exports = factory()
+ } else {
+ // Browser globals (root is window)
+ factory()(root.lunr);
+ }
+}(this, function() {
+ /**
+ * Just return a value to define the module export.
+ * This example returns an object, but the module
+ * can return a function as the exported value.
+ */
+ return function(lunr) {
+ /* throw error if lunr is not yet included */
+ if ('undefined' === typeof lunr) {
+ throw new Error('Lunr is not present. Please include / require Lunr before this script.');
+ }
+
+ /* throw error if lunr stemmer support is not yet included */
+ if ('undefined' === typeof lunr.stemmerSupport) {
+ throw new Error('Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.');
+ }
+
+ /* register specific locale function */
+ lunr.nl = function() {
+ this.pipeline.reset();
+ this.pipeline.add(
+ lunr.nl.trimmer,
+ lunr.nl.stopWordFilter,
+ lunr.nl.stemmer
+ );
+
+ // for lunr version 2
+ // this is necessary so that every searched word is also stemmed before
+ // in lunr <= 1 this is not needed, as it is done using the normal pipeline
+ if (this.searchPipeline) {
+ this.searchPipeline.reset();
+ this.searchPipeline.add(lunr.nl.stemmer)
+ }
+ };
+
+ /* lunr trimmer function */
+ lunr.nl.wordCharacters = "A-Za-z\xAA\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02B8\u02E0-\u02E4\u1D00-\u1D25\u1D2C-\u1D5C\u1D62-\u1D65\u1D6B-\u1D77\u1D79-\u1DBE\u1E00-\u1EFF\u2071\u207F\u2090-\u209C\u212A\u212B\u2132\u214E\u2160-\u2188\u2C60-\u2C7F\uA722-\uA787\uA78B-\uA7AD\uA7B0-\uA7B7\uA7F7-\uA7FF\uAB30-\uAB5A\uAB5C-\uAB64\uFB00-\uFB06\uFF21-\uFF3A\uFF41-\uFF5A";
+ lunr.nl.trimmer = lunr.trimmerSupport.generateTrimmer(lunr.nl.wordCharacters);
+
+ lunr.Pipeline.registerFunction(lunr.nl.trimmer, 'trimmer-nl');
+
+ /* lunr stemmer function */
+ lunr.nl.stemmer = (function() {
+ /* create the wrapped stemmer object */
+ var Among = lunr.stemmerSupport.Among,
+ SnowballProgram = lunr.stemmerSupport.SnowballProgram,
+ st = new function DutchStemmer() {
+ var a_0 = [new Among("", -1, 6), new Among("\u00E1", 0, 1),
+ new Among("\u00E4", 0, 1), new Among("\u00E9", 0, 2),
+ new Among("\u00EB", 0, 2), new Among("\u00ED", 0, 3),
+ new Among("\u00EF", 0, 3), new Among("\u00F3", 0, 4),
+ new Among("\u00F6", 0, 4), new Among("\u00FA", 0, 5),
+ new Among("\u00FC", 0, 5)
+ ],
+ a_1 = [new Among("", -1, 3),
+ new Among("I", 0, 2), new Among("Y", 0, 1)
+ ],
+ a_2 = [
+ new Among("dd", -1, -1), new Among("kk", -1, -1),
+ new Among("tt", -1, -1)
+ ],
+ a_3 = [new Among("ene", -1, 2),
+ new Among("se", -1, 3), new Among("en", -1, 2),
+ new Among("heden", 2, 1), new Among("s", -1, 3)
+ ],
+ a_4 = [
+ new Among("end", -1, 1), new Among("ig", -1, 2),
+ new Among("ing", -1, 1), new Among("lijk", -1, 3),
+ new Among("baar", -1, 4), new Among("bar", -1, 5)
+ ],
+ a_5 = [
+ new Among("aa", -1, -1), new Among("ee", -1, -1),
+ new Among("oo", -1, -1), new Among("uu", -1, -1)
+ ],
+ g_v = [17, 65,
+ 16, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128
+ ],
+ g_v_I = [1, 0, 0,
+ 17, 65, 16, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128
+ ],
+ g_v_j = [
+ 17, 67, 16, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128
+ ],
+ I_p2, I_p1, B_e_found, sbp = new SnowballProgram();
+ this.setCurrent = function(word) {
+ sbp.setCurrent(word);
+ };
+ this.getCurrent = function() {
+ return sbp.getCurrent();
+ };
+
+ function r_prelude() {
+ var among_var, v_1 = sbp.cursor,
+ v_2, v_3;
+ while (true) {
+ sbp.bra = sbp.cursor;
+ among_var = sbp.find_among(a_0, 11);
+ if (among_var) {
+ sbp.ket = sbp.cursor;
+ switch (among_var) {
+ case 1:
+ sbp.slice_from("a");
+ continue;
+ case 2:
+ sbp.slice_from("e");
+ continue;
+ case 3:
+ sbp.slice_from("i");
+ continue;
+ case 4:
+ sbp.slice_from("o");
+ continue;
+ case 5:
+ sbp.slice_from("u");
+ continue;
+ case 6:
+ if (sbp.cursor >= sbp.limit)
+ break;
+ sbp.cursor++;
+ continue;
+ }
+ }
+ break;
+ }
+ sbp.cursor = v_1;
+ sbp.bra = v_1;
+ if (sbp.eq_s(1, "y")) {
+ sbp.ket = sbp.cursor;
+ sbp.slice_from("Y");
+ } else
+ sbp.cursor = v_1;
+ while (true) {
+ v_2 = sbp.cursor;
+ if (sbp.in_grouping(g_v, 97, 232)) {
+ v_3 = sbp.cursor;
+ sbp.bra = v_3;
+ if (sbp.eq_s(1, "i")) {
+ sbp.ket = sbp.cursor;
+ if (sbp.in_grouping(g_v, 97, 232)) {
+ sbp.slice_from("I");
+ sbp.cursor = v_2;
+ }
+ } else {
+ sbp.cursor = v_3;
+ if (sbp.eq_s(1, "y")) {
+ sbp.ket = sbp.cursor;
+ sbp.slice_from("Y");
+ sbp.cursor = v_2;
+ } else if (habr1(v_2))
+ break;
+ }
+ } else if (habr1(v_2))
+ break;
+ }
+ }
+
+ function habr1(v_1) {
+ sbp.cursor = v_1;
+ if (v_1 >= sbp.limit)
+ return true;
+ sbp.cursor++;
+ return false;
+ }
+
+ function r_mark_regions() {
+ I_p1 = sbp.limit;
+ I_p2 = I_p1;
+ if (!habr2()) {
+ I_p1 = sbp.cursor;
+ if (I_p1 < 3)
+ I_p1 = 3;
+ if (!habr2())
+ I_p2 = sbp.cursor;
+ }
+ }
+
+ function habr2() {
+ while (!sbp.in_grouping(g_v, 97, 232)) {
+ if (sbp.cursor >= sbp.limit)
+ return true;
+ sbp.cursor++;
+ }
+ while (!sbp.out_grouping(g_v, 97, 232)) {
+ if (sbp.cursor >= sbp.limit)
+ return true;
+ sbp.cursor++;
+ }
+ return false;
+ }
+
+ function r_postlude() {
+ var among_var;
+ while (true) {
+ sbp.bra = sbp.cursor;
+ among_var = sbp.find_among(a_1, 3);
+ if (among_var) {
+ sbp.ket = sbp.cursor;
+ switch (among_var) {
+ case 1:
+ sbp.slice_from("y");
+ break;
+ case 2:
+ sbp.slice_from("i");
+ break;
+ case 3:
+ if (sbp.cursor >= sbp.limit)
+ return;
+ sbp.cursor++;
+ break;
+ }
+ }
+ }
+ }
+
+ function r_R1() {
+ return I_p1 <= sbp.cursor;
+ }
+
+ function r_R2() {
+ return I_p2 <= sbp.cursor;
+ }
+
+ function r_undouble() {
+ var v_1 = sbp.limit - sbp.cursor;
+ if (sbp.find_among_b(a_2, 3)) {
+ sbp.cursor = sbp.limit - v_1;
+ sbp.ket = sbp.cursor;
+ if (sbp.cursor > sbp.limit_backward) {
+ sbp.cursor--;
+ sbp.bra = sbp.cursor;
+ sbp.slice_del();
+ }
+ }
+ }
+
+ function r_e_ending() {
+ var v_1;
+ B_e_found = false;
+ sbp.ket = sbp.cursor;
+ if (sbp.eq_s_b(1, "e")) {
+ sbp.bra = sbp.cursor;
+ if (r_R1()) {
+ v_1 = sbp.limit - sbp.cursor;
+ if (sbp.out_grouping_b(g_v, 97, 232)) {
+ sbp.cursor = sbp.limit - v_1;
+ sbp.slice_del();
+ B_e_found = true;
+ r_undouble();
+ }
+ }
+ }
+ }
+
+ function r_en_ending() {
+ var v_1;
+ if (r_R1()) {
+ v_1 = sbp.limit - sbp.cursor;
+ if (sbp.out_grouping_b(g_v, 97, 232)) {
+ sbp.cursor = sbp.limit - v_1;
+ if (!sbp.eq_s_b(3, "gem")) {
+ sbp.cursor = sbp.limit - v_1;
+ sbp.slice_del();
+ r_undouble();
+ }
+ }
+ }
+ }
+
+ function r_standard_suffix() {
+ var among_var, v_1 = sbp.limit - sbp.cursor,
+ v_2, v_3, v_4, v_5, v_6;
+ sbp.ket = sbp.cursor;
+ among_var = sbp.find_among_b(a_3, 5);
+ if (among_var) {
+ sbp.bra = sbp.cursor;
+ switch (among_var) {
+ case 1:
+ if (r_R1())
+ sbp.slice_from("heid");
+ break;
+ case 2:
+ r_en_ending();
+ break;
+ case 3:
+ if (r_R1() && sbp.out_grouping_b(g_v_j, 97, 232))
+ sbp.slice_del();
+ break;
+ }
+ }
+ sbp.cursor = sbp.limit - v_1;
+ r_e_ending();
+ sbp.cursor = sbp.limit - v_1;
+ sbp.ket = sbp.cursor;
+ if (sbp.eq_s_b(4, "heid")) {
+ sbp.bra = sbp.cursor;
+ if (r_R2()) {
+ v_2 = sbp.limit - sbp.cursor;
+ if (!sbp.eq_s_b(1, "c")) {
+ sbp.cursor = sbp.limit - v_2;
+ sbp.slice_del();
+ sbp.ket = sbp.cursor;
+ if (sbp.eq_s_b(2, "en")) {
+ sbp.bra = sbp.cursor;
+ r_en_ending();
+ }
+ }
+ }
+ }
+ sbp.cursor = sbp.limit - v_1;
+ sbp.ket = sbp.cursor;
+ among_var = sbp.find_among_b(a_4, 6);
+ if (among_var) {
+ sbp.bra = sbp.cursor;
+ switch (among_var) {
+ case 1:
+ if (r_R2()) {
+ sbp.slice_del();
+ v_3 = sbp.limit - sbp.cursor;
+ sbp.ket = sbp.cursor;
+ if (sbp.eq_s_b(2, "ig")) {
+ sbp.bra = sbp.cursor;
+ if (r_R2()) {
+ v_4 = sbp.limit - sbp.cursor;
+ if (!sbp.eq_s_b(1, "e")) {
+ sbp.cursor = sbp.limit - v_4;
+ sbp.slice_del();
+ break;
+ }
+ }
+ }
+ sbp.cursor = sbp.limit - v_3;
+ r_undouble();
+ }
+ break;
+ case 2:
+ if (r_R2()) {
+ v_5 = sbp.limit - sbp.cursor;
+ if (!sbp.eq_s_b(1, "e")) {
+ sbp.cursor = sbp.limit - v_5;
+ sbp.slice_del();
+ }
+ }
+ break;
+ case 3:
+ if (r_R2()) {
+ sbp.slice_del();
+ r_e_ending();
+ }
+ break;
+ case 4:
+ if (r_R2())
+ sbp.slice_del();
+ break;
+ case 5:
+ if (r_R2() && B_e_found)
+ sbp.slice_del();
+ break;
+ }
+ }
+ sbp.cursor = sbp.limit - v_1;
+ if (sbp.out_grouping_b(g_v_I, 73, 232)) {
+ v_6 = sbp.limit - sbp.cursor;
+ if (sbp.find_among_b(a_5, 4) && sbp.out_grouping_b(g_v, 97, 232)) {
+ sbp.cursor = sbp.limit - v_6;
+ sbp.ket = sbp.cursor;
+ if (sbp.cursor > sbp.limit_backward) {
+ sbp.cursor--;
+ sbp.bra = sbp.cursor;
+ sbp.slice_del();
+ }
+ }
+ }
+ }
+ this.stem = function() {
+ var v_1 = sbp.cursor;
+ r_prelude();
+ sbp.cursor = v_1;
+ r_mark_regions();
+ sbp.limit_backward = v_1;
+ sbp.cursor = sbp.limit;
+ r_standard_suffix();
+ sbp.cursor = sbp.limit_backward;
+ r_postlude();
+ return true;
+ }
+ };
+
+ /* and return a function that stems a word for the current locale */
+ return function(token) {
+ // for lunr version 2
+ if (typeof token.update === "function") {
+ return token.update(function(word) {
+ st.setCurrent(word);
+ st.stem();
+ return st.getCurrent();
+ })
+ } else { // for lunr version <= 1
+ st.setCurrent(token);
+ st.stem();
+ return st.getCurrent();
+ }
+ }
+ })();
+
+ lunr.Pipeline.registerFunction(lunr.nl.stemmer, 'stemmer-nl');
+
+ lunr.nl.stopWordFilter = lunr.generateStopWordFilter(' aan al alles als altijd andere ben bij daar dan dat de der deze die dit doch doen door dus een eens en er ge geen geweest haar had heb hebben heeft hem het hier hij hoe hun iemand iets ik in is ja je kan kon kunnen maar me meer men met mij mijn moet na naar niet niets nog nu of om omdat onder ons ook op over reeds te tegen toch toen tot u uit uw van veel voor want waren was wat werd wezen wie wil worden wordt zal ze zelf zich zij zijn zo zonder zou'.split(' '));
+
+ lunr.Pipeline.registerFunction(lunr.nl.stopWordFilter, 'stopWordFilter-nl');
+ };
+}))
\ No newline at end of file
diff --git a/venv/lib/python3.11/site-packages/mkdocs/contrib/search/lunr-language/lunr.no.js b/venv/lib/python3.11/site-packages/mkdocs/contrib/search/lunr-language/lunr.no.js
new file mode 100644
index 0000000..34f8ab1
--- /dev/null
+++ b/venv/lib/python3.11/site-packages/mkdocs/contrib/search/lunr-language/lunr.no.js
@@ -0,0 +1,258 @@
+/*!
+ * Lunr languages, `Norwegian` language
+ * https://github.com/MihaiValentin/lunr-languages
+ *
+ * Copyright 2014, Mihai Valentin
+ * http://www.mozilla.org/MPL/
+ */
+/*!
+ * based on
+ * Snowball JavaScript Library v0.3
+ * http://code.google.com/p/urim/
+ * http://snowball.tartarus.org/
+ *
+ * Copyright 2010, Oleg Mazko
+ * http://www.mozilla.org/MPL/
+ */
+
+/**
+ * export the module via AMD, CommonJS or as a browser global
+ * Export code from https://github.com/umdjs/umd/blob/master/returnExports.js
+ */
+;
+(function(root, factory) {
+ if (typeof define === 'function' && define.amd) {
+ // AMD. Register as an anonymous module.
+ define(factory)
+ } else if (typeof exports === 'object') {
+ /**
+ * Node. Does not work with strict CommonJS, but
+ * only CommonJS-like environments that support module.exports,
+ * like Node.
+ */
+ module.exports = factory()
+ } else {
+ // Browser globals (root is window)
+ factory()(root.lunr);
+ }
+}(this, function() {
+ /**
+ * Just return a value to define the module export.
+ * This example returns an object, but the module
+ * can return a function as the exported value.
+ */
+ return function(lunr) {
+ /* throw error if lunr is not yet included */
+ if ('undefined' === typeof lunr) {
+ throw new Error('Lunr is not present. Please include / require Lunr before this script.');
+ }
+
+ /* throw error if lunr stemmer support is not yet included */
+ if ('undefined' === typeof lunr.stemmerSupport) {
+ throw new Error('Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.');
+ }
+
+ /* register specific locale function */
+ lunr.no = function() {
+ this.pipeline.reset();
+ this.pipeline.add(
+ lunr.no.trimmer,
+ lunr.no.stopWordFilter,
+ lunr.no.stemmer
+ );
+
+ // for lunr version 2
+ // this is necessary so that every searched word is also stemmed before
+ // in lunr <= 1 this is not needed, as it is done using the normal pipeline
+ if (this.searchPipeline) {
+ this.searchPipeline.reset();
+ this.searchPipeline.add(lunr.no.stemmer)
+ }
+ };
+
+ /* lunr trimmer function */
+ lunr.no.wordCharacters = "A-Za-z\xAA\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02B8\u02E0-\u02E4\u1D00-\u1D25\u1D2C-\u1D5C\u1D62-\u1D65\u1D6B-\u1D77\u1D79-\u1DBE\u1E00-\u1EFF\u2071\u207F\u2090-\u209C\u212A\u212B\u2132\u214E\u2160-\u2188\u2C60-\u2C7F\uA722-\uA787\uA78B-\uA7AD\uA7B0-\uA7B7\uA7F7-\uA7FF\uAB30-\uAB5A\uAB5C-\uAB64\uFB00-\uFB06\uFF21-\uFF3A\uFF41-\uFF5A";
+ lunr.no.trimmer = lunr.trimmerSupport.generateTrimmer(lunr.no.wordCharacters);
+
+ lunr.Pipeline.registerFunction(lunr.no.trimmer, 'trimmer-no');
+
+ /* lunr stemmer function */
+ lunr.no.stemmer = (function() {
+ /* create the wrapped stemmer object */
+ var Among = lunr.stemmerSupport.Among,
+ SnowballProgram = lunr.stemmerSupport.SnowballProgram,
+ st = new function NorwegianStemmer() {
+ var a_0 = [new Among("a", -1, 1), new Among("e", -1, 1),
+ new Among("ede", 1, 1), new Among("ande", 1, 1),
+ new Among("ende", 1, 1), new Among("ane", 1, 1),
+ new Among("ene", 1, 1), new Among("hetene", 6, 1),
+ new Among("erte", 1, 3), new Among("en", -1, 1),
+ new Among("heten", 9, 1), new Among("ar", -1, 1),
+ new Among("er", -1, 1), new Among("heter", 12, 1),
+ new Among("s", -1, 2), new Among("as", 14, 1),
+ new Among("es", 14, 1), new Among("edes", 16, 1),
+ new Among("endes", 16, 1), new Among("enes", 16, 1),
+ new Among("hetenes", 19, 1), new Among("ens", 14, 1),
+ new Among("hetens", 21, 1), new Among("ers", 14, 1),
+ new Among("ets", 14, 1), new Among("et", -1, 1),
+ new Among("het", 25, 1), new Among("ert", -1, 3),
+ new Among("ast", -1, 1)
+ ],
+ a_1 = [new Among("dt", -1, -1),
+ new Among("vt", -1, -1)
+ ],
+ a_2 = [new Among("leg", -1, 1),
+ new Among("eleg", 0, 1), new Among("ig", -1, 1),
+ new Among("eig", 2, 1), new Among("lig", 2, 1),
+ new Among("elig", 4, 1), new Among("els", -1, 1),
+ new Among("lov", -1, 1), new Among("elov", 7, 1),
+ new Among("slov", 7, 1), new Among("hetslov", 9, 1)
+ ],
+ g_v = [17,
+ 65, 16, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 0, 128
+ ],
+ g_s_ending = [
+ 119, 125, 149, 1
+ ],
+ I_x, I_p1, sbp = new SnowballProgram();
+ this.setCurrent = function(word) {
+ sbp.setCurrent(word);
+ };
+ this.getCurrent = function() {
+ return sbp.getCurrent();
+ };
+
+ function r_mark_regions() {
+ var v_1, c = sbp.cursor + 3;
+ I_p1 = sbp.limit;
+ if (0 <= c || c <= sbp.limit) {
+ I_x = c;
+ while (true) {
+ v_1 = sbp.cursor;
+ if (sbp.in_grouping(g_v, 97, 248)) {
+ sbp.cursor = v_1;
+ break;
+ }
+ if (v_1 >= sbp.limit)
+ return;
+ sbp.cursor = v_1 + 1;
+ }
+ while (!sbp.out_grouping(g_v, 97, 248)) {
+ if (sbp.cursor >= sbp.limit)
+ return;
+ sbp.cursor++;
+ }
+ I_p1 = sbp.cursor;
+ if (I_p1 < I_x)
+ I_p1 = I_x;
+ }
+ }
+
+ function r_main_suffix() {
+ var among_var, v_1, v_2;
+ if (sbp.cursor >= I_p1) {
+ v_1 = sbp.limit_backward;
+ sbp.limit_backward = I_p1;
+ sbp.ket = sbp.cursor;
+ among_var = sbp.find_among_b(a_0, 29);
+ sbp.limit_backward = v_1;
+ if (among_var) {
+ sbp.bra = sbp.cursor;
+ switch (among_var) {
+ case 1:
+ sbp.slice_del();
+ break;
+ case 2:
+ v_2 = sbp.limit - sbp.cursor;
+ if (sbp.in_grouping_b(g_s_ending, 98, 122))
+ sbp.slice_del();
+ else {
+ sbp.cursor = sbp.limit - v_2;
+ if (sbp.eq_s_b(1, "k") &&
+ sbp.out_grouping_b(g_v, 97, 248))
+ sbp.slice_del();
+ }
+ break;
+ case 3:
+ sbp.slice_from("er");
+ break;
+ }
+ }
+ }
+ }
+
+ function r_consonant_pair() {
+ var v_1 = sbp.limit - sbp.cursor,
+ v_2;
+ if (sbp.cursor >= I_p1) {
+ v_2 = sbp.limit_backward;
+ sbp.limit_backward = I_p1;
+ sbp.ket = sbp.cursor;
+ if (sbp.find_among_b(a_1, 2)) {
+ sbp.bra = sbp.cursor;
+ sbp.limit_backward = v_2;
+ sbp.cursor = sbp.limit - v_1;
+ if (sbp.cursor > sbp.limit_backward) {
+ sbp.cursor--;
+ sbp.bra = sbp.cursor;
+ sbp.slice_del();
+ }
+ } else
+ sbp.limit_backward = v_2;
+ }
+ }
+
+ function r_other_suffix() {
+ var among_var, v_1;
+ if (sbp.cursor >= I_p1) {
+ v_1 = sbp.limit_backward;
+ sbp.limit_backward = I_p1;
+ sbp.ket = sbp.cursor;
+ among_var = sbp.find_among_b(a_2, 11);
+ if (among_var) {
+ sbp.bra = sbp.cursor;
+ sbp.limit_backward = v_1;
+ if (among_var == 1)
+ sbp.slice_del();
+ } else
+ sbp.limit_backward = v_1;
+ }
+ }
+ this.stem = function() {
+ var v_1 = sbp.cursor;
+ r_mark_regions();
+ sbp.limit_backward = v_1;
+ sbp.cursor = sbp.limit;
+ r_main_suffix();
+ sbp.cursor = sbp.limit;
+ r_consonant_pair();
+ sbp.cursor = sbp.limit;
+ r_other_suffix();
+ return true;
+ }
+ };
+
+ /* and return a function that stems a word for the current locale */
+ return function(token) {
+ // for lunr version 2
+ if (typeof token.update === "function") {
+ return token.update(function(word) {
+ st.setCurrent(word);
+ st.stem();
+ return st.getCurrent();
+ })
+ } else { // for lunr version <= 1
+ st.setCurrent(token);
+ st.stem();
+ return st.getCurrent();
+ }
+ }
+ })();
+
+ lunr.Pipeline.registerFunction(lunr.no.stemmer, 'stemmer-no');
+
+ lunr.no.stopWordFilter = lunr.generateStopWordFilter('alle at av bare begge ble blei bli blir blitt både båe da de deg dei deim deira deires dem den denne der dere deres det dette di din disse ditt du dykk dykkar då eg ein eit eitt eller elles en enn er et ett etter for fordi fra før ha hadde han hans har hennar henne hennes her hjå ho hoe honom hoss hossen hun hva hvem hver hvilke hvilken hvis hvor hvordan hvorfor i ikke ikkje ikkje ingen ingi inkje inn inni ja jeg kan kom korleis korso kun kunne kva kvar kvarhelst kven kvi kvifor man mange me med medan meg meget mellom men mi min mine mitt mot mykje ned no noe noen noka noko nokon nokor nokre nå når og også om opp oss over på samme seg selv si si sia sidan siden sin sine sitt sjøl skal skulle slik so som som somme somt så sånn til um upp ut uten var vart varte ved vere verte vi vil ville vore vors vort vår være være vært å'.split(' '));
+
+ lunr.Pipeline.registerFunction(lunr.no.stopWordFilter, 'stopWordFilter-no');
+ };
+}))
\ No newline at end of file
diff --git a/venv/lib/python3.11/site-packages/mkdocs/contrib/search/lunr-language/lunr.pt.js b/venv/lib/python3.11/site-packages/mkdocs/contrib/search/lunr-language/lunr.pt.js
new file mode 100644
index 0000000..8834b90
--- /dev/null
+++ b/venv/lib/python3.11/site-packages/mkdocs/contrib/search/lunr-language/lunr.pt.js
@@ -0,0 +1,570 @@
+/*!
+ * Lunr languages, `Portuguese` language
+ * https://github.com/MihaiValentin/lunr-languages
+ *
+ * Copyright 2014, Mihai Valentin
+ * http://www.mozilla.org/MPL/
+ */
+/*!
+ * based on
+ * Snowball JavaScript Library v0.3
+ * http://code.google.com/p/urim/
+ * http://snowball.tartarus.org/
+ *
+ * Copyright 2010, Oleg Mazko
+ * http://www.mozilla.org/MPL/
+ */
+
+/**
+ * export the module via AMD, CommonJS or as a browser global
+ * Export code from https://github.com/umdjs/umd/blob/master/returnExports.js
+ */
+;
+(function(root, factory) {
+ if (typeof define === 'function' && define.amd) {
+ // AMD. Register as an anonymous module.
+ define(factory)
+ } else if (typeof exports === 'object') {
+ /**
+ * Node. Does not work with strict CommonJS, but
+ * only CommonJS-like environments that support module.exports,
+ * like Node.
+ */
+ module.exports = factory()
+ } else {
+ // Browser globals (root is window)
+ factory()(root.lunr);
+ }
+}(this, function() {
+ /**
+ * Just return a value to define the module export.
+ * This example returns an object, but the module
+ * can return a function as the exported value.
+ */
+ return function(lunr) {
+ /* throw error if lunr is not yet included */
+ if ('undefined' === typeof lunr) {
+ throw new Error('Lunr is not present. Please include / require Lunr before this script.');
+ }
+
+ /* throw error if lunr stemmer support is not yet included */
+ if ('undefined' === typeof lunr.stemmerSupport) {
+ throw new Error('Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.');
+ }
+
+ /* register specific locale function */
+ lunr.pt = function() {
+ this.pipeline.reset();
+ this.pipeline.add(
+ lunr.pt.trimmer,
+ lunr.pt.stopWordFilter,
+ lunr.pt.stemmer
+ );
+
+ // for lunr version 2
+ // this is necessary so that every searched word is also stemmed before
+ // in lunr <= 1 this is not needed, as it is done using the normal pipeline
+ if (this.searchPipeline) {
+ this.searchPipeline.reset();
+ this.searchPipeline.add(lunr.pt.stemmer)
+ }
+ };
+
+ /* lunr trimmer function */
+ lunr.pt.wordCharacters = "A-Za-z\xAA\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02B8\u02E0-\u02E4\u1D00-\u1D25\u1D2C-\u1D5C\u1D62-\u1D65\u1D6B-\u1D77\u1D79-\u1DBE\u1E00-\u1EFF\u2071\u207F\u2090-\u209C\u212A\u212B\u2132\u214E\u2160-\u2188\u2C60-\u2C7F\uA722-\uA787\uA78B-\uA7AD\uA7B0-\uA7B7\uA7F7-\uA7FF\uAB30-\uAB5A\uAB5C-\uAB64\uFB00-\uFB06\uFF21-\uFF3A\uFF41-\uFF5A";
+ lunr.pt.trimmer = lunr.trimmerSupport.generateTrimmer(lunr.pt.wordCharacters);
+
+ lunr.Pipeline.registerFunction(lunr.pt.trimmer, 'trimmer-pt');
+
+ /* lunr stemmer function */
+ lunr.pt.stemmer = (function() {
+ /* create the wrapped stemmer object */
+ var Among = lunr.stemmerSupport.Among,
+ SnowballProgram = lunr.stemmerSupport.SnowballProgram,
+ st = new function PortugueseStemmer() {
+ var a_0 = [new Among("", -1, 3), new Among("\u00E3", 0, 1),
+ new Among("\u00F5", 0, 2)
+ ],
+ a_1 = [new Among("", -1, 3),
+ new Among("a~", 0, 1), new Among("o~", 0, 2)
+ ],
+ a_2 = [
+ new Among("ic", -1, -1), new Among("ad", -1, -1),
+ new Among("os", -1, -1), new Among("iv", -1, 1)
+ ],
+ a_3 = [
+ new Among("ante", -1, 1), new Among("avel", -1, 1),
+ new Among("\u00EDvel", -1, 1)
+ ],
+ a_4 = [new Among("ic", -1, 1),
+ new Among("abil", -1, 1), new Among("iv", -1, 1)
+ ],
+ a_5 = [
+ new Among("ica", -1, 1), new Among("\u00E2ncia", -1, 1),
+ new Among("\u00EAncia", -1, 4), new Among("ira", -1, 9),
+ new Among("adora", -1, 1), new Among("osa", -1, 1),
+ new Among("ista", -1, 1), new Among("iva", -1, 8),
+ new Among("eza", -1, 1), new Among("log\u00EDa", -1, 2),
+ new Among("idade", -1, 7), new Among("ante", -1, 1),
+ new Among("mente", -1, 6), new Among("amente", 12, 5),
+ new Among("\u00E1vel", -1, 1), new Among("\u00EDvel", -1, 1),
+ new Among("uci\u00F3n", -1, 3), new Among("ico", -1, 1),
+ new Among("ismo", -1, 1), new Among("oso", -1, 1),
+ new Among("amento", -1, 1), new Among("imento", -1, 1),
+ new Among("ivo", -1, 8), new Among("a\u00E7a~o", -1, 1),
+ new Among("ador", -1, 1), new Among("icas", -1, 1),
+ new Among("\u00EAncias", -1, 4), new Among("iras", -1, 9),
+ new Among("adoras", -1, 1), new Among("osas", -1, 1),
+ new Among("istas", -1, 1), new Among("ivas", -1, 8),
+ new Among("ezas", -1, 1), new Among("log\u00EDas", -1, 2),
+ new Among("idades", -1, 7), new Among("uciones", -1, 3),
+ new Among("adores", -1, 1), new Among("antes", -1, 1),
+ new Among("a\u00E7o~es", -1, 1), new Among("icos", -1, 1),
+ new Among("ismos", -1, 1), new Among("osos", -1, 1),
+ new Among("amentos", -1, 1), new Among("imentos", -1, 1),
+ new Among("ivos", -1, 8)
+ ],
+ a_6 = [new Among("ada", -1, 1),
+ new Among("ida", -1, 1), new Among("ia", -1, 1),
+ new Among("aria", 2, 1), new Among("eria", 2, 1),
+ new Among("iria", 2, 1), new Among("ara", -1, 1),
+ new Among("era", -1, 1), new Among("ira", -1, 1),
+ new Among("ava", -1, 1), new Among("asse", -1, 1),
+ new Among("esse", -1, 1), new Among("isse", -1, 1),
+ new Among("aste", -1, 1), new Among("este", -1, 1),
+ new Among("iste", -1, 1), new Among("ei", -1, 1),
+ new Among("arei", 16, 1), new Among("erei", 16, 1),
+ new Among("irei", 16, 1), new Among("am", -1, 1),
+ new Among("iam", 20, 1), new Among("ariam", 21, 1),
+ new Among("eriam", 21, 1), new Among("iriam", 21, 1),
+ new Among("aram", 20, 1), new Among("eram", 20, 1),
+ new Among("iram", 20, 1), new Among("avam", 20, 1),
+ new Among("em", -1, 1), new Among("arem", 29, 1),
+ new Among("erem", 29, 1), new Among("irem", 29, 1),
+ new Among("assem", 29, 1), new Among("essem", 29, 1),
+ new Among("issem", 29, 1), new Among("ado", -1, 1),
+ new Among("ido", -1, 1), new Among("ando", -1, 1),
+ new Among("endo", -1, 1), new Among("indo", -1, 1),
+ new Among("ara~o", -1, 1), new Among("era~o", -1, 1),
+ new Among("ira~o", -1, 1), new Among("ar", -1, 1),
+ new Among("er", -1, 1), new Among("ir", -1, 1),
+ new Among("as", -1, 1), new Among("adas", 47, 1),
+ new Among("idas", 47, 1), new Among("ias", 47, 1),
+ new Among("arias", 50, 1), new Among("erias", 50, 1),
+ new Among("irias", 50, 1), new Among("aras", 47, 1),
+ new Among("eras", 47, 1), new Among("iras", 47, 1),
+ new Among("avas", 47, 1), new Among("es", -1, 1),
+ new Among("ardes", 58, 1), new Among("erdes", 58, 1),
+ new Among("irdes", 58, 1), new Among("ares", 58, 1),
+ new Among("eres", 58, 1), new Among("ires", 58, 1),
+ new Among("asses", 58, 1), new Among("esses", 58, 1),
+ new Among("isses", 58, 1), new Among("astes", 58, 1),
+ new Among("estes", 58, 1), new Among("istes", 58, 1),
+ new Among("is", -1, 1), new Among("ais", 71, 1),
+ new Among("eis", 71, 1), new Among("areis", 73, 1),
+ new Among("ereis", 73, 1), new Among("ireis", 73, 1),
+ new Among("\u00E1reis", 73, 1), new Among("\u00E9reis", 73, 1),
+ new Among("\u00EDreis", 73, 1), new Among("\u00E1sseis", 73, 1),
+ new Among("\u00E9sseis", 73, 1), new Among("\u00EDsseis", 73, 1),
+ new Among("\u00E1veis", 73, 1), new Among("\u00EDeis", 73, 1),
+ new Among("ar\u00EDeis", 84, 1), new Among("er\u00EDeis", 84, 1),
+ new Among("ir\u00EDeis", 84, 1), new Among("ados", -1, 1),
+ new Among("idos", -1, 1), new Among("amos", -1, 1),
+ new Among("\u00E1ramos", 90, 1), new Among("\u00E9ramos", 90, 1),
+ new Among("\u00EDramos", 90, 1), new Among("\u00E1vamos", 90, 1),
+ new Among("\u00EDamos", 90, 1), new Among("ar\u00EDamos", 95, 1),
+ new Among("er\u00EDamos", 95, 1), new Among("ir\u00EDamos", 95, 1),
+ new Among("emos", -1, 1), new Among("aremos", 99, 1),
+ new Among("eremos", 99, 1), new Among("iremos", 99, 1),
+ new Among("\u00E1ssemos", 99, 1), new Among("\u00EAssemos", 99, 1),
+ new Among("\u00EDssemos", 99, 1), new Among("imos", -1, 1),
+ new Among("armos", -1, 1), new Among("ermos", -1, 1),
+ new Among("irmos", -1, 1), new Among("\u00E1mos", -1, 1),
+ new Among("ar\u00E1s", -1, 1), new Among("er\u00E1s", -1, 1),
+ new Among("ir\u00E1s", -1, 1), new Among("eu", -1, 1),
+ new Among("iu", -1, 1), new Among("ou", -1, 1),
+ new Among("ar\u00E1", -1, 1), new Among("er\u00E1", -1, 1),
+ new Among("ir\u00E1", -1, 1)
+ ],
+ a_7 = [new Among("a", -1, 1),
+ new Among("i", -1, 1), new Among("o", -1, 1),
+ new Among("os", -1, 1), new Among("\u00E1", -1, 1),
+ new Among("\u00ED", -1, 1), new Among("\u00F3", -1, 1)
+ ],
+ a_8 = [
+ new Among("e", -1, 1), new Among("\u00E7", -1, 2),
+ new Among("\u00E9", -1, 1), new Among("\u00EA", -1, 1)
+ ],
+ g_v = [17,
+ 65, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 19, 12, 2
+ ],
+ I_p2, I_p1, I_pV, sbp = new SnowballProgram();
+ this.setCurrent = function(word) {
+ sbp.setCurrent(word);
+ };
+ this.getCurrent = function() {
+ return sbp.getCurrent();
+ };
+
+ function r_prelude() {
+ var among_var;
+ while (true) {
+ sbp.bra = sbp.cursor;
+ among_var = sbp.find_among(a_0, 3);
+ if (among_var) {
+ sbp.ket = sbp.cursor;
+ switch (among_var) {
+ case 1:
+ sbp.slice_from("a~");
+ continue;
+ case 2:
+ sbp.slice_from("o~");
+ continue;
+ case 3:
+ if (sbp.cursor >= sbp.limit)
+ break;
+ sbp.cursor++;
+ continue;
+ }
+ }
+ break;
+ }
+ }
+
+ function habr2() {
+ if (sbp.out_grouping(g_v, 97, 250)) {
+ while (!sbp.in_grouping(g_v, 97, 250)) {
+ if (sbp.cursor >= sbp.limit)
+ return true;
+ sbp.cursor++;
+ }
+ return false;
+ }
+ return true;
+ }
+
+ function habr3() {
+ if (sbp.in_grouping(g_v, 97, 250)) {
+ while (!sbp.out_grouping(g_v, 97, 250)) {
+ if (sbp.cursor >= sbp.limit)
+ return false;
+ sbp.cursor++;
+ }
+ }
+ I_pV = sbp.cursor;
+ return true;
+ }
+
+ function habr4() {
+ var v_1 = sbp.cursor,
+ v_2, v_3;
+ if (sbp.in_grouping(g_v, 97, 250)) {
+ v_2 = sbp.cursor;
+ if (habr2()) {
+ sbp.cursor = v_2;
+ if (habr3())
+ return;
+ } else
+ I_pV = sbp.cursor;
+ }
+ sbp.cursor = v_1;
+ if (sbp.out_grouping(g_v, 97, 250)) {
+ v_3 = sbp.cursor;
+ if (habr2()) {
+ sbp.cursor = v_3;
+ if (!sbp.in_grouping(g_v, 97, 250) || sbp.cursor >= sbp.limit)
+ return;
+ sbp.cursor++;
+ }
+ I_pV = sbp.cursor;
+ }
+ }
+
+ function habr5() {
+ while (!sbp.in_grouping(g_v, 97, 250)) {
+ if (sbp.cursor >= sbp.limit)
+ return false;
+ sbp.cursor++;
+ }
+ while (!sbp.out_grouping(g_v, 97, 250)) {
+ if (sbp.cursor >= sbp.limit)
+ return false;
+ sbp.cursor++;
+ }
+ return true;
+ }
+
+ function r_mark_regions() {
+ var v_1 = sbp.cursor;
+ I_pV = sbp.limit;
+ I_p1 = I_pV;
+ I_p2 = I_pV;
+ habr4();
+ sbp.cursor = v_1;
+ if (habr5()) {
+ I_p1 = sbp.cursor;
+ if (habr5())
+ I_p2 = sbp.cursor;
+ }
+ }
+
+ function r_postlude() {
+ var among_var;
+ while (true) {
+ sbp.bra = sbp.cursor;
+ among_var = sbp.find_among(a_1, 3);
+ if (among_var) {
+ sbp.ket = sbp.cursor;
+ switch (among_var) {
+ case 1:
+ sbp.slice_from("\u00E3");
+ continue;
+ case 2:
+ sbp.slice_from("\u00F5");
+ continue;
+ case 3:
+ if (sbp.cursor >= sbp.limit)
+ break;
+ sbp.cursor++;
+ continue;
+ }
+ }
+ break;
+ }
+ }
+
+ function r_RV() {
+ return I_pV <= sbp.cursor;
+ }
+
+ function r_R1() {
+ return I_p1 <= sbp.cursor;
+ }
+
+ function r_R2() {
+ return I_p2 <= sbp.cursor;
+ }
+
+ function r_standard_suffix() {
+ var among_var;
+ sbp.ket = sbp.cursor;
+ among_var = sbp.find_among_b(a_5, 45);
+ if (!among_var)
+ return false;
+ sbp.bra = sbp.cursor;
+ switch (among_var) {
+ case 1:
+ if (!r_R2())
+ return false;
+ sbp.slice_del();
+ break;
+ case 2:
+ if (!r_R2())
+ return false;
+ sbp.slice_from("log");
+ break;
+ case 3:
+ if (!r_R2())
+ return false;
+ sbp.slice_from("u");
+ break;
+ case 4:
+ if (!r_R2())
+ return false;
+ sbp.slice_from("ente");
+ break;
+ case 5:
+ if (!r_R1())
+ return false;
+ sbp.slice_del();
+ sbp.ket = sbp.cursor;
+ among_var = sbp.find_among_b(a_2, 4);
+ if (among_var) {
+ sbp.bra = sbp.cursor;
+ if (r_R2()) {
+ sbp.slice_del();
+ if (among_var == 1) {
+ sbp.ket = sbp.cursor;
+ if (sbp.eq_s_b(2, "at")) {
+ sbp.bra = sbp.cursor;
+ if (r_R2())
+ sbp.slice_del();
+ }
+ }
+ }
+ }
+ break;
+ case 6:
+ if (!r_R2())
+ return false;
+ sbp.slice_del();
+ sbp.ket = sbp.cursor;
+ among_var = sbp.find_among_b(a_3, 3);
+ if (among_var) {
+ sbp.bra = sbp.cursor;
+ if (among_var == 1)
+ if (r_R2())
+ sbp.slice_del();
+ }
+ break;
+ case 7:
+ if (!r_R2())
+ return false;
+ sbp.slice_del();
+ sbp.ket = sbp.cursor;
+ among_var = sbp.find_among_b(a_4, 3);
+ if (among_var) {
+ sbp.bra = sbp.cursor;
+ if (among_var == 1)
+ if (r_R2())
+ sbp.slice_del();
+ }
+ break;
+ case 8:
+ if (!r_R2())
+ return false;
+ sbp.slice_del();
+ sbp.ket = sbp.cursor;
+ if (sbp.eq_s_b(2, "at")) {
+ sbp.bra = sbp.cursor;
+ if (r_R2())
+ sbp.slice_del();
+ }
+ break;
+ case 9:
+ if (!r_RV() || !sbp.eq_s_b(1, "e"))
+ return false;
+ sbp.slice_from("ir");
+ break;
+ }
+ return true;
+ }
+
+ function r_verb_suffix() {
+ var among_var, v_1;
+ if (sbp.cursor >= I_pV) {
+ v_1 = sbp.limit_backward;
+ sbp.limit_backward = I_pV;
+ sbp.ket = sbp.cursor;
+ among_var = sbp.find_among_b(a_6, 120);
+ if (among_var) {
+ sbp.bra = sbp.cursor;
+ if (among_var == 1)
+ sbp.slice_del();
+ sbp.limit_backward = v_1;
+ return true;
+ }
+ sbp.limit_backward = v_1;
+ }
+ return false;
+ }
+
+ function r_residual_suffix() {
+ var among_var;
+ sbp.ket = sbp.cursor;
+ among_var = sbp.find_among_b(a_7, 7);
+ if (among_var) {
+ sbp.bra = sbp.cursor;
+ if (among_var == 1)
+ if (r_RV())
+ sbp.slice_del();
+ }
+ }
+
+ function habr6(c1, c2) {
+ if (sbp.eq_s_b(1, c1)) {
+ sbp.bra = sbp.cursor;
+ var v_1 = sbp.limit - sbp.cursor;
+ if (sbp.eq_s_b(1, c2)) {
+ sbp.cursor = sbp.limit - v_1;
+ if (r_RV())
+ sbp.slice_del();
+ return false;
+ }
+ }
+ return true;
+ }
+
+ function r_residual_form() {
+ var among_var, v_1, v_2, v_3;
+ sbp.ket = sbp.cursor;
+ among_var = sbp.find_among_b(a_8, 4);
+ if (among_var) {
+ sbp.bra = sbp.cursor;
+ switch (among_var) {
+ case 1:
+ if (r_RV()) {
+ sbp.slice_del();
+ sbp.ket = sbp.cursor;
+ v_1 = sbp.limit - sbp.cursor;
+ if (habr6("u", "g"))
+ habr6("i", "c")
+ }
+ break;
+ case 2:
+ sbp.slice_from("c");
+ break;
+ }
+ }
+ }
+
+ function habr1() {
+ if (!r_standard_suffix()) {
+ sbp.cursor = sbp.limit;
+ if (!r_verb_suffix()) {
+ sbp.cursor = sbp.limit;
+ r_residual_suffix();
+ return;
+ }
+ }
+ sbp.cursor = sbp.limit;
+ sbp.ket = sbp.cursor;
+ if (sbp.eq_s_b(1, "i")) {
+ sbp.bra = sbp.cursor;
+ if (sbp.eq_s_b(1, "c")) {
+ sbp.cursor = sbp.limit;
+ if (r_RV())
+ sbp.slice_del();
+ }
+ }
+ }
+ this.stem = function() {
+ var v_1 = sbp.cursor;
+ r_prelude();
+ sbp.cursor = v_1;
+ r_mark_regions();
+ sbp.limit_backward = v_1;
+ sbp.cursor = sbp.limit;
+ habr1();
+ sbp.cursor = sbp.limit;
+ r_residual_form();
+ sbp.cursor = sbp.limit_backward;
+ r_postlude();
+ return true;
+ }
+ };
+
+ /* and return a function that stems a word for the current locale */
+ return function(token) {
+ // for lunr version 2
+ if (typeof token.update === "function") {
+ return token.update(function(word) {
+ st.setCurrent(word);
+ st.stem();
+ return st.getCurrent();
+ })
+ } else { // for lunr version <= 1
+ st.setCurrent(token);
+ st.stem();
+ return st.getCurrent();
+ }
+ }
+ })();
+
+ lunr.Pipeline.registerFunction(lunr.pt.stemmer, 'stemmer-pt');
+
+ lunr.pt.stopWordFilter = lunr.generateStopWordFilter('a ao aos aquela aquelas aquele aqueles aquilo as até com como da das de dela delas dele deles depois do dos e ela elas ele eles em entre era eram essa essas esse esses esta estamos estas estava estavam este esteja estejam estejamos estes esteve estive estivemos estiver estivera estiveram estiverem estivermos estivesse estivessem estivéramos estivéssemos estou está estávamos estão eu foi fomos for fora foram forem formos fosse fossem fui fôramos fôssemos haja hajam hajamos havemos hei houve houvemos houver houvera houveram houverei houverem houveremos houveria houveriam houvermos houverá houverão houveríamos houvesse houvessem houvéramos houvéssemos há hão isso isto já lhe lhes mais mas me mesmo meu meus minha minhas muito na nas nem no nos nossa nossas nosso nossos num numa não nós o os ou para pela pelas pelo pelos por qual quando que quem se seja sejam sejamos sem serei seremos seria seriam será serão seríamos seu seus somos sou sua suas são só também te tem temos tenha tenham tenhamos tenho terei teremos teria teriam terá terão teríamos teu teus teve tinha tinham tive tivemos tiver tivera tiveram tiverem tivermos tivesse tivessem tivéramos tivéssemos tu tua tuas tém tínhamos um uma você vocês vos à às éramos'.split(' '));
+
+ lunr.Pipeline.registerFunction(lunr.pt.stopWordFilter, 'stopWordFilter-pt');
+ };
+}))
\ No newline at end of file
diff --git a/venv/lib/python3.11/site-packages/mkdocs/contrib/search/lunr-language/lunr.ro.js b/venv/lib/python3.11/site-packages/mkdocs/contrib/search/lunr-language/lunr.ro.js
new file mode 100644
index 0000000..9659b76
--- /dev/null
+++ b/venv/lib/python3.11/site-packages/mkdocs/contrib/search/lunr-language/lunr.ro.js
@@ -0,0 +1,558 @@
+/*!
+ * Lunr languages, `Romanian` language
+ * https://github.com/MihaiValentin/lunr-languages
+ *
+ * Copyright 2014, Mihai Valentin
+ * http://www.mozilla.org/MPL/
+ */
+/*!
+ * based on
+ * Snowball JavaScript Library v0.3
+ * http://code.google.com/p/urim/
+ * http://snowball.tartarus.org/
+ *
+ * Copyright 2010, Oleg Mazko
+ * http://www.mozilla.org/MPL/
+ */
+
+/**
+ * export the module via AMD, CommonJS or as a browser global
+ * Export code from https://github.com/umdjs/umd/blob/master/returnExports.js
+ */
+;
+(function(root, factory) {
+ if (typeof define === 'function' && define.amd) {
+ // AMD. Register as an anonymous module.
+ define(factory)
+ } else if (typeof exports === 'object') {
+ /**
+ * Node. Does not work with strict CommonJS, but
+ * only CommonJS-like environments that support module.exports,
+ * like Node.
+ */
+ module.exports = factory()
+ } else {
+ // Browser globals (root is window)
+ factory()(root.lunr);
+ }
+}(this, function() {
+ /**
+ * Just return a value to define the module export.
+ * This example returns an object, but the module
+ * can return a function as the exported value.
+ */
+ return function(lunr) {
+ /* throw error if lunr is not yet included */
+ if ('undefined' === typeof lunr) {
+ throw new Error('Lunr is not present. Please include / require Lunr before this script.');
+ }
+
+ /* throw error if lunr stemmer support is not yet included */
+ if ('undefined' === typeof lunr.stemmerSupport) {
+ throw new Error('Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.');
+ }
+
+ /* register specific locale function */
+ lunr.ro = function() {
+ this.pipeline.reset();
+ this.pipeline.add(
+ lunr.ro.trimmer,
+ lunr.ro.stopWordFilter,
+ lunr.ro.stemmer
+ );
+
+ // for lunr version 2
+ // this is necessary so that every searched word is also stemmed before
+ // in lunr <= 1 this is not needed, as it is done using the normal pipeline
+ if (this.searchPipeline) {
+ this.searchPipeline.reset();
+ this.searchPipeline.add(lunr.ro.stemmer)
+ }
+ };
+
+ /* lunr trimmer function */
+ lunr.ro.wordCharacters = "A-Za-z\xAA\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02B8\u02E0-\u02E4\u1D00-\u1D25\u1D2C-\u1D5C\u1D62-\u1D65\u1D6B-\u1D77\u1D79-\u1DBE\u1E00-\u1EFF\u2071\u207F\u2090-\u209C\u212A\u212B\u2132\u214E\u2160-\u2188\u2C60-\u2C7F\uA722-\uA787\uA78B-\uA7AD\uA7B0-\uA7B7\uA7F7-\uA7FF\uAB30-\uAB5A\uAB5C-\uAB64\uFB00-\uFB06\uFF21-\uFF3A\uFF41-\uFF5A";
+ lunr.ro.trimmer = lunr.trimmerSupport.generateTrimmer(lunr.ro.wordCharacters);
+
+ lunr.Pipeline.registerFunction(lunr.ro.trimmer, 'trimmer-ro');
+
+ /* lunr stemmer function */
+ lunr.ro.stemmer = (function() {
+ /* create the wrapped stemmer object */
+ var Among = lunr.stemmerSupport.Among,
+ SnowballProgram = lunr.stemmerSupport.SnowballProgram,
+ st = new function RomanianStemmer() {
+ var a_0 = [new Among("", -1, 3), new Among("I", 0, 1), new Among("U", 0, 2)],
+ a_1 = [
+ new Among("ea", -1, 3), new Among("a\u0163ia", -1, 7),
+ new Among("aua", -1, 2), new Among("iua", -1, 4),
+ new Among("a\u0163ie", -1, 7), new Among("ele", -1, 3),
+ new Among("ile", -1, 5), new Among("iile", 6, 4),
+ new Among("iei", -1, 4), new Among("atei", -1, 6),
+ new Among("ii", -1, 4), new Among("ului", -1, 1),
+ new Among("ul", -1, 1), new Among("elor", -1, 3),
+ new Among("ilor", -1, 4), new Among("iilor", 14, 4)
+ ],
+ a_2 = [
+ new Among("icala", -1, 4), new Among("iciva", -1, 4),
+ new Among("ativa", -1, 5), new Among("itiva", -1, 6),
+ new Among("icale", -1, 4), new Among("a\u0163iune", -1, 5),
+ new Among("i\u0163iune", -1, 6), new Among("atoare", -1, 5),
+ new Among("itoare", -1, 6), new Among("\u0103toare", -1, 5),
+ new Among("icitate", -1, 4), new Among("abilitate", -1, 1),
+ new Among("ibilitate", -1, 2), new Among("ivitate", -1, 3),
+ new Among("icive", -1, 4), new Among("ative", -1, 5),
+ new Among("itive", -1, 6), new Among("icali", -1, 4),
+ new Among("atori", -1, 5), new Among("icatori", 18, 4),
+ new Among("itori", -1, 6), new Among("\u0103tori", -1, 5),
+ new Among("icitati", -1, 4), new Among("abilitati", -1, 1),
+ new Among("ivitati", -1, 3), new Among("icivi", -1, 4),
+ new Among("ativi", -1, 5), new Among("itivi", -1, 6),
+ new Among("icit\u0103i", -1, 4), new Among("abilit\u0103i", -1, 1),
+ new Among("ivit\u0103i", -1, 3),
+ new Among("icit\u0103\u0163i", -1, 4),
+ new Among("abilit\u0103\u0163i", -1, 1),
+ new Among("ivit\u0103\u0163i", -1, 3), new Among("ical", -1, 4),
+ new Among("ator", -1, 5), new Among("icator", 35, 4),
+ new Among("itor", -1, 6), new Among("\u0103tor", -1, 5),
+ new Among("iciv", -1, 4), new Among("ativ", -1, 5),
+ new Among("itiv", -1, 6), new Among("ical\u0103", -1, 4),
+ new Among("iciv\u0103", -1, 4), new Among("ativ\u0103", -1, 5),
+ new Among("itiv\u0103", -1, 6)
+ ],
+ a_3 = [new Among("ica", -1, 1),
+ new Among("abila", -1, 1), new Among("ibila", -1, 1),
+ new Among("oasa", -1, 1), new Among("ata", -1, 1),
+ new Among("ita", -1, 1), new Among("anta", -1, 1),
+ new Among("ista", -1, 3), new Among("uta", -1, 1),
+ new Among("iva", -1, 1), new Among("ic", -1, 1),
+ new Among("ice", -1, 1), new Among("abile", -1, 1),
+ new Among("ibile", -1, 1), new Among("isme", -1, 3),
+ new Among("iune", -1, 2), new Among("oase", -1, 1),
+ new Among("ate", -1, 1), new Among("itate", 17, 1),
+ new Among("ite", -1, 1), new Among("ante", -1, 1),
+ new Among("iste", -1, 3), new Among("ute", -1, 1),
+ new Among("ive", -1, 1), new Among("ici", -1, 1),
+ new Among("abili", -1, 1), new Among("ibili", -1, 1),
+ new Among("iuni", -1, 2), new Among("atori", -1, 1),
+ new Among("osi", -1, 1), new Among("ati", -1, 1),
+ new Among("itati", 30, 1), new Among("iti", -1, 1),
+ new Among("anti", -1, 1), new Among("isti", -1, 3),
+ new Among("uti", -1, 1), new Among("i\u015Fti", -1, 3),
+ new Among("ivi", -1, 1), new Among("it\u0103i", -1, 1),
+ new Among("o\u015Fi", -1, 1), new Among("it\u0103\u0163i", -1, 1),
+ new Among("abil", -1, 1), new Among("ibil", -1, 1),
+ new Among("ism", -1, 3), new Among("ator", -1, 1),
+ new Among("os", -1, 1), new Among("at", -1, 1),
+ new Among("it", -1, 1), new Among("ant", -1, 1),
+ new Among("ist", -1, 3), new Among("ut", -1, 1),
+ new Among("iv", -1, 1), new Among("ic\u0103", -1, 1),
+ new Among("abil\u0103", -1, 1), new Among("ibil\u0103", -1, 1),
+ new Among("oas\u0103", -1, 1), new Among("at\u0103", -1, 1),
+ new Among("it\u0103", -1, 1), new Among("ant\u0103", -1, 1),
+ new Among("ist\u0103", -1, 3), new Among("ut\u0103", -1, 1),
+ new Among("iv\u0103", -1, 1)
+ ],
+ a_4 = [new Among("ea", -1, 1),
+ new Among("ia", -1, 1), new Among("esc", -1, 1),
+ new Among("\u0103sc", -1, 1), new Among("ind", -1, 1),
+ new Among("\u00E2nd", -1, 1), new Among("are", -1, 1),
+ new Among("ere", -1, 1), new Among("ire", -1, 1),
+ new Among("\u00E2re", -1, 1), new Among("se", -1, 2),
+ new Among("ase", 10, 1), new Among("sese", 10, 2),
+ new Among("ise", 10, 1), new Among("use", 10, 1),
+ new Among("\u00E2se", 10, 1), new Among("e\u015Fte", -1, 1),
+ new Among("\u0103\u015Fte", -1, 1), new Among("eze", -1, 1),
+ new Among("ai", -1, 1), new Among("eai", 19, 1),
+ new Among("iai", 19, 1), new Among("sei", -1, 2),
+ new Among("e\u015Fti", -1, 1), new Among("\u0103\u015Fti", -1, 1),
+ new Among("ui", -1, 1), new Among("ezi", -1, 1),
+ new Among("\u00E2i", -1, 1), new Among("a\u015Fi", -1, 1),
+ new Among("se\u015Fi", -1, 2), new Among("ase\u015Fi", 29, 1),
+ new Among("sese\u015Fi", 29, 2), new Among("ise\u015Fi", 29, 1),
+ new Among("use\u015Fi", 29, 1),
+ new Among("\u00E2se\u015Fi", 29, 1), new Among("i\u015Fi", -1, 1),
+ new Among("u\u015Fi", -1, 1), new Among("\u00E2\u015Fi", -1, 1),
+ new Among("a\u0163i", -1, 2), new Among("ea\u0163i", 38, 1),
+ new Among("ia\u0163i", 38, 1), new Among("e\u0163i", -1, 2),
+ new Among("i\u0163i", -1, 2), new Among("\u00E2\u0163i", -1, 2),
+ new Among("ar\u0103\u0163i", -1, 1),
+ new Among("ser\u0103\u0163i", -1, 2),
+ new Among("aser\u0103\u0163i", 45, 1),
+ new Among("seser\u0103\u0163i", 45, 2),
+ new Among("iser\u0103\u0163i", 45, 1),
+ new Among("user\u0103\u0163i", 45, 1),
+ new Among("\u00E2ser\u0103\u0163i", 45, 1),
+ new Among("ir\u0103\u0163i", -1, 1),
+ new Among("ur\u0103\u0163i", -1, 1),
+ new Among("\u00E2r\u0103\u0163i", -1, 1), new Among("am", -1, 1),
+ new Among("eam", 54, 1), new Among("iam", 54, 1),
+ new Among("em", -1, 2), new Among("asem", 57, 1),
+ new Among("sesem", 57, 2), new Among("isem", 57, 1),
+ new Among("usem", 57, 1), new Among("\u00E2sem", 57, 1),
+ new Among("im", -1, 2), new Among("\u00E2m", -1, 2),
+ new Among("\u0103m", -1, 2), new Among("ar\u0103m", 65, 1),
+ new Among("ser\u0103m", 65, 2), new Among("aser\u0103m", 67, 1),
+ new Among("seser\u0103m", 67, 2), new Among("iser\u0103m", 67, 1),
+ new Among("user\u0103m", 67, 1),
+ new Among("\u00E2ser\u0103m", 67, 1),
+ new Among("ir\u0103m", 65, 1), new Among("ur\u0103m", 65, 1),
+ new Among("\u00E2r\u0103m", 65, 1), new Among("au", -1, 1),
+ new Among("eau", 76, 1), new Among("iau", 76, 1),
+ new Among("indu", -1, 1), new Among("\u00E2ndu", -1, 1),
+ new Among("ez", -1, 1), new Among("easc\u0103", -1, 1),
+ new Among("ar\u0103", -1, 1), new Among("ser\u0103", -1, 2),
+ new Among("aser\u0103", 84, 1), new Among("seser\u0103", 84, 2),
+ new Among("iser\u0103", 84, 1), new Among("user\u0103", 84, 1),
+ new Among("\u00E2ser\u0103", 84, 1), new Among("ir\u0103", -1, 1),
+ new Among("ur\u0103", -1, 1), new Among("\u00E2r\u0103", -1, 1),
+ new Among("eaz\u0103", -1, 1)
+ ],
+ a_5 = [new Among("a", -1, 1),
+ new Among("e", -1, 1), new Among("ie", 1, 1),
+ new Among("i", -1, 1), new Among("\u0103", -1, 1)
+ ],
+ g_v = [17, 65,
+ 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 32, 0, 0, 4
+ ],
+ B_standard_suffix_removed, I_p2, I_p1, I_pV, sbp = new SnowballProgram();
+ this.setCurrent = function(word) {
+ sbp.setCurrent(word);
+ };
+ this.getCurrent = function() {
+ return sbp.getCurrent();
+ };
+
+ function habr1(c1, c2) {
+ if (sbp.eq_s(1, c1)) {
+ sbp.ket = sbp.cursor;
+ if (sbp.in_grouping(g_v, 97, 259))
+ sbp.slice_from(c2);
+ }
+ }
+
+ function r_prelude() {
+ var v_1, v_2;
+ while (true) {
+ v_1 = sbp.cursor;
+ if (sbp.in_grouping(g_v, 97, 259)) {
+ v_2 = sbp.cursor;
+ sbp.bra = v_2;
+ habr1("u", "U");
+ sbp.cursor = v_2;
+ habr1("i", "I");
+ }
+ sbp.cursor = v_1;
+ if (sbp.cursor >= sbp.limit) {
+ break;
+ }
+ sbp.cursor++;
+ }
+ }
+
+ function habr2() {
+ if (sbp.out_grouping(g_v, 97, 259)) {
+ while (!sbp.in_grouping(g_v, 97, 259)) {
+ if (sbp.cursor >= sbp.limit)
+ return true;
+ sbp.cursor++;
+ }
+ return false;
+ }
+ return true;
+ }
+
+ function habr3() {
+ if (sbp.in_grouping(g_v, 97, 259)) {
+ while (!sbp.out_grouping(g_v, 97, 259)) {
+ if (sbp.cursor >= sbp.limit)
+ return true;
+ sbp.cursor++;
+ }
+ }
+ return false;
+ }
+
+ function habr4() {
+ var v_1 = sbp.cursor,
+ v_2, v_3;
+ if (sbp.in_grouping(g_v, 97, 259)) {
+ v_2 = sbp.cursor;
+ if (habr2()) {
+ sbp.cursor = v_2;
+ if (!habr3()) {
+ I_pV = sbp.cursor;
+ return;
+ }
+ } else {
+ I_pV = sbp.cursor;
+ return;
+ }
+ }
+ sbp.cursor = v_1;
+ if (sbp.out_grouping(g_v, 97, 259)) {
+ v_3 = sbp.cursor;
+ if (habr2()) {
+ sbp.cursor = v_3;
+ if (sbp.in_grouping(g_v, 97, 259) && sbp.cursor < sbp.limit)
+ sbp.cursor++;
+ }
+ I_pV = sbp.cursor;
+ }
+ }
+
+ function habr5() {
+ while (!sbp.in_grouping(g_v, 97, 259)) {
+ if (sbp.cursor >= sbp.limit)
+ return false;
+ sbp.cursor++;
+ }
+ while (!sbp.out_grouping(g_v, 97, 259)) {
+ if (sbp.cursor >= sbp.limit)
+ return false;
+ sbp.cursor++;
+ }
+ return true;
+ }
+
+ function r_mark_regions() {
+ var v_1 = sbp.cursor;
+ I_pV = sbp.limit;
+ I_p1 = I_pV;
+ I_p2 = I_pV;
+ habr4();
+ sbp.cursor = v_1;
+ if (habr5()) {
+ I_p1 = sbp.cursor;
+ if (habr5())
+ I_p2 = sbp.cursor;
+ }
+ }
+
+ function r_postlude() {
+ var among_var;
+ while (true) {
+ sbp.bra = sbp.cursor;
+ among_var = sbp.find_among(a_0, 3);
+ if (among_var) {
+ sbp.ket = sbp.cursor;
+ switch (among_var) {
+ case 1:
+ sbp.slice_from("i");
+ continue;
+ case 2:
+ sbp.slice_from("u");
+ continue;
+ case 3:
+ if (sbp.cursor >= sbp.limit)
+ break;
+ sbp.cursor++;
+ continue;
+ }
+ }
+ break;
+ }
+ }
+
+ function r_RV() {
+ return I_pV <= sbp.cursor;
+ }
+
+ function r_R1() {
+ return I_p1 <= sbp.cursor;
+ }
+
+ function r_R2() {
+ return I_p2 <= sbp.cursor;
+ }
+
+ function r_step_0() {
+ var among_var, v_1;
+ sbp.ket = sbp.cursor;
+ among_var = sbp.find_among_b(a_1, 16);
+ if (among_var) {
+ sbp.bra = sbp.cursor;
+ if (r_R1()) {
+ switch (among_var) {
+ case 1:
+ sbp.slice_del();
+ break;
+ case 2:
+ sbp.slice_from("a");
+ break;
+ case 3:
+ sbp.slice_from("e");
+ break;
+ case 4:
+ sbp.slice_from("i");
+ break;
+ case 5:
+ v_1 = sbp.limit - sbp.cursor;
+ if (!sbp.eq_s_b(2, "ab")) {
+ sbp.cursor = sbp.limit - v_1;
+ sbp.slice_from("i");
+ }
+ break;
+ case 6:
+ sbp.slice_from("at");
+ break;
+ case 7:
+ sbp.slice_from("a\u0163i");
+ break;
+ }
+ }
+ }
+ }
+
+ function r_combo_suffix() {
+ var among_var, v_1 = sbp.limit - sbp.cursor;
+ sbp.ket = sbp.cursor;
+ among_var = sbp.find_among_b(a_2, 46);
+ if (among_var) {
+ sbp.bra = sbp.cursor;
+ if (r_R1()) {
+ switch (among_var) {
+ case 1:
+ sbp.slice_from("abil");
+ break;
+ case 2:
+ sbp.slice_from("ibil");
+ break;
+ case 3:
+ sbp.slice_from("iv");
+ break;
+ case 4:
+ sbp.slice_from("ic");
+ break;
+ case 5:
+ sbp.slice_from("at");
+ break;
+ case 6:
+ sbp.slice_from("it");
+ break;
+ }
+ B_standard_suffix_removed = true;
+ sbp.cursor = sbp.limit - v_1;
+ return true;
+ }
+ }
+ return false;
+ }
+
+ function r_standard_suffix() {
+ var among_var, v_1;
+ B_standard_suffix_removed = false;
+ while (true) {
+ v_1 = sbp.limit - sbp.cursor;
+ if (!r_combo_suffix()) {
+ sbp.cursor = sbp.limit - v_1;
+ break;
+ }
+ }
+ sbp.ket = sbp.cursor;
+ among_var = sbp.find_among_b(a_3, 62);
+ if (among_var) {
+ sbp.bra = sbp.cursor;
+ if (r_R2()) {
+ switch (among_var) {
+ case 1:
+ sbp.slice_del();
+ break;
+ case 2:
+ if (sbp.eq_s_b(1, "\u0163")) {
+ sbp.bra = sbp.cursor;
+ sbp.slice_from("t");
+ }
+ break;
+ case 3:
+ sbp.slice_from("ist");
+ break;
+ }
+ B_standard_suffix_removed = true;
+ }
+ }
+ }
+
+ function r_verb_suffix() {
+ var among_var, v_1, v_2;
+ if (sbp.cursor >= I_pV) {
+ v_1 = sbp.limit_backward;
+ sbp.limit_backward = I_pV;
+ sbp.ket = sbp.cursor;
+ among_var = sbp.find_among_b(a_4, 94);
+ if (among_var) {
+ sbp.bra = sbp.cursor;
+ switch (among_var) {
+ case 1:
+ v_2 = sbp.limit - sbp.cursor;
+ if (!sbp.out_grouping_b(g_v, 97, 259)) {
+ sbp.cursor = sbp.limit - v_2;
+ if (!sbp.eq_s_b(1, "u"))
+ break;
+ }
+ case 2:
+ sbp.slice_del();
+ break;
+ }
+ }
+ sbp.limit_backward = v_1;
+ }
+ }
+
+ function r_vowel_suffix() {
+ var among_var;
+ sbp.ket = sbp.cursor;
+ among_var = sbp.find_among_b(a_5, 5);
+ if (among_var) {
+ sbp.bra = sbp.cursor;
+ if (r_RV() && among_var == 1)
+ sbp.slice_del();
+ }
+ }
+ this.stem = function() {
+ var v_1 = sbp.cursor;
+ r_prelude();
+ sbp.cursor = v_1;
+ r_mark_regions();
+ sbp.limit_backward = v_1;
+ sbp.cursor = sbp.limit;
+ r_step_0();
+ sbp.cursor = sbp.limit;
+ r_standard_suffix();
+ sbp.cursor = sbp.limit;
+ if (!B_standard_suffix_removed) {
+ sbp.cursor = sbp.limit;
+ r_verb_suffix();
+ sbp.cursor = sbp.limit;
+ }
+ r_vowel_suffix();
+ sbp.cursor = sbp.limit_backward;
+ r_postlude();
+ return true;
+ }
+ };
+
+ /* and return a function that stems a word for the current locale */
+ return function(token) {
+ // for lunr version 2
+ if (typeof token.update === "function") {
+ return token.update(function(word) {
+ st.setCurrent(word);
+ st.stem();
+ return st.getCurrent();
+ })
+ } else { // for lunr version <= 1
+ st.setCurrent(token);
+ st.stem();
+ return st.getCurrent();
+ }
+ }
+ })();
+
+ lunr.Pipeline.registerFunction(lunr.ro.stemmer, 'stemmer-ro');
+
+ lunr.ro.stopWordFilter = lunr.generateStopWordFilter('acea aceasta această aceea acei aceia acel acela acele acelea acest acesta aceste acestea aceşti aceştia acolo acord acum ai aia aibă aici al ale alea altceva altcineva am ar are asemenea asta astea astăzi asupra au avea avem aveţi azi aş aşadar aţi bine bucur bună ca care caut ce cel ceva chiar cinci cine cineva contra cu cum cumva curând curînd când cât câte câtva câţi cînd cît cîte cîtva cîţi că căci cărei căror cărui către da dacă dar datorită dată dau de deci deja deoarece departe deşi din dinaintea dintr- dintre doi doilea două drept după dă ea ei el ele eram este eu eşti face fata fi fie fiecare fii fim fiu fiţi frumos fără graţie halbă iar ieri la le li lor lui lângă lîngă mai mea mei mele mereu meu mi mie mine mult multă mulţi mulţumesc mâine mîine mă ne nevoie nici nicăieri nimeni nimeri nimic nişte noastre noastră noi noroc nostru nouă noştri nu opt ori oricare orice oricine oricum oricând oricât oricînd oricît oriunde patra patru patrulea pe pentru peste pic poate pot prea prima primul prin puţin puţina puţină până pînă rog sa sale sau se spate spre sub sunt suntem sunteţi sută sînt sîntem sînteţi să săi său ta tale te timp tine toate toată tot totuşi toţi trei treia treilea tu tăi tău un una unde undeva unei uneia unele uneori unii unor unora unu unui unuia unul vi voastre voastră voi vostru vouă voştri vreme vreo vreun vă zece zero zi zice îi îl îmi împotriva în înainte înaintea încotro încât încît între întrucât întrucît îţi ăla ălea ăsta ăstea ăştia şapte şase şi ştiu ţi ţie'.split(' '));
+
+ lunr.Pipeline.registerFunction(lunr.ro.stopWordFilter, 'stopWordFilter-ro');
+ };
+}))
\ No newline at end of file
diff --git a/venv/lib/python3.11/site-packages/mkdocs/contrib/search/lunr-language/lunr.ru.js b/venv/lib/python3.11/site-packages/mkdocs/contrib/search/lunr-language/lunr.ru.js
new file mode 100644
index 0000000..3e79452
--- /dev/null
+++ b/venv/lib/python3.11/site-packages/mkdocs/contrib/search/lunr-language/lunr.ru.js
@@ -0,0 +1,391 @@
+/*!
+ * Lunr languages, `Russian` language
+ * https://github.com/MihaiValentin/lunr-languages
+ *
+ * Copyright 2014, Mihai Valentin
+ * http://www.mozilla.org/MPL/
+ */
+/*!
+ * based on
+ * Snowball JavaScript Library v0.3
+ * http://code.google.com/p/urim/
+ * http://snowball.tartarus.org/
+ *
+ * Copyright 2010, Oleg Mazko
+ * http://www.mozilla.org/MPL/
+ */
+
+/**
+ * export the module via AMD, CommonJS or as a browser global
+ * Export code from https://github.com/umdjs/umd/blob/master/returnExports.js
+ */
+;
+(function(root, factory) {
+ if (typeof define === 'function' && define.amd) {
+ // AMD. Register as an anonymous module.
+ define(factory)
+ } else if (typeof exports === 'object') {
+ /**
+ * Node. Does not work with strict CommonJS, but
+ * only CommonJS-like environments that support module.exports,
+ * like Node.
+ */
+ module.exports = factory()
+ } else {
+ // Browser globals (root is window)
+ factory()(root.lunr);
+ }
+}(this, function() {
+ /**
+ * Just return a value to define the module export.
+ * This example returns an object, but the module
+ * can return a function as the exported value.
+ */
+ return function(lunr) {
+ /* throw error if lunr is not yet included */
+ if ('undefined' === typeof lunr) {
+ throw new Error('Lunr is not present. Please include / require Lunr before this script.');
+ }
+
+ /* throw error if lunr stemmer support is not yet included */
+ if ('undefined' === typeof lunr.stemmerSupport) {
+ throw new Error('Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.');
+ }
+
+ /* register specific locale function */
+ lunr.ru = function() {
+ this.pipeline.reset();
+ this.pipeline.add(
+ lunr.ru.trimmer,
+ lunr.ru.stopWordFilter,
+ lunr.ru.stemmer
+ );
+
+ // for lunr version 2
+ // this is necessary so that every searched word is also stemmed before
+ // in lunr <= 1 this is not needed, as it is done using the normal pipeline
+ if (this.searchPipeline) {
+ this.searchPipeline.reset();
+ this.searchPipeline.add(lunr.ru.stemmer)
+ }
+ };
+
+ /* lunr trimmer function */
+ lunr.ru.wordCharacters = "\u0400-\u0484\u0487-\u052F\u1D2B\u1D78\u2DE0-\u2DFF\uA640-\uA69F\uFE2E\uFE2F";
+ lunr.ru.trimmer = lunr.trimmerSupport.generateTrimmer(lunr.ru.wordCharacters);
+
+ lunr.Pipeline.registerFunction(lunr.ru.trimmer, 'trimmer-ru');
+
+ /* lunr stemmer function */
+ lunr.ru.stemmer = (function() {
+ /* create the wrapped stemmer object */
+ var Among = lunr.stemmerSupport.Among,
+ SnowballProgram = lunr.stemmerSupport.SnowballProgram,
+ st = new function RussianStemmer() {
+ var a_0 = [new Among("\u0432", -1, 1), new Among("\u0438\u0432", 0, 2),
+ new Among("\u044B\u0432", 0, 2),
+ new Among("\u0432\u0448\u0438", -1, 1),
+ new Among("\u0438\u0432\u0448\u0438", 3, 2),
+ new Among("\u044B\u0432\u0448\u0438", 3, 2),
+ new Among("\u0432\u0448\u0438\u0441\u044C", -1, 1),
+ new Among("\u0438\u0432\u0448\u0438\u0441\u044C", 6, 2),
+ new Among("\u044B\u0432\u0448\u0438\u0441\u044C", 6, 2)
+ ],
+ a_1 = [
+ new Among("\u0435\u0435", -1, 1), new Among("\u0438\u0435", -1, 1),
+ new Among("\u043E\u0435", -1, 1), new Among("\u044B\u0435", -1, 1),
+ new Among("\u0438\u043C\u0438", -1, 1),
+ new Among("\u044B\u043C\u0438", -1, 1),
+ new Among("\u0435\u0439", -1, 1), new Among("\u0438\u0439", -1, 1),
+ new Among("\u043E\u0439", -1, 1), new Among("\u044B\u0439", -1, 1),
+ new Among("\u0435\u043C", -1, 1), new Among("\u0438\u043C", -1, 1),
+ new Among("\u043E\u043C", -1, 1), new Among("\u044B\u043C", -1, 1),
+ new Among("\u0435\u0433\u043E", -1, 1),
+ new Among("\u043E\u0433\u043E", -1, 1),
+ new Among("\u0435\u043C\u0443", -1, 1),
+ new Among("\u043E\u043C\u0443", -1, 1),
+ new Among("\u0438\u0445", -1, 1), new Among("\u044B\u0445", -1, 1),
+ new Among("\u0435\u044E", -1, 1), new Among("\u043E\u044E", -1, 1),
+ new Among("\u0443\u044E", -1, 1), new Among("\u044E\u044E", -1, 1),
+ new Among("\u0430\u044F", -1, 1), new Among("\u044F\u044F", -1, 1)
+ ],
+ a_2 = [
+ new Among("\u0435\u043C", -1, 1), new Among("\u043D\u043D", -1, 1),
+ new Among("\u0432\u0448", -1, 1),
+ new Among("\u0438\u0432\u0448", 2, 2),
+ new Among("\u044B\u0432\u0448", 2, 2), new Among("\u0449", -1, 1),
+ new Among("\u044E\u0449", 5, 1),
+ new Among("\u0443\u044E\u0449", 6, 2)
+ ],
+ a_3 = [
+ new Among("\u0441\u044C", -1, 1), new Among("\u0441\u044F", -1, 1)
+ ],
+ a_4 = [
+ new Among("\u043B\u0430", -1, 1),
+ new Among("\u0438\u043B\u0430", 0, 2),
+ new Among("\u044B\u043B\u0430", 0, 2),
+ new Among("\u043D\u0430", -1, 1),
+ new Among("\u0435\u043D\u0430", 3, 2),
+ new Among("\u0435\u0442\u0435", -1, 1),
+ new Among("\u0438\u0442\u0435", -1, 2),
+ new Among("\u0439\u0442\u0435", -1, 1),
+ new Among("\u0435\u0439\u0442\u0435", 7, 2),
+ new Among("\u0443\u0439\u0442\u0435", 7, 2),
+ new Among("\u043B\u0438", -1, 1),
+ new Among("\u0438\u043B\u0438", 10, 2),
+ new Among("\u044B\u043B\u0438", 10, 2), new Among("\u0439", -1, 1),
+ new Among("\u0435\u0439", 13, 2), new Among("\u0443\u0439", 13, 2),
+ new Among("\u043B", -1, 1), new Among("\u0438\u043B", 16, 2),
+ new Among("\u044B\u043B", 16, 2), new Among("\u0435\u043C", -1, 1),
+ new Among("\u0438\u043C", -1, 2), new Among("\u044B\u043C", -1, 2),
+ new Among("\u043D", -1, 1), new Among("\u0435\u043D", 22, 2),
+ new Among("\u043B\u043E", -1, 1),
+ new Among("\u0438\u043B\u043E", 24, 2),
+ new Among("\u044B\u043B\u043E", 24, 2),
+ new Among("\u043D\u043E", -1, 1),
+ new Among("\u0435\u043D\u043E", 27, 2),
+ new Among("\u043D\u043D\u043E", 27, 1),
+ new Among("\u0435\u0442", -1, 1),
+ new Among("\u0443\u0435\u0442", 30, 2),
+ new Among("\u0438\u0442", -1, 2), new Among("\u044B\u0442", -1, 2),
+ new Among("\u044E\u0442", -1, 1),
+ new Among("\u0443\u044E\u0442", 34, 2),
+ new Among("\u044F\u0442", -1, 2), new Among("\u043D\u044B", -1, 1),
+ new Among("\u0435\u043D\u044B", 37, 2),
+ new Among("\u0442\u044C", -1, 1),
+ new Among("\u0438\u0442\u044C", 39, 2),
+ new Among("\u044B\u0442\u044C", 39, 2),
+ new Among("\u0435\u0448\u044C", -1, 1),
+ new Among("\u0438\u0448\u044C", -1, 2), new Among("\u044E", -1, 2),
+ new Among("\u0443\u044E", 44, 2)
+ ],
+ a_5 = [
+ new Among("\u0430", -1, 1), new Among("\u0435\u0432", -1, 1),
+ new Among("\u043E\u0432", -1, 1), new Among("\u0435", -1, 1),
+ new Among("\u0438\u0435", 3, 1), new Among("\u044C\u0435", 3, 1),
+ new Among("\u0438", -1, 1), new Among("\u0435\u0438", 6, 1),
+ new Among("\u0438\u0438", 6, 1),
+ new Among("\u0430\u043C\u0438", 6, 1),
+ new Among("\u044F\u043C\u0438", 6, 1),
+ new Among("\u0438\u044F\u043C\u0438", 10, 1),
+ new Among("\u0439", -1, 1), new Among("\u0435\u0439", 12, 1),
+ new Among("\u0438\u0435\u0439", 13, 1),
+ new Among("\u0438\u0439", 12, 1), new Among("\u043E\u0439", 12, 1),
+ new Among("\u0430\u043C", -1, 1), new Among("\u0435\u043C", -1, 1),
+ new Among("\u0438\u0435\u043C", 18, 1),
+ new Among("\u043E\u043C", -1, 1), new Among("\u044F\u043C", -1, 1),
+ new Among("\u0438\u044F\u043C", 21, 1), new Among("\u043E", -1, 1),
+ new Among("\u0443", -1, 1), new Among("\u0430\u0445", -1, 1),
+ new Among("\u044F\u0445", -1, 1),
+ new Among("\u0438\u044F\u0445", 26, 1), new Among("\u044B", -1, 1),
+ new Among("\u044C", -1, 1), new Among("\u044E", -1, 1),
+ new Among("\u0438\u044E", 30, 1), new Among("\u044C\u044E", 30, 1),
+ new Among("\u044F", -1, 1), new Among("\u0438\u044F", 33, 1),
+ new Among("\u044C\u044F", 33, 1)
+ ],
+ a_6 = [
+ new Among("\u043E\u0441\u0442", -1, 1),
+ new Among("\u043E\u0441\u0442\u044C", -1, 1)
+ ],
+ a_7 = [
+ new Among("\u0435\u0439\u0448\u0435", -1, 1),
+ new Among("\u043D", -1, 2), new Among("\u0435\u0439\u0448", -1, 1),
+ new Among("\u044C", -1, 3)
+ ],
+ g_v = [33, 65, 8, 232],
+ I_p2, I_pV, sbp = new SnowballProgram();
+ this.setCurrent = function(word) {
+ sbp.setCurrent(word);
+ };
+ this.getCurrent = function() {
+ return sbp.getCurrent();
+ };
+
+ function habr3() {
+ while (!sbp.in_grouping(g_v, 1072, 1103)) {
+ if (sbp.cursor >= sbp.limit)
+ return false;
+ sbp.cursor++;
+ }
+ return true;
+ }
+
+ function habr4() {
+ while (!sbp.out_grouping(g_v, 1072, 1103)) {
+ if (sbp.cursor >= sbp.limit)
+ return false;
+ sbp.cursor++;
+ }
+ return true;
+ }
+
+ function r_mark_regions() {
+ I_pV = sbp.limit;
+ I_p2 = I_pV;
+ if (habr3()) {
+ I_pV = sbp.cursor;
+ if (habr4())
+ if (habr3())
+ if (habr4())
+ I_p2 = sbp.cursor;
+ }
+ }
+
+ function r_R2() {
+ return I_p2 <= sbp.cursor;
+ }
+
+ function habr2(a, n) {
+ var among_var, v_1;
+ sbp.ket = sbp.cursor;
+ among_var = sbp.find_among_b(a, n);
+ if (among_var) {
+ sbp.bra = sbp.cursor;
+ switch (among_var) {
+ case 1:
+ v_1 = sbp.limit - sbp.cursor;
+ if (!sbp.eq_s_b(1, "\u0430")) {
+ sbp.cursor = sbp.limit - v_1;
+ if (!sbp.eq_s_b(1, "\u044F"))
+ return false;
+ }
+ case 2:
+ sbp.slice_del();
+ break;
+ }
+ return true;
+ }
+ return false;
+ }
+
+ function r_perfective_gerund() {
+ return habr2(a_0, 9);
+ }
+
+ function habr1(a, n) {
+ var among_var;
+ sbp.ket = sbp.cursor;
+ among_var = sbp.find_among_b(a, n);
+ if (among_var) {
+ sbp.bra = sbp.cursor;
+ if (among_var == 1)
+ sbp.slice_del();
+ return true;
+ }
+ return false;
+ }
+
+ function r_adjective() {
+ return habr1(a_1, 26);
+ }
+
+ function r_adjectival() {
+ var among_var;
+ if (r_adjective()) {
+ habr2(a_2, 8);
+ return true;
+ }
+ return false;
+ }
+
+ function r_reflexive() {
+ return habr1(a_3, 2);
+ }
+
+ function r_verb() {
+ return habr2(a_4, 46);
+ }
+
+ function r_noun() {
+ habr1(a_5, 36);
+ }
+
+ function r_derivational() {
+ var among_var;
+ sbp.ket = sbp.cursor;
+ among_var = sbp.find_among_b(a_6, 2);
+ if (among_var) {
+ sbp.bra = sbp.cursor;
+ if (r_R2() && among_var == 1)
+ sbp.slice_del();
+ }
+ }
+
+ function r_tidy_up() {
+ var among_var;
+ sbp.ket = sbp.cursor;
+ among_var = sbp.find_among_b(a_7, 4);
+ if (among_var) {
+ sbp.bra = sbp.cursor;
+ switch (among_var) {
+ case 1:
+ sbp.slice_del();
+ sbp.ket = sbp.cursor;
+ if (!sbp.eq_s_b(1, "\u043D"))
+ break;
+ sbp.bra = sbp.cursor;
+ case 2:
+ if (!sbp.eq_s_b(1, "\u043D"))
+ break;
+ case 3:
+ sbp.slice_del();
+ break;
+ }
+ }
+ }
+ this.stem = function() {
+ r_mark_regions();
+ sbp.cursor = sbp.limit;
+ if (sbp.cursor < I_pV)
+ return false;
+ sbp.limit_backward = I_pV;
+ if (!r_perfective_gerund()) {
+ sbp.cursor = sbp.limit;
+ if (!r_reflexive())
+ sbp.cursor = sbp.limit;
+ if (!r_adjectival()) {
+ sbp.cursor = sbp.limit;
+ if (!r_verb()) {
+ sbp.cursor = sbp.limit;
+ r_noun();
+ }
+ }
+ }
+ sbp.cursor = sbp.limit;
+ sbp.ket = sbp.cursor;
+ if (sbp.eq_s_b(1, "\u0438")) {
+ sbp.bra = sbp.cursor;
+ sbp.slice_del();
+ } else
+ sbp.cursor = sbp.limit;
+ r_derivational();
+ sbp.cursor = sbp.limit;
+ r_tidy_up();
+ return true;
+ }
+ };
+
+ /* and return a function that stems a word for the current locale */
+ return function(token) {
+ // for lunr version 2
+ if (typeof token.update === "function") {
+ return token.update(function(word) {
+ st.setCurrent(word);
+ st.stem();
+ return st.getCurrent();
+ })
+ } else { // for lunr version <= 1
+ st.setCurrent(token);
+ st.stem();
+ return st.getCurrent();
+ }
+ }
+ })();
+
+ lunr.Pipeline.registerFunction(lunr.ru.stemmer, 'stemmer-ru');
+
+ lunr.ru.stopWordFilter = lunr.generateStopWordFilter('алло без близко более больше будем будет будете будешь будто буду будут будь бы бывает бывь был была были было быть в важная важное важные важный вам вами вас ваш ваша ваше ваши вверх вдали вдруг ведь везде весь вниз внизу во вокруг вон восемнадцатый восемнадцать восемь восьмой вот впрочем времени время все всегда всего всем всеми всему всех всею всю всюду вся всё второй вы г где говорил говорит год года году да давно даже далеко дальше даром два двадцатый двадцать две двенадцатый двенадцать двух девятнадцатый девятнадцать девятый девять действительно дел день десятый десять для до довольно долго должно другая другие других друго другое другой е его ее ей ему если есть еще ещё ею её ж же жизнь за занят занята занято заняты затем зато зачем здесь значит и из или им именно иметь ими имя иногда их к каждая каждое каждые каждый кажется как какая какой кем когда кого ком кому конечно которая которого которой которые который которых кроме кругом кто куда лет ли лишь лучше люди м мало между меля менее меньше меня миллионов мимо мира мне много многочисленная многочисленное многочисленные многочисленный мной мною мог могут мож может можно можхо мои мой мор мочь моя моё мы на наверху над надо назад наиболее наконец нам нами нас начала наш наша наше наши не него недавно недалеко нее ней нельзя нем немного нему непрерывно нередко несколько нет нею неё ни нибудь ниже низко никогда никуда ними них ничего но ну нужно нх о об оба обычно один одиннадцатый одиннадцать однажды однако одного одной около он она они оно опять особенно от отовсюду отсюда очень первый перед по под пожалуйста позже пока пор пора после посреди потом потому почему почти прекрасно при про просто против процентов пятнадцатый пятнадцать пятый пять раз разве рано раньше рядом с сам сама сами самим самими самих само самого самой самом самому саму свое своего своей свои своих свою сеаой себе себя сегодня седьмой сейчас семнадцатый семнадцать семь сих сказал сказала сказать сколько слишком сначала снова со собой собою совсем спасибо стал суть т та так такая также такие такое такой там твой твоя твоё те тебе тебя тем теми теперь тех то тобой тобою тогда того тоже только том тому тот тою третий три тринадцатый тринадцать ту туда тут ты тысяч у уж уже уметь хорошо хотеть хоть хотя хочешь часто чаще чего человек чем чему через четвертый четыре четырнадцатый четырнадцать что чтоб чтобы чуть шестнадцатый шестнадцать шестой шесть эта эти этим этими этих это этого этой этом этому этот эту я а'.split(' '));
+
+ lunr.Pipeline.registerFunction(lunr.ru.stopWordFilter, 'stopWordFilter-ru');
+ };
+}))
\ No newline at end of file
diff --git a/venv/lib/python3.11/site-packages/mkdocs/contrib/search/lunr-language/lunr.stemmer.support.js b/venv/lib/python3.11/site-packages/mkdocs/contrib/search/lunr-language/lunr.stemmer.support.js
new file mode 100644
index 0000000..896476a
--- /dev/null
+++ b/venv/lib/python3.11/site-packages/mkdocs/contrib/search/lunr-language/lunr.stemmer.support.js
@@ -0,0 +1,304 @@
+/*!
+ * Snowball JavaScript Library v0.3
+ * http://code.google.com/p/urim/
+ * http://snowball.tartarus.org/
+ *
+ * Copyright 2010, Oleg Mazko
+ * http://www.mozilla.org/MPL/
+ */
+
+/**
+ * export the module via AMD, CommonJS or as a browser global
+ * Export code from https://github.com/umdjs/umd/blob/master/returnExports.js
+ */
+;(function (root, factory) {
+ if (typeof define === 'function' && define.amd) {
+ // AMD. Register as an anonymous module.
+ define(factory)
+ } else if (typeof exports === 'object') {
+ /**
+ * Node. Does not work with strict CommonJS, but
+ * only CommonJS-like environments that support module.exports,
+ * like Node.
+ */
+ module.exports = factory()
+ } else {
+ // Browser globals (root is window)
+ factory()(root.lunr);
+ }
+}(this, function () {
+ /**
+ * Just return a value to define the module export.
+ * This example returns an object, but the module
+ * can return a function as the exported value.
+ */
+ return function(lunr) {
+ /* provides utilities for the included stemmers */
+ lunr.stemmerSupport = {
+ Among: function(s, substring_i, result, method) {
+ this.toCharArray = function(s) {
+ var sLength = s.length, charArr = new Array(sLength);
+ for (var i = 0; i < sLength; i++)
+ charArr[i] = s.charCodeAt(i);
+ return charArr;
+ };
+
+ if ((!s && s != "") || (!substring_i && (substring_i != 0)) || !result)
+ throw ("Bad Among initialisation: s:" + s + ", substring_i: "
+ + substring_i + ", result: " + result);
+ this.s_size = s.length;
+ this.s = this.toCharArray(s);
+ this.substring_i = substring_i;
+ this.result = result;
+ this.method = method;
+ },
+ SnowballProgram: function() {
+ var current;
+ return {
+ bra : 0,
+ ket : 0,
+ limit : 0,
+ cursor : 0,
+ limit_backward : 0,
+ setCurrent : function(word) {
+ current = word;
+ this.cursor = 0;
+ this.limit = word.length;
+ this.limit_backward = 0;
+ this.bra = this.cursor;
+ this.ket = this.limit;
+ },
+ getCurrent : function() {
+ var result = current;
+ current = null;
+ return result;
+ },
+ in_grouping : function(s, min, max) {
+ if (this.cursor < this.limit) {
+ var ch = current.charCodeAt(this.cursor);
+ if (ch <= max && ch >= min) {
+ ch -= min;
+ if (s[ch >> 3] & (0X1 << (ch & 0X7))) {
+ this.cursor++;
+ return true;
+ }
+ }
+ }
+ return false;
+ },
+ in_grouping_b : function(s, min, max) {
+ if (this.cursor > this.limit_backward) {
+ var ch = current.charCodeAt(this.cursor - 1);
+ if (ch <= max && ch >= min) {
+ ch -= min;
+ if (s[ch >> 3] & (0X1 << (ch & 0X7))) {
+ this.cursor--;
+ return true;
+ }
+ }
+ }
+ return false;
+ },
+ out_grouping : function(s, min, max) {
+ if (this.cursor < this.limit) {
+ var ch = current.charCodeAt(this.cursor);
+ if (ch > max || ch < min) {
+ this.cursor++;
+ return true;
+ }
+ ch -= min;
+ if (!(s[ch >> 3] & (0X1 << (ch & 0X7)))) {
+ this.cursor++;
+ return true;
+ }
+ }
+ return false;
+ },
+ out_grouping_b : function(s, min, max) {
+ if (this.cursor > this.limit_backward) {
+ var ch = current.charCodeAt(this.cursor - 1);
+ if (ch > max || ch < min) {
+ this.cursor--;
+ return true;
+ }
+ ch -= min;
+ if (!(s[ch >> 3] & (0X1 << (ch & 0X7)))) {
+ this.cursor--;
+ return true;
+ }
+ }
+ return false;
+ },
+ eq_s : function(s_size, s) {
+ if (this.limit - this.cursor < s_size)
+ return false;
+ for (var i = 0; i < s_size; i++)
+ if (current.charCodeAt(this.cursor + i) != s.charCodeAt(i))
+ return false;
+ this.cursor += s_size;
+ return true;
+ },
+ eq_s_b : function(s_size, s) {
+ if (this.cursor - this.limit_backward < s_size)
+ return false;
+ for (var i = 0; i < s_size; i++)
+ if (current.charCodeAt(this.cursor - s_size + i) != s
+ .charCodeAt(i))
+ return false;
+ this.cursor -= s_size;
+ return true;
+ },
+ find_among : function(v, v_size) {
+ var i = 0, j = v_size, c = this.cursor, l = this.limit, common_i = 0, common_j = 0, first_key_inspected = false;
+ while (true) {
+ var k = i + ((j - i) >> 1), diff = 0, common = common_i < common_j
+ ? common_i
+ : common_j, w = v[k];
+ for (var i2 = common; i2 < w.s_size; i2++) {
+ if (c + common == l) {
+ diff = -1;
+ break;
+ }
+ diff = current.charCodeAt(c + common) - w.s[i2];
+ if (diff)
+ break;
+ common++;
+ }
+ if (diff < 0) {
+ j = k;
+ common_j = common;
+ } else {
+ i = k;
+ common_i = common;
+ }
+ if (j - i <= 1) {
+ if (i > 0 || j == i || first_key_inspected)
+ break;
+ first_key_inspected = true;
+ }
+ }
+ while (true) {
+ var w = v[i];
+ if (common_i >= w.s_size) {
+ this.cursor = c + w.s_size;
+ if (!w.method)
+ return w.result;
+ var res = w.method();
+ this.cursor = c + w.s_size;
+ if (res)
+ return w.result;
+ }
+ i = w.substring_i;
+ if (i < 0)
+ return 0;
+ }
+ },
+ find_among_b : function(v, v_size) {
+ var i = 0, j = v_size, c = this.cursor, lb = this.limit_backward, common_i = 0, common_j = 0, first_key_inspected = false;
+ while (true) {
+ var k = i + ((j - i) >> 1), diff = 0, common = common_i < common_j
+ ? common_i
+ : common_j, w = v[k];
+ for (var i2 = w.s_size - 1 - common; i2 >= 0; i2--) {
+ if (c - common == lb) {
+ diff = -1;
+ break;
+ }
+ diff = current.charCodeAt(c - 1 - common) - w.s[i2];
+ if (diff)
+ break;
+ common++;
+ }
+ if (diff < 0) {
+ j = k;
+ common_j = common;
+ } else {
+ i = k;
+ common_i = common;
+ }
+ if (j - i <= 1) {
+ if (i > 0 || j == i || first_key_inspected)
+ break;
+ first_key_inspected = true;
+ }
+ }
+ while (true) {
+ var w = v[i];
+ if (common_i >= w.s_size) {
+ this.cursor = c - w.s_size;
+ if (!w.method)
+ return w.result;
+ var res = w.method();
+ this.cursor = c - w.s_size;
+ if (res)
+ return w.result;
+ }
+ i = w.substring_i;
+ if (i < 0)
+ return 0;
+ }
+ },
+ replace_s : function(c_bra, c_ket, s) {
+ var adjustment = s.length - (c_ket - c_bra), left = current
+ .substring(0, c_bra), right = current.substring(c_ket);
+ current = left + s + right;
+ this.limit += adjustment;
+ if (this.cursor >= c_ket)
+ this.cursor += adjustment;
+ else if (this.cursor > c_bra)
+ this.cursor = c_bra;
+ return adjustment;
+ },
+ slice_check : function() {
+ if (this.bra < 0 || this.bra > this.ket || this.ket > this.limit
+ || this.limit > current.length)
+ throw ("faulty slice operation");
+ },
+ slice_from : function(s) {
+ this.slice_check();
+ this.replace_s(this.bra, this.ket, s);
+ },
+ slice_del : function() {
+ this.slice_from("");
+ },
+ insert : function(c_bra, c_ket, s) {
+ var adjustment = this.replace_s(c_bra, c_ket, s);
+ if (c_bra <= this.bra)
+ this.bra += adjustment;
+ if (c_bra <= this.ket)
+ this.ket += adjustment;
+ },
+ slice_to : function() {
+ this.slice_check();
+ return current.substring(this.bra, this.ket);
+ },
+ eq_v_b : function(s) {
+ return this.eq_s_b(s.length, s);
+ }
+ };
+ }
+ };
+
+ lunr.trimmerSupport = {
+ generateTrimmer: function(wordCharacters) {
+ var startRegex = new RegExp("^[^" + wordCharacters + "]+")
+ var endRegex = new RegExp("[^" + wordCharacters + "]+$")
+
+ return function(token) {
+ // for lunr version 2
+ if (typeof token.update === "function") {
+ return token.update(function (s) {
+ return s
+ .replace(startRegex, '')
+ .replace(endRegex, '');
+ })
+ } else { // for lunr version 1
+ return token
+ .replace(startRegex, '')
+ .replace(endRegex, '');
+ }
+ };
+ }
+ }
+ }
+}));
diff --git a/venv/lib/python3.11/site-packages/mkdocs/contrib/search/lunr-language/lunr.sv.js b/venv/lib/python3.11/site-packages/mkdocs/contrib/search/lunr-language/lunr.sv.js
new file mode 100644
index 0000000..6a7d932
--- /dev/null
+++ b/venv/lib/python3.11/site-packages/mkdocs/contrib/search/lunr-language/lunr.sv.js
@@ -0,0 +1,256 @@
+/*!
+ * Lunr languages, `Swedish` language
+ * https://github.com/MihaiValentin/lunr-languages
+ *
+ * Copyright 2014, Mihai Valentin
+ * http://www.mozilla.org/MPL/
+ */
+/*!
+ * based on
+ * Snowball JavaScript Library v0.3
+ * http://code.google.com/p/urim/
+ * http://snowball.tartarus.org/
+ *
+ * Copyright 2010, Oleg Mazko
+ * http://www.mozilla.org/MPL/
+ */
+
+/**
+ * export the module via AMD, CommonJS or as a browser global
+ * Export code from https://github.com/umdjs/umd/blob/master/returnExports.js
+ */
+;
+(function(root, factory) {
+ if (typeof define === 'function' && define.amd) {
+ // AMD. Register as an anonymous module.
+ define(factory)
+ } else if (typeof exports === 'object') {
+ /**
+ * Node. Does not work with strict CommonJS, but
+ * only CommonJS-like environments that support module.exports,
+ * like Node.
+ */
+ module.exports = factory()
+ } else {
+ // Browser globals (root is window)
+ factory()(root.lunr);
+ }
+}(this, function() {
+ /**
+ * Just return a value to define the module export.
+ * This example returns an object, but the module
+ * can return a function as the exported value.
+ */
+ return function(lunr) {
+ /* throw error if lunr is not yet included */
+ if ('undefined' === typeof lunr) {
+ throw new Error('Lunr is not present. Please include / require Lunr before this script.');
+ }
+
+ /* throw error if lunr stemmer support is not yet included */
+ if ('undefined' === typeof lunr.stemmerSupport) {
+ throw new Error('Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.');
+ }
+
+ /* register specific locale function */
+ lunr.sv = function() {
+ this.pipeline.reset();
+ this.pipeline.add(
+ lunr.sv.trimmer,
+ lunr.sv.stopWordFilter,
+ lunr.sv.stemmer
+ );
+
+ // for lunr version 2
+ // this is necessary so that every searched word is also stemmed before
+ // in lunr <= 1 this is not needed, as it is done using the normal pipeline
+ if (this.searchPipeline) {
+ this.searchPipeline.reset();
+ this.searchPipeline.add(lunr.sv.stemmer)
+ }
+ };
+
+ /* lunr trimmer function */
+ lunr.sv.wordCharacters = "A-Za-z\xAA\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02B8\u02E0-\u02E4\u1D00-\u1D25\u1D2C-\u1D5C\u1D62-\u1D65\u1D6B-\u1D77\u1D79-\u1DBE\u1E00-\u1EFF\u2071\u207F\u2090-\u209C\u212A\u212B\u2132\u214E\u2160-\u2188\u2C60-\u2C7F\uA722-\uA787\uA78B-\uA7AD\uA7B0-\uA7B7\uA7F7-\uA7FF\uAB30-\uAB5A\uAB5C-\uAB64\uFB00-\uFB06\uFF21-\uFF3A\uFF41-\uFF5A";
+ lunr.sv.trimmer = lunr.trimmerSupport.generateTrimmer(lunr.sv.wordCharacters);
+
+ lunr.Pipeline.registerFunction(lunr.sv.trimmer, 'trimmer-sv');
+
+ /* lunr stemmer function */
+ lunr.sv.stemmer = (function() {
+ /* create the wrapped stemmer object */
+ var Among = lunr.stemmerSupport.Among,
+ SnowballProgram = lunr.stemmerSupport.SnowballProgram,
+ st = new function SwedishStemmer() {
+ var a_0 = [new Among("a", -1, 1), new Among("arna", 0, 1),
+ new Among("erna", 0, 1), new Among("heterna", 2, 1),
+ new Among("orna", 0, 1), new Among("ad", -1, 1),
+ new Among("e", -1, 1), new Among("ade", 6, 1),
+ new Among("ande", 6, 1), new Among("arne", 6, 1),
+ new Among("are", 6, 1), new Among("aste", 6, 1),
+ new Among("en", -1, 1), new Among("anden", 12, 1),
+ new Among("aren", 12, 1), new Among("heten", 12, 1),
+ new Among("ern", -1, 1), new Among("ar", -1, 1),
+ new Among("er", -1, 1), new Among("heter", 18, 1),
+ new Among("or", -1, 1), new Among("s", -1, 2),
+ new Among("as", 21, 1), new Among("arnas", 22, 1),
+ new Among("ernas", 22, 1), new Among("ornas", 22, 1),
+ new Among("es", 21, 1), new Among("ades", 26, 1),
+ new Among("andes", 26, 1), new Among("ens", 21, 1),
+ new Among("arens", 29, 1), new Among("hetens", 29, 1),
+ new Among("erns", 21, 1), new Among("at", -1, 1),
+ new Among("andet", -1, 1), new Among("het", -1, 1),
+ new Among("ast", -1, 1)
+ ],
+ a_1 = [new Among("dd", -1, -1),
+ new Among("gd", -1, -1), new Among("nn", -1, -1),
+ new Among("dt", -1, -1), new Among("gt", -1, -1),
+ new Among("kt", -1, -1), new Among("tt", -1, -1)
+ ],
+ a_2 = [
+ new Among("ig", -1, 1), new Among("lig", 0, 1),
+ new Among("els", -1, 1), new Among("fullt", -1, 3),
+ new Among("l\u00F6st", -1, 2)
+ ],
+ g_v = [17, 65, 16, 1, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 24, 0, 32
+ ],
+ g_s_ending = [119, 127, 149],
+ I_x, I_p1, sbp = new SnowballProgram();
+ this.setCurrent = function(word) {
+ sbp.setCurrent(word);
+ };
+ this.getCurrent = function() {
+ return sbp.getCurrent();
+ };
+
+ function r_mark_regions() {
+ var v_1, c = sbp.cursor + 3;
+ I_p1 = sbp.limit;
+ if (0 <= c || c <= sbp.limit) {
+ I_x = c;
+ while (true) {
+ v_1 = sbp.cursor;
+ if (sbp.in_grouping(g_v, 97, 246)) {
+ sbp.cursor = v_1;
+ break;
+ }
+ sbp.cursor = v_1;
+ if (sbp.cursor >= sbp.limit)
+ return;
+ sbp.cursor++;
+ }
+ while (!sbp.out_grouping(g_v, 97, 246)) {
+ if (sbp.cursor >= sbp.limit)
+ return;
+ sbp.cursor++;
+ }
+ I_p1 = sbp.cursor;
+ if (I_p1 < I_x)
+ I_p1 = I_x;
+ }
+ }
+
+ function r_main_suffix() {
+ var among_var, v_2 = sbp.limit_backward;
+ if (sbp.cursor >= I_p1) {
+ sbp.limit_backward = I_p1;
+ sbp.cursor = sbp.limit;
+ sbp.ket = sbp.cursor;
+ among_var = sbp.find_among_b(a_0, 37);
+ sbp.limit_backward = v_2;
+ if (among_var) {
+ sbp.bra = sbp.cursor;
+ switch (among_var) {
+ case 1:
+ sbp.slice_del();
+ break;
+ case 2:
+ if (sbp.in_grouping_b(g_s_ending, 98, 121))
+ sbp.slice_del();
+ break;
+ }
+ }
+ }
+ }
+
+ function r_consonant_pair() {
+ var v_1 = sbp.limit_backward;
+ if (sbp.cursor >= I_p1) {
+ sbp.limit_backward = I_p1;
+ sbp.cursor = sbp.limit;
+ if (sbp.find_among_b(a_1, 7)) {
+ sbp.cursor = sbp.limit;
+ sbp.ket = sbp.cursor;
+ if (sbp.cursor > sbp.limit_backward) {
+ sbp.bra = --sbp.cursor;
+ sbp.slice_del();
+ }
+ }
+ sbp.limit_backward = v_1;
+ }
+ }
+
+ function r_other_suffix() {
+ var among_var, v_2;
+ if (sbp.cursor >= I_p1) {
+ v_2 = sbp.limit_backward;
+ sbp.limit_backward = I_p1;
+ sbp.cursor = sbp.limit;
+ sbp.ket = sbp.cursor;
+ among_var = sbp.find_among_b(a_2, 5);
+ if (among_var) {
+ sbp.bra = sbp.cursor;
+ switch (among_var) {
+ case 1:
+ sbp.slice_del();
+ break;
+ case 2:
+ sbp.slice_from("l\u00F6s");
+ break;
+ case 3:
+ sbp.slice_from("full");
+ break;
+ }
+ }
+ sbp.limit_backward = v_2;
+ }
+ }
+ this.stem = function() {
+ var v_1 = sbp.cursor;
+ r_mark_regions();
+ sbp.limit_backward = v_1;
+ sbp.cursor = sbp.limit;
+ r_main_suffix();
+ sbp.cursor = sbp.limit;
+ r_consonant_pair();
+ sbp.cursor = sbp.limit;
+ r_other_suffix();
+ return true;
+ }
+ };
+
+ /* and return a function that stems a word for the current locale */
+ return function(token) {
+ // for lunr version 2
+ if (typeof token.update === "function") {
+ return token.update(function(word) {
+ st.setCurrent(word);
+ st.stem();
+ return st.getCurrent();
+ })
+ } else { // for lunr version <= 1
+ st.setCurrent(token);
+ st.stem();
+ return st.getCurrent();
+ }
+ }
+ })();
+
+ lunr.Pipeline.registerFunction(lunr.sv.stemmer, 'stemmer-sv');
+
+ lunr.sv.stopWordFilter = lunr.generateStopWordFilter('alla allt att av blev bli blir blivit de dem den denna deras dess dessa det detta dig din dina ditt du där då efter ej eller en er era ert ett från för ha hade han hans har henne hennes hon honom hur här i icke ingen inom inte jag ju kan kunde man med mellan men mig min mina mitt mot mycket ni nu när någon något några och om oss på samma sedan sig sin sina sitta själv skulle som så sådan sådana sådant till under upp ut utan vad var vara varför varit varje vars vart vem vi vid vilka vilkas vilken vilket vår våra vårt än är åt över'.split(' '));
+
+ lunr.Pipeline.registerFunction(lunr.sv.stopWordFilter, 'stopWordFilter-sv');
+ };
+}))
\ No newline at end of file
diff --git a/venv/lib/python3.11/site-packages/mkdocs/contrib/search/lunr-language/lunr.th.js b/venv/lib/python3.11/site-packages/mkdocs/contrib/search/lunr-language/lunr.th.js
new file mode 100644
index 0000000..2bf7db5
--- /dev/null
+++ b/venv/lib/python3.11/site-packages/mkdocs/contrib/search/lunr-language/lunr.th.js
@@ -0,0 +1,97 @@
+/*!
+ * Lunr languages, `Thai` language
+ * https://github.com/MihaiValentin/lunr-languages
+ *
+ * Copyright 2017, Keerati Thiwanruk
+ * http://www.mozilla.org/MPL/
+ */
+/*!
+ * based on
+ * Snowball JavaScript Library v0.3
+ * http://code.google.com/p/urim/
+ * http://snowball.tartarus.org/
+ *
+ * Copyright 2010, Oleg Mazko
+ * http://www.mozilla.org/MPL/
+ */
+
+/**
+ * export the module via AMD, CommonJS or as a browser global
+ * Export code from https://github.com/umdjs/umd/blob/master/returnExports.js
+ */
+;
+(function(root, factory) {
+ if (typeof define === 'function' && define.amd) {
+ // AMD. Register as an anonymous module.
+ define(factory)
+ } else if (typeof exports === 'object') {
+ /**
+ * Node. Does not work with strict CommonJS, but
+ * only CommonJS-like environments that support module.exports,
+ * like Node.
+ */
+ module.exports = factory()
+ } else {
+ // Browser globals (root is window)
+ factory()(root.lunr);
+ }
+}(this, function() {
+ /**
+ * Just return a value to define the module export.
+ * This example returns an object, but the module
+ * can return a function as the exported value.
+ */
+ return function(lunr) {
+ /* throw error if lunr is not yet included */
+ if ('undefined' === typeof lunr) {
+ throw new Error('Lunr is not present. Please include / require Lunr before this script.');
+ }
+
+ /* throw error if lunr stemmer support is not yet included */
+ if ('undefined' === typeof lunr.stemmerSupport) {
+ throw new Error('Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.');
+ }
+
+ /*
+ Thai tokenization is the same to Japanense, which does not take into account spaces.
+ So, it uses the same logic to assign tokenization function due to different Lunr versions.
+ */
+ var isLunr2 = lunr.version[0] == "2";
+
+ /* register specific locale function */
+ lunr.th = function() {
+ this.pipeline.reset();
+ this.pipeline.add(
+ /*lunr.th.stopWordFilter,*/
+ lunr.th.trimmer
+ );
+
+ if (isLunr2) { // for lunr version 2.0.0
+ this.tokenizer = lunr.th.tokenizer;
+ } else {
+ if (lunr.tokenizer) { // for lunr version 0.6.0
+ lunr.tokenizer = lunr.th.tokenizer;
+ }
+ if (this.tokenizerFn) { // for lunr version 0.7.0 -> 1.0.0
+ this.tokenizerFn = lunr.th.tokenizer;
+ }
+ }
+ };
+
+ /* lunr trimmer function */
+ lunr.th.wordCharacters = "[\u0e00-\u0e7f]";
+ lunr.th.trimmer = lunr.trimmerSupport.generateTrimmer(lunr.th.wordCharacters);
+ lunr.Pipeline.registerFunction(lunr.th.trimmer, 'trimmer-th');
+
+ var segmenter = lunr.wordcut;
+ segmenter.init();
+ lunr.th.tokenizer = function (obj) {
+ //console.log(obj);
+ if (!arguments.length || obj == null || obj == undefined) return []
+ if (Array.isArray(obj)) return obj.map(function (t) { return isLunr2 ? new lunr.Token(t) : t })
+
+ var str = obj.toString().replace(/^\s+/, '');
+ return segmenter.cut(str).split('|');
+ }
+ };
+}))
diff --git a/venv/lib/python3.11/site-packages/mkdocs/contrib/search/lunr-language/lunr.tr.js b/venv/lib/python3.11/site-packages/mkdocs/contrib/search/lunr-language/lunr.tr.js
new file mode 100644
index 0000000..5b4bad8
--- /dev/null
+++ b/venv/lib/python3.11/site-packages/mkdocs/contrib/search/lunr-language/lunr.tr.js
@@ -0,0 +1,1087 @@
+/*!
+ * Lunr languages, `Turkish` language
+ * https://github.com/MihaiValentin/lunr-languages
+ *
+ * Copyright 2014, Mihai Valentin
+ * http://www.mozilla.org/MPL/
+ */
+/*!
+ * based on
+ * Snowball JavaScript Library v0.3
+ * http://code.google.com/p/urim/
+ * http://snowball.tartarus.org/
+ *
+ * Copyright 2010, Oleg Mazko
+ * http://www.mozilla.org/MPL/
+ */
+
+/**
+ * export the module via AMD, CommonJS or as a browser global
+ * Export code from https://github.com/umdjs/umd/blob/master/returnExports.js
+ */
+;
+(function(root, factory) {
+ if (typeof define === 'function' && define.amd) {
+ // AMD. Register as an anonymous module.
+ define(factory)
+ } else if (typeof exports === 'object') {
+ /**
+ * Node. Does not work with strict CommonJS, but
+ * only CommonJS-like environments that support module.exports,
+ * like Node.
+ */
+ module.exports = factory()
+ } else {
+ // Browser globals (root is window)
+ factory()(root.lunr);
+ }
+}(this, function() {
+ /**
+ * Just return a value to define the module export.
+ * This example returns an object, but the module
+ * can return a function as the exported value.
+ */
+ return function(lunr) {
+ /* throw error if lunr is not yet included */
+ if ('undefined' === typeof lunr) {
+ throw new Error('Lunr is not present. Please include / require Lunr before this script.');
+ }
+
+ /* throw error if lunr stemmer support is not yet included */
+ if ('undefined' === typeof lunr.stemmerSupport) {
+ throw new Error('Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.');
+ }
+
+ /* register specific locale function */
+ lunr.tr = function() {
+ this.pipeline.reset();
+ this.pipeline.add(
+ lunr.tr.trimmer,
+ lunr.tr.stopWordFilter,
+ lunr.tr.stemmer
+ );
+
+ // for lunr version 2
+ // this is necessary so that every searched word is also stemmed before
+ // in lunr <= 1 this is not needed, as it is done using the normal pipeline
+ if (this.searchPipeline) {
+ this.searchPipeline.reset();
+ this.searchPipeline.add(lunr.tr.stemmer)
+ }
+ };
+
+ /* lunr trimmer function */
+ lunr.tr.wordCharacters = "A-Za-z\xAA\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02B8\u02E0-\u02E4\u1D00-\u1D25\u1D2C-\u1D5C\u1D62-\u1D65\u1D6B-\u1D77\u1D79-\u1DBE\u1E00-\u1EFF\u2071\u207F\u2090-\u209C\u212A\u212B\u2132\u214E\u2160-\u2188\u2C60-\u2C7F\uA722-\uA787\uA78B-\uA7AD\uA7B0-\uA7B7\uA7F7-\uA7FF\uAB30-\uAB5A\uAB5C-\uAB64\uFB00-\uFB06\uFF21-\uFF3A\uFF41-\uFF5A";
+ lunr.tr.trimmer = lunr.trimmerSupport.generateTrimmer(lunr.tr.wordCharacters);
+
+ lunr.Pipeline.registerFunction(lunr.tr.trimmer, 'trimmer-tr');
+
+ /* lunr stemmer function */
+ lunr.tr.stemmer = (function() {
+ /* create the wrapped stemmer object */
+ var Among = lunr.stemmerSupport.Among,
+ SnowballProgram = lunr.stemmerSupport.SnowballProgram,
+ st = new function TurkishStemmer() {
+ var a_0 = [new Among("m", -1, -1), new Among("n", -1, -1),
+ new Among("miz", -1, -1), new Among("niz", -1, -1),
+ new Among("muz", -1, -1), new Among("nuz", -1, -1),
+ new Among("m\u00FCz", -1, -1), new Among("n\u00FCz", -1, -1),
+ new Among("m\u0131z", -1, -1), new Among("n\u0131z", -1, -1)
+ ],
+ a_1 = [
+ new Among("leri", -1, -1), new Among("lar\u0131", -1, -1)
+ ],
+ a_2 = [
+ new Among("ni", -1, -1), new Among("nu", -1, -1),
+ new Among("n\u00FC", -1, -1), new Among("n\u0131", -1, -1)
+ ],
+ a_3 = [
+ new Among("in", -1, -1), new Among("un", -1, -1),
+ new Among("\u00FCn", -1, -1), new Among("\u0131n", -1, -1)
+ ],
+ a_4 = [
+ new Among("a", -1, -1), new Among("e", -1, -1)
+ ],
+ a_5 = [
+ new Among("na", -1, -1), new Among("ne", -1, -1)
+ ],
+ a_6 = [
+ new Among("da", -1, -1), new Among("ta", -1, -1),
+ new Among("de", -1, -1), new Among("te", -1, -1)
+ ],
+ a_7 = [
+ new Among("nda", -1, -1), new Among("nde", -1, -1)
+ ],
+ a_8 = [
+ new Among("dan", -1, -1), new Among("tan", -1, -1),
+ new Among("den", -1, -1), new Among("ten", -1, -1)
+ ],
+ a_9 = [
+ new Among("ndan", -1, -1), new Among("nden", -1, -1)
+ ],
+ a_10 = [
+ new Among("la", -1, -1), new Among("le", -1, -1)
+ ],
+ a_11 = [
+ new Among("ca", -1, -1), new Among("ce", -1, -1)
+ ],
+ a_12 = [
+ new Among("im", -1, -1), new Among("um", -1, -1),
+ new Among("\u00FCm", -1, -1), new Among("\u0131m", -1, -1)
+ ],
+ a_13 = [
+ new Among("sin", -1, -1), new Among("sun", -1, -1),
+ new Among("s\u00FCn", -1, -1), new Among("s\u0131n", -1, -1)
+ ],
+ a_14 = [
+ new Among("iz", -1, -1), new Among("uz", -1, -1),
+ new Among("\u00FCz", -1, -1), new Among("\u0131z", -1, -1)
+ ],
+ a_15 = [
+ new Among("siniz", -1, -1), new Among("sunuz", -1, -1),
+ new Among("s\u00FCn\u00FCz", -1, -1),
+ new Among("s\u0131n\u0131z", -1, -1)
+ ],
+ a_16 = [
+ new Among("lar", -1, -1), new Among("ler", -1, -1)
+ ],
+ a_17 = [
+ new Among("niz", -1, -1), new Among("nuz", -1, -1),
+ new Among("n\u00FCz", -1, -1), new Among("n\u0131z", -1, -1)
+ ],
+ a_18 = [
+ new Among("dir", -1, -1), new Among("tir", -1, -1),
+ new Among("dur", -1, -1), new Among("tur", -1, -1),
+ new Among("d\u00FCr", -1, -1), new Among("t\u00FCr", -1, -1),
+ new Among("d\u0131r", -1, -1), new Among("t\u0131r", -1, -1)
+ ],
+ a_19 = [
+ new Among("cas\u0131na", -1, -1), new Among("cesine", -1, -1)
+ ],
+ a_20 = [
+ new Among("di", -1, -1), new Among("ti", -1, -1),
+ new Among("dik", -1, -1), new Among("tik", -1, -1),
+ new Among("duk", -1, -1), new Among("tuk", -1, -1),
+ new Among("d\u00FCk", -1, -1), new Among("t\u00FCk", -1, -1),
+ new Among("d\u0131k", -1, -1), new Among("t\u0131k", -1, -1),
+ new Among("dim", -1, -1), new Among("tim", -1, -1),
+ new Among("dum", -1, -1), new Among("tum", -1, -1),
+ new Among("d\u00FCm", -1, -1), new Among("t\u00FCm", -1, -1),
+ new Among("d\u0131m", -1, -1), new Among("t\u0131m", -1, -1),
+ new Among("din", -1, -1), new Among("tin", -1, -1),
+ new Among("dun", -1, -1), new Among("tun", -1, -1),
+ new Among("d\u00FCn", -1, -1), new Among("t\u00FCn", -1, -1),
+ new Among("d\u0131n", -1, -1), new Among("t\u0131n", -1, -1),
+ new Among("du", -1, -1), new Among("tu", -1, -1),
+ new Among("d\u00FC", -1, -1), new Among("t\u00FC", -1, -1),
+ new Among("d\u0131", -1, -1), new Among("t\u0131", -1, -1)
+ ],
+ a_21 = [
+ new Among("sa", -1, -1), new Among("se", -1, -1),
+ new Among("sak", -1, -1), new Among("sek", -1, -1),
+ new Among("sam", -1, -1), new Among("sem", -1, -1),
+ new Among("san", -1, -1), new Among("sen", -1, -1)
+ ],
+ a_22 = [
+ new Among("mi\u015F", -1, -1), new Among("mu\u015F", -1, -1),
+ new Among("m\u00FC\u015F", -1, -1),
+ new Among("m\u0131\u015F", -1, -1)
+ ],
+ a_23 = [new Among("b", -1, 1),
+ new Among("c", -1, 2), new Among("d", -1, 3),
+ new Among("\u011F", -1, 4)
+ ],
+ g_vowel = [17, 65, 16, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 8, 0, 0, 0, 0, 0, 0, 1
+ ],
+ g_U = [
+ 1, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0,
+ 0, 0, 0, 1
+ ],
+ g_vowel1 = [1, 64, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1
+ ],
+ g_vowel2 = [17, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 130
+ ],
+ g_vowel3 = [1, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 1
+ ],
+ g_vowel4 = [17],
+ g_vowel5 = [65],
+ g_vowel6 = [65],
+ B_c_s_n_s, I_strlen, g_habr = [
+ ["a", g_vowel1, 97, 305],
+ ["e", g_vowel2, 101, 252],
+ ["\u0131", g_vowel3, 97, 305],
+ ["i", g_vowel4, 101, 105],
+ ["o", g_vowel5, 111, 117],
+ ["\u00F6", g_vowel6, 246, 252],
+ ["u", g_vowel5, 111, 117]
+ ],
+ sbp = new SnowballProgram();
+ this.setCurrent = function(word) {
+ sbp.setCurrent(word);
+ };
+ this.getCurrent = function() {
+ return sbp.getCurrent();
+ };
+
+ function habr1(g_v, n1, n2) {
+ while (true) {
+ var v_1 = sbp.limit - sbp.cursor;
+ if (sbp.in_grouping_b(g_v, n1, n2)) {
+ sbp.cursor = sbp.limit - v_1;
+ break;
+ }
+ sbp.cursor = sbp.limit - v_1;
+ if (sbp.cursor <= sbp.limit_backward)
+ return false;
+ sbp.cursor--;
+ }
+ return true;
+ }
+
+ function r_check_vowel_harmony() {
+ var v_1, v_2;
+ v_1 = sbp.limit - sbp.cursor;
+ habr1(g_vowel, 97, 305);
+ for (var i = 0; i < g_habr.length; i++) {
+ v_2 = sbp.limit - sbp.cursor;
+ var habr = g_habr[i];
+ if (sbp.eq_s_b(1, habr[0]) && habr1(habr[1], habr[2], habr[3])) {
+ sbp.cursor = sbp.limit - v_1;
+ return true;
+ }
+ sbp.cursor = sbp.limit - v_2;
+ }
+ sbp.cursor = sbp.limit - v_2;
+ if (!sbp.eq_s_b(1, "\u00FC") || !habr1(g_vowel6, 246, 252))
+ return false;
+ sbp.cursor = sbp.limit - v_1;
+ return true;
+ }
+
+ function habr2(f1, f2) {
+ var v_1 = sbp.limit - sbp.cursor,
+ v_2;
+ if (f1()) {
+ sbp.cursor = sbp.limit - v_1;
+ if (sbp.cursor > sbp.limit_backward) {
+ sbp.cursor--;
+ v_2 = sbp.limit - sbp.cursor;
+ if (f2()) {
+ sbp.cursor = sbp.limit - v_2;
+ return true;
+ }
+ }
+ }
+ sbp.cursor = sbp.limit - v_1;
+ if (f1()) {
+ sbp.cursor = sbp.limit - v_1;
+ return false;
+ }
+ sbp.cursor = sbp.limit - v_1;
+ if (sbp.cursor <= sbp.limit_backward)
+ return false;
+ sbp.cursor--;
+ if (!f2())
+ return false;
+ sbp.cursor = sbp.limit - v_1;
+ return true;
+ }
+
+ function habr3(f1) {
+ return habr2(f1, function() {
+ return sbp.in_grouping_b(g_vowel, 97, 305);
+ });
+ }
+
+ function r_mark_suffix_with_optional_n_consonant() {
+ return habr3(function() {
+ return sbp.eq_s_b(1, "n");
+ });
+ }
+
+ function r_mark_suffix_with_optional_s_consonant() {
+ return habr3(function() {
+ return sbp.eq_s_b(1, "s");
+ });
+ }
+
+ function r_mark_suffix_with_optional_y_consonant() {
+ return habr3(function() {
+ return sbp.eq_s_b(1, "y");
+ });
+ }
+
+ function r_mark_suffix_with_optional_U_vowel() {
+ return habr2(function() {
+ return sbp.in_grouping_b(g_U, 105, 305);
+ }, function() {
+ return sbp.out_grouping_b(g_vowel, 97, 305);
+ });
+ }
+
+ function r_mark_possessives() {
+ return sbp.find_among_b(a_0, 10) &&
+ r_mark_suffix_with_optional_U_vowel();
+ }
+
+ function r_mark_sU() {
+ return r_check_vowel_harmony() && sbp.in_grouping_b(g_U, 105, 305) &&
+ r_mark_suffix_with_optional_s_consonant();
+ }
+
+ function r_mark_lArI() {
+ return sbp.find_among_b(a_1, 2);
+ }
+
+ function r_mark_yU() {
+ return r_check_vowel_harmony() && sbp.in_grouping_b(g_U, 105, 305) &&
+ r_mark_suffix_with_optional_y_consonant();
+ }
+
+ function r_mark_nU() {
+ return r_check_vowel_harmony() && sbp.find_among_b(a_2, 4);
+ }
+
+ function r_mark_nUn() {
+ return r_check_vowel_harmony() && sbp.find_among_b(a_3, 4) &&
+ r_mark_suffix_with_optional_n_consonant();
+ }
+
+ function r_mark_yA() {
+ return r_check_vowel_harmony() && sbp.find_among_b(a_4, 2) &&
+ r_mark_suffix_with_optional_y_consonant();
+ }
+
+ function r_mark_nA() {
+ return r_check_vowel_harmony() && sbp.find_among_b(a_5, 2);
+ }
+
+ function r_mark_DA() {
+ return r_check_vowel_harmony() && sbp.find_among_b(a_6, 4);
+ }
+
+ function r_mark_ndA() {
+ return r_check_vowel_harmony() && sbp.find_among_b(a_7, 2);
+ }
+
+ function r_mark_DAn() {
+ return r_check_vowel_harmony() && sbp.find_among_b(a_8, 4);
+ }
+
+ function r_mark_ndAn() {
+ return r_check_vowel_harmony() && sbp.find_among_b(a_9, 2);
+ }
+
+ function r_mark_ylA() {
+ return r_check_vowel_harmony() && sbp.find_among_b(a_10, 2) &&
+ r_mark_suffix_with_optional_y_consonant();
+ }
+
+ function r_mark_ki() {
+ return sbp.eq_s_b(2, "ki");
+ }
+
+ function r_mark_ncA() {
+ return r_check_vowel_harmony() && sbp.find_among_b(a_11, 2) &&
+ r_mark_suffix_with_optional_n_consonant();
+ }
+
+ function r_mark_yUm() {
+ return r_check_vowel_harmony() && sbp.find_among_b(a_12, 4) &&
+ r_mark_suffix_with_optional_y_consonant();
+ }
+
+ function r_mark_sUn() {
+ return r_check_vowel_harmony() && sbp.find_among_b(a_13, 4);
+ }
+
+ function r_mark_yUz() {
+ return r_check_vowel_harmony() && sbp.find_among_b(a_14, 4) &&
+ r_mark_suffix_with_optional_y_consonant();
+ }
+
+ function r_mark_sUnUz() {
+ return sbp.find_among_b(a_15, 4);
+ }
+
+ function r_mark_lAr() {
+ return r_check_vowel_harmony() && sbp.find_among_b(a_16, 2);
+ }
+
+ function r_mark_nUz() {
+ return r_check_vowel_harmony() && sbp.find_among_b(a_17, 4);
+ }
+
+ function r_mark_DUr() {
+ return r_check_vowel_harmony() && sbp.find_among_b(a_18, 8);
+ }
+
+ function r_mark_cAsInA() {
+ return sbp.find_among_b(a_19, 2);
+ }
+
+ function r_mark_yDU() {
+ return r_check_vowel_harmony() && sbp.find_among_b(a_20, 32) &&
+ r_mark_suffix_with_optional_y_consonant();
+ }
+
+ function r_mark_ysA() {
+ return sbp.find_among_b(a_21, 8) &&
+ r_mark_suffix_with_optional_y_consonant();
+ }
+
+ function r_mark_ymUs_() {
+ return r_check_vowel_harmony() && sbp.find_among_b(a_22, 4) &&
+ r_mark_suffix_with_optional_y_consonant();
+ }
+
+ function r_mark_yken() {
+ return sbp.eq_s_b(3, "ken") &&
+ r_mark_suffix_with_optional_y_consonant();
+ }
+
+ function habr4() {
+ var v_1 = sbp.limit - sbp.cursor;
+ if (!r_mark_ymUs_()) {
+ sbp.cursor = sbp.limit - v_1;
+ if (!r_mark_yDU()) {
+ sbp.cursor = sbp.limit - v_1;
+ if (!r_mark_ysA()) {
+ sbp.cursor = sbp.limit - v_1;
+ if (!r_mark_yken())
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ function habr5() {
+ if (r_mark_cAsInA()) {
+ var v_1 = sbp.limit - sbp.cursor;
+ if (!r_mark_sUnUz()) {
+ sbp.cursor = sbp.limit - v_1;
+ if (!r_mark_lAr()) {
+ sbp.cursor = sbp.limit - v_1;
+ if (!r_mark_yUm()) {
+ sbp.cursor = sbp.limit - v_1;
+ if (!r_mark_sUn()) {
+ sbp.cursor = sbp.limit - v_1;
+ if (!r_mark_yUz())
+ sbp.cursor = sbp.limit - v_1;
+ }
+ }
+ }
+ }
+ if (r_mark_ymUs_())
+ return false;
+ }
+ return true;
+ }
+
+ function habr6() {
+ if (r_mark_lAr()) {
+ sbp.bra = sbp.cursor;
+ sbp.slice_del();
+ var v_1 = sbp.limit - sbp.cursor;
+ sbp.ket = sbp.cursor;
+ if (!r_mark_DUr()) {
+ sbp.cursor = sbp.limit - v_1;
+ if (!r_mark_yDU()) {
+ sbp.cursor = sbp.limit - v_1;
+ if (!r_mark_ysA()) {
+ sbp.cursor = sbp.limit - v_1;
+ if (!r_mark_ymUs_())
+ sbp.cursor = sbp.limit - v_1;
+ }
+ }
+ }
+ B_c_s_n_s = false;
+ return false;
+ }
+ return true;
+ }
+
+ function habr7() {
+ if (!r_mark_nUz())
+ return true;
+ var v_1 = sbp.limit - sbp.cursor;
+ if (!r_mark_yDU()) {
+ sbp.cursor = sbp.limit - v_1;
+ if (!r_mark_ysA())
+ return true;
+ }
+ return false;
+ }
+
+ function habr8() {
+ var v_1 = sbp.limit - sbp.cursor,
+ v_2;
+ if (!r_mark_sUnUz()) {
+ sbp.cursor = sbp.limit - v_1;
+ if (!r_mark_yUz()) {
+ sbp.cursor = sbp.limit - v_1;
+ if (!r_mark_sUn()) {
+ sbp.cursor = sbp.limit - v_1;
+ if (!r_mark_yUm())
+ return true;
+ }
+ }
+ }
+ sbp.bra = sbp.cursor;
+ sbp.slice_del();
+ v_2 = sbp.limit - sbp.cursor;
+ sbp.ket = sbp.cursor;
+ if (!r_mark_ymUs_())
+ sbp.cursor = sbp.limit - v_2;
+ return false;
+ }
+
+ function r_stem_nominal_verb_suffixes() {
+ var v_1 = sbp.limit - sbp.cursor,
+ v_2;
+ sbp.ket = sbp.cursor;
+ B_c_s_n_s = true;
+ if (habr4()) {
+ sbp.cursor = sbp.limit - v_1;
+ if (habr5()) {
+ sbp.cursor = sbp.limit - v_1;
+ if (habr6()) {
+ sbp.cursor = sbp.limit - v_1;
+ if (habr7()) {
+ sbp.cursor = sbp.limit - v_1;
+ if (habr8()) {
+ sbp.cursor = sbp.limit - v_1;
+ if (!r_mark_DUr())
+ return;
+ sbp.bra = sbp.cursor;
+ sbp.slice_del();
+ sbp.ket = sbp.cursor;
+ v_2 = sbp.limit - sbp.cursor;
+ if (!r_mark_sUnUz()) {
+ sbp.cursor = sbp.limit - v_2;
+ if (!r_mark_lAr()) {
+ sbp.cursor = sbp.limit - v_2;
+ if (!r_mark_yUm()) {
+ sbp.cursor = sbp.limit - v_2;
+ if (!r_mark_sUn()) {
+ sbp.cursor = sbp.limit - v_2;
+ if (!r_mark_yUz())
+ sbp.cursor = sbp.limit - v_2;
+ }
+ }
+ }
+ }
+ if (!r_mark_ymUs_())
+ sbp.cursor = sbp.limit - v_2;
+ }
+ }
+ }
+ }
+ }
+ sbp.bra = sbp.cursor;
+ sbp.slice_del();
+ }
+
+ function r_stem_suffix_chain_before_ki() {
+ var v_1, v_2, v_3, v_4;
+ sbp.ket = sbp.cursor;
+ if (r_mark_ki()) {
+ v_1 = sbp.limit - sbp.cursor;
+ if (r_mark_DA()) {
+ sbp.bra = sbp.cursor;
+ sbp.slice_del();
+ v_2 = sbp.limit - sbp.cursor;
+ sbp.ket = sbp.cursor;
+ if (r_mark_lAr()) {
+ sbp.bra = sbp.cursor;
+ sbp.slice_del();
+ r_stem_suffix_chain_before_ki();
+ } else {
+ sbp.cursor = sbp.limit - v_2;
+ if (r_mark_possessives()) {
+ sbp.bra = sbp.cursor;
+ sbp.slice_del();
+ sbp.ket = sbp.cursor;
+ if (r_mark_lAr()) {
+ sbp.bra = sbp.cursor;
+ sbp.slice_del();
+ r_stem_suffix_chain_before_ki();
+ }
+ }
+ }
+ return true;
+ }
+ sbp.cursor = sbp.limit - v_1;
+ if (r_mark_nUn()) {
+ sbp.bra = sbp.cursor;
+ sbp.slice_del();
+ sbp.ket = sbp.cursor;
+ v_3 = sbp.limit - sbp.cursor;
+ if (r_mark_lArI()) {
+ sbp.bra = sbp.cursor;
+ sbp.slice_del();
+ } else {
+ sbp.cursor = sbp.limit - v_3;
+ sbp.ket = sbp.cursor;
+ if (!r_mark_possessives()) {
+ sbp.cursor = sbp.limit - v_3;
+ if (!r_mark_sU()) {
+ sbp.cursor = sbp.limit - v_3;
+ if (!r_stem_suffix_chain_before_ki())
+ return true;
+ }
+ }
+ sbp.bra = sbp.cursor;
+ sbp.slice_del();
+ sbp.ket = sbp.cursor;
+ if (r_mark_lAr()) {
+ sbp.bra = sbp.cursor;
+ sbp.slice_del();
+ r_stem_suffix_chain_before_ki()
+ }
+ }
+ return true;
+ }
+ sbp.cursor = sbp.limit - v_1;
+ if (r_mark_ndA()) {
+ v_4 = sbp.limit - sbp.cursor;
+ if (r_mark_lArI()) {
+ sbp.bra = sbp.cursor;
+ sbp.slice_del();
+ } else {
+ sbp.cursor = sbp.limit - v_4;
+ if (r_mark_sU()) {
+ sbp.bra = sbp.cursor;
+ sbp.slice_del();
+ sbp.ket = sbp.cursor;
+ if (r_mark_lAr()) {
+ sbp.bra = sbp.cursor;
+ sbp.slice_del();
+ r_stem_suffix_chain_before_ki();
+ }
+ } else {
+ sbp.cursor = sbp.limit - v_4;
+ if (!r_stem_suffix_chain_before_ki())
+ return false;
+ }
+ }
+ return true;
+ }
+ }
+ return false;
+ }
+
+ function habr9(v_1) {
+ sbp.ket = sbp.cursor;
+ if (!r_mark_ndA()) {
+ sbp.cursor = sbp.limit - v_1;
+ if (!r_mark_nA())
+ return false;
+ }
+ var v_2 = sbp.limit - sbp.cursor;
+ if (r_mark_lArI()) {
+ sbp.bra = sbp.cursor;
+ sbp.slice_del();
+ } else {
+ sbp.cursor = sbp.limit - v_2;
+ if (r_mark_sU()) {
+ sbp.bra = sbp.cursor;
+ sbp.slice_del();
+ sbp.ket = sbp.cursor;
+ if (r_mark_lAr()) {
+ sbp.bra = sbp.cursor;
+ sbp.slice_del();
+ r_stem_suffix_chain_before_ki();
+ }
+ } else {
+ sbp.cursor = sbp.limit - v_2;
+ if (!r_stem_suffix_chain_before_ki())
+ return false;
+ }
+ }
+ return true;
+ }
+
+ function habr10(v_1) {
+ sbp.ket = sbp.cursor;
+ if (!r_mark_ndAn()) {
+ sbp.cursor = sbp.limit - v_1;
+ if (!r_mark_nU())
+ return false;
+ }
+ var v_2 = sbp.limit - sbp.cursor;
+ if (!r_mark_sU()) {
+ sbp.cursor = sbp.limit - v_2;
+ if (!r_mark_lArI())
+ return false;
+ }
+ sbp.bra = sbp.cursor;
+ sbp.slice_del();
+ sbp.ket = sbp.cursor;
+ if (r_mark_lAr()) {
+ sbp.bra = sbp.cursor;
+ sbp.slice_del();
+ r_stem_suffix_chain_before_ki();
+ }
+ return true;
+ }
+
+ function habr11() {
+ var v_1 = sbp.limit - sbp.cursor,
+ v_2;
+ sbp.ket = sbp.cursor;
+ if (!r_mark_nUn()) {
+ sbp.cursor = sbp.limit - v_1;
+ if (!r_mark_ylA())
+ return false;
+ }
+ sbp.bra = sbp.cursor;
+ sbp.slice_del();
+ v_2 = sbp.limit - sbp.cursor;
+ sbp.ket = sbp.cursor;
+ if (r_mark_lAr()) {
+ sbp.bra = sbp.cursor;
+ sbp.slice_del();
+ if (r_stem_suffix_chain_before_ki())
+ return true;
+ }
+ sbp.cursor = sbp.limit - v_2;
+ sbp.ket = sbp.cursor;
+ if (!r_mark_possessives()) {
+ sbp.cursor = sbp.limit - v_2;
+ if (!r_mark_sU()) {
+ sbp.cursor = sbp.limit - v_2;
+ if (!r_stem_suffix_chain_before_ki())
+ return true;
+ }
+ }
+ sbp.bra = sbp.cursor;
+ sbp.slice_del();
+ sbp.ket = sbp.cursor;
+ if (r_mark_lAr()) {
+ sbp.bra = sbp.cursor;
+ sbp.slice_del();
+ r_stem_suffix_chain_before_ki();
+ }
+ return true;
+ }
+
+ function habr12() {
+ var v_1 = sbp.limit - sbp.cursor,
+ v_2, v_3;
+ sbp.ket = sbp.cursor;
+ if (!r_mark_DA()) {
+ sbp.cursor = sbp.limit - v_1;
+ if (!r_mark_yU()) {
+ sbp.cursor = sbp.limit - v_1;
+ if (!r_mark_yA())
+ return false;
+ }
+ }
+ sbp.bra = sbp.cursor;
+ sbp.slice_del();
+ sbp.ket = sbp.cursor;
+ v_2 = sbp.limit - sbp.cursor;
+ if (r_mark_possessives()) {
+ sbp.bra = sbp.cursor;
+ sbp.slice_del();
+ v_3 = sbp.limit - sbp.cursor;
+ sbp.ket = sbp.cursor;
+ if (!r_mark_lAr())
+ sbp.cursor = sbp.limit - v_3;
+ } else {
+ sbp.cursor = sbp.limit - v_2;
+ if (!r_mark_lAr())
+ return true;
+ }
+ sbp.bra = sbp.cursor;
+ sbp.slice_del();
+ sbp.ket = sbp.cursor;
+ r_stem_suffix_chain_before_ki();
+ return true;
+ }
+
+ function r_stem_noun_suffixes() {
+ var v_1 = sbp.limit - sbp.cursor,
+ v_2, v_3;
+ sbp.ket = sbp.cursor;
+ if (r_mark_lAr()) {
+ sbp.bra = sbp.cursor;
+ sbp.slice_del();
+ r_stem_suffix_chain_before_ki();
+ return;
+ }
+ sbp.cursor = sbp.limit - v_1;
+ sbp.ket = sbp.cursor;
+ if (r_mark_ncA()) {
+ sbp.bra = sbp.cursor;
+ sbp.slice_del();
+ v_2 = sbp.limit - sbp.cursor;
+ sbp.ket = sbp.cursor;
+ if (r_mark_lArI()) {
+ sbp.bra = sbp.cursor;
+ sbp.slice_del();
+ } else {
+ sbp.cursor = sbp.limit - v_2;
+ sbp.ket = sbp.cursor;
+ if (!r_mark_possessives()) {
+ sbp.cursor = sbp.limit - v_2;
+ if (!r_mark_sU()) {
+ sbp.cursor = sbp.limit - v_2;
+ sbp.ket = sbp.cursor;
+ if (!r_mark_lAr())
+ return;
+ sbp.bra = sbp.cursor;
+ sbp.slice_del();
+ if (!r_stem_suffix_chain_before_ki())
+ return;
+ }
+ }
+ sbp.bra = sbp.cursor;
+ sbp.slice_del();
+ sbp.ket = sbp.cursor;
+ if (r_mark_lAr()) {
+ sbp.bra = sbp.cursor;
+ sbp.slice_del();
+ r_stem_suffix_chain_before_ki();
+ }
+ }
+ return;
+ }
+ sbp.cursor = sbp.limit - v_1;
+ if (habr9(v_1))
+ return;
+ sbp.cursor = sbp.limit - v_1;
+ if (habr10(v_1))
+ return;
+ sbp.cursor = sbp.limit - v_1;
+ sbp.ket = sbp.cursor;
+ if (r_mark_DAn()) {
+ sbp.bra = sbp.cursor;
+ sbp.slice_del();
+ sbp.ket = sbp.cursor;
+ v_3 = sbp.limit - sbp.cursor;
+ if (r_mark_possessives()) {
+ sbp.bra = sbp.cursor;
+ sbp.slice_del();
+ sbp.ket = sbp.cursor;
+ if (r_mark_lAr()) {
+ sbp.bra = sbp.cursor;
+ sbp.slice_del();
+ r_stem_suffix_chain_before_ki();
+ }
+ } else {
+ sbp.cursor = sbp.limit - v_3;
+ if (r_mark_lAr()) {
+ sbp.bra = sbp.cursor;
+ sbp.slice_del();
+ r_stem_suffix_chain_before_ki();
+ } else {
+ sbp.cursor = sbp.limit - v_3;
+ r_stem_suffix_chain_before_ki();
+ }
+ }
+ return;
+ }
+ sbp.cursor = sbp.limit - v_1;
+ if (habr11())
+ return;
+ sbp.cursor = sbp.limit - v_1;
+ if (r_mark_lArI()) {
+ sbp.bra = sbp.cursor;
+ sbp.slice_del();
+ return;
+ }
+ sbp.cursor = sbp.limit - v_1;
+ if (r_stem_suffix_chain_before_ki())
+ return;
+ sbp.cursor = sbp.limit - v_1;
+ if (habr12())
+ return;
+ sbp.cursor = sbp.limit - v_1;
+ sbp.ket = sbp.cursor;
+ if (!r_mark_possessives()) {
+ sbp.cursor = sbp.limit - v_1;
+ if (!r_mark_sU())
+ return;
+ }
+ sbp.bra = sbp.cursor;
+ sbp.slice_del();
+ sbp.ket = sbp.cursor;
+ if (r_mark_lAr()) {
+ sbp.bra = sbp.cursor;
+ sbp.slice_del();
+ r_stem_suffix_chain_before_ki();
+ }
+ }
+
+ function r_post_process_last_consonants() {
+ var among_var;
+ sbp.ket = sbp.cursor;
+ among_var = sbp.find_among_b(a_23, 4);
+ if (among_var) {
+ sbp.bra = sbp.cursor;
+ switch (among_var) {
+ case 1:
+ sbp.slice_from("p");
+ break;
+ case 2:
+ sbp.slice_from("\u00E7");
+ break;
+ case 3:
+ sbp.slice_from("t");
+ break;
+ case 4:
+ sbp.slice_from("k");
+ break;
+ }
+ }
+ }
+
+ function habr13() {
+ while (true) {
+ var v_1 = sbp.limit - sbp.cursor;
+ if (sbp.in_grouping_b(g_vowel, 97, 305)) {
+ sbp.cursor = sbp.limit - v_1;
+ break;
+ }
+ sbp.cursor = sbp.limit - v_1;
+ if (sbp.cursor <= sbp.limit_backward)
+ return false;
+ sbp.cursor--;
+ }
+ return true;
+ }
+
+ function habr14(v_1, c1, c2) {
+ sbp.cursor = sbp.limit - v_1;
+ if (habr13()) {
+ var v_2 = sbp.limit - sbp.cursor;
+ if (!sbp.eq_s_b(1, c1)) {
+ sbp.cursor = sbp.limit - v_2;
+ if (!sbp.eq_s_b(1, c2))
+ return true;
+ }
+ sbp.cursor = sbp.limit - v_1;
+ var c = sbp.cursor;
+ sbp.insert(sbp.cursor, sbp.cursor, c2);
+ sbp.cursor = c;
+ return false;
+ }
+ return true;
+ }
+
+ function r_append_U_to_stems_ending_with_d_or_g() {
+ var v_1 = sbp.limit - sbp.cursor;
+ if (!sbp.eq_s_b(1, "d")) {
+ sbp.cursor = sbp.limit - v_1;
+ if (!sbp.eq_s_b(1, "g"))
+ return;
+ }
+ if (habr14(v_1, "a", "\u0131"))
+ if (habr14(v_1, "e", "i"))
+ if (habr14(v_1, "o", "u"))
+ habr14(v_1, "\u00F6", "\u00FC")
+ }
+
+ function r_more_than_one_syllable_word() {
+ var v_1 = sbp.cursor,
+ v_2 = 2,
+ v_3;
+ while (true) {
+ v_3 = sbp.cursor;
+ while (!sbp.in_grouping(g_vowel, 97, 305)) {
+ if (sbp.cursor >= sbp.limit) {
+ sbp.cursor = v_3;
+ if (v_2 > 0)
+ return false;
+ sbp.cursor = v_1;
+ return true;
+ }
+ sbp.cursor++;
+ }
+ v_2--;
+ }
+ }
+
+ function habr15(v_1, n1, c1) {
+ while (!sbp.eq_s(n1, c1)) {
+ if (sbp.cursor >= sbp.limit)
+ return true;
+ sbp.cursor++;
+ }
+ I_strlen = n1;
+ if (I_strlen != sbp.limit)
+ return true;
+ sbp.cursor = v_1;
+ return false;
+ }
+
+ function r_is_reserved_word() {
+ var v_1 = sbp.cursor;
+ if (habr15(v_1, 2, "ad")) {
+ sbp.cursor = v_1;
+ if (habr15(v_1, 5, "soyad"))
+ return false;
+ }
+ return true;
+ }
+
+ function r_postlude() {
+ var v_1 = sbp.cursor;
+ if (r_is_reserved_word())
+ return false;
+ sbp.limit_backward = v_1;
+ sbp.cursor = sbp.limit;
+ r_append_U_to_stems_ending_with_d_or_g();
+ sbp.cursor = sbp.limit;
+ r_post_process_last_consonants();
+ return true;
+ }
+ this.stem = function() {
+ if (r_more_than_one_syllable_word()) {
+ sbp.limit_backward = sbp.cursor;
+ sbp.cursor = sbp.limit;
+ r_stem_nominal_verb_suffixes();
+ sbp.cursor = sbp.limit;
+ if (B_c_s_n_s) {
+ r_stem_noun_suffixes();
+ sbp.cursor = sbp.limit_backward;
+ if (r_postlude())
+ return true;
+ }
+ }
+ return false;
+ }
+ };
+
+ /* and return a function that stems a word for the current locale */
+ return function(token) {
+ // for lunr version 2
+ if (typeof token.update === "function") {
+ return token.update(function(word) {
+ st.setCurrent(word);
+ st.stem();
+ return st.getCurrent();
+ })
+ } else { // for lunr version <= 1
+ st.setCurrent(token);
+ st.stem();
+ return st.getCurrent();
+ }
+ }
+ })();
+
+ lunr.Pipeline.registerFunction(lunr.tr.stemmer, 'stemmer-tr');
+
+ lunr.tr.stopWordFilter = lunr.generateStopWordFilter('acaba altmış altı ama ancak arada aslında ayrıca bana bazı belki ben benden beni benim beri beş bile bin bir biri birkaç birkez birçok birşey birşeyi biz bizden bize bizi bizim bu buna bunda bundan bunlar bunları bunların bunu bunun burada böyle böylece da daha dahi de defa değil diye diğer doksan dokuz dolayı dolayısıyla dört edecek eden ederek edilecek ediliyor edilmesi ediyor elli en etmesi etti ettiği ettiğini eğer gibi göre halen hangi hatta hem henüz hep hepsi her herhangi herkesin hiç hiçbir iki ile ilgili ise itibaren itibariyle için işte kadar karşın katrilyon kendi kendilerine kendini kendisi kendisine kendisini kez ki kim kimden kime kimi kimse kırk milyar milyon mu mü mı nasıl ne neden nedenle nerde nerede nereye niye niçin o olan olarak oldu olduklarını olduğu olduğunu olmadı olmadığı olmak olması olmayan olmaz olsa olsun olup olur olursa oluyor on ona ondan onlar onlardan onları onların onu onun otuz oysa pek rağmen sadece sanki sekiz seksen sen senden seni senin siz sizden sizi sizin tarafından trilyon tüm var vardı ve veya ya yani yapacak yapmak yaptı yaptıkları yaptığı yaptığını yapılan yapılması yapıyor yedi yerine yetmiş yine yirmi yoksa yüz zaten çok çünkü öyle üzere üç şey şeyden şeyi şeyler şu şuna şunda şundan şunları şunu şöyle'.split(' '));
+
+ lunr.Pipeline.registerFunction(lunr.tr.stopWordFilter, 'stopWordFilter-tr');
+ };
+}))
\ No newline at end of file
diff --git a/venv/lib/python3.11/site-packages/mkdocs/contrib/search/lunr-language/lunr.vi.js b/venv/lib/python3.11/site-packages/mkdocs/contrib/search/lunr-language/lunr.vi.js
new file mode 100644
index 0000000..e7a65b2
--- /dev/null
+++ b/venv/lib/python3.11/site-packages/mkdocs/contrib/search/lunr-language/lunr.vi.js
@@ -0,0 +1,84 @@
+/*!
+ * Lunr languages, `Vietnamese` language
+ * https://github.com/MihaiValentin/lunr-languages
+ *
+ * Copyright 2017, Keerati Thiwanruk
+ * http://www.mozilla.org/MPL/
+ */
+/*!
+ * based on
+ * Snowball JavaScript Library v0.3
+ * http://code.google.com/p/urim/
+ * http://snowball.tartarus.org/
+ *
+ * Copyright 2010, Oleg Mazko
+ * http://www.mozilla.org/MPL/
+ */
+
+/**
+ * export the module via AMD, CommonJS or as a browser global
+ * Export code from https://github.com/umdjs/umd/blob/master/returnExports.js
+ */
+;
+(function(root, factory) {
+ if (typeof define === 'function' && define.amd) {
+ // AMD. Register as an anonymous module.
+ define(factory)
+ } else if (typeof exports === 'object') {
+ /**
+ * Node. Does not work with strict CommonJS, but
+ * only CommonJS-like environments that support module.exports,
+ * like Node.
+ */
+ module.exports = factory()
+ } else {
+ // Browser globals (root is window)
+ factory()(root.lunr);
+ }
+}(this, function() {
+ /**
+ * Just return a value to define the module export.
+ * This example returns an object, but the module
+ * can return a function as the exported value.
+ */
+ return function(lunr) {
+ /* throw error if lunr is not yet included */
+ if ('undefined' === typeof lunr) {
+ throw new Error('Lunr is not present. Please include / require Lunr before this script.');
+ }
+
+ /* throw error if lunr stemmer support is not yet included */
+ if ('undefined' === typeof lunr.stemmerSupport) {
+ throw new Error('Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.');
+ }
+
+ /* register specific locale function */
+ lunr.vi = function() {
+ this.pipeline.reset();
+ this.pipeline.add(
+ lunr.vi.stopWordFilter,
+ lunr.vi.trimmer
+ );
+ };
+
+ /* lunr trimmer function */
+ lunr.vi.wordCharacters = "[" +
+ "A-Za-z" +
+ "\u0300\u0350" + // dấu huyền
+ "\u0301\u0351" + // dấu sắc
+ "\u0309" + // dấu hỏi
+ "\u0323" + // dấu nặng
+ "\u0303\u0343" + // dấu ngã
+ "\u00C2\u00E2" + // Â
+ "\u00CA\u00EA" + // Ê
+ "\u00D4\u00F4" + // Ô
+ "\u0102-\u0103" + // Ă
+ "\u0110-\u0111" + // Đ
+ "\u01A0-\u01A1" + // Ơ
+ "\u01AF-\u01B0" + // Ư
+ "]";
+ lunr.vi.trimmer = lunr.trimmerSupport.generateTrimmer(lunr.vi.wordCharacters);
+ lunr.Pipeline.registerFunction(lunr.vi.trimmer, 'trimmer-vi');
+ lunr.vi.stopWordFilter = lunr.generateStopWordFilter('là cái nhưng mà'.split(' '));
+ };
+}))
\ No newline at end of file
diff --git a/venv/lib/python3.11/site-packages/mkdocs/contrib/search/lunr-language/tinyseg.js b/venv/lib/python3.11/site-packages/mkdocs/contrib/search/lunr-language/tinyseg.js
new file mode 100644
index 0000000..167fa6d
--- /dev/null
+++ b/venv/lib/python3.11/site-packages/mkdocs/contrib/search/lunr-language/tinyseg.js
@@ -0,0 +1,206 @@
+/**
+ * export the module via AMD, CommonJS or as a browser global
+ * Export code from https://github.com/umdjs/umd/blob/master/returnExports.js
+ */
+;(function (root, factory) {
+ if (typeof define === 'function' && define.amd) {
+ // AMD. Register as an anonymous module.
+ define(factory)
+ } else if (typeof exports === 'object') {
+ /**
+ * Node. Does not work with strict CommonJS, but
+ * only CommonJS-like environments that support module.exports,
+ * like Node.
+ */
+ module.exports = factory()
+ } else {
+ // Browser globals (root is window)
+ factory()(root.lunr);
+ }
+}(this, function () {
+ /**
+ * Just return a value to define the module export.
+ * This example returns an object, but the module
+ * can return a function as the exported value.
+ */
+
+ return function(lunr) {
+ // TinySegmenter 0.1 -- Super compact Japanese tokenizer in Javascript
+ // (c) 2008 Taku Kudo
+ // TinySegmenter is freely distributable under the terms of a new BSD licence.
+ // For details, see http://chasen.org/~taku/software/TinySegmenter/LICENCE.txt
+
+ function TinySegmenter() {
+ var patterns = {
+ "[一二三四五六七八九十百千万億兆]":"M",
+ "[一-龠々〆ヵヶ]":"H",
+ "[ぁ-ん]":"I",
+ "[ァ-ヴーア-ン゙ー]":"K",
+ "[a-zA-Za-zA-Z]":"A",
+ "[0-90-9]":"N"
+ }
+ this.chartype_ = [];
+ for (var i in patterns) {
+ var regexp = new RegExp(i);
+ this.chartype_.push([regexp, patterns[i]]);
+ }
+
+ this.BIAS__ = -332
+ this.BC1__ = {"HH":6,"II":2461,"KH":406,"OH":-1378};
+ this.BC2__ = {"AA":-3267,"AI":2744,"AN":-878,"HH":-4070,"HM":-1711,"HN":4012,"HO":3761,"IA":1327,"IH":-1184,"II":-1332,"IK":1721,"IO":5492,"KI":3831,"KK":-8741,"MH":-3132,"MK":3334,"OO":-2920};
+ this.BC3__ = {"HH":996,"HI":626,"HK":-721,"HN":-1307,"HO":-836,"IH":-301,"KK":2762,"MK":1079,"MM":4034,"OA":-1652,"OH":266};
+ this.BP1__ = {"BB":295,"OB":304,"OO":-125,"UB":352};
+ this.BP2__ = {"BO":60,"OO":-1762};
+ this.BQ1__ = {"BHH":1150,"BHM":1521,"BII":-1158,"BIM":886,"BMH":1208,"BNH":449,"BOH":-91,"BOO":-2597,"OHI":451,"OIH":-296,"OKA":1851,"OKH":-1020,"OKK":904,"OOO":2965};
+ this.BQ2__ = {"BHH":118,"BHI":-1159,"BHM":466,"BIH":-919,"BKK":-1720,"BKO":864,"OHH":-1139,"OHM":-181,"OIH":153,"UHI":-1146};
+ this.BQ3__ = {"BHH":-792,"BHI":2664,"BII":-299,"BKI":419,"BMH":937,"BMM":8335,"BNN":998,"BOH":775,"OHH":2174,"OHM":439,"OII":280,"OKH":1798,"OKI":-793,"OKO":-2242,"OMH":-2402,"OOO":11699};
+ this.BQ4__ = {"BHH":-3895,"BIH":3761,"BII":-4654,"BIK":1348,"BKK":-1806,"BMI":-3385,"BOO":-12396,"OAH":926,"OHH":266,"OHK":-2036,"ONN":-973};
+ this.BW1__ = {",と":660,",同":727,"B1あ":1404,"B1同":542,"、と":660,"、同":727,"」と":1682,"あっ":1505,"いう":1743,"いっ":-2055,"いる":672,"うし":-4817,"うん":665,"から":3472,"がら":600,"こう":-790,"こと":2083,"こん":-1262,"さら":-4143,"さん":4573,"した":2641,"して":1104,"すで":-3399,"そこ":1977,"それ":-871,"たち":1122,"ため":601,"った":3463,"つい":-802,"てい":805,"てき":1249,"でき":1127,"です":3445,"では":844,"とい":-4915,"とみ":1922,"どこ":3887,"ない":5713,"なっ":3015,"など":7379,"なん":-1113,"にし":2468,"には":1498,"にも":1671,"に対":-912,"の一":-501,"の中":741,"ませ":2448,"まで":1711,"まま":2600,"まる":-2155,"やむ":-1947,"よっ":-2565,"れた":2369,"れで":-913,"をし":1860,"を見":731,"亡く":-1886,"京都":2558,"取り":-2784,"大き":-2604,"大阪":1497,"平方":-2314,"引き":-1336,"日本":-195,"本当":-2423,"毎日":-2113,"目指":-724,"B1あ":1404,"B1同":542,"」と":1682};
+ this.BW2__ = {"..":-11822,"11":-669,"――":-5730,"−−":-13175,"いう":-1609,"うか":2490,"かし":-1350,"かも":-602,"から":-7194,"かれ":4612,"がい":853,"がら":-3198,"きた":1941,"くな":-1597,"こと":-8392,"この":-4193,"させ":4533,"され":13168,"さん":-3977,"しい":-1819,"しか":-545,"した":5078,"して":972,"しな":939,"その":-3744,"たい":-1253,"たた":-662,"ただ":-3857,"たち":-786,"たと":1224,"たは":-939,"った":4589,"って":1647,"っと":-2094,"てい":6144,"てき":3640,"てく":2551,"ては":-3110,"ても":-3065,"でい":2666,"でき":-1528,"でし":-3828,"です":-4761,"でも":-4203,"とい":1890,"とこ":-1746,"とと":-2279,"との":720,"とみ":5168,"とも":-3941,"ない":-2488,"なが":-1313,"など":-6509,"なの":2614,"なん":3099,"にお":-1615,"にし":2748,"にな":2454,"によ":-7236,"に対":-14943,"に従":-4688,"に関":-11388,"のか":2093,"ので":-7059,"のに":-6041,"のの":-6125,"はい":1073,"はが":-1033,"はず":-2532,"ばれ":1813,"まし":-1316,"まで":-6621,"まれ":5409,"めて":-3153,"もい":2230,"もの":-10713,"らか":-944,"らし":-1611,"らに":-1897,"りし":651,"りま":1620,"れた":4270,"れて":849,"れば":4114,"ろう":6067,"われ":7901,"を通":-11877,"んだ":728,"んな":-4115,"一人":602,"一方":-1375,"一日":970,"一部":-1051,"上が":-4479,"会社":-1116,"出て":2163,"分の":-7758,"同党":970,"同日":-913,"大阪":-2471,"委員":-1250,"少な":-1050,"年度":-8669,"年間":-1626,"府県":-2363,"手権":-1982,"新聞":-4066,"日新":-722,"日本":-7068,"日米":3372,"曜日":-601,"朝鮮":-2355,"本人":-2697,"東京":-1543,"然と":-1384,"社会":-1276,"立て":-990,"第に":-1612,"米国":-4268,"11":-669};
+ this.BW3__ = {"あた":-2194,"あり":719,"ある":3846,"い.":-1185,"い。":-1185,"いい":5308,"いえ":2079,"いく":3029,"いた":2056,"いっ":1883,"いる":5600,"いわ":1527,"うち":1117,"うと":4798,"えと":1454,"か.":2857,"か。":2857,"かけ":-743,"かっ":-4098,"かに":-669,"から":6520,"かり":-2670,"が,":1816,"が、":1816,"がき":-4855,"がけ":-1127,"がっ":-913,"がら":-4977,"がり":-2064,"きた":1645,"けど":1374,"こと":7397,"この":1542,"ころ":-2757,"さい":-714,"さを":976,"し,":1557,"し、":1557,"しい":-3714,"した":3562,"して":1449,"しな":2608,"しま":1200,"す.":-1310,"す。":-1310,"する":6521,"ず,":3426,"ず、":3426,"ずに":841,"そう":428,"た.":8875,"た。":8875,"たい":-594,"たの":812,"たり":-1183,"たる":-853,"だ.":4098,"だ。":4098,"だっ":1004,"った":-4748,"って":300,"てい":6240,"てお":855,"ても":302,"です":1437,"でに":-1482,"では":2295,"とう":-1387,"とし":2266,"との":541,"とも":-3543,"どう":4664,"ない":1796,"なく":-903,"など":2135,"に,":-1021,"に、":-1021,"にし":1771,"にな":1906,"には":2644,"の,":-724,"の、":-724,"の子":-1000,"は,":1337,"は、":1337,"べき":2181,"まし":1113,"ます":6943,"まっ":-1549,"まで":6154,"まれ":-793,"らし":1479,"られ":6820,"るる":3818,"れ,":854,"れ、":854,"れた":1850,"れて":1375,"れば":-3246,"れる":1091,"われ":-605,"んだ":606,"んで":798,"カ月":990,"会議":860,"入り":1232,"大会":2217,"始め":1681,"市":965,"新聞":-5055,"日,":974,"日、":974,"社会":2024,"カ月":990};
+ this.TC1__ = {"AAA":1093,"HHH":1029,"HHM":580,"HII":998,"HOH":-390,"HOM":-331,"IHI":1169,"IOH":-142,"IOI":-1015,"IOM":467,"MMH":187,"OOI":-1832};
+ this.TC2__ = {"HHO":2088,"HII":-1023,"HMM":-1154,"IHI":-1965,"KKH":703,"OII":-2649};
+ this.TC3__ = {"AAA":-294,"HHH":346,"HHI":-341,"HII":-1088,"HIK":731,"HOH":-1486,"IHH":128,"IHI":-3041,"IHO":-1935,"IIH":-825,"IIM":-1035,"IOI":-542,"KHH":-1216,"KKA":491,"KKH":-1217,"KOK":-1009,"MHH":-2694,"MHM":-457,"MHO":123,"MMH":-471,"NNH":-1689,"NNO":662,"OHO":-3393};
+ this.TC4__ = {"HHH":-203,"HHI":1344,"HHK":365,"HHM":-122,"HHN":182,"HHO":669,"HIH":804,"HII":679,"HOH":446,"IHH":695,"IHO":-2324,"IIH":321,"III":1497,"IIO":656,"IOO":54,"KAK":4845,"KKA":3386,"KKK":3065,"MHH":-405,"MHI":201,"MMH":-241,"MMM":661,"MOM":841};
+ this.TQ1__ = {"BHHH":-227,"BHHI":316,"BHIH":-132,"BIHH":60,"BIII":1595,"BNHH":-744,"BOHH":225,"BOOO":-908,"OAKK":482,"OHHH":281,"OHIH":249,"OIHI":200,"OIIH":-68};
+ this.TQ2__ = {"BIHH":-1401,"BIII":-1033,"BKAK":-543,"BOOO":-5591};
+ this.TQ3__ = {"BHHH":478,"BHHM":-1073,"BHIH":222,"BHII":-504,"BIIH":-116,"BIII":-105,"BMHI":-863,"BMHM":-464,"BOMH":620,"OHHH":346,"OHHI":1729,"OHII":997,"OHMH":481,"OIHH":623,"OIIH":1344,"OKAK":2792,"OKHH":587,"OKKA":679,"OOHH":110,"OOII":-685};
+ this.TQ4__ = {"BHHH":-721,"BHHM":-3604,"BHII":-966,"BIIH":-607,"BIII":-2181,"OAAA":-2763,"OAKK":180,"OHHH":-294,"OHHI":2446,"OHHO":480,"OHIH":-1573,"OIHH":1935,"OIHI":-493,"OIIH":626,"OIII":-4007,"OKAK":-8156};
+ this.TW1__ = {"につい":-4681,"東京都":2026};
+ this.TW2__ = {"ある程":-2049,"いった":-1256,"ころが":-2434,"しょう":3873,"その後":-4430,"だって":-1049,"ていた":1833,"として":-4657,"ともに":-4517,"もので":1882,"一気に":-792,"初めて":-1512,"同時に":-8097,"大きな":-1255,"対して":-2721,"社会党":-3216};
+ this.TW3__ = {"いただ":-1734,"してい":1314,"として":-4314,"につい":-5483,"にとっ":-5989,"に当た":-6247,"ので,":-727,"ので、":-727,"のもの":-600,"れから":-3752,"十二月":-2287};
+ this.TW4__ = {"いう.":8576,"いう。":8576,"からな":-2348,"してい":2958,"たが,":1516,"たが、":1516,"ている":1538,"という":1349,"ました":5543,"ません":1097,"ようと":-4258,"よると":5865};
+ this.UC1__ = {"A":484,"K":93,"M":645,"O":-505};
+ this.UC2__ = {"A":819,"H":1059,"I":409,"M":3987,"N":5775,"O":646};
+ this.UC3__ = {"A":-1370,"I":2311};
+ this.UC4__ = {"A":-2643,"H":1809,"I":-1032,"K":-3450,"M":3565,"N":3876,"O":6646};
+ this.UC5__ = {"H":313,"I":-1238,"K":-799,"M":539,"O":-831};
+ this.UC6__ = {"H":-506,"I":-253,"K":87,"M":247,"O":-387};
+ this.UP1__ = {"O":-214};
+ this.UP2__ = {"B":69,"O":935};
+ this.UP3__ = {"B":189};
+ this.UQ1__ = {"BH":21,"BI":-12,"BK":-99,"BN":142,"BO":-56,"OH":-95,"OI":477,"OK":410,"OO":-2422};
+ this.UQ2__ = {"BH":216,"BI":113,"OK":1759};
+ this.UQ3__ = {"BA":-479,"BH":42,"BI":1913,"BK":-7198,"BM":3160,"BN":6427,"BO":14761,"OI":-827,"ON":-3212};
+ this.UW1__ = {",":156,"、":156,"「":-463,"あ":-941,"う":-127,"が":-553,"き":121,"こ":505,"で":-201,"と":-547,"ど":-123,"に":-789,"の":-185,"は":-847,"も":-466,"や":-470,"よ":182,"ら":-292,"り":208,"れ":169,"を":-446,"ん":-137,"・":-135,"主":-402,"京":-268,"区":-912,"午":871,"国":-460,"大":561,"委":729,"市":-411,"日":-141,"理":361,"生":-408,"県":-386,"都":-718,"「":-463,"・":-135};
+ this.UW2__ = {",":-829,"、":-829,"〇":892,"「":-645,"」":3145,"あ":-538,"い":505,"う":134,"お":-502,"か":1454,"が":-856,"く":-412,"こ":1141,"さ":878,"ざ":540,"し":1529,"す":-675,"せ":300,"そ":-1011,"た":188,"だ":1837,"つ":-949,"て":-291,"で":-268,"と":-981,"ど":1273,"な":1063,"に":-1764,"の":130,"は":-409,"ひ":-1273,"べ":1261,"ま":600,"も":-1263,"や":-402,"よ":1639,"り":-579,"る":-694,"れ":571,"を":-2516,"ん":2095,"ア":-587,"カ":306,"キ":568,"ッ":831,"三":-758,"不":-2150,"世":-302,"中":-968,"主":-861,"事":492,"人":-123,"会":978,"保":362,"入":548,"初":-3025,"副":-1566,"北":-3414,"区":-422,"大":-1769,"天":-865,"太":-483,"子":-1519,"学":760,"実":1023,"小":-2009,"市":-813,"年":-1060,"強":1067,"手":-1519,"揺":-1033,"政":1522,"文":-1355,"新":-1682,"日":-1815,"明":-1462,"最":-630,"朝":-1843,"本":-1650,"東":-931,"果":-665,"次":-2378,"民":-180,"気":-1740,"理":752,"発":529,"目":-1584,"相":-242,"県":-1165,"立":-763,"第":810,"米":509,"自":-1353,"行":838,"西":-744,"見":-3874,"調":1010,"議":1198,"込":3041,"開":1758,"間":-1257,"「":-645,"」":3145,"ッ":831,"ア":-587,"カ":306,"キ":568};
+ this.UW3__ = {",":4889,"1":-800,"−":-1723,"、":4889,"々":-2311,"〇":5827,"」":2670,"〓":-3573,"あ":-2696,"い":1006,"う":2342,"え":1983,"お":-4864,"か":-1163,"が":3271,"く":1004,"け":388,"げ":401,"こ":-3552,"ご":-3116,"さ":-1058,"し":-395,"す":584,"せ":3685,"そ":-5228,"た":842,"ち":-521,"っ":-1444,"つ":-1081,"て":6167,"で":2318,"と":1691,"ど":-899,"な":-2788,"に":2745,"の":4056,"は":4555,"ひ":-2171,"ふ":-1798,"へ":1199,"ほ":-5516,"ま":-4384,"み":-120,"め":1205,"も":2323,"や":-788,"よ":-202,"ら":727,"り":649,"る":5905,"れ":2773,"わ":-1207,"を":6620,"ん":-518,"ア":551,"グ":1319,"ス":874,"ッ":-1350,"ト":521,"ム":1109,"ル":1591,"ロ":2201,"ン":278,"・":-3794,"一":-1619,"下":-1759,"世":-2087,"両":3815,"中":653,"主":-758,"予":-1193,"二":974,"人":2742,"今":792,"他":1889,"以":-1368,"低":811,"何":4265,"作":-361,"保":-2439,"元":4858,"党":3593,"全":1574,"公":-3030,"六":755,"共":-1880,"円":5807,"再":3095,"分":457,"初":2475,"別":1129,"前":2286,"副":4437,"力":365,"動":-949,"務":-1872,"化":1327,"北":-1038,"区":4646,"千":-2309,"午":-783,"協":-1006,"口":483,"右":1233,"各":3588,"合":-241,"同":3906,"和":-837,"員":4513,"国":642,"型":1389,"場":1219,"外":-241,"妻":2016,"学":-1356,"安":-423,"実":-1008,"家":1078,"小":-513,"少":-3102,"州":1155,"市":3197,"平":-1804,"年":2416,"広":-1030,"府":1605,"度":1452,"建":-2352,"当":-3885,"得":1905,"思":-1291,"性":1822,"戸":-488,"指":-3973,"政":-2013,"教":-1479,"数":3222,"文":-1489,"新":1764,"日":2099,"旧":5792,"昨":-661,"時":-1248,"曜":-951,"最":-937,"月":4125,"期":360,"李":3094,"村":364,"東":-805,"核":5156,"森":2438,"業":484,"氏":2613,"民":-1694,"決":-1073,"法":1868,"海":-495,"無":979,"物":461,"特":-3850,"生":-273,"用":914,"町":1215,"的":7313,"直":-1835,"省":792,"県":6293,"知":-1528,"私":4231,"税":401,"立":-960,"第":1201,"米":7767,"系":3066,"約":3663,"級":1384,"統":-4229,"総":1163,"線":1255,"者":6457,"能":725,"自":-2869,"英":785,"見":1044,"調":-562,"財":-733,"費":1777,"車":1835,"軍":1375,"込":-1504,"通":-1136,"選":-681,"郎":1026,"郡":4404,"部":1200,"金":2163,"長":421,"開":-1432,"間":1302,"関":-1282,"雨":2009,"電":-1045,"非":2066,"駅":1620,"1":-800,"」":2670,"・":-3794,"ッ":-1350,"ア":551,"グ":1319,"ス":874,"ト":521,"ム":1109,"ル":1591,"ロ":2201,"ン":278};
+ this.UW4__ = {",":3930,".":3508,"―":-4841,"、":3930,"。":3508,"〇":4999,"「":1895,"」":3798,"〓":-5156,"あ":4752,"い":-3435,"う":-640,"え":-2514,"お":2405,"か":530,"が":6006,"き":-4482,"ぎ":-3821,"く":-3788,"け":-4376,"げ":-4734,"こ":2255,"ご":1979,"さ":2864,"し":-843,"じ":-2506,"す":-731,"ず":1251,"せ":181,"そ":4091,"た":5034,"だ":5408,"ち":-3654,"っ":-5882,"つ":-1659,"て":3994,"で":7410,"と":4547,"な":5433,"に":6499,"ぬ":1853,"ね":1413,"の":7396,"は":8578,"ば":1940,"ひ":4249,"び":-4134,"ふ":1345,"へ":6665,"べ":-744,"ほ":1464,"ま":1051,"み":-2082,"む":-882,"め":-5046,"も":4169,"ゃ":-2666,"や":2795,"ょ":-1544,"よ":3351,"ら":-2922,"り":-9726,"る":-14896,"れ":-2613,"ろ":-4570,"わ":-1783,"を":13150,"ん":-2352,"カ":2145,"コ":1789,"セ":1287,"ッ":-724,"ト":-403,"メ":-1635,"ラ":-881,"リ":-541,"ル":-856,"ン":-3637,"・":-4371,"ー":-11870,"一":-2069,"中":2210,"予":782,"事":-190,"井":-1768,"人":1036,"以":544,"会":950,"体":-1286,"作":530,"側":4292,"先":601,"党":-2006,"共":-1212,"内":584,"円":788,"初":1347,"前":1623,"副":3879,"力":-302,"動":-740,"務":-2715,"化":776,"区":4517,"協":1013,"参":1555,"合":-1834,"和":-681,"員":-910,"器":-851,"回":1500,"国":-619,"園":-1200,"地":866,"場":-1410,"塁":-2094,"士":-1413,"多":1067,"大":571,"子":-4802,"学":-1397,"定":-1057,"寺":-809,"小":1910,"屋":-1328,"山":-1500,"島":-2056,"川":-2667,"市":2771,"年":374,"庁":-4556,"後":456,"性":553,"感":916,"所":-1566,"支":856,"改":787,"政":2182,"教":704,"文":522,"方":-856,"日":1798,"時":1829,"最":845,"月":-9066,"木":-485,"来":-442,"校":-360,"業":-1043,"氏":5388,"民":-2716,"気":-910,"沢":-939,"済":-543,"物":-735,"率":672,"球":-1267,"生":-1286,"産":-1101,"田":-2900,"町":1826,"的":2586,"目":922,"省":-3485,"県":2997,"空":-867,"立":-2112,"第":788,"米":2937,"系":786,"約":2171,"経":1146,"統":-1169,"総":940,"線":-994,"署":749,"者":2145,"能":-730,"般":-852,"行":-792,"規":792,"警":-1184,"議":-244,"谷":-1000,"賞":730,"車":-1481,"軍":1158,"輪":-1433,"込":-3370,"近":929,"道":-1291,"選":2596,"郎":-4866,"都":1192,"野":-1100,"銀":-2213,"長":357,"間":-2344,"院":-2297,"際":-2604,"電":-878,"領":-1659,"題":-792,"館":-1984,"首":1749,"高":2120,"「":1895,"」":3798,"・":-4371,"ッ":-724,"ー":-11870,"カ":2145,"コ":1789,"セ":1287,"ト":-403,"メ":-1635,"ラ":-881,"リ":-541,"ル":-856,"ン":-3637};
+ this.UW5__ = {",":465,".":-299,"1":-514,"E2":-32768,"]":-2762,"、":465,"。":-299,"「":363,"あ":1655,"い":331,"う":-503,"え":1199,"お":527,"か":647,"が":-421,"き":1624,"ぎ":1971,"く":312,"げ":-983,"さ":-1537,"し":-1371,"す":-852,"だ":-1186,"ち":1093,"っ":52,"つ":921,"て":-18,"で":-850,"と":-127,"ど":1682,"な":-787,"に":-1224,"の":-635,"は":-578,"べ":1001,"み":502,"め":865,"ゃ":3350,"ょ":854,"り":-208,"る":429,"れ":504,"わ":419,"を":-1264,"ん":327,"イ":241,"ル":451,"ン":-343,"中":-871,"京":722,"会":-1153,"党":-654,"務":3519,"区":-901,"告":848,"員":2104,"大":-1296,"学":-548,"定":1785,"嵐":-1304,"市":-2991,"席":921,"年":1763,"思":872,"所":-814,"挙":1618,"新":-1682,"日":218,"月":-4353,"査":932,"格":1356,"機":-1508,"氏":-1347,"田":240,"町":-3912,"的":-3149,"相":1319,"省":-1052,"県":-4003,"研":-997,"社":-278,"空":-813,"統":1955,"者":-2233,"表":663,"語":-1073,"議":1219,"選":-1018,"郎":-368,"長":786,"間":1191,"題":2368,"館":-689,"1":-514,"E2":-32768,"「":363,"イ":241,"ル":451,"ン":-343};
+ this.UW6__ = {",":227,".":808,"1":-270,"E1":306,"、":227,"。":808,"あ":-307,"う":189,"か":241,"が":-73,"く":-121,"こ":-200,"じ":1782,"す":383,"た":-428,"っ":573,"て":-1014,"で":101,"と":-105,"な":-253,"に":-149,"の":-417,"は":-236,"も":-206,"り":187,"る":-135,"を":195,"ル":-673,"ン":-496,"一":-277,"中":201,"件":-800,"会":624,"前":302,"区":1792,"員":-1212,"委":798,"学":-960,"市":887,"広":-695,"後":535,"業":-697,"相":753,"社":-507,"福":974,"空":-822,"者":1811,"連":463,"郎":1082,"1":-270,"E1":306,"ル":-673,"ン":-496};
+
+ return this;
+ }
+ TinySegmenter.prototype.ctype_ = function(str) {
+ for (var i in this.chartype_) {
+ if (str.match(this.chartype_[i][0])) {
+ return this.chartype_[i][1];
+ }
+ }
+ return "O";
+ }
+
+ TinySegmenter.prototype.ts_ = function(v) {
+ if (v) { return v; }
+ return 0;
+ }
+
+ TinySegmenter.prototype.segment = function(input) {
+ if (input == null || input == undefined || input == "") {
+ return [];
+ }
+ var result = [];
+ var seg = ["B3","B2","B1"];
+ var ctype = ["O","O","O"];
+ var o = input.split("");
+ for (i = 0; i < o.length; ++i) {
+ seg.push(o[i]);
+ ctype.push(this.ctype_(o[i]))
+ }
+ seg.push("E1");
+ seg.push("E2");
+ seg.push("E3");
+ ctype.push("O");
+ ctype.push("O");
+ ctype.push("O");
+ var word = seg[3];
+ var p1 = "U";
+ var p2 = "U";
+ var p3 = "U";
+ for (var i = 4; i < seg.length - 3; ++i) {
+ var score = this.BIAS__;
+ var w1 = seg[i-3];
+ var w2 = seg[i-2];
+ var w3 = seg[i-1];
+ var w4 = seg[i];
+ var w5 = seg[i+1];
+ var w6 = seg[i+2];
+ var c1 = ctype[i-3];
+ var c2 = ctype[i-2];
+ var c3 = ctype[i-1];
+ var c4 = ctype[i];
+ var c5 = ctype[i+1];
+ var c6 = ctype[i+2];
+ score += this.ts_(this.UP1__[p1]);
+ score += this.ts_(this.UP2__[p2]);
+ score += this.ts_(this.UP3__[p3]);
+ score += this.ts_(this.BP1__[p1 + p2]);
+ score += this.ts_(this.BP2__[p2 + p3]);
+ score += this.ts_(this.UW1__[w1]);
+ score += this.ts_(this.UW2__[w2]);
+ score += this.ts_(this.UW3__[w3]);
+ score += this.ts_(this.UW4__[w4]);
+ score += this.ts_(this.UW5__[w5]);
+ score += this.ts_(this.UW6__[w6]);
+ score += this.ts_(this.BW1__[w2 + w3]);
+ score += this.ts_(this.BW2__[w3 + w4]);
+ score += this.ts_(this.BW3__[w4 + w5]);
+ score += this.ts_(this.TW1__[w1 + w2 + w3]);
+ score += this.ts_(this.TW2__[w2 + w3 + w4]);
+ score += this.ts_(this.TW3__[w3 + w4 + w5]);
+ score += this.ts_(this.TW4__[w4 + w5 + w6]);
+ score += this.ts_(this.UC1__[c1]);
+ score += this.ts_(this.UC2__[c2]);
+ score += this.ts_(this.UC3__[c3]);
+ score += this.ts_(this.UC4__[c4]);
+ score += this.ts_(this.UC5__[c5]);
+ score += this.ts_(this.UC6__[c6]);
+ score += this.ts_(this.BC1__[c2 + c3]);
+ score += this.ts_(this.BC2__[c3 + c4]);
+ score += this.ts_(this.BC3__[c4 + c5]);
+ score += this.ts_(this.TC1__[c1 + c2 + c3]);
+ score += this.ts_(this.TC2__[c2 + c3 + c4]);
+ score += this.ts_(this.TC3__[c3 + c4 + c5]);
+ score += this.ts_(this.TC4__[c4 + c5 + c6]);
+ // score += this.ts_(this.TC5__[c4 + c5 + c6]);
+ score += this.ts_(this.UQ1__[p1 + c1]);
+ score += this.ts_(this.UQ2__[p2 + c2]);
+ score += this.ts_(this.UQ3__[p3 + c3]);
+ score += this.ts_(this.BQ1__[p2 + c2 + c3]);
+ score += this.ts_(this.BQ2__[p2 + c3 + c4]);
+ score += this.ts_(this.BQ3__[p3 + c2 + c3]);
+ score += this.ts_(this.BQ4__[p3 + c3 + c4]);
+ score += this.ts_(this.TQ1__[p2 + c1 + c2 + c3]);
+ score += this.ts_(this.TQ2__[p2 + c2 + c3 + c4]);
+ score += this.ts_(this.TQ3__[p3 + c1 + c2 + c3]);
+ score += this.ts_(this.TQ4__[p3 + c2 + c3 + c4]);
+ var p = "O";
+ if (score > 0) {
+ result.push(word);
+ word = "";
+ p = "B";
+ }
+ p1 = p2;
+ p2 = p3;
+ p3 = p;
+ word += seg[i];
+ }
+ result.push(word);
+
+ return result;
+ }
+
+ lunr.TinySegmenter = TinySegmenter;
+ };
+
+}));
\ No newline at end of file
diff --git a/venv/lib/python3.11/site-packages/mkdocs/contrib/search/prebuild-index.js b/venv/lib/python3.11/site-packages/mkdocs/contrib/search/prebuild-index.js
new file mode 100644
index 0000000..835d17b
--- /dev/null
+++ b/venv/lib/python3.11/site-packages/mkdocs/contrib/search/prebuild-index.js
@@ -0,0 +1,56 @@
+var lunr = require('./templates/search/lunr'),
+ stdin = process.stdin,
+ stdout = process.stdout,
+ buffer = [];
+
+stdin.resume();
+stdin.setEncoding('utf8');
+
+stdin.on('data', function (data) {
+ buffer.push(data);
+});
+
+stdin.on('end', function () {
+ var data = JSON.parse(buffer.join('')),
+ lang = ['en'];
+
+ if (data.config) {
+ if (data.config.lang && data.config.lang.length) {
+ lang = data.config.lang;
+ if (lang.length > 1 || lang[0] !== "en") {
+ require('./lunr-language/lunr.stemmer.support')(lunr);
+ if (lang.length > 1) {
+ require('./lunr-language/lunr.multi')(lunr);
+ }
+ if (lang.includes("ja") || lang.includes("jp")) {
+ require('./lunr-language/tinyseg')(lunr);
+ }
+ for (var i=0; i < lang.length; i++) {
+ if (lang[i] != 'en') {
+ require('./lunr-language/lunr.' + lang[i])(lunr);
+ }
+ }
+ }
+ }
+ if (data.config.separator && data.config.separator.length) {
+ lunr.tokenizer.separator = new RegExp(data.config.separator);
+ }
+ }
+
+ var idx = lunr(function () {
+ if (lang.length === 1 && lang[0] !== "en" && lunr[lang[0]]) {
+ this.use(lunr[lang[0]]);
+ } else if (lang.length > 1) {
+ this.use(lunr.multiLanguage.apply(null, lang));
+ }
+ this.field('title');
+ this.field('text');
+ this.ref('location');
+
+ data.docs.forEach(function (doc) {
+ this.add(doc);
+ }, this);
+ });
+
+ stdout.write(JSON.stringify(idx));
+});
diff --git a/venv/lib/python3.11/site-packages/mkdocs/contrib/search/search_index.py b/venv/lib/python3.11/site-packages/mkdocs/contrib/search/search_index.py
new file mode 100644
index 0000000..18e406f
--- /dev/null
+++ b/venv/lib/python3.11/site-packages/mkdocs/contrib/search/search_index.py
@@ -0,0 +1,230 @@
+from __future__ import annotations
+
+import json
+import logging
+import os
+import re
+import subprocess
+from html.parser import HTMLParser
+from typing import List, Optional, Tuple
+
+from mkdocs.structure.pages import Page
+from mkdocs.structure.toc import AnchorLink, TableOfContents
+
+try:
+ from lunr import lunr
+
+ haslunrpy = True
+except ImportError:
+ haslunrpy = False
+
+log = logging.getLogger(__name__)
+
+
+class SearchIndex:
+ """
+ Search index is a collection of pages and sections (heading
+ tags and their following content are sections).
+ """
+
+ def __init__(self, **config) -> None:
+ self._entries: List[dict] = []
+ self.config = config
+
+ def _find_toc_by_id(self, toc, id_: Optional[str]) -> Optional[AnchorLink]:
+ """
+ Given a table of contents and HTML ID, iterate through
+ and return the matched item in the TOC.
+ """
+ for toc_item in toc:
+ if toc_item.id == id_:
+ return toc_item
+ toc_item_r = self._find_toc_by_id(toc_item.children, id_)
+ if toc_item_r is not None:
+ return toc_item_r
+ return None
+
+ def _add_entry(self, title: Optional[str], text: str, loc: str) -> None:
+ """
+ A simple wrapper to add an entry, dropping bad characters.
+ """
+ text = text.replace('\u00a0', ' ')
+ text = re.sub(r'[ \t\n\r\f\v]+', ' ', text.strip())
+
+ self._entries.append({'title': title, 'text': text, 'location': loc})
+
+ def add_entry_from_context(self, page: Page) -> None:
+ """
+ Create a set of entries in the index for a page. One for
+ the page itself and then one for each of its' heading
+ tags.
+ """
+ # Create the content parser and feed in the HTML for the
+ # full page. This handles all the parsing and prepares
+ # us to iterate through it.
+ parser = ContentParser()
+ assert page.content is not None
+ parser.feed(page.content)
+ parser.close()
+
+ # Get the absolute URL for the page, this is then
+ # prepended to the urls of the sections
+ url = page.url
+
+ # Create an entry for the full page.
+ text = parser.stripped_html.rstrip('\n') if self.config['indexing'] == 'full' else ''
+ self._add_entry(title=page.title, text=text, loc=url)
+
+ if self.config['indexing'] in ['full', 'sections']:
+ for section in parser.data:
+ self.create_entry_for_section(section, page.toc, url)
+
+ def create_entry_for_section(
+ self, section: ContentSection, toc: TableOfContents, abs_url: str
+ ) -> None:
+ """
+ Given a section on the page, the table of contents and
+ the absolute url for the page create an entry in the
+ index
+ """
+ toc_item = self._find_toc_by_id(toc, section.id)
+
+ text = ' '.join(section.text) if self.config['indexing'] == 'full' else ''
+ if toc_item is not None:
+ self._add_entry(title=toc_item.title, text=text, loc=abs_url + toc_item.url)
+
+ def generate_search_index(self) -> str:
+ """python to json conversion"""
+ page_dicts = {'docs': self._entries, 'config': self.config}
+ data = json.dumps(page_dicts, sort_keys=True, separators=(',', ':'), default=str)
+
+ if self.config['prebuild_index'] in (True, 'node'):
+ try:
+ script_path = os.path.join(
+ os.path.dirname(os.path.abspath(__file__)), 'prebuild-index.js'
+ )
+ p = subprocess.Popen(
+ ['node', script_path],
+ stdin=subprocess.PIPE,
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE,
+ encoding='utf-8',
+ )
+ idx, err = p.communicate(data)
+ if not err:
+ page_dicts['index'] = json.loads(idx)
+ data = json.dumps(page_dicts, sort_keys=True, separators=(',', ':'))
+ log.debug('Pre-built search index created successfully.')
+ else:
+ log.warning(f'Failed to pre-build search index. Error: {err}')
+ except (OSError, ValueError) as e:
+ log.warning(f'Failed to pre-build search index. Error: {e}')
+ elif self.config['prebuild_index'] == 'python':
+ if haslunrpy:
+ lunr_idx = lunr(
+ ref='location',
+ fields=('title', 'text'),
+ documents=self._entries,
+ languages=self.config['lang'],
+ )
+ page_dicts['index'] = lunr_idx.serialize()
+ data = json.dumps(page_dicts, sort_keys=True, separators=(',', ':'))
+ else:
+ log.warning(
+ "Failed to pre-build search index. The 'python' method was specified; "
+ "however, the 'lunr.py' library does not appear to be installed. Try "
+ "installing it with 'pip install lunr'. If you are using any language "
+ "other than English you will also need to install 'lunr[languages]'."
+ )
+
+ return data
+
+
+class ContentSection:
+ """
+ Used by the ContentParser class to capture the information we
+ need when it is parsing the HMTL.
+ """
+
+ def __init__(
+ self,
+ text: Optional[List[str]] = None,
+ id_: Optional[str] = None,
+ title: Optional[str] = None,
+ ) -> None:
+ self.text = text or []
+ self.id = id_
+ self.title = title
+
+ def __eq__(self, other):
+ return self.text == other.text and self.id == other.id and self.title == other.title
+
+
+_HEADER_TAGS = tuple(f"h{x}" for x in range(1, 7))
+
+
+class ContentParser(HTMLParser):
+ """
+ Given a block of HTML, group the content under the preceding
+ heading tags which can then be used for creating an index
+ for that section.
+ """
+
+ def __init__(self, *args, **kwargs) -> None:
+ super().__init__(*args, **kwargs)
+
+ self.data: List[ContentSection] = []
+ self.section: Optional[ContentSection] = None
+ self.is_header_tag = False
+ self._stripped_html: List[str] = []
+
+ def handle_starttag(self, tag: str, attrs: List[Tuple[str, Optional[str]]]) -> None:
+ """Called at the start of every HTML tag."""
+
+ # We only care about the opening tag for headings.
+ if tag not in _HEADER_TAGS:
+ return
+
+ # We are dealing with a new header, create a new section
+ # for it and assign the ID if it has one.
+ self.is_header_tag = True
+ self.section = ContentSection()
+ self.data.append(self.section)
+
+ for attr in attrs:
+ if attr[0] == "id":
+ self.section.id = attr[1]
+
+ def handle_endtag(self, tag: str) -> None:
+ """Called at the end of every HTML tag."""
+
+ # We only care about the opening tag for headings.
+ if tag not in _HEADER_TAGS:
+ return
+
+ self.is_header_tag = False
+
+ def handle_data(self, data: str) -> None:
+ """
+ Called for the text contents of each tag.
+ """
+ self._stripped_html.append(data)
+
+ if self.section is None:
+ # This means we have some content at the start of the
+ # HTML before we reach a heading tag. We don't actually
+ # care about that content as it will be added to the
+ # overall page entry in the search. So just skip it.
+ return
+
+ # If this is a header, then the data is the title.
+ # Otherwise it is content of something under that header
+ # section.
+ if self.is_header_tag:
+ self.section.title = data
+ else:
+ self.section.text.append(data.rstrip('\n'))
+
+ @property
+ def stripped_html(self) -> str:
+ return '\n'.join(self._stripped_html)
diff --git a/venv/lib/python3.11/site-packages/mkdocs/contrib/search/templates/search/lunr.js b/venv/lib/python3.11/site-packages/mkdocs/contrib/search/templates/search/lunr.js
new file mode 100644
index 0000000..aca0a16
--- /dev/null
+++ b/venv/lib/python3.11/site-packages/mkdocs/contrib/search/templates/search/lunr.js
@@ -0,0 +1,3475 @@
+/**
+ * lunr - http://lunrjs.com - A bit like Solr, but much smaller and not as bright - 2.3.9
+ * Copyright (C) 2020 Oliver Nightingale
+ * @license MIT
+ */
+
+;(function(){
+
+/**
+ * A convenience function for configuring and constructing
+ * a new lunr Index.
+ *
+ * A lunr.Builder instance is created and the pipeline setup
+ * with a trimmer, stop word filter and stemmer.
+ *
+ * This builder object is yielded to the configuration function
+ * that is passed as a parameter, allowing the list of fields
+ * and other builder parameters to be customised.
+ *
+ * All documents _must_ be added within the passed config function.
+ *
+ * @example
+ * var idx = lunr(function () {
+ * this.field('title')
+ * this.field('body')
+ * this.ref('id')
+ *
+ * documents.forEach(function (doc) {
+ * this.add(doc)
+ * }, this)
+ * })
+ *
+ * @see {@link lunr.Builder}
+ * @see {@link lunr.Pipeline}
+ * @see {@link lunr.trimmer}
+ * @see {@link lunr.stopWordFilter}
+ * @see {@link lunr.stemmer}
+ * @namespace {function} lunr
+ */
+var lunr = function (config) {
+ var builder = new lunr.Builder
+
+ builder.pipeline.add(
+ lunr.trimmer,
+ lunr.stopWordFilter,
+ lunr.stemmer
+ )
+
+ builder.searchPipeline.add(
+ lunr.stemmer
+ )
+
+ config.call(builder, builder)
+ return builder.build()
+}
+
+lunr.version = "2.3.9"
+/*!
+ * lunr.utils
+ * Copyright (C) 2020 Oliver Nightingale
+ */
+
+/**
+ * A namespace containing utils for the rest of the lunr library
+ * @namespace lunr.utils
+ */
+lunr.utils = {}
+
+/**
+ * Print a warning message to the console.
+ *
+ * @param {String} message The message to be printed.
+ * @memberOf lunr.utils
+ * @function
+ */
+lunr.utils.warn = (function (global) {
+ /* eslint-disable no-console */
+ return function (message) {
+ if (global.console && console.warn) {
+ console.warn(message)
+ }
+ }
+ /* eslint-enable no-console */
+})(this)
+
+/**
+ * Convert an object to a string.
+ *
+ * In the case of `null` and `undefined` the function returns
+ * the empty string, in all other cases the result of calling
+ * `toString` on the passed object is returned.
+ *
+ * @param {Any} obj The object to convert to a string.
+ * @return {String} string representation of the passed object.
+ * @memberOf lunr.utils
+ */
+lunr.utils.asString = function (obj) {
+ if (obj === void 0 || obj === null) {
+ return ""
+ } else {
+ return obj.toString()
+ }
+}
+
+/**
+ * Clones an object.
+ *
+ * Will create a copy of an existing object such that any mutations
+ * on the copy cannot affect the original.
+ *
+ * Only shallow objects are supported, passing a nested object to this
+ * function will cause a TypeError.
+ *
+ * Objects with primitives, and arrays of primitives are supported.
+ *
+ * @param {Object} obj The object to clone.
+ * @return {Object} a clone of the passed object.
+ * @throws {TypeError} when a nested object is passed.
+ * @memberOf Utils
+ */
+lunr.utils.clone = function (obj) {
+ if (obj === null || obj === undefined) {
+ return obj
+ }
+
+ var clone = Object.create(null),
+ keys = Object.keys(obj)
+
+ for (var i = 0; i < keys.length; i++) {
+ var key = keys[i],
+ val = obj[key]
+
+ if (Array.isArray(val)) {
+ clone[key] = val.slice()
+ continue
+ }
+
+ if (typeof val === 'string' ||
+ typeof val === 'number' ||
+ typeof val === 'boolean') {
+ clone[key] = val
+ continue
+ }
+
+ throw new TypeError("clone is not deep and does not support nested objects")
+ }
+
+ return clone
+}
+lunr.FieldRef = function (docRef, fieldName, stringValue) {
+ this.docRef = docRef
+ this.fieldName = fieldName
+ this._stringValue = stringValue
+}
+
+lunr.FieldRef.joiner = "/"
+
+lunr.FieldRef.fromString = function (s) {
+ var n = s.indexOf(lunr.FieldRef.joiner)
+
+ if (n === -1) {
+ throw "malformed field ref string"
+ }
+
+ var fieldRef = s.slice(0, n),
+ docRef = s.slice(n + 1)
+
+ return new lunr.FieldRef (docRef, fieldRef, s)
+}
+
+lunr.FieldRef.prototype.toString = function () {
+ if (this._stringValue == undefined) {
+ this._stringValue = this.fieldName + lunr.FieldRef.joiner + this.docRef
+ }
+
+ return this._stringValue
+}
+/*!
+ * lunr.Set
+ * Copyright (C) 2020 Oliver Nightingale
+ */
+
+/**
+ * A lunr set.
+ *
+ * @constructor
+ */
+lunr.Set = function (elements) {
+ this.elements = Object.create(null)
+
+ if (elements) {
+ this.length = elements.length
+
+ for (var i = 0; i < this.length; i++) {
+ this.elements[elements[i]] = true
+ }
+ } else {
+ this.length = 0
+ }
+}
+
+/**
+ * A complete set that contains all elements.
+ *
+ * @static
+ * @readonly
+ * @type {lunr.Set}
+ */
+lunr.Set.complete = {
+ intersect: function (other) {
+ return other
+ },
+
+ union: function () {
+ return this
+ },
+
+ contains: function () {
+ return true
+ }
+}
+
+/**
+ * An empty set that contains no elements.
+ *
+ * @static
+ * @readonly
+ * @type {lunr.Set}
+ */
+lunr.Set.empty = {
+ intersect: function () {
+ return this
+ },
+
+ union: function (other) {
+ return other
+ },
+
+ contains: function () {
+ return false
+ }
+}
+
+/**
+ * Returns true if this set contains the specified object.
+ *
+ * @param {object} object - Object whose presence in this set is to be tested.
+ * @returns {boolean} - True if this set contains the specified object.
+ */
+lunr.Set.prototype.contains = function (object) {
+ return !!this.elements[object]
+}
+
+/**
+ * Returns a new set containing only the elements that are present in both
+ * this set and the specified set.
+ *
+ * @param {lunr.Set} other - set to intersect with this set.
+ * @returns {lunr.Set} a new set that is the intersection of this and the specified set.
+ */
+
+lunr.Set.prototype.intersect = function (other) {
+ var a, b, elements, intersection = []
+
+ if (other === lunr.Set.complete) {
+ return this
+ }
+
+ if (other === lunr.Set.empty) {
+ return other
+ }
+
+ if (this.length < other.length) {
+ a = this
+ b = other
+ } else {
+ a = other
+ b = this
+ }
+
+ elements = Object.keys(a.elements)
+
+ for (var i = 0; i < elements.length; i++) {
+ var element = elements[i]
+ if (element in b.elements) {
+ intersection.push(element)
+ }
+ }
+
+ return new lunr.Set (intersection)
+}
+
+/**
+ * Returns a new set combining the elements of this and the specified set.
+ *
+ * @param {lunr.Set} other - set to union with this set.
+ * @return {lunr.Set} a new set that is the union of this and the specified set.
+ */
+
+lunr.Set.prototype.union = function (other) {
+ if (other === lunr.Set.complete) {
+ return lunr.Set.complete
+ }
+
+ if (other === lunr.Set.empty) {
+ return this
+ }
+
+ return new lunr.Set(Object.keys(this.elements).concat(Object.keys(other.elements)))
+}
+/**
+ * A function to calculate the inverse document frequency for
+ * a posting. This is shared between the builder and the index
+ *
+ * @private
+ * @param {object} posting - The posting for a given term
+ * @param {number} documentCount - The total number of documents.
+ */
+lunr.idf = function (posting, documentCount) {
+ var documentsWithTerm = 0
+
+ for (var fieldName in posting) {
+ if (fieldName == '_index') continue // Ignore the term index, its not a field
+ documentsWithTerm += Object.keys(posting[fieldName]).length
+ }
+
+ var x = (documentCount - documentsWithTerm + 0.5) / (documentsWithTerm + 0.5)
+
+ return Math.log(1 + Math.abs(x))
+}
+
+/**
+ * A token wraps a string representation of a token
+ * as it is passed through the text processing pipeline.
+ *
+ * @constructor
+ * @param {string} [str=''] - The string token being wrapped.
+ * @param {object} [metadata={}] - Metadata associated with this token.
+ */
+lunr.Token = function (str, metadata) {
+ this.str = str || ""
+ this.metadata = metadata || {}
+}
+
+/**
+ * Returns the token string that is being wrapped by this object.
+ *
+ * @returns {string}
+ */
+lunr.Token.prototype.toString = function () {
+ return this.str
+}
+
+/**
+ * A token update function is used when updating or optionally
+ * when cloning a token.
+ *
+ * @callback lunr.Token~updateFunction
+ * @param {string} str - The string representation of the token.
+ * @param {Object} metadata - All metadata associated with this token.
+ */
+
+/**
+ * Applies the given function to the wrapped string token.
+ *
+ * @example
+ * token.update(function (str, metadata) {
+ * return str.toUpperCase()
+ * })
+ *
+ * @param {lunr.Token~updateFunction} fn - A function to apply to the token string.
+ * @returns {lunr.Token}
+ */
+lunr.Token.prototype.update = function (fn) {
+ this.str = fn(this.str, this.metadata)
+ return this
+}
+
+/**
+ * Creates a clone of this token. Optionally a function can be
+ * applied to the cloned token.
+ *
+ * @param {lunr.Token~updateFunction} [fn] - An optional function to apply to the cloned token.
+ * @returns {lunr.Token}
+ */
+lunr.Token.prototype.clone = function (fn) {
+ fn = fn || function (s) { return s }
+ return new lunr.Token (fn(this.str, this.metadata), this.metadata)
+}
+/*!
+ * lunr.tokenizer
+ * Copyright (C) 2020 Oliver Nightingale
+ */
+
+/**
+ * A function for splitting a string into tokens ready to be inserted into
+ * the search index. Uses `lunr.tokenizer.separator` to split strings, change
+ * the value of this property to change how strings are split into tokens.
+ *
+ * This tokenizer will convert its parameter to a string by calling `toString` and
+ * then will split this string on the character in `lunr.tokenizer.separator`.
+ * Arrays will have their elements converted to strings and wrapped in a lunr.Token.
+ *
+ * Optional metadata can be passed to the tokenizer, this metadata will be cloned and
+ * added as metadata to every token that is created from the object to be tokenized.
+ *
+ * @static
+ * @param {?(string|object|object[])} obj - The object to convert into tokens
+ * @param {?object} metadata - Optional metadata to associate with every token
+ * @returns {lunr.Token[]}
+ * @see {@link lunr.Pipeline}
+ */
+lunr.tokenizer = function (obj, metadata) {
+ if (obj == null || obj == undefined) {
+ return []
+ }
+
+ if (Array.isArray(obj)) {
+ return obj.map(function (t) {
+ return new lunr.Token(
+ lunr.utils.asString(t).toLowerCase(),
+ lunr.utils.clone(metadata)
+ )
+ })
+ }
+
+ var str = obj.toString().toLowerCase(),
+ len = str.length,
+ tokens = []
+
+ for (var sliceEnd = 0, sliceStart = 0; sliceEnd <= len; sliceEnd++) {
+ var char = str.charAt(sliceEnd),
+ sliceLength = sliceEnd - sliceStart
+
+ if ((char.match(lunr.tokenizer.separator) || sliceEnd == len)) {
+
+ if (sliceLength > 0) {
+ var tokenMetadata = lunr.utils.clone(metadata) || {}
+ tokenMetadata["position"] = [sliceStart, sliceLength]
+ tokenMetadata["index"] = tokens.length
+
+ tokens.push(
+ new lunr.Token (
+ str.slice(sliceStart, sliceEnd),
+ tokenMetadata
+ )
+ )
+ }
+
+ sliceStart = sliceEnd + 1
+ }
+
+ }
+
+ return tokens
+}
+
+/**
+ * The separator used to split a string into tokens. Override this property to change the behaviour of
+ * `lunr.tokenizer` behaviour when tokenizing strings. By default this splits on whitespace and hyphens.
+ *
+ * @static
+ * @see lunr.tokenizer
+ */
+lunr.tokenizer.separator = /[\s\-]+/
+/*!
+ * lunr.Pipeline
+ * Copyright (C) 2020 Oliver Nightingale
+ */
+
+/**
+ * lunr.Pipelines maintain an ordered list of functions to be applied to all
+ * tokens in documents entering the search index and queries being ran against
+ * the index.
+ *
+ * An instance of lunr.Index created with the lunr shortcut will contain a
+ * pipeline with a stop word filter and an English language stemmer. Extra
+ * functions can be added before or after either of these functions or these
+ * default functions can be removed.
+ *
+ * When run the pipeline will call each function in turn, passing a token, the
+ * index of that token in the original list of all tokens and finally a list of
+ * all the original tokens.
+ *
+ * The output of functions in the pipeline will be passed to the next function
+ * in the pipeline. To exclude a token from entering the index the function
+ * should return undefined, the rest of the pipeline will not be called with
+ * this token.
+ *
+ * For serialisation of pipelines to work, all functions used in an instance of
+ * a pipeline should be registered with lunr.Pipeline. Registered functions can
+ * then be loaded. If trying to load a serialised pipeline that uses functions
+ * that are not registered an error will be thrown.
+ *
+ * If not planning on serialising the pipeline then registering pipeline functions
+ * is not necessary.
+ *
+ * @constructor
+ */
+lunr.Pipeline = function () {
+ this._stack = []
+}
+
+lunr.Pipeline.registeredFunctions = Object.create(null)
+
+/**
+ * A pipeline function maps lunr.Token to lunr.Token. A lunr.Token contains the token
+ * string as well as all known metadata. A pipeline function can mutate the token string
+ * or mutate (or add) metadata for a given token.
+ *
+ * A pipeline function can indicate that the passed token should be discarded by returning
+ * null, undefined or an empty string. This token will not be passed to any downstream pipeline
+ * functions and will not be added to the index.
+ *
+ * Multiple tokens can be returned by returning an array of tokens. Each token will be passed
+ * to any downstream pipeline functions and all will returned tokens will be added to the index.
+ *
+ * Any number of pipeline functions may be chained together using a lunr.Pipeline.
+ *
+ * @interface lunr.PipelineFunction
+ * @param {lunr.Token} token - A token from the document being processed.
+ * @param {number} i - The index of this token in the complete list of tokens for this document/field.
+ * @param {lunr.Token[]} tokens - All tokens for this document/field.
+ * @returns {(?lunr.Token|lunr.Token[])}
+ */
+
+/**
+ * Register a function with the pipeline.
+ *
+ * Functions that are used in the pipeline should be registered if the pipeline
+ * needs to be serialised, or a serialised pipeline needs to be loaded.
+ *
+ * Registering a function does not add it to a pipeline, functions must still be
+ * added to instances of the pipeline for them to be used when running a pipeline.
+ *
+ * @param {lunr.PipelineFunction} fn - The function to check for.
+ * @param {String} label - The label to register this function with
+ */
+lunr.Pipeline.registerFunction = function (fn, label) {
+ if (label in this.registeredFunctions) {
+ lunr.utils.warn('Overwriting existing registered function: ' + label)
+ }
+
+ fn.label = label
+ lunr.Pipeline.registeredFunctions[fn.label] = fn
+}
+
+/**
+ * Warns if the function is not registered as a Pipeline function.
+ *
+ * @param {lunr.PipelineFunction} fn - The function to check for.
+ * @private
+ */
+lunr.Pipeline.warnIfFunctionNotRegistered = function (fn) {
+ var isRegistered = fn.label && (fn.label in this.registeredFunctions)
+
+ if (!isRegistered) {
+ lunr.utils.warn('Function is not registered with pipeline. This may cause problems when serialising the index.\n', fn)
+ }
+}
+
+/**
+ * Loads a previously serialised pipeline.
+ *
+ * All functions to be loaded must already be registered with lunr.Pipeline.
+ * If any function from the serialised data has not been registered then an
+ * error will be thrown.
+ *
+ * @param {Object} serialised - The serialised pipeline to load.
+ * @returns {lunr.Pipeline}
+ */
+lunr.Pipeline.load = function (serialised) {
+ var pipeline = new lunr.Pipeline
+
+ serialised.forEach(function (fnName) {
+ var fn = lunr.Pipeline.registeredFunctions[fnName]
+
+ if (fn) {
+ pipeline.add(fn)
+ } else {
+ throw new Error('Cannot load unregistered function: ' + fnName)
+ }
+ })
+
+ return pipeline
+}
+
+/**
+ * Adds new functions to the end of the pipeline.
+ *
+ * Logs a warning if the function has not been registered.
+ *
+ * @param {lunr.PipelineFunction[]} functions - Any number of functions to add to the pipeline.
+ */
+lunr.Pipeline.prototype.add = function () {
+ var fns = Array.prototype.slice.call(arguments)
+
+ fns.forEach(function (fn) {
+ lunr.Pipeline.warnIfFunctionNotRegistered(fn)
+ this._stack.push(fn)
+ }, this)
+}
+
+/**
+ * Adds a single function after a function that already exists in the
+ * pipeline.
+ *
+ * Logs a warning if the function has not been registered.
+ *
+ * @param {lunr.PipelineFunction} existingFn - A function that already exists in the pipeline.
+ * @param {lunr.PipelineFunction} newFn - The new function to add to the pipeline.
+ */
+lunr.Pipeline.prototype.after = function (existingFn, newFn) {
+ lunr.Pipeline.warnIfFunctionNotRegistered(newFn)
+
+ var pos = this._stack.indexOf(existingFn)
+ if (pos == -1) {
+ throw new Error('Cannot find existingFn')
+ }
+
+ pos = pos + 1
+ this._stack.splice(pos, 0, newFn)
+}
+
+/**
+ * Adds a single function before a function that already exists in the
+ * pipeline.
+ *
+ * Logs a warning if the function has not been registered.
+ *
+ * @param {lunr.PipelineFunction} existingFn - A function that already exists in the pipeline.
+ * @param {lunr.PipelineFunction} newFn - The new function to add to the pipeline.
+ */
+lunr.Pipeline.prototype.before = function (existingFn, newFn) {
+ lunr.Pipeline.warnIfFunctionNotRegistered(newFn)
+
+ var pos = this._stack.indexOf(existingFn)
+ if (pos == -1) {
+ throw new Error('Cannot find existingFn')
+ }
+
+ this._stack.splice(pos, 0, newFn)
+}
+
+/**
+ * Removes a function from the pipeline.
+ *
+ * @param {lunr.PipelineFunction} fn The function to remove from the pipeline.
+ */
+lunr.Pipeline.prototype.remove = function (fn) {
+ var pos = this._stack.indexOf(fn)
+ if (pos == -1) {
+ return
+ }
+
+ this._stack.splice(pos, 1)
+}
+
+/**
+ * Runs the current list of functions that make up the pipeline against the
+ * passed tokens.
+ *
+ * @param {Array} tokens The tokens to run through the pipeline.
+ * @returns {Array}
+ */
+lunr.Pipeline.prototype.run = function (tokens) {
+ var stackLength = this._stack.length
+
+ for (var i = 0; i < stackLength; i++) {
+ var fn = this._stack[i]
+ var memo = []
+
+ for (var j = 0; j < tokens.length; j++) {
+ var result = fn(tokens[j], j, tokens)
+
+ if (result === null || result === void 0 || result === '') continue
+
+ if (Array.isArray(result)) {
+ for (var k = 0; k < result.length; k++) {
+ memo.push(result[k])
+ }
+ } else {
+ memo.push(result)
+ }
+ }
+
+ tokens = memo
+ }
+
+ return tokens
+}
+
+/**
+ * Convenience method for passing a string through a pipeline and getting
+ * strings out. This method takes care of wrapping the passed string in a
+ * token and mapping the resulting tokens back to strings.
+ *
+ * @param {string} str - The string to pass through the pipeline.
+ * @param {?object} metadata - Optional metadata to associate with the token
+ * passed to the pipeline.
+ * @returns {string[]}
+ */
+lunr.Pipeline.prototype.runString = function (str, metadata) {
+ var token = new lunr.Token (str, metadata)
+
+ return this.run([token]).map(function (t) {
+ return t.toString()
+ })
+}
+
+/**
+ * Resets the pipeline by removing any existing processors.
+ *
+ */
+lunr.Pipeline.prototype.reset = function () {
+ this._stack = []
+}
+
+/**
+ * Returns a representation of the pipeline ready for serialisation.
+ *
+ * Logs a warning if the function has not been registered.
+ *
+ * @returns {Array}
+ */
+lunr.Pipeline.prototype.toJSON = function () {
+ return this._stack.map(function (fn) {
+ lunr.Pipeline.warnIfFunctionNotRegistered(fn)
+
+ return fn.label
+ })
+}
+/*!
+ * lunr.Vector
+ * Copyright (C) 2020 Oliver Nightingale
+ */
+
+/**
+ * A vector is used to construct the vector space of documents and queries. These
+ * vectors support operations to determine the similarity between two documents or
+ * a document and a query.
+ *
+ * Normally no parameters are required for initializing a vector, but in the case of
+ * loading a previously dumped vector the raw elements can be provided to the constructor.
+ *
+ * For performance reasons vectors are implemented with a flat array, where an elements
+ * index is immediately followed by its value. E.g. [index, value, index, value]. This
+ * allows the underlying array to be as sparse as possible and still offer decent
+ * performance when being used for vector calculations.
+ *
+ * @constructor
+ * @param {Number[]} [elements] - The flat list of element index and element value pairs.
+ */
+lunr.Vector = function (elements) {
+ this._magnitude = 0
+ this.elements = elements || []
+}
+
+
+/**
+ * Calculates the position within the vector to insert a given index.
+ *
+ * This is used internally by insert and upsert. If there are duplicate indexes then
+ * the position is returned as if the value for that index were to be updated, but it
+ * is the callers responsibility to check whether there is a duplicate at that index
+ *
+ * @param {Number} insertIdx - The index at which the element should be inserted.
+ * @returns {Number}
+ */
+lunr.Vector.prototype.positionForIndex = function (index) {
+ // For an empty vector the tuple can be inserted at the beginning
+ if (this.elements.length == 0) {
+ return 0
+ }
+
+ var start = 0,
+ end = this.elements.length / 2,
+ sliceLength = end - start,
+ pivotPoint = Math.floor(sliceLength / 2),
+ pivotIndex = this.elements[pivotPoint * 2]
+
+ while (sliceLength > 1) {
+ if (pivotIndex < index) {
+ start = pivotPoint
+ }
+
+ if (pivotIndex > index) {
+ end = pivotPoint
+ }
+
+ if (pivotIndex == index) {
+ break
+ }
+
+ sliceLength = end - start
+ pivotPoint = start + Math.floor(sliceLength / 2)
+ pivotIndex = this.elements[pivotPoint * 2]
+ }
+
+ if (pivotIndex == index) {
+ return pivotPoint * 2
+ }
+
+ if (pivotIndex > index) {
+ return pivotPoint * 2
+ }
+
+ if (pivotIndex < index) {
+ return (pivotPoint + 1) * 2
+ }
+}
+
+/**
+ * Inserts an element at an index within the vector.
+ *
+ * Does not allow duplicates, will throw an error if there is already an entry
+ * for this index.
+ *
+ * @param {Number} insertIdx - The index at which the element should be inserted.
+ * @param {Number} val - The value to be inserted into the vector.
+ */
+lunr.Vector.prototype.insert = function (insertIdx, val) {
+ this.upsert(insertIdx, val, function () {
+ throw "duplicate index"
+ })
+}
+
+/**
+ * Inserts or updates an existing index within the vector.
+ *
+ * @param {Number} insertIdx - The index at which the element should be inserted.
+ * @param {Number} val - The value to be inserted into the vector.
+ * @param {function} fn - A function that is called for updates, the existing value and the
+ * requested value are passed as arguments
+ */
+lunr.Vector.prototype.upsert = function (insertIdx, val, fn) {
+ this._magnitude = 0
+ var position = this.positionForIndex(insertIdx)
+
+ if (this.elements[position] == insertIdx) {
+ this.elements[position + 1] = fn(this.elements[position + 1], val)
+ } else {
+ this.elements.splice(position, 0, insertIdx, val)
+ }
+}
+
+/**
+ * Calculates the magnitude of this vector.
+ *
+ * @returns {Number}
+ */
+lunr.Vector.prototype.magnitude = function () {
+ if (this._magnitude) return this._magnitude
+
+ var sumOfSquares = 0,
+ elementsLength = this.elements.length
+
+ for (var i = 1; i < elementsLength; i += 2) {
+ var val = this.elements[i]
+ sumOfSquares += val * val
+ }
+
+ return this._magnitude = Math.sqrt(sumOfSquares)
+}
+
+/**
+ * Calculates the dot product of this vector and another vector.
+ *
+ * @param {lunr.Vector} otherVector - The vector to compute the dot product with.
+ * @returns {Number}
+ */
+lunr.Vector.prototype.dot = function (otherVector) {
+ var dotProduct = 0,
+ a = this.elements, b = otherVector.elements,
+ aLen = a.length, bLen = b.length,
+ aVal = 0, bVal = 0,
+ i = 0, j = 0
+
+ while (i < aLen && j < bLen) {
+ aVal = a[i], bVal = b[j]
+ if (aVal < bVal) {
+ i += 2
+ } else if (aVal > bVal) {
+ j += 2
+ } else if (aVal == bVal) {
+ dotProduct += a[i + 1] * b[j + 1]
+ i += 2
+ j += 2
+ }
+ }
+
+ return dotProduct
+}
+
+/**
+ * Calculates the similarity between this vector and another vector.
+ *
+ * @param {lunr.Vector} otherVector - The other vector to calculate the
+ * similarity with.
+ * @returns {Number}
+ */
+lunr.Vector.prototype.similarity = function (otherVector) {
+ return this.dot(otherVector) / this.magnitude() || 0
+}
+
+/**
+ * Converts the vector to an array of the elements within the vector.
+ *
+ * @returns {Number[]}
+ */
+lunr.Vector.prototype.toArray = function () {
+ var output = new Array (this.elements.length / 2)
+
+ for (var i = 1, j = 0; i < this.elements.length; i += 2, j++) {
+ output[j] = this.elements[i]
+ }
+
+ return output
+}
+
+/**
+ * A JSON serializable representation of the vector.
+ *
+ * @returns {Number[]}
+ */
+lunr.Vector.prototype.toJSON = function () {
+ return this.elements
+}
+/* eslint-disable */
+/*!
+ * lunr.stemmer
+ * Copyright (C) 2020 Oliver Nightingale
+ * Includes code from - http://tartarus.org/~martin/PorterStemmer/js.txt
+ */
+
+/**
+ * lunr.stemmer is an english language stemmer, this is a JavaScript
+ * implementation of the PorterStemmer taken from http://tartarus.org/~martin
+ *
+ * @static
+ * @implements {lunr.PipelineFunction}
+ * @param {lunr.Token} token - The string to stem
+ * @returns {lunr.Token}
+ * @see {@link lunr.Pipeline}
+ * @function
+ */
+lunr.stemmer = (function(){
+ var step2list = {
+ "ational" : "ate",
+ "tional" : "tion",
+ "enci" : "ence",
+ "anci" : "ance",
+ "izer" : "ize",
+ "bli" : "ble",
+ "alli" : "al",
+ "entli" : "ent",
+ "eli" : "e",
+ "ousli" : "ous",
+ "ization" : "ize",
+ "ation" : "ate",
+ "ator" : "ate",
+ "alism" : "al",
+ "iveness" : "ive",
+ "fulness" : "ful",
+ "ousness" : "ous",
+ "aliti" : "al",
+ "iviti" : "ive",
+ "biliti" : "ble",
+ "logi" : "log"
+ },
+
+ step3list = {
+ "icate" : "ic",
+ "ative" : "",
+ "alize" : "al",
+ "iciti" : "ic",
+ "ical" : "ic",
+ "ful" : "",
+ "ness" : ""
+ },
+
+ c = "[^aeiou]", // consonant
+ v = "[aeiouy]", // vowel
+ C = c + "[^aeiouy]*", // consonant sequence
+ V = v + "[aeiou]*", // vowel sequence
+
+ mgr0 = "^(" + C + ")?" + V + C, // [C]VC... is m>0
+ meq1 = "^(" + C + ")?" + V + C + "(" + V + ")?$", // [C]VC[V] is m=1
+ mgr1 = "^(" + C + ")?" + V + C + V + C, // [C]VCVC... is m>1
+ s_v = "^(" + C + ")?" + v; // vowel in stem
+
+ var re_mgr0 = new RegExp(mgr0);
+ var re_mgr1 = new RegExp(mgr1);
+ var re_meq1 = new RegExp(meq1);
+ var re_s_v = new RegExp(s_v);
+
+ var re_1a = /^(.+?)(ss|i)es$/;
+ var re2_1a = /^(.+?)([^s])s$/;
+ var re_1b = /^(.+?)eed$/;
+ var re2_1b = /^(.+?)(ed|ing)$/;
+ var re_1b_2 = /.$/;
+ var re2_1b_2 = /(at|bl|iz)$/;
+ var re3_1b_2 = new RegExp("([^aeiouylsz])\\1$");
+ var re4_1b_2 = new RegExp("^" + C + v + "[^aeiouwxy]$");
+
+ var re_1c = /^(.+?[^aeiou])y$/;
+ var re_2 = /^(.+?)(ational|tional|enci|anci|izer|bli|alli|entli|eli|ousli|ization|ation|ator|alism|iveness|fulness|ousness|aliti|iviti|biliti|logi)$/;
+
+ var re_3 = /^(.+?)(icate|ative|alize|iciti|ical|ful|ness)$/;
+
+ var re_4 = /^(.+?)(al|ance|ence|er|ic|able|ible|ant|ement|ment|ent|ou|ism|ate|iti|ous|ive|ize)$/;
+ var re2_4 = /^(.+?)(s|t)(ion)$/;
+
+ var re_5 = /^(.+?)e$/;
+ var re_5_1 = /ll$/;
+ var re3_5 = new RegExp("^" + C + v + "[^aeiouwxy]$");
+
+ var porterStemmer = function porterStemmer(w) {
+ var stem,
+ suffix,
+ firstch,
+ re,
+ re2,
+ re3,
+ re4;
+
+ if (w.length < 3) { return w; }
+
+ firstch = w.substr(0,1);
+ if (firstch == "y") {
+ w = firstch.toUpperCase() + w.substr(1);
+ }
+
+ // Step 1a
+ re = re_1a
+ re2 = re2_1a;
+
+ if (re.test(w)) { w = w.replace(re,"$1$2"); }
+ else if (re2.test(w)) { w = w.replace(re2,"$1$2"); }
+
+ // Step 1b
+ re = re_1b;
+ re2 = re2_1b;
+ if (re.test(w)) {
+ var fp = re.exec(w);
+ re = re_mgr0;
+ if (re.test(fp[1])) {
+ re = re_1b_2;
+ w = w.replace(re,"");
+ }
+ } else if (re2.test(w)) {
+ var fp = re2.exec(w);
+ stem = fp[1];
+ re2 = re_s_v;
+ if (re2.test(stem)) {
+ w = stem;
+ re2 = re2_1b_2;
+ re3 = re3_1b_2;
+ re4 = re4_1b_2;
+ if (re2.test(w)) { w = w + "e"; }
+ else if (re3.test(w)) { re = re_1b_2; w = w.replace(re,""); }
+ else if (re4.test(w)) { w = w + "e"; }
+ }
+ }
+
+ // Step 1c - replace suffix y or Y by i if preceded by a non-vowel which is not the first letter of the word (so cry -> cri, by -> by, say -> say)
+ re = re_1c;
+ if (re.test(w)) {
+ var fp = re.exec(w);
+ stem = fp[1];
+ w = stem + "i";
+ }
+
+ // Step 2
+ re = re_2;
+ if (re.test(w)) {
+ var fp = re.exec(w);
+ stem = fp[1];
+ suffix = fp[2];
+ re = re_mgr0;
+ if (re.test(stem)) {
+ w = stem + step2list[suffix];
+ }
+ }
+
+ // Step 3
+ re = re_3;
+ if (re.test(w)) {
+ var fp = re.exec(w);
+ stem = fp[1];
+ suffix = fp[2];
+ re = re_mgr0;
+ if (re.test(stem)) {
+ w = stem + step3list[suffix];
+ }
+ }
+
+ // Step 4
+ re = re_4;
+ re2 = re2_4;
+ if (re.test(w)) {
+ var fp = re.exec(w);
+ stem = fp[1];
+ re = re_mgr1;
+ if (re.test(stem)) {
+ w = stem;
+ }
+ } else if (re2.test(w)) {
+ var fp = re2.exec(w);
+ stem = fp[1] + fp[2];
+ re2 = re_mgr1;
+ if (re2.test(stem)) {
+ w = stem;
+ }
+ }
+
+ // Step 5
+ re = re_5;
+ if (re.test(w)) {
+ var fp = re.exec(w);
+ stem = fp[1];
+ re = re_mgr1;
+ re2 = re_meq1;
+ re3 = re3_5;
+ if (re.test(stem) || (re2.test(stem) && !(re3.test(stem)))) {
+ w = stem;
+ }
+ }
+
+ re = re_5_1;
+ re2 = re_mgr1;
+ if (re.test(w) && re2.test(w)) {
+ re = re_1b_2;
+ w = w.replace(re,"");
+ }
+
+ // and turn initial Y back to y
+
+ if (firstch == "y") {
+ w = firstch.toLowerCase() + w.substr(1);
+ }
+
+ return w;
+ };
+
+ return function (token) {
+ return token.update(porterStemmer);
+ }
+})();
+
+lunr.Pipeline.registerFunction(lunr.stemmer, 'stemmer')
+/*!
+ * lunr.stopWordFilter
+ * Copyright (C) 2020 Oliver Nightingale
+ */
+
+/**
+ * lunr.generateStopWordFilter builds a stopWordFilter function from the provided
+ * list of stop words.
+ *
+ * The built in lunr.stopWordFilter is built using this generator and can be used
+ * to generate custom stopWordFilters for applications or non English languages.
+ *
+ * @function
+ * @param {Array} token The token to pass through the filter
+ * @returns {lunr.PipelineFunction}
+ * @see lunr.Pipeline
+ * @see lunr.stopWordFilter
+ */
+lunr.generateStopWordFilter = function (stopWords) {
+ var words = stopWords.reduce(function (memo, stopWord) {
+ memo[stopWord] = stopWord
+ return memo
+ }, {})
+
+ return function (token) {
+ if (token && words[token.toString()] !== token.toString()) return token
+ }
+}
+
+/**
+ * lunr.stopWordFilter is an English language stop word list filter, any words
+ * contained in the list will not be passed through the filter.
+ *
+ * This is intended to be used in the Pipeline. If the token does not pass the
+ * filter then undefined will be returned.
+ *
+ * @function
+ * @implements {lunr.PipelineFunction}
+ * @params {lunr.Token} token - A token to check for being a stop word.
+ * @returns {lunr.Token}
+ * @see {@link lunr.Pipeline}
+ */
+lunr.stopWordFilter = lunr.generateStopWordFilter([
+ 'a',
+ 'able',
+ 'about',
+ 'across',
+ 'after',
+ 'all',
+ 'almost',
+ 'also',
+ 'am',
+ 'among',
+ 'an',
+ 'and',
+ 'any',
+ 'are',
+ 'as',
+ 'at',
+ 'be',
+ 'because',
+ 'been',
+ 'but',
+ 'by',
+ 'can',
+ 'cannot',
+ 'could',
+ 'dear',
+ 'did',
+ 'do',
+ 'does',
+ 'either',
+ 'else',
+ 'ever',
+ 'every',
+ 'for',
+ 'from',
+ 'get',
+ 'got',
+ 'had',
+ 'has',
+ 'have',
+ 'he',
+ 'her',
+ 'hers',
+ 'him',
+ 'his',
+ 'how',
+ 'however',
+ 'i',
+ 'if',
+ 'in',
+ 'into',
+ 'is',
+ 'it',
+ 'its',
+ 'just',
+ 'least',
+ 'let',
+ 'like',
+ 'likely',
+ 'may',
+ 'me',
+ 'might',
+ 'most',
+ 'must',
+ 'my',
+ 'neither',
+ 'no',
+ 'nor',
+ 'not',
+ 'of',
+ 'off',
+ 'often',
+ 'on',
+ 'only',
+ 'or',
+ 'other',
+ 'our',
+ 'own',
+ 'rather',
+ 'said',
+ 'say',
+ 'says',
+ 'she',
+ 'should',
+ 'since',
+ 'so',
+ 'some',
+ 'than',
+ 'that',
+ 'the',
+ 'their',
+ 'them',
+ 'then',
+ 'there',
+ 'these',
+ 'they',
+ 'this',
+ 'tis',
+ 'to',
+ 'too',
+ 'twas',
+ 'us',
+ 'wants',
+ 'was',
+ 'we',
+ 'were',
+ 'what',
+ 'when',
+ 'where',
+ 'which',
+ 'while',
+ 'who',
+ 'whom',
+ 'why',
+ 'will',
+ 'with',
+ 'would',
+ 'yet',
+ 'you',
+ 'your'
+])
+
+lunr.Pipeline.registerFunction(lunr.stopWordFilter, 'stopWordFilter')
+/*!
+ * lunr.trimmer
+ * Copyright (C) 2020 Oliver Nightingale
+ */
+
+/**
+ * lunr.trimmer is a pipeline function for trimming non word
+ * characters from the beginning and end of tokens before they
+ * enter the index.
+ *
+ * This implementation may not work correctly for non latin
+ * characters and should either be removed or adapted for use
+ * with languages with non-latin characters.
+ *
+ * @static
+ * @implements {lunr.PipelineFunction}
+ * @param {lunr.Token} token The token to pass through the filter
+ * @returns {lunr.Token}
+ * @see lunr.Pipeline
+ */
+lunr.trimmer = function (token) {
+ return token.update(function (s) {
+ return s.replace(/^\W+/, '').replace(/\W+$/, '')
+ })
+}
+
+lunr.Pipeline.registerFunction(lunr.trimmer, 'trimmer')
+/*!
+ * lunr.TokenSet
+ * Copyright (C) 2020 Oliver Nightingale
+ */
+
+/**
+ * A token set is used to store the unique list of all tokens
+ * within an index. Token sets are also used to represent an
+ * incoming query to the index, this query token set and index
+ * token set are then intersected to find which tokens to look
+ * up in the inverted index.
+ *
+ * A token set can hold multiple tokens, as in the case of the
+ * index token set, or it can hold a single token as in the
+ * case of a simple query token set.
+ *
+ * Additionally token sets are used to perform wildcard matching.
+ * Leading, contained and trailing wildcards are supported, and
+ * from this edit distance matching can also be provided.
+ *
+ * Token sets are implemented as a minimal finite state automata,
+ * where both common prefixes and suffixes are shared between tokens.
+ * This helps to reduce the space used for storing the token set.
+ *
+ * @constructor
+ */
+lunr.TokenSet = function () {
+ this.final = false
+ this.edges = {}
+ this.id = lunr.TokenSet._nextId
+ lunr.TokenSet._nextId += 1
+}
+
+/**
+ * Keeps track of the next, auto increment, identifier to assign
+ * to a new tokenSet.
+ *
+ * TokenSets require a unique identifier to be correctly minimised.
+ *
+ * @private
+ */
+lunr.TokenSet._nextId = 1
+
+/**
+ * Creates a TokenSet instance from the given sorted array of words.
+ *
+ * @param {String[]} arr - A sorted array of strings to create the set from.
+ * @returns {lunr.TokenSet}
+ * @throws Will throw an error if the input array is not sorted.
+ */
+lunr.TokenSet.fromArray = function (arr) {
+ var builder = new lunr.TokenSet.Builder
+
+ for (var i = 0, len = arr.length; i < len; i++) {
+ builder.insert(arr[i])
+ }
+
+ builder.finish()
+ return builder.root
+}
+
+/**
+ * Creates a token set from a query clause.
+ *
+ * @private
+ * @param {Object} clause - A single clause from lunr.Query.
+ * @param {string} clause.term - The query clause term.
+ * @param {number} [clause.editDistance] - The optional edit distance for the term.
+ * @returns {lunr.TokenSet}
+ */
+lunr.TokenSet.fromClause = function (clause) {
+ if ('editDistance' in clause) {
+ return lunr.TokenSet.fromFuzzyString(clause.term, clause.editDistance)
+ } else {
+ return lunr.TokenSet.fromString(clause.term)
+ }
+}
+
+/**
+ * Creates a token set representing a single string with a specified
+ * edit distance.
+ *
+ * Insertions, deletions, substitutions and transpositions are each
+ * treated as an edit distance of 1.
+ *
+ * Increasing the allowed edit distance will have a dramatic impact
+ * on the performance of both creating and intersecting these TokenSets.
+ * It is advised to keep the edit distance less than 3.
+ *
+ * @param {string} str - The string to create the token set from.
+ * @param {number} editDistance - The allowed edit distance to match.
+ * @returns {lunr.Vector}
+ */
+lunr.TokenSet.fromFuzzyString = function (str, editDistance) {
+ var root = new lunr.TokenSet
+
+ var stack = [{
+ node: root,
+ editsRemaining: editDistance,
+ str: str
+ }]
+
+ while (stack.length) {
+ var frame = stack.pop()
+
+ // no edit
+ if (frame.str.length > 0) {
+ var char = frame.str.charAt(0),
+ noEditNode
+
+ if (char in frame.node.edges) {
+ noEditNode = frame.node.edges[char]
+ } else {
+ noEditNode = new lunr.TokenSet
+ frame.node.edges[char] = noEditNode
+ }
+
+ if (frame.str.length == 1) {
+ noEditNode.final = true
+ }
+
+ stack.push({
+ node: noEditNode,
+ editsRemaining: frame.editsRemaining,
+ str: frame.str.slice(1)
+ })
+ }
+
+ if (frame.editsRemaining == 0) {
+ continue
+ }
+
+ // insertion
+ if ("*" in frame.node.edges) {
+ var insertionNode = frame.node.edges["*"]
+ } else {
+ var insertionNode = new lunr.TokenSet
+ frame.node.edges["*"] = insertionNode
+ }
+
+ if (frame.str.length == 0) {
+ insertionNode.final = true
+ }
+
+ stack.push({
+ node: insertionNode,
+ editsRemaining: frame.editsRemaining - 1,
+ str: frame.str
+ })
+
+ // deletion
+ // can only do a deletion if we have enough edits remaining
+ // and if there are characters left to delete in the string
+ if (frame.str.length > 1) {
+ stack.push({
+ node: frame.node,
+ editsRemaining: frame.editsRemaining - 1,
+ str: frame.str.slice(1)
+ })
+ }
+
+ // deletion
+ // just removing the last character from the str
+ if (frame.str.length == 1) {
+ frame.node.final = true
+ }
+
+ // substitution
+ // can only do a substitution if we have enough edits remaining
+ // and if there are characters left to substitute
+ if (frame.str.length >= 1) {
+ if ("*" in frame.node.edges) {
+ var substitutionNode = frame.node.edges["*"]
+ } else {
+ var substitutionNode = new lunr.TokenSet
+ frame.node.edges["*"] = substitutionNode
+ }
+
+ if (frame.str.length == 1) {
+ substitutionNode.final = true
+ }
+
+ stack.push({
+ node: substitutionNode,
+ editsRemaining: frame.editsRemaining - 1,
+ str: frame.str.slice(1)
+ })
+ }
+
+ // transposition
+ // can only do a transposition if there are edits remaining
+ // and there are enough characters to transpose
+ if (frame.str.length > 1) {
+ var charA = frame.str.charAt(0),
+ charB = frame.str.charAt(1),
+ transposeNode
+
+ if (charB in frame.node.edges) {
+ transposeNode = frame.node.edges[charB]
+ } else {
+ transposeNode = new lunr.TokenSet
+ frame.node.edges[charB] = transposeNode
+ }
+
+ if (frame.str.length == 1) {
+ transposeNode.final = true
+ }
+
+ stack.push({
+ node: transposeNode,
+ editsRemaining: frame.editsRemaining - 1,
+ str: charA + frame.str.slice(2)
+ })
+ }
+ }
+
+ return root
+}
+
+/**
+ * Creates a TokenSet from a string.
+ *
+ * The string may contain one or more wildcard characters (*)
+ * that will allow wildcard matching when intersecting with
+ * another TokenSet.
+ *
+ * @param {string} str - The string to create a TokenSet from.
+ * @returns {lunr.TokenSet}
+ */
+lunr.TokenSet.fromString = function (str) {
+ var node = new lunr.TokenSet,
+ root = node
+
+ /*
+ * Iterates through all characters within the passed string
+ * appending a node for each character.
+ *
+ * When a wildcard character is found then a self
+ * referencing edge is introduced to continually match
+ * any number of any characters.
+ */
+ for (var i = 0, len = str.length; i < len; i++) {
+ var char = str[i],
+ final = (i == len - 1)
+
+ if (char == "*") {
+ node.edges[char] = node
+ node.final = final
+
+ } else {
+ var next = new lunr.TokenSet
+ next.final = final
+
+ node.edges[char] = next
+ node = next
+ }
+ }
+
+ return root
+}
+
+/**
+ * Converts this TokenSet into an array of strings
+ * contained within the TokenSet.
+ *
+ * This is not intended to be used on a TokenSet that
+ * contains wildcards, in these cases the results are
+ * undefined and are likely to cause an infinite loop.
+ *
+ * @returns {string[]}
+ */
+lunr.TokenSet.prototype.toArray = function () {
+ var words = []
+
+ var stack = [{
+ prefix: "",
+ node: this
+ }]
+
+ while (stack.length) {
+ var frame = stack.pop(),
+ edges = Object.keys(frame.node.edges),
+ len = edges.length
+
+ if (frame.node.final) {
+ /* In Safari, at this point the prefix is sometimes corrupted, see:
+ * https://github.com/olivernn/lunr.js/issues/279 Calling any
+ * String.prototype method forces Safari to "cast" this string to what
+ * it's supposed to be, fixing the bug. */
+ frame.prefix.charAt(0)
+ words.push(frame.prefix)
+ }
+
+ for (var i = 0; i < len; i++) {
+ var edge = edges[i]
+
+ stack.push({
+ prefix: frame.prefix.concat(edge),
+ node: frame.node.edges[edge]
+ })
+ }
+ }
+
+ return words
+}
+
+/**
+ * Generates a string representation of a TokenSet.
+ *
+ * This is intended to allow TokenSets to be used as keys
+ * in objects, largely to aid the construction and minimisation
+ * of a TokenSet. As such it is not designed to be a human
+ * friendly representation of the TokenSet.
+ *
+ * @returns {string}
+ */
+lunr.TokenSet.prototype.toString = function () {
+ // NOTE: Using Object.keys here as this.edges is very likely
+ // to enter 'hash-mode' with many keys being added
+ //
+ // avoiding a for-in loop here as it leads to the function
+ // being de-optimised (at least in V8). From some simple
+ // benchmarks the performance is comparable, but allowing
+ // V8 to optimize may mean easy performance wins in the future.
+
+ if (this._str) {
+ return this._str
+ }
+
+ var str = this.final ? '1' : '0',
+ labels = Object.keys(this.edges).sort(),
+ len = labels.length
+
+ for (var i = 0; i < len; i++) {
+ var label = labels[i],
+ node = this.edges[label]
+
+ str = str + label + node.id
+ }
+
+ return str
+}
+
+/**
+ * Returns a new TokenSet that is the intersection of
+ * this TokenSet and the passed TokenSet.
+ *
+ * This intersection will take into account any wildcards
+ * contained within the TokenSet.
+ *
+ * @param {lunr.TokenSet} b - An other TokenSet to intersect with.
+ * @returns {lunr.TokenSet}
+ */
+lunr.TokenSet.prototype.intersect = function (b) {
+ var output = new lunr.TokenSet,
+ frame = undefined
+
+ var stack = [{
+ qNode: b,
+ output: output,
+ node: this
+ }]
+
+ while (stack.length) {
+ frame = stack.pop()
+
+ // NOTE: As with the #toString method, we are using
+ // Object.keys and a for loop instead of a for-in loop
+ // as both of these objects enter 'hash' mode, causing
+ // the function to be de-optimised in V8
+ var qEdges = Object.keys(frame.qNode.edges),
+ qLen = qEdges.length,
+ nEdges = Object.keys(frame.node.edges),
+ nLen = nEdges.length
+
+ for (var q = 0; q < qLen; q++) {
+ var qEdge = qEdges[q]
+
+ for (var n = 0; n < nLen; n++) {
+ var nEdge = nEdges[n]
+
+ if (nEdge == qEdge || qEdge == '*') {
+ var node = frame.node.edges[nEdge],
+ qNode = frame.qNode.edges[qEdge],
+ final = node.final && qNode.final,
+ next = undefined
+
+ if (nEdge in frame.output.edges) {
+ // an edge already exists for this character
+ // no need to create a new node, just set the finality
+ // bit unless this node is already final
+ next = frame.output.edges[nEdge]
+ next.final = next.final || final
+
+ } else {
+ // no edge exists yet, must create one
+ // set the finality bit and insert it
+ // into the output
+ next = new lunr.TokenSet
+ next.final = final
+ frame.output.edges[nEdge] = next
+ }
+
+ stack.push({
+ qNode: qNode,
+ output: next,
+ node: node
+ })
+ }
+ }
+ }
+ }
+
+ return output
+}
+lunr.TokenSet.Builder = function () {
+ this.previousWord = ""
+ this.root = new lunr.TokenSet
+ this.uncheckedNodes = []
+ this.minimizedNodes = {}
+}
+
+lunr.TokenSet.Builder.prototype.insert = function (word) {
+ var node,
+ commonPrefix = 0
+
+ if (word < this.previousWord) {
+ throw new Error ("Out of order word insertion")
+ }
+
+ for (var i = 0; i < word.length && i < this.previousWord.length; i++) {
+ if (word[i] != this.previousWord[i]) break
+ commonPrefix++
+ }
+
+ this.minimize(commonPrefix)
+
+ if (this.uncheckedNodes.length == 0) {
+ node = this.root
+ } else {
+ node = this.uncheckedNodes[this.uncheckedNodes.length - 1].child
+ }
+
+ for (var i = commonPrefix; i < word.length; i++) {
+ var nextNode = new lunr.TokenSet,
+ char = word[i]
+
+ node.edges[char] = nextNode
+
+ this.uncheckedNodes.push({
+ parent: node,
+ char: char,
+ child: nextNode
+ })
+
+ node = nextNode
+ }
+
+ node.final = true
+ this.previousWord = word
+}
+
+lunr.TokenSet.Builder.prototype.finish = function () {
+ this.minimize(0)
+}
+
+lunr.TokenSet.Builder.prototype.minimize = function (downTo) {
+ for (var i = this.uncheckedNodes.length - 1; i >= downTo; i--) {
+ var node = this.uncheckedNodes[i],
+ childKey = node.child.toString()
+
+ if (childKey in this.minimizedNodes) {
+ node.parent.edges[node.char] = this.minimizedNodes[childKey]
+ } else {
+ // Cache the key for this node since
+ // we know it can't change anymore
+ node.child._str = childKey
+
+ this.minimizedNodes[childKey] = node.child
+ }
+
+ this.uncheckedNodes.pop()
+ }
+}
+/*!
+ * lunr.Index
+ * Copyright (C) 2020 Oliver Nightingale
+ */
+
+/**
+ * An index contains the built index of all documents and provides a query interface
+ * to the index.
+ *
+ * Usually instances of lunr.Index will not be created using this constructor, instead
+ * lunr.Builder should be used to construct new indexes, or lunr.Index.load should be
+ * used to load previously built and serialized indexes.
+ *
+ * @constructor
+ * @param {Object} attrs - The attributes of the built search index.
+ * @param {Object} attrs.invertedIndex - An index of term/field to document reference.
+ * @param {Object} attrs.fieldVectors - Field vectors
+ * @param {lunr.TokenSet} attrs.tokenSet - An set of all corpus tokens.
+ * @param {string[]} attrs.fields - The names of indexed document fields.
+ * @param {lunr.Pipeline} attrs.pipeline - The pipeline to use for search terms.
+ */
+lunr.Index = function (attrs) {
+ this.invertedIndex = attrs.invertedIndex
+ this.fieldVectors = attrs.fieldVectors
+ this.tokenSet = attrs.tokenSet
+ this.fields = attrs.fields
+ this.pipeline = attrs.pipeline
+}
+
+/**
+ * A result contains details of a document matching a search query.
+ * @typedef {Object} lunr.Index~Result
+ * @property {string} ref - The reference of the document this result represents.
+ * @property {number} score - A number between 0 and 1 representing how similar this document is to the query.
+ * @property {lunr.MatchData} matchData - Contains metadata about this match including which term(s) caused the match.
+ */
+
+/**
+ * Although lunr provides the ability to create queries using lunr.Query, it also provides a simple
+ * query language which itself is parsed into an instance of lunr.Query.
+ *
+ * For programmatically building queries it is advised to directly use lunr.Query, the query language
+ * is best used for human entered text rather than program generated text.
+ *
+ * At its simplest queries can just be a single term, e.g. `hello`, multiple terms are also supported
+ * and will be combined with OR, e.g `hello world` will match documents that contain either 'hello'
+ * or 'world', though those that contain both will rank higher in the results.
+ *
+ * Wildcards can be included in terms to match one or more unspecified characters, these wildcards can
+ * be inserted anywhere within the term, and more than one wildcard can exist in a single term. Adding
+ * wildcards will increase the number of documents that will be found but can also have a negative
+ * impact on query performance, especially with wildcards at the beginning of a term.
+ *
+ * Terms can be restricted to specific fields, e.g. `title:hello`, only documents with the term
+ * hello in the title field will match this query. Using a field not present in the index will lead
+ * to an error being thrown.
+ *
+ * Modifiers can also be added to terms, lunr supports edit distance and boost modifiers on terms. A term
+ * boost will make documents matching that term score higher, e.g. `foo^5`. Edit distance is also supported
+ * to provide fuzzy matching, e.g. 'hello~2' will match documents with hello with an edit distance of 2.
+ * Avoid large values for edit distance to improve query performance.
+ *
+ * Each term also supports a presence modifier. By default a term's presence in document is optional, however
+ * this can be changed to either required or prohibited. For a term's presence to be required in a document the
+ * term should be prefixed with a '+', e.g. `+foo bar` is a search for documents that must contain 'foo' and
+ * optionally contain 'bar'. Conversely a leading '-' sets the terms presence to prohibited, i.e. it must not
+ * appear in a document, e.g. `-foo bar` is a search for documents that do not contain 'foo' but may contain 'bar'.
+ *
+ * To escape special characters the backslash character '\' can be used, this allows searches to include
+ * characters that would normally be considered modifiers, e.g. `foo\~2` will search for a term "foo~2" instead
+ * of attempting to apply a boost of 2 to the search term "foo".
+ *
+ * @typedef {string} lunr.Index~QueryString
+ * @example Simple single term query
+ * hello
+ * @example Multiple term query
+ * hello world
+ * @example term scoped to a field
+ * title:hello
+ * @example term with a boost of 10
+ * hello^10
+ * @example term with an edit distance of 2
+ * hello~2
+ * @example terms with presence modifiers
+ * -foo +bar baz
+ */
+
+/**
+ * Performs a search against the index using lunr query syntax.
+ *
+ * Results will be returned sorted by their score, the most relevant results
+ * will be returned first. For details on how the score is calculated, please see
+ * the {@link https://lunrjs.com/guides/searching.html#scoring|guide}.
+ *
+ * For more programmatic querying use lunr.Index#query.
+ *
+ * @param {lunr.Index~QueryString} queryString - A string containing a lunr query.
+ * @throws {lunr.QueryParseError} If the passed query string cannot be parsed.
+ * @returns {lunr.Index~Result[]}
+ */
+lunr.Index.prototype.search = function (queryString) {
+ return this.query(function (query) {
+ var parser = new lunr.QueryParser(queryString, query)
+ parser.parse()
+ })
+}
+
+/**
+ * A query builder callback provides a query object to be used to express
+ * the query to perform on the index.
+ *
+ * @callback lunr.Index~queryBuilder
+ * @param {lunr.Query} query - The query object to build up.
+ * @this lunr.Query
+ */
+
+/**
+ * Performs a query against the index using the yielded lunr.Query object.
+ *
+ * If performing programmatic queries against the index, this method is preferred
+ * over lunr.Index#search so as to avoid the additional query parsing overhead.
+ *
+ * A query object is yielded to the supplied function which should be used to
+ * express the query to be run against the index.
+ *
+ * Note that although this function takes a callback parameter it is _not_ an
+ * asynchronous operation, the callback is just yielded a query object to be
+ * customized.
+ *
+ * @param {lunr.Index~queryBuilder} fn - A function that is used to build the query.
+ * @returns {lunr.Index~Result[]}
+ */
+lunr.Index.prototype.query = function (fn) {
+ // for each query clause
+ // * process terms
+ // * expand terms from token set
+ // * find matching documents and metadata
+ // * get document vectors
+ // * score documents
+
+ var query = new lunr.Query(this.fields),
+ matchingFields = Object.create(null),
+ queryVectors = Object.create(null),
+ termFieldCache = Object.create(null),
+ requiredMatches = Object.create(null),
+ prohibitedMatches = Object.create(null)
+
+ /*
+ * To support field level boosts a query vector is created per
+ * field. An empty vector is eagerly created to support negated
+ * queries.
+ */
+ for (var i = 0; i < this.fields.length; i++) {
+ queryVectors[this.fields[i]] = new lunr.Vector
+ }
+
+ fn.call(query, query)
+
+ for (var i = 0; i < query.clauses.length; i++) {
+ /*
+ * Unless the pipeline has been disabled for this term, which is
+ * the case for terms with wildcards, we need to pass the clause
+ * term through the search pipeline. A pipeline returns an array
+ * of processed terms. Pipeline functions may expand the passed
+ * term, which means we may end up performing multiple index lookups
+ * for a single query term.
+ */
+ var clause = query.clauses[i],
+ terms = null,
+ clauseMatches = lunr.Set.empty
+
+ if (clause.usePipeline) {
+ terms = this.pipeline.runString(clause.term, {
+ fields: clause.fields
+ })
+ } else {
+ terms = [clause.term]
+ }
+
+ for (var m = 0; m < terms.length; m++) {
+ var term = terms[m]
+
+ /*
+ * Each term returned from the pipeline needs to use the same query
+ * clause object, e.g. the same boost and or edit distance. The
+ * simplest way to do this is to re-use the clause object but mutate
+ * its term property.
+ */
+ clause.term = term
+
+ /*
+ * From the term in the clause we create a token set which will then
+ * be used to intersect the indexes token set to get a list of terms
+ * to lookup in the inverted index
+ */
+ var termTokenSet = lunr.TokenSet.fromClause(clause),
+ expandedTerms = this.tokenSet.intersect(termTokenSet).toArray()
+
+ /*
+ * If a term marked as required does not exist in the tokenSet it is
+ * impossible for the search to return any matches. We set all the field
+ * scoped required matches set to empty and stop examining any further
+ * clauses.
+ */
+ if (expandedTerms.length === 0 && clause.presence === lunr.Query.presence.REQUIRED) {
+ for (var k = 0; k < clause.fields.length; k++) {
+ var field = clause.fields[k]
+ requiredMatches[field] = lunr.Set.empty
+ }
+
+ break
+ }
+
+ for (var j = 0; j < expandedTerms.length; j++) {
+ /*
+ * For each term get the posting and termIndex, this is required for
+ * building the query vector.
+ */
+ var expandedTerm = expandedTerms[j],
+ posting = this.invertedIndex[expandedTerm],
+ termIndex = posting._index
+
+ for (var k = 0; k < clause.fields.length; k++) {
+ /*
+ * For each field that this query term is scoped by (by default
+ * all fields are in scope) we need to get all the document refs
+ * that have this term in that field.
+ *
+ * The posting is the entry in the invertedIndex for the matching
+ * term from above.
+ */
+ var field = clause.fields[k],
+ fieldPosting = posting[field],
+ matchingDocumentRefs = Object.keys(fieldPosting),
+ termField = expandedTerm + "/" + field,
+ matchingDocumentsSet = new lunr.Set(matchingDocumentRefs)
+
+ /*
+ * if the presence of this term is required ensure that the matching
+ * documents are added to the set of required matches for this clause.
+ *
+ */
+ if (clause.presence == lunr.Query.presence.REQUIRED) {
+ clauseMatches = clauseMatches.union(matchingDocumentsSet)
+
+ if (requiredMatches[field] === undefined) {
+ requiredMatches[field] = lunr.Set.complete
+ }
+ }
+
+ /*
+ * if the presence of this term is prohibited ensure that the matching
+ * documents are added to the set of prohibited matches for this field,
+ * creating that set if it does not yet exist.
+ */
+ if (clause.presence == lunr.Query.presence.PROHIBITED) {
+ if (prohibitedMatches[field] === undefined) {
+ prohibitedMatches[field] = lunr.Set.empty
+ }
+
+ prohibitedMatches[field] = prohibitedMatches[field].union(matchingDocumentsSet)
+
+ /*
+ * Prohibited matches should not be part of the query vector used for
+ * similarity scoring and no metadata should be extracted so we continue
+ * to the next field
+ */
+ continue
+ }
+
+ /*
+ * The query field vector is populated using the termIndex found for
+ * the term and a unit value with the appropriate boost applied.
+ * Using upsert because there could already be an entry in the vector
+ * for the term we are working with. In that case we just add the scores
+ * together.
+ */
+ queryVectors[field].upsert(termIndex, clause.boost, function (a, b) { return a + b })
+
+ /**
+ * If we've already seen this term, field combo then we've already collected
+ * the matching documents and metadata, no need to go through all that again
+ */
+ if (termFieldCache[termField]) {
+ continue
+ }
+
+ for (var l = 0; l < matchingDocumentRefs.length; l++) {
+ /*
+ * All metadata for this term/field/document triple
+ * are then extracted and collected into an instance
+ * of lunr.MatchData ready to be returned in the query
+ * results
+ */
+ var matchingDocumentRef = matchingDocumentRefs[l],
+ matchingFieldRef = new lunr.FieldRef (matchingDocumentRef, field),
+ metadata = fieldPosting[matchingDocumentRef],
+ fieldMatch
+
+ if ((fieldMatch = matchingFields[matchingFieldRef]) === undefined) {
+ matchingFields[matchingFieldRef] = new lunr.MatchData (expandedTerm, field, metadata)
+ } else {
+ fieldMatch.add(expandedTerm, field, metadata)
+ }
+
+ }
+
+ termFieldCache[termField] = true
+ }
+ }
+ }
+
+ /**
+ * If the presence was required we need to update the requiredMatches field sets.
+ * We do this after all fields for the term have collected their matches because
+ * the clause terms presence is required in _any_ of the fields not _all_ of the
+ * fields.
+ */
+ if (clause.presence === lunr.Query.presence.REQUIRED) {
+ for (var k = 0; k < clause.fields.length; k++) {
+ var field = clause.fields[k]
+ requiredMatches[field] = requiredMatches[field].intersect(clauseMatches)
+ }
+ }
+ }
+
+ /**
+ * Need to combine the field scoped required and prohibited
+ * matching documents into a global set of required and prohibited
+ * matches
+ */
+ var allRequiredMatches = lunr.Set.complete,
+ allProhibitedMatches = lunr.Set.empty
+
+ for (var i = 0; i < this.fields.length; i++) {
+ var field = this.fields[i]
+
+ if (requiredMatches[field]) {
+ allRequiredMatches = allRequiredMatches.intersect(requiredMatches[field])
+ }
+
+ if (prohibitedMatches[field]) {
+ allProhibitedMatches = allProhibitedMatches.union(prohibitedMatches[field])
+ }
+ }
+
+ var matchingFieldRefs = Object.keys(matchingFields),
+ results = [],
+ matches = Object.create(null)
+
+ /*
+ * If the query is negated (contains only prohibited terms)
+ * we need to get _all_ fieldRefs currently existing in the
+ * index. This is only done when we know that the query is
+ * entirely prohibited terms to avoid any cost of getting all
+ * fieldRefs unnecessarily.
+ *
+ * Additionally, blank MatchData must be created to correctly
+ * populate the results.
+ */
+ if (query.isNegated()) {
+ matchingFieldRefs = Object.keys(this.fieldVectors)
+
+ for (var i = 0; i < matchingFieldRefs.length; i++) {
+ var matchingFieldRef = matchingFieldRefs[i]
+ var fieldRef = lunr.FieldRef.fromString(matchingFieldRef)
+ matchingFields[matchingFieldRef] = new lunr.MatchData
+ }
+ }
+
+ for (var i = 0; i < matchingFieldRefs.length; i++) {
+ /*
+ * Currently we have document fields that match the query, but we
+ * need to return documents. The matchData and scores are combined
+ * from multiple fields belonging to the same document.
+ *
+ * Scores are calculated by field, using the query vectors created
+ * above, and combined into a final document score using addition.
+ */
+ var fieldRef = lunr.FieldRef.fromString(matchingFieldRefs[i]),
+ docRef = fieldRef.docRef
+
+ if (!allRequiredMatches.contains(docRef)) {
+ continue
+ }
+
+ if (allProhibitedMatches.contains(docRef)) {
+ continue
+ }
+
+ var fieldVector = this.fieldVectors[fieldRef],
+ score = queryVectors[fieldRef.fieldName].similarity(fieldVector),
+ docMatch
+
+ if ((docMatch = matches[docRef]) !== undefined) {
+ docMatch.score += score
+ docMatch.matchData.combine(matchingFields[fieldRef])
+ } else {
+ var match = {
+ ref: docRef,
+ score: score,
+ matchData: matchingFields[fieldRef]
+ }
+ matches[docRef] = match
+ results.push(match)
+ }
+ }
+
+ /*
+ * Sort the results objects by score, highest first.
+ */
+ return results.sort(function (a, b) {
+ return b.score - a.score
+ })
+}
+
+/**
+ * Prepares the index for JSON serialization.
+ *
+ * The schema for this JSON blob will be described in a
+ * separate JSON schema file.
+ *
+ * @returns {Object}
+ */
+lunr.Index.prototype.toJSON = function () {
+ var invertedIndex = Object.keys(this.invertedIndex)
+ .sort()
+ .map(function (term) {
+ return [term, this.invertedIndex[term]]
+ }, this)
+
+ var fieldVectors = Object.keys(this.fieldVectors)
+ .map(function (ref) {
+ return [ref, this.fieldVectors[ref].toJSON()]
+ }, this)
+
+ return {
+ version: lunr.version,
+ fields: this.fields,
+ fieldVectors: fieldVectors,
+ invertedIndex: invertedIndex,
+ pipeline: this.pipeline.toJSON()
+ }
+}
+
+/**
+ * Loads a previously serialized lunr.Index
+ *
+ * @param {Object} serializedIndex - A previously serialized lunr.Index
+ * @returns {lunr.Index}
+ */
+lunr.Index.load = function (serializedIndex) {
+ var attrs = {},
+ fieldVectors = {},
+ serializedVectors = serializedIndex.fieldVectors,
+ invertedIndex = Object.create(null),
+ serializedInvertedIndex = serializedIndex.invertedIndex,
+ tokenSetBuilder = new lunr.TokenSet.Builder,
+ pipeline = lunr.Pipeline.load(serializedIndex.pipeline)
+
+ if (serializedIndex.version != lunr.version) {
+ lunr.utils.warn("Version mismatch when loading serialised index. Current version of lunr '" + lunr.version + "' does not match serialized index '" + serializedIndex.version + "'")
+ }
+
+ for (var i = 0; i < serializedVectors.length; i++) {
+ var tuple = serializedVectors[i],
+ ref = tuple[0],
+ elements = tuple[1]
+
+ fieldVectors[ref] = new lunr.Vector(elements)
+ }
+
+ for (var i = 0; i < serializedInvertedIndex.length; i++) {
+ var tuple = serializedInvertedIndex[i],
+ term = tuple[0],
+ posting = tuple[1]
+
+ tokenSetBuilder.insert(term)
+ invertedIndex[term] = posting
+ }
+
+ tokenSetBuilder.finish()
+
+ attrs.fields = serializedIndex.fields
+
+ attrs.fieldVectors = fieldVectors
+ attrs.invertedIndex = invertedIndex
+ attrs.tokenSet = tokenSetBuilder.root
+ attrs.pipeline = pipeline
+
+ return new lunr.Index(attrs)
+}
+/*!
+ * lunr.Builder
+ * Copyright (C) 2020 Oliver Nightingale
+ */
+
+/**
+ * lunr.Builder performs indexing on a set of documents and
+ * returns instances of lunr.Index ready for querying.
+ *
+ * All configuration of the index is done via the builder, the
+ * fields to index, the document reference, the text processing
+ * pipeline and document scoring parameters are all set on the
+ * builder before indexing.
+ *
+ * @constructor
+ * @property {string} _ref - Internal reference to the document reference field.
+ * @property {string[]} _fields - Internal reference to the document fields to index.
+ * @property {object} invertedIndex - The inverted index maps terms to document fields.
+ * @property {object} documentTermFrequencies - Keeps track of document term frequencies.
+ * @property {object} documentLengths - Keeps track of the length of documents added to the index.
+ * @property {lunr.tokenizer} tokenizer - Function for splitting strings into tokens for indexing.
+ * @property {lunr.Pipeline} pipeline - The pipeline performs text processing on tokens before indexing.
+ * @property {lunr.Pipeline} searchPipeline - A pipeline for processing search terms before querying the index.
+ * @property {number} documentCount - Keeps track of the total number of documents indexed.
+ * @property {number} _b - A parameter to control field length normalization, setting this to 0 disabled normalization, 1 fully normalizes field lengths, the default value is 0.75.
+ * @property {number} _k1 - A parameter to control how quickly an increase in term frequency results in term frequency saturation, the default value is 1.2.
+ * @property {number} termIndex - A counter incremented for each unique term, used to identify a terms position in the vector space.
+ * @property {array} metadataWhitelist - A list of metadata keys that have been whitelisted for entry in the index.
+ */
+lunr.Builder = function () {
+ this._ref = "id"
+ this._fields = Object.create(null)
+ this._documents = Object.create(null)
+ this.invertedIndex = Object.create(null)
+ this.fieldTermFrequencies = {}
+ this.fieldLengths = {}
+ this.tokenizer = lunr.tokenizer
+ this.pipeline = new lunr.Pipeline
+ this.searchPipeline = new lunr.Pipeline
+ this.documentCount = 0
+ this._b = 0.75
+ this._k1 = 1.2
+ this.termIndex = 0
+ this.metadataWhitelist = []
+}
+
+/**
+ * Sets the document field used as the document reference. Every document must have this field.
+ * The type of this field in the document should be a string, if it is not a string it will be
+ * coerced into a string by calling toString.
+ *
+ * The default ref is 'id'.
+ *
+ * The ref should _not_ be changed during indexing, it should be set before any documents are
+ * added to the index. Changing it during indexing can lead to inconsistent results.
+ *
+ * @param {string} ref - The name of the reference field in the document.
+ */
+lunr.Builder.prototype.ref = function (ref) {
+ this._ref = ref
+}
+
+/**
+ * A function that is used to extract a field from a document.
+ *
+ * Lunr expects a field to be at the top level of a document, if however the field
+ * is deeply nested within a document an extractor function can be used to extract
+ * the right field for indexing.
+ *
+ * @callback fieldExtractor
+ * @param {object} doc - The document being added to the index.
+ * @returns {?(string|object|object[])} obj - The object that will be indexed for this field.
+ * @example Extracting a nested field
+ * function (doc) { return doc.nested.field }
+ */
+
+/**
+ * Adds a field to the list of document fields that will be indexed. Every document being
+ * indexed should have this field. Null values for this field in indexed documents will
+ * not cause errors but will limit the chance of that document being retrieved by searches.
+ *
+ * All fields should be added before adding documents to the index. Adding fields after
+ * a document has been indexed will have no effect on already indexed documents.
+ *
+ * Fields can be boosted at build time. This allows terms within that field to have more
+ * importance when ranking search results. Use a field boost to specify that matches within
+ * one field are more important than other fields.
+ *
+ * @param {string} fieldName - The name of a field to index in all documents.
+ * @param {object} attributes - Optional attributes associated with this field.
+ * @param {number} [attributes.boost=1] - Boost applied to all terms within this field.
+ * @param {fieldExtractor} [attributes.extractor] - Function to extract a field from a document.
+ * @throws {RangeError} fieldName cannot contain unsupported characters '/'
+ */
+lunr.Builder.prototype.field = function (fieldName, attributes) {
+ if (/\//.test(fieldName)) {
+ throw new RangeError ("Field '" + fieldName + "' contains illegal character '/'")
+ }
+
+ this._fields[fieldName] = attributes || {}
+}
+
+/**
+ * A parameter to tune the amount of field length normalisation that is applied when
+ * calculating relevance scores. A value of 0 will completely disable any normalisation
+ * and a value of 1 will fully normalise field lengths. The default is 0.75. Values of b
+ * will be clamped to the range 0 - 1.
+ *
+ * @param {number} number - The value to set for this tuning parameter.
+ */
+lunr.Builder.prototype.b = function (number) {
+ if (number < 0) {
+ this._b = 0
+ } else if (number > 1) {
+ this._b = 1
+ } else {
+ this._b = number
+ }
+}
+
+/**
+ * A parameter that controls the speed at which a rise in term frequency results in term
+ * frequency saturation. The default value is 1.2. Setting this to a higher value will give
+ * slower saturation levels, a lower value will result in quicker saturation.
+ *
+ * @param {number} number - The value to set for this tuning parameter.
+ */
+lunr.Builder.prototype.k1 = function (number) {
+ this._k1 = number
+}
+
+/**
+ * Adds a document to the index.
+ *
+ * Before adding fields to the index the index should have been fully setup, with the document
+ * ref and all fields to index already having been specified.
+ *
+ * The document must have a field name as specified by the ref (by default this is 'id') and
+ * it should have all fields defined for indexing, though null or undefined values will not
+ * cause errors.
+ *
+ * Entire documents can be boosted at build time. Applying a boost to a document indicates that
+ * this document should rank higher in search results than other documents.
+ *
+ * @param {object} doc - The document to add to the index.
+ * @param {object} attributes - Optional attributes associated with this document.
+ * @param {number} [attributes.boost=1] - Boost applied to all terms within this document.
+ */
+lunr.Builder.prototype.add = function (doc, attributes) {
+ var docRef = doc[this._ref],
+ fields = Object.keys(this._fields)
+
+ this._documents[docRef] = attributes || {}
+ this.documentCount += 1
+
+ for (var i = 0; i < fields.length; i++) {
+ var fieldName = fields[i],
+ extractor = this._fields[fieldName].extractor,
+ field = extractor ? extractor(doc) : doc[fieldName],
+ tokens = this.tokenizer(field, {
+ fields: [fieldName]
+ }),
+ terms = this.pipeline.run(tokens),
+ fieldRef = new lunr.FieldRef (docRef, fieldName),
+ fieldTerms = Object.create(null)
+
+ this.fieldTermFrequencies[fieldRef] = fieldTerms
+ this.fieldLengths[fieldRef] = 0
+
+ // store the length of this field for this document
+ this.fieldLengths[fieldRef] += terms.length
+
+ // calculate term frequencies for this field
+ for (var j = 0; j < terms.length; j++) {
+ var term = terms[j]
+
+ if (fieldTerms[term] == undefined) {
+ fieldTerms[term] = 0
+ }
+
+ fieldTerms[term] += 1
+
+ // add to inverted index
+ // create an initial posting if one doesn't exist
+ if (this.invertedIndex[term] == undefined) {
+ var posting = Object.create(null)
+ posting["_index"] = this.termIndex
+ this.termIndex += 1
+
+ for (var k = 0; k < fields.length; k++) {
+ posting[fields[k]] = Object.create(null)
+ }
+
+ this.invertedIndex[term] = posting
+ }
+
+ // add an entry for this term/fieldName/docRef to the invertedIndex
+ if (this.invertedIndex[term][fieldName][docRef] == undefined) {
+ this.invertedIndex[term][fieldName][docRef] = Object.create(null)
+ }
+
+ // store all whitelisted metadata about this token in the
+ // inverted index
+ for (var l = 0; l < this.metadataWhitelist.length; l++) {
+ var metadataKey = this.metadataWhitelist[l],
+ metadata = term.metadata[metadataKey]
+
+ if (this.invertedIndex[term][fieldName][docRef][metadataKey] == undefined) {
+ this.invertedIndex[term][fieldName][docRef][metadataKey] = []
+ }
+
+ this.invertedIndex[term][fieldName][docRef][metadataKey].push(metadata)
+ }
+ }
+
+ }
+}
+
+/**
+ * Calculates the average document length for this index
+ *
+ * @private
+ */
+lunr.Builder.prototype.calculateAverageFieldLengths = function () {
+
+ var fieldRefs = Object.keys(this.fieldLengths),
+ numberOfFields = fieldRefs.length,
+ accumulator = {},
+ documentsWithField = {}
+
+ for (var i = 0; i < numberOfFields; i++) {
+ var fieldRef = lunr.FieldRef.fromString(fieldRefs[i]),
+ field = fieldRef.fieldName
+
+ documentsWithField[field] || (documentsWithField[field] = 0)
+ documentsWithField[field] += 1
+
+ accumulator[field] || (accumulator[field] = 0)
+ accumulator[field] += this.fieldLengths[fieldRef]
+ }
+
+ var fields = Object.keys(this._fields)
+
+ for (var i = 0; i < fields.length; i++) {
+ var fieldName = fields[i]
+ accumulator[fieldName] = accumulator[fieldName] / documentsWithField[fieldName]
+ }
+
+ this.averageFieldLength = accumulator
+}
+
+/**
+ * Builds a vector space model of every document using lunr.Vector
+ *
+ * @private
+ */
+lunr.Builder.prototype.createFieldVectors = function () {
+ var fieldVectors = {},
+ fieldRefs = Object.keys(this.fieldTermFrequencies),
+ fieldRefsLength = fieldRefs.length,
+ termIdfCache = Object.create(null)
+
+ for (var i = 0; i < fieldRefsLength; i++) {
+ var fieldRef = lunr.FieldRef.fromString(fieldRefs[i]),
+ fieldName = fieldRef.fieldName,
+ fieldLength = this.fieldLengths[fieldRef],
+ fieldVector = new lunr.Vector,
+ termFrequencies = this.fieldTermFrequencies[fieldRef],
+ terms = Object.keys(termFrequencies),
+ termsLength = terms.length
+
+
+ var fieldBoost = this._fields[fieldName].boost || 1,
+ docBoost = this._documents[fieldRef.docRef].boost || 1
+
+ for (var j = 0; j < termsLength; j++) {
+ var term = terms[j],
+ tf = termFrequencies[term],
+ termIndex = this.invertedIndex[term]._index,
+ idf, score, scoreWithPrecision
+
+ if (termIdfCache[term] === undefined) {
+ idf = lunr.idf(this.invertedIndex[term], this.documentCount)
+ termIdfCache[term] = idf
+ } else {
+ idf = termIdfCache[term]
+ }
+
+ score = idf * ((this._k1 + 1) * tf) / (this._k1 * (1 - this._b + this._b * (fieldLength / this.averageFieldLength[fieldName])) + tf)
+ score *= fieldBoost
+ score *= docBoost
+ scoreWithPrecision = Math.round(score * 1000) / 1000
+ // Converts 1.23456789 to 1.234.
+ // Reducing the precision so that the vectors take up less
+ // space when serialised. Doing it now so that they behave
+ // the same before and after serialisation. Also, this is
+ // the fastest approach to reducing a number's precision in
+ // JavaScript.
+
+ fieldVector.insert(termIndex, scoreWithPrecision)
+ }
+
+ fieldVectors[fieldRef] = fieldVector
+ }
+
+ this.fieldVectors = fieldVectors
+}
+
+/**
+ * Creates a token set of all tokens in the index using lunr.TokenSet
+ *
+ * @private
+ */
+lunr.Builder.prototype.createTokenSet = function () {
+ this.tokenSet = lunr.TokenSet.fromArray(
+ Object.keys(this.invertedIndex).sort()
+ )
+}
+
+/**
+ * Builds the index, creating an instance of lunr.Index.
+ *
+ * This completes the indexing process and should only be called
+ * once all documents have been added to the index.
+ *
+ * @returns {lunr.Index}
+ */
+lunr.Builder.prototype.build = function () {
+ this.calculateAverageFieldLengths()
+ this.createFieldVectors()
+ this.createTokenSet()
+
+ return new lunr.Index({
+ invertedIndex: this.invertedIndex,
+ fieldVectors: this.fieldVectors,
+ tokenSet: this.tokenSet,
+ fields: Object.keys(this._fields),
+ pipeline: this.searchPipeline
+ })
+}
+
+/**
+ * Applies a plugin to the index builder.
+ *
+ * A plugin is a function that is called with the index builder as its context.
+ * Plugins can be used to customise or extend the behaviour of the index
+ * in some way. A plugin is just a function, that encapsulated the custom
+ * behaviour that should be applied when building the index.
+ *
+ * The plugin function will be called with the index builder as its argument, additional
+ * arguments can also be passed when calling use. The function will be called
+ * with the index builder as its context.
+ *
+ * @param {Function} plugin The plugin to apply.
+ */
+lunr.Builder.prototype.use = function (fn) {
+ var args = Array.prototype.slice.call(arguments, 1)
+ args.unshift(this)
+ fn.apply(this, args)
+}
+/**
+ * Contains and collects metadata about a matching document.
+ * A single instance of lunr.MatchData is returned as part of every
+ * lunr.Index~Result.
+ *
+ * @constructor
+ * @param {string} term - The term this match data is associated with
+ * @param {string} field - The field in which the term was found
+ * @param {object} metadata - The metadata recorded about this term in this field
+ * @property {object} metadata - A cloned collection of metadata associated with this document.
+ * @see {@link lunr.Index~Result}
+ */
+lunr.MatchData = function (term, field, metadata) {
+ var clonedMetadata = Object.create(null),
+ metadataKeys = Object.keys(metadata || {})
+
+ // Cloning the metadata to prevent the original
+ // being mutated during match data combination.
+ // Metadata is kept in an array within the inverted
+ // index so cloning the data can be done with
+ // Array#slice
+ for (var i = 0; i < metadataKeys.length; i++) {
+ var key = metadataKeys[i]
+ clonedMetadata[key] = metadata[key].slice()
+ }
+
+ this.metadata = Object.create(null)
+
+ if (term !== undefined) {
+ this.metadata[term] = Object.create(null)
+ this.metadata[term][field] = clonedMetadata
+ }
+}
+
+/**
+ * An instance of lunr.MatchData will be created for every term that matches a
+ * document. However only one instance is required in a lunr.Index~Result. This
+ * method combines metadata from another instance of lunr.MatchData with this
+ * objects metadata.
+ *
+ * @param {lunr.MatchData} otherMatchData - Another instance of match data to merge with this one.
+ * @see {@link lunr.Index~Result}
+ */
+lunr.MatchData.prototype.combine = function (otherMatchData) {
+ var terms = Object.keys(otherMatchData.metadata)
+
+ for (var i = 0; i < terms.length; i++) {
+ var term = terms[i],
+ fields = Object.keys(otherMatchData.metadata[term])
+
+ if (this.metadata[term] == undefined) {
+ this.metadata[term] = Object.create(null)
+ }
+
+ for (var j = 0; j < fields.length; j++) {
+ var field = fields[j],
+ keys = Object.keys(otherMatchData.metadata[term][field])
+
+ if (this.metadata[term][field] == undefined) {
+ this.metadata[term][field] = Object.create(null)
+ }
+
+ for (var k = 0; k < keys.length; k++) {
+ var key = keys[k]
+
+ if (this.metadata[term][field][key] == undefined) {
+ this.metadata[term][field][key] = otherMatchData.metadata[term][field][key]
+ } else {
+ this.metadata[term][field][key] = this.metadata[term][field][key].concat(otherMatchData.metadata[term][field][key])
+ }
+
+ }
+ }
+ }
+}
+
+/**
+ * Add metadata for a term/field pair to this instance of match data.
+ *
+ * @param {string} term - The term this match data is associated with
+ * @param {string} field - The field in which the term was found
+ * @param {object} metadata - The metadata recorded about this term in this field
+ */
+lunr.MatchData.prototype.add = function (term, field, metadata) {
+ if (!(term in this.metadata)) {
+ this.metadata[term] = Object.create(null)
+ this.metadata[term][field] = metadata
+ return
+ }
+
+ if (!(field in this.metadata[term])) {
+ this.metadata[term][field] = metadata
+ return
+ }
+
+ var metadataKeys = Object.keys(metadata)
+
+ for (var i = 0; i < metadataKeys.length; i++) {
+ var key = metadataKeys[i]
+
+ if (key in this.metadata[term][field]) {
+ this.metadata[term][field][key] = this.metadata[term][field][key].concat(metadata[key])
+ } else {
+ this.metadata[term][field][key] = metadata[key]
+ }
+ }
+}
+/**
+ * A lunr.Query provides a programmatic way of defining queries to be performed
+ * against a {@link lunr.Index}.
+ *
+ * Prefer constructing a lunr.Query using the {@link lunr.Index#query} method
+ * so the query object is pre-initialized with the right index fields.
+ *
+ * @constructor
+ * @property {lunr.Query~Clause[]} clauses - An array of query clauses.
+ * @property {string[]} allFields - An array of all available fields in a lunr.Index.
+ */
+lunr.Query = function (allFields) {
+ this.clauses = []
+ this.allFields = allFields
+}
+
+/**
+ * Constants for indicating what kind of automatic wildcard insertion will be used when constructing a query clause.
+ *
+ * This allows wildcards to be added to the beginning and end of a term without having to manually do any string
+ * concatenation.
+ *
+ * The wildcard constants can be bitwise combined to select both leading and trailing wildcards.
+ *
+ * @constant
+ * @default
+ * @property {number} wildcard.NONE - The term will have no wildcards inserted, this is the default behaviour
+ * @property {number} wildcard.LEADING - Prepend the term with a wildcard, unless a leading wildcard already exists
+ * @property {number} wildcard.TRAILING - Append a wildcard to the term, unless a trailing wildcard already exists
+ * @see lunr.Query~Clause
+ * @see lunr.Query#clause
+ * @see lunr.Query#term
+ * @example query term with trailing wildcard
+ * query.term('foo', { wildcard: lunr.Query.wildcard.TRAILING })
+ * @example query term with leading and trailing wildcard
+ * query.term('foo', {
+ * wildcard: lunr.Query.wildcard.LEADING | lunr.Query.wildcard.TRAILING
+ * })
+ */
+
+lunr.Query.wildcard = new String ("*")
+lunr.Query.wildcard.NONE = 0
+lunr.Query.wildcard.LEADING = 1
+lunr.Query.wildcard.TRAILING = 2
+
+/**
+ * Constants for indicating what kind of presence a term must have in matching documents.
+ *
+ * @constant
+ * @enum {number}
+ * @see lunr.Query~Clause
+ * @see lunr.Query#clause
+ * @see lunr.Query#term
+ * @example query term with required presence
+ * query.term('foo', { presence: lunr.Query.presence.REQUIRED })
+ */
+lunr.Query.presence = {
+ /**
+ * Term's presence in a document is optional, this is the default value.
+ */
+ OPTIONAL: 1,
+
+ /**
+ * Term's presence in a document is required, documents that do not contain
+ * this term will not be returned.
+ */
+ REQUIRED: 2,
+
+ /**
+ * Term's presence in a document is prohibited, documents that do contain
+ * this term will not be returned.
+ */
+ PROHIBITED: 3
+}
+
+/**
+ * A single clause in a {@link lunr.Query} contains a term and details on how to
+ * match that term against a {@link lunr.Index}.
+ *
+ * @typedef {Object} lunr.Query~Clause
+ * @property {string[]} fields - The fields in an index this clause should be matched against.
+ * @property {number} [boost=1] - Any boost that should be applied when matching this clause.
+ * @property {number} [editDistance] - Whether the term should have fuzzy matching applied, and how fuzzy the match should be.
+ * @property {boolean} [usePipeline] - Whether the term should be passed through the search pipeline.
+ * @property {number} [wildcard=lunr.Query.wildcard.NONE] - Whether the term should have wildcards appended or prepended.
+ * @property {number} [presence=lunr.Query.presence.OPTIONAL] - The terms presence in any matching documents.
+ */
+
+/**
+ * Adds a {@link lunr.Query~Clause} to this query.
+ *
+ * Unless the clause contains the fields to be matched all fields will be matched. In addition
+ * a default boost of 1 is applied to the clause.
+ *
+ * @param {lunr.Query~Clause} clause - The clause to add to this query.
+ * @see lunr.Query~Clause
+ * @returns {lunr.Query}
+ */
+lunr.Query.prototype.clause = function (clause) {
+ if (!('fields' in clause)) {
+ clause.fields = this.allFields
+ }
+
+ if (!('boost' in clause)) {
+ clause.boost = 1
+ }
+
+ if (!('usePipeline' in clause)) {
+ clause.usePipeline = true
+ }
+
+ if (!('wildcard' in clause)) {
+ clause.wildcard = lunr.Query.wildcard.NONE
+ }
+
+ if ((clause.wildcard & lunr.Query.wildcard.LEADING) && (clause.term.charAt(0) != lunr.Query.wildcard)) {
+ clause.term = "*" + clause.term
+ }
+
+ if ((clause.wildcard & lunr.Query.wildcard.TRAILING) && (clause.term.slice(-1) != lunr.Query.wildcard)) {
+ clause.term = "" + clause.term + "*"
+ }
+
+ if (!('presence' in clause)) {
+ clause.presence = lunr.Query.presence.OPTIONAL
+ }
+
+ this.clauses.push(clause)
+
+ return this
+}
+
+/**
+ * A negated query is one in which every clause has a presence of
+ * prohibited. These queries require some special processing to return
+ * the expected results.
+ *
+ * @returns boolean
+ */
+lunr.Query.prototype.isNegated = function () {
+ for (var i = 0; i < this.clauses.length; i++) {
+ if (this.clauses[i].presence != lunr.Query.presence.PROHIBITED) {
+ return false
+ }
+ }
+
+ return true
+}
+
+/**
+ * Adds a term to the current query, under the covers this will create a {@link lunr.Query~Clause}
+ * to the list of clauses that make up this query.
+ *
+ * The term is used as is, i.e. no tokenization will be performed by this method. Instead conversion
+ * to a token or token-like string should be done before calling this method.
+ *
+ * The term will be converted to a string by calling `toString`. Multiple terms can be passed as an
+ * array, each term in the array will share the same options.
+ *
+ * @param {object|object[]} term - The term(s) to add to the query.
+ * @param {object} [options] - Any additional properties to add to the query clause.
+ * @returns {lunr.Query}
+ * @see lunr.Query#clause
+ * @see lunr.Query~Clause
+ * @example adding a single term to a query
+ * query.term("foo")
+ * @example adding a single term to a query and specifying search fields, term boost and automatic trailing wildcard
+ * query.term("foo", {
+ * fields: ["title"],
+ * boost: 10,
+ * wildcard: lunr.Query.wildcard.TRAILING
+ * })
+ * @example using lunr.tokenizer to convert a string to tokens before using them as terms
+ * query.term(lunr.tokenizer("foo bar"))
+ */
+lunr.Query.prototype.term = function (term, options) {
+ if (Array.isArray(term)) {
+ term.forEach(function (t) { this.term(t, lunr.utils.clone(options)) }, this)
+ return this
+ }
+
+ var clause = options || {}
+ clause.term = term.toString()
+
+ this.clause(clause)
+
+ return this
+}
+lunr.QueryParseError = function (message, start, end) {
+ this.name = "QueryParseError"
+ this.message = message
+ this.start = start
+ this.end = end
+}
+
+lunr.QueryParseError.prototype = new Error
+lunr.QueryLexer = function (str) {
+ this.lexemes = []
+ this.str = str
+ this.length = str.length
+ this.pos = 0
+ this.start = 0
+ this.escapeCharPositions = []
+}
+
+lunr.QueryLexer.prototype.run = function () {
+ var state = lunr.QueryLexer.lexText
+
+ while (state) {
+ state = state(this)
+ }
+}
+
+lunr.QueryLexer.prototype.sliceString = function () {
+ var subSlices = [],
+ sliceStart = this.start,
+ sliceEnd = this.pos
+
+ for (var i = 0; i < this.escapeCharPositions.length; i++) {
+ sliceEnd = this.escapeCharPositions[i]
+ subSlices.push(this.str.slice(sliceStart, sliceEnd))
+ sliceStart = sliceEnd + 1
+ }
+
+ subSlices.push(this.str.slice(sliceStart, this.pos))
+ this.escapeCharPositions.length = 0
+
+ return subSlices.join('')
+}
+
+lunr.QueryLexer.prototype.emit = function (type) {
+ this.lexemes.push({
+ type: type,
+ str: this.sliceString(),
+ start: this.start,
+ end: this.pos
+ })
+
+ this.start = this.pos
+}
+
+lunr.QueryLexer.prototype.escapeCharacter = function () {
+ this.escapeCharPositions.push(this.pos - 1)
+ this.pos += 1
+}
+
+lunr.QueryLexer.prototype.next = function () {
+ if (this.pos >= this.length) {
+ return lunr.QueryLexer.EOS
+ }
+
+ var char = this.str.charAt(this.pos)
+ this.pos += 1
+ return char
+}
+
+lunr.QueryLexer.prototype.width = function () {
+ return this.pos - this.start
+}
+
+lunr.QueryLexer.prototype.ignore = function () {
+ if (this.start == this.pos) {
+ this.pos += 1
+ }
+
+ this.start = this.pos
+}
+
+lunr.QueryLexer.prototype.backup = function () {
+ this.pos -= 1
+}
+
+lunr.QueryLexer.prototype.acceptDigitRun = function () {
+ var char, charCode
+
+ do {
+ char = this.next()
+ charCode = char.charCodeAt(0)
+ } while (charCode > 47 && charCode < 58)
+
+ if (char != lunr.QueryLexer.EOS) {
+ this.backup()
+ }
+}
+
+lunr.QueryLexer.prototype.more = function () {
+ return this.pos < this.length
+}
+
+lunr.QueryLexer.EOS = 'EOS'
+lunr.QueryLexer.FIELD = 'FIELD'
+lunr.QueryLexer.TERM = 'TERM'
+lunr.QueryLexer.EDIT_DISTANCE = 'EDIT_DISTANCE'
+lunr.QueryLexer.BOOST = 'BOOST'
+lunr.QueryLexer.PRESENCE = 'PRESENCE'
+
+lunr.QueryLexer.lexField = function (lexer) {
+ lexer.backup()
+ lexer.emit(lunr.QueryLexer.FIELD)
+ lexer.ignore()
+ return lunr.QueryLexer.lexText
+}
+
+lunr.QueryLexer.lexTerm = function (lexer) {
+ if (lexer.width() > 1) {
+ lexer.backup()
+ lexer.emit(lunr.QueryLexer.TERM)
+ }
+
+ lexer.ignore()
+
+ if (lexer.more()) {
+ return lunr.QueryLexer.lexText
+ }
+}
+
+lunr.QueryLexer.lexEditDistance = function (lexer) {
+ lexer.ignore()
+ lexer.acceptDigitRun()
+ lexer.emit(lunr.QueryLexer.EDIT_DISTANCE)
+ return lunr.QueryLexer.lexText
+}
+
+lunr.QueryLexer.lexBoost = function (lexer) {
+ lexer.ignore()
+ lexer.acceptDigitRun()
+ lexer.emit(lunr.QueryLexer.BOOST)
+ return lunr.QueryLexer.lexText
+}
+
+lunr.QueryLexer.lexEOS = function (lexer) {
+ if (lexer.width() > 0) {
+ lexer.emit(lunr.QueryLexer.TERM)
+ }
+}
+
+// This matches the separator used when tokenising fields
+// within a document. These should match otherwise it is
+// not possible to search for some tokens within a document.
+//
+// It is possible for the user to change the separator on the
+// tokenizer so it _might_ clash with any other of the special
+// characters already used within the search string, e.g. :.
+//
+// This means that it is possible to change the separator in
+// such a way that makes some words unsearchable using a search
+// string.
+lunr.QueryLexer.termSeparator = lunr.tokenizer.separator
+
+lunr.QueryLexer.lexText = function (lexer) {
+ while (true) {
+ var char = lexer.next()
+
+ if (char == lunr.QueryLexer.EOS) {
+ return lunr.QueryLexer.lexEOS
+ }
+
+ // Escape character is '\'
+ if (char.charCodeAt(0) == 92) {
+ lexer.escapeCharacter()
+ continue
+ }
+
+ if (char == ":") {
+ return lunr.QueryLexer.lexField
+ }
+
+ if (char == "~") {
+ lexer.backup()
+ if (lexer.width() > 0) {
+ lexer.emit(lunr.QueryLexer.TERM)
+ }
+ return lunr.QueryLexer.lexEditDistance
+ }
+
+ if (char == "^") {
+ lexer.backup()
+ if (lexer.width() > 0) {
+ lexer.emit(lunr.QueryLexer.TERM)
+ }
+ return lunr.QueryLexer.lexBoost
+ }
+
+ // "+" indicates term presence is required
+ // checking for length to ensure that only
+ // leading "+" are considered
+ if (char == "+" && lexer.width() === 1) {
+ lexer.emit(lunr.QueryLexer.PRESENCE)
+ return lunr.QueryLexer.lexText
+ }
+
+ // "-" indicates term presence is prohibited
+ // checking for length to ensure that only
+ // leading "-" are considered
+ if (char == "-" && lexer.width() === 1) {
+ lexer.emit(lunr.QueryLexer.PRESENCE)
+ return lunr.QueryLexer.lexText
+ }
+
+ if (char.match(lunr.QueryLexer.termSeparator)) {
+ return lunr.QueryLexer.lexTerm
+ }
+ }
+}
+
+lunr.QueryParser = function (str, query) {
+ this.lexer = new lunr.QueryLexer (str)
+ this.query = query
+ this.currentClause = {}
+ this.lexemeIdx = 0
+}
+
+lunr.QueryParser.prototype.parse = function () {
+ this.lexer.run()
+ this.lexemes = this.lexer.lexemes
+
+ var state = lunr.QueryParser.parseClause
+
+ while (state) {
+ state = state(this)
+ }
+
+ return this.query
+}
+
+lunr.QueryParser.prototype.peekLexeme = function () {
+ return this.lexemes[this.lexemeIdx]
+}
+
+lunr.QueryParser.prototype.consumeLexeme = function () {
+ var lexeme = this.peekLexeme()
+ this.lexemeIdx += 1
+ return lexeme
+}
+
+lunr.QueryParser.prototype.nextClause = function () {
+ var completedClause = this.currentClause
+ this.query.clause(completedClause)
+ this.currentClause = {}
+}
+
+lunr.QueryParser.parseClause = function (parser) {
+ var lexeme = parser.peekLexeme()
+
+ if (lexeme == undefined) {
+ return
+ }
+
+ switch (lexeme.type) {
+ case lunr.QueryLexer.PRESENCE:
+ return lunr.QueryParser.parsePresence
+ case lunr.QueryLexer.FIELD:
+ return lunr.QueryParser.parseField
+ case lunr.QueryLexer.TERM:
+ return lunr.QueryParser.parseTerm
+ default:
+ var errorMessage = "expected either a field or a term, found " + lexeme.type
+
+ if (lexeme.str.length >= 1) {
+ errorMessage += " with value '" + lexeme.str + "'"
+ }
+
+ throw new lunr.QueryParseError (errorMessage, lexeme.start, lexeme.end)
+ }
+}
+
+lunr.QueryParser.parsePresence = function (parser) {
+ var lexeme = parser.consumeLexeme()
+
+ if (lexeme == undefined) {
+ return
+ }
+
+ switch (lexeme.str) {
+ case "-":
+ parser.currentClause.presence = lunr.Query.presence.PROHIBITED
+ break
+ case "+":
+ parser.currentClause.presence = lunr.Query.presence.REQUIRED
+ break
+ default:
+ var errorMessage = "unrecognised presence operator'" + lexeme.str + "'"
+ throw new lunr.QueryParseError (errorMessage, lexeme.start, lexeme.end)
+ }
+
+ var nextLexeme = parser.peekLexeme()
+
+ if (nextLexeme == undefined) {
+ var errorMessage = "expecting term or field, found nothing"
+ throw new lunr.QueryParseError (errorMessage, lexeme.start, lexeme.end)
+ }
+
+ switch (nextLexeme.type) {
+ case lunr.QueryLexer.FIELD:
+ return lunr.QueryParser.parseField
+ case lunr.QueryLexer.TERM:
+ return lunr.QueryParser.parseTerm
+ default:
+ var errorMessage = "expecting term or field, found '" + nextLexeme.type + "'"
+ throw new lunr.QueryParseError (errorMessage, nextLexeme.start, nextLexeme.end)
+ }
+}
+
+lunr.QueryParser.parseField = function (parser) {
+ var lexeme = parser.consumeLexeme()
+
+ if (lexeme == undefined) {
+ return
+ }
+
+ if (parser.query.allFields.indexOf(lexeme.str) == -1) {
+ var possibleFields = parser.query.allFields.map(function (f) { return "'" + f + "'" }).join(', '),
+ errorMessage = "unrecognised field '" + lexeme.str + "', possible fields: " + possibleFields
+
+ throw new lunr.QueryParseError (errorMessage, lexeme.start, lexeme.end)
+ }
+
+ parser.currentClause.fields = [lexeme.str]
+
+ var nextLexeme = parser.peekLexeme()
+
+ if (nextLexeme == undefined) {
+ var errorMessage = "expecting term, found nothing"
+ throw new lunr.QueryParseError (errorMessage, lexeme.start, lexeme.end)
+ }
+
+ switch (nextLexeme.type) {
+ case lunr.QueryLexer.TERM:
+ return lunr.QueryParser.parseTerm
+ default:
+ var errorMessage = "expecting term, found '" + nextLexeme.type + "'"
+ throw new lunr.QueryParseError (errorMessage, nextLexeme.start, nextLexeme.end)
+ }
+}
+
+lunr.QueryParser.parseTerm = function (parser) {
+ var lexeme = parser.consumeLexeme()
+
+ if (lexeme == undefined) {
+ return
+ }
+
+ parser.currentClause.term = lexeme.str.toLowerCase()
+
+ if (lexeme.str.indexOf("*") != -1) {
+ parser.currentClause.usePipeline = false
+ }
+
+ var nextLexeme = parser.peekLexeme()
+
+ if (nextLexeme == undefined) {
+ parser.nextClause()
+ return
+ }
+
+ switch (nextLexeme.type) {
+ case lunr.QueryLexer.TERM:
+ parser.nextClause()
+ return lunr.QueryParser.parseTerm
+ case lunr.QueryLexer.FIELD:
+ parser.nextClause()
+ return lunr.QueryParser.parseField
+ case lunr.QueryLexer.EDIT_DISTANCE:
+ return lunr.QueryParser.parseEditDistance
+ case lunr.QueryLexer.BOOST:
+ return lunr.QueryParser.parseBoost
+ case lunr.QueryLexer.PRESENCE:
+ parser.nextClause()
+ return lunr.QueryParser.parsePresence
+ default:
+ var errorMessage = "Unexpected lexeme type '" + nextLexeme.type + "'"
+ throw new lunr.QueryParseError (errorMessage, nextLexeme.start, nextLexeme.end)
+ }
+}
+
+lunr.QueryParser.parseEditDistance = function (parser) {
+ var lexeme = parser.consumeLexeme()
+
+ if (lexeme == undefined) {
+ return
+ }
+
+ var editDistance = parseInt(lexeme.str, 10)
+
+ if (isNaN(editDistance)) {
+ var errorMessage = "edit distance must be numeric"
+ throw new lunr.QueryParseError (errorMessage, lexeme.start, lexeme.end)
+ }
+
+ parser.currentClause.editDistance = editDistance
+
+ var nextLexeme = parser.peekLexeme()
+
+ if (nextLexeme == undefined) {
+ parser.nextClause()
+ return
+ }
+
+ switch (nextLexeme.type) {
+ case lunr.QueryLexer.TERM:
+ parser.nextClause()
+ return lunr.QueryParser.parseTerm
+ case lunr.QueryLexer.FIELD:
+ parser.nextClause()
+ return lunr.QueryParser.parseField
+ case lunr.QueryLexer.EDIT_DISTANCE:
+ return lunr.QueryParser.parseEditDistance
+ case lunr.QueryLexer.BOOST:
+ return lunr.QueryParser.parseBoost
+ case lunr.QueryLexer.PRESENCE:
+ parser.nextClause()
+ return lunr.QueryParser.parsePresence
+ default:
+ var errorMessage = "Unexpected lexeme type '" + nextLexeme.type + "'"
+ throw new lunr.QueryParseError (errorMessage, nextLexeme.start, nextLexeme.end)
+ }
+}
+
+lunr.QueryParser.parseBoost = function (parser) {
+ var lexeme = parser.consumeLexeme()
+
+ if (lexeme == undefined) {
+ return
+ }
+
+ var boost = parseInt(lexeme.str, 10)
+
+ if (isNaN(boost)) {
+ var errorMessage = "boost must be numeric"
+ throw new lunr.QueryParseError (errorMessage, lexeme.start, lexeme.end)
+ }
+
+ parser.currentClause.boost = boost
+
+ var nextLexeme = parser.peekLexeme()
+
+ if (nextLexeme == undefined) {
+ parser.nextClause()
+ return
+ }
+
+ switch (nextLexeme.type) {
+ case lunr.QueryLexer.TERM:
+ parser.nextClause()
+ return lunr.QueryParser.parseTerm
+ case lunr.QueryLexer.FIELD:
+ parser.nextClause()
+ return lunr.QueryParser.parseField
+ case lunr.QueryLexer.EDIT_DISTANCE:
+ return lunr.QueryParser.parseEditDistance
+ case lunr.QueryLexer.BOOST:
+ return lunr.QueryParser.parseBoost
+ case lunr.QueryLexer.PRESENCE:
+ parser.nextClause()
+ return lunr.QueryParser.parsePresence
+ default:
+ var errorMessage = "Unexpected lexeme type '" + nextLexeme.type + "'"
+ throw new lunr.QueryParseError (errorMessage, nextLexeme.start, nextLexeme.end)
+ }
+}
+
+ /**
+ * export the module via AMD, CommonJS or as a browser global
+ * Export code from https://github.com/umdjs/umd/blob/master/returnExports.js
+ */
+ ;(function (root, factory) {
+ if (typeof define === 'function' && define.amd) {
+ // AMD. Register as an anonymous module.
+ define(factory)
+ } else if (typeof exports === 'object') {
+ /**
+ * Node. Does not work with strict CommonJS, but
+ * only CommonJS-like environments that support module.exports,
+ * like Node.
+ */
+ module.exports = factory()
+ } else {
+ // Browser globals (root is window)
+ root.lunr = factory()
+ }
+ }(this, function () {
+ /**
+ * Just return a value to define the module export.
+ * This example returns an object, but the module
+ * can return a function as the exported value.
+ */
+ return lunr
+ }))
+})();
diff --git a/venv/lib/python3.11/site-packages/mkdocs/contrib/search/templates/search/main.js b/venv/lib/python3.11/site-packages/mkdocs/contrib/search/templates/search/main.js
new file mode 100644
index 0000000..a5e469d
--- /dev/null
+++ b/venv/lib/python3.11/site-packages/mkdocs/contrib/search/templates/search/main.js
@@ -0,0 +1,109 @@
+function getSearchTermFromLocation() {
+ var sPageURL = window.location.search.substring(1);
+ var sURLVariables = sPageURL.split('&');
+ for (var i = 0; i < sURLVariables.length; i++) {
+ var sParameterName = sURLVariables[i].split('=');
+ if (sParameterName[0] == 'q') {
+ return decodeURIComponent(sParameterName[1].replace(/\+/g, '%20'));
+ }
+ }
+}
+
+function joinUrl (base, path) {
+ if (path.substring(0, 1) === "/") {
+ // path starts with `/`. Thus it is absolute.
+ return path;
+ }
+ if (base.substring(base.length-1) === "/") {
+ // base ends with `/`
+ return base + path;
+ }
+ return base + "/" + path;
+}
+
+function escapeHtml (value) {
+ return value.replace(/&/g, '&')
+ .replace(/"/g, '"')
+ .replace(//g, '>');
+}
+
+function formatResult (location, title, summary) {
+ return '' + escapeHtml(summary) +'
';
+}
+
+function displayResults (results) {
+ var search_results = document.getElementById("mkdocs-search-results");
+ while (search_results.firstChild) {
+ search_results.removeChild(search_results.firstChild);
+ }
+ if (results.length > 0){
+ for (var i=0; i < results.length; i++){
+ var result = results[i];
+ var html = formatResult(result.location, result.title, result.summary);
+ search_results.insertAdjacentHTML('beforeend', html);
+ }
+ } else {
+ var noResultsText = search_results.getAttribute('data-no-results-text');
+ if (!noResultsText) {
+ noResultsText = "No results found";
+ }
+ search_results.insertAdjacentHTML('beforeend', '' + noResultsText + '
');
+ }
+}
+
+function doSearch () {
+ var query = document.getElementById('mkdocs-search-query').value;
+ if (query.length > min_search_length) {
+ if (!window.Worker) {
+ displayResults(search(query));
+ } else {
+ searchWorker.postMessage({query: query});
+ }
+ } else {
+ // Clear results for short queries
+ displayResults([]);
+ }
+}
+
+function initSearch () {
+ var search_input = document.getElementById('mkdocs-search-query');
+ if (search_input) {
+ search_input.addEventListener("keyup", doSearch);
+ }
+ var term = getSearchTermFromLocation();
+ if (term) {
+ search_input.value = term;
+ doSearch();
+ }
+}
+
+function onWorkerMessage (e) {
+ if (e.data.allowSearch) {
+ initSearch();
+ } else if (e.data.results) {
+ var results = e.data.results;
+ displayResults(results);
+ } else if (e.data.config) {
+ min_search_length = e.data.config.min_search_length-1;
+ }
+}
+
+if (!window.Worker) {
+ console.log('Web Worker API not supported');
+ // load index in main thread
+ $.getScript(joinUrl(base_url, "search/worker.js")).done(function () {
+ console.log('Loaded worker');
+ init();
+ window.postMessage = function (msg) {
+ onWorkerMessage({data: msg});
+ };
+ }).fail(function (jqxhr, settings, exception) {
+ console.error('Could not load worker.js');
+ });
+} else {
+ // Wrap search in a web worker
+ var searchWorker = new Worker(joinUrl(base_url, "search/worker.js"));
+ searchWorker.postMessage({init: true});
+ searchWorker.onmessage = onWorkerMessage;
+}
diff --git a/venv/lib/python3.11/site-packages/mkdocs/contrib/search/templates/search/worker.js b/venv/lib/python3.11/site-packages/mkdocs/contrib/search/templates/search/worker.js
new file mode 100644
index 0000000..8628dbc
--- /dev/null
+++ b/venv/lib/python3.11/site-packages/mkdocs/contrib/search/templates/search/worker.js
@@ -0,0 +1,133 @@
+var base_path = 'function' === typeof importScripts ? '.' : '/search/';
+var allowSearch = false;
+var index;
+var documents = {};
+var lang = ['en'];
+var data;
+
+function getScript(script, callback) {
+ console.log('Loading script: ' + script);
+ $.getScript(base_path + script).done(function () {
+ callback();
+ }).fail(function (jqxhr, settings, exception) {
+ console.log('Error: ' + exception);
+ });
+}
+
+function getScriptsInOrder(scripts, callback) {
+ if (scripts.length === 0) {
+ callback();
+ return;
+ }
+ getScript(scripts[0], function() {
+ getScriptsInOrder(scripts.slice(1), callback);
+ });
+}
+
+function loadScripts(urls, callback) {
+ if( 'function' === typeof importScripts ) {
+ importScripts.apply(null, urls);
+ callback();
+ } else {
+ getScriptsInOrder(urls, callback);
+ }
+}
+
+function onJSONLoaded () {
+ data = JSON.parse(this.responseText);
+ var scriptsToLoad = ['lunr.js'];
+ if (data.config && data.config.lang && data.config.lang.length) {
+ lang = data.config.lang;
+ }
+ if (lang.length > 1 || lang[0] !== "en") {
+ scriptsToLoad.push('lunr.stemmer.support.js');
+ if (lang.length > 1) {
+ scriptsToLoad.push('lunr.multi.js');
+ }
+ if (lang.includes("ja") || lang.includes("jp")) {
+ scriptsToLoad.push('tinyseg.js');
+ }
+ for (var i=0; i < lang.length; i++) {
+ if (lang[i] != 'en') {
+ scriptsToLoad.push(['lunr', lang[i], 'js'].join('.'));
+ }
+ }
+ }
+ loadScripts(scriptsToLoad, onScriptsLoaded);
+}
+
+function onScriptsLoaded () {
+ console.log('All search scripts loaded, building Lunr index...');
+ if (data.config && data.config.separator && data.config.separator.length) {
+ lunr.tokenizer.separator = new RegExp(data.config.separator);
+ }
+
+ if (data.index) {
+ index = lunr.Index.load(data.index);
+ data.docs.forEach(function (doc) {
+ documents[doc.location] = doc;
+ });
+ console.log('Lunr pre-built index loaded, search ready');
+ } else {
+ index = lunr(function () {
+ if (lang.length === 1 && lang[0] !== "en" && lunr[lang[0]]) {
+ this.use(lunr[lang[0]]);
+ } else if (lang.length > 1) {
+ this.use(lunr.multiLanguage.apply(null, lang)); // spread operator not supported in all browsers: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_operator#Browser_compatibility
+ }
+ this.field('title');
+ this.field('text');
+ this.ref('location');
+
+ for (var i=0; i < data.docs.length; i++) {
+ var doc = data.docs[i];
+ this.add(doc);
+ documents[doc.location] = doc;
+ }
+ });
+ console.log('Lunr index built, search ready');
+ }
+ allowSearch = true;
+ postMessage({config: data.config});
+ postMessage({allowSearch: allowSearch});
+}
+
+function init () {
+ var oReq = new XMLHttpRequest();
+ oReq.addEventListener("load", onJSONLoaded);
+ var index_path = base_path + '/search_index.json';
+ if( 'function' === typeof importScripts ){
+ index_path = 'search_index.json';
+ }
+ oReq.open("GET", index_path);
+ oReq.send();
+}
+
+function search (query) {
+ if (!allowSearch) {
+ console.error('Assets for search still loading');
+ return;
+ }
+
+ var resultDocuments = [];
+ var results = index.search(query);
+ for (var i=0; i < results.length; i++){
+ var result = results[i];
+ doc = documents[result.ref];
+ doc.summary = doc.text.substring(0, 200);
+ resultDocuments.push(doc);
+ }
+ return resultDocuments;
+}
+
+if( 'function' === typeof importScripts ) {
+ onmessage = function (e) {
+ if (e.data.init) {
+ init();
+ } else if (e.data.query) {
+ postMessage({ results: search(e.data.query) });
+ } else {
+ console.error("Worker - Unrecognized message: " + e);
+ }
+ };
+}
diff --git a/venv/lib/python3.11/site-packages/mkdocs/exceptions.py b/venv/lib/python3.11/site-packages/mkdocs/exceptions.py
new file mode 100644
index 0000000..e7307ad
--- /dev/null
+++ b/venv/lib/python3.11/site-packages/mkdocs/exceptions.py
@@ -0,0 +1,31 @@
+from __future__ import annotations
+
+from click import ClickException, echo
+
+
+class MkDocsException(ClickException):
+ """The base class which all MkDocs exceptions inherit from. This should
+ not be raised directly. One of the subclasses should be raised instead."""
+
+
+class Abort(MkDocsException):
+ """Abort the build"""
+
+ def show(self, *args, **kwargs) -> None:
+ echo(self.format_message())
+
+
+class ConfigurationError(MkDocsException):
+ """This error is raised by configuration validation when a validation error
+ is encountered. This error should be raised by any configuration options
+ defined in a plugin's [config_scheme][]."""
+
+
+class BuildError(MkDocsException):
+ """This error may be raised by MkDocs during the build process. Plugins should
+ not raise this error."""
+
+
+class PluginError(BuildError):
+ """A subclass of [`mkdocs.exceptions.BuildError`][] which can be raised by plugin
+ events."""
diff --git a/venv/lib/python3.11/site-packages/mkdocs/livereload/__init__.py b/venv/lib/python3.11/site-packages/mkdocs/livereload/__init__.py
new file mode 100644
index 0000000..e136ff0
--- /dev/null
+++ b/venv/lib/python3.11/site-packages/mkdocs/livereload/__init__.py
@@ -0,0 +1,345 @@
+from __future__ import annotations
+
+import functools
+import io
+import ipaddress
+import logging
+import mimetypes
+import os
+import os.path
+import pathlib
+import posixpath
+import re
+import socket
+import socketserver
+import string
+import threading
+import time
+import urllib.parse
+import warnings
+import wsgiref.simple_server
+import wsgiref.util
+from typing import Any, BinaryIO, Callable, Dict, Iterable, Optional, Tuple
+
+import watchdog.events
+import watchdog.observers.polling
+
+_SCRIPT_TEMPLATE_STR = """
+var livereload = function(epoch, requestId) {
+ var req = new XMLHttpRequest();
+ req.onloadend = function() {
+ if (parseFloat(this.responseText) > epoch) {
+ location.reload();
+ return;
+ }
+ var launchNext = livereload.bind(this, epoch, requestId);
+ if (this.status === 200) {
+ launchNext();
+ } else {
+ setTimeout(launchNext, 3000);
+ }
+ };
+ req.open("GET", "/livereload/" + epoch + "/" + requestId);
+ req.send();
+
+ console.log('Enabled live reload');
+}
+livereload(${epoch}, ${request_id});
+"""
+_SCRIPT_TEMPLATE = string.Template(_SCRIPT_TEMPLATE_STR)
+
+
+class _LoggerAdapter(logging.LoggerAdapter):
+ def process(self, msg: str, kwargs: dict) -> Tuple[str, dict]: # type: ignore[override]
+ return time.strftime("[%H:%M:%S] ") + msg, kwargs
+
+
+log = _LoggerAdapter(logging.getLogger(__name__), {})
+
+
+class LiveReloadServer(socketserver.ThreadingMixIn, wsgiref.simple_server.WSGIServer):
+ daemon_threads = True
+ poll_response_timeout = 60
+
+ def __init__(
+ self,
+ builder: Callable[[], None],
+ host: str,
+ port: int,
+ root: str,
+ mount_path: str = "/",
+ polling_interval: float = 0.5,
+ shutdown_delay: float = 0.25,
+ **kwargs,
+ ) -> None:
+ self.builder = builder
+ self.server_name = host
+ self.server_port = port
+ try:
+ if isinstance(ipaddress.ip_address(host), ipaddress.IPv6Address):
+ self.address_family = socket.AF_INET6
+ except Exception:
+ pass
+ self.root = os.path.abspath(root)
+ self.mount_path = ("/" + mount_path.lstrip("/")).rstrip("/") + "/"
+ self.url = f"http://{self.server_name}:{self.server_port}{self.mount_path}"
+ self.build_delay = 0.1
+ self.shutdown_delay = shutdown_delay
+ # To allow custom error pages.
+ self.error_handler: Callable[[int], Optional[bytes]] = lambda code: None
+
+ super().__init__((host, port), _Handler, **kwargs)
+ self.set_app(self.serve_request)
+
+ self._wanted_epoch = _timestamp() # The version of the site that started building.
+ self._visible_epoch = self._wanted_epoch # Latest fully built version of the site.
+ self._epoch_cond = threading.Condition() # Must be held when accessing _visible_epoch.
+
+ self._to_rebuild: Dict[
+ Callable[[], None], bool
+ ] = {} # Used as an ordered set of functions to call.
+ self._rebuild_cond = threading.Condition() # Must be held when accessing _to_rebuild.
+
+ self._shutdown = False
+ self.serve_thread = threading.Thread(target=lambda: self.serve_forever(shutdown_delay))
+ self.observer = watchdog.observers.polling.PollingObserver(timeout=polling_interval)
+
+ self._watched_paths: Dict[str, int] = {}
+ self._watch_refs: Dict[str, Any] = {}
+
+ def watch(
+ self, path: str, func: Optional[Callable[[], None]] = None, recursive: bool = True
+ ) -> None:
+ """Add the 'path' to watched paths, call the function and reload when any file changes under it."""
+ path = os.path.abspath(path)
+ if func is None or func is self.builder:
+ funct = self.builder
+ else:
+ funct = func
+ warnings.warn(
+ "Plugins should not pass the 'func' parameter of watch(). "
+ "The ability to execute custom callbacks will be removed soon.",
+ DeprecationWarning,
+ stacklevel=2,
+ )
+
+ if path in self._watched_paths:
+ self._watched_paths[path] += 1
+ return
+ self._watched_paths[path] = 1
+
+ def callback(event):
+ if event.is_directory:
+ return
+ log.debug(str(event))
+ with self._rebuild_cond:
+ self._to_rebuild[funct] = True
+ self._rebuild_cond.notify_all()
+
+ handler = watchdog.events.FileSystemEventHandler()
+ handler.on_any_event = callback
+ log.debug(f"Watching '{path}'")
+ self._watch_refs[path] = self.observer.schedule(handler, path, recursive=recursive)
+
+ def unwatch(self, path: str) -> None:
+ """Stop watching file changes for path. Raises if there was no corresponding `watch` call."""
+ path = os.path.abspath(path)
+
+ self._watched_paths[path] -= 1
+ if self._watched_paths[path] <= 0:
+ self._watched_paths.pop(path)
+ self.observer.unschedule(self._watch_refs.pop(path))
+
+ def serve(self):
+ self.observer.start()
+
+ paths_str = ", ".join(f"'{_try_relativize_path(path)}'" for path in self._watched_paths)
+ log.info(f"Watching paths for changes: {paths_str}")
+
+ log.info(f"Serving on {self.url}")
+ self.serve_thread.start()
+
+ self._build_loop()
+
+ def _build_loop(self):
+ while True:
+ with self._rebuild_cond:
+ while not self._rebuild_cond.wait_for(
+ lambda: self._to_rebuild or self._shutdown, timeout=self.shutdown_delay
+ ):
+ # We could have used just one wait instead of a loop + timeout, but we need
+ # occasional breaks, otherwise on Windows we can't receive KeyboardInterrupt.
+ pass
+ if self._shutdown:
+ break
+ log.info("Detected file changes")
+ while self._rebuild_cond.wait(timeout=self.build_delay):
+ log.debug("Waiting for file changes to stop happening")
+
+ self._wanted_epoch = _timestamp()
+ funcs = list(self._to_rebuild)
+ self._to_rebuild.clear()
+
+ for func in funcs:
+ func()
+
+ with self._epoch_cond:
+ log.info("Reloading browsers")
+ self._visible_epoch = self._wanted_epoch
+ self._epoch_cond.notify_all()
+
+ def shutdown(self, wait=False) -> None:
+ self.observer.stop()
+ with self._rebuild_cond:
+ self._shutdown = True
+ self._rebuild_cond.notify_all()
+
+ if self.serve_thread.is_alive():
+ super().shutdown()
+ if wait:
+ self.serve_thread.join()
+ self.observer.join()
+
+ def serve_request(self, environ, start_response) -> Iterable[bytes]:
+ try:
+ result = self._serve_request(environ, start_response)
+ except Exception:
+ code = 500
+ msg = "500 Internal Server Error"
+ log.exception(msg)
+ else:
+ if result is not None:
+ return result
+ code = 404
+ msg = "404 Not Found"
+
+ error_content = None
+ try:
+ error_content = self.error_handler(code)
+ except Exception:
+ log.exception("Failed to render an error message!")
+ if error_content is None:
+ error_content = msg.encode()
+
+ start_response(msg, [("Content-Type", "text/html")])
+ return [error_content]
+
+ def _serve_request(self, environ, start_response) -> Optional[Iterable[bytes]]:
+ # https://bugs.python.org/issue16679
+ # https://github.com/bottlepy/bottle/blob/f9b1849db4/bottle.py#L984
+ path = environ["PATH_INFO"].encode("latin-1").decode("utf-8", "ignore")
+
+ if path.startswith("/livereload/"):
+ m = re.fullmatch(r"/livereload/([0-9]+)/[0-9]+", path)
+ if m:
+ epoch = int(m[1])
+ start_response("200 OK", [("Content-Type", "text/plain")])
+
+ def condition():
+ return self._visible_epoch > epoch
+
+ with self._epoch_cond:
+ if not condition():
+ # Stall the browser, respond as soon as there's something new.
+ # If there's not, respond anyway after a minute.
+ self._log_poll_request(environ.get("HTTP_REFERER"), request_id=path)
+ self._epoch_cond.wait_for(condition, timeout=self.poll_response_timeout)
+ return [b"%d" % self._visible_epoch]
+
+ if (path + "/").startswith(self.mount_path):
+ rel_file_path = path[len(self.mount_path) :]
+
+ if path.endswith("/"):
+ rel_file_path += "index.html"
+ # Prevent directory traversal - normalize the path.
+ rel_file_path = posixpath.normpath("/" + rel_file_path).lstrip("/")
+ file_path = os.path.join(self.root, rel_file_path)
+ elif path == "/":
+ start_response("302 Found", [("Location", urllib.parse.quote(self.mount_path))])
+ return []
+ else:
+ return None # Not found
+
+ # Wait until the ongoing rebuild (if any) finishes, so we're not serving a half-built site.
+ with self._epoch_cond:
+ self._epoch_cond.wait_for(lambda: self._visible_epoch == self._wanted_epoch)
+ epoch = self._visible_epoch
+
+ try:
+ file: BinaryIO = open(file_path, "rb")
+ except OSError:
+ if not path.endswith("/") and os.path.isfile(os.path.join(file_path, "index.html")):
+ start_response("302 Found", [("Location", urllib.parse.quote(path) + "/")])
+ return []
+ return None # Not found
+
+ if self._watched_paths and file_path.endswith(".html"):
+ with file:
+ content = file.read()
+ content = self._inject_js_into_html(content, epoch)
+ file = io.BytesIO(content)
+ content_length = len(content)
+ else:
+ content_length = os.path.getsize(file_path)
+
+ content_type = self._guess_type(file_path)
+ start_response(
+ "200 OK", [("Content-Type", content_type), ("Content-Length", str(content_length))]
+ )
+ return wsgiref.util.FileWrapper(file)
+
+ def _inject_js_into_html(self, content, epoch):
+ try:
+ body_end = content.rindex(b"