test bkp
This commit is contained in:
1 parent
6ccab0347b
commit
954a2fd6d6
18684 files changed
+601012
-190
No files matched your search
@@ -0,0 +1,5 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
|
||||
# For acceptable version formats, see https://www.python.org/dev/peps/pep-0440/
|
||||
__version__ = '1.6.1'
|
||||
@@ -0,0 +1,370 @@
|
||||
#!/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():
|
||||
# When `python -W...` or `PYTHONWARNINGS` are used, `sys.warnoptions` is set.
|
||||
# In that case, we skip warnings configuration since
|
||||
# we don't want to overwrite the user configuration.
|
||||
if not sys.warnoptions:
|
||||
from mkdocs.commands import build
|
||||
|
||||
build.log.addFilter(utils.DuplicateFilter())
|
||||
|
||||
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=' ' * 11,
|
||||
subsequent_indent=' ' * 11,
|
||||
)
|
||||
|
||||
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[11:]
|
||||
return prefix + message
|
||||
|
||||
|
||||
class State:
|
||||
"""Maintain logging level."""
|
||||
|
||||
def __init__(self, log_name='mkdocs', level=logging.INFO):
|
||||
self.logger = logging.getLogger(log_name)
|
||||
self.logger.setLevel(level)
|
||||
self.logger.propagate = False
|
||||
|
||||
self.stream = logging.StreamHandler()
|
||||
self.stream.setFormatter(ColorFormatter())
|
||||
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. This can be a file name, or '-' to read from stdin."
|
||||
)
|
||||
dev_addr_help = "IP address and port to serve documentation locally (default: localhost:8000)"
|
||||
serve_open_help = "Open the website in a Web browser after the initial build finishes."
|
||||
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."
|
||||
serve_dirty_help = "Only re-build files that have changed."
|
||||
serve_clean_help = (
|
||||
"Build the site without any effects of `mkdocs serve` - pure `mkdocs build`, then serve."
|
||||
)
|
||||
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."
|
||||
projects_file_help = (
|
||||
"URL or local path of the registry file that declares all known MkDocs-related projects."
|
||||
)
|
||||
|
||||
|
||||
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.logger.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.logger.setLevel(logging.ERROR)
|
||||
|
||||
return click.option(
|
||||
'-q',
|
||||
'--quiet',
|
||||
is_flag=True,
|
||||
expose_value=False,
|
||||
help='Silence warnings',
|
||||
callback=callback,
|
||||
)(f)
|
||||
|
||||
|
||||
def color_option(f):
|
||||
def callback(ctx, param, value):
|
||||
state = ctx.ensure_object(State)
|
||||
if value is False or (
|
||||
value is None
|
||||
and (
|
||||
not sys.stdout.isatty()
|
||||
or os.environ.get('NO_COLOR')
|
||||
or os.environ.get('TERM') == 'dumb'
|
||||
)
|
||||
):
|
||||
state.stream.setFormatter(logging.Formatter('%(levelname)-8s- %(message)s'))
|
||||
|
||||
return click.option(
|
||||
'--color/--no-color',
|
||||
is_flag=True,
|
||||
default=None,
|
||||
expose_value=False,
|
||||
help="Force enable or disable color and wrapping for the output. Default is auto-detect.",
|
||||
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/--no-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=dict(help_option_names=['-h', '--help'], max_content_width=120))
|
||||
@click.version_option(
|
||||
__version__,
|
||||
'-V',
|
||||
'--version',
|
||||
message=f'%(prog)s, version %(version)s from { PKG_DIR } (Python { PYTHON_VERSION })',
|
||||
)
|
||||
@common_options
|
||||
@color_option
|
||||
def cli():
|
||||
"""MkDocs - Project documentation with Markdown."""
|
||||
|
||||
|
||||
@cli.command(name="serve")
|
||||
@click.option('-a', '--dev-addr', help=dev_addr_help, metavar='<IP:PORT>')
|
||||
@click.option('-o', '--open', 'open_in_browser', help=serve_open_help, is_flag=True)
|
||||
@click.option('--no-livereload', 'livereload', flag_value=False, help=no_reload_help)
|
||||
@click.option('--livereload', 'livereload', flag_value=True, default=True, hidden=True)
|
||||
@click.option('--dirtyreload', 'build_type', flag_value='dirty', hidden=True)
|
||||
@click.option('--dirty', 'build_type', flag_value='dirty', help=serve_dirty_help)
|
||||
@click.option('-c', '--clean', 'build_type', flag_value='clean', help=serve_clean_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(**kwargs):
|
||||
"""Run the builtin development server."""
|
||||
from mkdocs.commands import serve
|
||||
|
||||
_enable_warnings()
|
||||
serve.serve(**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.on_startup(command='build', dirty=not clean)
|
||||
try:
|
||||
build.build(cfg, dirty=not clean)
|
||||
finally:
|
||||
cfg.plugins.on_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.on_startup(command='gh-deploy', dirty=not clean)
|
||||
try:
|
||||
build.build(cfg, dirty=not clean)
|
||||
finally:
|
||||
cfg.plugins.on_shutdown()
|
||||
gh_deploy.gh_deploy(
|
||||
cfg,
|
||||
message=message,
|
||||
force=force,
|
||||
no_history=no_history,
|
||||
ignore_version=ignore_version,
|
||||
shell=shell,
|
||||
)
|
||||
|
||||
|
||||
@cli.command(name="get-deps")
|
||||
@verbose_option
|
||||
@click.option('-f', '--config-file', type=click.File('rb'), help=config_help)
|
||||
@click.option(
|
||||
'-p',
|
||||
'--projects-file',
|
||||
default=None,
|
||||
help=projects_file_help,
|
||||
show_default=True,
|
||||
)
|
||||
def get_deps_command(config_file, projects_file):
|
||||
"""Show required PyPI packages inferred from plugins in mkdocs.yml."""
|
||||
from mkdocs_get_deps import get_deps, get_projects_file
|
||||
|
||||
from mkdocs.config.base import _open_config_file
|
||||
|
||||
warning_counter = utils.CountHandler()
|
||||
warning_counter.setLevel(logging.WARNING)
|
||||
logging.getLogger('mkdocs').addHandler(warning_counter)
|
||||
|
||||
with get_projects_file(projects_file) as p:
|
||||
with _open_config_file(config_file) as f:
|
||||
deps = get_deps(config_file=f, projects_file=p)
|
||||
|
||||
for dep in deps:
|
||||
print(dep) # noqa: T201
|
||||
|
||||
if warning_counter.get_counts():
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
@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()
|
||||
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
Binary file not shown.
Whitespace-only changes.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
@@ -0,0 +1,369 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import gzip
|
||||
import logging
|
||||
import os
|
||||
import time
|
||||
from typing import TYPE_CHECKING, Sequence
|
||||
from urllib.parse import urljoin, urlsplit
|
||||
|
||||
import jinja2
|
||||
from jinja2.exceptions import TemplateNotFound
|
||||
|
||||
import mkdocs
|
||||
from mkdocs import utils
|
||||
from mkdocs.exceptions import Abort, BuildError
|
||||
from mkdocs.structure.files import File, Files, InclusionLevel, get_files, set_exclusions
|
||||
from mkdocs.structure.nav import Navigation, get_navigation
|
||||
from mkdocs.structure.pages import Page
|
||||
from mkdocs.utils import DuplicateFilter # noqa: F401 - legacy re-export
|
||||
from mkdocs.utils import templates
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from mkdocs.config.defaults import MkDocsConfig
|
||||
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def get_context(
|
||||
nav: Navigation,
|
||||
files: Sequence[File] | Files,
|
||||
config: MkDocsConfig,
|
||||
page: Page | None = None,
|
||||
base_url: str = '',
|
||||
) -> templates.TemplateContext:
|
||||
"""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.normalize_url(str(script), page, base_url) for script in config.extra_javascript
|
||||
]
|
||||
extra_css = [utils.normalize_url(path, page, base_url) for path in config.extra_css]
|
||||
|
||||
if isinstance(files, Files):
|
||||
files = files.documentation_pages()
|
||||
|
||||
return templates.TemplateContext(
|
||||
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.on_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.on_template_context(context, template_name=name, config=config)
|
||||
|
||||
output = template.render(context)
|
||||
|
||||
# Run `post_template` plugin events.
|
||||
output = config.plugins.on_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(
|
||||
pages=[f.page for f in files.documentation_pages() if f.page is not None]
|
||||
)
|
||||
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:
|
||||
template = jinja2.Template(file.content_string)
|
||||
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."""
|
||||
config._current_page = page
|
||||
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.on_pre_page(page, config=config, files=files)
|
||||
|
||||
page.read_source(config)
|
||||
assert page.markdown is not None
|
||||
|
||||
# Run `page_markdown` plugin events.
|
||||
page.markdown = config.plugins.on_page_markdown(
|
||||
page.markdown, page=page, config=config, files=files
|
||||
)
|
||||
|
||||
page.render(config, files)
|
||||
assert page.content is not None
|
||||
|
||||
# Run `page_content` plugin events.
|
||||
page.content = config.plugins.on_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
|
||||
finally:
|
||||
config._current_page = None
|
||||
|
||||
|
||||
def _build_page(
|
||||
page: Page,
|
||||
config: MkDocsConfig,
|
||||
doc_files: Sequence[File],
|
||||
nav: Navigation,
|
||||
env: jinja2.Environment,
|
||||
dirty: bool = False,
|
||||
excluded: bool = False,
|
||||
) -> None:
|
||||
"""Pass a Page to theme template and write output to site_dir."""
|
||||
config._current_page = page
|
||||
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.
|
||||
template = env.get_template(page.meta.get('template', 'main.html'))
|
||||
|
||||
# Run `page_context` plugin events.
|
||||
context = config.plugins.on_page_context(context, page=page, config=config, nav=nav)
|
||||
|
||||
if excluded:
|
||||
page.content = (
|
||||
'<div class="mkdocs-draft-marker" title="This page will not be included into the built site.">'
|
||||
'DRAFT'
|
||||
'</div>' + (page.content or '')
|
||||
)
|
||||
|
||||
# Render the template.
|
||||
output = template.render(context)
|
||||
|
||||
# Run `post_page` plugin events.
|
||||
output = config.plugins.on_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.")
|
||||
|
||||
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
|
||||
finally:
|
||||
# Deactivate page
|
||||
page.active = False
|
||||
config._current_page = None
|
||||
|
||||
|
||||
def build(config: MkDocsConfig, *, serve_url: str | None = None, 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)
|
||||
|
||||
inclusion = InclusionLevel.is_in_serve if serve_url else InclusionLevel.is_included
|
||||
|
||||
try:
|
||||
start = time.monotonic()
|
||||
|
||||
# Run `config` plugin events.
|
||||
config = config.plugins.on_config(config)
|
||||
|
||||
# Run `pre_build` plugin events.
|
||||
config.plugins.on_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 serve_url: # 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.on_files(files, config=config)
|
||||
# If plugins have added files but haven't set their inclusion level, calculate it again.
|
||||
set_exclusions(files, config)
|
||||
|
||||
nav = get_navigation(files, config)
|
||||
|
||||
# Run `nav` plugin events.
|
||||
nav = config.plugins.on_nav(nav, config=config, files=files)
|
||||
|
||||
log.debug("Reading markdown pages.")
|
||||
excluded = []
|
||||
for file in files.documentation_pages(inclusion=inclusion):
|
||||
log.debug(f"Reading: {file.src_uri}")
|
||||
if file.page is None and file.inclusion.is_not_in_nav():
|
||||
if serve_url and file.inclusion.is_excluded():
|
||||
excluded.append(urljoin(serve_url, file.url))
|
||||
Page(None, file, config)
|
||||
assert file.page is not None
|
||||
_populate_page(file.page, config, files, dirty)
|
||||
if excluded:
|
||||
log.info(
|
||||
"The following pages are being built only for the preview "
|
||||
"but will be excluded from `mkdocs build` per `draft_docs` config:\n - "
|
||||
+ "\n - ".join(excluded)
|
||||
)
|
||||
|
||||
# Run `env` plugin events.
|
||||
env = config.plugins.on_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, inclusion=inclusion)
|
||||
|
||||
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(inclusion=inclusion)
|
||||
for file in doc_files:
|
||||
assert file.page is not None
|
||||
_build_page(
|
||||
file.page, config, doc_files, nav, env, dirty, excluded=file.inclusion.is_excluded()
|
||||
)
|
||||
|
||||
log_level = config.validation.links.anchors
|
||||
for file in doc_files:
|
||||
assert file.page is not None
|
||||
file.page.validate_anchor_links(files=files, log_level=log_level)
|
||||
|
||||
# Run `post_build` plugin events.
|
||||
config.plugins.on_post_build(config=config)
|
||||
|
||||
if counts := warning_counter.get_counts():
|
||||
msg = ', '.join(f'{v} {k.lower()}s' for k, v in counts)
|
||||
raise Abort(f'Aborted with {msg} in strict mode!')
|
||||
|
||||
log.info(f'Documentation built in {time.monotonic() - start:.2f} seconds')
|
||||
|
||||
except Exception as e:
|
||||
# Run `build_error` plugin events.
|
||||
config.plugins.on_build_error(error=e)
|
||||
if isinstance(e, BuildError):
|
||||
log.error(str(e))
|
||||
raise Abort('Aborted 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 bool(os.path.exists(site_directory) and os.listdir(site_directory))
|
||||
@@ -0,0 +1,169 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import logging
|
||||
import os
|
||||
import re
|
||||
import subprocess
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
import ghp_import # type: ignore
|
||||
from packaging import version
|
||||
|
||||
import mkdocs
|
||||
from mkdocs.exceptions import Abort
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from mkdocs.config.defaults import MkDocsConfig
|
||||
|
||||
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) -> 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: str | None = 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}")
|
||||
@@ -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)
|
||||
@@ -0,0 +1,112 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import logging
|
||||
import shutil
|
||||
import tempfile
|
||||
from os.path import isdir, isfile, join
|
||||
from typing import TYPE_CHECKING
|
||||
from urllib.parse import urlsplit
|
||||
|
||||
from mkdocs.commands.build import build
|
||||
from mkdocs.config import load_config
|
||||
from mkdocs.livereload import LiveReloadServer, _serve_url
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from mkdocs.config.defaults import MkDocsConfig
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def serve(
|
||||
config_file: str | None = None,
|
||||
livereload: bool = True,
|
||||
build_type: str | None = None,
|
||||
watch_theme: bool = False,
|
||||
watch: list[str] = [],
|
||||
*,
|
||||
open_in_browser: bool = False,
|
||||
**kwargs,
|
||||
) -> None:
|
||||
"""
|
||||
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 get_config():
|
||||
config = load_config(
|
||||
config_file=config_file,
|
||||
site_dir=site_dir,
|
||||
**kwargs,
|
||||
)
|
||||
config.watch.extend(watch)
|
||||
return config
|
||||
|
||||
is_clean = build_type == 'clean'
|
||||
is_dirty = build_type == 'dirty'
|
||||
|
||||
config = get_config()
|
||||
config.plugins.on_startup(command=('build' if is_clean else 'serve'), dirty=is_dirty)
|
||||
|
||||
host, port = config.dev_addr
|
||||
mount_path = urlsplit(config.site_url or '/').path
|
||||
config.site_url = serve_url = _serve_url(host, port, mount_path)
|
||||
|
||||
def builder(config: MkDocsConfig | None = None):
|
||||
log.info("Building documentation...")
|
||||
if config is None:
|
||||
config = get_config()
|
||||
config.site_url = serve_url
|
||||
|
||||
build(config, serve_url=None if is_clean else serve_url, dirty=is_dirty)
|
||||
|
||||
server = LiveReloadServer(
|
||||
builder=builder, host=host, port=port, root=site_dir, mount_path=mount_path
|
||||
)
|
||||
|
||||
def error_handler(code) -> bytes | None:
|
||||
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
|
||||
|
||||
try:
|
||||
# Perform the initial build
|
||||
builder(config)
|
||||
|
||||
if livereload:
|
||||
# Watch the documentation files, the config file and the theme files.
|
||||
server.watch(config.docs_dir)
|
||||
if config.config_file_path:
|
||||
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.on_serve(server, config=config, builder=builder)
|
||||
|
||||
for item in config.watch:
|
||||
server.watch(item)
|
||||
|
||||
try:
|
||||
server.serve(open_in_browser=open_in_browser)
|
||||
except KeyboardInterrupt:
|
||||
log.info("Shutting down...")
|
||||
finally:
|
||||
server.shutdown()
|
||||
finally:
|
||||
config.plugins.on_shutdown()
|
||||
if isdir(site_dir):
|
||||
shutil.rmtree(site_dir)
|
||||
@@ -0,0 +1,3 @@
|
||||
from mkdocs.config.base import Config, load_config
|
||||
|
||||
__all__ = ['load_config', 'Config']
|
||||
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
@@ -0,0 +1,392 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import functools
|
||||
import logging
|
||||
import os
|
||||
import sys
|
||||
import warnings
|
||||
from collections import UserDict
|
||||
from contextlib import contextmanager
|
||||
from typing import (
|
||||
IO,
|
||||
TYPE_CHECKING,
|
||||
Any,
|
||||
Generic,
|
||||
Iterator,
|
||||
List,
|
||||
Mapping,
|
||||
Sequence,
|
||||
Tuple,
|
||||
TypeVar,
|
||||
overload,
|
||||
)
|
||||
|
||||
from mkdocs import exceptions, utils
|
||||
from mkdocs.utils import weak_property
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from mkdocs.config.defaults import MkDocsConfig
|
||||
|
||||
|
||||
log = logging.getLogger('mkdocs.config')
|
||||
|
||||
|
||||
T = TypeVar('T')
|
||||
|
||||
|
||||
class BaseConfigOption(Generic[T]):
|
||||
def __init__(self) -> None:
|
||||
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):
|
||||
if name.endswith('_') and not name.startswith('_'):
|
||||
name = name[:-1]
|
||||
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: str
|
||||
|
||||
def __init_subclass__(cls):
|
||||
schema = dict(getattr(cls, '_schema', ()))
|
||||
for attr_name, attr in cls.__dict__.items():
|
||||
if isinstance(attr, BaseConfigOption):
|
||||
schema[getattr(attr, '_name', 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: str | bytes | None = 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 or ''
|
||||
|
||||
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))
|
||||
break
|
||||
|
||||
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: dict) -> None:
|
||||
"""Load config options from a dictionary."""
|
||||
if not isinstance(patch, dict):
|
||||
raise exceptions.ConfigurationError(
|
||||
"The configuration is invalid. Expected a key-"
|
||||
f"value mapping (dict) but received: {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."""
|
||||
warnings.warn(
|
||||
"Config.load_file is not used since MkDocs 1.5 and will be removed soon. "
|
||||
"Use MkDocsConfig.load_file instead",
|
||||
DeprecationWarning,
|
||||
)
|
||||
return self.load_dict(utils.yaml_load(config_file))
|
||||
|
||||
@weak_property
|
||||
def user_configs(self) -> Sequence[Mapping[str, Any]]:
|
||||
warnings.warn(
|
||||
"user_configs is never used in MkDocs and will be removed soon.", DeprecationWarning
|
||||
)
|
||||
return self.__user_configs
|
||||
|
||||
|
||||
@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: str | None = 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: str | IO | None) -> 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
|
||||
try:
|
||||
result_config_file.seek(0)
|
||||
except OSError:
|
||||
pass
|
||||
|
||||
try:
|
||||
yield result_config_file
|
||||
finally:
|
||||
if hasattr(result_config_file, 'close'):
|
||||
result_config_file.close()
|
||||
|
||||
|
||||
def load_config(
|
||||
config_file: str | IO | None = None, *, config_file_path: str | None = 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
|
||||
|
||||
if config_file_path is None:
|
||||
if sys.stdin and fd is not sys.stdin.buffer:
|
||||
config_file_path = getattr(fd, 'name', None)
|
||||
cfg = MkDocsConfig(config_file_path=config_file_path)
|
||||
# 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("Aborted with a configuration error!")
|
||||
elif cfg.strict and len(warnings) > 0:
|
||||
raise exceptions.Abort(
|
||||
f"Aborted with {len(warnings)} configuration warnings in 'strict' mode!"
|
||||
)
|
||||
|
||||
return cfg
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,218 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import logging
|
||||
from typing import IO, Dict, Mapping
|
||||
|
||||
from mkdocs.config import base
|
||||
from mkdocs.config import config_options as c
|
||||
from mkdocs.structure.pages import Page, _AbsoluteLinksValidationValue
|
||||
from mkdocs.utils.yaml import get_yaml_loader, yaml_load
|
||||
|
||||
|
||||
class _LogLevel(c.OptionallyRequired[int]):
|
||||
levels: Mapping[str, int] = {
|
||||
"warn": logging.WARNING,
|
||||
"info": logging.INFO,
|
||||
"ignore": logging.DEBUG,
|
||||
}
|
||||
|
||||
def run_validation(self, value: object) -> int:
|
||||
if not isinstance(value, str):
|
||||
raise base.ValidationError(f"Expected a string, but a {type(value)} was given.")
|
||||
try:
|
||||
return self.levels[value]
|
||||
except KeyError:
|
||||
raise base.ValidationError(f"Expected one of {list(self.levels)}, got {value!r}")
|
||||
|
||||
|
||||
class _AbsoluteLinksValidation(_LogLevel):
|
||||
levels: Mapping[str, int] = {
|
||||
**_LogLevel.levels,
|
||||
"relative_to_docs": _AbsoluteLinksValidationValue.RELATIVE_TO_DOCS,
|
||||
}
|
||||
|
||||
|
||||
# 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.Type(str) # type: ignore[assignment]
|
||||
"""The path to the mkdocs.yml config file. Can't be populated from the config."""
|
||||
|
||||
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')
|
||||
|
||||
exclude_docs = c.Optional(c.PathSpec())
|
||||
"""Gitignore-like patterns of files (relative to docs dir) to exclude from the site."""
|
||||
|
||||
draft_docs = c.Optional(c.PathSpec())
|
||||
"""Gitignore-like patterns of files (relative to docs dir) to mark as draft."""
|
||||
|
||||
not_in_nav = c.Optional(c.PathSpec())
|
||||
"""Gitignore-like patterns of files (relative to docs dir) that are not intended to be in the nav.
|
||||
|
||||
This marks doc files that are expected not to be in the nav, otherwise they will cause a log message
|
||||
(see also `validation.nav.omitted_files`).
|
||||
"""
|
||||
|
||||
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 `<page_name>/index.html` style files with hyperlinks to
|
||||
the directory. If `False`, use `<page_name>.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.ListOfItems(c.ExtraScript(), 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[Dict[str, dict]]()
|
||||
"""PyMarkdown extension configs. Populated from `markdown_extensions`."""
|
||||
|
||||
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`."""
|
||||
|
||||
class Validation(base.Config):
|
||||
class NavValidation(base.Config):
|
||||
omitted_files = _LogLevel(default='info')
|
||||
"""Warning level for when a doc file is never mentioned in the navigation.
|
||||
For granular configuration, see `not_in_nav`."""
|
||||
|
||||
not_found = _LogLevel(default='warn')
|
||||
"""Warning level for when the navigation links to a relative path that isn't an existing page on the site."""
|
||||
|
||||
absolute_links = _AbsoluteLinksValidation(default='info')
|
||||
"""Warning level for when the navigation links to an absolute path (starting with `/`)."""
|
||||
|
||||
nav = c.SubConfig(NavValidation)
|
||||
|
||||
class LinksValidation(base.Config):
|
||||
not_found = _LogLevel(default='warn')
|
||||
"""Warning level for when a Markdown doc links to a relative path that isn't an existing document on the site."""
|
||||
|
||||
absolute_links = _AbsoluteLinksValidation(default='info')
|
||||
"""Warning level for when a Markdown doc links to an absolute path (starting with `/`)."""
|
||||
|
||||
unrecognized_links = _LogLevel(default='info')
|
||||
"""Warning level for when a Markdown doc links to a relative path that doesn't look like
|
||||
it could be a valid internal link. For example, if the link ends with `/`."""
|
||||
|
||||
anchors = _LogLevel(default='info')
|
||||
"""Warning level for when a Markdown doc links to an anchor that's not present on the target page."""
|
||||
|
||||
links = c.SubConfig(LinksValidation)
|
||||
|
||||
validation = c.PropagatingSubConfig[Validation]()
|
||||
|
||||
_current_page: Page | None = None
|
||||
"""The currently rendered page. Please do not access this and instead
|
||||
rely on the `page` argument to event handlers."""
|
||||
|
||||
def load_dict(self, patch: dict) -> None:
|
||||
super().load_dict(patch)
|
||||
if 'config_file_path' in patch:
|
||||
raise base.ValidationError("Can't set config_file_path in config")
|
||||
|
||||
def load_file(self, config_file: IO) -> None:
|
||||
"""Load config options from the open file descriptor of a YAML file."""
|
||||
loader = get_yaml_loader(config=self)
|
||||
self.load_dict(yaml_load(config_file, loader))
|
||||
|
||||
|
||||
def get_schema() -> base.PlainConfigSchema:
|
||||
"""Soft-deprecated, do not use."""
|
||||
return MkDocsConfig._schema
|
||||
Whitespace-only changes.
BIN
Binary file not shown.
@@ -0,0 +1,120 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import logging
|
||||
import os
|
||||
from typing import TYPE_CHECKING, List
|
||||
|
||||
from mkdocs import utils
|
||||
from mkdocs.config import base
|
||||
from mkdocs.config import config_options as c
|
||||
from mkdocs.contrib.search.search_index import SearchIndex
|
||||
from mkdocs.plugins import BasePlugin
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from mkdocs.config.defaults import MkDocsConfig
|
||||
from mkdocs.structure.pages import Page
|
||||
from mkdocs.utils.templates import TemplateContext
|
||||
|
||||
|
||||
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 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 config.theme.get('include_search_page'):
|
||||
config.theme.static_templates.add('search.html')
|
||||
if not config.theme.get('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') # type: ignore
|
||||
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: TemplateContext, page: Page, **kwargs) -> None:
|
||||
"""Add page to search index."""
|
||||
self.search_index.add_entry_from_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 config.theme.get('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)
|
||||
BIN
Binary file not shown.
BIN
Binary file not shown.
+381
@@ -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(new RegExp('\u0640', 'g'), '');
|
||||
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');
|
||||
};
|
||||
}))
|
||||
+284
@@ -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');
|
||||
};
|
||||
}))
|
||||
+384
@@ -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');
|
||||
};
|
||||
}))
|
||||
+450
@@ -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');
|
||||
};
|
||||
}))
|
||||
+599
@@ -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');
|
||||
};
|
||||
}))
|
||||
+541
@@ -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');
|
||||
};
|
||||
}))
|
||||
+703
@@ -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');
|
||||
};
|
||||
}))
|
||||
+123
@@ -0,0 +1,123 @@
|
||||
/*!
|
||||
* Lunr languages, `Hindi` language
|
||||
* https://github.com/MiKr13/lunr-languages
|
||||
*
|
||||
* Copyright 2020, Mihir Kumar
|
||||
* 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.hi = function() {
|
||||
this.pipeline.reset();
|
||||
this.pipeline.add(
|
||||
lunr.hi.trimmer,
|
||||
lunr.hi.stopWordFilter,
|
||||
lunr.hi.stemmer
|
||||
);
|
||||
|
||||
// change the tokenizer for japanese one
|
||||
// if (isLunr2) { // for lunr version 2.0.0
|
||||
// this.tokenizer = lunr.hi.tokenizer;
|
||||
// } else {
|
||||
// if (lunr.tokenizer) { // for lunr version 0.6.0
|
||||
// lunr.tokenizer = lunr.hi.tokenizer;
|
||||
// }
|
||||
// if (this.tokenizerFn) { // for lunr version 0.7.0 -> 1.0.0
|
||||
// this.tokenizerFn = lunr.hi.tokenizer;
|
||||
// }
|
||||
// }
|
||||
|
||||
if (this.searchPipeline) {
|
||||
this.searchPipeline.reset();
|
||||
this.searchPipeline.add(lunr.hi.stemmer)
|
||||
}
|
||||
};
|
||||
|
||||
/* lunr trimmer function */
|
||||
lunr.hi.wordCharacters = "\u0900-\u0903\u0904-\u090f\u0910-\u091f\u0920-\u092f\u0930-\u093f\u0940-\u094f\u0950-\u095f\u0960-\u096f\u0970-\u097fa-zA-Za-zA-Z0-90-9";
|
||||
// lunr.hi.wordCharacters = "ऀँंःऄअआइईउऊऋऌऍऎएऐऑऒओऔकखगघङचछजझञटठडढणतथदधनऩपफबभमयरऱलळऴवशषसहऺऻ़ऽािीुूृॄॅॆेैॉॊोौ्ॎॏॐ॒॑॓॔ॕॖॗक़ख़ग़ज़ड़ढ़फ़य़ॠॡॢॣ।॥०१२३४५६७८९॰ॱॲॳॴॵॶॷॸॹॺॻॼॽॾॿa-zA-Za-zA-Z0-90-9";
|
||||
lunr.hi.trimmer = lunr.trimmerSupport.generateTrimmer(lunr.hi.wordCharacters);
|
||||
|
||||
lunr.Pipeline.registerFunction(lunr.hi.trimmer, 'trimmer-hi');
|
||||
/* lunr stop word filter */
|
||||
lunr.hi.stopWordFilter = lunr.generateStopWordFilter(
|
||||
'अत अपना अपनी अपने अभी अंदर आदि आप इत्यादि इन इनका इन्हीं इन्हें इन्हों इस इसका इसकी इसके इसमें इसी इसे उन उनका उनकी उनके उनको उन्हीं उन्हें उन्हों उस उसके उसी उसे एक एवं एस ऐसे और कई कर करता करते करना करने करें कहते कहा का काफ़ी कि कितना किन्हें किन्हों किया किर किस किसी किसे की कुछ कुल के को कोई कौन कौनसा गया घर जब जहाँ जा जितना जिन जिन्हें जिन्हों जिस जिसे जीधर जैसा जैसे जो तक तब तरह तिन तिन्हें तिन्हों तिस तिसे तो था थी थे दबारा दिया दुसरा दूसरे दो द्वारा न नके नहीं ना निहायत नीचे ने पर पहले पूरा पे फिर बनी बही बहुत बाद बाला बिलकुल भी भीतर मगर मानो मे में यदि यह यहाँ यही या यिह ये रखें रहा रहे ऱ्वासा लिए लिये लेकिन व वग़ैरह वर्ग वह वहाँ वहीं वाले वुह वे वो सकता सकते सबसे सभी साथ साबुत साभ सारा से सो संग ही हुआ हुई हुए है हैं हो होता होती होते होना होने'.split(' '));
|
||||
/* lunr stemmer function */
|
||||
lunr.hi.stemmer = (function() {
|
||||
|
||||
return function(word) {
|
||||
// for lunr version 2
|
||||
if (typeof word.update === "function") {
|
||||
return word.update(function(word) {
|
||||
return word;
|
||||
})
|
||||
} else { // for lunr version <= 1
|
||||
return word;
|
||||
}
|
||||
|
||||
}
|
||||
})();
|
||||
|
||||
var segmenter = lunr.wordcut;
|
||||
segmenter.init();
|
||||
lunr.hi.tokenizer = function(obj) {
|
||||
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()
|
||||
});
|
||||
|
||||
var str = obj.toString().toLowerCase().replace(/^\s+/, '');
|
||||
return segmenter.cut(str).split('|');
|
||||
}
|
||||
|
||||
lunr.Pipeline.registerFunction(lunr.hi.stemmer, 'stemmer-hi');
|
||||
lunr.Pipeline.registerFunction(lunr.hi.stopWordFilter, 'stopWordFilter-hi');
|
||||
|
||||
};
|
||||
}))
|
||||
+565
@@ -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');
|
||||
};
|
||||
}))
|
||||
+98
@@ -0,0 +1,98 @@
|
||||
/*!
|
||||
* Lunr languages, `Armenian` language
|
||||
* https://github.com/turbobit/lunr-languages
|
||||
*
|
||||
* Copyright 2021, Manikandan Venkatasubban
|
||||
* 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.hy = function() {
|
||||
this.pipeline.reset();
|
||||
this.pipeline.add(
|
||||
lunr.hy.trimmer,
|
||||
lunr.hy.stopWordFilter
|
||||
);
|
||||
};
|
||||
|
||||
/* lunr trimmer function */
|
||||
// http://www.unicode.org/charts/
|
||||
lunr.hy.wordCharacters = "[" +
|
||||
"A-Za-z" +
|
||||
"\u0530-\u058F" + // armenian alphabet
|
||||
"\uFB00-\uFB4F" + // armenian ligatures
|
||||
"]";
|
||||
lunr.hy.trimmer = lunr.trimmerSupport.generateTrimmer(lunr.hy.wordCharacters);
|
||||
|
||||
lunr.Pipeline.registerFunction(lunr.hy.trimmer, 'trimmer-hy');
|
||||
|
||||
|
||||
/* lunr stop word filter */
|
||||
// https://www.ranks.nl/stopwords/armenian
|
||||
lunr.hy.stopWordFilter = lunr.generateStopWordFilter('դու և եք էիր էիք հետո նաև նրանք որը վրա է որ պիտի են այս մեջ ն իր ու ի այդ որոնք այն կամ էր մի ես համար այլ իսկ էին ենք հետ ին թ էինք մենք նրա նա դուք եմ էի ըստ որպես ում'.split(' '));
|
||||
lunr.Pipeline.registerFunction(lunr.hy.stopWordFilter, 'stopWordFilter-hy');
|
||||
|
||||
/* lunr stemmer function */
|
||||
lunr.hy.stemmer = (function() {
|
||||
|
||||
return function(word) {
|
||||
// for lunr version 2
|
||||
if (typeof word.update === "function") {
|
||||
return word.update(function(word) {
|
||||
return word;
|
||||
})
|
||||
} else { // for lunr version <= 1
|
||||
return word;
|
||||
}
|
||||
|
||||
}
|
||||
})();
|
||||
lunr.Pipeline.registerFunction(lunr.hy.stemmer, 'stemmer-hy');
|
||||
};
|
||||
}))
|
||||
+617
@@ -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');
|
||||
};
|
||||
}))
|
||||
+188
@@ -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');
|
||||
};
|
||||
}))
|
||||
+5
@@ -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');
|
||||
+110
@@ -0,0 +1,110 @@
|
||||
/*!
|
||||
* Lunr languages, `Kannada` language
|
||||
* https://github.com/MiKr13/lunr-languages
|
||||
*
|
||||
* Copyright 2023, India
|
||||
* 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.kn = function() {
|
||||
this.pipeline.reset();
|
||||
this.pipeline.add(
|
||||
lunr.kn.trimmer,
|
||||
lunr.kn.stopWordFilter,
|
||||
lunr.kn.stemmer
|
||||
);
|
||||
|
||||
if (this.searchPipeline) {
|
||||
this.searchPipeline.reset();
|
||||
this.searchPipeline.add(lunr.kn.stemmer)
|
||||
}
|
||||
};
|
||||
|
||||
/* lunr trimmer function */
|
||||
lunr.kn.wordCharacters = "\u0C80-\u0C84\u0C85-\u0C94\u0C95-\u0CB9\u0CBE-\u0CCC\u0CBC-\u0CBD\u0CD5-\u0CD6\u0CDD-\u0CDE\u0CE0-\u0CE1\u0CE2-\u0CE3\u0CE4\u0CE5\u0CE6-\u0CEF\u0CF1-\u0CF3";
|
||||
lunr.kn.trimmer = lunr.trimmerSupport.generateTrimmer(lunr.kn.wordCharacters);
|
||||
|
||||
lunr.Pipeline.registerFunction(lunr.kn.trimmer, 'trimmer-kn');
|
||||
/* lunr stop word filter */
|
||||
lunr.kn.stopWordFilter = lunr.generateStopWordFilter(
|
||||
'ಮತ್ತು ಈ ಒಂದು ರಲ್ಲಿ ಹಾಗೂ ಎಂದು ಅಥವಾ ಇದು ರ ಅವರು ಎಂಬ ಮೇಲೆ ಅವರ ತನ್ನ ಆದರೆ ತಮ್ಮ ನಂತರ ಮೂಲಕ ಹೆಚ್ಚು ನ ಆ ಕೆಲವು ಅನೇಕ ಎರಡು ಹಾಗು ಪ್ರಮುಖ ಇದನ್ನು ಇದರ ಸುಮಾರು ಅದರ ಅದು ಮೊದಲ ಬಗ್ಗೆ ನಲ್ಲಿ ರಂದು ಇತರ ಅತ್ಯಂತ ಹೆಚ್ಚಿನ ಸಹ ಸಾಮಾನ್ಯವಾಗಿ ನೇ ಹಲವಾರು ಹೊಸ ದಿ ಕಡಿಮೆ ಯಾವುದೇ ಹೊಂದಿದೆ ದೊಡ್ಡ ಅನ್ನು ಇವರು ಪ್ರಕಾರ ಇದೆ ಮಾತ್ರ ಕೂಡ ಇಲ್ಲಿ ಎಲ್ಲಾ ವಿವಿಧ ಅದನ್ನು ಹಲವು ರಿಂದ ಕೇವಲ ದ ದಕ್ಷಿಣ ಗೆ ಅವನ ಅತಿ ನೆಯ ಬಹಳ ಕೆಲಸ ಎಲ್ಲ ಪ್ರತಿ ಇತ್ಯಾದಿ ಇವು ಬೇರೆ ಹೀಗೆ ನಡುವೆ ಇದಕ್ಕೆ ಎಸ್ ಇವರ ಮೊದಲು ಶ್ರೀ ಮಾಡುವ ಇದರಲ್ಲಿ ರೀತಿಯ ಮಾಡಿದ ಕಾಲ ಅಲ್ಲಿ ಮಾಡಲು ಅದೇ ಈಗ ಅವು ಗಳು ಎ ಎಂಬುದು ಅವನು ಅಂದರೆ ಅವರಿಗೆ ಇರುವ ವಿಶೇಷ ಮುಂದೆ ಅವುಗಳ ಮುಂತಾದ ಮೂಲ ಬಿ ಮೀ ಒಂದೇ ಇನ್ನೂ ಹೆಚ್ಚಾಗಿ ಮಾಡಿ ಅವರನ್ನು ಇದೇ ಯ ರೀತಿಯಲ್ಲಿ ಜೊತೆ ಅದರಲ್ಲಿ ಮಾಡಿದರು ನಡೆದ ಆಗ ಮತ್ತೆ ಪೂರ್ವ ಆತ ಬಂದ ಯಾವ ಒಟ್ಟು ಇತರೆ ಹಿಂದೆ ಪ್ರಮಾಣದ ಗಳನ್ನು ಕುರಿತು ಯು ಆದ್ದರಿಂದ ಅಲ್ಲದೆ ನಗರದ ಮೇಲಿನ ಏಕೆಂದರೆ ರಷ್ಟು ಎಂಬುದನ್ನು ಬಾರಿ ಎಂದರೆ ಹಿಂದಿನ ಆದರೂ ಆದ ಸಂಬಂಧಿಸಿದ ಮತ್ತೊಂದು ಸಿ ಆತನ '.split(' '));
|
||||
/* lunr stemmer function */
|
||||
lunr.kn.stemmer = (function() {
|
||||
|
||||
return function(word) {
|
||||
// for lunr version 2
|
||||
if (typeof word.update === "function") {
|
||||
return word.update(function(word) {
|
||||
return word;
|
||||
})
|
||||
} else { // for lunr version <= 1
|
||||
return word;
|
||||
}
|
||||
|
||||
}
|
||||
})();
|
||||
|
||||
var segmenter = lunr.wordcut;
|
||||
segmenter.init();
|
||||
lunr.kn.tokenizer = function(obj) {
|
||||
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()
|
||||
});
|
||||
|
||||
var str = obj.toString().toLowerCase().replace(/^\s+/, '');
|
||||
return segmenter.cut(str).split('|');
|
||||
}
|
||||
|
||||
lunr.Pipeline.registerFunction(lunr.kn.stemmer, 'stemmer-kn');
|
||||
lunr.Pipeline.registerFunction(lunr.kn.stopWordFilter, 'stopWordFilter-kn');
|
||||
|
||||
};
|
||||
}))
|
||||
+114
@@ -0,0 +1,114 @@
|
||||
/*!
|
||||
* Lunr languages, `Korean` language
|
||||
* https://github.com/turbobit/lunr-languages
|
||||
*
|
||||
* Copyright 2021, Manikandan Venkatasubban
|
||||
* 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.ko = function() {
|
||||
this.pipeline.reset();
|
||||
this.pipeline.add(
|
||||
lunr.ko.trimmer,
|
||||
lunr.ko.stopWordFilter
|
||||
);
|
||||
|
||||
// change the tokenizer for japanese one
|
||||
// if (isLunr2) { // for lunr version 2.0.0
|
||||
// this.tokenizer = lunr.ko.tokenizer;
|
||||
// } else {
|
||||
// if (lunr.tokenizer) { // for lunr version 0.6.0
|
||||
// lunr.tokenizer = lunr.ko.tokenizer;
|
||||
// }
|
||||
// if (this.tokenizerFn) { // for lunr version 0.7.0 -> 1.0.0
|
||||
// this.tokenizerFn = lunr.ko.tokenizer;
|
||||
// }
|
||||
// }
|
||||
/*
|
||||
if (this.searchPipeline) {
|
||||
this.searchPipeline.reset();
|
||||
this.searchPipeline.add(lunr.ko.stemmer)
|
||||
}
|
||||
*/
|
||||
};
|
||||
|
||||
/* lunr trimmer function */
|
||||
lunr.ko.wordCharacters = "[" +
|
||||
"A-Za-z" +
|
||||
"\uac00-\ud7a3" +
|
||||
"]";
|
||||
lunr.ko.trimmer = lunr.trimmerSupport.generateTrimmer(lunr.ko.wordCharacters);
|
||||
|
||||
lunr.Pipeline.registerFunction(lunr.ko.trimmer, 'trimmer-ko');
|
||||
|
||||
|
||||
/* lunr stop word filter */
|
||||
//https://www.ranks.nl/stopwords/korean
|
||||
lunr.ko.stopWordFilter = lunr.generateStopWordFilter('아 휴 아이구 아이쿠 아이고 어 나 우리 저희 따라 의해 을 를 에 의 가 으로 로 에게 뿐이다 의거하여 근거하여 입각하여 기준으로 예하면 예를 들면 예를 들자면 저 소인 소생 저희 지말고 하지마 하지마라 다른 물론 또한 그리고 비길수 없다 해서는 안된다 뿐만 아니라 만이 아니다 만은 아니다 막론하고 관계없이 그치지 않다 그러나 그런데 하지만 든간에 논하지 않다 따지지 않다 설사 비록 더라도 아니면 만 못하다 하는 편이 낫다 불문하고 향하여 향해서 향하다 쪽으로 틈타 이용하여 타다 오르다 제외하고 이 외에 이 밖에 하여야 비로소 한다면 몰라도 외에도 이곳 여기 부터 기점으로 따라서 할 생각이다 하려고하다 이리하여 그리하여 그렇게 함으로써 하지만 일때 할때 앞에서 중에서 보는데서 으로써 로써 까지 해야한다 일것이다 반드시 할줄알다 할수있다 할수있어 임에 틀림없다 한다면 등 등등 제 겨우 단지 다만 할뿐 딩동 댕그 대해서 대하여 대하면 훨씬 얼마나 얼마만큼 얼마큼 남짓 여 얼마간 약간 다소 좀 조금 다수 몇 얼마 지만 하물며 또한 그러나 그렇지만 하지만 이외에도 대해 말하자면 뿐이다 다음에 반대로 반대로 말하자면 이와 반대로 바꾸어서 말하면 바꾸어서 한다면 만약 그렇지않으면 까악 툭 딱 삐걱거리다 보드득 비걱거리다 꽈당 응당 해야한다 에 가서 각 각각 여러분 각종 각자 제각기 하도록하다 와 과 그러므로 그래서 고로 한 까닭에 하기 때문에 거니와 이지만 대하여 관하여 관한 과연 실로 아니나다를가 생각한대로 진짜로 한적이있다 하곤하였다 하 하하 허허 아하 거바 와 오 왜 어째서 무엇때문에 어찌 하겠는가 무슨 어디 어느곳 더군다나 하물며 더욱이는 어느때 언제 야 이봐 어이 여보시오 흐흐 흥 휴 헉헉 헐떡헐떡 영차 여차 어기여차 끙끙 아야 앗 아야 콸콸 졸졸 좍좍 뚝뚝 주룩주룩 솨 우르르 그래도 또 그리고 바꾸어말하면 바꾸어말하자면 혹은 혹시 답다 및 그에 따르는 때가 되어 즉 지든지 설령 가령 하더라도 할지라도 일지라도 지든지 몇 거의 하마터면 인젠 이젠 된바에야 된이상 만큼 어찌됏든 그위에 게다가 점에서 보아 비추어 보아 고려하면 하게될것이다 일것이다 비교적 좀 보다더 비하면 시키다 하게하다 할만하다 의해서 연이서 이어서 잇따라 뒤따라 뒤이어 결국 의지하여 기대여 통하여 자마자 더욱더 불구하고 얼마든지 마음대로 주저하지 않고 곧 즉시 바로 당장 하자마자 밖에 안된다 하면된다 그래 그렇지 요컨대 다시 말하자면 바꿔 말하면 즉 구체적으로 말하자면 시작하여 시초에 이상 허 헉 허걱 바와같이 해도좋다 해도된다 게다가 더구나 하물며 와르르 팍 퍽 펄렁 동안 이래 하고있었다 이었다 에서 로부터 까지 예하면 했어요 해요 함께 같이 더불어 마저 마저도 양자 모두 습니다 가까스로 하려고하다 즈음하여 다른 다른 방면으로 해봐요 습니까 했어요 말할것도 없고 무릎쓰고 개의치않고 하는것만 못하다 하는것이 낫다 매 매번 들 모 어느것 어느 로써 갖고말하자면 어디 어느쪽 어느것 어느해 어느 년도 라 해도 언젠가 어떤것 어느것 저기 저쪽 저것 그때 그럼 그러면 요만한걸 그래 그때 저것만큼 그저 이르기까지 할 줄 안다 할 힘이 있다 너 너희 당신 어찌 설마 차라리 할지언정 할지라도 할망정 할지언정 구토하다 게우다 토하다 메쓰겁다 옆사람 퉤 쳇 의거하여 근거하여 의해 따라 힘입어 그 다음 버금 두번째로 기타 첫번째로 나머지는 그중에서 견지에서 형식으로 쓰여 입장에서 위해서 단지 의해되다 하도록시키다 뿐만아니라 반대로 전후 전자 앞의것 잠시 잠깐 하면서 그렇지만 다음에 그러한즉 그런즉 남들 아무거나 어찌하든지 같다 비슷하다 예컨대 이럴정도로 어떻게 만약 만일 위에서 서술한바와같이 인 듯하다 하지 않는다면 만약에 무엇 무슨 어느 어떤 아래윗 조차 한데 그럼에도 불구하고 여전히 심지어 까지도 조차도 하지 않도록 않기 위하여 때 시각 무렵 시간 동안 어때 어떠한 하여금 네 예 우선 누구 누가 알겠는가 아무도 줄은모른다 줄은 몰랏다 하는 김에 겸사겸사 하는바 그런 까닭에 한 이유는 그러니 그러니까 때문에 그 너희 그들 너희들 타인 것 것들 너 위하여 공동으로 동시에 하기 위하여
Line truncated
|
||||
lunr.Pipeline.registerFunction(lunr.ko.stopWordFilter, 'stopWordFilter-ko');
|
||||
|
||||
/* lunr stemmer function */
|
||||
lunr.ko.stemmer = (function() {
|
||||
|
||||
return function(word) {
|
||||
// for lunr version 2
|
||||
if (typeof word.update === "function") {
|
||||
return word.update(function(word) {
|
||||
return word;
|
||||
})
|
||||
} else { // for lunr version <= 1
|
||||
return word;
|
||||
}
|
||||
|
||||
}
|
||||
})();
|
||||
lunr.Pipeline.registerFunction(lunr.ko.stemmer, 'stemmer-ko');
|
||||
};
|
||||
}))
|
||||
+79
@@ -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);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}));
|
||||
+448
@@ -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');
|
||||
};
|
||||
}))
|
||||
+258
@@ -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');
|
||||
};
|
||||
}))
|
||||
+570
@@ -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');
|
||||
};
|
||||
}))
|
||||
+558
@@ -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');
|
||||
};
|
||||
}))
|
||||
+391
@@ -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');
|
||||
};
|
||||
}))
|
||||
+110
@@ -0,0 +1,110 @@
|
||||
/*!
|
||||
* Lunr languages, `Sanskrit` language
|
||||
* https://github.com/MiKr13/lunr-languages
|
||||
*
|
||||
* Copyright 2023, India
|
||||
* 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.sa = function() {
|
||||
this.pipeline.reset();
|
||||
this.pipeline.add(
|
||||
lunr.sa.trimmer,
|
||||
lunr.sa.stopWordFilter,
|
||||
lunr.sa.stemmer
|
||||
);
|
||||
|
||||
if (this.searchPipeline) {
|
||||
this.searchPipeline.reset();
|
||||
this.searchPipeline.add(lunr.sa.stemmer)
|
||||
}
|
||||
};
|
||||
|
||||
/* lunr trimmer function */
|
||||
lunr.sa.wordCharacters = "\u0900-\u0903\u0904-\u090f\u0910-\u091f\u0920-\u092f\u0930-\u093f\u0940-\u094f\u0950-\u095f\u0960-\u096f\u0970-\u097f\uA8E0-\uA8F1\uA8F2-\uA8F7\uA8F8-\uA8FB\uA8FC-\uA8FD\uA8FE-\uA8FF\u11B00-\u11B09";
|
||||
lunr.sa.trimmer = lunr.trimmerSupport.generateTrimmer(lunr.sa.wordCharacters);
|
||||
|
||||
lunr.Pipeline.registerFunction(lunr.sa.trimmer, 'trimmer-sa');
|
||||
/* lunr stop word filter */
|
||||
lunr.sa.stopWordFilter = lunr.generateStopWordFilter(
|
||||
'तथा अयम् एकम् इत्यस्मिन् तथा तत् वा अयम् इत्यस्य ते आहूत उपरि तेषाम् किन्तु तेषाम् तदा इत्यनेन अधिकः इत्यस्य तत् केचन बहवः द्वि तथा महत्वपूर्णः अयम् अस्य विषये अयं अस्ति तत् प्रथमः विषये इत्युपरि इत्युपरि इतर अधिकतमः अधिकः अपि सामान्यतया ठ इतरेतर नूतनम् द न्यूनम् कश्चित् वा विशालः द सः अस्ति तदनुसारम् तत्र अस्ति केवलम् अपि अत्र सर्वे विविधाः तत् बहवः यतः इदानीम् द दक्षिण इत्यस्मै तस्य उपरि नथ अतीव कार्यम् सर्वे एकैकम् इत्यादि। एते सन्ति उत इत्थम् मध्ये एतदर्थं . स कस्य प्रथमः श्री. करोति अस्मिन् प्रकारः निर्मिता कालः तत्र कर्तुं समान अधुना ते सन्ति स एकः अस्ति सः अर्थात् तेषां कृते . स्थितम् विशेषः अग्रिम तेषाम् समान स्रोतः ख म समान इदानीमपि अधिकतया करोतु ते समान इत्यस्य वीथी सह यस्मिन् कृतवान् धृतः तदा पुनः पूर्वं सः आगतः किम् कुल इतर पुरा मात्रा स विषये उ अतएव अपि नगरस्य उपरि यतः प्रतिशतं कतरः कालः साधनानि भूत तथापि जात सम्बन्धि अन्यत् ग अतः अस्माकं स्वकीयाः अस्माकं इदानीं अन्तः इत्यादयः भवन्तः इत्यादयः एते एताः तस्य अस्य इदम् एते तेषां तेषां तेषां तान् तेषां तेषां तेषां समानः सः एकः च तादृशाः बहवः अन्ये च वदन्ति यत् कियत् कस्मै कस्मै यस्मै यस्मै यस्मै यस्मै न अतिनीचः किन्तु प्रथमं सम्पूर्णतया ततः चिरकालानन्तरं पुस्तकं सम्पूर्णतया अन्तः किन्तु अत्र वा इह इव श्रद्धाय अवशिष्यते परन्तु अन्ये वर्गाः सन्ति ते सन्ति शक्नुवन्ति सर्वे मिलित्वा सर्वे एकत्र"'.split(' '));
|
||||
/* lunr stemmer function */
|
||||
lunr.sa.stemmer = (function() {
|
||||
|
||||
return function(word) {
|
||||
// for lunr version 2
|
||||
if (typeof word.update === "function") {
|
||||
return word.update(function(word) {
|
||||
return word;
|
||||
})
|
||||
} else { // for lunr version <= 1
|
||||
return word;
|
||||
}
|
||||
|
||||
}
|
||||
})();
|
||||
|
||||
var segmenter = lunr.wordcut;
|
||||
segmenter.init();
|
||||
lunr.sa.tokenizer = function(obj) {
|
||||
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()
|
||||
});
|
||||
|
||||
var str = obj.toString().toLowerCase().replace(/^\s+/, '');
|
||||
return segmenter.cut(str).split('|');
|
||||
}
|
||||
|
||||
lunr.Pipeline.registerFunction(lunr.sa.stemmer, 'stemmer-sa');
|
||||
lunr.Pipeline.registerFunction(lunr.sa.stopWordFilter, 'stopWordFilter-sa');
|
||||
|
||||
};
|
||||
}))
|
||||
+304
@@ -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, '');
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
}));
|
||||
+256
@@ -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');
|
||||
};
|
||||
}))
|
||||
+123
@@ -0,0 +1,123 @@
|
||||
/*!
|
||||
* Lunr languages, `Tamil` language
|
||||
* https://github.com/tvmani/lunr-languages
|
||||
*
|
||||
* Copyright 2021, Manikandan Venkatasubban
|
||||
* 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.ta = function() {
|
||||
this.pipeline.reset();
|
||||
this.pipeline.add(
|
||||
lunr.ta.trimmer,
|
||||
lunr.ta.stopWordFilter,
|
||||
lunr.ta.stemmer
|
||||
);
|
||||
|
||||
// change the tokenizer for japanese one
|
||||
// if (isLunr2) { // for lunr version 2.0.0
|
||||
// this.tokenizer = lunr.ta.tokenizer;
|
||||
// } else {
|
||||
// if (lunr.tokenizer) { // for lunr version 0.6.0
|
||||
// lunr.tokenizer = lunr.ta.tokenizer;
|
||||
// }
|
||||
// if (this.tokenizerFn) { // for lunr version 0.7.0 -> 1.0.0
|
||||
// this.tokenizerFn = lunr.ta.tokenizer;
|
||||
// }
|
||||
// }
|
||||
|
||||
if (this.searchPipeline) {
|
||||
this.searchPipeline.reset();
|
||||
this.searchPipeline.add(lunr.ta.stemmer)
|
||||
}
|
||||
};
|
||||
|
||||
/* lunr trimmer function */
|
||||
lunr.ta.wordCharacters = "\u0b80-\u0b89\u0b8a-\u0b8f\u0b90-\u0b99\u0b9a-\u0b9f\u0ba0-\u0ba9\u0baa-\u0baf\u0bb0-\u0bb9\u0bba-\u0bbf\u0bc0-\u0bc9\u0bca-\u0bcf\u0bd0-\u0bd9\u0bda-\u0bdf\u0be0-\u0be9\u0bea-\u0bef\u0bf0-\u0bf9\u0bfa-\u0bffa-zA-Za-zA-Z0-90-9";
|
||||
|
||||
lunr.ta.trimmer = lunr.trimmerSupport.generateTrimmer(lunr.ta.wordCharacters);
|
||||
|
||||
lunr.Pipeline.registerFunction(lunr.ta.trimmer, 'trimmer-ta');
|
||||
/* lunr stop word filter */
|
||||
lunr.ta.stopWordFilter = lunr.generateStopWordFilter(
|
||||
'அங்கு அங்கே அது அதை அந்த அவர் அவர்கள் அவள் அவன் அவை ஆக ஆகவே ஆகையால் ஆதலால் ஆதலினால் ஆனாலும் ஆனால் இங்கு இங்கே இது இதை இந்த இப்படி இவர் இவர்கள் இவள் இவன் இவை இவ்வளவு உனக்கு உனது உன் உன்னால் எங்கு எங்கே எது எதை எந்த எப்படி எவர் எவர்கள் எவள் எவன் எவை எவ்வளவு எனக்கு எனது எனவே என் என்ன என்னால் ஏது ஏன் தனது தன்னால் தானே தான் நாங்கள் நாம் நான் நீ நீங்கள்'.split(' '));
|
||||
/* lunr stemmer function */
|
||||
lunr.ta.stemmer = (function() {
|
||||
|
||||
return function(word) {
|
||||
// for lunr version 2
|
||||
if (typeof word.update === "function") {
|
||||
return word.update(function(word) {
|
||||
return word;
|
||||
})
|
||||
} else { // for lunr version <= 1
|
||||
return word;
|
||||
}
|
||||
|
||||
}
|
||||
})();
|
||||
|
||||
var segmenter = lunr.wordcut;
|
||||
segmenter.init();
|
||||
lunr.ta.tokenizer = function(obj) {
|
||||
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()
|
||||
});
|
||||
|
||||
var str = obj.toString().toLowerCase().replace(/^\s+/, '');
|
||||
return segmenter.cut(str).split('|');
|
||||
}
|
||||
|
||||
lunr.Pipeline.registerFunction(lunr.ta.stemmer, 'stemmer-ta');
|
||||
lunr.Pipeline.registerFunction(lunr.ta.stopWordFilter, 'stopWordFilter-ta');
|
||||
|
||||
};
|
||||
}))
|
||||
+122
@@ -0,0 +1,122 @@
|
||||
/*!
|
||||
* Lunr languages, `Hindi` language
|
||||
* https://github.com/MiKr13/lunr-languages
|
||||
*
|
||||
* Copyright 2023, India
|
||||
* 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.te = function() {
|
||||
this.pipeline.reset();
|
||||
this.pipeline.add(
|
||||
lunr.te.trimmer,
|
||||
lunr.te.stopWordFilter,
|
||||
lunr.te.stemmer
|
||||
);
|
||||
|
||||
// change the tokenizer for japanese one
|
||||
// if (isLunr2) { // for lunr version 2.0.0
|
||||
// this.tokenizer = lunr.hi.tokenizer;
|
||||
// } else {
|
||||
// if (lunr.tokenizer) { // for lunr version 0.6.0
|
||||
// lunr.tokenizer = lunr.hi.tokenizer;
|
||||
// }
|
||||
// if (this.tokenizerFn) { // for lunr version 0.7.0 -> 1.0.0
|
||||
// this.tokenizerFn = lunr.hi.tokenizer;
|
||||
// }
|
||||
// }
|
||||
|
||||
if (this.searchPipeline) {
|
||||
this.searchPipeline.reset();
|
||||
this.searchPipeline.add(lunr.te.stemmer)
|
||||
}
|
||||
};
|
||||
|
||||
/* lunr trimmer function */
|
||||
lunr.te.wordCharacters = "\u0C00-\u0C04\u0C05-\u0C14\u0C15-\u0C39\u0C3E-\u0C4C\u0C55-\u0C56\u0C58-\u0C5A\u0C60-\u0C61\u0C62-\u0C63\u0C66-\u0C6F\u0C78-\u0C7F\u0C3C\u0C3D\u0C4D\u0C5D\u0C77\u0C64\u0C65";
|
||||
lunr.te.trimmer = lunr.trimmerSupport.generateTrimmer(lunr.te.wordCharacters);
|
||||
|
||||
lunr.Pipeline.registerFunction(lunr.te.trimmer, 'trimmer-te');
|
||||
/* lunr stop word filter */
|
||||
lunr.te.stopWordFilter = lunr.generateStopWordFilter(
|
||||
'అందరూ అందుబాటులో అడగండి అడగడం అడ్డంగా అనుగుణంగా అనుమతించు అనుమతిస్తుంది అయితే ఇప్పటికే ఉన్నారు ఎక్కడైనా ఎప్పుడు ఎవరైనా ఎవరో ఏ ఏదైనా ఏమైనప్పటికి ఒక ఒకరు కనిపిస్తాయి కాదు కూడా గా గురించి చుట్టూ చేయగలిగింది తగిన తర్వాత దాదాపు దూరంగా నిజంగా పై ప్రకారం ప్రక్కన మధ్య మరియు మరొక మళ్ళీ మాత్రమే మెచ్చుకో వద్ద వెంట వేరుగా వ్యతిరేకంగా సంబంధం'.split(' '));
|
||||
/* lunr stemmer function */
|
||||
lunr.te.stemmer = (function() {
|
||||
|
||||
return function(word) {
|
||||
// for lunr version 2
|
||||
if (typeof word.update === "function") {
|
||||
return word.update(function(word) {
|
||||
return word;
|
||||
})
|
||||
} else { // for lunr version <= 1
|
||||
return word;
|
||||
}
|
||||
|
||||
}
|
||||
})();
|
||||
|
||||
var segmenter = lunr.wordcut;
|
||||
segmenter.init();
|
||||
lunr.te.tokenizer = function(obj) {
|
||||
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()
|
||||
});
|
||||
|
||||
var str = obj.toString().toLowerCase().replace(/^\s+/, '');
|
||||
return segmenter.cut(str).split('|');
|
||||
}
|
||||
|
||||
lunr.Pipeline.registerFunction(lunr.te.stemmer, 'stemmer-te');
|
||||
lunr.Pipeline.registerFunction(lunr.te.stopWordFilter, 'stopWordFilter-te');
|
||||
|
||||
};
|
||||
}))
|
||||
+99
@@ -0,0 +1,99 @@
|
||||
/*!
|
||||
* 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('|');
|
||||
}
|
||||
};
|
||||
}))
|
||||
+1087
File diff suppressed because it is too large.
Load diff
+84
@@ -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(' '));
|
||||
};
|
||||
}))
|
||||
+145
@@ -0,0 +1,145 @@
|
||||
/*!
|
||||
* Lunr languages, `Chinese` language
|
||||
* https://github.com/MihaiValentin/lunr-languages
|
||||
*
|
||||
* Copyright 2019, Felix Lian (repairearth)
|
||||
* http://www.mozilla.org/MPL/
|
||||
*/
|
||||
/*!
|
||||
* based on
|
||||
* Snowball zhvaScript 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(require('@node-rs/jieba'))
|
||||
} else {
|
||||
// Browser globals (root is window)
|
||||
factory()(root.lunr);
|
||||
}
|
||||
}(this, function(nodejieba) {
|
||||
/**
|
||||
* 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, nodejiebaDictJson) {
|
||||
/* 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.');
|
||||
}
|
||||
|
||||
/*
|
||||
Chinese 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.zh = function() {
|
||||
this.pipeline.reset();
|
||||
this.pipeline.add(
|
||||
lunr.zh.trimmer,
|
||||
lunr.zh.stopWordFilter,
|
||||
lunr.zh.stemmer
|
||||
);
|
||||
|
||||
// change the tokenizer for Chinese one
|
||||
if (isLunr2) { // for lunr version 2.0.0
|
||||
this.tokenizer = lunr.zh.tokenizer;
|
||||
} else {
|
||||
if (lunr.tokenizer) { // for lunr version 0.6.0
|
||||
lunr.tokenizer = lunr.zh.tokenizer;
|
||||
}
|
||||
if (this.tokenizerFn) { // for lunr version 0.7.0 -> 1.0.0
|
||||
this.tokenizerFn = lunr.zh.tokenizer;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
lunr.zh.tokenizer = function(obj) {
|
||||
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()
|
||||
})
|
||||
|
||||
nodejiebaDictJson && nodejieba.load(nodejiebaDictJson)
|
||||
|
||||
var str = obj.toString().trim().toLowerCase();
|
||||
var tokens = [];
|
||||
|
||||
nodejieba.cut(str, true).forEach(function(seg) {
|
||||
tokens = tokens.concat(seg.split(' '))
|
||||
})
|
||||
|
||||
tokens = tokens.filter(function(token) {
|
||||
return !!token;
|
||||
});
|
||||
|
||||
var fromIndex = 0
|
||||
|
||||
return tokens.map(function(token, index) {
|
||||
if (isLunr2) {
|
||||
var start = str.indexOf(token, fromIndex)
|
||||
|
||||
var tokenMetadata = {}
|
||||
tokenMetadata["position"] = [start, token.length]
|
||||
tokenMetadata["index"] = index
|
||||
|
||||
fromIndex = start
|
||||
|
||||
return new lunr.Token(token, tokenMetadata);
|
||||
} else {
|
||||
return token
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/* lunr trimmer function */
|
||||
lunr.zh.wordCharacters = "\\w\u4e00-\u9fa5";
|
||||
lunr.zh.trimmer = lunr.trimmerSupport.generateTrimmer(lunr.zh.wordCharacters);
|
||||
lunr.Pipeline.registerFunction(lunr.zh.trimmer, 'trimmer-zh');
|
||||
|
||||
/* lunr stemmer function */
|
||||
lunr.zh.stemmer = (function() {
|
||||
|
||||
/* TODO Chinese stemmer */
|
||||
return function(word) {
|
||||
return word;
|
||||
}
|
||||
})();
|
||||
lunr.Pipeline.registerFunction(lunr.zh.stemmer, 'stemmer-zh');
|
||||
|
||||
/* lunr stop word filter. see https://www.ranks.nl/stopwords/chinese-stopwords */
|
||||
lunr.zh.stopWordFilter = lunr.generateStopWordFilter(
|
||||
'的 一 不 在 人 有 是 为 為 以 于 於 上 他 而 后 後 之 来 來 及 了 因 下 可 到 由 这 這 与 與 也 此 但 并 並 个 個 其 已 无 無 小 我 们 們 起 最 再 今 去 好 只 又 或 很 亦 某 把 那 你 乃 它 吧 被 比 别 趁 当 當 从 從 得 打 凡 儿 兒 尔 爾 该 該 各 给 給 跟 和 何 还 還 即 几 幾 既 看 据 據 距 靠 啦 另 么 麽 每 嘛 拿 哪 您 凭 憑 且 却 卻 让 讓 仍 啥 如 若 使 谁 誰 虽 雖 随 隨 同 所 她 哇 嗡 往 些 向 沿 哟 喲 用 咱 则 則 怎 曾 至 致 着 著 诸 諸 自'.split(' '));
|
||||
lunr.Pipeline.registerFunction(lunr.zh.stopWordFilter, 'stopWordFilter-zh');
|
||||
};
|
||||
}))
|
||||
+206
@@ -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 <taku@chasen.org>
|
||||
// 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;
|
||||
};
|
||||
|
||||
}));
|
||||
@@ -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));
|
||||
});
|
||||
@@ -0,0 +1,225 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
import logging
|
||||
import os
|
||||
import re
|
||||
import subprocess
|
||||
from html.parser import HTMLParser
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from mkdocs.structure.pages import Page
|
||||
from mkdocs.structure.toc import AnchorLink, TableOfContents
|
||||
|
||||
try:
|
||||
from lunr import lunr # type: ignore
|
||||
|
||||
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_: str | None) -> AnchorLink | None:
|
||||
"""
|
||||
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: str | None, 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 HTML.
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
text: list[str] | None = None,
|
||||
id_: str | None = None,
|
||||
title: str | None = 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: ContentSection | None = None
|
||||
self.is_header_tag = False
|
||||
self._stripped_html: list[str] = []
|
||||
|
||||
def handle_starttag(self, tag: str, attrs: list[tuple[str, str | None]]) -> 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)
|
||||
+3475
File diff suppressed because it is too large.
Load diff
+109
@@ -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, '<')
|
||||
.replace(/>/g, '>');
|
||||
}
|
||||
|
||||
function formatResult (location, title, summary) {
|
||||
return '<article><h3><a href="' + joinUrl(base_url, location) + '">'+ escapeHtml(title) + '</a></h3><p>' + escapeHtml(summary) +'</p></article>';
|
||||
}
|
||||
|
||||
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', '<p>' + noResultsText + '</p>');
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
+133
@@ -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);
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
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, SystemExit):
|
||||
"""Abort the build."""
|
||||
|
||||
code = 1
|
||||
|
||||
def show(self, *args, **kwargs) -> None:
|
||||
echo('\n' + 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.
|
||||
"""
|
||||
@@ -0,0 +1,381 @@
|
||||
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 sys
|
||||
import threading
|
||||
import time
|
||||
import traceback
|
||||
import urllib.parse
|
||||
import webbrowser
|
||||
import wsgiref.simple_server
|
||||
import wsgiref.util
|
||||
from typing import Any, BinaryIO, Callable, Iterable
|
||||
|
||||
import watchdog.events
|
||||
import watchdog.observers.polling
|
||||
|
||||
_SCRIPT_TEMPLATE_STR = """
|
||||
var livereload = function(epoch, requestId) {
|
||||
var req, timeout;
|
||||
|
||||
var poll = function() {
|
||||
req = new XMLHttpRequest();
|
||||
req.onloadend = function() {
|
||||
if (parseFloat(this.responseText) > epoch) {
|
||||
location.reload();
|
||||
} else {
|
||||
timeout = setTimeout(poll, this.status === 200 ? 0 : 3000);
|
||||
}
|
||||
};
|
||||
req.open("GET", "/livereload/" + epoch + "/" + requestId);
|
||||
req.send();
|
||||
}
|
||||
|
||||
var stop = function() {
|
||||
if (req) {
|
||||
req.abort();
|
||||
}
|
||||
if (timeout) {
|
||||
clearTimeout(timeout);
|
||||
}
|
||||
req = timeout = undefined;
|
||||
};
|
||||
|
||||
window.addEventListener("load", function() {
|
||||
if (document.visibilityState === "visible") {
|
||||
poll();
|
||||
}
|
||||
});
|
||||
window.addEventListener("visibilitychange", function() {
|
||||
if (document.visibilityState === "visible") {
|
||||
poll();
|
||||
} else {
|
||||
stop();
|
||||
}
|
||||
});
|
||||
window.addEventListener("beforeunload", stop);
|
||||
|
||||
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__), {})
|
||||
|
||||
|
||||
def _normalize_mount_path(mount_path: str) -> str:
|
||||
"""Ensure the mount path starts and ends with a slash."""
|
||||
return ("/" + mount_path.lstrip("/")).rstrip("/") + "/"
|
||||
|
||||
|
||||
def _serve_url(host: str, port: int, path: str) -> str:
|
||||
return f"http://{host}:{port}{_normalize_mount_path(path)}"
|
||||
|
||||
|
||||
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,
|
||||
) -> None:
|
||||
self.builder = builder
|
||||
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 = _normalize_mount_path(mount_path)
|
||||
self.url = _serve_url(host, port, mount_path)
|
||||
self.build_delay = 0.1
|
||||
self.shutdown_delay = shutdown_delay
|
||||
# To allow custom error pages.
|
||||
self.error_handler: Callable[[int], bytes | None] = lambda code: None
|
||||
|
||||
super().__init__((host, port), _Handler, bind_and_activate=False)
|
||||
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._want_rebuild: bool = False
|
||||
self._rebuild_cond = threading.Condition() # Must be held when accessing _want_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: 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 not (func is None or func is self.builder): # type: ignore[unreachable]
|
||||
raise TypeError("Plugins can no longer pass a 'func' parameter to watch().")
|
||||
|
||||
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._want_rebuild = True
|
||||
self._rebuild_cond.notify_all()
|
||||
|
||||
handler = watchdog.events.FileSystemEventHandler()
|
||||
handler.on_any_event = callback # type: ignore[method-assign]
|
||||
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, *, open_in_browser=False):
|
||||
self.server_bind()
|
||||
self.server_activate()
|
||||
|
||||
if self._watched_paths:
|
||||
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}")
|
||||
|
||||
if open_in_browser:
|
||||
log.info(f"Serving on {self.url} and opening it in a browser")
|
||||
else:
|
||||
log.info(f"Serving on {self.url}")
|
||||
self.serve_thread.start()
|
||||
if open_in_browser:
|
||||
webbrowser.open(self.url)
|
||||
|
||||
self._build_loop()
|
||||
|
||||
def _build_loop(self):
|
||||
while True:
|
||||
with self._rebuild_cond:
|
||||
while not self._rebuild_cond.wait_for(
|
||||
lambda: self._want_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()
|
||||
self._want_rebuild = False
|
||||
|
||||
try:
|
||||
self.builder()
|
||||
except Exception as e:
|
||||
if isinstance(e, SystemExit):
|
||||
print(e, file=sys.stderr) # noqa: T201
|
||||
else:
|
||||
traceback.print_exc()
|
||||
log.error(
|
||||
"An error happened during the rebuild. The server will appear stuck until build errors are resolved."
|
||||
)
|
||||
continue
|
||||
|
||||
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()
|
||||
self.server_close()
|
||||
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) -> Iterable[bytes] | None:
|
||||
# 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/"):
|
||||
if m := re.fullmatch(r"/livereload/([0-9]+)/[0-9]+", path):
|
||||
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"</body>")
|
||||
except ValueError:
|
||||
body_end = len(content)
|
||||
# The page will reload if the livereload poller returns a newer epoch than what it knows.
|
||||
# The other timestamp becomes just a unique identifier for the initiating page.
|
||||
script = _SCRIPT_TEMPLATE.substitute(epoch=epoch, request_id=_timestamp())
|
||||
return b"%b<script>%b</script>%b" % (
|
||||
content[:body_end],
|
||||
script.encode(),
|
||||
content[body_end:],
|
||||
)
|
||||
|
||||
@classmethod
|
||||
@functools.lru_cache # "Cache" to not repeat the same message for the same browser tab.
|
||||
def _log_poll_request(cls, url, request_id):
|
||||
log.info(f"Browser connected: {url}")
|
||||
|
||||
@classmethod
|
||||
def _guess_type(cls, path):
|
||||
# MkDocs only ensures a few common types (as seen in livereload_tests.py::test_mime_types).
|
||||
# Other uncommon types will not be accepted.
|
||||
if path.endswith((".js", ".JS", ".mjs")):
|
||||
return "application/javascript"
|
||||
if path.endswith(".gz"):
|
||||
return "application/gzip"
|
||||
|
||||
guess, _ = mimetypes.guess_type(path)
|
||||
if guess:
|
||||
return guess
|
||||
return "application/octet-stream"
|
||||
|
||||
|
||||
class _Handler(wsgiref.simple_server.WSGIRequestHandler):
|
||||
def log_request(self, code="-", size="-"):
|
||||
level = logging.DEBUG if str(code) == "200" else logging.WARNING
|
||||
log.log(level, f'"{self.requestline}" code {code}')
|
||||
|
||||
def log_message(self, format, *args):
|
||||
log.debug(format, *args)
|
||||
|
||||
|
||||
def _timestamp() -> int:
|
||||
return round(time.monotonic() * 1000)
|
||||
|
||||
|
||||
def _try_relativize_path(path: str) -> str:
|
||||
"""Make the path relative to current directory if it's under that directory."""
|
||||
p = pathlib.Path(path)
|
||||
try:
|
||||
p = p.relative_to(os.getcwd())
|
||||
except ValueError:
|
||||
pass
|
||||
return str(p)
|
||||
BIN
Binary file not shown.
@@ -0,0 +1,92 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import logging
|
||||
import os
|
||||
from typing import TYPE_CHECKING, Sequence
|
||||
|
||||
from jinja2.ext import Extension, InternationalizationExtension
|
||||
|
||||
from mkdocs.config.base import ValidationError
|
||||
|
||||
if TYPE_CHECKING:
|
||||
import jinja2
|
||||
|
||||
try:
|
||||
from babel.core import Locale, UnknownLocaleError
|
||||
from babel.support import NullTranslations, Translations
|
||||
|
||||
has_babel = True
|
||||
except ImportError: # pragma: no cover
|
||||
from mkdocs.utils.babel_stub import Locale, UnknownLocaleError # type: ignore
|
||||
|
||||
has_babel = False
|
||||
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
base_path = os.path.dirname(os.path.abspath(__file__))
|
||||
|
||||
|
||||
class NoBabelExtension(InternationalizationExtension): # pragma: no cover
|
||||
def __init__(self, environment):
|
||||
Extension.__init__(self, environment)
|
||||
environment.extend(
|
||||
install_null_translations=self._install_null,
|
||||
newstyle_gettext=False,
|
||||
)
|
||||
|
||||
|
||||
def parse_locale(locale: str) -> Locale:
|
||||
try:
|
||||
return Locale.parse(locale, sep='_')
|
||||
except (ValueError, UnknownLocaleError, TypeError) as e:
|
||||
raise ValidationError(f'Invalid value for locale: {e}')
|
||||
|
||||
|
||||
def install_translations(
|
||||
env: jinja2.Environment, locale: Locale, theme_dirs: Sequence[str]
|
||||
) -> None:
|
||||
if has_babel:
|
||||
env.add_extension('jinja2.ext.i18n')
|
||||
translations = _get_merged_translations(theme_dirs, 'locales', locale)
|
||||
if translations is not None:
|
||||
env.install_gettext_translations(translations) # type: ignore[attr-defined]
|
||||
else:
|
||||
env.install_null_translations() # type: ignore[attr-defined]
|
||||
if locale.language != 'en':
|
||||
log.warning(
|
||||
f"No translations could be found for the locale '{locale}'. "
|
||||
'Defaulting to English.'
|
||||
)
|
||||
else: # pragma: no cover
|
||||
# no babel installed, add dummy support for trans/endtrans blocks
|
||||
env.add_extension(NoBabelExtension)
|
||||
env.install_null_translations() # type: ignore[attr-defined]
|
||||
|
||||
|
||||
def _get_merged_translations(
|
||||
theme_dirs: Sequence[str], locales_dir: str, locale: Locale
|
||||
) -> Translations | None:
|
||||
merged_translations: Translations | None = None
|
||||
|
||||
log.debug(f"Looking for translations for locale '{locale}'")
|
||||
if locale.territory:
|
||||
locale_str = f"{locale.language}_{locale.territory}"
|
||||
else:
|
||||
locale_str = locale.language
|
||||
for theme_dir in reversed(theme_dirs):
|
||||
dirname = os.path.join(theme_dir, locales_dir)
|
||||
translations = Translations.load(dirname, [locale_str])
|
||||
|
||||
if type(translations) is NullTranslations:
|
||||
log.debug(f"No translations found here: '{dirname}'")
|
||||
continue
|
||||
if TYPE_CHECKING:
|
||||
assert isinstance(translations, Translations)
|
||||
|
||||
log.debug(f"Translations found here: '{dirname}'")
|
||||
if merged_translations is None:
|
||||
merged_translations = translations
|
||||
else:
|
||||
merged_translations.merge(translations)
|
||||
|
||||
return merged_translations
|
||||
@@ -0,0 +1,697 @@
|
||||
"""Implements the plugin API for MkDocs."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import logging
|
||||
import sys
|
||||
from typing import TYPE_CHECKING, Any, Callable, Generic, Literal, MutableMapping, TypeVar, overload
|
||||
|
||||
if sys.version_info >= (3, 10):
|
||||
from importlib.metadata import EntryPoint, entry_points
|
||||
else:
|
||||
from importlib_metadata import EntryPoint, entry_points
|
||||
|
||||
if TYPE_CHECKING:
|
||||
import jinja2.environment
|
||||
|
||||
from mkdocs import utils
|
||||
from mkdocs.config.base import Config, ConfigErrors, ConfigWarnings, LegacyConfig, PlainConfigSchema
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from mkdocs.config.defaults import MkDocsConfig
|
||||
from mkdocs.livereload import LiveReloadServer
|
||||
from mkdocs.structure.files import Files
|
||||
from mkdocs.structure.nav import Navigation
|
||||
from mkdocs.structure.pages import Page
|
||||
from mkdocs.utils.templates import TemplateContext
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from typing_extensions import Concatenate, ParamSpec
|
||||
else:
|
||||
ParamSpec = TypeVar
|
||||
|
||||
P = ParamSpec('P')
|
||||
T = TypeVar('T')
|
||||
|
||||
|
||||
log = logging.getLogger('mkdocs.plugins')
|
||||
|
||||
|
||||
def get_plugins() -> dict[str, EntryPoint]:
|
||||
"""Return a dict of all installed Plugins as {name: EntryPoint}."""
|
||||
plugins = entry_points(group='mkdocs.plugins')
|
||||
|
||||
# Allow third-party plugins to override core plugins
|
||||
pluginmap = {}
|
||||
for plugin in plugins:
|
||||
if plugin.name in pluginmap and plugin.value.startswith("mkdocs.contrib."):
|
||||
continue
|
||||
|
||||
pluginmap[plugin.name] = plugin
|
||||
|
||||
return pluginmap
|
||||
|
||||
|
||||
SomeConfig = TypeVar('SomeConfig', bound=Config)
|
||||
|
||||
|
||||
class BasePlugin(Generic[SomeConfig]):
|
||||
"""
|
||||
Plugin base class.
|
||||
|
||||
All plugins should subclass this class.
|
||||
"""
|
||||
|
||||
config_class: type[SomeConfig] = LegacyConfig # type: ignore[assignment]
|
||||
config_scheme: PlainConfigSchema = ()
|
||||
config: SomeConfig = {} # type: ignore[assignment]
|
||||
|
||||
supports_multiple_instances: bool = False
|
||||
"""Set to true in subclasses to declare support for adding the same plugin multiple times."""
|
||||
|
||||
def __class_getitem__(cls, config_class: type[Config]):
|
||||
"""Eliminates the need to write `config_class = FooConfig` when subclassing BasePlugin[FooConfig]."""
|
||||
name = f'{cls.__name__}[{config_class.__name__}]'
|
||||
return type(name, (cls,), dict(config_class=config_class))
|
||||
|
||||
def __init_subclass__(cls):
|
||||
if not issubclass(cls.config_class, Config):
|
||||
raise TypeError(
|
||||
f"config_class {cls.config_class} must be a subclass of `mkdocs.config.base.Config`"
|
||||
)
|
||||
if cls.config_class is not LegacyConfig:
|
||||
cls.config_scheme = cls.config_class._schema # For compatibility.
|
||||
|
||||
def load_config(
|
||||
self, options: dict[str, Any], config_file_path: str | None = None
|
||||
) -> tuple[ConfigErrors, ConfigWarnings]:
|
||||
"""Load config from a dict of options. Returns a tuple of (errors, warnings)."""
|
||||
if self.config_class is LegacyConfig:
|
||||
self.config = LegacyConfig(self.config_scheme, config_file_path=config_file_path) # type: ignore
|
||||
else:
|
||||
self.config = self.config_class(config_file_path=config_file_path)
|
||||
|
||||
self.config.load_dict(options)
|
||||
|
||||
return self.config.validate()
|
||||
|
||||
# One-time events
|
||||
|
||||
def on_startup(self, *, command: Literal['build', 'gh-deploy', 'serve'], dirty: bool) -> None:
|
||||
"""
|
||||
The `startup` event runs once at the very beginning of an `mkdocs` invocation.
|
||||
|
||||
New in MkDocs 1.4.
|
||||
|
||||
The presence of an `on_startup` method (even if empty) migrates the plugin to the new
|
||||
system where the plugin object is kept across builds within one `mkdocs serve`.
|
||||
|
||||
Note that for initializing variables, the `__init__` method is still preferred.
|
||||
For initializing per-build variables (and whenever in doubt), use the `on_config` event.
|
||||
|
||||
Args:
|
||||
command: the command that MkDocs was invoked with, e.g. "serve" for `mkdocs serve`.
|
||||
dirty: whether `--dirty` flag was passed.
|
||||
"""
|
||||
|
||||
def on_shutdown(self) -> None:
|
||||
"""
|
||||
The `shutdown` event runs once at the very end of an `mkdocs` invocation, before exiting.
|
||||
|
||||
This event is relevant only for support of `mkdocs serve`, otherwise within a
|
||||
single build it's undistinguishable from `on_post_build`.
|
||||
|
||||
New in MkDocs 1.4.
|
||||
|
||||
The presence of an `on_shutdown` method (even if empty) migrates the plugin to the new
|
||||
system where the plugin object is kept across builds within one `mkdocs serve`.
|
||||
|
||||
Note the `on_post_build` method is still preferred for cleanups, when possible, as it has
|
||||
a much higher chance of actually triggering. `on_shutdown` is "best effort" because it
|
||||
relies on detecting a graceful shutdown of MkDocs.
|
||||
"""
|
||||
|
||||
def on_serve(
|
||||
self, server: LiveReloadServer, /, *, config: MkDocsConfig, builder: Callable
|
||||
) -> LiveReloadServer | None:
|
||||
"""
|
||||
The `serve` event is only called when the `serve` command is used during
|
||||
development. It runs only once, after the first build finishes.
|
||||
It is passed the `Server` instance which can be modified before
|
||||
it is activated. For example, additional files or directories could be added
|
||||
to the list of "watched" files for auto-reloading.
|
||||
|
||||
Args:
|
||||
server: `livereload.Server` instance
|
||||
config: global configuration object
|
||||
builder: a callable which gets passed to each call to `server.watch`
|
||||
|
||||
Returns:
|
||||
`livereload.Server` instance
|
||||
"""
|
||||
return server
|
||||
|
||||
# Global events
|
||||
|
||||
def on_config(self, config: MkDocsConfig) -> MkDocsConfig | None:
|
||||
"""
|
||||
The `config` event is the first event called on build and is run immediately
|
||||
after the user configuration is loaded and validated. Any alterations to the
|
||||
config should be made here.
|
||||
|
||||
Args:
|
||||
config: global configuration object
|
||||
|
||||
Returns:
|
||||
global configuration object
|
||||
"""
|
||||
return config
|
||||
|
||||
def on_pre_build(self, *, config: MkDocsConfig) -> None:
|
||||
"""
|
||||
The `pre_build` event does not alter any variables. Use this event to call
|
||||
pre-build scripts.
|
||||
|
||||
Args:
|
||||
config: global configuration object
|
||||
"""
|
||||
|
||||
def on_files(self, files: Files, /, *, config: MkDocsConfig) -> Files | None:
|
||||
"""
|
||||
The `files` event is called after the files collection is populated from the
|
||||
`docs_dir`. Use this event to add, remove, or alter files in the
|
||||
collection. Note that Page objects have not yet been associated with the
|
||||
file objects in the collection. Use [Page Events](plugins.md#page-events) to manipulate page
|
||||
specific data.
|
||||
|
||||
Args:
|
||||
files: global files collection
|
||||
config: global configuration object
|
||||
|
||||
Returns:
|
||||
global files collection
|
||||
"""
|
||||
return files
|
||||
|
||||
def on_nav(
|
||||
self, nav: Navigation, /, *, config: MkDocsConfig, files: Files
|
||||
) -> Navigation | None:
|
||||
"""
|
||||
The `nav` event is called after the site navigation is created and can
|
||||
be used to alter the site navigation.
|
||||
|
||||
Args:
|
||||
nav: global navigation object
|
||||
config: global configuration object
|
||||
files: global files collection
|
||||
|
||||
Returns:
|
||||
global navigation object
|
||||
"""
|
||||
return nav
|
||||
|
||||
def on_env(
|
||||
self, env: jinja2.Environment, /, *, config: MkDocsConfig, files: Files
|
||||
) -> jinja2.Environment | None:
|
||||
"""
|
||||
The `env` event is called after the Jinja template environment is created
|
||||
and can be used to alter the
|
||||
[Jinja environment](https://jinja.palletsprojects.com/en/latest/api/#jinja2.Environment).
|
||||
|
||||
Args:
|
||||
env: global Jinja environment
|
||||
config: global configuration object
|
||||
files: global files collection
|
||||
|
||||
Returns:
|
||||
global Jinja Environment
|
||||
"""
|
||||
return env
|
||||
|
||||
def on_post_build(self, *, config: MkDocsConfig) -> None:
|
||||
"""
|
||||
The `post_build` event does not alter any variables. Use this event to call
|
||||
post-build scripts.
|
||||
|
||||
Args:
|
||||
config: global configuration object
|
||||
"""
|
||||
|
||||
def on_build_error(self, *, error: Exception) -> None:
|
||||
"""
|
||||
The `build_error` event is called after an exception of any kind
|
||||
is caught by MkDocs during the build process.
|
||||
Use this event to clean things up before MkDocs terminates. Note that any other
|
||||
events which were scheduled to run after the error will have been skipped. See
|
||||
[Handling Errors](plugins.md#handling-errors) for more details.
|
||||
|
||||
Args:
|
||||
error: exception raised
|
||||
"""
|
||||
|
||||
# Template events
|
||||
|
||||
def on_pre_template(
|
||||
self, template: jinja2.Template, /, *, template_name: str, config: MkDocsConfig
|
||||
) -> jinja2.Template | None:
|
||||
"""
|
||||
The `pre_template` event is called immediately after the subject template is
|
||||
loaded and can be used to alter the template.
|
||||
|
||||
Args:
|
||||
template: a Jinja2 [Template](https://jinja.palletsprojects.com/en/latest/api/#jinja2.Template) object
|
||||
template_name: string filename of template
|
||||
config: global configuration object
|
||||
|
||||
Returns:
|
||||
a Jinja2 [Template](https://jinja.palletsprojects.com/en/latest/api/#jinja2.Template) object
|
||||
"""
|
||||
return template
|
||||
|
||||
def on_template_context(
|
||||
self, context: TemplateContext, /, *, template_name: str, config: MkDocsConfig
|
||||
) -> TemplateContext | None:
|
||||
"""
|
||||
The `template_context` event is called immediately after the context is created
|
||||
for the subject template and can be used to alter the context for that specific
|
||||
template only.
|
||||
|
||||
Args:
|
||||
context: dict of template context variables
|
||||
template_name: string filename of template
|
||||
config: global configuration object
|
||||
|
||||
Returns:
|
||||
dict of template context variables
|
||||
"""
|
||||
return context
|
||||
|
||||
def on_post_template(
|
||||
self, output_content: str, /, *, template_name: str, config: MkDocsConfig
|
||||
) -> str | None:
|
||||
"""
|
||||
The `post_template` event is called after the template is rendered, but before
|
||||
it is written to disc and can be used to alter the output of the template.
|
||||
If an empty string is returned, the template is skipped and nothing is is
|
||||
written to disc.
|
||||
|
||||
Args:
|
||||
output_content: output of rendered template as string
|
||||
template_name: string filename of template
|
||||
config: global configuration object
|
||||
|
||||
Returns:
|
||||
output of rendered template as string
|
||||
"""
|
||||
return output_content
|
||||
|
||||
# Page events
|
||||
|
||||
def on_pre_page(self, page: Page, /, *, config: MkDocsConfig, files: Files) -> Page | None:
|
||||
"""
|
||||
The `pre_page` event is called before any actions are taken on the subject
|
||||
page and can be used to alter the `Page` instance.
|
||||
|
||||
Args:
|
||||
page: `mkdocs.structure.pages.Page` instance
|
||||
config: global configuration object
|
||||
files: global files collection
|
||||
|
||||
Returns:
|
||||
`mkdocs.structure.pages.Page` instance
|
||||
"""
|
||||
return page
|
||||
|
||||
def on_page_read_source(self, /, *, page: Page, config: MkDocsConfig) -> str | None:
|
||||
"""
|
||||
> DEPRECATED: Instead of this event, prefer one of these alternatives:
|
||||
>
|
||||
> * Since MkDocs 1.6, instead set `content_bytes`/`content_string` of a `File` inside [`on_files`][].
|
||||
> * Usually (although it's not an exact alternative), `on_page_markdown` can serve the same purpose.
|
||||
|
||||
The `on_page_read_source` event can replace the default mechanism to read
|
||||
the contents of a page's source from the filesystem.
|
||||
|
||||
Args:
|
||||
page: `mkdocs.structure.pages.Page` instance
|
||||
config: global configuration object
|
||||
|
||||
Returns:
|
||||
The raw source for a page as unicode string. If `None` is returned, the
|
||||
default loading from a file will be performed.
|
||||
"""
|
||||
return None
|
||||
|
||||
def on_page_markdown(
|
||||
self, markdown: str, /, *, page: Page, config: MkDocsConfig, files: Files
|
||||
) -> str | None:
|
||||
"""
|
||||
The `page_markdown` event is called after the page's markdown is loaded
|
||||
from file and can be used to alter the Markdown source text. The meta-
|
||||
data has been stripped off and is available as `page.meta` at this point.
|
||||
|
||||
Args:
|
||||
markdown: Markdown source text of page as string
|
||||
page: `mkdocs.structure.pages.Page` instance
|
||||
config: global configuration object
|
||||
files: global files collection
|
||||
|
||||
Returns:
|
||||
Markdown source text of page as string
|
||||
"""
|
||||
return markdown
|
||||
|
||||
def on_page_content(
|
||||
self, html: str, /, *, page: Page, config: MkDocsConfig, files: Files
|
||||
) -> str | None:
|
||||
"""
|
||||
The `page_content` event is called after the Markdown text is rendered to
|
||||
HTML (but before being passed to a template) and can be used to alter the
|
||||
HTML body of the page.
|
||||
|
||||
Args:
|
||||
html: HTML rendered from Markdown source as string
|
||||
page: `mkdocs.structure.pages.Page` instance
|
||||
config: global configuration object
|
||||
files: global files collection
|
||||
|
||||
Returns:
|
||||
HTML rendered from Markdown source as string
|
||||
"""
|
||||
return html
|
||||
|
||||
def on_page_context(
|
||||
self, context: TemplateContext, /, *, page: Page, config: MkDocsConfig, nav: Navigation
|
||||
) -> TemplateContext | None:
|
||||
"""
|
||||
The `page_context` event is called after the context for a page is created
|
||||
and can be used to alter the context for that specific page only.
|
||||
|
||||
Args:
|
||||
context: dict of template context variables
|
||||
page: `mkdocs.structure.pages.Page` instance
|
||||
config: global configuration object
|
||||
nav: global navigation object
|
||||
|
||||
Returns:
|
||||
dict of template context variables
|
||||
"""
|
||||
return context
|
||||
|
||||
def on_post_page(self, output: str, /, *, page: Page, config: MkDocsConfig) -> str | None:
|
||||
"""
|
||||
The `post_page` event is called after the template is rendered, but
|
||||
before it is written to disc and can be used to alter the output of the
|
||||
page. If an empty string is returned, the page is skipped and nothing is
|
||||
written to disc.
|
||||
|
||||
Args:
|
||||
output: output of rendered template as string
|
||||
page: `mkdocs.structure.pages.Page` instance
|
||||
config: global configuration object
|
||||
|
||||
Returns:
|
||||
output of rendered template as string
|
||||
"""
|
||||
return output
|
||||
|
||||
|
||||
EVENTS = tuple(k[3:] for k in BasePlugin.__dict__ if k.startswith("on_"))
|
||||
|
||||
# The above definitions were just for docs and type checking, we don't actually want them.
|
||||
for k in EVENTS:
|
||||
delattr(BasePlugin, 'on_' + k)
|
||||
|
||||
|
||||
def event_priority(priority: float) -> Callable[[T], T]:
|
||||
"""
|
||||
A decorator to set an event priority for an event handler method.
|
||||
|
||||
Recommended priority values:
|
||||
`100` "first", `50` "early", `0` "default", `-50` "late", `-100` "last".
|
||||
As different plugins discover more precise relations to each other, the values should be further tweaked.
|
||||
|
||||
Usage example:
|
||||
|
||||
```python
|
||||
@plugins.event_priority(-100) # Wishing to run this after all other plugins' `on_files` events.
|
||||
def on_files(self, files, config, **kwargs):
|
||||
...
|
||||
```
|
||||
|
||||
New in MkDocs 1.4.
|
||||
Recommended shim for backwards compatibility:
|
||||
|
||||
```python
|
||||
try:
|
||||
from mkdocs.plugins import event_priority
|
||||
except ImportError:
|
||||
event_priority = lambda priority: lambda f: f # No-op fallback
|
||||
```
|
||||
"""
|
||||
|
||||
def decorator(event_method):
|
||||
event_method.mkdocs_priority = priority
|
||||
return event_method
|
||||
|
||||
return decorator
|
||||
|
||||
|
||||
class CombinedEvent(Generic[P, T]):
|
||||
"""
|
||||
A descriptor that allows defining multiple event handlers and declaring them under one event's name.
|
||||
|
||||
Usage example:
|
||||
|
||||
```python
|
||||
@plugins.event_priority(100)
|
||||
def _on_page_markdown_1(self, markdown: str, **kwargs):
|
||||
...
|
||||
|
||||
@plugins.event_priority(-50)
|
||||
def _on_page_markdown_2(self, markdown: str, **kwargs):
|
||||
...
|
||||
|
||||
on_page_markdown = plugins.CombinedEvent(_on_page_markdown_1, _on_page_markdown_2)
|
||||
```
|
||||
|
||||
NOTE: The names of the sub-methods **can't** start with `on_`;
|
||||
instead they can start with `_on_` like in the the above example, or anything else.
|
||||
"""
|
||||
|
||||
def __init__(self, *methods: Callable[Concatenate[Any, P], T]):
|
||||
self.methods = methods
|
||||
|
||||
# This is only for mypy, so CombinedEvent can be a valid override of the methods in BasePlugin
|
||||
def __call__(self, instance: BasePlugin, *args: P.args, **kwargs: P.kwargs) -> T:
|
||||
raise TypeError(f"{type(self).__name__!r} object is not callable")
|
||||
|
||||
def __get__(self, instance, owner=None):
|
||||
return CombinedEvent(*(f.__get__(instance, owner) for f in self.methods))
|
||||
|
||||
|
||||
class PluginCollection(dict, MutableMapping[str, BasePlugin]):
|
||||
"""
|
||||
A collection of plugins.
|
||||
|
||||
In addition to being a dict of Plugin instances, each event method is registered
|
||||
upon being added. All registered methods for a given event can then be run in order
|
||||
by calling `run_event`.
|
||||
"""
|
||||
|
||||
_current_plugin: str | None
|
||||
|
||||
def __init__(self, *args, **kwargs) -> None:
|
||||
super().__init__(*args, **kwargs)
|
||||
self.events: dict[str, list[Callable]] = {k: [] for k in EVENTS}
|
||||
self._event_origins: dict[Callable, str] = {}
|
||||
|
||||
def _register_event(
|
||||
self, event_name: str, method: CombinedEvent | Callable, plugin_name: str | None = None
|
||||
) -> None:
|
||||
"""Register a method for an event."""
|
||||
if isinstance(method, CombinedEvent):
|
||||
for sub in method.methods:
|
||||
self._register_event(event_name, sub, plugin_name=plugin_name)
|
||||
else:
|
||||
events = self.events[event_name]
|
||||
if event_name == 'page_read_source' and len(events) == 1:
|
||||
plugin1 = self._event_origins.get(next(iter(events)), '<unknown>')
|
||||
plugin2 = plugin_name or '<unknown>'
|
||||
log.warning(
|
||||
"Multiple 'on_page_read_source' handlers can't work "
|
||||
f"(both plugins '{plugin1}' and '{plugin2}' registered one)."
|
||||
)
|
||||
utils.insort(events, method, key=lambda m: -getattr(m, 'mkdocs_priority', 0))
|
||||
if plugin_name:
|
||||
try:
|
||||
self._event_origins[method] = plugin_name
|
||||
except TypeError: # If the method is somehow not hashable.
|
||||
pass
|
||||
|
||||
def __getitem__(self, key: str) -> BasePlugin:
|
||||
return super().__getitem__(key)
|
||||
|
||||
def __setitem__(self, key: str, value: BasePlugin) -> None:
|
||||
super().__setitem__(key, value)
|
||||
# Register all of the event methods defined for this Plugin.
|
||||
for event_name in (x for x in dir(value) if x.startswith('on_')):
|
||||
method = getattr(value, event_name, None)
|
||||
if callable(method):
|
||||
self._register_event(event_name[3:], method, plugin_name=key)
|
||||
|
||||
@overload
|
||||
def run_event(self, name: str, **kwargs) -> Any:
|
||||
...
|
||||
|
||||
@overload
|
||||
def run_event(self, name: str, item: T, **kwargs) -> T:
|
||||
...
|
||||
|
||||
def run_event(self, name: str, item=None, **kwargs):
|
||||
"""
|
||||
Run all registered methods of an event.
|
||||
|
||||
`item` is the object to be modified or replaced and returned by the event method.
|
||||
If it isn't given the event method creates a new object to be returned.
|
||||
All other keywords are variables for context, but would not generally
|
||||
be modified by the event method.
|
||||
"""
|
||||
pass_item = item is not None
|
||||
for method in self.events[name]:
|
||||
self._current_plugin = self._event_origins.get(method, '<unknown>')
|
||||
if log.getEffectiveLevel() <= logging.DEBUG:
|
||||
log.debug(f"Running `{name}` event from plugin '{self._current_plugin}'")
|
||||
if pass_item:
|
||||
result = method(item, **kwargs)
|
||||
else:
|
||||
result = method(**kwargs)
|
||||
# keep item if method returned `None`
|
||||
if result is not None:
|
||||
item = result
|
||||
self._current_plugin = None
|
||||
return item
|
||||
|
||||
def on_startup(self, *, command: Literal['build', 'gh-deploy', 'serve'], dirty: bool) -> None:
|
||||
return self.run_event('startup', command=command, dirty=dirty)
|
||||
|
||||
def on_shutdown(self) -> None:
|
||||
return self.run_event('shutdown')
|
||||
|
||||
def on_serve(
|
||||
self, server: LiveReloadServer, *, config: MkDocsConfig, builder: Callable
|
||||
) -> LiveReloadServer:
|
||||
return self.run_event('serve', server, config=config, builder=builder)
|
||||
|
||||
def on_config(self, config: MkDocsConfig) -> MkDocsConfig:
|
||||
return self.run_event('config', config)
|
||||
|
||||
def on_pre_build(self, *, config: MkDocsConfig) -> None:
|
||||
return self.run_event('pre_build', config=config)
|
||||
|
||||
def on_files(self, files: Files, *, config: MkDocsConfig) -> Files:
|
||||
return self.run_event('files', files, config=config)
|
||||
|
||||
def on_nav(self, nav: Navigation, *, config: MkDocsConfig, files: Files) -> Navigation:
|
||||
return self.run_event('nav', nav, config=config, files=files)
|
||||
|
||||
def on_env(self, env: jinja2.Environment, *, config: MkDocsConfig, files: Files):
|
||||
return self.run_event('env', env, config=config, files=files)
|
||||
|
||||
def on_post_build(self, *, config: MkDocsConfig) -> None:
|
||||
return self.run_event('post_build', config=config)
|
||||
|
||||
def on_build_error(self, *, error: Exception) -> None:
|
||||
return self.run_event('build_error', error=error)
|
||||
|
||||
def on_pre_template(
|
||||
self, template: jinja2.Template, *, template_name: str, config: MkDocsConfig
|
||||
) -> jinja2.Template:
|
||||
return self.run_event('pre_template', template, template_name=template_name, config=config)
|
||||
|
||||
def on_template_context(
|
||||
self, context: TemplateContext, *, template_name: str, config: MkDocsConfig
|
||||
) -> TemplateContext:
|
||||
return self.run_event(
|
||||
'template_context', context, template_name=template_name, config=config
|
||||
)
|
||||
|
||||
def on_post_template(
|
||||
self, output_content: str, *, template_name: str, config: MkDocsConfig
|
||||
) -> str:
|
||||
return self.run_event(
|
||||
'post_template', output_content, template_name=template_name, config=config
|
||||
)
|
||||
|
||||
def on_pre_page(self, page: Page, *, config: MkDocsConfig, files: Files) -> Page:
|
||||
return self.run_event('pre_page', page, config=config, files=files)
|
||||
|
||||
def on_page_read_source(self, *, page: Page, config: MkDocsConfig) -> str | None:
|
||||
return self.run_event('page_read_source', page=page, config=config)
|
||||
|
||||
def on_page_markdown(
|
||||
self, markdown: str, *, page: Page, config: MkDocsConfig, files: Files
|
||||
) -> str:
|
||||
return self.run_event('page_markdown', markdown, page=page, config=config, files=files)
|
||||
|
||||
def on_page_content(self, html: str, *, page: Page, config: MkDocsConfig, files: Files) -> str:
|
||||
return self.run_event('page_content', html, page=page, config=config, files=files)
|
||||
|
||||
def on_page_context(
|
||||
self, context: TemplateContext, *, page: Page, config: MkDocsConfig, nav: Navigation
|
||||
) -> TemplateContext:
|
||||
return self.run_event('page_context', context, page=page, config=config, nav=nav)
|
||||
|
||||
def on_post_page(self, output: str, *, page: Page, config: MkDocsConfig) -> str:
|
||||
return self.run_event('post_page', output, page=page, config=config)
|
||||
|
||||
|
||||
class PrefixedLogger(logging.LoggerAdapter):
|
||||
"""A logger adapter to prefix log messages."""
|
||||
|
||||
def __init__(self, prefix: str, logger: logging.Logger) -> None:
|
||||
"""
|
||||
Initialize the logger adapter.
|
||||
|
||||
Arguments:
|
||||
prefix: The string to insert in front of every message.
|
||||
logger: The logger instance.
|
||||
"""
|
||||
super().__init__(logger, {})
|
||||
self.prefix = prefix
|
||||
|
||||
def process(self, msg: str, kwargs: MutableMapping[str, Any]) -> tuple[str, Any]:
|
||||
"""
|
||||
Process the message.
|
||||
|
||||
Arguments:
|
||||
msg: The message:
|
||||
kwargs: Remaining arguments.
|
||||
|
||||
Returns:
|
||||
The processed message.
|
||||
"""
|
||||
return f"{self.prefix}: {msg}", kwargs
|
||||
|
||||
|
||||
def get_plugin_logger(name: str) -> PrefixedLogger:
|
||||
"""
|
||||
Return a logger for plugins.
|
||||
|
||||
Arguments:
|
||||
name: The name to use with `logging.getLogger`.
|
||||
|
||||
Returns:
|
||||
A logger configured to work well in MkDocs,
|
||||
prefixing each message with the plugin package name.
|
||||
|
||||
Example:
|
||||
```python
|
||||
from mkdocs.plugins import get_plugin_logger
|
||||
|
||||
log = get_plugin_logger(__name__)
|
||||
log.info("My plugin message")
|
||||
```
|
||||
"""
|
||||
logger = logging.getLogger(f"mkdocs.plugins.{name}")
|
||||
return PrefixedLogger(name.split(".", 1)[0], logger)
|
||||
Whitespace-only changes.
@@ -0,0 +1,36 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import abc
|
||||
from typing import TYPE_CHECKING, Iterable
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from mkdocs.structure.nav import Section
|
||||
|
||||
|
||||
class StructureItem(metaclass=abc.ABCMeta):
|
||||
"""An item in MkDocs structure - see concrete subclasses Section, Page or Link."""
|
||||
|
||||
@abc.abstractmethod
|
||||
def __init__(self):
|
||||
...
|
||||
|
||||
parent: Section | None = None
|
||||
"""The immediate parent of the item in the site navigation. `None` if it's at the top level."""
|
||||
|
||||
@property
|
||||
def is_top_level(self) -> bool:
|
||||
return self.parent is None
|
||||
|
||||
title: str | None
|
||||
is_section: bool = False
|
||||
is_page: bool = False
|
||||
is_link: bool = False
|
||||
|
||||
@property
|
||||
def ancestors(self) -> Iterable[StructureItem]:
|
||||
if self.parent is None:
|
||||
return []
|
||||
return [self.parent, *self.parent.ancestors]
|
||||
|
||||
def _indent_print(self, depth: int = 0) -> str:
|
||||
return (' ' * depth) + repr(self)
|
||||
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
@@ -0,0 +1,626 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import enum
|
||||
import fnmatch
|
||||
import logging
|
||||
import os
|
||||
import posixpath
|
||||
import shutil
|
||||
import warnings
|
||||
from functools import cached_property
|
||||
from pathlib import PurePath, PurePosixPath
|
||||
from typing import TYPE_CHECKING, Callable, Iterable, Iterator, Mapping, Sequence, overload
|
||||
from urllib.parse import quote as urlquote
|
||||
|
||||
import pathspec
|
||||
import pathspec.gitignore
|
||||
import pathspec.util
|
||||
|
||||
from mkdocs import utils
|
||||
|
||||
if TYPE_CHECKING:
|
||||
import jinja2.environment
|
||||
|
||||
from mkdocs.config.defaults import MkDocsConfig
|
||||
from mkdocs.structure.pages import Page
|
||||
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class InclusionLevel(enum.Enum):
|
||||
EXCLUDED = -3
|
||||
"""The file is excluded and will not be processed."""
|
||||
DRAFT = -2
|
||||
"""The file is excluded from the final site, but will still be populated during `mkdocs serve`."""
|
||||
NOT_IN_NAV = -1
|
||||
"""The file is part of the site, but doesn't produce nav warnings."""
|
||||
UNDEFINED = 0
|
||||
"""Still needs to be computed based on the config. If the config doesn't kick in, acts the same as `included`."""
|
||||
INCLUDED = 1
|
||||
"""The file is part of the site. Documentation pages that are omitted from the nav will produce warnings."""
|
||||
|
||||
def all(self):
|
||||
return True
|
||||
|
||||
def is_included(self):
|
||||
return self.value > self.DRAFT.value
|
||||
|
||||
def is_excluded(self):
|
||||
return self.value <= self.DRAFT.value
|
||||
|
||||
def is_in_serve(self):
|
||||
return self.value >= self.DRAFT.value
|
||||
|
||||
def is_in_nav(self):
|
||||
return self.value > self.NOT_IN_NAV.value
|
||||
|
||||
def is_not_in_nav(self):
|
||||
return self.value <= self.NOT_IN_NAV.value
|
||||
|
||||
|
||||
class Files:
|
||||
"""A collection of [File][mkdocs.structure.files.File] objects."""
|
||||
|
||||
def __init__(self, files: Iterable[File]) -> None:
|
||||
self._src_uris = {f.src_uri: f for f in files}
|
||||
|
||||
def __iter__(self) -> Iterator[File]:
|
||||
"""Iterate over the files within."""
|
||||
return iter(self._src_uris.values())
|
||||
|
||||
def __len__(self) -> int:
|
||||
"""The number of files within."""
|
||||
return len(self._src_uris)
|
||||
|
||||
def __contains__(self, path: str) -> bool:
|
||||
"""Soft-deprecated, prefer `get_file_from_path(path) is not None`."""
|
||||
return PurePath(path).as_posix() in self._src_uris
|
||||
|
||||
@property
|
||||
def src_paths(self) -> dict[str, File]:
|
||||
"""Soft-deprecated, prefer `src_uris`."""
|
||||
return {file.src_path: file for file in self}
|
||||
|
||||
@property
|
||||
def src_uris(self) -> Mapping[str, File]:
|
||||
"""
|
||||
A mapping containing every file, with the keys being their
|
||||
[`src_uri`][mkdocs.structure.files.File.src_uri].
|
||||
"""
|
||||
return self._src_uris
|
||||
|
||||
def get_file_from_path(self, path: str) -> File | None:
|
||||
"""Return a File instance with File.src_uri equal to path."""
|
||||
return self._src_uris.get(PurePath(path).as_posix())
|
||||
|
||||
def append(self, file: File) -> None:
|
||||
"""Add file to the Files collection."""
|
||||
if file.src_uri in self._src_uris:
|
||||
warnings.warn(
|
||||
"To replace an existing file, call `remove` before `append`.", DeprecationWarning
|
||||
)
|
||||
del self._src_uris[file.src_uri]
|
||||
self._src_uris[file.src_uri] = file
|
||||
|
||||
def remove(self, file: File) -> None:
|
||||
"""Remove file from Files collection."""
|
||||
try:
|
||||
del self._src_uris[file.src_uri]
|
||||
except KeyError:
|
||||
raise ValueError(f'{file.src_uri!r} not in collection')
|
||||
|
||||
def copy_static_files(
|
||||
self,
|
||||
dirty: bool = False,
|
||||
*,
|
||||
inclusion: Callable[[InclusionLevel], bool] = InclusionLevel.is_included,
|
||||
) -> None:
|
||||
"""Copy static files from source to destination."""
|
||||
for file in self:
|
||||
if not file.is_documentation_page() and inclusion(file.inclusion):
|
||||
file.copy_file(dirty)
|
||||
|
||||
def documentation_pages(
|
||||
self, *, inclusion: Callable[[InclusionLevel], bool] = InclusionLevel.is_included
|
||||
) -> Sequence[File]:
|
||||
"""Return iterable of all Markdown page file objects."""
|
||||
return [file for file in self if file.is_documentation_page() and inclusion(file.inclusion)]
|
||||
|
||||
def static_pages(self) -> Sequence[File]:
|
||||
"""Return iterable of all static page file objects."""
|
||||
return [file for file in self if file.is_static_page()]
|
||||
|
||||
def media_files(self) -> Sequence[File]:
|
||||
"""Return iterable of all file objects which are not documentation or static pages."""
|
||||
return [file for file in self if file.is_media_file()]
|
||||
|
||||
def javascript_files(self) -> Sequence[File]:
|
||||
"""Return iterable of all javascript file objects."""
|
||||
return [file for file in self if file.is_javascript()]
|
||||
|
||||
def css_files(self) -> Sequence[File]:
|
||||
"""Return iterable of all CSS file objects."""
|
||||
return [file for file in self if file.is_css()]
|
||||
|
||||
def add_files_from_theme(self, env: jinja2.Environment, config: MkDocsConfig) -> None:
|
||||
"""Retrieve static files from Jinja environment and add to collection."""
|
||||
|
||||
def filter(name):
|
||||
# '.*' filters dot files/dirs at root level whereas '*/.*' filters nested levels
|
||||
patterns = ['.*', '*/.*', '*.py', '*.pyc', '*.html', '*readme*', 'mkdocs_theme.yml']
|
||||
# Exclude translation files
|
||||
patterns.append("locales/*")
|
||||
patterns.extend(f'*{x}' for x in utils.markdown_extensions)
|
||||
patterns.extend(config.theme.static_templates)
|
||||
for pattern in patterns:
|
||||
if fnmatch.fnmatch(name.lower(), pattern):
|
||||
return False
|
||||
return True
|
||||
|
||||
for path in env.list_templates(filter_func=filter):
|
||||
# Theme files do not override docs_dir files
|
||||
if self.get_file_from_path(path) is None:
|
||||
for dir in config.theme.dirs:
|
||||
# Find the first theme dir which contains path
|
||||
if os.path.isfile(os.path.join(dir, path)):
|
||||
self.append(File(path, dir, config.site_dir, config.use_directory_urls))
|
||||
break
|
||||
|
||||
@property
|
||||
def _files(self) -> Iterable[File]:
|
||||
warnings.warn("Do not access Files._files.", DeprecationWarning)
|
||||
return self
|
||||
|
||||
@_files.setter
|
||||
def _files(self, value: Iterable[File]):
|
||||
warnings.warn("Do not access Files._files.", DeprecationWarning)
|
||||
self._src_uris = {f.src_uri: f for f in value}
|
||||
|
||||
|
||||
class File:
|
||||
"""
|
||||
A MkDocs File object.
|
||||
|
||||
It represents how the contents of one file should be populated in the destination site.
|
||||
|
||||
A file always has its `abs_dest_path` (obtained by joining `dest_dir` and `dest_path`),
|
||||
where the `dest_dir` is understood to be the *site* directory.
|
||||
|
||||
`content_bytes`/`content_string` (new in MkDocs 1.6) can always be used to obtain the file's
|
||||
content. But it may be backed by one of the two sources:
|
||||
|
||||
* A physical source file at `abs_src_path` (by default obtained by joining `src_dir` and
|
||||
`src_uri`). `src_dir` is understood to be the *docs* directory.
|
||||
|
||||
Then `content_bytes`/`content_string` will read the file at `abs_src_path`.
|
||||
|
||||
`src_dir` *should* be populated for real files and should be `None` for generated files.
|
||||
|
||||
* Since MkDocs 1.6 a file may alternatively be stored in memory - `content_string`/`content_bytes`.
|
||||
|
||||
Then `src_dir` and `abs_src_path` will remain `None`. `content_bytes`/`content_string` need
|
||||
to be written to, or populated through the `content` argument in the constructor.
|
||||
|
||||
But `src_uri` is still populated for such files as well! The virtual file pretends as if it
|
||||
originated from that path in the `docs` directory, and other values are derived.
|
||||
|
||||
For static files the file is just copied to the destination, and `dest_uri` equals `src_uri`.
|
||||
|
||||
For Markdown files (determined by the file extension in `src_uri`) the destination content
|
||||
will be the rendered content, and `dest_uri` will have the `.html` extension and some
|
||||
additional transformations to the path, based on `use_directory_urls`.
|
||||
"""
|
||||
|
||||
src_uri: str
|
||||
"""The pure path (always '/'-separated) of the source file relative to the source directory."""
|
||||
|
||||
use_directory_urls: bool
|
||||
"""Whether directory URLs ('foo/') should be used or not ('foo.html').
|
||||
|
||||
If `False`, a Markdown file is mapped to an HTML file of the same name (the file extension is
|
||||
changed to `.html`). If True, a Markdown file is mapped to an HTML index file (`index.html`)
|
||||
nested in a directory using the "name" of the file in `path`. Non-Markdown files retain their
|
||||
original path.
|
||||
"""
|
||||
|
||||
src_dir: str | None
|
||||
"""The OS path of the top-level directory that the source file originates from.
|
||||
|
||||
Assumed to be the *docs_dir*; not populated for generated files."""
|
||||
|
||||
dest_dir: str
|
||||
"""The OS path of the destination directory (top-level site_dir) that the file should be copied to."""
|
||||
|
||||
inclusion: InclusionLevel = InclusionLevel.UNDEFINED
|
||||
"""Whether the file will be excluded from the built site."""
|
||||
|
||||
generated_by: str | None = None
|
||||
"""If not None, indicates that a plugin generated this file on the fly.
|
||||
|
||||
The value is the plugin's entrypoint name and can be used to find the plugin by key in the PluginCollection."""
|
||||
|
||||
_content: str | bytes | None = None
|
||||
"""If set, the file's content will be read from here.
|
||||
|
||||
This logic is handled by `content_bytes`/`content_string`, which should be used instead of
|
||||
accessing this attribute."""
|
||||
|
||||
@property
|
||||
def src_path(self) -> str:
|
||||
"""Same as `src_uri` (and synchronized with it) but will use backslashes on Windows. Discouraged."""
|
||||
return os.path.normpath(self.src_uri)
|
||||
|
||||
@src_path.setter
|
||||
def src_path(self, value: str):
|
||||
self.src_uri = PurePath(value).as_posix()
|
||||
|
||||
@property
|
||||
def dest_path(self) -> str:
|
||||
"""Same as `dest_uri` (and synchronized with it) but will use backslashes on Windows. Discouraged."""
|
||||
return os.path.normpath(self.dest_uri)
|
||||
|
||||
@dest_path.setter
|
||||
def dest_path(self, value: str):
|
||||
self.dest_uri = PurePath(value).as_posix()
|
||||
|
||||
page: Page | None = None
|
||||
|
||||
@overload
|
||||
@classmethod
|
||||
def generated(
|
||||
cls,
|
||||
config: MkDocsConfig,
|
||||
src_uri: str,
|
||||
*,
|
||||
content: str | bytes,
|
||||
inclusion: InclusionLevel = InclusionLevel.UNDEFINED,
|
||||
) -> File:
|
||||
"""
|
||||
Create a virtual file backed by in-memory content.
|
||||
|
||||
It will pretend to be a file in the docs dir at `src_uri`.
|
||||
"""
|
||||
|
||||
@overload
|
||||
@classmethod
|
||||
def generated(
|
||||
cls,
|
||||
config: MkDocsConfig,
|
||||
src_uri: str,
|
||||
*,
|
||||
abs_src_path: str,
|
||||
inclusion: InclusionLevel = InclusionLevel.UNDEFINED,
|
||||
) -> File:
|
||||
"""
|
||||
Create a virtual file backed by a physical temporary file at `abs_src_path`.
|
||||
|
||||
It will pretend to be a file in the docs dir at `src_uri`.
|
||||
"""
|
||||
|
||||
@classmethod
|
||||
def generated(
|
||||
cls,
|
||||
config: MkDocsConfig,
|
||||
src_uri: str,
|
||||
*,
|
||||
content: str | bytes | None = None,
|
||||
abs_src_path: str | None = None,
|
||||
inclusion: InclusionLevel = InclusionLevel.UNDEFINED,
|
||||
) -> File:
|
||||
"""
|
||||
Create a virtual file, backed either by in-memory `content` or by a file at `abs_src_path`.
|
||||
|
||||
It will pretend to be a file in the docs dir at `src_uri`.
|
||||
"""
|
||||
if (content is None) == (abs_src_path is None):
|
||||
raise TypeError("File must have exactly one of 'content' or 'abs_src_path'")
|
||||
f = cls(
|
||||
src_uri,
|
||||
src_dir=None,
|
||||
dest_dir=config.site_dir,
|
||||
use_directory_urls=config.use_directory_urls,
|
||||
inclusion=inclusion,
|
||||
)
|
||||
f.generated_by = config.plugins._current_plugin or '<unknown>'
|
||||
f.abs_src_path = abs_src_path
|
||||
f._content = content
|
||||
return f
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
path: str,
|
||||
src_dir: str | None,
|
||||
dest_dir: str,
|
||||
use_directory_urls: bool,
|
||||
*,
|
||||
dest_uri: str | None = None,
|
||||
inclusion: InclusionLevel = InclusionLevel.UNDEFINED,
|
||||
) -> None:
|
||||
self.src_path = path
|
||||
self.src_dir = src_dir
|
||||
self.dest_dir = dest_dir
|
||||
self.use_directory_urls = use_directory_urls
|
||||
if dest_uri is not None:
|
||||
self.dest_uri = dest_uri
|
||||
self.inclusion = inclusion
|
||||
|
||||
def __repr__(self):
|
||||
return (
|
||||
f"{type(self).__name__}({self.src_uri!r}, src_dir={self.src_dir!r}, "
|
||||
f"dest_dir={self.dest_dir!r}, use_directory_urls={self.use_directory_urls!r}, "
|
||||
f"dest_uri={self.dest_uri!r}, inclusion={self.inclusion})"
|
||||
)
|
||||
|
||||
@utils.weak_property
|
||||
def edit_uri(self) -> str | None:
|
||||
"""
|
||||
A path relative to the source repository to use for the "edit" button.
|
||||
|
||||
Defaults to `src_uri` and can be overwritten.
|
||||
For generated files this should be set to `None`.
|
||||
"""
|
||||
return self.src_uri if self.generated_by is None else None
|
||||
|
||||
def _get_stem(self) -> str:
|
||||
"""Soft-deprecated, do not use."""
|
||||
filename = posixpath.basename(self.src_uri)
|
||||
stem, ext = posixpath.splitext(filename)
|
||||
return 'index' if stem == 'README' else stem
|
||||
|
||||
name = cached_property(_get_stem)
|
||||
"""Return the name of the file without its extension."""
|
||||
|
||||
def _get_dest_path(self, use_directory_urls: bool | None = None) -> str:
|
||||
"""Soft-deprecated, do not use."""
|
||||
if self.is_documentation_page():
|
||||
parent, filename = posixpath.split(self.src_uri)
|
||||
if use_directory_urls is None:
|
||||
use_directory_urls = self.use_directory_urls
|
||||
if not use_directory_urls or self.name == 'index':
|
||||
# index.md or README.md => index.html
|
||||
# foo.md => foo.html
|
||||
return posixpath.join(parent, self.name + '.html')
|
||||
else:
|
||||
# foo.md => foo/index.html
|
||||
return posixpath.join(parent, self.name, 'index.html')
|
||||
return self.src_uri
|
||||
|
||||
dest_uri = cached_property(_get_dest_path)
|
||||
"""The pure path (always '/'-separated) of the destination file relative to the destination directory."""
|
||||
|
||||
def _get_url(self, use_directory_urls: bool | None = None) -> str:
|
||||
"""Soft-deprecated, do not use."""
|
||||
url = self.dest_uri
|
||||
dirname, filename = posixpath.split(url)
|
||||
if use_directory_urls is None:
|
||||
use_directory_urls = self.use_directory_urls
|
||||
if use_directory_urls and filename == 'index.html':
|
||||
url = (dirname or '.') + '/'
|
||||
return urlquote(url)
|
||||
|
||||
url = cached_property(_get_url)
|
||||
"""The URI of the destination file relative to the destination directory as a string."""
|
||||
|
||||
@cached_property
|
||||
def abs_src_path(self) -> str | None:
|
||||
"""
|
||||
The absolute concrete path of the source file. Will use backslashes on Windows.
|
||||
|
||||
Note: do not use this path to read the file, prefer `content_bytes`/`content_string`.
|
||||
"""
|
||||
if self.src_dir is None:
|
||||
return None
|
||||
return os.path.normpath(os.path.join(self.src_dir, self.src_uri))
|
||||
|
||||
@cached_property
|
||||
def abs_dest_path(self) -> str:
|
||||
"""The absolute concrete path of the destination file. Will use backslashes on Windows."""
|
||||
return os.path.normpath(os.path.join(self.dest_dir, self.dest_uri))
|
||||
|
||||
def url_relative_to(self, other: File | str) -> str:
|
||||
"""Return url for file relative to other file."""
|
||||
return utils.get_relative_url(self.url, other.url if isinstance(other, File) else other)
|
||||
|
||||
@property
|
||||
def content_bytes(self) -> bytes:
|
||||
"""
|
||||
Get the content of this file as a bytestring.
|
||||
|
||||
May raise if backed by a real file (`abs_src_path`) if it cannot be read.
|
||||
|
||||
If used as a setter, it defines the content of the file, and `abs_src_path` becomes unset.
|
||||
"""
|
||||
content = self._content
|
||||
if content is None:
|
||||
assert self.abs_src_path is not None
|
||||
with open(self.abs_src_path, 'rb') as f:
|
||||
return f.read()
|
||||
if not isinstance(content, bytes):
|
||||
content = content.encode()
|
||||
return content
|
||||
|
||||
@content_bytes.setter
|
||||
def content_bytes(self, value: bytes):
|
||||
assert isinstance(value, bytes)
|
||||
self._content = value
|
||||
self.abs_src_path = None
|
||||
|
||||
@property
|
||||
def content_string(self) -> str:
|
||||
"""
|
||||
Get the content of this file as a string. Assumes UTF-8 encoding, may raise.
|
||||
|
||||
May also raise if backed by a real file (`abs_src_path`) if it cannot be read.
|
||||
|
||||
If used as a setter, it defines the content of the file, and `abs_src_path` becomes unset.
|
||||
"""
|
||||
content = self._content
|
||||
if content is None:
|
||||
assert self.abs_src_path is not None
|
||||
with open(self.abs_src_path, encoding='utf-8-sig', errors='strict') as f:
|
||||
return f.read()
|
||||
if not isinstance(content, str):
|
||||
content = content.decode('utf-8-sig', errors='strict')
|
||||
return content
|
||||
|
||||
@content_string.setter
|
||||
def content_string(self, value: str):
|
||||
assert isinstance(value, str)
|
||||
self._content = value
|
||||
self.abs_src_path = None
|
||||
|
||||
def copy_file(self, dirty: bool = False) -> None:
|
||||
"""Copy source file to destination, ensuring parent directories exist."""
|
||||
if dirty and not self.is_modified():
|
||||
log.debug(f"Skip copying unmodified file: '{self.src_uri}'")
|
||||
return
|
||||
log.debug(f"Copying media file: '{self.src_uri}'")
|
||||
output_path = self.abs_dest_path
|
||||
os.makedirs(os.path.dirname(output_path), exist_ok=True)
|
||||
content = self._content
|
||||
if content is None:
|
||||
assert self.abs_src_path is not None
|
||||
try:
|
||||
utils.copy_file(self.abs_src_path, output_path)
|
||||
except shutil.SameFileError:
|
||||
pass # Let plugins write directly into site_dir.
|
||||
elif isinstance(content, str):
|
||||
with open(output_path, 'w', encoding='utf-8') as output_file:
|
||||
output_file.write(content)
|
||||
else:
|
||||
with open(output_path, 'wb') as output_file:
|
||||
output_file.write(content)
|
||||
|
||||
def is_modified(self) -> bool:
|
||||
if self._content is not None:
|
||||
return True
|
||||
assert self.abs_src_path is not None
|
||||
if os.path.isfile(self.abs_dest_path):
|
||||
return os.path.getmtime(self.abs_dest_path) < os.path.getmtime(self.abs_src_path)
|
||||
return True
|
||||
|
||||
def is_documentation_page(self) -> bool:
|
||||
"""Return True if file is a Markdown page."""
|
||||
return utils.is_markdown_file(self.src_uri)
|
||||
|
||||
def is_static_page(self) -> bool:
|
||||
"""Return True if file is a static page (HTML, XML, JSON)."""
|
||||
return self.src_uri.endswith(('.html', '.htm', '.xml', '.json'))
|
||||
|
||||
def is_media_file(self) -> bool:
|
||||
"""Return True if file is not a documentation or static page."""
|
||||
return not (self.is_documentation_page() or self.is_static_page())
|
||||
|
||||
def is_javascript(self) -> bool:
|
||||
"""Return True if file is a JavaScript file."""
|
||||
return self.src_uri.endswith(('.js', '.javascript', '.mjs'))
|
||||
|
||||
def is_css(self) -> bool:
|
||||
"""Return True if file is a CSS file."""
|
||||
return self.src_uri.endswith('.css')
|
||||
|
||||
|
||||
_default_exclude = pathspec.gitignore.GitIgnoreSpec.from_lines(['.*', '/templates/'])
|
||||
|
||||
|
||||
def set_exclusions(files: Iterable[File], config: MkDocsConfig) -> None:
|
||||
"""Re-calculate which files are excluded, based on the patterns in the config."""
|
||||
exclude: pathspec.gitignore.GitIgnoreSpec | None = config.get('exclude_docs')
|
||||
exclude = _default_exclude + exclude if exclude else _default_exclude
|
||||
drafts: pathspec.gitignore.GitIgnoreSpec | None = config.get('draft_docs')
|
||||
nav_exclude: pathspec.gitignore.GitIgnoreSpec | None = config.get('not_in_nav')
|
||||
|
||||
for file in files:
|
||||
if file.inclusion == InclusionLevel.UNDEFINED:
|
||||
if exclude.match_file(file.src_uri):
|
||||
file.inclusion = InclusionLevel.EXCLUDED
|
||||
elif drafts and drafts.match_file(file.src_uri):
|
||||
file.inclusion = InclusionLevel.DRAFT
|
||||
elif nav_exclude and nav_exclude.match_file(file.src_uri):
|
||||
file.inclusion = InclusionLevel.NOT_IN_NAV
|
||||
else:
|
||||
file.inclusion = InclusionLevel.INCLUDED
|
||||
|
||||
|
||||
def get_files(config: MkDocsConfig) -> Files:
|
||||
"""Walk the `docs_dir` and return a Files collection."""
|
||||
files: list[File] = []
|
||||
conflicting_files: list[tuple[File, File]] = []
|
||||
for source_dir, dirnames, filenames in os.walk(config['docs_dir'], followlinks=True):
|
||||
relative_dir = os.path.relpath(source_dir, config['docs_dir'])
|
||||
dirnames.sort()
|
||||
filenames.sort(key=_file_sort_key)
|
||||
|
||||
files_by_dest: dict[str, File] = {}
|
||||
for filename in filenames:
|
||||
file = File(
|
||||
os.path.join(relative_dir, filename),
|
||||
config['docs_dir'],
|
||||
config['site_dir'],
|
||||
config['use_directory_urls'],
|
||||
)
|
||||
# Skip README.md if an index file also exists in dir (part 1)
|
||||
prev_file = files_by_dest.setdefault(file.dest_uri, file)
|
||||
if prev_file is not file:
|
||||
conflicting_files.append((prev_file, file))
|
||||
files.append(file)
|
||||
prev_file = file
|
||||
|
||||
set_exclusions(files, config)
|
||||
# Skip README.md if an index file also exists in dir (part 2)
|
||||
for a, b in conflicting_files:
|
||||
if b.inclusion.is_included():
|
||||
if a.inclusion.is_included():
|
||||
log.warning(
|
||||
f"Excluding '{a.src_uri}' from the site because it conflicts with '{b.src_uri}'."
|
||||
)
|
||||
try:
|
||||
files.remove(a)
|
||||
except ValueError:
|
||||
pass # Catching this to avoid errors if attempting to remove the same file twice.
|
||||
else:
|
||||
try:
|
||||
files.remove(b)
|
||||
except ValueError:
|
||||
pass
|
||||
|
||||
return Files(files)
|
||||
|
||||
|
||||
def file_sort_key(f: File, /):
|
||||
"""
|
||||
Replicates the sort order how `get_files` produces it - index first, directories last.
|
||||
|
||||
To sort a list of `File`, pass as the `key` argument to `sort`.
|
||||
"""
|
||||
parts = PurePosixPath(f.src_uri).parts
|
||||
if not parts:
|
||||
return ()
|
||||
return (parts[:-1], f.name != "index", parts[-1])
|
||||
|
||||
|
||||
def _file_sort_key(f: str):
|
||||
"""Always sort `index` or `README` as first filename in list. This works only on basenames of files."""
|
||||
return (os.path.splitext(f)[0] not in ('index', 'README'), f)
|
||||
|
||||
|
||||
def _sort_files(filenames: Iterable[str]) -> list[str]:
|
||||
"""Soft-deprecated, do not use."""
|
||||
return sorted(filenames, key=_file_sort_key)
|
||||
|
||||
|
||||
def _filter_paths(basename: str, path: str, is_dir: bool, exclude: Iterable[str]) -> bool:
|
||||
warnings.warn(
|
||||
"_filter_paths is not used since MkDocs 1.5 and will be removed soon.", DeprecationWarning
|
||||
)
|
||||
for item in exclude:
|
||||
# Items ending in '/' apply only to directories.
|
||||
if item.endswith('/') and not is_dir:
|
||||
continue
|
||||
# Items starting with '/' apply to the whole path.
|
||||
# In any other cases just the basename is used.
|
||||
match = path if item.startswith('/') else basename
|
||||
if fnmatch.fnmatch(match, item.strip('/')):
|
||||
return True
|
||||
return False
|
||||
@@ -0,0 +1,251 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import logging
|
||||
from typing import TYPE_CHECKING, Iterator, TypeVar
|
||||
from urllib.parse import urlsplit
|
||||
|
||||
from mkdocs.exceptions import BuildError
|
||||
from mkdocs.structure import StructureItem
|
||||
from mkdocs.structure.files import file_sort_key
|
||||
from mkdocs.structure.pages import Page, _AbsoluteLinksValidationValue
|
||||
from mkdocs.utils import nest_paths
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from mkdocs.config.defaults import MkDocsConfig
|
||||
from mkdocs.structure.files import Files
|
||||
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class Navigation:
|
||||
def __init__(self, items: list, pages: list[Page]) -> None:
|
||||
self.items = items # Nested List with full navigation of Sections, Pages, and Links.
|
||||
self.pages = pages # Flat List of subset of Pages in nav, in order.
|
||||
|
||||
self.homepage = None
|
||||
for page in pages:
|
||||
if page.is_homepage:
|
||||
self.homepage = page
|
||||
break
|
||||
|
||||
homepage: Page | None
|
||||
"""The [page][mkdocs.structure.pages.Page] object for the homepage of the site."""
|
||||
|
||||
pages: list[Page]
|
||||
"""A flat list of all [page][mkdocs.structure.pages.Page] objects contained in the navigation."""
|
||||
|
||||
def __str__(self) -> str:
|
||||
return '\n'.join(item._indent_print() for item in self)
|
||||
|
||||
def __iter__(self) -> Iterator:
|
||||
return iter(self.items)
|
||||
|
||||
def __len__(self) -> int:
|
||||
return len(self.items)
|
||||
|
||||
|
||||
class Section(StructureItem):
|
||||
def __init__(self, title: str, children: list[StructureItem]) -> None:
|
||||
self.title = title
|
||||
self.children = children
|
||||
|
||||
self.active = False
|
||||
|
||||
def __repr__(self):
|
||||
name = self.__class__.__name__
|
||||
return f"{name}(title={self.title!r})"
|
||||
|
||||
title: str
|
||||
"""The title of the section."""
|
||||
|
||||
children: list[StructureItem]
|
||||
"""An iterable of all child navigation objects. Children may include nested sections, pages and links."""
|
||||
|
||||
@property
|
||||
def active(self) -> bool:
|
||||
"""
|
||||
When `True`, indicates that a child page of this section is the current page and
|
||||
can be used to highlight the section as the currently viewed section. Defaults
|
||||
to `False`.
|
||||
"""
|
||||
return self.__active
|
||||
|
||||
@active.setter
|
||||
def active(self, value: bool):
|
||||
"""Set active status of section and ancestors."""
|
||||
self.__active = bool(value)
|
||||
if self.parent is not None:
|
||||
self.parent.active = bool(value)
|
||||
|
||||
is_section: bool = True
|
||||
"""Indicates that the navigation object is a "section" object. Always `True` for section objects."""
|
||||
|
||||
is_page: bool = False
|
||||
"""Indicates that the navigation object is a "page" object. Always `False` for section objects."""
|
||||
|
||||
is_link: bool = False
|
||||
"""Indicates that the navigation object is a "link" object. Always `False` for section objects."""
|
||||
|
||||
def _indent_print(self, depth: int = 0) -> str:
|
||||
ret = [super()._indent_print(depth)]
|
||||
for item in self.children:
|
||||
ret.append(item._indent_print(depth + 1))
|
||||
return '\n'.join(ret)
|
||||
|
||||
|
||||
class Link(StructureItem):
|
||||
def __init__(self, title: str, url: str):
|
||||
self.title = title
|
||||
self.url = url
|
||||
|
||||
def __repr__(self):
|
||||
name = self.__class__.__name__
|
||||
title = f"{self.title!r}" if self.title is not None else '[blank]'
|
||||
return f"{name}(title={title}, url={self.url!r})"
|
||||
|
||||
title: str
|
||||
"""The title of the link. This would generally be used as the label of the link."""
|
||||
|
||||
url: str
|
||||
"""The URL that the link points to. The URL should always be an absolute URLs and
|
||||
should not need to have `base_url` prepended."""
|
||||
|
||||
children: None = None
|
||||
"""Links do not contain children and the attribute is always `None`."""
|
||||
|
||||
active: bool = False
|
||||
"""External links cannot be "active" and the attribute is always `False`."""
|
||||
|
||||
is_section: bool = False
|
||||
"""Indicates that the navigation object is a "section" object. Always `False` for link objects."""
|
||||
|
||||
is_page: bool = False
|
||||
"""Indicates that the navigation object is a "page" object. Always `False` for link objects."""
|
||||
|
||||
is_link: bool = True
|
||||
"""Indicates that the navigation object is a "link" object. Always `True` for link objects."""
|
||||
|
||||
|
||||
def get_navigation(files: Files, config: MkDocsConfig) -> Navigation:
|
||||
"""Build site navigation from config and files."""
|
||||
documentation_pages = files.documentation_pages()
|
||||
nav_config = config['nav']
|
||||
if nav_config is None:
|
||||
documentation_pages = sorted(documentation_pages, key=file_sort_key)
|
||||
nav_config = nest_paths(f.src_uri for f in documentation_pages if f.inclusion.is_in_nav())
|
||||
items = _data_to_navigation(nav_config, files, config)
|
||||
if not isinstance(items, list):
|
||||
items = [items]
|
||||
|
||||
# Get only the pages from the navigation, ignoring any sections and links.
|
||||
pages = _get_by_type(items, Page)
|
||||
|
||||
# Include next, previous and parent links.
|
||||
_add_previous_and_next_links(pages)
|
||||
_add_parent_links(items)
|
||||
|
||||
missing_from_config = []
|
||||
for file in documentation_pages:
|
||||
if file.page is None:
|
||||
# Any documentation files not found in the nav should still have an associated page, so we
|
||||
# create them here. The Page object will automatically be assigned to `file.page` during
|
||||
# its creation (and this is the only way in which these page objects are accessible).
|
||||
Page(None, file, config)
|
||||
if file.inclusion.is_in_nav():
|
||||
missing_from_config.append(file.src_path)
|
||||
if missing_from_config:
|
||||
log.log(
|
||||
config.validation.nav.omitted_files,
|
||||
'The following pages exist in the docs directory, but are not '
|
||||
'included in the "nav" configuration:\n - ' + '\n - '.join(missing_from_config),
|
||||
)
|
||||
|
||||
links = _get_by_type(items, Link)
|
||||
for link in links:
|
||||
scheme, netloc, path, query, fragment = urlsplit(link.url)
|
||||
if scheme or netloc:
|
||||
log.debug(f"An external link to '{link.url}' is included in the 'nav' configuration.")
|
||||
elif (
|
||||
link.url.startswith('/')
|
||||
and config.validation.nav.absolute_links
|
||||
is not _AbsoluteLinksValidationValue.RELATIVE_TO_DOCS
|
||||
):
|
||||
log.log(
|
||||
config.validation.nav.absolute_links,
|
||||
f"An absolute path to '{link.url}' is included in the 'nav' "
|
||||
"configuration, which presumably points to an external resource.",
|
||||
)
|
||||
else:
|
||||
log.log(
|
||||
config.validation.nav.not_found,
|
||||
f"A reference to '{link.url}' is included in the 'nav' "
|
||||
"configuration, which is not found in the documentation files.",
|
||||
)
|
||||
return Navigation(items, pages)
|
||||
|
||||
|
||||
def _data_to_navigation(data, files: Files, config: MkDocsConfig):
|
||||
if isinstance(data, dict):
|
||||
return [
|
||||
_data_to_navigation((key, value), files, config)
|
||||
if isinstance(value, str)
|
||||
else Section(title=key, children=_data_to_navigation(value, files, config))
|
||||
for key, value in data.items()
|
||||
]
|
||||
elif isinstance(data, list):
|
||||
return [
|
||||
_data_to_navigation(item, files, config)[0]
|
||||
if isinstance(item, dict) and len(item) == 1
|
||||
else _data_to_navigation(item, files, config)
|
||||
for item in data
|
||||
]
|
||||
title, path = data if isinstance(data, tuple) else (None, data)
|
||||
lookup_path = path
|
||||
if (
|
||||
lookup_path.startswith('/')
|
||||
and config.validation.nav.absolute_links is _AbsoluteLinksValidationValue.RELATIVE_TO_DOCS
|
||||
):
|
||||
lookup_path = lookup_path.lstrip('/')
|
||||
if file := files.get_file_from_path(lookup_path):
|
||||
if file.inclusion.is_excluded():
|
||||
log.log(
|
||||
min(logging.INFO, config.validation.nav.not_found),
|
||||
f"A reference to '{file.src_path}' is included in the 'nav' "
|
||||
"configuration, but this file is excluded from the built site.",
|
||||
)
|
||||
page = file.page
|
||||
if page is not None:
|
||||
if not isinstance(page, Page):
|
||||
raise BuildError("A plugin has set File.page to a type other than Page.")
|
||||
return page
|
||||
return Page(title, file, config)
|
||||
return Link(title, path)
|
||||
|
||||
|
||||
T = TypeVar('T')
|
||||
|
||||
|
||||
def _get_by_type(nav, t: type[T]) -> list[T]:
|
||||
ret = []
|
||||
for item in nav:
|
||||
if isinstance(item, t):
|
||||
ret.append(item)
|
||||
if item.children:
|
||||
ret.extend(_get_by_type(item.children, t))
|
||||
return ret
|
||||
|
||||
|
||||
def _add_parent_links(nav) -> None:
|
||||
for item in nav:
|
||||
if item.is_section:
|
||||
for child in item.children:
|
||||
child.parent = item
|
||||
_add_parent_links(item.children)
|
||||
|
||||
|
||||
def _add_previous_and_next_links(pages: list[Page]) -> None:
|
||||
bookended = [None, *pages, None]
|
||||
zipped = zip(bookended[:-2], pages, bookended[2:])
|
||||
for page0, page1, page2 in zipped:
|
||||
page1.previous_page, page1.next_page = page0, page2
|
||||
@@ -0,0 +1,569 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import enum
|
||||
import logging
|
||||
import posixpath
|
||||
import warnings
|
||||
from typing import TYPE_CHECKING, Any, Callable, Iterator, MutableMapping, Sequence
|
||||
from urllib.parse import unquote as urlunquote
|
||||
from urllib.parse import urljoin, urlsplit, urlunsplit
|
||||
|
||||
import markdown
|
||||
import markdown.extensions.toc
|
||||
import markdown.htmlparser # type: ignore
|
||||
import markdown.postprocessors
|
||||
import markdown.treeprocessors
|
||||
from markdown.util import AMP_SUBSTITUTE
|
||||
|
||||
from mkdocs import utils
|
||||
from mkdocs.structure import StructureItem
|
||||
from mkdocs.structure.toc import get_toc
|
||||
from mkdocs.utils import _removesuffix, get_build_date, get_markdown_title, meta, weak_property
|
||||
from mkdocs.utils.rendering import get_heading_text
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from xml.etree import ElementTree as etree
|
||||
|
||||
from mkdocs.config.defaults import MkDocsConfig
|
||||
from mkdocs.structure.files import File, Files
|
||||
from mkdocs.structure.toc import TableOfContents
|
||||
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class Page(StructureItem):
|
||||
def __init__(self, title: str | None, file: File, config: MkDocsConfig) -> None:
|
||||
file.page = self
|
||||
self.file = file
|
||||
if title is not None:
|
||||
self.title = title
|
||||
|
||||
# Navigation attributes
|
||||
self.children = None
|
||||
self.previous_page = None
|
||||
self.next_page = None
|
||||
self.active = False
|
||||
|
||||
self.update_date: str = get_build_date()
|
||||
|
||||
self._set_canonical_url(config.get('site_url', None))
|
||||
self._set_edit_url(
|
||||
config.get('repo_url', None), config.get('edit_uri'), config.get('edit_uri_template')
|
||||
)
|
||||
|
||||
# Placeholders to be filled in later in the build process.
|
||||
self.markdown = None
|
||||
self._title_from_render: str | None = None
|
||||
self.content = None
|
||||
self.toc = [] # type: ignore
|
||||
self.meta = {}
|
||||
|
||||
def __eq__(self, other) -> bool:
|
||||
return (
|
||||
isinstance(other, self.__class__)
|
||||
and self.title == other.title
|
||||
and self.file == other.file
|
||||
)
|
||||
|
||||
def __repr__(self):
|
||||
name = self.__class__.__name__
|
||||
title = f"{self.title!r}" if self.title is not None else '[blank]'
|
||||
url = self.abs_url or self.file.url
|
||||
return f"{name}(title={title}, url={url!r})"
|
||||
|
||||
markdown: str | None
|
||||
"""The original Markdown content from the file."""
|
||||
|
||||
content: str | None
|
||||
"""The rendered Markdown as HTML, this is the contents of the documentation.
|
||||
|
||||
Populated after `.render()`."""
|
||||
|
||||
toc: TableOfContents
|
||||
"""An iterable object representing the Table of contents for a page. Each item in
|
||||
the `toc` is an [`AnchorLink`][mkdocs.structure.toc.AnchorLink]."""
|
||||
|
||||
meta: MutableMapping[str, Any]
|
||||
"""A mapping of the metadata included at the top of the markdown page."""
|
||||
|
||||
@property
|
||||
def url(self) -> str:
|
||||
"""The URL of the page relative to the MkDocs `site_dir`."""
|
||||
url = self.file.url
|
||||
if url in ('.', './'):
|
||||
return ''
|
||||
return url
|
||||
|
||||
file: File
|
||||
"""The documentation [`File`][mkdocs.structure.files.File] that the page is being rendered from."""
|
||||
|
||||
abs_url: str | None
|
||||
"""The absolute URL of the page from the server root as determined by the value
|
||||
assigned to the [site_url][] configuration setting. The value includes any
|
||||
subdirectory included in the `site_url`, but not the domain. [base_url][] should
|
||||
not be used with this variable."""
|
||||
|
||||
canonical_url: str | None
|
||||
"""The full, canonical URL to the current page as determined by the value assigned
|
||||
to the [site_url][] configuration setting. The value includes the domain and any
|
||||
subdirectory included in the `site_url`. [base_url][] should not be used with this
|
||||
variable."""
|
||||
|
||||
@property
|
||||
def active(self) -> bool:
|
||||
"""When `True`, indicates that this page is the currently viewed page. Defaults to `False`."""
|
||||
return self.__active
|
||||
|
||||
@active.setter
|
||||
def active(self, value: bool):
|
||||
"""Set active status of page and ancestors."""
|
||||
self.__active = bool(value)
|
||||
if self.parent is not None:
|
||||
self.parent.active = bool(value)
|
||||
|
||||
@property
|
||||
def is_index(self) -> bool:
|
||||
return self.file.name == 'index'
|
||||
|
||||
edit_url: str | None
|
||||
"""The full URL to the source page in the source repository. Typically used to
|
||||
provide a link to edit the source page. [base_url][] should not be used with this
|
||||
variable."""
|
||||
|
||||
@property
|
||||
def is_homepage(self) -> bool:
|
||||
"""Evaluates to `True` for the homepage of the site and `False` for all other pages."""
|
||||
return self.is_top_level and self.is_index and self.file.url in ('.', './', 'index.html')
|
||||
|
||||
previous_page: Page | None
|
||||
"""The [page][mkdocs.structure.pages.Page] object for the previous page or `None`.
|
||||
The value will be `None` if the current page is the first item in the site navigation
|
||||
or if the current page is not included in the navigation at all."""
|
||||
|
||||
next_page: Page | None
|
||||
"""The [page][mkdocs.structure.pages.Page] object for the next page or `None`.
|
||||
The value will be `None` if the current page is the last item in the site navigation
|
||||
or if the current page is not included in the navigation at all."""
|
||||
|
||||
children: None = None
|
||||
"""Pages do not contain children and the attribute is always `None`."""
|
||||
|
||||
is_section: bool = False
|
||||
"""Indicates that the navigation object is a "section" object. Always `False` for page objects."""
|
||||
|
||||
is_page: bool = True
|
||||
"""Indicates that the navigation object is a "page" object. Always `True` for page objects."""
|
||||
|
||||
is_link: bool = False
|
||||
"""Indicates that the navigation object is a "link" object. Always `False` for page objects."""
|
||||
|
||||
def _set_canonical_url(self, base: str | None) -> None:
|
||||
if base:
|
||||
if not base.endswith('/'):
|
||||
base += '/'
|
||||
self.canonical_url = canonical_url = urljoin(base, self.url)
|
||||
self.abs_url = urlsplit(canonical_url).path
|
||||
else:
|
||||
self.canonical_url = None
|
||||
self.abs_url = None
|
||||
|
||||
def _set_edit_url(
|
||||
self,
|
||||
repo_url: str | None,
|
||||
edit_uri: str | None = None,
|
||||
edit_uri_template: str | None = None,
|
||||
) -> None:
|
||||
if not edit_uri_template and not edit_uri:
|
||||
self.edit_url = None
|
||||
return
|
||||
src_uri = self.file.edit_uri
|
||||
if src_uri is None:
|
||||
self.edit_url = None
|
||||
return
|
||||
|
||||
if edit_uri_template:
|
||||
noext = posixpath.splitext(src_uri)[0]
|
||||
file_edit_uri = edit_uri_template.format(path=src_uri, path_noext=noext)
|
||||
else:
|
||||
assert edit_uri is not None and edit_uri.endswith('/')
|
||||
file_edit_uri = edit_uri + src_uri
|
||||
|
||||
if repo_url:
|
||||
# Ensure urljoin behavior is correct
|
||||
if not file_edit_uri.startswith(('?', '#')) and not repo_url.endswith('/'):
|
||||
repo_url += '/'
|
||||
else:
|
||||
try:
|
||||
parsed_url = urlsplit(file_edit_uri)
|
||||
if not parsed_url.scheme or not parsed_url.netloc:
|
||||
log.warning(
|
||||
f"edit_uri: {file_edit_uri!r} is not a valid URL, it should include the http:// (scheme)"
|
||||
)
|
||||
except ValueError as e:
|
||||
log.warning(f"edit_uri: {file_edit_uri!r} is not a valid URL: {e}")
|
||||
|
||||
self.edit_url = urljoin(repo_url or '', file_edit_uri)
|
||||
|
||||
def read_source(self, config: MkDocsConfig) -> None:
|
||||
source = config.plugins.on_page_read_source(page=self, config=config)
|
||||
if source is None:
|
||||
try:
|
||||
source = self.file.content_string
|
||||
except OSError:
|
||||
log.error(f'File not found: {self.file.src_path}')
|
||||
raise
|
||||
except ValueError:
|
||||
log.error(f'Encoding error reading file: {self.file.src_path}')
|
||||
raise
|
||||
|
||||
self.markdown, self.meta = meta.get_data(source)
|
||||
|
||||
def _set_title(self) -> None:
|
||||
warnings.warn(
|
||||
"_set_title is no longer used in MkDocs and will be removed soon.", DeprecationWarning
|
||||
)
|
||||
|
||||
@weak_property
|
||||
def title(self) -> str | None: # type: ignore[override]
|
||||
"""
|
||||
Returns the title for the current page.
|
||||
|
||||
Before calling `read_source()`, this value is empty. It can also be updated by `render()`.
|
||||
|
||||
Checks these in order and uses the first that returns a valid title:
|
||||
|
||||
- value provided on init (passed in from config)
|
||||
- value of metadata 'title'
|
||||
- content of the first H1 in Markdown content
|
||||
- convert filename to title
|
||||
"""
|
||||
if self.markdown is None:
|
||||
return None
|
||||
|
||||
if 'title' in self.meta:
|
||||
return self.meta['title']
|
||||
|
||||
if self._title_from_render:
|
||||
return self._title_from_render
|
||||
elif self.content is None: # Preserve legacy behavior only for edge cases in plugins.
|
||||
title_from_md = get_markdown_title(self.markdown)
|
||||
if title_from_md is not None:
|
||||
return title_from_md
|
||||
|
||||
if self.is_homepage:
|
||||
return 'Home'
|
||||
|
||||
title = self.file.name.replace('-', ' ').replace('_', ' ')
|
||||
# Capitalize if the filename was all lowercase, otherwise leave it as-is.
|
||||
if title.lower() == title:
|
||||
title = title.capitalize()
|
||||
return title
|
||||
|
||||
def render(self, config: MkDocsConfig, files: Files) -> None:
|
||||
"""Convert the Markdown source file to HTML as per the config."""
|
||||
if self.markdown is None:
|
||||
raise RuntimeError("`markdown` field hasn't been set (via `read_source`)")
|
||||
|
||||
md = markdown.Markdown(
|
||||
extensions=config['markdown_extensions'],
|
||||
extension_configs=config['mdx_configs'] or {},
|
||||
)
|
||||
|
||||
raw_html_ext = _RawHTMLPreprocessor()
|
||||
raw_html_ext._register(md)
|
||||
|
||||
extract_anchors_ext = _ExtractAnchorsTreeprocessor(self.file, files, config)
|
||||
extract_anchors_ext._register(md)
|
||||
|
||||
relative_path_ext = _RelativePathTreeprocessor(self.file, files, config)
|
||||
relative_path_ext._register(md)
|
||||
|
||||
extract_title_ext = _ExtractTitleTreeprocessor()
|
||||
extract_title_ext._register(md)
|
||||
|
||||
self.content = md.convert(self.markdown)
|
||||
self.toc = get_toc(getattr(md, 'toc_tokens', []))
|
||||
self._title_from_render = extract_title_ext.title
|
||||
self.present_anchor_ids = (
|
||||
extract_anchors_ext.present_anchor_ids | raw_html_ext.present_anchor_ids
|
||||
)
|
||||
if log.getEffectiveLevel() > logging.DEBUG:
|
||||
self.links_to_anchors = relative_path_ext.links_to_anchors
|
||||
|
||||
present_anchor_ids: set[str] | None = None
|
||||
"""Anchor IDs that this page contains (can be linked to in this page)."""
|
||||
|
||||
links_to_anchors: dict[File, dict[str, str]] | None = None
|
||||
"""Links to anchors in other files that this page contains.
|
||||
|
||||
The structure is: `{file_that_is_linked_to: {'anchor': 'original_link/to/some_file.md#anchor'}}`.
|
||||
Populated after `.render()`. Populated only if `validation: {anchors: info}` (or greater) is set.
|
||||
"""
|
||||
|
||||
def validate_anchor_links(self, *, files: Files, log_level: int) -> None:
|
||||
if not self.links_to_anchors:
|
||||
return
|
||||
for to_file, links in self.links_to_anchors.items():
|
||||
for anchor, original_link in links.items():
|
||||
page = to_file.page
|
||||
if page is None:
|
||||
continue
|
||||
if page.present_anchor_ids is None: # Page was somehow not rendered.
|
||||
continue
|
||||
if anchor in page.present_anchor_ids:
|
||||
continue
|
||||
context = ""
|
||||
if to_file == self.file:
|
||||
problem = "there is no such anchor on this page"
|
||||
if anchor.startswith('fnref:'):
|
||||
context = " This seems to be a footnote that is never referenced."
|
||||
else:
|
||||
problem = f"the doc '{to_file.src_uri}' does not contain an anchor '#{anchor}'"
|
||||
log.log(
|
||||
log_level,
|
||||
f"Doc file '{self.file.src_uri}' contains a link '{original_link}', but {problem}.{context}",
|
||||
)
|
||||
|
||||
|
||||
class _ExtractAnchorsTreeprocessor(markdown.treeprocessors.Treeprocessor):
|
||||
def __init__(self, file: File, files: Files, config: MkDocsConfig) -> None:
|
||||
self.present_anchor_ids: set[str] = set()
|
||||
|
||||
def run(self, root: etree.Element) -> None:
|
||||
add = self.present_anchor_ids.add
|
||||
for element in root.iter():
|
||||
if anchor := element.get('id'):
|
||||
add(anchor)
|
||||
if element.tag == 'a':
|
||||
if anchor := element.get('name'):
|
||||
add(anchor)
|
||||
|
||||
def _register(self, md: markdown.Markdown) -> None:
|
||||
md.treeprocessors.register(self, "mkdocs_extract_anchors", priority=5) # Same as 'toc'.
|
||||
|
||||
|
||||
class _RelativePathTreeprocessor(markdown.treeprocessors.Treeprocessor):
|
||||
def __init__(self, file: File, files: Files, config: MkDocsConfig) -> None:
|
||||
self.file = file
|
||||
self.files = files
|
||||
self.config = config
|
||||
self.links_to_anchors: dict[File, dict[str, str]] = {}
|
||||
|
||||
def run(self, root: etree.Element) -> etree.Element:
|
||||
"""
|
||||
Update urls on anchors and images to make them relative.
|
||||
|
||||
Iterates through the full document tree looking for specific
|
||||
tags and then makes them relative based on the site navigation
|
||||
"""
|
||||
for element in root.iter():
|
||||
if element.tag == 'a':
|
||||
key = 'href'
|
||||
elif element.tag == 'img':
|
||||
key = 'src'
|
||||
else:
|
||||
continue
|
||||
|
||||
url = element.get(key)
|
||||
assert url is not None
|
||||
new_url = self.path_to_url(url)
|
||||
element.set(key, new_url)
|
||||
|
||||
return root
|
||||
|
||||
@classmethod
|
||||
def _target_uri(cls, src_path: str, dest_path: str) -> str:
|
||||
return posixpath.normpath(
|
||||
posixpath.join(posixpath.dirname(src_path), dest_path).lstrip('/')
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def _possible_target_uris(
|
||||
cls, file: File, path: str, use_directory_urls: bool, suggest_absolute: bool = False
|
||||
) -> Iterator[str]:
|
||||
"""First yields the resolved file uri for the link, then proceeds to yield guesses for possible mistakes."""
|
||||
target_uri = cls._target_uri(file.src_uri, path)
|
||||
yield target_uri
|
||||
|
||||
if posixpath.normpath(path) == '.':
|
||||
# Explicitly link to current file.
|
||||
yield file.src_uri
|
||||
return
|
||||
tried = {target_uri}
|
||||
|
||||
prefixes = [target_uri, cls._target_uri(file.url, path)]
|
||||
if prefixes[0] == prefixes[1]:
|
||||
prefixes.pop()
|
||||
|
||||
suffixes: list[Callable[[str], str]] = []
|
||||
if use_directory_urls:
|
||||
suffixes.append(lambda p: p)
|
||||
if not posixpath.splitext(target_uri)[-1]:
|
||||
suffixes.append(lambda p: posixpath.join(p, 'index.md'))
|
||||
suffixes.append(lambda p: posixpath.join(p, 'README.md'))
|
||||
if (
|
||||
not target_uri.endswith('.')
|
||||
and not path.endswith('.md')
|
||||
and (use_directory_urls or not path.endswith('/'))
|
||||
):
|
||||
suffixes.append(lambda p: _removesuffix(p, '.html') + '.md')
|
||||
|
||||
for pref in prefixes:
|
||||
for suf in suffixes:
|
||||
guess = posixpath.normpath(suf(pref))
|
||||
if guess not in tried and not guess.startswith('../'):
|
||||
yield guess
|
||||
tried.add(guess)
|
||||
|
||||
def path_to_url(self, url: str) -> str:
|
||||
scheme, netloc, path, query, anchor = urlsplit(url)
|
||||
|
||||
absolute_link = None
|
||||
warning_level, warning = 0, ''
|
||||
|
||||
# Ignore URLs unless they are a relative link to a source file.
|
||||
if scheme or netloc: # External link.
|
||||
return url
|
||||
elif url.startswith(('/', '\\')): # Absolute link.
|
||||
absolute_link = self.config.validation.links.absolute_links
|
||||
if absolute_link is not _AbsoluteLinksValidationValue.RELATIVE_TO_DOCS:
|
||||
warning_level = absolute_link
|
||||
warning = f"Doc file '{self.file.src_uri}' contains an absolute link '{url}', it was left as is."
|
||||
elif AMP_SUBSTITUTE in url: # AMP_SUBSTITUTE is used internally by Markdown only for email.
|
||||
return url
|
||||
elif not path: # Self-link containing only query or anchor.
|
||||
if anchor:
|
||||
# Register that the page links to itself with an anchor.
|
||||
self.links_to_anchors.setdefault(self.file, {}).setdefault(anchor, url)
|
||||
return url
|
||||
|
||||
path = urlunquote(path)
|
||||
# Determine the filepath of the target.
|
||||
possible_target_uris = self._possible_target_uris(
|
||||
self.file, path, self.config.use_directory_urls
|
||||
)
|
||||
|
||||
if warning:
|
||||
# For absolute path (already has a warning), the primary lookup path should be preserved as a tip option.
|
||||
target_uri = url
|
||||
target_file = None
|
||||
else:
|
||||
# Validate that the target exists in files collection.
|
||||
target_uri = next(possible_target_uris)
|
||||
target_file = self.files.get_file_from_path(target_uri)
|
||||
|
||||
if target_file is None and not warning:
|
||||
# Primary lookup path had no match, definitely produce a warning, just choose which one.
|
||||
if not posixpath.splitext(path)[-1] and absolute_link is None:
|
||||
# No '.' in the last part of a path indicates path does not point to a file.
|
||||
warning_level = self.config.validation.links.unrecognized_links
|
||||
warning = (
|
||||
f"Doc file '{self.file.src_uri}' contains an unrecognized relative link '{url}', "
|
||||
f"it was left as is."
|
||||
)
|
||||
else:
|
||||
target = f" '{target_uri}'" if target_uri != url.lstrip('/') else ""
|
||||
warning_level = self.config.validation.links.not_found
|
||||
warning = (
|
||||
f"Doc file '{self.file.src_uri}' contains a link '{url}', "
|
||||
f"but the target{target} is not found among documentation files."
|
||||
)
|
||||
|
||||
if warning:
|
||||
if self.file.inclusion.is_excluded():
|
||||
warning_level = min(logging.INFO, warning_level)
|
||||
|
||||
# There was no match, so try to guess what other file could've been intended.
|
||||
if warning_level > logging.DEBUG:
|
||||
suggest_url = ''
|
||||
for path in possible_target_uris:
|
||||
if self.files.get_file_from_path(path) is not None:
|
||||
if anchor and path == self.file.src_uri:
|
||||
path = ''
|
||||
elif absolute_link is _AbsoluteLinksValidationValue.RELATIVE_TO_DOCS:
|
||||
path = '/' + path
|
||||
else:
|
||||
path = utils.get_relative_url(path, self.file.src_uri)
|
||||
suggest_url = urlunsplit(('', '', path, query, anchor))
|
||||
break
|
||||
else:
|
||||
if '@' in url and '.' in url and '/' not in url:
|
||||
suggest_url = f'mailto:{url}'
|
||||
if suggest_url:
|
||||
warning += f" Did you mean '{suggest_url}'?"
|
||||
log.log(warning_level, warning)
|
||||
return url
|
||||
|
||||
assert target_uri is not None
|
||||
assert target_file is not None
|
||||
|
||||
if anchor:
|
||||
# Register that this page links to the target file with an anchor.
|
||||
self.links_to_anchors.setdefault(target_file, {}).setdefault(anchor, url)
|
||||
|
||||
if target_file.inclusion.is_excluded():
|
||||
if self.file.inclusion.is_excluded():
|
||||
warning_level = logging.DEBUG
|
||||
else:
|
||||
warning_level = min(logging.INFO, self.config.validation.links.not_found)
|
||||
warning = (
|
||||
f"Doc file '{self.file.src_uri}' contains a link to "
|
||||
f"'{target_uri}' which is excluded from the built site."
|
||||
)
|
||||
log.log(warning_level, warning)
|
||||
path = utils.get_relative_url(target_file.url, self.file.url)
|
||||
return urlunsplit(('', '', path, query, anchor))
|
||||
|
||||
def _register(self, md: markdown.Markdown) -> None:
|
||||
md.treeprocessors.register(self, "relpath", 0)
|
||||
|
||||
|
||||
class _RawHTMLPreprocessor(markdown.preprocessors.Preprocessor):
|
||||
def __init__(self) -> None:
|
||||
super().__init__()
|
||||
self.present_anchor_ids: set[str] = set()
|
||||
|
||||
def run(self, lines: list[str]) -> list[str]:
|
||||
parser = _HTMLHandler()
|
||||
parser.feed('\n'.join(lines))
|
||||
parser.close()
|
||||
self.present_anchor_ids = parser.present_anchor_ids
|
||||
return lines
|
||||
|
||||
def _register(self, md: markdown.Markdown) -> None:
|
||||
md.preprocessors.register(
|
||||
self, "mkdocs_raw_html", priority=21 # Right before 'html_block'.
|
||||
)
|
||||
|
||||
|
||||
class _HTMLHandler(markdown.htmlparser.htmlparser.HTMLParser): # type: ignore[name-defined]
|
||||
def __init__(self) -> None:
|
||||
super().__init__()
|
||||
self.present_anchor_ids: set[str] = set()
|
||||
|
||||
def handle_starttag(self, tag: str, attrs: Sequence[tuple[str, str]]) -> None:
|
||||
for k, v in attrs:
|
||||
if k == 'id' or (k == 'name' and tag == 'a'):
|
||||
self.present_anchor_ids.add(v)
|
||||
return super().handle_starttag(tag, attrs)
|
||||
|
||||
|
||||
class _ExtractTitleTreeprocessor(markdown.treeprocessors.Treeprocessor):
|
||||
title: str | None = None
|
||||
md: markdown.Markdown
|
||||
|
||||
def run(self, root: etree.Element) -> etree.Element:
|
||||
for el in root:
|
||||
if el.tag == 'h1':
|
||||
self.title = get_heading_text(el, self.md)
|
||||
break
|
||||
return root
|
||||
|
||||
def _register(self, md: markdown.Markdown) -> None:
|
||||
self.md = md
|
||||
md.treeprocessors.register(self, "mkdocs_extract_title", priority=1) # Close to the end.
|
||||
|
||||
|
||||
class _AbsoluteLinksValidationValue(enum.IntEnum):
|
||||
RELATIVE_TO_DOCS = -1
|
||||
@@ -0,0 +1,80 @@
|
||||
"""
|
||||
Deals with generating the per-page table of contents.
|
||||
|
||||
For the sake of simplicity we use the Python-Markdown `toc` extension to
|
||||
generate a list of dicts for each toc item, and then store it as AnchorLinks to
|
||||
maintain compatibility with older versions of MkDocs.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Iterable, Iterator, TypedDict
|
||||
|
||||
|
||||
class _TocToken(TypedDict):
|
||||
level: int
|
||||
id: str
|
||||
name: str
|
||||
children: list[_TocToken]
|
||||
|
||||
|
||||
def get_toc(toc_tokens: list[_TocToken]) -> TableOfContents:
|
||||
toc = [_parse_toc_token(i) for i in toc_tokens]
|
||||
# For the table of contents, always mark the first element as active
|
||||
if len(toc):
|
||||
toc[0].active = True # type: ignore[attr-defined]
|
||||
return TableOfContents(toc)
|
||||
|
||||
|
||||
class AnchorLink:
|
||||
"""A single entry in the table of contents."""
|
||||
|
||||
def __init__(self, title: str, id: str, level: int) -> None:
|
||||
self.title, self.id, self.level = title, id, level
|
||||
self.children = []
|
||||
|
||||
title: str
|
||||
"""The text of the item, as HTML."""
|
||||
|
||||
@property
|
||||
def url(self) -> str:
|
||||
"""The hash fragment of a URL pointing to the item."""
|
||||
return '#' + self.id
|
||||
|
||||
level: int
|
||||
"""The zero-based level of the item."""
|
||||
|
||||
children: list[AnchorLink]
|
||||
"""An iterable of any child items."""
|
||||
|
||||
def __str__(self) -> str:
|
||||
return self.indent_print()
|
||||
|
||||
def indent_print(self, depth: int = 0) -> str:
|
||||
indent = ' ' * depth
|
||||
ret = f'{indent}{self.title} - {self.url}\n'
|
||||
for item in self.children:
|
||||
ret += item.indent_print(depth + 1)
|
||||
return ret
|
||||
|
||||
|
||||
class TableOfContents(Iterable[AnchorLink]):
|
||||
"""Represents the table of contents for a given page."""
|
||||
|
||||
def __init__(self, items: list[AnchorLink]) -> None:
|
||||
self.items = items
|
||||
|
||||
def __iter__(self) -> Iterator[AnchorLink]:
|
||||
return iter(self.items)
|
||||
|
||||
def __len__(self) -> int:
|
||||
return len(self.items)
|
||||
|
||||
def __str__(self) -> str:
|
||||
return ''.join(str(item) for item in self)
|
||||
|
||||
|
||||
def _parse_toc_token(token: _TocToken) -> AnchorLink:
|
||||
anchor = AnchorLink(token['name'], token['id'], token['level'])
|
||||
for i in token['children']:
|
||||
anchor.children.append(_parse_toc_token(i))
|
||||
return anchor
|
||||
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
|
||||
{%- for file in pages -%}
|
||||
{% if not file.page.is_link and (file.page.abs_url or file.page.canonical_url) %}
|
||||
<url>
|
||||
<loc>{% if file.page.canonical_url %}{{ file.page.canonical_url|e }}{% else %}{{ file.page.abs_url|e }}{% endif %}</loc>
|
||||
{% if file.page.update_date %}<lastmod>{{file.page.update_date}}</lastmod>{% endif %}
|
||||
</url>
|
||||
{%- endif -%}
|
||||
{% endfor %}
|
||||
</urlset>
|
||||
@@ -0,0 +1,166 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import logging
|
||||
import os
|
||||
import warnings
|
||||
from typing import Any, Collection, MutableMapping
|
||||
|
||||
import jinja2
|
||||
import yaml
|
||||
|
||||
try:
|
||||
from yaml import CSafeLoader as SafeLoader
|
||||
except ImportError: # pragma: no cover
|
||||
from yaml import SafeLoader # type: ignore
|
||||
|
||||
from mkdocs import localization, utils
|
||||
from mkdocs.config.base import ValidationError
|
||||
from mkdocs.utils import templates
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class Theme(MutableMapping[str, Any]):
|
||||
"""
|
||||
A Theme object.
|
||||
|
||||
Args:
|
||||
name: The name of the theme as defined by its entrypoint.
|
||||
custom_dir: User defined directory for custom templates.
|
||||
static_templates: A list of templates to render as static pages.
|
||||
|
||||
All other keywords are passed as-is and made available as a key/value mapping.
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
name: str | None = None,
|
||||
*,
|
||||
custom_dir: str | None = None,
|
||||
static_templates: Collection[str] = (),
|
||||
locale: str | None = None,
|
||||
**user_config,
|
||||
) -> None:
|
||||
self.name = name
|
||||
self._custom_dir = custom_dir
|
||||
_vars: dict[str, Any] = {'name': name, 'locale': 'en'}
|
||||
self.__vars = _vars
|
||||
|
||||
# MkDocs provided static templates are always included
|
||||
package_dir = os.path.abspath(os.path.dirname(__file__))
|
||||
mkdocs_templates = os.path.join(package_dir, 'templates')
|
||||
self.static_templates = set(os.listdir(mkdocs_templates))
|
||||
|
||||
# Build self.dirs from various sources in order of precedence
|
||||
self.dirs = []
|
||||
|
||||
if custom_dir is not None:
|
||||
self.dirs.append(custom_dir)
|
||||
|
||||
if name:
|
||||
self._load_theme_config(name)
|
||||
|
||||
# Include templates provided directly by MkDocs (outside any theme)
|
||||
self.dirs.append(mkdocs_templates)
|
||||
|
||||
# Handle remaining user configs. Override theme configs (if set)
|
||||
self.static_templates.update(static_templates)
|
||||
_vars.update(user_config)
|
||||
|
||||
# Validate locale and convert to Locale object
|
||||
if locale is None:
|
||||
locale = _vars['locale']
|
||||
_vars['locale'] = localization.parse_locale(locale)
|
||||
|
||||
name: str | None
|
||||
|
||||
@property
|
||||
def locale(self) -> localization.Locale:
|
||||
return self['locale']
|
||||
|
||||
@property
|
||||
def custom_dir(self) -> str | None:
|
||||
return self._custom_dir
|
||||
|
||||
@property
|
||||
def _vars(self) -> dict[str, Any]:
|
||||
warnings.warn(
|
||||
"Do not access Theme._vars, instead access the keys of Theme directly.",
|
||||
DeprecationWarning,
|
||||
)
|
||||
return self.__vars
|
||||
|
||||
dirs: list[str]
|
||||
|
||||
static_templates: set[str]
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return "{}(name={!r}, dirs={!r}, static_templates={!r}, {})".format(
|
||||
self.__class__.__name__,
|
||||
self.name,
|
||||
self.dirs,
|
||||
self.static_templates,
|
||||
', '.join(f'{k}={v!r}' for k, v in self.items()),
|
||||
)
|
||||
|
||||
def __getitem__(self, key: str) -> Any:
|
||||
return self.__vars[key]
|
||||
|
||||
def __setitem__(self, key: str, value):
|
||||
self.__vars[key] = value
|
||||
|
||||
def __delitem__(self, key: str):
|
||||
del self.__vars[key]
|
||||
|
||||
def __contains__(self, item: object) -> bool:
|
||||
return item in self.__vars
|
||||
|
||||
def __len__(self):
|
||||
return len(self.__vars)
|
||||
|
||||
def __iter__(self):
|
||||
return iter(self.__vars)
|
||||
|
||||
def _load_theme_config(self, name: str) -> None:
|
||||
"""Recursively load theme and any parent themes."""
|
||||
theme_dir = utils.get_theme_dir(name)
|
||||
utils.get_themes.cache_clear()
|
||||
self.dirs.append(theme_dir)
|
||||
|
||||
try:
|
||||
file_path = os.path.join(theme_dir, 'mkdocs_theme.yml')
|
||||
with open(file_path, 'rb') as f:
|
||||
theme_config = yaml.load(f, SafeLoader)
|
||||
except OSError as e:
|
||||
log.debug(e)
|
||||
raise ValidationError(
|
||||
f"The theme '{name}' does not appear to have a configuration file. "
|
||||
f"Please upgrade to a current version of the theme."
|
||||
)
|
||||
|
||||
if theme_config is None:
|
||||
theme_config = {}
|
||||
|
||||
log.debug(f"Loaded theme configuration for '{name}' from '{file_path}': {theme_config}")
|
||||
|
||||
if parent_theme := theme_config.pop('extends', None):
|
||||
themes = utils.get_theme_names()
|
||||
if parent_theme not in themes:
|
||||
raise ValidationError(
|
||||
f"The theme '{name}' inherits from '{parent_theme}', which does not appear to be installed. "
|
||||
f"The available installed themes are: {', '.join(themes)}"
|
||||
)
|
||||
self._load_theme_config(parent_theme)
|
||||
|
||||
self.static_templates.update(theme_config.pop('static_templates', []))
|
||||
self.__vars.update(theme_config)
|
||||
|
||||
def get_env(self) -> jinja2.Environment:
|
||||
"""Return a Jinja environment for the theme."""
|
||||
loader = jinja2.FileSystemLoader(self.dirs)
|
||||
# No autoreload because editing a template in the middle of a build is not useful.
|
||||
env = jinja2.Environment(loader=loader, auto_reload=False)
|
||||
env.filters['url'] = templates.url_filter
|
||||
env.filters['script_tag'] = templates.script_tag_filter
|
||||
localization.install_translations(env, self.locale, self.dirs)
|
||||
return env
|
||||
Whitespace-only changes.
BIN
Binary file not shown.
@@ -0,0 +1,12 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
<div class="row-fluid">
|
||||
<div id="main-content" class="span12">
|
||||
<h1 id="404-page-not-found" style="text-align: center">404</h1>
|
||||
<p style="text-align: center"><strong>{% trans %}Page not found{% endtrans %}</strong></p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
||||
Whitespace-only changes.
BIN
Binary file not shown.
@@ -0,0 +1,251 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="{{ config.theme.locale|default('en') }}" data-bs-theme="{{ config.theme.color_mode }}">
|
||||
<head>
|
||||
{%- block site_meta %}
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
{% if page and page.is_homepage %}<meta name="description" content="{{ config.site_description }}">{% endif %}
|
||||
{% if config.site_author %}<meta name="author" content="{{ config.site_author }}">{% endif %}
|
||||
{% if page and page.canonical_url %}<link rel="canonical" href="{{ page.canonical_url }}">{% endif %}
|
||||
{% if config.site_favicon %}<link rel="shortcut icon" href="{{ config.site_favicon|url }}">
|
||||
{% else %}<link rel="shortcut icon" href="{{ 'img/favicon.ico'|url }}">{% endif %}
|
||||
{%- endblock %}
|
||||
|
||||
{%- block htmltitle %}
|
||||
<title>{% if page and page.title and not page.is_homepage %}{{ page.title }} - {% endif %}{{ config.site_name }}</title>
|
||||
{%- endblock %}
|
||||
|
||||
{%- block styles %}
|
||||
<link href="{{ 'css/bootstrap.min.css'|url }}" rel="stylesheet">
|
||||
<link href="{{ 'css/fontawesome.min.css'|url }}" rel="stylesheet">
|
||||
<link href="{{ 'css/brands.min.css'|url }}" rel="stylesheet">
|
||||
<link href="{{ 'css/solid.min.css'|url }}" rel="stylesheet">
|
||||
<link href="{{ 'css/v4-font-face.min.css'|url }}" rel="stylesheet">
|
||||
<link href="{{ 'css/base.css'|url }}" rel="stylesheet">
|
||||
{%- if config.theme.highlightjs %}
|
||||
<link id="hljs-light" rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.8.0/styles/{{ config.theme.hljs_style }}.min.css" {% if config.theme.color_mode != "light" %}disabled{% endif %}>
|
||||
<link id="hljs-dark" rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.8.0/styles/{{ config.theme.hljs_style_dark }}.min.css" {% if config.theme.color_mode != "dark" %}disabled{% endif %}>
|
||||
{%- endif %}
|
||||
{%- for path in config.extra_css %}
|
||||
<link href="{{ path|url }}" rel="stylesheet">
|
||||
{%- endfor %}
|
||||
{%- endblock %}
|
||||
|
||||
{%- block libs %}
|
||||
{%- if config.theme.highlightjs %}
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.8.0/highlight.min.js"></script>
|
||||
{%- for lang in config.theme.hljs_languages %}
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.8.0/languages/{{lang}}.min.js"></script>
|
||||
{%- endfor %}
|
||||
<script>hljs.highlightAll();</script>
|
||||
{%- endif %}
|
||||
{%- endblock %}
|
||||
|
||||
{%- block analytics %}
|
||||
{%- if config.theme.analytics.gtag %}
|
||||
<script async src="https://www.googletagmanager.com/gtag/js?id={{ config.theme.analytics.gtag }}"></script>
|
||||
<script>
|
||||
window.dataLayer = window.dataLayer || [];
|
||||
function gtag(){dataLayer.push(arguments);}
|
||||
gtag('js', new Date());
|
||||
|
||||
gtag('config', {{ config.theme.analytics.gtag|tojson }});
|
||||
</script>
|
||||
{%- elif config.google_analytics %}
|
||||
<script>
|
||||
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
|
||||
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
|
||||
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
|
||||
})(window,document,'script','https://www.google-analytics.com/analytics.js','ga');
|
||||
|
||||
ga('create', {{ config.google_analytics[0]|tojson }}, {{ config.google_analytics[1]|tojson }});
|
||||
ga('send', 'pageview');
|
||||
</script>
|
||||
{%- endif %}
|
||||
{%- endblock %}
|
||||
|
||||
{%- block extrahead %} {% endblock %}
|
||||
</head>
|
||||
|
||||
<body{% if page and page.is_homepage %} class="homepage"{% endif %}>
|
||||
<div class="navbar fixed-top navbar-expand-lg navbar-{% if config.theme.nav_style == "light" %}light{% else %}dark{% endif %} bg-{{ config.theme.nav_style }}">
|
||||
<div class="container">
|
||||
|
||||
{%- block site_name %}
|
||||
<a class="navbar-brand" href="{{ nav.homepage.url|url }}">{{ config.site_name }}</a>
|
||||
{%- endblock %}
|
||||
|
||||
{%- if nav|length>1 or (page and (page.next_page or page.previous_page)) or config.repo_url %}
|
||||
<!-- Expander button -->
|
||||
<button type="button" class="navbar-toggler" data-bs-toggle="collapse" data-bs-target="#navbar-collapse" aria-controls="navbar-collapse" aria-expanded="false" aria-label="Toggle navigation">
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
{%- endif %}
|
||||
|
||||
<!-- Expanded navigation -->
|
||||
<div id="navbar-collapse" class="navbar-collapse collapse">
|
||||
{%- block site_nav %}
|
||||
{%- if nav|length>1 %}
|
||||
<!-- Main navigation -->
|
||||
<ul class="nav navbar-nav">
|
||||
{%- for nav_item in nav %}
|
||||
{%- if nav_item.children %}
|
||||
<li class="nav-item dropdown">
|
||||
<a href="#" class="nav-link dropdown-toggle{% if nav_item.active %} active" aria-current="page{% endif %}" role="button" data-bs-toggle="dropdown" aria-expanded="false">{{ nav_item.title }}</a>
|
||||
<ul class="dropdown-menu">
|
||||
{%- for nav_item in nav_item.children %}
|
||||
{% include "nav-sub.html" %}
|
||||
{%- endfor %}
|
||||
</ul>
|
||||
</li>
|
||||
{%- else %}
|
||||
<li class="nav-item">
|
||||
<a href="{{ nav_item.url|url }}" class="nav-link{% if nav_item.active %} active" aria-current="page{% endif %}">{{ nav_item.title }}</a>
|
||||
</li>
|
||||
{%- endif %}
|
||||
{%- endfor %}
|
||||
</ul>
|
||||
{%- endif %}
|
||||
{%- endblock %}
|
||||
|
||||
<ul class="nav navbar-nav ms-md-auto">
|
||||
{%- block search_button %}
|
||||
{%- if 'search' in config.plugins %}
|
||||
<li class="nav-item">
|
||||
<a href="#" class="nav-link" data-bs-toggle="modal" data-bs-target="#mkdocs_search_modal">
|
||||
<i class="fa fa-search"></i> {% trans %}Search{% endtrans %}
|
||||
</a>
|
||||
</li>
|
||||
{%- endif %}
|
||||
{%- endblock %}
|
||||
|
||||
{%- block next_prev %}
|
||||
{%- if page and (page.next_page or page.previous_page) %}
|
||||
<li class="nav-item">
|
||||
<a rel="prev" {% if page.previous_page %}href="{{ page.previous_page.url|url }}" class="nav-link"{% else %}class="nav-link disabled"{% endif %}>
|
||||
<i class="fa fa-arrow-left"></i> {% trans %}Previous{% endtrans %}
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a rel="next" {% if page.next_page %}href="{{ page.next_page.url|url }}" class="nav-link"{% else %}class="nav-link disabled"{% endif %}>
|
||||
{% trans %}Next{% endtrans %} <i class="fa fa-arrow-right"></i>
|
||||
</a>
|
||||
</li>
|
||||
{%- endif %}
|
||||
{%- endblock %}
|
||||
|
||||
{%- block repo %}
|
||||
{%- if page and page.edit_url %}
|
||||
<li class="nav-item">
|
||||
<a href="{{ page.edit_url }}" class="nav-link">
|
||||
{%- if config.repo_name == 'GitHub' -%}
|
||||
<i class="fa-brands fa-github"></i> {% trans repo_name=config.repo_name %}Edit on {{ repo_name }}{% endtrans %}
|
||||
{%- elif config.repo_name == 'Bitbucket' -%}
|
||||
<i class="fa-brands fa-bitbucket"></i> {% trans repo_name=config.repo_name %}Edit on {{ repo_name }}{% endtrans %}
|
||||
{%- elif config.repo_name == 'GitLab' -%}
|
||||
<i class="fa-brands fa-gitlab"></i> {% trans repo_name=config.repo_name %}Edit on {{ repo_name }}{% endtrans %}
|
||||
{%- elif config.repo_name -%}
|
||||
{% trans repo_name=config.repo_name%}Edit on {{ repo_name }}{% endtrans %}
|
||||
{% else %}
|
||||
{% trans repo_name=config.repo_name%}Edit{% endtrans %}
|
||||
{%- endif -%}
|
||||
</a>
|
||||
</li>
|
||||
{%- elif config.repo_url %}
|
||||
<li class="nav-item">
|
||||
<a href="{{ config.repo_url }}" class="nav-link">
|
||||
{%- if config.repo_name == 'GitHub' -%}
|
||||
<i class="fa-brands fa-github"></i> {{ config.repo_name }}
|
||||
{%- elif config.repo_name == 'Bitbucket' -%}
|
||||
<i class="fa-brands fa-bitbucket"></i> {{ config.repo_name }}
|
||||
{%- elif config.repo_name == 'GitLab' -%}
|
||||
<i class="fa-brands fa-gitlab"></i> {{ config.repo_name }}
|
||||
{%- else -%}
|
||||
{{ config.repo_name }}
|
||||
{%- endif -%}
|
||||
</a>
|
||||
</li>
|
||||
{%- endif %}
|
||||
{%- endblock %}
|
||||
{%- if config.theme.user_color_mode_toggle %}
|
||||
<li class="nav-item dropdown">
|
||||
<button id="theme-menu" aria-expanded="false" data-bs-toggle="dropdown" data-bs-display="static" aria-label="Toggle theme" class="nav-link dropdown-toggle">
|
||||
<i class="fa-solid fa-circle-half-stroke fa-fw"></i>
|
||||
<span class="d-lg-none ms-2">Toggle theme</span>
|
||||
</button>
|
||||
<ul class="dropdown-menu dropdown-menu-end">
|
||||
<li>
|
||||
<button class="dropdown-item d-flex align-items-center" data-bs-theme-value="light" aria-pressed="{% if config.theme.color_mode == 'light' %}true{% else %}false{% endif %}">
|
||||
<i class="fa-solid fa-sun fa-fw"></i>
|
||||
<span class="ms-2">Light</span>
|
||||
<i class="fa-solid fa-check ms-auto{% if config.theme.color_mode != 'light' %} d-none{% endif %}"></i>
|
||||
</button>
|
||||
</li>
|
||||
<li>
|
||||
<button class="dropdown-item d-flex align-items-center" data-bs-theme-value="dark" aria-pressed="{% if config.theme.color_mode == 'dark' %}true{% else %}false{% endif %}">
|
||||
<i class="fa-solid fa-moon fa-fw"></i>
|
||||
<span class="ms-2">Dark</span>
|
||||
<i class="fa-solid fa-check ms-auto{% if config.theme.color_mode != 'dark' %} d-none{% endif %}"></i>
|
||||
</button>
|
||||
</li>
|
||||
<li>
|
||||
<button class="dropdown-item d-flex align-items-center" data-bs-theme-value="auto" aria-pressed="{% if config.theme.color_mode == 'auto' %}true{% else %}false{% endif %}">
|
||||
<i class="fa-solid fa-circle-half-stroke fa-fw"></i>
|
||||
<span class="ms-2">Auto</span>
|
||||
<i class="fa-solid fa-check ms-auto{% if config.theme.color_mode != 'auto' %} d-none{% endif %}"></i>
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
{%- endif %}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{%- if config.theme.color_mode != "light" or config.theme.user_color_mode_toggle %}
|
||||
<script src="{{ 'js/darkmode.js'|url }}"></script>
|
||||
{%- endif %}
|
||||
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
{%- block content %}
|
||||
<div class="col-md-3">{% include "toc.html" %}</div>
|
||||
<div class="col-md-9" role="main">{% include "content.html" %}</div>
|
||||
{%- endblock %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<footer class="col-md-12">
|
||||
{%- block footer %}
|
||||
<hr>
|
||||
{%- if config.copyright %}
|
||||
<p>{{ config.copyright }}</p>
|
||||
{%- endif %}
|
||||
<p>{% trans mkdocs_link='<a href="https://www.mkdocs.org/">MkDocs</a>' %}Documentation built with {{ mkdocs_link }}.{% endtrans %}</p>
|
||||
{%- endblock %}
|
||||
</footer>
|
||||
|
||||
{%- block scripts %}
|
||||
<script src="{{ 'js/bootstrap.bundle.min.js'|url }}"></script>
|
||||
<script>
|
||||
var base_url = {{ base_url|tojson }},
|
||||
shortcuts = {{ config.theme.shortcuts|tojson }};
|
||||
</script>
|
||||
<script src="{{ 'js/base.js'|url }}"></script>
|
||||
{%- for script in config.extra_javascript %}
|
||||
{{ script|script_tag }}
|
||||
{%- endfor %}
|
||||
{%- endblock %}
|
||||
|
||||
{% if 'search' in config.plugins %}{%- include "search-modal.html" %}{% endif %}
|
||||
{%- include "keyboard-modal.html" %}
|
||||
|
||||
</body>
|
||||
</html>
|
||||
{% if page and page.is_homepage %}
|
||||
<!--
|
||||
MkDocs version : {{ mkdocs_version }}
|
||||
Build Date UTC : {{ build_date_utc }}
|
||||
-->
|
||||
{% endif %}
|
||||
@@ -0,0 +1,9 @@
|
||||
{% if page.meta.source %}
|
||||
<div class="source-links">
|
||||
{% for filename in page.meta.source %}
|
||||
<span class="label label-primary">{{ filename }}</span>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{{ page.content }}
|
||||
@@ -0,0 +1,366 @@
|
||||
html {
|
||||
/* The nav header is 3.5rem high, plus 20px for the margin-top of the
|
||||
main container. */
|
||||
scroll-padding-top: calc(3.5rem + 20px);
|
||||
}
|
||||
|
||||
/* Replacement for `body { background-attachment: fixed; }`, which has
|
||||
performance issues when scrolling on large displays. See #1394. */
|
||||
body::before {
|
||||
content: ' ';
|
||||
position: fixed;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
top: 0;
|
||||
left: 0;
|
||||
background-color: var(--bs-body-bg);
|
||||
background: url(../img/grid.png) repeat-x;
|
||||
will-change: transform;
|
||||
z-index: -1;
|
||||
}
|
||||
|
||||
body > .container {
|
||||
margin-top: 20px;
|
||||
min-height: 400px;
|
||||
}
|
||||
|
||||
.navbar.fixed-top {
|
||||
position: -webkit-sticky;
|
||||
position: sticky;
|
||||
}
|
||||
|
||||
.source-links {
|
||||
float: right;
|
||||
}
|
||||
|
||||
.col-md-9 img {
|
||||
max-width: 100%;
|
||||
display: inline-block;
|
||||
padding: 4px;
|
||||
line-height: 1.428571429;
|
||||
background-color: var(--bs-secondary-bg-subtle);
|
||||
border: 1px solid var(--bs-secondary-border-subtle);
|
||||
border-radius: 4px;
|
||||
margin: 20px auto 30px auto;
|
||||
}
|
||||
|
||||
h1 {
|
||||
color: inherit;
|
||||
font-weight: 400;
|
||||
font-size: 42px;
|
||||
}
|
||||
|
||||
h2, h3, h4, h5, h6 {
|
||||
color: inherit;
|
||||
font-weight: 300;
|
||||
}
|
||||
|
||||
hr {
|
||||
border-top: 1px solid #aaa;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
pre, .rst-content tt {
|
||||
max-width: 100%;
|
||||
background-color: var(--bs-body-bg);
|
||||
border: solid 1px var(--bs-border-color);
|
||||
color: var(--bs-body-color);
|
||||
overflow-x: auto;
|
||||
}
|
||||
|
||||
code.code-large, .rst-content tt.code-large {
|
||||
font-size: 90%;
|
||||
}
|
||||
|
||||
code {
|
||||
padding: 2px 5px;
|
||||
background-color: rgba(var(--bs-body-bg-rgb), 0.75);
|
||||
border: solid 1px var(--bs-border-color);
|
||||
color: var(--bs-body-color);
|
||||
white-space: pre-wrap;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
|
||||
pre code {
|
||||
display: block;
|
||||
border: none;
|
||||
white-space: pre;
|
||||
word-wrap: normal;
|
||||
font-family: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
kbd {
|
||||
padding: 2px 4px;
|
||||
font-size: 90%;
|
||||
color: var(--bs-secondary-text-emphasis);
|
||||
background-color: var(--bs-secondary-bg-subtle);
|
||||
border-radius: 3px;
|
||||
-webkit-box-shadow: inset 0 -1px 0 rgba(0,0,0,.25);
|
||||
box-shadow: inset 0 -1px 0 rgba(0,0,0,.25);
|
||||
}
|
||||
|
||||
a code {
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
a:hover code, a:focus code {
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
footer {
|
||||
margin-top: 30px;
|
||||
margin-bottom: 10px;
|
||||
text-align: center;
|
||||
font-weight: 200;
|
||||
}
|
||||
|
||||
.modal-dialog {
|
||||
margin-top: 60px;
|
||||
}
|
||||
|
||||
/*
|
||||
* Side navigation
|
||||
*
|
||||
* Scrollspy and affixed enhanced navigation to highlight sections and secondary
|
||||
* sections of docs content.
|
||||
*/
|
||||
|
||||
.bs-sidebar.affix {
|
||||
position: -webkit-sticky;
|
||||
position: sticky;
|
||||
/* The nav header is 3.5rem high, plus 20px for the margin-top of the
|
||||
main container. */
|
||||
top: calc(3.5rem + 20px);
|
||||
}
|
||||
|
||||
.bs-sidebar.card {
|
||||
padding: 0;
|
||||
max-height: 90%;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
/* Toggle (vertically flip) sidebar collapse icon */
|
||||
.bs-sidebar .navbar-toggler span {
|
||||
-moz-transform: scale(1, -1);
|
||||
-webkit-transform: scale(1, -1);
|
||||
-o-transform: scale(1, -1);
|
||||
-ms-transform: scale(1, -1);
|
||||
transform: scale(1, -1);
|
||||
}
|
||||
|
||||
.bs-sidebar .navbar-toggler.collapsed span {
|
||||
-moz-transform: scale(1, 1);
|
||||
-webkit-transform: scale(1, 1);
|
||||
-o-transform: scale(1, 1);
|
||||
-ms-transform: scale(1, 1);
|
||||
transform: scale(1, 1);
|
||||
}
|
||||
|
||||
/* First level of nav */
|
||||
.bs-sidebar > .navbar-collapse > .nav {
|
||||
padding-top: 10px;
|
||||
padding-bottom: 10px;
|
||||
border-radius: 5px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
/* All levels of nav */
|
||||
.bs-sidebar .nav > li > a {
|
||||
display: block;
|
||||
padding: 5px 20px;
|
||||
z-index: 1;
|
||||
}
|
||||
.bs-sidebar .nav > li > a:hover,
|
||||
.bs-sidebar .nav > li > a:focus {
|
||||
text-decoration: none;
|
||||
border-right: 1px solid;
|
||||
}
|
||||
.bs-sidebar .nav > li > a.active,
|
||||
.bs-sidebar .nav > li > a.active:hover,
|
||||
.bs-sidebar .nav > li > a.active:focus {
|
||||
font-weight: bold;
|
||||
background-color: transparent;
|
||||
border-right: 1px solid;
|
||||
}
|
||||
|
||||
.bs-sidebar .nav .nav .nav {
|
||||
margin-left: 1em;
|
||||
}
|
||||
|
||||
.bs-sidebar .nav > li > a {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.bs-sidebar .nav .nav > li > a {
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.headerlink {
|
||||
font-family: FontAwesome;
|
||||
font-size: 14px;
|
||||
display: none;
|
||||
padding-left: .5em;
|
||||
text-decoration: none;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
h1:hover .headerlink, h2:hover .headerlink, h3:hover .headerlink, h4:hover .headerlink, h5:hover .headerlink, h6:hover .headerlink {
|
||||
display:inline-block;
|
||||
}
|
||||
|
||||
blockquote {
|
||||
padding-left: 10px;
|
||||
border-left: 4px solid #e6e6e6;
|
||||
}
|
||||
|
||||
.admonition, details {
|
||||
padding: 15px;
|
||||
margin-bottom: 20px;
|
||||
border: 1px solid transparent;
|
||||
border-radius: 4px;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.admonition.note, details.note {
|
||||
color: var(--bs-primary-text-emphasis);
|
||||
background-color: var(--bs-primary-bg-subtle);
|
||||
border-color: var(--bs-primary-border-subtle);
|
||||
}
|
||||
|
||||
.admonition.note h1, .admonition.note h2, .admonition.note h3,
|
||||
.admonition.note h4, .admonition.note h5, .admonition.note h6,
|
||||
details.note h1, details.note h2, details.note h3,
|
||||
details.note h4, details.note h5, details.note h6 {
|
||||
color: var(--bs-primary-text-emphasis);
|
||||
}
|
||||
|
||||
.admonition.info, details.info {
|
||||
color: var(--bs-info-text-emphasis);
|
||||
background-color: var(--bs-info-bg-subtle);
|
||||
border-color: var(--bs-info-border-subtle);
|
||||
}
|
||||
|
||||
.admonition.info h1, .admonition.info h2, .admonition.info h3,
|
||||
.admonition.info h4, .admonition.info h5, .admonition.info h6,
|
||||
details.info h1, details.info h2, details.info h3,
|
||||
details.info h4, details.info h5, details.info h6 {
|
||||
color: var(--bs-info-text-emphasis);
|
||||
}
|
||||
|
||||
.admonition.warning, details.warning {
|
||||
color: var(--bs-warning-text-emphasis);
|
||||
background-color: var(--bs-warning-bg-subtle);
|
||||
border-color: var(--bs-warning-border-subtle);
|
||||
}
|
||||
|
||||
.admonition.warning h1, .admonition.warning h2, .admonition.warning h3,
|
||||
.admonition.warning h4, .admonition.warning h5, .admonition.warning h6,
|
||||
details.warning h1, details.warning h2, details.warning h3,
|
||||
details.warning h4, details.warning h5, details.warning h6 {
|
||||
color: var(--bs-warning-text-emphasis);
|
||||
}
|
||||
|
||||
.admonition.danger, details.danger {
|
||||
color: var(--bs-danger-text-emphasis);
|
||||
background-color: var(--bs-danger-bg-subtle);
|
||||
border-color: var(--bs-danger-border-subtle);
|
||||
}
|
||||
|
||||
.admonition.danger h1, .admonition.danger h2, .admonition.danger h3,
|
||||
.admonition.danger h4, .admonition.danger h5, .admonition.danger h6,
|
||||
details.danger h1, details.danger h2, details.danger h3,
|
||||
details.danger h4, details.danger h5, details.danger h6 {
|
||||
color: var(--bs-danger-text-emphasis);
|
||||
}
|
||||
|
||||
.admonition, details {
|
||||
color: var(--bs-light-text-emphasis);
|
||||
background-color: var(--bs-light-bg-subtle);
|
||||
border-color: var(--bs-light-border-subtle);
|
||||
}
|
||||
|
||||
.admonition h1, .admonition h2, .admonition h3,
|
||||
.admonition h4, .admonition h5, .admonition h6,
|
||||
details h1, details h2, details h3,
|
||||
details h4, details h5, details h6 {
|
||||
color: var(--bs-light-text-emphasis);
|
||||
}
|
||||
|
||||
.admonition-title, summary {
|
||||
font-weight: bold;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.admonition>p:last-child, details>p:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
@media (max-width: 991.98px) {
|
||||
.navbar-collapse.show {
|
||||
overflow-y: auto;
|
||||
max-height: calc(100vh - 3.5rem);
|
||||
}
|
||||
}
|
||||
|
||||
.dropdown-item.open {
|
||||
color: var(--bs-dropdown-link-active-color);
|
||||
background-color: var(--bs-dropdown-link-active-bg);
|
||||
}
|
||||
|
||||
.dropdown-submenu > .dropdown-menu {
|
||||
margin: 0 0 0 1.5rem;
|
||||
padding: 0;
|
||||
border-width: 0;
|
||||
}
|
||||
|
||||
.dropdown-submenu > a::after {
|
||||
display: block;
|
||||
content: " ";
|
||||
float: right;
|
||||
width: 0;
|
||||
height: 0;
|
||||
border-color: transparent;
|
||||
border-style: solid;
|
||||
border-width: 5px 0 5px 5px;
|
||||
border-left-color: var(--bs-dropdown-link-active-color);
|
||||
margin-top: 5px;
|
||||
margin-right: -10px;
|
||||
}
|
||||
|
||||
.dropdown-submenu:hover > a::after {
|
||||
border-left-color: var(--bs-dropdown-link-active-color);
|
||||
}
|
||||
|
||||
@media (min-width: 992px) {
|
||||
.dropdown-menu {
|
||||
overflow-y: auto;
|
||||
max-height: calc(100vh - 3.5rem);
|
||||
}
|
||||
|
||||
.dropdown-submenu {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.dropdown-submenu > .dropdown-menu {
|
||||
position: fixed !important;
|
||||
margin-top: -9px;
|
||||
margin-left: -2px;
|
||||
border-width: 1px;
|
||||
padding: 0.5rem 0;
|
||||
}
|
||||
|
||||
.dropdown-submenu.pull-left {
|
||||
float: none;
|
||||
}
|
||||
|
||||
.dropdown-submenu.pull-left > .dropdown-menu {
|
||||
left: -100%;
|
||||
margin-left: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
@media print {
|
||||
/* Remove sidebar when print */
|
||||
.col-md-3 { display: none; }
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
@charset "UTF-8";/*!
|
||||
* Bootswatch v5.3.2 (https://bootswatch.com)
|
||||
* Theme: cerulean
|
||||
* Copyright 2012-2023 Thomas Park
|
||||
* Licensed under MIT
|
||||
* Based on Bootstrap
|
||||
*//*!
|
||||
* Bootstrap v5.3.2 (https://getbootstrap.com/)
|
||||
* Copyright 2011-2023 The Bootstrap Authors
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||||
*/:root,[data-bs-theme=light]{--bs-blue:#033c73;--bs-indigo:#6610f2;--bs-purple:#6f42c1;--bs-pink:#e83e8c;--bs-red:#c71c22;--bs-orange:#fd7e14;--bs-yellow:#dd5600;--bs-green:#73a839;--bs-teal:#20c997;--bs-cyan:#2fa4e7;--bs-black:#000;--bs-white:#fff;--bs-gray:#868e96;--bs-gray-dark:#343a40;--bs-gray-100:#f8f9fa;--bs-gray-200:#e9ecef;--bs-gray-300:#dee2e6;--bs-gray-400:#ced4da;--bs-gray-500:#adb5bd;--bs-gray-600:#868e96;--bs-gray-700:#495057;--bs-gray-800:#343a40;--bs-gray-900:#212529;--bs-primary:#2fa4e7;--bs-secondary:#e9ecef;--bs-success:#73a839;--bs-info:#033c73;--bs-warning:#dd5600;--bs-danger:#c71c22;--bs-light:#f8f9fa;--bs-dark:#343a40;--bs-primary-rgb:47,164,231;--bs-secondary-rgb:233,236,239;--bs-success-rgb:115,168,57;--bs-info-rgb:3,60,115;--bs-warning-rgb:221,86,0;--bs-danger-rgb:199,28,34;--bs-light-rgb:248,249,250;--bs-dark-rgb:52,58,64;--bs-primary-text-emphasis:#13425c;--bs-secondary-text-emphasis:#5d5e60;--bs-success-text-emphasis:#2e4317;--bs-info-text-emphasis:#01182e;--bs-warning-text-emphasis:#582200;--bs-danger-text-emphasis:#500b0e;--bs-light-text-emphasis:#495057;--bs-dark-text-emphasis:#495057;--bs-primary-bg-subtle:#d5edfa;--bs-secondary-bg-subtle:#fbfbfc;--bs-success-bg-subtle:#e3eed7;--bs-info-bg-subtle:#cdd8e3;--bs-warning-bg-subtle:#f8ddcc;--bs-danger-bg-subtle:#f4d2d3;--bs-light-bg-subtle:#fcfcfd;--bs-dark-bg-subtle:#ced4da;--bs-primary-border-subtle:#acdbf5;--bs-secondary-border-subtle:#f6f7f9;--bs-success-border-subtle:#c7dcb0;--bs-info-border-subtle:#9ab1c7;--bs-warning-border-subtle:#f1bb99;--bs-danger-border-subtle:#e9a4a7;--bs-light-border-subtle:#e9ecef;--bs-dark-border-subtle:#adb5bd;--bs-white-rgb:255,255,255;--bs-black-rgb:0,0,0;--bs-font-sans-serif:system-ui,-apple-system,"Segoe UI",Roboto,"Helvetica Neue","Noto Sans","Liberation Sans",Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";--bs-font-monospace:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;--bs-gradient:linear-gradient(180deg, rgba(255, 255, 255, 0.15), rgba(255, 255, 255, 0));--bs-body-font-family:var(--bs-font-sans-serif);--bs-body-font-size:1rem;--bs-body-font-weight:400;--bs-body-line-height:1.5;--bs-body-color:#495057;--bs-body-color-rgb:73,80,87;--bs-body-bg:#fff;--bs-body-bg-rgb:255,255,255;--bs-emphasis-color:#000;--bs-emphasis-color-rgb:0,0,0;--bs-secondary-color:rgba(73, 80, 87, 0.75);--bs-secondary-color-rgb:73,80,87;--bs-secondary-bg:#e9ecef;--bs-secondary-bg-rgb:233,236,239;--bs-tertiary-color:rgba(73, 80, 87, 0.5);--bs-tertiary-color-rgb:73,80,87;--bs-tertiary-bg:#f8f9fa;--bs-tertiary-bg-rgb:248,249,250;--bs-heading-color:#2fa4e7;--bs-link-color:#2fa4e7;--bs-link-color-rgb:47,164,231;--bs-link-decoration:underline;--bs-link-hover-color:#2683b9;--bs-link-hover-color-rgb:38,131,185;--bs-code-color:#e83e8c;--bs-highlight-color:#495057;--bs-highlight-bg:#f8ddcc;--bs-border-width:1px;--bs-border-style:solid;--bs-border-color:#dee2e6;--bs-border-color-translucent:rgba(0, 0, 0, 0.175);--bs-border-radius:0.375rem;--bs-border-radius-sm:0.25rem;--bs-border-radius-lg:0.5rem;--bs-border-radius-xl:1rem;--bs-border-radius-xxl:2rem;--bs-border-radius-2xl:var(--bs-border-radius-xxl);--bs-border-radius-pill:50rem;--bs-box-shadow:0 0.5rem 1rem rgba(0, 0, 0, 0.15);--bs-box-shadow-sm:0 0.125rem 0.25rem rgba(0, 0, 0, 0.075);--bs-box-shadow-lg:0 1rem 3rem rgba(0, 0, 0, 0.175);--bs-box-shadow-inset:inset 0 1px 2px rgba(0, 0, 0, 0.075);--bs-focus-ring-width:0.25rem;--bs-focus-ring-opacity:0.25;--bs-focus-ring-color:rgba(47, 164, 231, 0.25);--bs-form-valid-color:#73a839;--bs-form-valid-border-color:#73a839;--bs-form-invalid-color:#c71c22;--bs-form-invalid-border-color:#c71c22}[data-bs-theme=dark]{color-scheme:dark;--bs-body-color:#dee2e6;--bs-body-color-rgb:222,226,230;--bs-body-bg:#212529;--bs-body-bg-rgb:33,37,41;--bs-emphasis-color:#fff;--bs-emphasis-color-rgb:255,255,255;--bs-secondary-color:rgba(222, 226, 230, 0.75);--bs-secondary-color-rgb:222,226,230;--bs-secondary-bg:#343a40;--bs-secondary-bg-rgb:52,58,64;--bs-tertiary-color:rgba(222, 226, 230, 0.5);--bs-tertiary-color-rgb:222,226,230;--bs-tertiary-bg:#2b3035;--bs-tertiary-bg-rgb:43,48,53;--bs-primary-text-emphasis:#82c8f1;--bs-secondary-text-emphasis:#f2f4f5;--bs-success-text-emphasis:#abcb88;--bs-info-text-emphasis:#688aab;--bs-warning-text-emphasis:#eb9a66;--bs-danger-text-emphasis:#dd777a;--bs-light-text-emphasis:#f8f9fa;--bs-dark-text-emphasis:#dee2e6;--bs-primary-bg-subtle:#09212e;--bs-secondary-bg-subtle:#2f2f30;--bs-success-bg-subtle:#17220b;--bs-info-bg-subtle:#010c17;--bs-warning-bg-subtle:#2c1100;--bs-danger-bg-subtle:#280607;--bs-light-bg-subtle:#343a40;--bs-dark-bg-subtle:#1a1d20;--bs-primary-border-subtle:#1c628b;--bs-secondary-border-subtle:#8c8e8f;--bs-success-border-subtle:#456522;--bs-info-border-subtle:#022445;--bs-warning-border-subtle:#853400;--bs-danger-border-subtle:#771114;--bs-light-border-subtle:#495057;--bs-dark-border-subtle:#343a40;--bs-heading-color:inheriLine truncated
|
||||
/*# sourceMappingURL=bootstrap.min.css.map */
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"sources":["dist/cerulean/bootstrap.css"],"names":[],"mappings":"iBACA;;;;;;AAOA;;;;AAKA,MACA,sBACE,UAAW,QACX,YAAa,QACb,YAAa,QACb,UAAW,QACX,SAAU,QACV,YAAa,QACb,YAAa,QACb,WAAY,QACZ,UAAW,QACX,UAAW,QACX,WAAY,KACZ,WAAY,KACZ,UAAW,QACX,eAAgB,QAChB,cAAe,QACf,cAAe,QACf,cAAe,QACf,cAAe,QACf,cAAe,QACf,cAAe,QACf,cAAe,QACf,cAAe,QACf,cAAe,QACf,aAAc,QACd,eAAgB,QAChB,aAAc,QACd,UAAW,QACX,aAAc,QACd,YAAa,QACb,WAAY,QACZ,UAAW,QACX,iBAAkB,EAAE,CAAE,GAAG,CAAE,IAC3B,mBAAoB,GAAG,CAAE,GAAG,CAAE,IAC9B,iBAAkB,GAAG,CAAE,GAAG,CAAE,GAC5B,cAAe,CAAC,CAAE,EAAE,CAAE,IACtB,iBAAkB,GAAG,CAAE,EAAE,CAAE,EAC3B,gBAAiB,GAAG,CAAE,EAAE,CAAE,GAC1B,eAAgB,GAAG,CAAE,GAAG,CAAE,IAC1B,cAAe,EAAE,CAAE,EAAE,CAAE,GACvB,2BAA4B,QAC5B,6BAA8B,QAC9B,2BAA4B,QAC5B,wBAAyB,QACzB,2BAA4B,QAC5B,0BAA2B,QAC3B,yBAA0B,QAC1B,wBAAyB,QACzB,uBAAwB,QACxB,yBAA0B,QAC1B,uBAAwB,QACxB,oBAAqB,QACrB,uBAAwB,QACxB,sBAAuB,QACvB,qBAAsB,QACtB,oBAAqB,QACrB,2BAA4B,QAC5B,6BAA8B,QAC9B,2BAA4B,QAC5B,wBAAyB,QACzB,2BAA4B,QAC5B,0BAA2B,QAC3B,yBAA0B,QAC1B,wBAAyB,QACzB,eAAgB,GAAG,CAAE,GAAG,CAAE,IAC1B,eAAgB,CAAC,CAAE,CAAC,CAAE,EACtB,qBAAsB,SAAS,CAAE,aAAa,CAAE,UAAU,CAAE,MAAM,CAAE,gBAAgB,CAAE,WAAW,CAAE,iBAAiB,CAAE,KAAK,CAAE,UAAU,CAAE,mBAAmB,CAAE,gBAAgB,CAAE,iBAAiB,CAAE,mBACnM,oBAAqB,cAAc,CAAE,KAAK,CAAE,MAAM,CAAE,QAAQ,CAAE,iBAAiB,CAAE,aAAa,CAAE,UAChG,cAAe,2EACf,sBAAuB,0BACvB,oBAAqB,KACrB,sBAAuB,IACvB,sBAAuB,IACvB,gBAAiB,QACjB,oBAAqB,EAAE,CAAE,EAAE,CAAE,GAC7B,aAAc,KACd,iBAAkB,GAAG,CAAE,GAAG,CAAE,IAC5B,oBAAqB,KACrB,wBAAyB,CAAC,CAAE,CAAC,CAAE,EAC/B,qBAAsB,uBACtB,yBAA0B,EAAE,CAAE,EAAE,CAAE,GAClC,kBAAmB,QACnB,sBAAuB,GAAG,CAAE,GAAG,CAAE,IACjC,oBAAqB,sBACrB,wBAAyB,EAAE,CAAE,EAAE,CAAE,GACjC,iBAAkB,QAClB,qBAAsB,GAAG,CAAE,GAAG,CAAE,IAChC,mBAAoB,QACpB,gBAAiB,QACjB,oBAAqB,EAAE,CAAE,GAAG,CAAE,IAC9B,qBAAsB,UACtB,sBAAuB,QACvB,0BAA2B,EAAE,CAAE,GAAG,CAAE,IACpC,gBAAiB,QACjB,qBAAsB,QACtB,kBAAmB,QACnB,kBAAmB,IACnB,kBAAmB,MACnB,kBAAmB,QACnB,8BAA+B,qBAC/B,mBAAoB,SACpB,sBAAuB,QACvB,sBAAuB,OACvB,sBAAuB,KACvB,uBAAwB,KACxB,uBAAwB,4BACxB,wBAAyB,MACzB,gBAAiB,EAAE,OAAO,KAAK,oBAC/B,mBAAoB,EAAE,SAAS,QAAQ,qBACvC,mBAAoB,EAAE,KAAK,KAAK,qBAChC,sBAAuB,MAAM,EAAE,IAAI,IAAI,qBACvC,sBAAuB,QACvB,wBAAyB,KACzB,sBAAuB,yBACvB,sBAAuB,QACvB,6BAA8B,QAC9B,wBAAyB,QACzB,+BAAgC,QAGlC,qBACE,aAAc,KACd,gBAAiB,QACjB,oBAAqB,GAAG,CAAE,GAAG,CAAE,IAC/B,aAAc,QACd,iBAAkB,EAAE,CAAE,EAAE,CAAE,GAC1B,oBAAqB,KACrB,wBAAyB,GAAG,CAAE,GAAG,CAAE,IACnC,qBAAsB,0BACtB,yBAA0B,GAAG,CAAE,GAAG,CAAE,IACpC,kBAAmB,QACnB,sBAAuB,EAAE,CAAE,EAAE,CAAE,GAC/B,oBAAqB,yBACrB,wBAAyB,GAAG,CAAE,GAAG,CAAE,IACnC,iBAAkB,QAClB,qBAAsB,EAAE,CAAE,EAAE,CAAE,GAC9B,2BAA4B,QAC5B,6BAA8B,QAC9B,2BAA4B,QAC5B,wBAAyB,QACzB,2BAA4B,QAC5B,0BAA2B,QAC3B,yBAA0B,QAC1B,wBAAyB,QACzB,uBAAwB,QACxB,yBAA0B,QAC1B,uBAAwB,QACxB,oBAAqB,QACrB,uBAAwB,QACxB,sBAAuB,QACvB,qBAAsB,QACtB,oBAAqB,QACrB,2BAA4B,QAC5B,6BAA8B,QAC9B,2BAA4B,QAC5B,wBAAyB,QACzB,2BAA4B,QAC5B,0BAA2B,QAC3B,yBAA0B,QAC1B,wBAAyB,QACzB,mBAAoB,QACpB,gBAAiB,QACjB,sBAAuB,QACvB,oBAAqB,GAAG,CAAE,GAAG,CAAE,IAC/B,0BAA2B,GAAG,CAAE,GAAG,CAAE,IACrC,gBAAiB,QACjB,qBAAsB,QACtB,kBAAmB,QACnB,kBAAmB,QACnB,8BAA+B,0BAC/B,sBAAuB,QACvB,6BAA8B,QAC9B,wBAAyB,QACzB,+BAAgC,QAGlC,EAEA,QADA,SAEE,WAAY,WAGd,8CACE,MACE,gBAAiB,QAIrB,KACE,OAAQ,EACR,YAAa,2BACb,UAAW,yBACX,YAAa,2BACb,YAAa,2BACb,MAAO,qBACP,WAAY,0BACZ,iBAAkB,kBAClB,yBAA0B,KAC1B,4BAA6B,YAG/B,GACE,OAAQ,KAAK,EACb,MAAO,QACP,OAAQ,EACR,WAAY,uBAAuB,MACnC,QAAS,IAGsC,IAAT,IAAT,IAAT,IAAT,IAAT,IAAyC,GAAT,GAAT,GAAT,GAAT,GAAT,GACE,WAAY,EACZ,cAAe,MACf,YAAa,IACb,YAAa,IACb,MAAO,wBAGL,IAAJ,GACE,UAAW,uBAEb,0BACM,IAAJ,GACE,UAAW,QAIX,IAAJ,GACE,UAAW,sBAEb,0BACM,IAAJ,GACE,UAAW,MAIX,IAAJ,GACE,UAAW,oBAEb,0BACM,IAAJ,GACE,UAAW,SAIX,IAAJ,GACE,UAAW,sBAEb,0BACM,IAAJ,GACE,UAAW,QAIX,IAAJ,GACE,UAAW,QAGT,IAAJ,GACE,UAAW,KAGb,EACE,WAAY,EACZ,cAAe,KAGjB,YACE,wBAAyB,UAAU,OACnC,gBAAiB,UAAU,OAC3B,OAAQ,KACR,iCAAkC,KAClC,yBAA0B,KAG5B,QACE,cAAe,KACf,WAAY,OACZ,YAAa,QAGf,GACA,GACE,aAAc,KAKhB,GAFA,GACA,GAEE,WAAY,EACZ,cAAe,KAGjB,MAEA,MACA,MAFA,MAGE,cAAe,EAGjB,GACE,YAAa,IAGf,GACE,cAAe,MACf,YAAa,EAGf,WACE,OAAQ,EAAE,EAAE,KAGd,EACA,OACE,YAAa,OAGR,OAAP,MACE,UAAW,OAGP,MAAN,KACE,QAAS,QACT,MAAO,0BACP,iBAAkB,uBAGpB,IACA,IACE,SAAU,SACV,UAAW,MACX,YAAa,EACb,eAAgB,SAGlB,IACE,OAAQ,OAGV,IACE,IAAK,MAGP,EACE,MAAO,wDACP,gBAAiB,UAEnB,QACE,oBAAqB,+BAGvB,2BAA4B,iCAC1B,MAAO,QACP,gBAAiB,KAInB,KACA,IAFA,IAGA,KACE,YAAa,yBACb,UAAW,IAGb,IACE,QAAS,MACT,WAAY,EACZ,cAAe,KACf,SAAU,KACV,UAAW,OAEb,SACE,UAAW,QACX,MAAO,QACP,WAAY,OAGd,KACE,UAAW,OACX,MAAO,qBACP,UAAW,WAEb,OACE,MAAO,QAGT,IACE,QAAS,SAAU,QACnB,UAAW,OACX,MAAO,kBACP,iBAAkB,qBAClB,cAAe,OAEjB,QACE,QAAS,EACT,UAAW,IAGb,OACE,OAAQ,EAAE,EAAE,KAGd,IACA,IACE,eAAgB,OAGlB,MACE,aAAc,OACd,gBAAiB,SAGnB,QACE,YAAa,MACb,eAAgB,MAChB,MAAO,0BACP,WAAY,KAGd,GACE,WAAY,QACZ,WAAY,qBAId,MAGA,GAFA,MAGA,GALA,MAGA,GAGE,aAAc,QACd,aAAc,MACd,aAAc,EAGhB,MACE,QAAS,aAGX,OACE,cAAe,EAGjB,iCACE,QAAS,EAIX,OADA,MAGA,SADA,OAEA,SACE,OAAQ,EACR,YAAa,QACb,UAAW,QACX,YAAa,QAGf,OACA,OACE,eAAgB,KAGlB,cACE,OAAQ,QAGV,OACE,UAAW,OAEb,gBACE,QAAS,EAGX,0IACE,QAAS,eAIX,cACA,aACA,cAHA,OAIE,mBAAoB,OAGtB,6BACA,4BACA,6BAHA,sBAIE,OAAQ,QAGV,mBACE,QAAS,EACT,aAAc,KAGhB,SACE,OAAQ,SAGV,SACE,UAAW,EACX,QAAS,EACT,OAAQ,EACR,Line truncated
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
/*!
|
||||
* Font Awesome Free 6.5.1 by @fontawesome - https://fontawesome.com
|
||||
* License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License)
|
||||
* Copyright 2023 Fonticons, Inc.
|
||||
*/
|
||||
:host,:root{--fa-style-family-brands:"Font Awesome 6 Brands";--fa-font-brands:normal 400 1em/1 "Font Awesome 6 Brands"}@font-face{font-family:"Font Awesome 6 Brands";font-style:normal;font-weight:400;font-display:block;src:url(../webfonts/fa-brands-400.woff2) format("woff2"),url(../webfonts/fa-brands-400.ttf) format("truetype")}.fa-brands,.fab{font-weight:400}.fa-monero:before{content:"\f3d0"}.fa-hooli:before{content:"\f427"}.fa-yelp:before{content:"\f1e9"}.fa-cc-visa:before{content:"\f1f0"}.fa-lastfm:before{content:"\f202"}.fa-shopware:before{content:"\f5b5"}.fa-creative-commons-nc:before{content:"\f4e8"}.fa-aws:before{content:"\f375"}.fa-redhat:before{content:"\f7bc"}.fa-yoast:before{content:"\f2b1"}.fa-cloudflare:before{content:"\e07d"}.fa-ups:before{content:"\f7e0"}.fa-pixiv:before{content:"\e640"}.fa-wpexplorer:before{content:"\f2de"}.fa-dyalog:before{content:"\f399"}.fa-bity:before{content:"\f37a"}.fa-stackpath:before{content:"\f842"}.fa-buysellads:before{content:"\f20d"}.fa-first-order:before{content:"\f2b0"}.fa-modx:before{content:"\f285"}.fa-guilded:before{content:"\e07e"}.fa-vnv:before{content:"\f40b"}.fa-js-square:before,.fa-square-js:before{content:"\f3b9"}.fa-microsoft:before{content:"\f3ca"}.fa-qq:before{content:"\f1d6"}.fa-orcid:before{content:"\f8d2"}.fa-java:before{content:"\f4e4"}.fa-invision:before{content:"\f7b0"}.fa-creative-commons-pd-alt:before{content:"\f4ed"}.fa-centercode:before{content:"\f380"}.fa-glide-g:before{content:"\f2a6"}.fa-drupal:before{content:"\f1a9"}.fa-hire-a-helper:before{content:"\f3b0"}.fa-creative-commons-by:before{content:"\f4e7"}.fa-unity:before{content:"\e049"}.fa-whmcs:before{content:"\f40d"}.fa-rocketchat:before{content:"\f3e8"}.fa-vk:before{content:"\f189"}.fa-untappd:before{content:"\f405"}.fa-mailchimp:before{content:"\f59e"}.fa-css3-alt:before{content:"\f38b"}.fa-reddit-square:before,.fa-square-reddit:before{content:"\f1a2"}.fa-vimeo-v:before{content:"\f27d"}.fa-contao:before{content:"\f26d"}.fa-square-font-awesome:before{content:"\e5ad"}.fa-deskpro:before{content:"\f38f"}.fa-brave:before{content:"\e63c"}.fa-sistrix:before{content:"\f3ee"}.fa-instagram-square:before,.fa-square-instagram:before{content:"\e055"}.fa-battle-net:before{content:"\f835"}.fa-the-red-yeti:before{content:"\f69d"}.fa-hacker-news-square:before,.fa-square-hacker-news:before{content:"\f3af"}.fa-edge:before{content:"\f282"}.fa-threads:before{content:"\e618"}.fa-napster:before{content:"\f3d2"}.fa-snapchat-square:before,.fa-square-snapchat:before{content:"\f2ad"}.fa-google-plus-g:before{content:"\f0d5"}.fa-artstation:before{content:"\f77a"}.fa-markdown:before{content:"\f60f"}.fa-sourcetree:before{content:"\f7d3"}.fa-google-plus:before{content:"\f2b3"}.fa-diaspora:before{content:"\f791"}.fa-foursquare:before{content:"\f180"}.fa-stack-overflow:before{content:"\f16c"}.fa-github-alt:before{content:"\f113"}.fa-phoenix-squadron:before{content:"\f511"}.fa-pagelines:before{content:"\f18c"}.fa-algolia:before{content:"\f36c"}.fa-red-river:before{content:"\f3e3"}.fa-creative-commons-sa:before{content:"\f4ef"}.fa-safari:before{content:"\f267"}.fa-google:before{content:"\f1a0"}.fa-font-awesome-alt:before,.fa-square-font-awesome-stroke:before{content:"\f35c"}.fa-atlassian:before{content:"\f77b"}.fa-linkedin-in:before{content:"\f0e1"}.fa-digital-ocean:before{content:"\f391"}.fa-nimblr:before{content:"\f5a8"}.fa-chromecast:before{content:"\f838"}.fa-evernote:before{content:"\f839"}.fa-hacker-news:before{content:"\f1d4"}.fa-creative-commons-sampling:before{content:"\f4f0"}.fa-adversal:before{content:"\f36a"}.fa-creative-commons:before{content:"\f25e"}.fa-watchman-monitoring:before{content:"\e087"}.fa-fonticons:before{content:"\f280"}.fa-weixin:before{content:"\f1d7"}.fa-shirtsinbulk:before{content:"\f214"}.fa-codepen:before{content:"\f1cb"}.fa-git-alt:before{content:"\f841"}.fa-lyft:before{content:"\f3c3"}.fa-rev:before{content:"\f5b2"}.fa-windows:before{content:"\f17a"}.fa-wizards-of-the-coast:before{content:"\f730"}.fa-square-viadeo:before,.fa-viadeo-square:before{content:"\f2aa"}.fa-meetup:before{content:"\f2e0"}.fa-centos:before{content:"\f789"}.fa-adn:before{content:"\f170"}.fa-cloudsmith:before{content:"\f384"}.fa-opensuse:before{content:"\e62b"}.fa-pied-piper-alt:before{content:"\f1a8"}.fa-dribbble-square:before,.fa-square-dribbble:before{content:"\f397"}.fa-codiepie:before{content:"\f284"}.fa-node:before{content:"\f419"}.fa-mix:before{content:"\f3cb"}.fa-steam:before{content:"\f1b6"}.fa-cc-apple-pay:before{content:"\f416"}.fa-scribd:before{content:"\f28a"}.fa-debian:before{content:"\e60b"}.fa-openid:before{content:"\f19b"}.fa-instalod:before{content:"\e081"}.fa-expeditedssl:before{content:"\f23e"}.fa-sellcast:before{content:"\f2da"}.fa-square-twitter:before,.fa-twitter-square:before{content:"\f081"}.fa-r-project:before{content:"\f4f7"}.fa-delicious:before{content:"\f1a5"}.fa-freebsd:before{content:"\f3a4"}.fa-vuejs:before{content:"\f41f"}.fa-accusoft:before{content:"\f369"}.fa-ioxhost:before{contLine truncated
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
/*!
|
||||
* Font Awesome Free 6.5.1 by @fontawesome - https://fontawesome.com
|
||||
* License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License)
|
||||
* Copyright 2023 Fonticons, Inc.
|
||||
*/
|
||||
.fa{font-family:var(--fa-style-family,"Font Awesome 6 Free");font-weight:var(--fa-style,900)}.fa,.fa-brands,.fa-classic,.fa-regular,.fa-sharp,.fa-solid,.fab,.far,.fas{-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;display:var(--fa-display,inline-block);font-style:normal;font-variant:normal;line-height:1;text-rendering:auto}.fa-classic,.fa-regular,.fa-solid,.far,.fas{font-family:"Font Awesome 6 Free"}.fa-brands,.fab{font-family:"Font Awesome 6 Brands"}.fa-1x{font-size:1em}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-6x{font-size:6em}.fa-7x{font-size:7em}.fa-8x{font-size:8em}.fa-9x{font-size:9em}.fa-10x{font-size:10em}.fa-2xs{font-size:.625em;line-height:.1em;vertical-align:.225em}.fa-xs{font-size:.75em;line-height:.08333em;vertical-align:.125em}.fa-sm{font-size:.875em;line-height:.07143em;vertical-align:.05357em}.fa-lg{font-size:1.25em;line-height:.05em;vertical-align:-.075em}.fa-xl{font-size:1.5em;line-height:.04167em;vertical-align:-.125em}.fa-2xl{font-size:2em;line-height:.03125em;vertical-align:-.1875em}.fa-fw{text-align:center;width:1.25em}.fa-ul{list-style-type:none;margin-left:var(--fa-li-margin,2.5em);padding-left:0}.fa-ul>li{position:relative}.fa-li{left:calc(var(--fa-li-width, 2em)*-1);position:absolute;text-align:center;width:var(--fa-li-width,2em);line-height:inherit}.fa-border{border-radius:var(--fa-border-radius,.1em);border:var(--fa-border-width,.08em) var(--fa-border-style,solid) var(--fa-border-color,#eee);padding:var(--fa-border-padding,.2em .25em .15em)}.fa-pull-left{float:left;margin-right:var(--fa-pull-margin,.3em)}.fa-pull-right{float:right;margin-left:var(--fa-pull-margin,.3em)}.fa-beat{-webkit-animation-name:fa-beat;animation-name:fa-beat;-webkit-animation-delay:var(--fa-animation-delay,0s);animation-delay:var(--fa-animation-delay,0s);-webkit-animation-direction:var(--fa-animation-direction,normal);animation-direction:var(--fa-animation-direction,normal);-webkit-animation-duration:var(--fa-animation-duration,1s);animation-duration:var(--fa-animation-duration,1s);-webkit-animation-iteration-count:var(--fa-animation-iteration-count,infinite);animation-iteration-count:var(--fa-animation-iteration-count,infinite);-webkit-animation-timing-function:var(--fa-animation-timing,ease-in-out);animation-timing-function:var(--fa-animation-timing,ease-in-out)}.fa-bounce{-webkit-animation-name:fa-bounce;animation-name:fa-bounce;-webkit-animation-delay:var(--fa-animation-delay,0s);animation-delay:var(--fa-animation-delay,0s);-webkit-animation-direction:var(--fa-animation-direction,normal);animation-direction:var(--fa-animation-direction,normal);-webkit-animation-duration:var(--fa-animation-duration,1s);animation-duration:var(--fa-animation-duration,1s);-webkit-animation-iteration-count:var(--fa-animation-iteration-count,infinite);animation-iteration-count:var(--fa-animation-iteration-count,infinite);-webkit-animation-timing-function:var(--fa-animation-timing,cubic-bezier(.28,.84,.42,1));animation-timing-function:var(--fa-animation-timing,cubic-bezier(.28,.84,.42,1))}.fa-fade{-webkit-animation-name:fa-fade;animation-name:fa-fade;-webkit-animation-iteration-count:var(--fa-animation-iteration-count,infinite);animation-iteration-count:var(--fa-animation-iteration-count,infinite);-webkit-animation-timing-function:var(--fa-animation-timing,cubic-bezier(.4,0,.6,1));animation-timing-function:var(--fa-animation-timing,cubic-bezier(.4,0,.6,1))}.fa-beat-fade,.fa-fade{-webkit-animation-delay:var(--fa-animation-delay,0s);animation-delay:var(--fa-animation-delay,0s);-webkit-animation-direction:var(--fa-animation-direction,normal);animation-direction:var(--fa-animation-direction,normal);-webkit-animation-duration:var(--fa-animation-duration,1s);animation-duration:var(--fa-animation-duration,1s)}.fa-beat-fade{-webkit-animation-name:fa-beat-fade;animation-name:fa-beat-fade;-webkit-animation-iteration-count:var(--fa-animation-iteration-count,infinite);animation-iteration-count:var(--fa-animation-iteration-count,infinite);-webkit-animation-timing-function:var(--fa-animation-timing,cubic-bezier(.4,0,.6,1));animation-timing-function:var(--fa-animation-timing,cubic-bezier(.4,0,.6,1))}.fa-flip{-webkit-animation-name:fa-flip;animation-name:fa-flip;-webkit-animation-delay:var(--fa-animation-delay,0s);animation-delay:var(--fa-animation-delay,0s);-webkit-animation-direction:var(--fa-animation-direction,normal);animation-direction:var(--fa-animation-direction,normal);-webkit-animation-duration:var(--fa-animation-duration,1s);animation-duration:var(--fa-animation-duration,1s);-webkit-animation-iteration-count:var(--fa-animation-iteration-count,infinite);animation-iteration-count:var(--fa-animation-iteration-count,infinite);-webkit-animation-timing-function:var(--fa-animation-timing,ease-in-out);animation-timing-function:var(--fa-animation-timing,ease-in-out)}.fa-shake{-webkit-animation-name:fa-shake;animation-name:fa-shake;-webkit-animation-duration:var(--fa-animatLine truncated
|
||||
|
||||
.fa-0:before{content:"\30"}.fa-1:before{content:"\31"}.fa-2:before{content:"\32"}.fa-3:before{content:"\33"}.fa-4:before{content:"\34"}.fa-5:before{content:"\35"}.fa-6:before{content:"\36"}.fa-7:before{content:"\37"}.fa-8:before{content:"\38"}.fa-9:before{content:"\39"}.fa-fill-drip:before{content:"\f576"}.fa-arrows-to-circle:before{content:"\e4bd"}.fa-chevron-circle-right:before,.fa-circle-chevron-right:before{content:"\f138"}.fa-at:before{content:"\40"}.fa-trash-alt:before,.fa-trash-can:before{content:"\f2ed"}.fa-text-height:before{content:"\f034"}.fa-user-times:before,.fa-user-xmark:before{content:"\f235"}.fa-stethoscope:before{content:"\f0f1"}.fa-comment-alt:before,.fa-message:before{content:"\f27a"}.fa-info:before{content:"\f129"}.fa-compress-alt:before,.fa-down-left-and-up-right-to-center:before{content:"\f422"}.fa-explosion:before{content:"\e4e9"}.fa-file-alt:before,.fa-file-lines:before,.fa-file-text:before{content:"\f15c"}.fa-wave-square:before{content:"\f83e"}.fa-ring:before{content:"\f70b"}.fa-building-un:before{content:"\e4d9"}.fa-dice-three:before{content:"\f527"}.fa-calendar-alt:before,.fa-calendar-days:before{content:"\f073"}.fa-anchor-circle-check:before{content:"\e4aa"}.fa-building-circle-arrow-right:before{content:"\e4d1"}.fa-volleyball-ball:before,.fa-volleyball:before{content:"\f45f"}.fa-arrows-up-to-line:before{content:"\e4c2"}.fa-sort-desc:before,.fa-sort-down:before{content:"\f0dd"}.fa-circle-minus:before,.fa-minus-circle:before{content:"\f056"}.fa-door-open:before{content:"\f52b"}.fa-right-from-bracket:before,.fa-sign-out-alt:before{content:"\f2f5"}.fa-atom:before{content:"\f5d2"}.fa-soap:before{content:"\e06e"}.fa-heart-music-camera-bolt:before,.fa-icons:before{content:"\f86d"}.fa-microphone-alt-slash:before,.fa-microphone-lines-slash:before{content:"\f539"}.fa-bridge-circle-check:before{content:"\e4c9"}.fa-pump-medical:before{content:"\e06a"}.fa-fingerprint:before{content:"\f577"}.fa-hand-point-right:before{content:"\f0a4"}.fa-magnifying-glass-location:before,.fa-search-location:before{content:"\f689"}.fa-forward-step:before,.fa-step-forward:before{content:"\f051"}.fa-face-smile-beam:before,.fa-smile-beam:before{content:"\f5b8"}.fa-flag-checkered:before{content:"\f11e"}.fa-football-ball:before,.fa-football:before{content:"\f44e"}.fa-school-circle-exclamation:before{content:"\e56c"}.fa-crop:before{content:"\f125"}.fa-angle-double-down:before,.fa-angles-down:before{content:"\f103"}.fa-users-rectangle:before{content:"\e594"}.fa-people-roof:before{content:"\e537"}.fa-people-line:before{content:"\e534"}.fa-beer-mug-empty:before,.fa-beer:before{content:"\f0fc"}.fa-diagram-predecessor:before{content:"\e477"}.fa-arrow-up-long:before,.fa-long-arrow-up:before{content:"\f176"}.fa-burn:before,.fa-fire-flame-simple:before{content:"\f46a"}.fa-male:before,.fa-person:before{content:"\f183"}.fa-laptop:before{content:"\f109"}.fa-file-csv:before{content:"\f6dd"}.fa-menorah:before{content:"\f676"}.fa-truck-plane:before{content:"\e58f"}.fa-record-vinyl:before{content:"\f8d9"}.fa-face-grin-stars:before,.fa-grin-stars:before{content:"\f587"}.fa-bong:before{content:"\f55c"}.fa-pastafarianism:before,.fa-spaghetti-monster-flying:before{content:"\f67b"}.fa-arrow-down-up-across-line:before{content:"\e4af"}.fa-spoon:before,.fa-utensil-spoon:before{content:"\f2e5"}.fa-jar-wheat:before{content:"\e517"}.fa-envelopes-bulk:before,.fa-mail-bulk:before{content:"\f674"}.fa-file-circle-exclamation:before{content:"\e4eb"}.fa-circle-h:before,.fa-hospital-symbol:before{content:"\f47e"}.fa-pager:before{content:"\f815"}.fa-address-book:before,.fa-contact-book:before{content:"\f2b9"}.fa-strikethrough:before{content:"\f0cc"}.fa-k:before{content:"\4b"}.fa-landmark-flag:before{content:"\e51c"}.fa-pencil-alt:before,.fa-pencil:before{content:"\f303"}.fa-backward:before{content:"\f04a"}.fa-caret-right:before{content:"\f0da"}.fa-comments:before{content:"\f086"}.fa-file-clipboard:before,.fa-paste:before{content:"\f0ea"}.fa-code-pull-request:before{content:"\e13c"}.fa-clipboard-list:before{content:"\f46d"}.fa-truck-loading:before,.fa-truck-ramp-box:before{content:"\f4de"}.fa-user-check:before{content:"\f4fc"}.fa-vial-virus:before{content:"\e597"}.fa-sheet-plastic:before{content:"\e571"}.fa-blog:before{content:"\f781"}.fa-user-ninja:before{content:"\f504"}.fa-person-arrow-up-from-line:before{content:"\e539"}.fa-scroll-torah:before,.fa-torah:before{content:"\f6a0"}.fa-broom-ball:before,.fa-quidditch-broom-ball:before,.fa-quidditch:before{content:"\f458"}.fa-toggle-off:before{content:"\f204"}.fa-archive:before,.fa-box-archive:before{content:"\f187"}.fa-person-drowning:before{content:"\e545"}.fa-arrow-down-9-1:before,.fa-sort-numeric-desc:before,.fa-sort-numeric-down-alt:before{content:"\f886"}.fa-face-grin-tongue-squint:before,.fa-grin-tongue-squint:before{content:"\f58a"}.fa-spray-can:before{content:"\f5bd"}.fa-truck-monster:before{content:"\f63b"}.fa-w:before{content:"\57"}.fa-earth-africa:before,.fa-globe-africa:before{content:"\f57Line truncated
|
||||
.fa-sr-only,.fa-sr-only-focusable:not(:focus),.sr-only,.sr-only-focusable:not(:focus){position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border-width:0}
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
/*!
|
||||
* Font Awesome Free 6.5.1 by @fontawesome - https://fontawesome.com
|
||||
* License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License)
|
||||
* Copyright 2023 Fonticons, Inc.
|
||||
*/
|
||||
:host,:root{--fa-style-family-classic:"Font Awesome 6 Free";--fa-font-solid:normal 900 1em/1 "Font Awesome 6 Free"}@font-face{font-family:"Font Awesome 6 Free";font-style:normal;font-weight:900;font-display:block;src:url(../webfonts/fa-solid-900.woff2) format("woff2"),url(../webfonts/fa-solid-900.ttf) format("truetype")}.fa-solid,.fas{font-weight:900}
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
/*!
|
||||
* Font Awesome Free 6.5.1 by @fontawesome - https://fontawesome.com
|
||||
* License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License)
|
||||
* Copyright 2023 Fonticons, Inc.
|
||||
*/
|
||||
@font-face{font-family:"FontAwesome";font-display:block;src:url(../webfonts/fa-solid-900.woff2) format("woff2"),url(../webfonts/fa-solid-900.ttf) format("truetype")}@font-face{font-family:"FontAwesome";font-display:block;src:url(../webfonts/fa-brands-400.woff2) format("woff2"),url(../webfonts/fa-brands-400.ttf) format("truetype")}@font-face{font-family:"FontAwesome";font-display:block;src:url(../webfonts/fa-regular-400.woff2) format("woff2"),url(../webfonts/fa-regular-400.ttf) format("truetype");unicode-range:u+f003,u+f006,u+f014,u+f016-f017,u+f01a-f01b,u+f01d,u+f022,u+f03e,u+f044,u+f046,u+f05c-f05d,u+f06e,u+f070,u+f087-f088,u+f08a,u+f094,u+f096-f097,u+f09d,u+f0a0,u+f0a2,u+f0a4-f0a7,u+f0c5,u+f0c7,u+f0e5-f0e6,u+f0eb,u+f0f6-f0f8,u+f10c,u+f114-f115,u+f118-f11a,u+f11c-f11d,u+f133,u+f147,u+f14e,u+f150-f152,u+f185-f186,u+f18e,u+f190-f192,u+f196,u+f1c1-f1c9,u+f1d9,u+f1db,u+f1e3,u+f1ea,u+f1f7,u+f1f9,u+f20a,u+f247-f248,u+f24a,u+f24d,u+f255-f25b,u+f25d,u+f271-f274,u+f278,u+f27b,u+f28c,u+f28e,u+f29c,u+f2b5,u+f2b7,u+f2ba,u+f2bc,u+f2be,u+f2c0-f2c1,u+f2c3,u+f2d0,u+f2d2,u+f2d4,u+f2dc}@font-face{font-family:"FontAwesome";font-display:block;src:url(../webfonts/fa-v4compatibility.woff2) format("woff2"),url(../webfonts/fa-v4compatibility.ttf) format("truetype");unicode-range:u+f041,u+f047,u+f065-f066,u+f07d-f07e,u+f080,u+f08b,u+f08e,u+f090,u+f09a,u+f0ac,u+f0ae,u+f0b2,u+f0d0,u+f0d6,u+f0e4,u+f0ec,u+f10a-f10b,u+f123,u+f13e,u+f148-f149,u+f14c,u+f156,u+f15e,u+f160-f161,u+f163,u+f175-f178,u+f195,u+f1f8,u+f219,u+f27a}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 1.1 KiB |
Loaded 100 of 18684 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user