diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 25f2fd9..ee6f964 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -41,3 +41,6 @@ jobs: - name: Run template tests run: make test + + - name: Check spelling + run: make spelling diff --git a/.gitignore b/.gitignore index 6c56ff1..b309d4b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,6 @@ __pycache__/ .pytest_cache/ + +# Untracked cache of the estate-wide en-GB-oxendict dictionary. +.typos-oxendict-base.json +.typos-oxendict-base.toml diff --git a/Makefile b/Makefile index e0ce73d..0ddc5ed 100644 --- a/Makefile +++ b/Makefile @@ -1,17 +1,20 @@ -.PHONY: help check-fmt lint test typecheck +.PHONY: help check-fmt lint spelling test typecheck MAKEFLAGS += --no-print-directory UV := $(shell command -v uvx 2>/dev/null) WITH_ACT ?= 0 ACT_TEST_ENV = $(if $(filter 1 true yes on,$(WITH_ACT)),RUN_ACT_VALIDATION=1,) +TYPOS_VERSION ?= 1.48.0 +TYPOS = uv tool run typos@$(TYPOS_VERSION) +MD_FILES_FIND = find . -type f \( -name '*.md' -o -name '*.md.jinja' \) -not -path './.git/*' -print0 ifeq ($(strip $(UV)),) $(error uvx is required to run template tests. Install uv from https://docs.astral.sh/uv/getting-started/installation/) endif test: ## Run template tests - $(ACT_TEST_ENV) $(UV) --with pytest-copier --with pyyaml --with syrupy --with make-parser pytest tests/ + $(ACT_TEST_ENV) $(UV) --with hypothesis --with pytest-copier --with pyyaml --with syrupy --with make-parser pytest tests/ check-fmt: ## Verify template test formatting $(UV) ruff format --check tests/ @@ -20,8 +23,12 @@ lint: ## Run template test lint checks $(UV) ruff check tests/ $(UV) --with interrogate interrogate --fail-under 100 tests/ +spelling: ## Enforce en-GB-oxendict spelling + uv run scripts/generate_typos_config.py + $(MD_FILES_FIND) | xargs -0 $(TYPOS) --config typos.toml --force-exclude + typecheck: ## Run template test type checks - $(UV) --with pytest --with pytest-copier --with pyyaml --with syrupy --with make-parser ty check tests/ + $(UV) --with hypothesis --with pytest --with pytest-copier --with pyyaml --with syrupy --with make-parser ty check tests/ help: ## Show available targets @grep -E '^[a-zA-Z_-]+:.*?##' $(MAKEFILE_LIST) | \ diff --git a/docs/adr-001-template-quality-gates.md b/docs/adr-001-template-quality-gates.md index 2905fd7..fd8db77 100644 --- a/docs/adr-001-template-quality-gates.md +++ b/docs/adr-001-template-quality-gates.md @@ -16,9 +16,12 @@ failures are predictable. Generated projects use `make all` as the public aggregate gate. The `lint` target delegates to language-specific targets: -- `lint-python` runs Ruff, Interrogate (`--fail-under 100`), and Pylint through the PyPy-backed runner. +- `lint-python` runs Ruff, Interrogate (`--fail-under 100`), and Pylint through + the PyPy-backed runner. - `lint-rust` is rendered only when `use_rust` is enabled and runs rustdoc, Clippy, and Whitaker. +- `spelling` generates shared en-GB-oxendict policy and runs the pinned + `typos` binary after the other aggregate prerequisites complete. Tool revision pins are exposed as Makefile variables where the generated Makefile owns installation or invocation. Generated Continuous Integration diff --git a/docs/adr-003-shared-oxford-spelling-base.md b/docs/adr-003-shared-oxford-spelling-base.md new file mode 100644 index 0000000..86b0451 --- /dev/null +++ b/docs/adr-003-shared-oxford-spelling-base.md @@ -0,0 +1,37 @@ +# ADR-003: Generate spelling policy from a shared base + +## Status + +Accepted. + +## Context + +Generated projects need the same en-GB-oxendict policy as the wider `leynos` +estate. The `typos` `en-gb` locale enforces British `-our` and `-yse` forms but +prefers plain-British `-ise` over Oxford `-ize`. Copying curated overrides into +each generated project would cause drift, while making every exception global +would hide repository-specific mistakes. + +## Decision + +Generated projects refresh the tracked shared dictionary published by +`leynos/agent-helper-scripts` into ignored `.typos-oxendict-base.toml`, using +`.typos-oxendict-base.json` for source identity and freshness validators. The +generator merges that base with tracked `typos.local.toml` and writes a +deterministic, tracked `typos.toml`. + +The refresh validates data before atomic replacement, keeps a valid cache when +its authority is not newer, and supports explicit offline reuse. The generated +Makefile pins `typos`, exposes `make spelling`, includes spelling in `make all`, +and runs it through Continuous Integration (CI). The template repository uses +the same mechanism for its own Markdown and rendered Markdown sources. + +## Consequences + +- Generic Oxford stems are curated once for the estate. +- Generated projects retain reviewable, reproducible configuration and work + offline after their cache is populated. +- Product names, upstream quotations, and deliberate fixtures remain narrow + local exceptions. +- A fresh checkout needs network access to collect the shared base before its + first spelling run. diff --git a/docs/developers-guide.md b/docs/developers-guide.md index 0f9869b..19c6318 100644 --- a/docs/developers-guide.md +++ b/docs/developers-guide.md @@ -15,10 +15,13 @@ template itself. - `make lint` — runs Ruff lint checks and `interrogate --fail-under 100` against the `tests/` directory in the parent template test suite. - `make typecheck` — runs `ty check` against the parent template test suite, - supplying the test dependencies through `uvx`. + supplying the test dependencies, including Hypothesis, through `uvx`. - `make test` — runs the template test suite via `uvx`, supplying - `pytest-copier`, `pyyaml`, `syrupy`, and `make-parser` without a manually - managed virtual environment. + Hypothesis, `pytest-copier`, `pyyaml`, `syrupy`, and `make-parser` without a + manually managed virtual environment. +- `make spelling` — refreshes the ignored estate-wide dictionary cache, merges + `typos.local.toml`, generates `typos.toml`, and checks Markdown plus rendered + Markdown template sources with the pinned `typos` version. - `make test WITH_ACT=1` — sets `RUN_ACT_VALIDATION=1` inside the pytest invocation, enabling the act-backed integration tests that run generated CI workflows locally. Requires `act` and Docker to be available. @@ -31,9 +34,9 @@ template itself. The parent repository uses two separate GitHub Actions workflows to keep Docker-dependent tests isolated from the standard template test gate: -- `.github/workflows/ci.yml` runs `make test` on every push to `main` and on - all pull requests. It installs `markdownlint-cli2` and `mbake` at pinned - versions. +- `.github/workflows/ci.yml` runs `make test` and `make spelling` on every push + to `main` and on all pull requests. It installs `markdownlint-cli2` and + `mbake` at pinned versions. - `.github/workflows/act-validation.yml` runs `make test WITH_ACT=1`. It additionally downloads the `act` binary at a pinned `ACT_VERSION`, verifies its SHA-256 checksum before extraction, and confirms Docker availability via @@ -44,7 +47,9 @@ Docker-dependent tests isolated from the standard template test gate: ## Makefile Template `template/Makefile.jinja` defines the generated developer workflow. The default -`all` target runs build, formatting, linting, typechecking, and tests. +`all` target runs build, formatting, linting, typechecking, tests, and spelling. +The spelling recipe runs last so generated configuration cannot race tests when +callers enable parallel Make execution. The generated `audit` target is an explicit security gate run by CI. It runs `pip-audit` for every rendered project and, when `use_rust` is enabled, also runs `cargo audit` in the Rust extension crate. @@ -68,7 +73,7 @@ override pins without editing target recipes. `template/.github/workflows/ci.yml.jinja` mirrors the generated local gates. It sets up Python, optionally sets up Rust, runs `make check-fmt`, `make lint`, -`make typecheck`, and `make audit`, then delegates coverage to +`make typecheck`, `make spelling`, and `make audit`, then delegates coverage to `leynos/shared-actions/.github/actions/generate-coverage`. The shared coverage action runs Python coverage through xdist-backed SlipCover @@ -83,6 +88,16 @@ Docker availability, and runs `make test WITH_ACT=1`. Rust-enabled workflows pass `rust_extension/Cargo.toml` to the coverage action because the generated Python project root does not contain a Rust manifest. +## Shared Spelling Configuration + +[ADR-003](adr-003-shared-oxford-spelling-base.md) records the shared-base +decision. Both the parent and generated project keep +`.typos-oxendict-base.toml` and `.typos-oxendict-base.json` untracked. Generic +Oxford stems belong in `leynos/agent-helper-scripts`; repository-only accepted +words, patterns, and file exclusions belong in `typos.local.toml`. Regenerate +tracked configuration with `uv run scripts/generate_typos_config.py` rather +than editing `typos.toml`. + ## Rust Integration When `use_rust` is enabled, the template renders a PyO3 extension under diff --git a/pytest.ini b/pytest.ini index 064079c..360046c 100644 --- a/pytest.ini +++ b/pytest.ini @@ -1,3 +1,4 @@ [pytest] markers = act: local GitHub Actions workflow validation through act + slow: exercises an external tool or process boundary diff --git a/scripts/generate_typos_config.py b/scripts/generate_typos_config.py new file mode 100644 index 0000000..9c91be4 --- /dev/null +++ b/scripts/generate_typos_config.py @@ -0,0 +1,63 @@ +#!/usr/bin/env -S uv run python +# /// script +# requires-python = ">=3.13" +# dependencies = [] +# /// +"""Generate ``typos.toml`` from the shared en-GB-oxendict dictionary. + +The shared dictionary is refreshed into an untracked repository-local cache +only when the authoritative copy is newer. A valid cache remains usable when +the network is unavailable, and ``typos.local.toml`` supplies the narrow +repository-specific policy that must not weaken the estate-wide base. +""" + +from pathlib import Path + +import typos_rollout as rollout + +DEFAULT_BASE_URL = ( + "https://raw.githubusercontent.com/leynos/agent-helper-scripts/" + "refs/heads/main/data/typos-oxendict-base.toml" +) +REPOSITORY_ROOT = Path(__file__).resolve().parent.parent + + +def dictionary_from_cache(repository: Path = REPOSITORY_ROOT) -> rollout.Dictionary: + """Load the cached shared base merged with local repository policy.""" + dictionary = rollout.load_dictionary(repository / ".typos-oxendict-base.toml") + local_overlay = repository / "typos.local.toml" + if local_overlay.exists(): + dictionary = rollout.merge_dictionaries( + dictionary, + rollout.load_dictionary(local_overlay), + ) + return dictionary + + +def render_config(repository: Path = REPOSITORY_ROOT) -> str: + """Render deterministic configuration from the populated local cache.""" + return rollout.render_typos_config(dictionary_from_cache(repository)) + + +def main( + output: Path | None = None, + *, + repository: Path = REPOSITORY_ROOT, + source: str | Path = DEFAULT_BASE_URL, + offline: bool = False, +) -> rollout.RefreshResult: + """Refresh the shared base cache and write the merged configuration.""" + result = rollout.refresh_base( + source, + repository / ".typos-oxendict-base.toml", + metadata=repository / ".typos-oxendict-base.json", + offline=offline, + ) + destination = output if output is not None else repository / "typos.toml" + rollout.write_config(destination, dictionary_from_cache(repository)) + return result + + +if __name__ == "__main__": + refresh = main() + print(f"{refresh.status}: {REPOSITORY_ROOT / 'typos.toml'}") diff --git a/scripts/typos_rollout.py b/scripts/typos_rollout.py new file mode 100644 index 0000000..8c73cfb --- /dev/null +++ b/scripts/typos_rollout.py @@ -0,0 +1,401 @@ +"""Refresh and render shared en-GB-oxendict ``typos`` configuration.""" + +from __future__ import annotations + +import dataclasses +import email.utils +import json +import pathlib +import tempfile +import tomllib +import typing as typ +import urllib.error +import urllib.parse +import urllib.request + +if typ.TYPE_CHECKING: + import collections.abc as cabc + +SCHEMA_VERSION = 1 +HTTP_NOT_MODIFIED = 304 +SUFFIX_PAIRS = ( + ("ise", "ize"), + ("ises", "izes"), + ("ised", "ized"), + ("ising", "izing"), + ("iser", "izer"), + ("isers", "izers"), + ("isable", "izable"), + ("isation", "ization"), + ("isations", "izations"), +) + + +@dataclasses.dataclass(frozen=True) +class Dictionary: + """Curated words and exclusions used to generate a ``typos`` config.""" + + stems: tuple[str, ...] = () + accepted: tuple[str, ...] = () + corrections: tuple[tuple[str, str], ...] = () + ignore_patterns: tuple[str, ...] = () + excluded_files: tuple[str, ...] = () + + +@dataclasses.dataclass(frozen=True) +class RefreshResult: + """Describe whether the untracked shared dictionary cache changed.""" + + status: str + cache: pathlib.Path + + +@dataclasses.dataclass(frozen=True) +class _CacheTargets: + """Group the untracked dictionary cache and metadata sidecar paths.""" + + cache: pathlib.Path + metadata: pathlib.Path + + +def _string_list(table: cabc.Mapping[str, object], key: str) -> tuple[str, ...]: + """Read and validate a list of strings from a TOML table.""" + value = table.get(key, []) + if not isinstance(value, list) or not all(isinstance(item, str) for item in value): + message = f"{key!r} must be a list of strings" + raise TypeError(message) + return tuple(sorted(set(value))) + + +def _table( + document: cabc.Mapping[str, object], + key: str, +) -> cabc.Mapping[str, object]: + """Read and validate a TOML table.""" + value = document.get(key, {}) + if not isinstance(value, dict): + message = f"{key!r} must be a table" + raise TypeError(message) + return value + + +def _dictionary_from_text(text: str) -> Dictionary: + """Parse and validate shared dictionary text.""" + document = tomllib.loads(text) + schema = document.get("schema") + if schema != SCHEMA_VERSION: + message = f"unsupported dictionary schema {schema!r}" + raise ValueError(message) + oxford = _table(document, "oxford") + words = _table(document, "words") + patterns = _table(document, "patterns") + files = _table(document, "files") + corrections_table = _table(words, "corrections") + if not all( + isinstance(key, str) and isinstance(value, str) + for key, value in corrections_table.items() + ): + message = "word corrections must map strings to strings" + raise TypeError(message) + return Dictionary( + stems=_string_list(oxford, "stems"), + accepted=_string_list(words, "accepted"), + corrections=tuple(sorted(corrections_table.items())), + ignore_patterns=_string_list(patterns, "ignore"), + excluded_files=_string_list(files, "exclude"), + ) + + +def load_dictionary(path: pathlib.Path) -> Dictionary: + """Load a validated shared dictionary from *path*.""" + return _dictionary_from_text(path.read_text(encoding="utf-8")) + + +def merge_dictionaries(base: Dictionary, local: Dictionary) -> Dictionary: + """Merge a shared dictionary with a non-conflicting local overlay.""" + corrections = dict(base.corrections) + for word, correction in local.corrections: + existing = corrections.get(word) + if existing is not None and existing != correction: + message = ( + f"conflicting correction for {word!r}: {existing!r} != {correction!r}" + ) + raise ValueError(message) + corrections[word] = correction + return Dictionary( + stems=tuple(sorted(set(base.stems) | set(local.stems))), + accepted=tuple(sorted(set(base.accepted) | set(local.accepted))), + corrections=tuple(sorted(corrections.items())), + ignore_patterns=tuple( + sorted(set(base.ignore_patterns) | set(local.ignore_patterns)) + ), + excluded_files=tuple( + sorted(set(base.excluded_files) | set(local.excluded_files)) + ), + ) + + +def generate_word_mappings(dictionary: Dictionary) -> dict[str, str]: + """Expand Oxford stems and explicit words into deterministic mappings.""" + mappings = {word: word for word in dictionary.accepted} + + def add(word: str, correction: str) -> None: + existing = mappings.get(word) + if existing is not None and existing != correction: + message = ( + f"conflicting generated correction for {word!r}: " + f"{existing!r} != {correction!r}" + ) + raise ValueError(message) + mappings[word] = correction + + for word, correction in dictionary.corrections: + add(word, correction) + for stem in dictionary.stems: + for plain_british, oxford in SUFFIX_PAIRS: + add(f"{stem}{plain_british}", f"{stem}{oxford}") + add(f"{stem}{oxford}", f"{stem}{oxford}") + return dict(sorted(mappings.items())) + + +def _toml_string(value: str) -> str: + """Render a string using TOML-compatible JSON quoting.""" + return json.dumps(value, ensure_ascii=False) + + +def _render_array(name: str, values: tuple[str, ...]) -> list[str]: + """Render a deterministic TOML string array.""" + lines = [f"{name} = ["] + lines.extend(f" {_toml_string(value)}," for value in values) + lines.append("]") + return lines + + +def render_typos_config(dictionary: Dictionary) -> str: + """Render a deterministic, parse-checked ``typos.toml`` document.""" + lines = [ + "# Generated from the shared en-GB-oxendict dictionary.", + "# Regenerate with scripts/generate_typos_config.py; do not edit by hand.", + "", + "[files]", + *_render_array("extend-exclude", dictionary.excluded_files), + "", + "[default]", + 'locale = "en-gb"', + *_render_array("extend-ignore-re", dictionary.ignore_patterns), + "", + "[default.extend-words]", + ] + lines.extend( + f"{_toml_string(word)} = {_toml_string(correction)}" + for word, correction in generate_word_mappings(dictionary).items() + ) + rendered = "\n".join(lines) + "\n" + tomllib.loads(rendered) + return rendered + + +def _atomic_write(path: pathlib.Path, content: bytes) -> None: + """Write *content* beside *path* and atomically replace the destination.""" + path.parent.mkdir(parents=True, exist_ok=True) + with tempfile.NamedTemporaryFile( + delete=False, dir=path.parent, prefix=f".{path.name}." + ) as stream: + stream.write(content) + temporary = pathlib.Path(stream.name) + try: + temporary.replace(path) + finally: + temporary.unlink(missing_ok=True) + + +def write_config(path: pathlib.Path, dictionary: Dictionary) -> None: + """Atomically write validated generated configuration to *path*.""" + _atomic_write(path, render_typos_config(dictionary).encode()) + + +def _read_metadata(path: pathlib.Path) -> dict[str, object]: + """Read best-effort HTTP freshness metadata.""" + try: + value = json.loads(path.read_text(encoding="utf-8")) + except (FileNotFoundError, json.JSONDecodeError): + return {} + return value if isinstance(value, dict) else {} + + +def _write_metadata( + path: pathlib.Path, + metadata: cabc.Mapping[str, object], +) -> None: + """Atomically write HTTP freshness metadata.""" + _atomic_write(path, (json.dumps(metadata, sort_keys=True) + "\n").encode()) + + +def _valid_cache(cache: pathlib.Path) -> bool: + """Return whether *cache* contains a valid shared dictionary.""" + try: + load_dictionary(cache) + except ( + FileNotFoundError, + OSError, + TypeError, + ValueError, + tomllib.TOMLDecodeError, + ): + return False + return True + + +def _remote_is_not_newer( + saved: cabc.Mapping[str, object], + headers: cabc.Mapping[str, str], +) -> bool: + """Return whether HTTP validators prove the response is not newer.""" + etag = headers.get("ETag") + if etag is not None and etag == saved.get("etag"): + return True + modified = headers.get("Last-Modified") + saved_modified = saved.get("last_modified") + if not isinstance(modified, str) or not isinstance(saved_modified, str): + return False + try: + return email.utils.parsedate_to_datetime( + modified + ) <= email.utils.parsedate_to_datetime(saved_modified) + except (TypeError, ValueError): + return modified == saved_modified + + +def _local_cache_is_current( + cache: pathlib.Path, + saved: cabc.Mapping[str, object], + source_name: str, + source_mtime_ns: int, +) -> bool: + """Return whether metadata proves a valid local-source cache is current.""" + saved_mtime = saved.get("mtime_ns") + has_matching_source = saved.get("source") == source_name + has_new_enough_mtime = ( + isinstance(saved_mtime, int) and source_mtime_ns <= saved_mtime + ) + return _valid_cache(cache) and has_matching_source and has_new_enough_mtime + + +def _refresh_local( + source: pathlib.Path, + cache: pathlib.Path, + metadata: pathlib.Path, +) -> RefreshResult: + """Refresh from a local authoritative copy when it is newer.""" + source_stat = source.stat() + source_name = str(source.resolve()) + saved = _read_metadata(metadata) + if _local_cache_is_current( + cache, + saved, + source_name, + source_stat.st_mtime_ns, + ): + return RefreshResult("current", cache) + content = source.read_bytes() + _dictionary_from_text(content.decode()) + _atomic_write(cache, content) + _write_metadata( + metadata, + {"source": source_name, "mtime_ns": source_stat.st_mtime_ns}, + ) + return RefreshResult("refreshed", cache) + + +def _conditional_headers(saved: cabc.Mapping[str, object]) -> dict[str, str]: + """Build conditional HTTP headers from persisted validators.""" + headers = {} + if isinstance(saved.get("etag"), str): + headers["If-None-Match"] = saved["etag"] + if isinstance(saved.get("last_modified"), str): + headers["If-Modified-Since"] = saved["last_modified"] + return headers + + +def _https_request( + source: str, + headers: cabc.Mapping[str, str], +) -> urllib.request.Request: + """Build a request after constraining the shared source to HTTPS.""" + if urllib.parse.urlsplit(source).scheme != "https": + message = f"shared dictionary URL must use HTTPS: {source}" + raise ValueError(message) + return urllib.request.Request(source, headers=dict(headers)) # noqa: S310 - HTTPS is required above. + + +def _write_remote_cache( + source: str, + targets: _CacheTargets, + content: bytes, + headers: cabc.Mapping[str, str], +) -> RefreshResult: + """Validate and atomically persist an HTTP dictionary response.""" + _dictionary_from_text(content.decode()) + _atomic_write(targets.cache, content) + _write_metadata( + targets.metadata, + { + "source": source, + "etag": headers.get("ETag"), + "last_modified": headers.get("Last-Modified"), + }, + ) + return RefreshResult("refreshed", targets.cache) + + +def _refresh_http( + source: str, + cache: pathlib.Path, + metadata: pathlib.Path, +) -> RefreshResult: + """Refresh a cache from a validated HTTPS source with stale fallback.""" + saved = _read_metadata(metadata) + request = _https_request(source, _conditional_headers(saved)) + try: + with urllib.request.urlopen( # noqa: S310 - _https_request rejects non-HTTPS URLs. + request, + timeout=30.0, + ) as response: + if response.status == HTTP_NOT_MODIFIED and _valid_cache(cache): + return RefreshResult("current", cache) + if _valid_cache(cache) and _remote_is_not_newer(saved, response.headers): + return RefreshResult("current", cache) + return _write_remote_cache( + source, + _CacheTargets(cache, metadata), + response.read(), + response.headers, + ) + except urllib.error.HTTPError as error: + if error.code == HTTP_NOT_MODIFIED and _valid_cache(cache): + return RefreshResult("current", cache) + if _valid_cache(cache): + return RefreshResult("stale-cache", cache) + raise + except (OSError, urllib.error.URLError): + if _valid_cache(cache): + return RefreshResult("stale-cache", cache) + raise + + +def refresh_base( + source: str | pathlib.Path, + cache: pathlib.Path, + *, + metadata: pathlib.Path, + offline: bool = False, +) -> RefreshResult: + """Refresh an untracked base cache when the authoritative copy is newer.""" + if offline: + if not _valid_cache(cache): + message = f"no cached shared dictionary at {cache}" + raise FileNotFoundError(message) + return RefreshResult("offline-cache", cache) + if isinstance(source, pathlib.Path) or "://" not in str(source): + return _refresh_local(pathlib.Path(source), cache, metadata) + return _refresh_http(str(source), cache, metadata) diff --git a/template/.github/workflows/ci.yml.jinja b/template/.github/workflows/ci.yml.jinja index 1a3b7fe..b071af7 100644 --- a/template/.github/workflows/ci.yml.jinja +++ b/template/.github/workflows/ci.yml.jinja @@ -76,6 +76,9 @@ jobs: - name: Run typechecker run: make typecheck + - name: Check spelling + run: make spelling + - name: Audit dependencies run: make audit diff --git a/template/.gitignore b/template/.gitignore index 4e9999a..70b5992 100644 --- a/template/.gitignore +++ b/template/.gitignore @@ -204,3 +204,7 @@ target/ **/mutants.out*/ .crush/ + +# Untracked cache of the estate-wide en-GB-oxendict dictionary. +.typos-oxendict-base.json +.typos-oxendict-base.toml diff --git a/template/.rules/python-exception-design-raising-handling-and-logging.md b/template/.rules/python-exception-design-raising-handling-and-logging.md index e33d50a..e39da2e 100644 --- a/template/.rules/python-exception-design-raising-handling-and-logging.md +++ b/template/.rules/python-exception-design-raising-handling-and-logging.md @@ -90,7 +90,7 @@ def reciprocal(n: float) -> float: return result ``` -`else` emphasises the happy path and avoids odd control‑flow within `try` +`else` emphasizes the happy path and avoids odd control‑flow within `try` blocks. ## 4) Message construction for raises (EM101/EM102) and logging practice (LOG004/LOG007/LOG009/LOG014/LOG015, TRY401) @@ -110,7 +110,7 @@ raise RuntimeError(msg) EM101/EM102 prefer a single message object; this reduces duplication and clarifies intent. -### Logging: parameterised messages, module loggers, correct APIs +### Logging: parameterized messages, module loggers, correct APIs ```python import logging diff --git a/template/.rules/python-pyproject.md b/template/.rules/python-pyproject.md index 89f8f76..50b20fc 100644 --- a/template/.rules/python-pyproject.md +++ b/template/.rules/python-pyproject.md @@ -228,7 +228,7 @@ package = true Reddit[^5]) - `description`, `readme`, `requires-python`: provide clarity about the project and help tools like PyPI. (Python Packaging[^4], Reddit[^5]) - - `license`, `authors`, `keywords`, `classifiers`: standardised metadata, + - `license`, `authors`, `keywords`, `classifiers`: standardized metadata, which improves discoverability. (Python Packaging[^4], Reddit[^5]) - `dependencies`: runtime requirements, expressed in PEP 508 syntax. (Astral Docs[^1], RidgeRun.ai[^2]) diff --git a/template/.rules/python-typing.md b/template/.rules/python-typing.md index 7962287..8110e7a 100644 --- a/template/.rules/python-typing.md +++ b/template/.rules/python-typing.md @@ -8,7 +8,7 @@ Use `Enum` for fixed sets of related constants. Use `enum.auto()` to avoid repeating values manually. Use `IntEnum` or `StrEnum` when interoperability -with integers or strings is required (e.g. for database or JSON serialisation). +with integers or strings is required (e.g. for database or JSON serialization). ```python import enum diff --git a/template/AGENTS.md.jinja b/template/AGENTS.md.jinja index 220f1e9..520fe98 100644 --- a/template/AGENTS.md.jinja +++ b/template/AGENTS.md.jinja @@ -64,7 +64,7 @@ commit, ensure all of the following are met: - New functionality or behaviour changes are fully validated by relevant unit and behavioural tests. - - Bug fixes include a failing test before the fix and a passing test afterward. + - Bug fixes include a failing test before the fix and a passing test afterwards. - Code passes lint checks. - Formatting is correct and validated. - **For Python files:** @@ -100,10 +100,11 @@ {% endif %} - **Markdown files (`.md` only):** - **Linting:** Passes markdown lint checks (`make markdownlint`). + - **Spelling:** Passes the en-GB-oxendict gate (`make spelling`). - **Mermaid diagrams:** Passes validation using nixie (`make nixie`). - **Committing:** - Only changes that meet all quality gates should be committed. - - Write clear, descriptive commit messages that summarise the change, following: + - Write clear, descriptive commit messages that summarize the change, following: - **Imperative mood** in the subject line (for example, "Fix bug", "Add feature"). - **Subject line length:** around 50 characters or fewer. - **Body:** Separate subject from body with a blank line. Explain *what* and @@ -288,7 +289,7 @@ project: - Use `pytest` fixtures for shared setup in Python work. Use `rstest` fixtures for shared setup in Rust work. - Replace duplicated tests with `#[rstest(...)]` parameterized cases in Rust and - equivalent fixture-driven parameterisation in Python. + equivalent fixture-driven parameterization in Python. - Prefer `mockall` for ad hoc mocks and stubs. - For testing reliant on environment variables, use dependency injection and the `mockable` crate where feasible. If mockable cannot be used, environment @@ -352,7 +353,13 @@ project: ## Markdown guidance -- Validate Markdown files using `make markdownlint`. +- Validate Markdown files using `make markdownlint`. This also runs the pinned + en-GB-oxendict spelling gate. +- The spelling configuration `typos.toml` is generated. Generic Oxford stems + belong in the shared base in `leynos/agent-helper-scripts`; project-specific + accepted words, patterns, and exclusions belong in `typos.local.toml`. + Regenerate with `uv run scripts/generate_typos_config.py` rather than editing + `typos.toml` by hand. - Run `make fmt` after documentation changes to format Markdown and fix table markup. - Validate Mermaid diagrams in Markdown by running `make nixie`. diff --git a/template/Makefile.jinja b/template/Makefile.jinja index 8f1639f..03b565f 100644 --- a/template/Makefile.jinja +++ b/template/Makefile.jinja @@ -9,6 +9,9 @@ USER_BIN_PATH := $(HOME)/.cargo/bin:$(HOME)/.local/bin:$(HOME)/.bun/bin TOOLS = $(MDFORMAT_ALL) $(MDLINT) VENV_TOOLS = pytest UV_ENV = PYO3_USE_ABI3_FORWARD_COMPATIBILITY=1 UV_CACHE_DIR=.uv-cache UV_TOOL_DIR=.uv-tools +TYPOS_VERSION ?= 1.48.0 +TYPOS = env $(UV_ENV) $(UV) tool run typos@$(TYPOS_VERSION) +MD_FILES_FIND = find . -type f -name '*.md' -not -path './.git/*' -print0 WITH_ACT ?= 0 ACT_TEST_ENV = $(if $(filter 1 true yes on,$(WITH_ACT)),RUN_ACT_VALIDATION=1,) PYTEST_XDIST_WORKERS ?= auto @@ -37,11 +40,12 @@ WHITAKER ?= $(or $(shell command -v whitaker 2>/dev/null),$(wildcard $(USER_WHIT {% endif %} .PHONY: help all audit clean build build-release lint lint-python fmt check-fmt \ - markdownlint nixie test typecheck $(TOOLS) $(VENV_TOOLS){% if use_rust %} lint-rust rust-audit whitaker{% endif %} + markdownlint nixie spelling test typecheck $(TOOLS) $(VENV_TOOLS){% if use_rust %} lint-rust rust-audit whitaker{% endif %} .DEFAULT_GOAL := all all: build check-fmt lint typecheck test + +$(MAKE) spelling define ensure_uv @command -v $(UV) >/dev/null 2>&1 || { \ @@ -64,7 +68,8 @@ build-release: ## Build artefacts (sdist & wheel) clean: ## Remove build artifacts rm -rf build dist *.egg-info \ .mypy_cache .pytest_cache .coverage coverage.* \ - lcov.info htmlcov .venv .uv-cache .uv-tools{% if use_rust %} $(RUST_CRATE_DIR)/target{% endif %} + lcov.info htmlcov .venv .uv-cache .uv-tools \ + .typos-oxendict-base.json .typos-oxendict-base.toml{% if use_rust %} $(RUST_CRATE_DIR)/target{% endif %} find . -type d -name '__pycache__' -print0 | xargs -0 -r rm -rf define ensure_tool @@ -159,8 +164,13 @@ rust-audit: ## Audit Rust extension dependencies for known vulnerabilities cd $(RUST_CRATE_DIR) && $(CARGO) audit {% endif %} -markdownlint: $(MDLINT) ## Lint Markdown files +markdownlint: $(MDLINT) ## Lint Markdown files and spelling env -u NO_COLOR $(MDLINT) '**/*.md' + +$(MAKE) spelling + +spelling: ## Enforce en-GB-oxendict spelling + $(UV) run scripts/generate_typos_config.py + $(MD_FILES_FIND) | xargs -0 $(TYPOS) --config typos.toml --force-exclude nixie: ## Validate Mermaid diagrams $(call ensure_tool,$(NIXIE)) diff --git a/template/docs/complexity-antipatterns-and-refactoring-strategies.md b/template/docs/complexity-antipatterns-and-refactoring-strategies.md index 7c0d207..d9a7c3d 100644 --- a/template/docs/complexity-antipatterns-and-refactoring-strategies.md +++ b/template/docs/complexity-antipatterns-and-refactoring-strategies.md @@ -111,7 +111,7 @@ Thresholds and Implications: Code with high Cognitive Complexity is harder to read, understand, test, and modify.[^8] SonarQube, for example, raises issues when a function's Cognitive -Complexity exceeds a certain threshold, signaling that the code should likely +Complexity exceeds a certain threshold, signalling that the code should likely be refactored into smaller, more manageable pieces.[^8] The primary impact of high Cognitive Complexity is a slowdown in development and an increase in maintenance costs.[^8] diff --git a/template/docs/developers-guide.md b/template/docs/developers-guide.md index 98ff017..f92893d 100644 --- a/template/docs/developers-guide.md +++ b/template/docs/developers-guide.md @@ -4,10 +4,10 @@ This guide explains the contributor workflow for the generated project. ## Local workflow -The public entrypoint for formatting, linting, typechecking, and tests is -`make all`. Narrower Make targets may be invoked when investigating a specific -failure, and changes should be reconciled with the aggregate gate before being -considered complete. +The public entrypoint for formatting, linting, typechecking, tests, and spelling +is `make all`. Narrower Make targets may be invoked when investigating a +specific failure, and changes should be reconciled with the aggregate gate +before being considered complete. `make lint` runs Ruff, `interrogate --fail-under 100 $(PYTHON_TARGETS)` for 100% docstring coverage across `$(PYTHON_TARGETS)`, and Pylint. @@ -36,17 +36,17 @@ actions under `.github/`. - `.github/workflows/ci.yml` runs on pushes to `main` and on pull requests. It sets up Python 3.13, installs `uv`, validates the generated `Makefile` with `mbake`, runs `make build`, `make check-fmt`, - `make lint` (Ruff + `interrogate --fail-under 100 $(PYTHON_TARGETS)` + Pylint), `make - typecheck`, and `make audit`, then delegates coverage generation to the shared - coverage action. When the Rust extension is enabled, it also sets up Rust, - installs Rust lint and test tools, and passes `rust_extension/Cargo.toml` to - coverage. + `make lint` (Ruff + `interrogate --fail-under 100 $(PYTHON_TARGETS)` + Pylint), + `make typecheck`, `make spelling`, and `make audit`, then delegates coverage + generation to the shared coverage action. When the Rust extension is enabled, + it also sets up Rust, installs Rust lint and test tools, and passes + `rust_extension/Cargo.toml` to coverage. - `.github/workflows/act-validation.yml` runs rendered workflow validation in a separate workflow. It installs `act`, checks Docker availability, and runs `make test WITH_ACT=1` outside the coverage path. - `.github/workflows/release.yml` publishes wheels when a `v*.*.*` tag is pushed. It builds a pure Python wheel, creates a GitHub release with generated - release notes, downloads wheel artifacts, and uploads them to the tag release. + release notes, downloads wheel artefacts, and uploads them to the tag release. - `.github/workflows/build-wheels.yml` is a reusable workflow for extension builds. It accepts a Python version and builds wheels across Linux, Windows, and macOS architectures via `.github/actions/build-wheels`. @@ -54,9 +54,9 @@ actions under `.github/`. the CodeScene coverage CLI installer, computes its SHA-256 digest, and writes the result to the `CODESCENE_CLI_SHA256` repository variable. - `.github/actions/build-wheels` wraps `cibuildwheel` with `uvx` and uploads - architecture-specific wheel artifacts. + architecture-specific wheel artefacts. - `.github/actions/pure-python-wheel` builds a pure Python wheel with - `uv build --wheel` and uploads the resulting artifact. + `uv build --wheel` and uploads the resulting artefact. - `.github/dependabot.yml` enables dependency update pull requests for GitHub Actions and Python packages. Rust-enabled projects also receive Cargo updates. @@ -64,3 +64,11 @@ The `CS_ACCESS_TOKEN` secret must be configured when CodeScene coverage upload is required. The `CODESCENE_CLI_SHA256` variable should be populated using the refresh workflow, so CI can verify the downloaded CodeScene installer before upload. + +## Shared spelling configuration + +Run `make spelling` to enforce en-GB-oxendict spelling. The generator fetches +the estate-wide base from `leynos/agent-helper-scripts` only when its authority +is newer than the ignored local cache. A populated cache supports offline +generation. Add only project-specific terms and exclusions to +`typos.local.toml`; never edit generated `typos.toml` by hand. diff --git a/template/docs/users-guide.md.jinja b/template/docs/users-guide.md.jinja index ab295e9..c0972b1 100644 --- a/template/docs/users-guide.md.jinja +++ b/template/docs/users-guide.md.jinja @@ -12,6 +12,8 @@ these targets in order: - `lint`: run `lint-python` and, when Rust is enabled, `lint-rust`. - `typecheck`: run `ty check`. - `test`: run pytest and, when Rust is enabled, Rust tests. +- `spelling`: generate shared en-GB-oxendict policy and check Markdown with the + pinned `typos` version. - `audit`: run `pip-audit` and, when Rust is enabled, `cargo audit`. The `lint-python` target runs Ruff, then Interrogate with @@ -20,6 +22,10 @@ coverage for the Python targets, then Pylint via a PyPy-backed runner. The Pylin runner is installed through `uv tool run` from the pinned `pylint-pypy-shim` repository. +The spelling target keeps an ignored shared-base cache and a tracked generated +`typos.toml`. Run `make spelling` directly when updating documentation; a +populated cache remains usable when the shared source is temporarily offline. + Pytest discovery is limited to the top-level `tests/` tree. Keep generated project unit tests there rather than in package module directories or `unittests/` subdirectories, because CI coverage runs through xdist-backed diff --git a/template/scripts/generate_typos_config.py b/template/scripts/generate_typos_config.py new file mode 100644 index 0000000..9c91be4 --- /dev/null +++ b/template/scripts/generate_typos_config.py @@ -0,0 +1,63 @@ +#!/usr/bin/env -S uv run python +# /// script +# requires-python = ">=3.13" +# dependencies = [] +# /// +"""Generate ``typos.toml`` from the shared en-GB-oxendict dictionary. + +The shared dictionary is refreshed into an untracked repository-local cache +only when the authoritative copy is newer. A valid cache remains usable when +the network is unavailable, and ``typos.local.toml`` supplies the narrow +repository-specific policy that must not weaken the estate-wide base. +""" + +from pathlib import Path + +import typos_rollout as rollout + +DEFAULT_BASE_URL = ( + "https://raw.githubusercontent.com/leynos/agent-helper-scripts/" + "refs/heads/main/data/typos-oxendict-base.toml" +) +REPOSITORY_ROOT = Path(__file__).resolve().parent.parent + + +def dictionary_from_cache(repository: Path = REPOSITORY_ROOT) -> rollout.Dictionary: + """Load the cached shared base merged with local repository policy.""" + dictionary = rollout.load_dictionary(repository / ".typos-oxendict-base.toml") + local_overlay = repository / "typos.local.toml" + if local_overlay.exists(): + dictionary = rollout.merge_dictionaries( + dictionary, + rollout.load_dictionary(local_overlay), + ) + return dictionary + + +def render_config(repository: Path = REPOSITORY_ROOT) -> str: + """Render deterministic configuration from the populated local cache.""" + return rollout.render_typos_config(dictionary_from_cache(repository)) + + +def main( + output: Path | None = None, + *, + repository: Path = REPOSITORY_ROOT, + source: str | Path = DEFAULT_BASE_URL, + offline: bool = False, +) -> rollout.RefreshResult: + """Refresh the shared base cache and write the merged configuration.""" + result = rollout.refresh_base( + source, + repository / ".typos-oxendict-base.toml", + metadata=repository / ".typos-oxendict-base.json", + offline=offline, + ) + destination = output if output is not None else repository / "typos.toml" + rollout.write_config(destination, dictionary_from_cache(repository)) + return result + + +if __name__ == "__main__": + refresh = main() + print(f"{refresh.status}: {REPOSITORY_ROOT / 'typos.toml'}") diff --git a/template/scripts/typos_rollout.py b/template/scripts/typos_rollout.py new file mode 100644 index 0000000..8c73cfb --- /dev/null +++ b/template/scripts/typos_rollout.py @@ -0,0 +1,401 @@ +"""Refresh and render shared en-GB-oxendict ``typos`` configuration.""" + +from __future__ import annotations + +import dataclasses +import email.utils +import json +import pathlib +import tempfile +import tomllib +import typing as typ +import urllib.error +import urllib.parse +import urllib.request + +if typ.TYPE_CHECKING: + import collections.abc as cabc + +SCHEMA_VERSION = 1 +HTTP_NOT_MODIFIED = 304 +SUFFIX_PAIRS = ( + ("ise", "ize"), + ("ises", "izes"), + ("ised", "ized"), + ("ising", "izing"), + ("iser", "izer"), + ("isers", "izers"), + ("isable", "izable"), + ("isation", "ization"), + ("isations", "izations"), +) + + +@dataclasses.dataclass(frozen=True) +class Dictionary: + """Curated words and exclusions used to generate a ``typos`` config.""" + + stems: tuple[str, ...] = () + accepted: tuple[str, ...] = () + corrections: tuple[tuple[str, str], ...] = () + ignore_patterns: tuple[str, ...] = () + excluded_files: tuple[str, ...] = () + + +@dataclasses.dataclass(frozen=True) +class RefreshResult: + """Describe whether the untracked shared dictionary cache changed.""" + + status: str + cache: pathlib.Path + + +@dataclasses.dataclass(frozen=True) +class _CacheTargets: + """Group the untracked dictionary cache and metadata sidecar paths.""" + + cache: pathlib.Path + metadata: pathlib.Path + + +def _string_list(table: cabc.Mapping[str, object], key: str) -> tuple[str, ...]: + """Read and validate a list of strings from a TOML table.""" + value = table.get(key, []) + if not isinstance(value, list) or not all(isinstance(item, str) for item in value): + message = f"{key!r} must be a list of strings" + raise TypeError(message) + return tuple(sorted(set(value))) + + +def _table( + document: cabc.Mapping[str, object], + key: str, +) -> cabc.Mapping[str, object]: + """Read and validate a TOML table.""" + value = document.get(key, {}) + if not isinstance(value, dict): + message = f"{key!r} must be a table" + raise TypeError(message) + return value + + +def _dictionary_from_text(text: str) -> Dictionary: + """Parse and validate shared dictionary text.""" + document = tomllib.loads(text) + schema = document.get("schema") + if schema != SCHEMA_VERSION: + message = f"unsupported dictionary schema {schema!r}" + raise ValueError(message) + oxford = _table(document, "oxford") + words = _table(document, "words") + patterns = _table(document, "patterns") + files = _table(document, "files") + corrections_table = _table(words, "corrections") + if not all( + isinstance(key, str) and isinstance(value, str) + for key, value in corrections_table.items() + ): + message = "word corrections must map strings to strings" + raise TypeError(message) + return Dictionary( + stems=_string_list(oxford, "stems"), + accepted=_string_list(words, "accepted"), + corrections=tuple(sorted(corrections_table.items())), + ignore_patterns=_string_list(patterns, "ignore"), + excluded_files=_string_list(files, "exclude"), + ) + + +def load_dictionary(path: pathlib.Path) -> Dictionary: + """Load a validated shared dictionary from *path*.""" + return _dictionary_from_text(path.read_text(encoding="utf-8")) + + +def merge_dictionaries(base: Dictionary, local: Dictionary) -> Dictionary: + """Merge a shared dictionary with a non-conflicting local overlay.""" + corrections = dict(base.corrections) + for word, correction in local.corrections: + existing = corrections.get(word) + if existing is not None and existing != correction: + message = ( + f"conflicting correction for {word!r}: {existing!r} != {correction!r}" + ) + raise ValueError(message) + corrections[word] = correction + return Dictionary( + stems=tuple(sorted(set(base.stems) | set(local.stems))), + accepted=tuple(sorted(set(base.accepted) | set(local.accepted))), + corrections=tuple(sorted(corrections.items())), + ignore_patterns=tuple( + sorted(set(base.ignore_patterns) | set(local.ignore_patterns)) + ), + excluded_files=tuple( + sorted(set(base.excluded_files) | set(local.excluded_files)) + ), + ) + + +def generate_word_mappings(dictionary: Dictionary) -> dict[str, str]: + """Expand Oxford stems and explicit words into deterministic mappings.""" + mappings = {word: word for word in dictionary.accepted} + + def add(word: str, correction: str) -> None: + existing = mappings.get(word) + if existing is not None and existing != correction: + message = ( + f"conflicting generated correction for {word!r}: " + f"{existing!r} != {correction!r}" + ) + raise ValueError(message) + mappings[word] = correction + + for word, correction in dictionary.corrections: + add(word, correction) + for stem in dictionary.stems: + for plain_british, oxford in SUFFIX_PAIRS: + add(f"{stem}{plain_british}", f"{stem}{oxford}") + add(f"{stem}{oxford}", f"{stem}{oxford}") + return dict(sorted(mappings.items())) + + +def _toml_string(value: str) -> str: + """Render a string using TOML-compatible JSON quoting.""" + return json.dumps(value, ensure_ascii=False) + + +def _render_array(name: str, values: tuple[str, ...]) -> list[str]: + """Render a deterministic TOML string array.""" + lines = [f"{name} = ["] + lines.extend(f" {_toml_string(value)}," for value in values) + lines.append("]") + return lines + + +def render_typos_config(dictionary: Dictionary) -> str: + """Render a deterministic, parse-checked ``typos.toml`` document.""" + lines = [ + "# Generated from the shared en-GB-oxendict dictionary.", + "# Regenerate with scripts/generate_typos_config.py; do not edit by hand.", + "", + "[files]", + *_render_array("extend-exclude", dictionary.excluded_files), + "", + "[default]", + 'locale = "en-gb"', + *_render_array("extend-ignore-re", dictionary.ignore_patterns), + "", + "[default.extend-words]", + ] + lines.extend( + f"{_toml_string(word)} = {_toml_string(correction)}" + for word, correction in generate_word_mappings(dictionary).items() + ) + rendered = "\n".join(lines) + "\n" + tomllib.loads(rendered) + return rendered + + +def _atomic_write(path: pathlib.Path, content: bytes) -> None: + """Write *content* beside *path* and atomically replace the destination.""" + path.parent.mkdir(parents=True, exist_ok=True) + with tempfile.NamedTemporaryFile( + delete=False, dir=path.parent, prefix=f".{path.name}." + ) as stream: + stream.write(content) + temporary = pathlib.Path(stream.name) + try: + temporary.replace(path) + finally: + temporary.unlink(missing_ok=True) + + +def write_config(path: pathlib.Path, dictionary: Dictionary) -> None: + """Atomically write validated generated configuration to *path*.""" + _atomic_write(path, render_typos_config(dictionary).encode()) + + +def _read_metadata(path: pathlib.Path) -> dict[str, object]: + """Read best-effort HTTP freshness metadata.""" + try: + value = json.loads(path.read_text(encoding="utf-8")) + except (FileNotFoundError, json.JSONDecodeError): + return {} + return value if isinstance(value, dict) else {} + + +def _write_metadata( + path: pathlib.Path, + metadata: cabc.Mapping[str, object], +) -> None: + """Atomically write HTTP freshness metadata.""" + _atomic_write(path, (json.dumps(metadata, sort_keys=True) + "\n").encode()) + + +def _valid_cache(cache: pathlib.Path) -> bool: + """Return whether *cache* contains a valid shared dictionary.""" + try: + load_dictionary(cache) + except ( + FileNotFoundError, + OSError, + TypeError, + ValueError, + tomllib.TOMLDecodeError, + ): + return False + return True + + +def _remote_is_not_newer( + saved: cabc.Mapping[str, object], + headers: cabc.Mapping[str, str], +) -> bool: + """Return whether HTTP validators prove the response is not newer.""" + etag = headers.get("ETag") + if etag is not None and etag == saved.get("etag"): + return True + modified = headers.get("Last-Modified") + saved_modified = saved.get("last_modified") + if not isinstance(modified, str) or not isinstance(saved_modified, str): + return False + try: + return email.utils.parsedate_to_datetime( + modified + ) <= email.utils.parsedate_to_datetime(saved_modified) + except (TypeError, ValueError): + return modified == saved_modified + + +def _local_cache_is_current( + cache: pathlib.Path, + saved: cabc.Mapping[str, object], + source_name: str, + source_mtime_ns: int, +) -> bool: + """Return whether metadata proves a valid local-source cache is current.""" + saved_mtime = saved.get("mtime_ns") + has_matching_source = saved.get("source") == source_name + has_new_enough_mtime = ( + isinstance(saved_mtime, int) and source_mtime_ns <= saved_mtime + ) + return _valid_cache(cache) and has_matching_source and has_new_enough_mtime + + +def _refresh_local( + source: pathlib.Path, + cache: pathlib.Path, + metadata: pathlib.Path, +) -> RefreshResult: + """Refresh from a local authoritative copy when it is newer.""" + source_stat = source.stat() + source_name = str(source.resolve()) + saved = _read_metadata(metadata) + if _local_cache_is_current( + cache, + saved, + source_name, + source_stat.st_mtime_ns, + ): + return RefreshResult("current", cache) + content = source.read_bytes() + _dictionary_from_text(content.decode()) + _atomic_write(cache, content) + _write_metadata( + metadata, + {"source": source_name, "mtime_ns": source_stat.st_mtime_ns}, + ) + return RefreshResult("refreshed", cache) + + +def _conditional_headers(saved: cabc.Mapping[str, object]) -> dict[str, str]: + """Build conditional HTTP headers from persisted validators.""" + headers = {} + if isinstance(saved.get("etag"), str): + headers["If-None-Match"] = saved["etag"] + if isinstance(saved.get("last_modified"), str): + headers["If-Modified-Since"] = saved["last_modified"] + return headers + + +def _https_request( + source: str, + headers: cabc.Mapping[str, str], +) -> urllib.request.Request: + """Build a request after constraining the shared source to HTTPS.""" + if urllib.parse.urlsplit(source).scheme != "https": + message = f"shared dictionary URL must use HTTPS: {source}" + raise ValueError(message) + return urllib.request.Request(source, headers=dict(headers)) # noqa: S310 - HTTPS is required above. + + +def _write_remote_cache( + source: str, + targets: _CacheTargets, + content: bytes, + headers: cabc.Mapping[str, str], +) -> RefreshResult: + """Validate and atomically persist an HTTP dictionary response.""" + _dictionary_from_text(content.decode()) + _atomic_write(targets.cache, content) + _write_metadata( + targets.metadata, + { + "source": source, + "etag": headers.get("ETag"), + "last_modified": headers.get("Last-Modified"), + }, + ) + return RefreshResult("refreshed", targets.cache) + + +def _refresh_http( + source: str, + cache: pathlib.Path, + metadata: pathlib.Path, +) -> RefreshResult: + """Refresh a cache from a validated HTTPS source with stale fallback.""" + saved = _read_metadata(metadata) + request = _https_request(source, _conditional_headers(saved)) + try: + with urllib.request.urlopen( # noqa: S310 - _https_request rejects non-HTTPS URLs. + request, + timeout=30.0, + ) as response: + if response.status == HTTP_NOT_MODIFIED and _valid_cache(cache): + return RefreshResult("current", cache) + if _valid_cache(cache) and _remote_is_not_newer(saved, response.headers): + return RefreshResult("current", cache) + return _write_remote_cache( + source, + _CacheTargets(cache, metadata), + response.read(), + response.headers, + ) + except urllib.error.HTTPError as error: + if error.code == HTTP_NOT_MODIFIED and _valid_cache(cache): + return RefreshResult("current", cache) + if _valid_cache(cache): + return RefreshResult("stale-cache", cache) + raise + except (OSError, urllib.error.URLError): + if _valid_cache(cache): + return RefreshResult("stale-cache", cache) + raise + + +def refresh_base( + source: str | pathlib.Path, + cache: pathlib.Path, + *, + metadata: pathlib.Path, + offline: bool = False, +) -> RefreshResult: + """Refresh an untracked base cache when the authoritative copy is newer.""" + if offline: + if not _valid_cache(cache): + message = f"no cached shared dictionary at {cache}" + raise FileNotFoundError(message) + return RefreshResult("offline-cache", cache) + if isinstance(source, pathlib.Path) or "://" not in str(source): + return _refresh_local(pathlib.Path(source), cache, metadata) + return _refresh_http(str(source), cache, metadata) diff --git a/template/typos.local.toml b/template/typos.local.toml new file mode 100644 index 0000000..f9a595d --- /dev/null +++ b/template/typos.local.toml @@ -0,0 +1,19 @@ +# Repository-specific identifiers, quotations and deliberate fixtures. + +schema = 1 + +[oxford] +stems = [] + +[words] +accepted = [] + +[words.corrections] + +[patterns] +ignore = [ + 'Center \| Microsoft Learn', +] + +[files] +exclude = [] diff --git a/template/typos.toml b/template/typos.toml new file mode 100644 index 0000000..c85d624 --- /dev/null +++ b/template/typos.toml @@ -0,0 +1,2631 @@ +# Generated from the shared en-GB-oxendict dictionary. +# Regenerate with scripts/generate_typos_config.py; do not edit by hand. + +[files] +extend-exclude = [ + ".git", + ".hypothesis", + ".pytest_cache", + ".tox", + ".typos-oxendict-base.json", + ".typos-oxendict-base.toml", + ".uv-cache", + ".uv-tools", + ".venv", + "Cargo.lock", + "bun.lock", + "data/typos-oxendict-base.toml", + "dist", + "node_modules", + "package-lock.json", + "pnpm-lock.yaml", + "target", + "typos.local.toml", + "typos.toml", + "uv.lock", + "yarn.lock", +] + +[default] +locale = "en-gb" +extend-ignore-re = [ + "(?s)```.*?```", + "Center \\| Microsoft Learn", + "`[^`\\n]+`", +] + +[default.extend-words] +"absolutisable" = "absolutizable" +"absolutisation" = "absolutization" +"absolutisations" = "absolutizations" +"absolutise" = "absolutize" +"absolutised" = "absolutized" +"absolutiser" = "absolutizer" +"absolutisers" = "absolutizers" +"absolutises" = "absolutizes" +"absolutising" = "absolutizing" +"absolutizable" = "absolutizable" +"absolutization" = "absolutization" +"absolutizations" = "absolutizations" +"absolutize" = "absolutize" +"absolutized" = "absolutized" +"absolutizer" = "absolutizer" +"absolutizers" = "absolutizers" +"absolutizes" = "absolutizes" +"absolutizing" = "absolutizing" +"actualisable" = "actualizable" +"actualisation" = "actualization" +"actualisations" = "actualizations" +"actualise" = "actualize" +"actualised" = "actualized" +"actualiser" = "actualizer" +"actualisers" = "actualizers" +"actualises" = "actualizes" +"actualising" = "actualizing" +"actualizable" = "actualizable" +"actualization" = "actualization" +"actualizations" = "actualizations" +"actualize" = "actualize" +"actualized" = "actualized" +"actualizer" = "actualizer" +"actualizers" = "actualizers" +"actualizes" = "actualizes" +"actualizing" = "actualizing" +"alphabetisable" = "alphabetizable" +"alphabetisation" = "alphabetization" +"alphabetisations" = "alphabetizations" +"alphabetise" = "alphabetize" +"alphabetised" = "alphabetized" +"alphabetiser" = "alphabetizer" +"alphabetisers" = "alphabetizers" +"alphabetises" = "alphabetizes" +"alphabetising" = "alphabetizing" +"alphabetizable" = "alphabetizable" +"alphabetization" = "alphabetization" +"alphabetizations" = "alphabetizations" +"alphabetize" = "alphabetize" +"alphabetized" = "alphabetized" +"alphabetizer" = "alphabetizer" +"alphabetizers" = "alphabetizers" +"alphabetizes" = "alphabetizes" +"alphabetizing" = "alphabetizing" +"amortisable" = "amortizable" +"amortisation" = "amortization" +"amortisations" = "amortizations" +"amortise" = "amortize" +"amortised" = "amortized" +"amortiser" = "amortizer" +"amortisers" = "amortizers" +"amortises" = "amortizes" +"amortising" = "amortizing" +"amortizable" = "amortizable" +"amortization" = "amortization" +"amortizations" = "amortizations" +"amortize" = "amortize" +"amortized" = "amortized" +"amortizer" = "amortizer" +"amortizers" = "amortizers" +"amortizes" = "amortizes" +"amortizing" = "amortizing" +"anonymisable" = "anonymizable" +"anonymisation" = "anonymization" +"anonymisations" = "anonymizations" +"anonymise" = "anonymize" +"anonymised" = "anonymized" +"anonymiser" = "anonymizer" +"anonymisers" = "anonymizers" +"anonymises" = "anonymizes" +"anonymising" = "anonymizing" +"anonymizable" = "anonymizable" +"anonymization" = "anonymization" +"anonymizations" = "anonymizations" +"anonymize" = "anonymize" +"anonymized" = "anonymized" +"anonymizer" = "anonymizer" +"anonymizers" = "anonymizers" +"anonymizes" = "anonymizes" +"anonymizing" = "anonymizing" +"apologisable" = "apologizable" +"apologisation" = "apologization" +"apologisations" = "apologizations" +"apologise" = "apologize" +"apologised" = "apologized" +"apologiser" = "apologizer" +"apologisers" = "apologizers" +"apologises" = "apologizes" +"apologising" = "apologizing" +"apologizable" = "apologizable" +"apologization" = "apologization" +"apologizations" = "apologizations" +"apologize" = "apologize" +"apologized" = "apologized" +"apologizer" = "apologizer" +"apologizers" = "apologizers" +"apologizes" = "apologizes" +"apologizing" = "apologizing" +"atomisable" = "atomizable" +"atomisation" = "atomization" +"atomisations" = "atomizations" +"atomise" = "atomize" +"atomised" = "atomized" +"atomiser" = "atomizer" +"atomisers" = "atomizers" +"atomises" = "atomizes" +"atomising" = "atomizing" +"atomizable" = "atomizable" +"atomization" = "atomization" +"atomizations" = "atomizations" +"atomize" = "atomize" +"atomized" = "atomized" +"atomizer" = "atomizer" +"atomizers" = "atomizers" +"atomizes" = "atomizes" +"atomizing" = "atomizing" +"authorisable" = "authorizable" +"authorisation" = "authorization" +"authorisations" = "authorizations" +"authorise" = "authorize" +"authorised" = "authorized" +"authoriser" = "authorizer" +"authorisers" = "authorizers" +"authorises" = "authorizes" +"authorising" = "authorizing" +"authorizable" = "authorizable" +"authorization" = "authorization" +"authorizations" = "authorizations" +"authorize" = "authorize" +"authorized" = "authorized" +"authorizer" = "authorizer" +"authorizers" = "authorizers" +"authorizes" = "authorizes" +"authorizing" = "authorizing" +"canonicalisable" = "canonicalizable" +"canonicalisation" = "canonicalization" +"canonicalisations" = "canonicalizations" +"canonicalise" = "canonicalize" +"canonicalised" = "canonicalized" +"canonicaliser" = "canonicalizer" +"canonicalisers" = "canonicalizers" +"canonicalises" = "canonicalizes" +"canonicalising" = "canonicalizing" +"canonicalizable" = "canonicalizable" +"canonicalization" = "canonicalization" +"canonicalizations" = "canonicalizations" +"canonicalize" = "canonicalize" +"canonicalized" = "canonicalized" +"canonicalizer" = "canonicalizer" +"canonicalizers" = "canonicalizers" +"canonicalizes" = "canonicalizes" +"canonicalizing" = "canonicalizing" +"capitalisable" = "capitalizable" +"capitalisation" = "capitalization" +"capitalisations" = "capitalizations" +"capitalise" = "capitalize" +"capitalised" = "capitalized" +"capitaliser" = "capitalizer" +"capitalisers" = "capitalizers" +"capitalises" = "capitalizes" +"capitalising" = "capitalizing" +"capitalizable" = "capitalizable" +"capitalization" = "capitalization" +"capitalizations" = "capitalizations" +"capitalize" = "capitalize" +"capitalized" = "capitalized" +"capitalizer" = "capitalizer" +"capitalizers" = "capitalizers" +"capitalizes" = "capitalizes" +"capitalizing" = "capitalizing" +"categorisable" = "categorizable" +"categorisation" = "categorization" +"categorisations" = "categorizations" +"categorise" = "categorize" +"categorised" = "categorized" +"categoriser" = "categorizer" +"categorisers" = "categorizers" +"categorises" = "categorizes" +"categorising" = "categorizing" +"categorizable" = "categorizable" +"categorization" = "categorization" +"categorizations" = "categorizations" +"categorize" = "categorize" +"categorized" = "categorized" +"categorizer" = "categorizer" +"categorizers" = "categorizers" +"categorizes" = "categorizes" +"categorizing" = "categorizing" +"centralisable" = "centralizable" +"centralisation" = "centralization" +"centralisations" = "centralizations" +"centralise" = "centralize" +"centralised" = "centralized" +"centraliser" = "centralizer" +"centralisers" = "centralizers" +"centralises" = "centralizes" +"centralising" = "centralizing" +"centralizable" = "centralizable" +"centralization" = "centralization" +"centralizations" = "centralizations" +"centralize" = "centralize" +"centralized" = "centralized" +"centralizer" = "centralizer" +"centralizers" = "centralizers" +"centralizes" = "centralizes" +"centralizing" = "centralizing" +"characterisable" = "characterizable" +"characterisation" = "characterization" +"characterisations" = "characterizations" +"characterise" = "characterize" +"characterised" = "characterized" +"characteriser" = "characterizer" +"characterisers" = "characterizers" +"characterises" = "characterizes" +"characterising" = "characterizing" +"characterizable" = "characterizable" +"characterization" = "characterization" +"characterizations" = "characterizations" +"characterize" = "characterize" +"characterized" = "characterized" +"characterizer" = "characterizer" +"characterizers" = "characterizers" +"characterizes" = "characterizes" +"characterizing" = "characterizing" +"civilisable" = "civilizable" +"civilisation" = "civilization" +"civilisations" = "civilizations" +"civilise" = "civilize" +"civilised" = "civilized" +"civiliser" = "civilizer" +"civilisers" = "civilizers" +"civilises" = "civilizes" +"civilising" = "civilizing" +"civilizable" = "civilizable" +"civilization" = "civilization" +"civilizations" = "civilizations" +"civilize" = "civilize" +"civilized" = "civilized" +"civilizer" = "civilizer" +"civilizers" = "civilizers" +"civilizes" = "civilizes" +"civilizing" = "civilizing" +"colonisable" = "colonizable" +"colonisation" = "colonization" +"colonisations" = "colonizations" +"colonise" = "colonize" +"colonised" = "colonized" +"coloniser" = "colonizer" +"colonisers" = "colonizers" +"colonises" = "colonizes" +"colonising" = "colonizing" +"colonizable" = "colonizable" +"colonization" = "colonization" +"colonizations" = "colonizations" +"colonize" = "colonize" +"colonized" = "colonized" +"colonizer" = "colonizer" +"colonizers" = "colonizers" +"colonizes" = "colonizes" +"colonizing" = "colonizing" +"colourisable" = "colourizable" +"colourisation" = "colourization" +"colourisations" = "colourizations" +"colourise" = "colourize" +"colourised" = "colourized" +"colouriser" = "colourizer" +"colourisers" = "colourizers" +"colourises" = "colourizes" +"colourising" = "colourizing" +"colourizable" = "colourizable" +"colourization" = "colourization" +"colourizations" = "colourizations" +"colourize" = "colourize" +"colourized" = "colourized" +"colourizer" = "colourizer" +"colourizers" = "colourizers" +"colourizes" = "colourizes" +"colourizing" = "colourizing" +"commonisable" = "commonizable" +"commonisation" = "commonization" +"commonisations" = "commonizations" +"commonise" = "commonize" +"commonised" = "commonized" +"commoniser" = "commonizer" +"commonisers" = "commonizers" +"commonises" = "commonizes" +"commonising" = "commonizing" +"commonizable" = "commonizable" +"commonization" = "commonization" +"commonizations" = "commonizations" +"commonize" = "commonize" +"commonized" = "commonized" +"commonizer" = "commonizer" +"commonizers" = "commonizers" +"commonizes" = "commonizes" +"commonizing" = "commonizing" +"conceptualisable" = "conceptualizable" +"conceptualisation" = "conceptualization" +"conceptualisations" = "conceptualizations" +"conceptualise" = "conceptualize" +"conceptualised" = "conceptualized" +"conceptualiser" = "conceptualizer" +"conceptualisers" = "conceptualizers" +"conceptualises" = "conceptualizes" +"conceptualising" = "conceptualizing" +"conceptualizable" = "conceptualizable" +"conceptualization" = "conceptualization" +"conceptualizations" = "conceptualizations" +"conceptualize" = "conceptualize" +"conceptualized" = "conceptualized" +"conceptualizer" = "conceptualizer" +"conceptualizers" = "conceptualizers" +"conceptualizes" = "conceptualizes" +"conceptualizing" = "conceptualizing" +"concretisable" = "concretizable" +"concretisation" = "concretization" +"concretisations" = "concretizations" +"concretise" = "concretize" +"concretised" = "concretized" +"concretiser" = "concretizer" +"concretisers" = "concretizers" +"concretises" = "concretizes" +"concretising" = "concretizing" +"concretizable" = "concretizable" +"concretization" = "concretization" +"concretizations" = "concretizations" +"concretize" = "concretize" +"concretized" = "concretized" +"concretizer" = "concretizer" +"concretizers" = "concretizers" +"concretizes" = "concretizes" +"concretizing" = "concretizing" +"containerisable" = "containerizable" +"containerisation" = "containerization" +"containerisations" = "containerizations" +"containerise" = "containerize" +"containerised" = "containerized" +"containeriser" = "containerizer" +"containerisers" = "containerizers" +"containerises" = "containerizes" +"containerising" = "containerizing" +"containerizable" = "containerizable" +"containerization" = "containerization" +"containerizations" = "containerizations" +"containerize" = "containerize" +"containerized" = "containerized" +"containerizer" = "containerizer" +"containerizers" = "containerizers" +"containerizes" = "containerizes" +"containerizing" = "containerizing" +"contextualisable" = "contextualizable" +"contextualisation" = "contextualization" +"contextualisations" = "contextualizations" +"contextualise" = "contextualize" +"contextualised" = "contextualized" +"contextualiser" = "contextualizer" +"contextualisers" = "contextualizers" +"contextualises" = "contextualizes" +"contextualising" = "contextualizing" +"contextualizable" = "contextualizable" +"contextualization" = "contextualization" +"contextualizations" = "contextualizations" +"contextualize" = "contextualize" +"contextualized" = "contextualized" +"contextualizer" = "contextualizer" +"contextualizers" = "contextualizers" +"contextualizes" = "contextualizes" +"contextualizing" = "contextualizing" +"criticisable" = "criticizable" +"criticisation" = "criticization" +"criticisations" = "criticizations" +"criticise" = "criticize" +"criticised" = "criticized" +"criticiser" = "criticizer" +"criticisers" = "criticizers" +"criticises" = "criticizes" +"criticising" = "criticizing" +"criticizable" = "criticizable" +"criticization" = "criticization" +"criticizations" = "criticizations" +"criticize" = "criticize" +"criticized" = "criticized" +"criticizer" = "criticizer" +"criticizers" = "criticizers" +"criticizes" = "criticizes" +"criticizing" = "criticizing" +"crystallisable" = "crystallizable" +"crystallisation" = "crystallization" +"crystallisations" = "crystallizations" +"crystallise" = "crystallize" +"crystallised" = "crystallized" +"crystalliser" = "crystallizer" +"crystallisers" = "crystallizers" +"crystallises" = "crystallizes" +"crystallising" = "crystallizing" +"crystallizable" = "crystallizable" +"crystallization" = "crystallization" +"crystallizations" = "crystallizations" +"crystallize" = "crystallize" +"crystallized" = "crystallized" +"crystallizer" = "crystallizer" +"crystallizers" = "crystallizers" +"crystallizes" = "crystallizes" +"crystallizing" = "crystallizing" +"customisable" = "customizable" +"customisation" = "customization" +"customisations" = "customizations" +"customise" = "customize" +"customised" = "customized" +"customiser" = "customizer" +"customisers" = "customizers" +"customises" = "customizes" +"customising" = "customizing" +"customizable" = "customizable" +"customization" = "customization" +"customizations" = "customizations" +"customize" = "customize" +"customized" = "customized" +"customizer" = "customizer" +"customizers" = "customizers" +"customizes" = "customizes" +"customizing" = "customizing" +"daemonisable" = "daemonizable" +"daemonisation" = "daemonization" +"daemonisations" = "daemonizations" +"daemonise" = "daemonize" +"daemonised" = "daemonized" +"daemoniser" = "daemonizer" +"daemonisers" = "daemonizers" +"daemonises" = "daemonizes" +"daemonising" = "daemonizing" +"daemonizable" = "daemonizable" +"daemonization" = "daemonization" +"daemonizations" = "daemonizations" +"daemonize" = "daemonize" +"daemonized" = "daemonized" +"daemonizer" = "daemonizer" +"daemonizers" = "daemonizers" +"daemonizes" = "daemonizes" +"daemonizing" = "daemonizing" +"decentralisable" = "decentralizable" +"decentralisation" = "decentralization" +"decentralisations" = "decentralizations" +"decentralise" = "decentralize" +"decentralised" = "decentralized" +"decentraliser" = "decentralizer" +"decentralisers" = "decentralizers" +"decentralises" = "decentralizes" +"decentralising" = "decentralizing" +"decentralizable" = "decentralizable" +"decentralization" = "decentralization" +"decentralizations" = "decentralizations" +"decentralize" = "decentralize" +"decentralized" = "decentralized" +"decentralizer" = "decentralizer" +"decentralizers" = "decentralizers" +"decentralizes" = "decentralizes" +"decentralizing" = "decentralizing" +"denormalisable" = "denormalizable" +"denormalisation" = "denormalization" +"denormalisations" = "denormalizations" +"denormalise" = "denormalize" +"denormalised" = "denormalized" +"denormaliser" = "denormalizer" +"denormalisers" = "denormalizers" +"denormalises" = "denormalizes" +"denormalising" = "denormalizing" +"denormalizable" = "denormalizable" +"denormalization" = "denormalization" +"denormalizations" = "denormalizations" +"denormalize" = "denormalize" +"denormalized" = "denormalized" +"denormalizer" = "denormalizer" +"denormalizers" = "denormalizers" +"denormalizes" = "denormalizes" +"denormalizing" = "denormalizing" +"derandomisable" = "derandomizable" +"derandomisation" = "derandomization" +"derandomisations" = "derandomizations" +"derandomise" = "derandomize" +"derandomised" = "derandomized" +"derandomiser" = "derandomizer" +"derandomisers" = "derandomizers" +"derandomises" = "derandomizes" +"derandomising" = "derandomizing" +"derandomizable" = "derandomizable" +"derandomization" = "derandomization" +"derandomizations" = "derandomizations" +"derandomize" = "derandomize" +"derandomized" = "derandomized" +"derandomizer" = "derandomizer" +"derandomizers" = "derandomizers" +"derandomizes" = "derandomizes" +"derandomizing" = "derandomizing" +"deserialisable" = "deserializable" +"deserialisation" = "deserialization" +"deserialisations" = "deserializations" +"deserialise" = "deserialize" +"deserialised" = "deserialized" +"deserialiser" = "deserializer" +"deserialisers" = "deserializers" +"deserialises" = "deserializes" +"deserialising" = "deserializing" +"deserializable" = "deserializable" +"deserialization" = "deserialization" +"deserializations" = "deserializations" +"deserialize" = "deserialize" +"deserialized" = "deserialized" +"deserializer" = "deserializer" +"deserializers" = "deserializers" +"deserializes" = "deserializes" +"deserializing" = "deserializing" +"destabilisable" = "destabilizable" +"destabilisation" = "destabilization" +"destabilisations" = "destabilizations" +"destabilise" = "destabilize" +"destabilised" = "destabilized" +"destabiliser" = "destabilizer" +"destabilisers" = "destabilizers" +"destabilises" = "destabilizes" +"destabilising" = "destabilizing" +"destabilizable" = "destabilizable" +"destabilization" = "destabilization" +"destabilizations" = "destabilizations" +"destabilize" = "destabilize" +"destabilized" = "destabilized" +"destabilizer" = "destabilizer" +"destabilizers" = "destabilizers" +"destabilizes" = "destabilizes" +"destabilizing" = "destabilizing" +"desynchronisable" = "desynchronizable" +"desynchronisation" = "desynchronization" +"desynchronisations" = "desynchronizations" +"desynchronise" = "desynchronize" +"desynchronised" = "desynchronized" +"desynchroniser" = "desynchronizer" +"desynchronisers" = "desynchronizers" +"desynchronises" = "desynchronizes" +"desynchronising" = "desynchronizing" +"desynchronizable" = "desynchronizable" +"desynchronization" = "desynchronization" +"desynchronizations" = "desynchronizations" +"desynchronize" = "desynchronize" +"desynchronized" = "desynchronized" +"desynchronizer" = "desynchronizer" +"desynchronizers" = "desynchronizers" +"desynchronizes" = "desynchronizes" +"desynchronizing" = "desynchronizing" +"dockerisable" = "dockerizable" +"dockerisation" = "dockerization" +"dockerisations" = "dockerizations" +"dockerise" = "dockerize" +"dockerised" = "dockerized" +"dockeriser" = "dockerizer" +"dockerisers" = "dockerizers" +"dockerises" = "dockerizes" +"dockerising" = "dockerizing" +"dockerizable" = "dockerizable" +"dockerization" = "dockerization" +"dockerizations" = "dockerizations" +"dockerize" = "dockerize" +"dockerized" = "dockerized" +"dockerizer" = "dockerizer" +"dockerizers" = "dockerizers" +"dockerizes" = "dockerizes" +"dockerizing" = "dockerizing" +"dramatisable" = "dramatizable" +"dramatisation" = "dramatization" +"dramatisations" = "dramatizations" +"dramatise" = "dramatize" +"dramatised" = "dramatized" +"dramatiser" = "dramatizer" +"dramatisers" = "dramatizers" +"dramatises" = "dramatizes" +"dramatising" = "dramatizing" +"dramatizable" = "dramatizable" +"dramatization" = "dramatization" +"dramatizations" = "dramatizations" +"dramatize" = "dramatize" +"dramatized" = "dramatized" +"dramatizer" = "dramatizer" +"dramatizers" = "dramatizers" +"dramatizes" = "dramatizes" +"dramatizing" = "dramatizing" +"emphasisable" = "emphasizable" +"emphasisation" = "emphasization" +"emphasisations" = "emphasizations" +"emphasise" = "emphasize" +"emphasised" = "emphasized" +"emphasiser" = "emphasizer" +"emphasisers" = "emphasizers" +"emphasises" = "emphasizes" +"emphasising" = "emphasizing" +"emphasizable" = "emphasizable" +"emphasization" = "emphasization" +"emphasizations" = "emphasizations" +"emphasize" = "emphasize" +"emphasized" = "emphasized" +"emphasizer" = "emphasizer" +"emphasizers" = "emphasizers" +"emphasizes" = "emphasizes" +"emphasizing" = "emphasizing" +"energisable" = "energizable" +"energisation" = "energization" +"energisations" = "energizations" +"energise" = "energize" +"energised" = "energized" +"energiser" = "energizer" +"energisers" = "energizers" +"energises" = "energizes" +"energising" = "energizing" +"energizable" = "energizable" +"energization" = "energization" +"energizations" = "energizations" +"energize" = "energize" +"energized" = "energized" +"energizer" = "energizer" +"energizers" = "energizers" +"energizes" = "energizes" +"energizing" = "energizing" +"equalisable" = "equalizable" +"equalisation" = "equalization" +"equalisations" = "equalizations" +"equalise" = "equalize" +"equalised" = "equalized" +"equaliser" = "equalizer" +"equalisers" = "equalizers" +"equalises" = "equalizes" +"equalising" = "equalizing" +"equalizable" = "equalizable" +"equalization" = "equalization" +"equalizations" = "equalizations" +"equalize" = "equalize" +"equalized" = "equalized" +"equalizer" = "equalizer" +"equalizers" = "equalizers" +"equalizes" = "equalizes" +"equalizing" = "equalizing" +"externalisable" = "externalizable" +"externalisation" = "externalization" +"externalisations" = "externalizations" +"externalise" = "externalize" +"externalised" = "externalized" +"externaliser" = "externalizer" +"externalisers" = "externalizers" +"externalises" = "externalizes" +"externalising" = "externalizing" +"externalizable" = "externalizable" +"externalization" = "externalization" +"externalizations" = "externalizations" +"externalize" = "externalize" +"externalized" = "externalized" +"externalizer" = "externalizer" +"externalizers" = "externalizers" +"externalizes" = "externalizes" +"externalizing" = "externalizing" +"factorisable" = "factorizable" +"factorisation" = "factorization" +"factorisations" = "factorizations" +"factorise" = "factorize" +"factorised" = "factorized" +"factoriser" = "factorizer" +"factorisers" = "factorizers" +"factorises" = "factorizes" +"factorising" = "factorizing" +"factorizable" = "factorizable" +"factorization" = "factorization" +"factorizations" = "factorizations" +"factorize" = "factorize" +"factorized" = "factorized" +"factorizer" = "factorizer" +"factorizers" = "factorizers" +"factorizes" = "factorizes" +"factorizing" = "factorizing" +"familiarisable" = "familiarizable" +"familiarisation" = "familiarization" +"familiarisations" = "familiarizations" +"familiarise" = "familiarize" +"familiarised" = "familiarized" +"familiariser" = "familiarizer" +"familiarisers" = "familiarizers" +"familiarises" = "familiarizes" +"familiarising" = "familiarizing" +"familiarizable" = "familiarizable" +"familiarization" = "familiarization" +"familiarizations" = "familiarizations" +"familiarize" = "familiarize" +"familiarized" = "familiarized" +"familiarizer" = "familiarizer" +"familiarizers" = "familiarizers" +"familiarizes" = "familiarizes" +"familiarizing" = "familiarizing" +"finalisable" = "finalizable" +"finalisation" = "finalization" +"finalisations" = "finalizations" +"finalise" = "finalize" +"finalised" = "finalized" +"finaliser" = "finalizer" +"finalisers" = "finalizers" +"finalises" = "finalizes" +"finalising" = "finalizing" +"finalizable" = "finalizable" +"finalization" = "finalization" +"finalizations" = "finalizations" +"finalize" = "finalize" +"finalized" = "finalized" +"finalizer" = "finalizer" +"finalizers" = "finalizers" +"finalizes" = "finalizes" +"finalizing" = "finalizing" +"formalisable" = "formalizable" +"formalisation" = "formalization" +"formalisations" = "formalizations" +"formalise" = "formalize" +"formalised" = "formalized" +"formaliser" = "formalizer" +"formalisers" = "formalizers" +"formalises" = "formalizes" +"formalising" = "formalizing" +"formalizable" = "formalizable" +"formalization" = "formalization" +"formalizations" = "formalizations" +"formalize" = "formalize" +"formalized" = "formalized" +"formalizer" = "formalizer" +"formalizers" = "formalizers" +"formalizes" = "formalizes" +"formalizing" = "formalizing" +"fossilisable" = "fossilizable" +"fossilisation" = "fossilization" +"fossilisations" = "fossilizations" +"fossilise" = "fossilize" +"fossilised" = "fossilized" +"fossiliser" = "fossilizer" +"fossilisers" = "fossilizers" +"fossilises" = "fossilizes" +"fossilising" = "fossilizing" +"fossilizable" = "fossilizable" +"fossilization" = "fossilization" +"fossilizations" = "fossilizations" +"fossilize" = "fossilize" +"fossilized" = "fossilized" +"fossilizer" = "fossilizer" +"fossilizers" = "fossilizers" +"fossilizes" = "fossilizes" +"fossilizing" = "fossilizing" +"generalisable" = "generalizable" +"generalisation" = "generalization" +"generalisations" = "generalizations" +"generalise" = "generalize" +"generalised" = "generalized" +"generaliser" = "generalizer" +"generalisers" = "generalizers" +"generalises" = "generalizes" +"generalising" = "generalizing" +"generalizable" = "generalizable" +"generalization" = "generalization" +"generalizations" = "generalizations" +"generalize" = "generalize" +"generalized" = "generalized" +"generalizer" = "generalizer" +"generalizers" = "generalizers" +"generalizes" = "generalizes" +"generalizing" = "generalizing" +"globalisable" = "globalizable" +"globalisation" = "globalization" +"globalisations" = "globalizations" +"globalise" = "globalize" +"globalised" = "globalized" +"globaliser" = "globalizer" +"globalisers" = "globalizers" +"globalises" = "globalizes" +"globalising" = "globalizing" +"globalizable" = "globalizable" +"globalization" = "globalization" +"globalizations" = "globalizations" +"globalize" = "globalize" +"globalized" = "globalized" +"globalizer" = "globalizer" +"globalizers" = "globalizers" +"globalizes" = "globalizes" +"globalizing" = "globalizing" +"harmonisable" = "harmonizable" +"harmonisation" = "harmonization" +"harmonisations" = "harmonizations" +"harmonise" = "harmonize" +"harmonised" = "harmonized" +"harmoniser" = "harmonizer" +"harmonisers" = "harmonizers" +"harmonises" = "harmonizes" +"harmonising" = "harmonizing" +"harmonizable" = "harmonizable" +"harmonization" = "harmonization" +"harmonizations" = "harmonizations" +"harmonize" = "harmonize" +"harmonized" = "harmonized" +"harmonizer" = "harmonizer" +"harmonizers" = "harmonizers" +"harmonizes" = "harmonizes" +"harmonizing" = "harmonizing" +"homogenisable" = "homogenizable" +"homogenisation" = "homogenization" +"homogenisations" = "homogenizations" +"homogenise" = "homogenize" +"homogenised" = "homogenized" +"homogeniser" = "homogenizer" +"homogenisers" = "homogenizers" +"homogenises" = "homogenizes" +"homogenising" = "homogenizing" +"homogenizable" = "homogenizable" +"homogenization" = "homogenization" +"homogenizations" = "homogenizations" +"homogenize" = "homogenize" +"homogenized" = "homogenized" +"homogenizer" = "homogenizer" +"homogenizers" = "homogenizers" +"homogenizes" = "homogenizes" +"homogenizing" = "homogenizing" +"humanisable" = "humanizable" +"humanisation" = "humanization" +"humanisations" = "humanizations" +"humanise" = "humanize" +"humanised" = "humanized" +"humaniser" = "humanizer" +"humanisers" = "humanizers" +"humanises" = "humanizes" +"humanising" = "humanizing" +"humanizable" = "humanizable" +"humanization" = "humanization" +"humanizations" = "humanizations" +"humanize" = "humanize" +"humanized" = "humanized" +"humanizer" = "humanizer" +"humanizers" = "humanizers" +"humanizes" = "humanizes" +"humanizing" = "humanizing" +"hypothesisable" = "hypothesizable" +"hypothesisation" = "hypothesization" +"hypothesisations" = "hypothesizations" +"hypothesise" = "hypothesize" +"hypothesised" = "hypothesized" +"hypothesiser" = "hypothesizer" +"hypothesisers" = "hypothesizers" +"hypothesises" = "hypothesizes" +"hypothesising" = "hypothesizing" +"hypothesizable" = "hypothesizable" +"hypothesization" = "hypothesization" +"hypothesizations" = "hypothesizations" +"hypothesize" = "hypothesize" +"hypothesized" = "hypothesized" +"hypothesizer" = "hypothesizer" +"hypothesizers" = "hypothesizers" +"hypothesizes" = "hypothesizes" +"hypothesizing" = "hypothesizing" +"idealisable" = "idealizable" +"idealisation" = "idealization" +"idealisations" = "idealizations" +"idealise" = "idealize" +"idealised" = "idealized" +"idealiser" = "idealizer" +"idealisers" = "idealizers" +"idealises" = "idealizes" +"idealising" = "idealizing" +"idealizable" = "idealizable" +"idealization" = "idealization" +"idealizations" = "idealizations" +"idealize" = "idealize" +"idealized" = "idealized" +"idealizer" = "idealizer" +"idealizers" = "idealizers" +"idealizes" = "idealizes" +"idealizing" = "idealizing" +"industrialisable" = "industrializable" +"industrialisation" = "industrialization" +"industrialisations" = "industrializations" +"industrialise" = "industrialize" +"industrialised" = "industrialized" +"industrialiser" = "industrializer" +"industrialisers" = "industrializers" +"industrialises" = "industrializes" +"industrialising" = "industrializing" +"industrializable" = "industrializable" +"industrialization" = "industrialization" +"industrializations" = "industrializations" +"industrialize" = "industrialize" +"industrialized" = "industrialized" +"industrializer" = "industrializer" +"industrializers" = "industrializers" +"industrializes" = "industrializes" +"industrializing" = "industrializing" +"initialisable" = "initializable" +"initialisation" = "initialization" +"initialisations" = "initializations" +"initialise" = "initialize" +"initialised" = "initialized" +"initialiser" = "initializer" +"initialisers" = "initializers" +"initialises" = "initializes" +"initialising" = "initializing" +"initializable" = "initializable" +"initialization" = "initialization" +"initializations" = "initializations" +"initialize" = "initialize" +"initialized" = "initialized" +"initializer" = "initializer" +"initializers" = "initializers" +"initializes" = "initializes" +"initializing" = "initializing" +"institutionalisable" = "institutionalizable" +"institutionalisation" = "institutionalization" +"institutionalisations" = "institutionalizations" +"institutionalise" = "institutionalize" +"institutionalised" = "institutionalized" +"institutionaliser" = "institutionalizer" +"institutionalisers" = "institutionalizers" +"institutionalises" = "institutionalizes" +"institutionalising" = "institutionalizing" +"institutionalizable" = "institutionalizable" +"institutionalization" = "institutionalization" +"institutionalizations" = "institutionalizations" +"institutionalize" = "institutionalize" +"institutionalized" = "institutionalized" +"institutionalizer" = "institutionalizer" +"institutionalizers" = "institutionalizers" +"institutionalizes" = "institutionalizes" +"institutionalizing" = "institutionalizing" +"internalisable" = "internalizable" +"internalisation" = "internalization" +"internalisations" = "internalizations" +"internalise" = "internalize" +"internalised" = "internalized" +"internaliser" = "internalizer" +"internalisers" = "internalizers" +"internalises" = "internalizes" +"internalising" = "internalizing" +"internalizable" = "internalizable" +"internalization" = "internalization" +"internalizations" = "internalizations" +"internalize" = "internalize" +"internalized" = "internalized" +"internalizer" = "internalizer" +"internalizers" = "internalizers" +"internalizes" = "internalizes" +"internalizing" = "internalizing" +"internationalisable" = "internationalizable" +"internationalisation" = "internationalization" +"internationalisations" = "internationalizations" +"internationalise" = "internationalize" +"internationalised" = "internationalized" +"internationaliser" = "internationalizer" +"internationalisers" = "internationalizers" +"internationalises" = "internationalizes" +"internationalising" = "internationalizing" +"internationalizable" = "internationalizable" +"internationalization" = "internationalization" +"internationalizations" = "internationalizations" +"internationalize" = "internationalize" +"internationalized" = "internationalized" +"internationalizer" = "internationalizer" +"internationalizers" = "internationalizers" +"internationalizes" = "internationalizes" +"internationalizing" = "internationalizing" +"itemisable" = "itemizable" +"itemisation" = "itemization" +"itemisations" = "itemizations" +"itemise" = "itemize" +"itemised" = "itemized" +"itemiser" = "itemizer" +"itemisers" = "itemizers" +"itemises" = "itemizes" +"itemising" = "itemizing" +"itemizable" = "itemizable" +"itemization" = "itemization" +"itemizations" = "itemizations" +"itemize" = "itemize" +"itemized" = "itemized" +"itemizer" = "itemizer" +"itemizers" = "itemizers" +"itemizes" = "itemizes" +"itemizing" = "itemizing" +"jeopardisable" = "jeopardizable" +"jeopardisation" = "jeopardization" +"jeopardisations" = "jeopardizations" +"jeopardise" = "jeopardize" +"jeopardised" = "jeopardized" +"jeopardiser" = "jeopardizer" +"jeopardisers" = "jeopardizers" +"jeopardises" = "jeopardizes" +"jeopardising" = "jeopardizing" +"jeopardizable" = "jeopardizable" +"jeopardization" = "jeopardization" +"jeopardizations" = "jeopardizations" +"jeopardize" = "jeopardize" +"jeopardized" = "jeopardized" +"jeopardizer" = "jeopardizer" +"jeopardizers" = "jeopardizers" +"jeopardizes" = "jeopardizes" +"jeopardizing" = "jeopardizing" +"kernelisable" = "kernelizable" +"kernelisation" = "kernelization" +"kernelisations" = "kernelizations" +"kernelise" = "kernelize" +"kernelised" = "kernelized" +"kerneliser" = "kernelizer" +"kernelisers" = "kernelizers" +"kernelises" = "kernelizes" +"kernelising" = "kernelizing" +"kernelizable" = "kernelizable" +"kernelization" = "kernelization" +"kernelizations" = "kernelizations" +"kernelize" = "kernelize" +"kernelized" = "kernelized" +"kernelizer" = "kernelizer" +"kernelizers" = "kernelizers" +"kernelizes" = "kernelizes" +"kernelizing" = "kernelizing" +"legitimisable" = "legitimizable" +"legitimisation" = "legitimization" +"legitimisations" = "legitimizations" +"legitimise" = "legitimize" +"legitimised" = "legitimized" +"legitimiser" = "legitimizer" +"legitimisers" = "legitimizers" +"legitimises" = "legitimizes" +"legitimising" = "legitimizing" +"legitimizable" = "legitimizable" +"legitimization" = "legitimization" +"legitimizations" = "legitimizations" +"legitimize" = "legitimize" +"legitimized" = "legitimized" +"legitimizer" = "legitimizer" +"legitimizers" = "legitimizers" +"legitimizes" = "legitimizes" +"legitimizing" = "legitimizing" +"lemmatisable" = "lemmatizable" +"lemmatisation" = "lemmatization" +"lemmatisations" = "lemmatizations" +"lemmatise" = "lemmatize" +"lemmatised" = "lemmatized" +"lemmatiser" = "lemmatizer" +"lemmatisers" = "lemmatizers" +"lemmatises" = "lemmatizes" +"lemmatising" = "lemmatizing" +"lemmatizable" = "lemmatizable" +"lemmatization" = "lemmatization" +"lemmatizations" = "lemmatizations" +"lemmatize" = "lemmatize" +"lemmatized" = "lemmatized" +"lemmatizer" = "lemmatizer" +"lemmatizers" = "lemmatizers" +"lemmatizes" = "lemmatizes" +"lemmatizing" = "lemmatizing" +"linearisable" = "linearizable" +"linearisation" = "linearization" +"linearisations" = "linearizations" +"linearise" = "linearize" +"linearised" = "linearized" +"lineariser" = "linearizer" +"linearisers" = "linearizers" +"linearises" = "linearizes" +"linearising" = "linearizing" +"linearizable" = "linearizable" +"linearization" = "linearization" +"linearizations" = "linearizations" +"linearize" = "linearize" +"linearized" = "linearized" +"linearizer" = "linearizer" +"linearizers" = "linearizers" +"linearizes" = "linearizes" +"linearizing" = "linearizing" +"localisable" = "localizable" +"localisation" = "localization" +"localisations" = "localizations" +"localise" = "localize" +"localised" = "localized" +"localiser" = "localizer" +"localisers" = "localizers" +"localises" = "localizes" +"localising" = "localizing" +"localizable" = "localizable" +"localization" = "localization" +"localizations" = "localizations" +"localize" = "localize" +"localized" = "localized" +"localizer" = "localizer" +"localizers" = "localizers" +"localizes" = "localizes" +"localizing" = "localizing" +"materialisable" = "materializable" +"materialisation" = "materialization" +"materialisations" = "materializations" +"materialise" = "materialize" +"materialised" = "materialized" +"materialiser" = "materializer" +"materialisers" = "materializers" +"materialises" = "materializes" +"materialising" = "materializing" +"materializable" = "materializable" +"materialization" = "materialization" +"materializations" = "materializations" +"materialize" = "materialize" +"materialized" = "materialized" +"materializer" = "materializer" +"materializers" = "materializers" +"materializes" = "materializes" +"materializing" = "materializing" +"maximisable" = "maximizable" +"maximisation" = "maximization" +"maximisations" = "maximizations" +"maximise" = "maximize" +"maximised" = "maximized" +"maximiser" = "maximizer" +"maximisers" = "maximizers" +"maximises" = "maximizes" +"maximising" = "maximizing" +"maximizable" = "maximizable" +"maximization" = "maximization" +"maximizations" = "maximizations" +"maximize" = "maximize" +"maximized" = "maximized" +"maximizer" = "maximizer" +"maximizers" = "maximizers" +"maximizes" = "maximizes" +"maximizing" = "maximizing" +"mechanisable" = "mechanizable" +"mechanisation" = "mechanization" +"mechanisations" = "mechanizations" +"mechanise" = "mechanize" +"mechanised" = "mechanized" +"mechaniser" = "mechanizer" +"mechanisers" = "mechanizers" +"mechanises" = "mechanizes" +"mechanising" = "mechanizing" +"mechanizable" = "mechanizable" +"mechanization" = "mechanization" +"mechanizations" = "mechanizations" +"mechanize" = "mechanize" +"mechanized" = "mechanized" +"mechanizer" = "mechanizer" +"mechanizers" = "mechanizers" +"mechanizes" = "mechanizes" +"mechanizing" = "mechanizing" +"memoisable" = "memoizable" +"memoisation" = "memoization" +"memoisations" = "memoizations" +"memoise" = "memoize" +"memoised" = "memoized" +"memoiser" = "memoizer" +"memoisers" = "memoizers" +"memoises" = "memoizes" +"memoising" = "memoizing" +"memoizable" = "memoizable" +"memoization" = "memoization" +"memoizations" = "memoizations" +"memoize" = "memoize" +"memoized" = "memoized" +"memoizer" = "memoizer" +"memoizers" = "memoizers" +"memoizes" = "memoizes" +"memoizing" = "memoizing" +"memorisable" = "memorizable" +"memorisation" = "memorization" +"memorisations" = "memorizations" +"memorise" = "memorize" +"memorised" = "memorized" +"memoriser" = "memorizer" +"memorisers" = "memorizers" +"memorises" = "memorizes" +"memorising" = "memorizing" +"memorizable" = "memorizable" +"memorization" = "memorization" +"memorizations" = "memorizations" +"memorize" = "memorize" +"memorized" = "memorized" +"memorizer" = "memorizer" +"memorizers" = "memorizers" +"memorizes" = "memorizes" +"memorizing" = "memorizing" +"miniaturisable" = "miniaturizable" +"miniaturisation" = "miniaturization" +"miniaturisations" = "miniaturizations" +"miniaturise" = "miniaturize" +"miniaturised" = "miniaturized" +"miniaturiser" = "miniaturizer" +"miniaturisers" = "miniaturizers" +"miniaturises" = "miniaturizes" +"miniaturising" = "miniaturizing" +"miniaturizable" = "miniaturizable" +"miniaturization" = "miniaturization" +"miniaturizations" = "miniaturizations" +"miniaturize" = "miniaturize" +"miniaturized" = "miniaturized" +"miniaturizer" = "miniaturizer" +"miniaturizers" = "miniaturizers" +"miniaturizes" = "miniaturizes" +"miniaturizing" = "miniaturizing" +"minimisable" = "minimizable" +"minimisation" = "minimization" +"minimisations" = "minimizations" +"minimise" = "minimize" +"minimised" = "minimized" +"minimiser" = "minimizer" +"minimisers" = "minimizers" +"minimises" = "minimizes" +"minimising" = "minimizing" +"minimizable" = "minimizable" +"minimization" = "minimization" +"minimizations" = "minimizations" +"minimize" = "minimize" +"minimized" = "minimized" +"minimizer" = "minimizer" +"minimizers" = "minimizers" +"minimizes" = "minimizes" +"minimizing" = "minimizing" +"mobilisable" = "mobilizable" +"mobilisation" = "mobilization" +"mobilisations" = "mobilizations" +"mobilise" = "mobilize" +"mobilised" = "mobilized" +"mobiliser" = "mobilizer" +"mobilisers" = "mobilizers" +"mobilises" = "mobilizes" +"mobilising" = "mobilizing" +"mobilizable" = "mobilizable" +"mobilization" = "mobilization" +"mobilizations" = "mobilizations" +"mobilize" = "mobilize" +"mobilized" = "mobilized" +"mobilizer" = "mobilizer" +"mobilizers" = "mobilizers" +"mobilizes" = "mobilizes" +"mobilizing" = "mobilizing" +"modernisable" = "modernizable" +"modernisation" = "modernization" +"modernisations" = "modernizations" +"modernise" = "modernize" +"modernised" = "modernized" +"moderniser" = "modernizer" +"modernisers" = "modernizers" +"modernises" = "modernizes" +"modernising" = "modernizing" +"modernizable" = "modernizable" +"modernization" = "modernization" +"modernizations" = "modernizations" +"modernize" = "modernize" +"modernized" = "modernized" +"modernizer" = "modernizer" +"modernizers" = "modernizers" +"modernizes" = "modernizes" +"modernizing" = "modernizing" +"modularisable" = "modularizable" +"modularisation" = "modularization" +"modularisations" = "modularizations" +"modularise" = "modularize" +"modularised" = "modularized" +"modulariser" = "modularizer" +"modularisers" = "modularizers" +"modularises" = "modularizes" +"modularising" = "modularizing" +"modularizable" = "modularizable" +"modularization" = "modularization" +"modularizations" = "modularizations" +"modularize" = "modularize" +"modularized" = "modularized" +"modularizer" = "modularizer" +"modularizers" = "modularizers" +"modularizes" = "modularizes" +"modularizing" = "modularizing" +"monetisable" = "monetizable" +"monetisation" = "monetization" +"monetisations" = "monetizations" +"monetise" = "monetize" +"monetised" = "monetized" +"monetiser" = "monetizer" +"monetisers" = "monetizers" +"monetises" = "monetizes" +"monetising" = "monetizing" +"monetizable" = "monetizable" +"monetization" = "monetization" +"monetizations" = "monetizations" +"monetize" = "monetize" +"monetized" = "monetized" +"monetizer" = "monetizer" +"monetizers" = "monetizers" +"monetizes" = "monetizes" +"monetizing" = "monetizing" +"monomorphisable" = "monomorphizable" +"monomorphisation" = "monomorphization" +"monomorphisations" = "monomorphizations" +"monomorphise" = "monomorphize" +"monomorphised" = "monomorphized" +"monomorphiser" = "monomorphizer" +"monomorphisers" = "monomorphizers" +"monomorphises" = "monomorphizes" +"monomorphising" = "monomorphizing" +"monomorphizable" = "monomorphizable" +"monomorphization" = "monomorphization" +"monomorphizations" = "monomorphizations" +"monomorphize" = "monomorphize" +"monomorphized" = "monomorphized" +"monomorphizer" = "monomorphizer" +"monomorphizers" = "monomorphizers" +"monomorphizes" = "monomorphizes" +"monomorphizing" = "monomorphizing" +"monopolisable" = "monopolizable" +"monopolisation" = "monopolization" +"monopolisations" = "monopolizations" +"monopolise" = "monopolize" +"monopolised" = "monopolized" +"monopoliser" = "monopolizer" +"monopolisers" = "monopolizers" +"monopolises" = "monopolizes" +"monopolising" = "monopolizing" +"monopolizable" = "monopolizable" +"monopolization" = "monopolization" +"monopolizations" = "monopolizations" +"monopolize" = "monopolize" +"monopolized" = "monopolized" +"monopolizer" = "monopolizer" +"monopolizers" = "monopolizers" +"monopolizes" = "monopolizes" +"monopolizing" = "monopolizing" +"moralisable" = "moralizable" +"moralisation" = "moralization" +"moralisations" = "moralizations" +"moralise" = "moralize" +"moralised" = "moralized" +"moraliser" = "moralizer" +"moralisers" = "moralizers" +"moralises" = "moralizes" +"moralising" = "moralizing" +"moralizable" = "moralizable" +"moralization" = "moralization" +"moralizations" = "moralizations" +"moralize" = "moralize" +"moralized" = "moralized" +"moralizer" = "moralizer" +"moralizers" = "moralizers" +"moralizes" = "moralizes" +"moralizing" = "moralizing" +"neutralisable" = "neutralizable" +"neutralisation" = "neutralization" +"neutralisations" = "neutralizations" +"neutralise" = "neutralize" +"neutralised" = "neutralized" +"neutraliser" = "neutralizer" +"neutralisers" = "neutralizers" +"neutralises" = "neutralizes" +"neutralising" = "neutralizing" +"neutralizable" = "neutralizable" +"neutralization" = "neutralization" +"neutralizations" = "neutralizations" +"neutralize" = "neutralize" +"neutralized" = "neutralized" +"neutralizer" = "neutralizer" +"neutralizers" = "neutralizers" +"neutralizes" = "neutralizes" +"neutralizing" = "neutralizing" +"normalisable" = "normalizable" +"normalisation" = "normalization" +"normalisations" = "normalizations" +"normalise" = "normalize" +"normalised" = "normalized" +"normaliser" = "normalizer" +"normalisers" = "normalizers" +"normalises" = "normalizes" +"normalising" = "normalizing" +"normalizable" = "normalizable" +"normalization" = "normalization" +"normalizations" = "normalizations" +"normalize" = "normalize" +"normalized" = "normalized" +"normalizer" = "normalizer" +"normalizers" = "normalizers" +"normalizes" = "normalizes" +"normalizing" = "normalizing" +"notarisable" = "notarizable" +"notarisation" = "notarization" +"notarisations" = "notarizations" +"notarise" = "notarize" +"notarised" = "notarized" +"notariser" = "notarizer" +"notarisers" = "notarizers" +"notarises" = "notarizes" +"notarising" = "notarizing" +"notarizable" = "notarizable" +"notarization" = "notarization" +"notarizations" = "notarizations" +"notarize" = "notarize" +"notarized" = "notarized" +"notarizer" = "notarizer" +"notarizers" = "notarizers" +"notarizes" = "notarizes" +"notarizing" = "notarizing" +"operationalisable" = "operationalizable" +"operationalisation" = "operationalization" +"operationalisations" = "operationalizations" +"operationalise" = "operationalize" +"operationalised" = "operationalized" +"operationaliser" = "operationalizer" +"operationalisers" = "operationalizers" +"operationalises" = "operationalizes" +"operationalising" = "operationalizing" +"operationalizable" = "operationalizable" +"operationalization" = "operationalization" +"operationalizations" = "operationalizations" +"operationalize" = "operationalize" +"operationalized" = "operationalized" +"operationalizer" = "operationalizer" +"operationalizers" = "operationalizers" +"operationalizes" = "operationalizes" +"operationalizing" = "operationalizing" +"optimisable" = "optimizable" +"optimisation" = "optimization" +"optimisations" = "optimizations" +"optimise" = "optimize" +"optimised" = "optimized" +"optimiser" = "optimizer" +"optimisers" = "optimizers" +"optimises" = "optimizes" +"optimising" = "optimizing" +"optimizable" = "optimizable" +"optimization" = "optimization" +"optimizations" = "optimizations" +"optimize" = "optimize" +"optimized" = "optimized" +"optimizer" = "optimizer" +"optimizers" = "optimizers" +"optimizes" = "optimizes" +"optimizing" = "optimizing" +"ordinalisable" = "ordinalizable" +"ordinalisation" = "ordinalization" +"ordinalisations" = "ordinalizations" +"ordinalise" = "ordinalize" +"ordinalised" = "ordinalized" +"ordinaliser" = "ordinalizer" +"ordinalisers" = "ordinalizers" +"ordinalises" = "ordinalizes" +"ordinalising" = "ordinalizing" +"ordinalizable" = "ordinalizable" +"ordinalization" = "ordinalization" +"ordinalizations" = "ordinalizations" +"ordinalize" = "ordinalize" +"ordinalized" = "ordinalized" +"ordinalizer" = "ordinalizer" +"ordinalizers" = "ordinalizers" +"ordinalizes" = "ordinalizes" +"ordinalizing" = "ordinalizing" +"organisable" = "organizable" +"organisation" = "organization" +"organisations" = "organizations" +"organise" = "organize" +"organised" = "organized" +"organiser" = "organizer" +"organisers" = "organizers" +"organises" = "organizes" +"organising" = "organizing" +"organizable" = "organizable" +"organization" = "organization" +"organizations" = "organizations" +"organize" = "organize" +"organized" = "organized" +"organizer" = "organizer" +"organizers" = "organizers" +"organizes" = "organizes" +"organizing" = "organizing" +"oxendict" = "oxendict" +"palettisable" = "palettizable" +"palettisation" = "palettization" +"palettisations" = "palettizations" +"palettise" = "palettize" +"palettised" = "palettized" +"palettiser" = "palettizer" +"palettisers" = "palettizers" +"palettises" = "palettizes" +"palettising" = "palettizing" +"palettizable" = "palettizable" +"palettization" = "palettization" +"palettizations" = "palettizations" +"palettize" = "palettize" +"palettized" = "palettized" +"palettizer" = "palettizer" +"palettizers" = "palettizers" +"palettizes" = "palettizes" +"palettizing" = "palettizing" +"parallelisable" = "parallelizable" +"parallelisation" = "parallelization" +"parallelisations" = "parallelizations" +"parallelise" = "parallelize" +"parallelised" = "parallelized" +"paralleliser" = "parallelizer" +"parallelisers" = "parallelizers" +"parallelises" = "parallelizes" +"parallelising" = "parallelizing" +"parallelizable" = "parallelizable" +"parallelization" = "parallelization" +"parallelizations" = "parallelizations" +"parallelize" = "parallelize" +"parallelized" = "parallelized" +"parallelizer" = "parallelizer" +"parallelizers" = "parallelizers" +"parallelizes" = "parallelizes" +"parallelizing" = "parallelizing" +"parameterisable" = "parameterizable" +"parameterisation" = "parameterization" +"parameterisations" = "parameterizations" +"parameterise" = "parameterize" +"parameterised" = "parameterized" +"parameteriser" = "parameterizer" +"parameterisers" = "parameterizers" +"parameterises" = "parameterizes" +"parameterising" = "parameterizing" +"parameterizable" = "parameterizable" +"parameterization" = "parameterization" +"parameterizations" = "parameterizations" +"parameterize" = "parameterize" +"parameterized" = "parameterized" +"parameterizer" = "parameterizer" +"parameterizers" = "parameterizers" +"parameterizes" = "parameterizes" +"parameterizing" = "parameterizing" +"parametrisable" = "parametrizable" +"parametrisation" = "parametrization" +"parametrisations" = "parametrizations" +"parametrise" = "parametrize" +"parametrised" = "parametrized" +"parametriser" = "parametrizer" +"parametrisers" = "parametrizers" +"parametrises" = "parametrizes" +"parametrising" = "parametrizing" +"parametrizable" = "parametrizable" +"parametrization" = "parametrization" +"parametrizations" = "parametrizations" +"parametrize" = "parametrize" +"parametrized" = "parametrized" +"parametrizer" = "parametrizer" +"parametrizers" = "parametrizers" +"parametrizes" = "parametrizes" +"parametrizing" = "parametrizing" +"parenthesisable" = "parenthesizable" +"parenthesisation" = "parenthesization" +"parenthesisations" = "parenthesizations" +"parenthesise" = "parenthesize" +"parenthesised" = "parenthesized" +"parenthesiser" = "parenthesizer" +"parenthesisers" = "parenthesizers" +"parenthesises" = "parenthesizes" +"parenthesising" = "parenthesizing" +"parenthesizable" = "parenthesizable" +"parenthesization" = "parenthesization" +"parenthesizations" = "parenthesizations" +"parenthesize" = "parenthesize" +"parenthesized" = "parenthesized" +"parenthesizer" = "parenthesizer" +"parenthesizers" = "parenthesizers" +"parenthesizes" = "parenthesizes" +"parenthesizing" = "parenthesizing" +"penalisable" = "penalizable" +"penalisation" = "penalization" +"penalisations" = "penalizations" +"penalise" = "penalize" +"penalised" = "penalized" +"penaliser" = "penalizer" +"penalisers" = "penalizers" +"penalises" = "penalizes" +"penalising" = "penalizing" +"penalizable" = "penalizable" +"penalization" = "penalization" +"penalizations" = "penalizations" +"penalize" = "penalize" +"penalized" = "penalized" +"penalizer" = "penalizer" +"penalizers" = "penalizers" +"penalizes" = "penalizes" +"penalizing" = "penalizing" +"personalisable" = "personalizable" +"personalisation" = "personalization" +"personalisations" = "personalizations" +"personalise" = "personalize" +"personalised" = "personalized" +"personaliser" = "personalizer" +"personalisers" = "personalizers" +"personalises" = "personalizes" +"personalising" = "personalizing" +"personalizable" = "personalizable" +"personalization" = "personalization" +"personalizations" = "personalizations" +"personalize" = "personalize" +"personalized" = "personalized" +"personalizer" = "personalizer" +"personalizers" = "personalizers" +"personalizes" = "personalizes" +"personalizing" = "personalizing" +"pluralisable" = "pluralizable" +"pluralisation" = "pluralization" +"pluralisations" = "pluralizations" +"pluralise" = "pluralize" +"pluralised" = "pluralized" +"pluraliser" = "pluralizer" +"pluralisers" = "pluralizers" +"pluralises" = "pluralizes" +"pluralising" = "pluralizing" +"pluralizable" = "pluralizable" +"pluralization" = "pluralization" +"pluralizations" = "pluralizations" +"pluralize" = "pluralize" +"pluralized" = "pluralized" +"pluralizer" = "pluralizer" +"pluralizers" = "pluralizers" +"pluralizes" = "pluralizes" +"pluralizing" = "pluralizing" +"popularisable" = "popularizable" +"popularisation" = "popularization" +"popularisations" = "popularizations" +"popularise" = "popularize" +"popularised" = "popularized" +"populariser" = "popularizer" +"popularisers" = "popularizers" +"popularises" = "popularizes" +"popularising" = "popularizing" +"popularizable" = "popularizable" +"popularization" = "popularization" +"popularizations" = "popularizations" +"popularize" = "popularize" +"popularized" = "popularized" +"popularizer" = "popularizer" +"popularizers" = "popularizers" +"popularizes" = "popularizes" +"popularizing" = "popularizing" +"prioritisable" = "prioritizable" +"prioritisation" = "prioritization" +"prioritisations" = "prioritizations" +"prioritise" = "prioritize" +"prioritised" = "prioritized" +"prioritiser" = "prioritizer" +"prioritisers" = "prioritizers" +"prioritises" = "prioritizes" +"prioritising" = "prioritizing" +"prioritizable" = "prioritizable" +"prioritization" = "prioritization" +"prioritizations" = "prioritizations" +"prioritize" = "prioritize" +"prioritized" = "prioritized" +"prioritizer" = "prioritizer" +"prioritizers" = "prioritizers" +"prioritizes" = "prioritizes" +"prioritizing" = "prioritizing" +"privatisable" = "privatizable" +"privatisation" = "privatization" +"privatisations" = "privatizations" +"privatise" = "privatize" +"privatised" = "privatized" +"privatiser" = "privatizer" +"privatisers" = "privatizers" +"privatises" = "privatizes" +"privatising" = "privatizing" +"privatizable" = "privatizable" +"privatization" = "privatization" +"privatizations" = "privatizations" +"privatize" = "privatize" +"privatized" = "privatized" +"privatizer" = "privatizer" +"privatizers" = "privatizers" +"privatizes" = "privatizes" +"privatizing" = "privatizing" +"productisable" = "productizable" +"productisation" = "productization" +"productisations" = "productizations" +"productise" = "productize" +"productised" = "productized" +"productiser" = "productizer" +"productisers" = "productizers" +"productises" = "productizes" +"productising" = "productizing" +"productizable" = "productizable" +"productization" = "productization" +"productizations" = "productizations" +"productize" = "productize" +"productized" = "productized" +"productizer" = "productizer" +"productizers" = "productizers" +"productizes" = "productizes" +"productizing" = "productizing" +"publicisable" = "publicizable" +"publicisation" = "publicization" +"publicisations" = "publicizations" +"publicise" = "publicize" +"publicised" = "publicized" +"publiciser" = "publicizer" +"publicisers" = "publicizers" +"publicises" = "publicizes" +"publicising" = "publicizing" +"publicizable" = "publicizable" +"publicization" = "publicization" +"publicizations" = "publicizations" +"publicize" = "publicize" +"publicized" = "publicized" +"publicizer" = "publicizer" +"publicizers" = "publicizers" +"publicizes" = "publicizes" +"publicizing" = "publicizing" +"quantisable" = "quantizable" +"quantisation" = "quantization" +"quantisations" = "quantizations" +"quantise" = "quantize" +"quantised" = "quantized" +"quantiser" = "quantizer" +"quantisers" = "quantizers" +"quantises" = "quantizes" +"quantising" = "quantizing" +"quantizable" = "quantizable" +"quantization" = "quantization" +"quantizations" = "quantizations" +"quantize" = "quantize" +"quantized" = "quantized" +"quantizer" = "quantizer" +"quantizers" = "quantizers" +"quantizes" = "quantizes" +"quantizing" = "quantizing" +"randomisable" = "randomizable" +"randomisation" = "randomization" +"randomisations" = "randomizations" +"randomise" = "randomize" +"randomised" = "randomized" +"randomiser" = "randomizer" +"randomisers" = "randomizers" +"randomises" = "randomizes" +"randomising" = "randomizing" +"randomizable" = "randomizable" +"randomization" = "randomization" +"randomizations" = "randomizations" +"randomize" = "randomize" +"randomized" = "randomized" +"randomizer" = "randomizer" +"randomizers" = "randomizers" +"randomizes" = "randomizes" +"randomizing" = "randomizing" +"rasterisable" = "rasterizable" +"rasterisation" = "rasterization" +"rasterisations" = "rasterizations" +"rasterise" = "rasterize" +"rasterised" = "rasterized" +"rasteriser" = "rasterizer" +"rasterisers" = "rasterizers" +"rasterises" = "rasterizes" +"rasterising" = "rasterizing" +"rasterizable" = "rasterizable" +"rasterization" = "rasterization" +"rasterizations" = "rasterizations" +"rasterize" = "rasterize" +"rasterized" = "rasterized" +"rasterizer" = "rasterizer" +"rasterizers" = "rasterizers" +"rasterizes" = "rasterizes" +"rasterizing" = "rasterizing" +"rationalisable" = "rationalizable" +"rationalisation" = "rationalization" +"rationalisations" = "rationalizations" +"rationalise" = "rationalize" +"rationalised" = "rationalized" +"rationaliser" = "rationalizer" +"rationalisers" = "rationalizers" +"rationalises" = "rationalizes" +"rationalising" = "rationalizing" +"rationalizable" = "rationalizable" +"rationalization" = "rationalization" +"rationalizations" = "rationalizations" +"rationalize" = "rationalize" +"rationalized" = "rationalized" +"rationalizer" = "rationalizer" +"rationalizers" = "rationalizers" +"rationalizes" = "rationalizes" +"rationalizing" = "rationalizing" +"realisable" = "realizable" +"realisation" = "realization" +"realisations" = "realizations" +"realise" = "realize" +"realised" = "realized" +"realiser" = "realizer" +"realisers" = "realizers" +"realises" = "realizes" +"realising" = "realizing" +"realizable" = "realizable" +"realization" = "realization" +"realizations" = "realizations" +"realize" = "realize" +"realized" = "realized" +"realizer" = "realizer" +"realizers" = "realizers" +"realizes" = "realizes" +"realizing" = "realizing" +"recognisable" = "recognizable" +"recognisation" = "recognization" +"recognisations" = "recognizations" +"recognise" = "recognize" +"recognised" = "recognized" +"recogniser" = "recognizer" +"recognisers" = "recognizers" +"recognises" = "recognizes" +"recognising" = "recognizing" +"recognizable" = "recognizable" +"recognization" = "recognization" +"recognizations" = "recognizations" +"recognize" = "recognize" +"recognized" = "recognized" +"recognizer" = "recognizer" +"recognizers" = "recognizers" +"recognizes" = "recognizes" +"recognizing" = "recognizing" +"regularisable" = "regularizable" +"regularisation" = "regularization" +"regularisations" = "regularizations" +"regularise" = "regularize" +"regularised" = "regularized" +"regulariser" = "regularizer" +"regularisers" = "regularizers" +"regularises" = "regularizes" +"regularising" = "regularizing" +"regularizable" = "regularizable" +"regularization" = "regularization" +"regularizations" = "regularizations" +"regularize" = "regularize" +"regularized" = "regularized" +"regularizer" = "regularizer" +"regularizers" = "regularizers" +"regularizes" = "regularizes" +"regularizing" = "regularizing" +"reinitialisable" = "reinitializable" +"reinitialisation" = "reinitialization" +"reinitialisations" = "reinitializations" +"reinitialise" = "reinitialize" +"reinitialised" = "reinitialized" +"reinitialiser" = "reinitializer" +"reinitialisers" = "reinitializers" +"reinitialises" = "reinitializes" +"reinitialising" = "reinitializing" +"reinitializable" = "reinitializable" +"reinitialization" = "reinitialization" +"reinitializations" = "reinitializations" +"reinitialize" = "reinitialize" +"reinitialized" = "reinitialized" +"reinitializer" = "reinitializer" +"reinitializers" = "reinitializers" +"reinitializes" = "reinitializes" +"reinitializing" = "reinitializing" +"reorganisable" = "reorganizable" +"reorganisation" = "reorganization" +"reorganisations" = "reorganizations" +"reorganise" = "reorganize" +"reorganised" = "reorganized" +"reorganiser" = "reorganizer" +"reorganisers" = "reorganizers" +"reorganises" = "reorganizes" +"reorganising" = "reorganizing" +"reorganizable" = "reorganizable" +"reorganization" = "reorganization" +"reorganizations" = "reorganizations" +"reorganize" = "reorganize" +"reorganized" = "reorganized" +"reorganizer" = "reorganizer" +"reorganizers" = "reorganizers" +"reorganizes" = "reorganizes" +"reorganizing" = "reorganizing" +"reserialisable" = "reserializable" +"reserialisation" = "reserialization" +"reserialisations" = "reserializations" +"reserialise" = "reserialize" +"reserialised" = "reserialized" +"reserialiser" = "reserializer" +"reserialisers" = "reserializers" +"reserialises" = "reserializes" +"reserialising" = "reserializing" +"reserializable" = "reserializable" +"reserialization" = "reserialization" +"reserializations" = "reserializations" +"reserialize" = "reserialize" +"reserialized" = "reserialized" +"reserializer" = "reserializer" +"reserializers" = "reserializers" +"reserializes" = "reserializes" +"reserializing" = "reserializing" +"resynchronisable" = "resynchronizable" +"resynchronisation" = "resynchronization" +"resynchronisations" = "resynchronizations" +"resynchronise" = "resynchronize" +"resynchronised" = "resynchronized" +"resynchroniser" = "resynchronizer" +"resynchronisers" = "resynchronizers" +"resynchronises" = "resynchronizes" +"resynchronising" = "resynchronizing" +"resynchronizable" = "resynchronizable" +"resynchronization" = "resynchronization" +"resynchronizations" = "resynchronizations" +"resynchronize" = "resynchronize" +"resynchronized" = "resynchronized" +"resynchronizer" = "resynchronizer" +"resynchronizers" = "resynchronizers" +"resynchronizes" = "resynchronizes" +"resynchronizing" = "resynchronizing" +"retokenisable" = "retokenizable" +"retokenisation" = "retokenization" +"retokenisations" = "retokenizations" +"retokenise" = "retokenize" +"retokenised" = "retokenized" +"retokeniser" = "retokenizer" +"retokenisers" = "retokenizers" +"retokenises" = "retokenizes" +"retokenising" = "retokenizing" +"retokenizable" = "retokenizable" +"retokenization" = "retokenization" +"retokenizations" = "retokenizations" +"retokenize" = "retokenize" +"retokenized" = "retokenized" +"retokenizer" = "retokenizer" +"retokenizers" = "retokenizers" +"retokenizes" = "retokenizes" +"retokenizing" = "retokenizing" +"romanticisable" = "romanticizable" +"romanticisation" = "romanticization" +"romanticisations" = "romanticizations" +"romanticise" = "romanticize" +"romanticised" = "romanticized" +"romanticiser" = "romanticizer" +"romanticisers" = "romanticizers" +"romanticises" = "romanticizes" +"romanticising" = "romanticizing" +"romanticizable" = "romanticizable" +"romanticization" = "romanticization" +"romanticizations" = "romanticizations" +"romanticize" = "romanticize" +"romanticized" = "romanticized" +"romanticizer" = "romanticizer" +"romanticizers" = "romanticizers" +"romanticizes" = "romanticizes" +"romanticizing" = "romanticizing" +"sanitisable" = "sanitizable" +"sanitisation" = "sanitization" +"sanitisations" = "sanitizations" +"sanitise" = "sanitize" +"sanitised" = "sanitized" +"sanitiser" = "sanitizer" +"sanitisers" = "sanitizers" +"sanitises" = "sanitizes" +"sanitising" = "sanitizing" +"sanitizable" = "sanitizable" +"sanitization" = "sanitization" +"sanitizations" = "sanitizations" +"sanitize" = "sanitize" +"sanitized" = "sanitized" +"sanitizer" = "sanitizer" +"sanitizers" = "sanitizers" +"sanitizes" = "sanitizes" +"sanitizing" = "sanitizing" +"scrutinisable" = "scrutinizable" +"scrutinisation" = "scrutinization" +"scrutinisations" = "scrutinizations" +"scrutinise" = "scrutinize" +"scrutinised" = "scrutinized" +"scrutiniser" = "scrutinizer" +"scrutinisers" = "scrutinizers" +"scrutinises" = "scrutinizes" +"scrutinising" = "scrutinizing" +"scrutinizable" = "scrutinizable" +"scrutinization" = "scrutinization" +"scrutinizations" = "scrutinizations" +"scrutinize" = "scrutinize" +"scrutinized" = "scrutinized" +"scrutinizer" = "scrutinizer" +"scrutinizers" = "scrutinizers" +"scrutinizes" = "scrutinizes" +"scrutinizing" = "scrutinizing" +"serialisable" = "serializable" +"serialisation" = "serialization" +"serialisations" = "serializations" +"serialise" = "serialize" +"serialised" = "serialized" +"serialiser" = "serializer" +"serialisers" = "serializers" +"serialises" = "serializes" +"serialising" = "serializing" +"serializable" = "serializable" +"serialization" = "serialization" +"serializations" = "serializations" +"serialize" = "serialize" +"serialized" = "serialized" +"serializer" = "serializer" +"serializers" = "serializers" +"serializes" = "serializes" +"serializing" = "serializing" +"sexualisable" = "sexualizable" +"sexualisation" = "sexualization" +"sexualisations" = "sexualizations" +"sexualise" = "sexualize" +"sexualised" = "sexualized" +"sexualiser" = "sexualizer" +"sexualisers" = "sexualizers" +"sexualises" = "sexualizes" +"sexualising" = "sexualizing" +"sexualizable" = "sexualizable" +"sexualization" = "sexualization" +"sexualizations" = "sexualizations" +"sexualize" = "sexualize" +"sexualized" = "sexualized" +"sexualizer" = "sexualizer" +"sexualizers" = "sexualizers" +"sexualizes" = "sexualizes" +"sexualizing" = "sexualizing" +"singularisable" = "singularizable" +"singularisation" = "singularization" +"singularisations" = "singularizations" +"singularise" = "singularize" +"singularised" = "singularized" +"singulariser" = "singularizer" +"singularisers" = "singularizers" +"singularises" = "singularizes" +"singularising" = "singularizing" +"singularizable" = "singularizable" +"singularization" = "singularization" +"singularizations" = "singularizations" +"singularize" = "singularize" +"singularized" = "singularized" +"singularizer" = "singularizer" +"singularizers" = "singularizers" +"singularizes" = "singularizes" +"singularizing" = "singularizing" +"socialisable" = "socializable" +"socialisation" = "socialization" +"socialisations" = "socializations" +"socialise" = "socialize" +"socialised" = "socialized" +"socialiser" = "socializer" +"socialisers" = "socializers" +"socialises" = "socializes" +"socialising" = "socializing" +"socializable" = "socializable" +"socialization" = "socialization" +"socializations" = "socializations" +"socialize" = "socialize" +"socialized" = "socialized" +"socializer" = "socializer" +"socializers" = "socializers" +"socializes" = "socializes" +"socializing" = "socializing" +"specialisable" = "specializable" +"specialisation" = "specialization" +"specialisations" = "specializations" +"specialise" = "specialize" +"specialised" = "specialized" +"specialiser" = "specializer" +"specialisers" = "specializers" +"specialises" = "specializes" +"specialising" = "specializing" +"specializable" = "specializable" +"specialization" = "specialization" +"specializations" = "specializations" +"specialize" = "specialize" +"specialized" = "specialized" +"specializer" = "specializer" +"specializers" = "specializers" +"specializes" = "specializes" +"specializing" = "specializing" +"stabilisable" = "stabilizable" +"stabilisation" = "stabilization" +"stabilisations" = "stabilizations" +"stabilise" = "stabilize" +"stabilised" = "stabilized" +"stabiliser" = "stabilizer" +"stabilisers" = "stabilizers" +"stabilises" = "stabilizes" +"stabilising" = "stabilizing" +"stabilizable" = "stabilizable" +"stabilization" = "stabilization" +"stabilizations" = "stabilizations" +"stabilize" = "stabilize" +"stabilized" = "stabilized" +"stabilizer" = "stabilizer" +"stabilizers" = "stabilizers" +"stabilizes" = "stabilizes" +"stabilizing" = "stabilizing" +"standardisable" = "standardizable" +"standardisation" = "standardization" +"standardisations" = "standardizations" +"standardise" = "standardize" +"standardised" = "standardized" +"standardiser" = "standardizer" +"standardisers" = "standardizers" +"standardises" = "standardizes" +"standardising" = "standardizing" +"standardizable" = "standardizable" +"standardization" = "standardization" +"standardizations" = "standardizations" +"standardize" = "standardize" +"standardized" = "standardized" +"standardizer" = "standardizer" +"standardizers" = "standardizers" +"standardizes" = "standardizes" +"standardizing" = "standardizing" +"stylisable" = "stylizable" +"stylisation" = "stylization" +"stylisations" = "stylizations" +"stylise" = "stylize" +"stylised" = "stylized" +"styliser" = "stylizer" +"stylisers" = "stylizers" +"stylises" = "stylizes" +"stylising" = "stylizing" +"stylizable" = "stylizable" +"stylization" = "stylization" +"stylizations" = "stylizations" +"stylize" = "stylize" +"stylized" = "stylized" +"stylizer" = "stylizer" +"stylizers" = "stylizers" +"stylizes" = "stylizes" +"stylizing" = "stylizing" +"subsidisable" = "subsidizable" +"subsidisation" = "subsidization" +"subsidisations" = "subsidizations" +"subsidise" = "subsidize" +"subsidised" = "subsidized" +"subsidiser" = "subsidizer" +"subsidisers" = "subsidizers" +"subsidises" = "subsidizes" +"subsidising" = "subsidizing" +"subsidizable" = "subsidizable" +"subsidization" = "subsidization" +"subsidizations" = "subsidizations" +"subsidize" = "subsidize" +"subsidized" = "subsidized" +"subsidizer" = "subsidizer" +"subsidizers" = "subsidizers" +"subsidizes" = "subsidizes" +"subsidizing" = "subsidizing" +"summarisable" = "summarizable" +"summarisation" = "summarization" +"summarisations" = "summarizations" +"summarise" = "summarize" +"summarised" = "summarized" +"summariser" = "summarizer" +"summarisers" = "summarizers" +"summarises" = "summarizes" +"summarising" = "summarizing" +"summarizable" = "summarizable" +"summarization" = "summarization" +"summarizations" = "summarizations" +"summarize" = "summarize" +"summarized" = "summarized" +"summarizer" = "summarizer" +"summarizers" = "summarizers" +"summarizes" = "summarizes" +"summarizing" = "summarizing" +"symbolisable" = "symbolizable" +"symbolisation" = "symbolization" +"symbolisations" = "symbolizations" +"symbolise" = "symbolize" +"symbolised" = "symbolized" +"symboliser" = "symbolizer" +"symbolisers" = "symbolizers" +"symbolises" = "symbolizes" +"symbolising" = "symbolizing" +"symbolizable" = "symbolizable" +"symbolization" = "symbolization" +"symbolizations" = "symbolizations" +"symbolize" = "symbolize" +"symbolized" = "symbolized" +"symbolizer" = "symbolizer" +"symbolizers" = "symbolizers" +"symbolizes" = "symbolizes" +"symbolizing" = "symbolizing" +"synchronisable" = "synchronizable" +"synchronisation" = "synchronization" +"synchronisations" = "synchronizations" +"synchronise" = "synchronize" +"synchronised" = "synchronized" +"synchroniser" = "synchronizer" +"synchronisers" = "synchronizers" +"synchronises" = "synchronizes" +"synchronising" = "synchronizing" +"synchronizable" = "synchronizable" +"synchronization" = "synchronization" +"synchronizations" = "synchronizations" +"synchronize" = "synchronize" +"synchronized" = "synchronized" +"synchronizer" = "synchronizer" +"synchronizers" = "synchronizers" +"synchronizes" = "synchronizes" +"synchronizing" = "synchronizing" +"synthesisable" = "synthesizable" +"synthesisation" = "synthesization" +"synthesisations" = "synthesizations" +"synthesise" = "synthesize" +"synthesised" = "synthesized" +"synthesiser" = "synthesizer" +"synthesisers" = "synthesizers" +"synthesises" = "synthesizes" +"synthesising" = "synthesizing" +"synthesizable" = "synthesizable" +"synthesization" = "synthesization" +"synthesizations" = "synthesizations" +"synthesize" = "synthesize" +"synthesized" = "synthesized" +"synthesizer" = "synthesizer" +"synthesizers" = "synthesizers" +"synthesizes" = "synthesizes" +"synthesizing" = "synthesizing" +"systematisable" = "systematizable" +"systematisation" = "systematization" +"systematisations" = "systematizations" +"systematise" = "systematize" +"systematised" = "systematized" +"systematiser" = "systematizer" +"systematisers" = "systematizers" +"systematises" = "systematizes" +"systematising" = "systematizing" +"systematizable" = "systematizable" +"systematization" = "systematization" +"systematizations" = "systematizations" +"systematize" = "systematize" +"systematized" = "systematized" +"systematizer" = "systematizer" +"systematizers" = "systematizers" +"systematizes" = "systematizes" +"systematizing" = "systematizing" +"systemisable" = "systemizable" +"systemisation" = "systemization" +"systemisations" = "systemizations" +"systemise" = "systemize" +"systemised" = "systemized" +"systemiser" = "systemizer" +"systemisers" = "systemizers" +"systemises" = "systemizes" +"systemising" = "systemizing" +"systemizable" = "systemizable" +"systemization" = "systemization" +"systemizations" = "systemizations" +"systemize" = "systemize" +"systemized" = "systemized" +"systemizer" = "systemizer" +"systemizers" = "systemizers" +"systemizes" = "systemizes" +"systemizing" = "systemizing" +"templatisable" = "templatizable" +"templatisation" = "templatization" +"templatisations" = "templatizations" +"templatise" = "templatize" +"templatised" = "templatized" +"templatiser" = "templatizer" +"templatisers" = "templatizers" +"templatises" = "templatizes" +"templatising" = "templatizing" +"templatizable" = "templatizable" +"templatization" = "templatization" +"templatizations" = "templatizations" +"templatize" = "templatize" +"templatized" = "templatized" +"templatizer" = "templatizer" +"templatizers" = "templatizers" +"templatizes" = "templatizes" +"templatizing" = "templatizing" +"terminalisable" = "terminalizable" +"terminalisation" = "terminalization" +"terminalisations" = "terminalizations" +"terminalise" = "terminalize" +"terminalised" = "terminalized" +"terminaliser" = "terminalizer" +"terminalisers" = "terminalizers" +"terminalises" = "terminalizes" +"terminalising" = "terminalizing" +"terminalizable" = "terminalizable" +"terminalization" = "terminalization" +"terminalizations" = "terminalizations" +"terminalize" = "terminalize" +"terminalized" = "terminalized" +"terminalizer" = "terminalizer" +"terminalizers" = "terminalizers" +"terminalizes" = "terminalizes" +"terminalizing" = "terminalizing" +"theorisable" = "theorizable" +"theorisation" = "theorization" +"theorisations" = "theorizations" +"theorise" = "theorize" +"theorised" = "theorized" +"theoriser" = "theorizer" +"theorisers" = "theorizers" +"theorises" = "theorizes" +"theorising" = "theorizing" +"theorizable" = "theorizable" +"theorization" = "theorization" +"theorizations" = "theorizations" +"theorize" = "theorize" +"theorized" = "theorized" +"theorizer" = "theorizer" +"theorizers" = "theorizers" +"theorizes" = "theorizes" +"theorizing" = "theorizing" +"tokenisable" = "tokenizable" +"tokenisation" = "tokenization" +"tokenisations" = "tokenizations" +"tokenise" = "tokenize" +"tokenised" = "tokenized" +"tokeniser" = "tokenizer" +"tokenisers" = "tokenizers" +"tokenises" = "tokenizes" +"tokenising" = "tokenizing" +"tokenizable" = "tokenizable" +"tokenization" = "tokenization" +"tokenizations" = "tokenizations" +"tokenize" = "tokenize" +"tokenized" = "tokenized" +"tokenizer" = "tokenizer" +"tokenizers" = "tokenizers" +"tokenizes" = "tokenizes" +"tokenizing" = "tokenizing" +"trivialisable" = "trivializable" +"trivialisation" = "trivialization" +"trivialisations" = "trivializations" +"trivialise" = "trivialize" +"trivialised" = "trivialized" +"trivialiser" = "trivializer" +"trivialisers" = "trivializers" +"trivialises" = "trivializes" +"trivialising" = "trivializing" +"trivializable" = "trivializable" +"trivialization" = "trivialization" +"trivializations" = "trivializations" +"trivialize" = "trivialize" +"trivialized" = "trivialized" +"trivializer" = "trivializer" +"trivializers" = "trivializers" +"trivializes" = "trivializes" +"trivializing" = "trivializing" +"unauthorisable" = "unauthorizable" +"unauthorisation" = "unauthorization" +"unauthorisations" = "unauthorizations" +"unauthorise" = "unauthorize" +"unauthorised" = "unauthorized" +"unauthoriser" = "unauthorizer" +"unauthorisers" = "unauthorizers" +"unauthorises" = "unauthorizes" +"unauthorising" = "unauthorizing" +"unauthorizable" = "unauthorizable" +"unauthorization" = "unauthorization" +"unauthorizations" = "unauthorizations" +"unauthorize" = "unauthorize" +"unauthorized" = "unauthorized" +"unauthorizer" = "unauthorizer" +"unauthorizers" = "unauthorizers" +"unauthorizes" = "unauthorizes" +"unauthorizing" = "unauthorizing" +"uncategorisable" = "uncategorizable" +"uncategorisation" = "uncategorization" +"uncategorisations" = "uncategorizations" +"uncategorise" = "uncategorize" +"uncategorised" = "uncategorized" +"uncategoriser" = "uncategorizer" +"uncategorisers" = "uncategorizers" +"uncategorises" = "uncategorizes" +"uncategorising" = "uncategorizing" +"uncategorizable" = "uncategorizable" +"uncategorization" = "uncategorization" +"uncategorizations" = "uncategorizations" +"uncategorize" = "uncategorize" +"uncategorized" = "uncategorized" +"uncategorizer" = "uncategorizer" +"uncategorizers" = "uncategorizers" +"uncategorizes" = "uncategorizes" +"uncategorizing" = "uncategorizing" +"uninitialisable" = "uninitializable" +"uninitialisation" = "uninitialization" +"uninitialisations" = "uninitializations" +"uninitialise" = "uninitialize" +"uninitialised" = "uninitialized" +"uninitialiser" = "uninitializer" +"uninitialisers" = "uninitializers" +"uninitialises" = "uninitializes" +"uninitialising" = "uninitializing" +"uninitializable" = "uninitializable" +"uninitialization" = "uninitialization" +"uninitializations" = "uninitializations" +"uninitialize" = "uninitialize" +"uninitialized" = "uninitialized" +"uninitializer" = "uninitializer" +"uninitializers" = "uninitializers" +"uninitializes" = "uninitializes" +"uninitializing" = "uninitializing" +"unlocalisable" = "unlocalizable" +"unlocalisation" = "unlocalization" +"unlocalisations" = "unlocalizations" +"unlocalise" = "unlocalize" +"unlocalised" = "unlocalized" +"unlocaliser" = "unlocalizer" +"unlocalisers" = "unlocalizers" +"unlocalises" = "unlocalizes" +"unlocalising" = "unlocalizing" +"unlocalizable" = "unlocalizable" +"unlocalization" = "unlocalization" +"unlocalizations" = "unlocalizations" +"unlocalize" = "unlocalize" +"unlocalized" = "unlocalized" +"unlocalizer" = "unlocalizer" +"unlocalizers" = "unlocalizers" +"unlocalizes" = "unlocalizes" +"unlocalizing" = "unlocalizing" +"unoptimisable" = "unoptimizable" +"unoptimisation" = "unoptimization" +"unoptimisations" = "unoptimizations" +"unoptimise" = "unoptimize" +"unoptimised" = "unoptimized" +"unoptimiser" = "unoptimizer" +"unoptimisers" = "unoptimizers" +"unoptimises" = "unoptimizes" +"unoptimising" = "unoptimizing" +"unoptimizable" = "unoptimizable" +"unoptimization" = "unoptimization" +"unoptimizations" = "unoptimizations" +"unoptimize" = "unoptimize" +"unoptimized" = "unoptimized" +"unoptimizer" = "unoptimizer" +"unoptimizers" = "unoptimizers" +"unoptimizes" = "unoptimizes" +"unoptimizing" = "unoptimizing" +"unparameterisable" = "unparameterizable" +"unparameterisation" = "unparameterization" +"unparameterisations" = "unparameterizations" +"unparameterise" = "unparameterize" +"unparameterised" = "unparameterized" +"unparameteriser" = "unparameterizer" +"unparameterisers" = "unparameterizers" +"unparameterises" = "unparameterizes" +"unparameterising" = "unparameterizing" +"unparameterizable" = "unparameterizable" +"unparameterization" = "unparameterization" +"unparameterizations" = "unparameterizations" +"unparameterize" = "unparameterize" +"unparameterized" = "unparameterized" +"unparameterizer" = "unparameterizer" +"unparameterizers" = "unparameterizers" +"unparameterizes" = "unparameterizes" +"unparameterizing" = "unparameterizing" +"unrecognisable" = "unrecognizable" +"unrecognisation" = "unrecognization" +"unrecognisations" = "unrecognizations" +"unrecognise" = "unrecognize" +"unrecognised" = "unrecognized" +"unrecogniser" = "unrecognizer" +"unrecognisers" = "unrecognizers" +"unrecognises" = "unrecognizes" +"unrecognising" = "unrecognizing" +"unrecognizable" = "unrecognizable" +"unrecognization" = "unrecognization" +"unrecognizations" = "unrecognizations" +"unrecognize" = "unrecognize" +"unrecognized" = "unrecognized" +"unrecognizer" = "unrecognizer" +"unrecognizers" = "unrecognizers" +"unrecognizes" = "unrecognizes" +"unrecognizing" = "unrecognizing" +"unsynchronisable" = "unsynchronizable" +"unsynchronisation" = "unsynchronization" +"unsynchronisations" = "unsynchronizations" +"unsynchronise" = "unsynchronize" +"unsynchronised" = "unsynchronized" +"unsynchroniser" = "unsynchronizer" +"unsynchronisers" = "unsynchronizers" +"unsynchronises" = "unsynchronizes" +"unsynchronising" = "unsynchronizing" +"unsynchronizable" = "unsynchronizable" +"unsynchronization" = "unsynchronization" +"unsynchronizations" = "unsynchronizations" +"unsynchronize" = "unsynchronize" +"unsynchronized" = "unsynchronized" +"unsynchronizer" = "unsynchronizer" +"unsynchronizers" = "unsynchronizers" +"unsynchronizes" = "unsynchronizes" +"unsynchronizing" = "unsynchronizing" +"utilisable" = "utilizable" +"utilisation" = "utilization" +"utilisations" = "utilizations" +"utilise" = "utilize" +"utilised" = "utilized" +"utiliser" = "utilizer" +"utilisers" = "utilizers" +"utilises" = "utilizes" +"utilising" = "utilizing" +"utilizable" = "utilizable" +"utilization" = "utilization" +"utilizations" = "utilizations" +"utilize" = "utilize" +"utilized" = "utilized" +"utilizer" = "utilizer" +"utilizers" = "utilizers" +"utilizes" = "utilizes" +"utilizing" = "utilizing" +"vectorisable" = "vectorizable" +"vectorisation" = "vectorization" +"vectorisations" = "vectorizations" +"vectorise" = "vectorize" +"vectorised" = "vectorized" +"vectoriser" = "vectorizer" +"vectorisers" = "vectorizers" +"vectorises" = "vectorizes" +"vectorising" = "vectorizing" +"vectorizable" = "vectorizable" +"vectorization" = "vectorization" +"vectorizations" = "vectorizations" +"vectorize" = "vectorize" +"vectorized" = "vectorized" +"vectorizer" = "vectorizer" +"vectorizers" = "vectorizers" +"vectorizes" = "vectorizes" +"vectorizing" = "vectorizing" +"virtualisable" = "virtualizable" +"virtualisation" = "virtualization" +"virtualisations" = "virtualizations" +"virtualise" = "virtualize" +"virtualised" = "virtualized" +"virtualiser" = "virtualizer" +"virtualisers" = "virtualizers" +"virtualises" = "virtualizes" +"virtualising" = "virtualizing" +"virtualizable" = "virtualizable" +"virtualization" = "virtualization" +"virtualizations" = "virtualizations" +"virtualize" = "virtualize" +"virtualized" = "virtualized" +"virtualizer" = "virtualizer" +"virtualizers" = "virtualizers" +"virtualizes" = "virtualizes" +"virtualizing" = "virtualizing" +"visualisable" = "visualizable" +"visualisation" = "visualization" +"visualisations" = "visualizations" +"visualise" = "visualize" +"visualised" = "visualized" +"visualiser" = "visualizer" +"visualisers" = "visualizers" +"visualises" = "visualizes" +"visualising" = "visualizing" +"visualizable" = "visualizable" +"visualization" = "visualization" +"visualizations" = "visualizations" +"visualize" = "visualize" +"visualized" = "visualized" +"visualizer" = "visualizer" +"visualizers" = "visualizers" +"visualizes" = "visualizes" +"visualizing" = "visualizing" +"weaponisable" = "weaponizable" +"weaponisation" = "weaponization" +"weaponisations" = "weaponizations" +"weaponise" = "weaponize" +"weaponised" = "weaponized" +"weaponiser" = "weaponizer" +"weaponisers" = "weaponizers" +"weaponises" = "weaponizes" +"weaponising" = "weaponizing" +"weaponizable" = "weaponizable" +"weaponization" = "weaponization" +"weaponizations" = "weaponizations" +"weaponize" = "weaponize" +"weaponized" = "weaponized" +"weaponizer" = "weaponizer" +"weaponizers" = "weaponizers" +"weaponizes" = "weaponizes" +"weaponizing" = "weaponizing" +"yse" = "yse" +"zeroisable" = "zeroizable" +"zeroisation" = "zeroization" +"zeroisations" = "zeroizations" +"zeroise" = "zeroize" +"zeroised" = "zeroized" +"zeroiser" = "zeroizer" +"zeroisers" = "zeroizers" +"zeroises" = "zeroizes" +"zeroising" = "zeroizing" +"zeroizable" = "zeroizable" +"zeroization" = "zeroization" +"zeroizations" = "zeroizations" +"zeroize" = "zeroize" +"zeroized" = "zeroized" +"zeroizer" = "zeroizer" +"zeroizers" = "zeroizers" +"zeroizes" = "zeroizes" +"zeroizing" = "zeroizing" diff --git a/tests/__snapshots__/test_template.ambr b/tests/__snapshots__/test_template.ambr index eee44c2..501e825 100644 --- a/tests/__snapshots__/test_template.ambr +++ b/tests/__snapshots__/test_template.ambr @@ -54,7 +54,8 @@ lint-python Run Python linters typecheck Run typechecking audit Audit dependencies for known vulnerabilities - markdownlint Lint Markdown files + markdownlint Lint Markdown files and spelling + spelling Enforce en-GB-oxendict spelling nixie Validate Mermaid diagrams test Run tests help Show available targets diff --git a/tests/helpers/agents_contracts.py b/tests/helpers/agents_contracts.py index b1e321a..afdebe5 100644 --- a/tests/helpers/agents_contracts.py +++ b/tests/helpers/agents_contracts.py @@ -64,6 +64,7 @@ def _assert_agents_make_targets_mirror_makefile( "lint", "markdownlint", "nixie", + "spelling", "test", "typecheck", } @@ -110,6 +111,11 @@ def _assert_documented_command_flags( ("AGENTS.md", "pip-audit"), ("Makefile", "pip-audit"), ], + "spelling": [ + ("AGENTS.md", "make spelling"), + ("Makefile", "generate_typos_config.py"), + ("Makefile", "--config typos.toml --force-exclude"), + ], "test": [ ("AGENTS.md", "pytest -v -n $(PYTEST_XDIST_WORKERS)"), ("Makefile", "pytest -v -n auto"), diff --git a/tests/helpers/ci_contracts.py b/tests/helpers/ci_contracts.py index 3511bb7..47981f0 100644 --- a/tests/helpers/ci_contracts.py +++ b/tests/helpers/ci_contracts.py @@ -128,6 +128,9 @@ def _assert_ci_workflow_contracts( assert "make typecheck" in ci_workflow, ( "expected generated CI workflow to run the typecheck gate" ) + assert "make spelling" in ci_workflow, ( + "expected generated CI workflow to run the spelling gate" + ) assert "make audit" in ci_workflow, ( "expected generated CI workflow to run the dependency audit gate" ) diff --git a/tests/helpers/makefile_contracts.py b/tests/helpers/makefile_contracts.py index 8157f0f..46e26f9 100644 --- a/tests/helpers/makefile_contracts.py +++ b/tests/helpers/makefile_contracts.py @@ -43,6 +43,14 @@ def assert_common_make_targets(makefile: str) -> None: assert "lint-python: build" in makefile, "Makefile should expose lint-python" assert "lint: lint-python" in makefile, "lint should delegate to lint-python" assert "audit: build" in makefile, "Makefile should expose audit" + assert "spelling:" in makefile, "Makefile should expose spelling" + assert "TYPOS_VERSION ?= 1.48.0" in makefile, "Makefile should pin typos" + assert "scripts/generate_typos_config.py" in makefile, ( + "spelling should generate configuration" + ) + assert "--config typos.toml --force-exclude" in makefile, ( + "spelling should apply generated configuration and exclusions" + ) assert ".uv-cache .uv-tools" in makefile, "clean should remove uv state dirs" @@ -108,6 +116,9 @@ def _assert_makefile_contracts(*, makefile: str, use_rust: bool) -> None: assert "$(UV_ENV) $(UV) run interrogate --fail-under 100" in makefile, ( "expected generated lint target to enforce docstring coverage" ) + assert "+$(MAKE) spelling" in makefile, ( + "expected generated aggregate gate to serialize spelling last" + ) if use_rust: assert "TEST_CMD :=" in makefile, ( "expected Rust variant to select nextest or cargo test" diff --git a/tests/test_helpers.py b/tests/test_helpers.py index e9cca5c..90e3f17 100644 --- a/tests/test_helpers.py +++ b/tests/test_helpers.py @@ -305,6 +305,10 @@ def test_common_make_targets_reports_missing_contracts() -> None: "lint-python: build\n" "lint: lint-python\n" "audit: build\n" + "TYPOS_VERSION ?= 1.48.0\n" + "spelling:\n" + "\tuv run scripts/generate_typos_config.py\n" + "\tuv tool run typos --config typos.toml --force-exclude\n" "clean:\n" "\trm -rf .uv-cache .uv-tools\n" ) @@ -441,7 +445,7 @@ def test_parent_makefile_test_target_uses_requisite_pytest_command() -> None: """ makefile = (REPO_ROOT / "Makefile").read_text(encoding="utf-8") - assert ".PHONY: help check-fmt lint test typecheck" in makefile, ( + assert ".PHONY: help check-fmt lint spelling test typecheck" in makefile, ( "expected parent Makefile to mark documented gate targets as phony" ) assert "check-fmt: ## Verify template test formatting" in makefile, ( @@ -463,7 +467,7 @@ def test_parent_makefile_test_target_uses_requisite_pytest_command() -> None: "expected parent Makefile to expose a documented typecheck target" ) assert ( - "$(UV) --with pytest --with pytest-copier --with pyyaml --with syrupy " + "$(UV) --with hypothesis --with pytest --with pytest-copier --with pyyaml --with syrupy " "--with make-parser ty check tests/" in makefile ), "expected parent Makefile typecheck target to run ty with test dependencies" assert "test: ## Run template tests" in makefile, ( @@ -482,11 +486,11 @@ def test_parent_makefile_test_target_uses_requisite_pytest_command() -> None: "expected parent Makefile to map WITH_ACT to act validation" ) assert ( - "$(ACT_TEST_ENV) $(UV) --with pytest-copier --with pyyaml --with syrupy " + "$(ACT_TEST_ENV) $(UV) --with hypothesis --with pytest-copier --with pyyaml --with syrupy " "--with make-parser pytest tests/" in makefile ), ( "expected parent Makefile test target to run pytest through $(UV) with " - "pytest-copier, pyyaml, syrupy, make-parser, and act environment wiring" + "Hypothesis, pytest-copier, pyyaml, syrupy, make-parser, and act environment wiring" ) diff --git a/tests/test_parent_ci.py b/tests/test_parent_ci.py index 19aaf2c..f3629bb 100644 --- a/tests/test_parent_ci.py +++ b/tests/test_parent_ci.py @@ -45,6 +45,9 @@ def test_parent_ci_splits_application_and_act_validation_tests() -> None: assert "make test\n" in ci_workflow, ( "expected parent CI to run the normal parent test gate" ) + assert "make spelling\n" in ci_workflow, ( + "expected parent CI to run the spelling gate" + ) assert "uv tool install mdformat-all" not in ci_workflow, ( "expected parent CI not to install mdformat-all through uv" ) diff --git a/tests/test_template.py b/tests/test_template.py index a266f11..d8a6940 100644 --- a/tests/test_template.py +++ b/tests/test_template.py @@ -80,7 +80,16 @@ def test_python_only_help_output_snapshot( ) help_output = project.run("make help") - for target in ["build", "check-fmt", "lint", "typecheck", "audit", "test", "help"]: + for target in [ + "build", + "check-fmt", + "lint", + "typecheck", + "audit", + "spelling", + "test", + "help", + ]: assert f" {target}" in help_output, ( f"expected generated help output to list the {target!r} target" ) diff --git a/tests/test_typos_rollout.py b/tests/test_typos_rollout.py new file mode 100644 index 0000000..6021557 --- /dev/null +++ b/tests/test_typos_rollout.py @@ -0,0 +1,245 @@ +"""Tests for shared-base ``typos.toml`` generation and consumption.""" + +from __future__ import annotations + +import importlib.util +import json +import os +import pathlib +import re +import shutil +import string +import subprocess # noqa: S404 - runs the pinned, trusted typos binary via uv. +import sys +import tomllib +import typing as typ + +import pytest +from hypothesis import given +from hypothesis import strategies as st + +if typ.TYPE_CHECKING: + import types + +REPOSITORY_ROOT = pathlib.Path(__file__).resolve().parents[1] +SCRIPTS_ROOT = REPOSITORY_ROOT / "scripts" +SCRIPT_PATH = SCRIPTS_ROOT / "generate_typos_config.py" +COMMITTED_CONFIG = REPOSITORY_ROOT / "typos.toml" + + +@pytest.fixture(name="generator", scope="module") +def generator_fixture() -> types.ModuleType: + """Load the standalone generator with its neighbouring module visible.""" + sys.path.insert(0, str(SCRIPTS_ROOT)) + try: + spec = importlib.util.spec_from_file_location( + "generate_typos_config", + SCRIPT_PATH, + ) + assert spec is not None, "could not create generator module specification" + assert spec.loader is not None, "generator module specification has no loader" + module = importlib.util.module_from_spec(spec) + spec.loader.exec_module(module) + finally: + sys.path.remove(str(SCRIPTS_ROOT)) + return module + + +def dictionary_text(*, stem: str = "organ", accepted: str = "oxendict") -> str: + """Return a minimal valid shared or local dictionary document.""" + return ( + "schema = 1\n\n[oxford]\n" + f'stems = ["{stem}"]\n\n' + f'[words]\naccepted = ["{accepted}"]\n\n' + "[words.corrections]\n\n[patterns]\nignore = []\n\n" + '[files]\nexclude = [".git"]\n' + ) + + +def prepare_repository( + tmp_path: pathlib.Path, + *, + base_stem: str = "organ", + local_stem: str = "custom", +) -> tuple[pathlib.Path, pathlib.Path]: + """Create a repository root and local shared source for generation tests.""" + repository = tmp_path / "repository" + repository.mkdir() + source = tmp_path / "shared.toml" + source.write_text(dictionary_text(stem=base_stem), encoding="utf-8") + (repository / "typos.local.toml").write_text( + dictionary_text(stem=local_stem, accepted="localword"), + encoding="utf-8", + ) + return repository, source + + +def test_main_refreshes_base_and_merges_local_overlay( + generator: types.ModuleType, + tmp_path: pathlib.Path, +) -> None: + """Generation starts from the shared base and retains narrow local policy.""" + repository, source = prepare_repository(tmp_path) + + result = generator.main(repository=repository, source=source) + rendered = (repository / "typos.toml").read_text(encoding="utf-8") + parsed = tomllib.loads(rendered) + words = parsed["default"]["extend-words"] + + assert result.status == "refreshed" + assert words["organise"] == "organize" + assert words["customise"] == "customize" + assert words["localword"] == "localword" + + +@given(stem=st.text(alphabet=string.ascii_lowercase, min_size=1, max_size=16)) +def test_oxford_mapping_property_covers_every_suffix_pair( + generator: types.ModuleType, + stem: str, +) -> None: + """Every safe stem expands to correction and identity entries.""" + mappings = generator.rollout.generate_word_mappings( + generator.rollout.Dictionary(stems=(stem,)) + ) + + for plain_british, oxford in generator.rollout.SUFFIX_PAIRS: + assert mappings[f"{stem}{plain_british}"] == f"{stem}{oxford}" + assert mappings[f"{stem}{oxford}"] == f"{stem}{oxford}" + + +def test_main_does_not_replace_newer_valid_local_cache( + generator: types.ModuleType, + tmp_path: pathlib.Path, +) -> None: + """An older shared copy cannot overwrite a newer untracked local cache.""" + repository, source = prepare_repository(tmp_path) + generator.main(repository=repository, source=source) + cache = repository / ".typos-oxendict-base.toml" + cache.write_text(dictionary_text(stem="newer"), encoding="utf-8") + os.utime(source, ns=(1_000_000_000, 1_000_000_000)) + os.utime(cache, ns=(2_000_000_000, 2_000_000_000)) + + result = generator.main(repository=repository, source=source) + + assert result.status == "current" + assert '"newerise" = "newerize"' in generator.render_config(repository) + + +def test_main_replaces_cache_from_different_authority( + generator: types.ModuleType, + tmp_path: pathlib.Path, +) -> None: + """Switching the explicit source replaces an unrelated newer cache.""" + repository, first_source = prepare_repository(tmp_path) + second_source = tmp_path / "second.toml" + second_source.write_text(dictionary_text(stem="second"), encoding="utf-8") + os.utime(first_source, ns=(3_000_000_000, 3_000_000_000)) + os.utime(second_source, ns=(1_000_000_000, 1_000_000_000)) + generator.main(repository=repository, source=first_source) + + result = generator.main(repository=repository, source=second_source) + + assert result.status == "refreshed" + assert '"secondise" = "secondize"' in generator.render_config(repository) + + +def test_offline_generation_requires_then_reuses_valid_cache( + generator: types.ModuleType, + tmp_path: pathlib.Path, +) -> None: + """Offline mode is safe after population and explicit before population.""" + repository, source = prepare_repository(tmp_path) + + with pytest.raises(FileNotFoundError, match="no cached shared dictionary"): + generator.main(repository=repository, source=source, offline=True) + + generator.main(repository=repository, source=source) + result = generator.main(repository=repository, source=source, offline=True) + + assert result.status == "offline-cache" + + +def test_rendered_config_is_deterministic_valid_toml( + generator: types.ModuleType, + tmp_path: pathlib.Path, +) -> None: + """Rendered output is stable, parseable and has one trailing newline.""" + repository, source = prepare_repository(tmp_path) + generator.main(repository=repository, source=source) + + first = generator.render_config(repository) + second = generator.render_config(repository) + + assert first == second + assert tomllib.loads(first)["default"]["locale"] == "en-gb" + assert first.endswith("\n") + assert not first.endswith("\n\n") + + +def test_committed_config_matches_current_shared_dictionary( + generator: types.ModuleType, + tmp_path: pathlib.Path, +) -> None: + """The committed generated file has not drifted from shared and local data.""" + output = tmp_path / "typos.toml" + + generator.main(output) + + assert COMMITTED_CONFIG.read_text(encoding="utf-8") == output.read_text( + encoding="utf-8" + ) + tomllib.loads(output.read_text(encoding="utf-8")) + + +def _pinned_typos_version() -> str: + """Read the Makefile's single source of truth for the typos version.""" + makefile = (REPOSITORY_ROOT / "Makefile").read_text(encoding="utf-8") + match = re.search(r"^TYPOS_VERSION\s*\?=\s*(\S+)", makefile, re.MULTILINE) + assert match is not None, "TYPOS_VERSION not found in Makefile" + return match.group(1) + + +@pytest.mark.slow +def test_generated_config_loads_in_pinned_typos( + generator: types.ModuleType, + tmp_path: pathlib.Path, +) -> None: + """The real pinned binary enforces Oxford and British sample spellings.""" + uv_executable = shutil.which("uv") + if uv_executable is None: + pytest.skip("uv is unavailable to run the pinned typos binary") + repository, source = prepare_repository(tmp_path) + config = repository / "typos.toml" + generator.main(repository=repository, source=source) + sample = repository / "sample.md" + sample.write_text( + "The team will organise color output.\n", + encoding="utf-8", + ) + + result = subprocess.run( # noqa: S603 - argv contains trusted paths and literals. + [ + uv_executable, + "tool", + "run", + f"typos@{_pinned_typos_version()}", + "--config", + str(config), + "--format", + "json", + str(sample), + ], + capture_output=True, + text=True, + timeout=90, + check=False, + ) + corrections = { + entry["typo"]: entry.get("corrections", []) + for line in result.stdout.splitlines() + for entry in (json.loads(line),) + if entry.get("type") == "typo" + } + + assert corrections.get("organise") == ["organize"] + assert corrections.get("color") == ["colour"] diff --git a/typos.local.toml b/typos.local.toml new file mode 100644 index 0000000..5e01e97 --- /dev/null +++ b/typos.local.toml @@ -0,0 +1,22 @@ +# Repository-specific identifiers, quotations and deliberate fixtures. + +schema = 1 + +[oxford] +stems = [] + +[words] +accepted = [] + +[words.corrections] + +[patterns] +ignore = [ + 'Center \| Microsoft Learn', +] + +[files] +exclude = [ + "docs/configuring-a-copier-template.md", + "docs/creating-a-copier-template.md", +] diff --git a/typos.toml b/typos.toml new file mode 100644 index 0000000..81e512c --- /dev/null +++ b/typos.toml @@ -0,0 +1,2633 @@ +# Generated from the shared en-GB-oxendict dictionary. +# Regenerate with scripts/generate_typos_config.py; do not edit by hand. + +[files] +extend-exclude = [ + ".git", + ".hypothesis", + ".pytest_cache", + ".tox", + ".typos-oxendict-base.json", + ".typos-oxendict-base.toml", + ".uv-cache", + ".uv-tools", + ".venv", + "Cargo.lock", + "bun.lock", + "data/typos-oxendict-base.toml", + "dist", + "docs/configuring-a-copier-template.md", + "docs/creating-a-copier-template.md", + "node_modules", + "package-lock.json", + "pnpm-lock.yaml", + "target", + "typos.local.toml", + "typos.toml", + "uv.lock", + "yarn.lock", +] + +[default] +locale = "en-gb" +extend-ignore-re = [ + "(?s)```.*?```", + "Center \\| Microsoft Learn", + "`[^`\\n]+`", +] + +[default.extend-words] +"absolutisable" = "absolutizable" +"absolutisation" = "absolutization" +"absolutisations" = "absolutizations" +"absolutise" = "absolutize" +"absolutised" = "absolutized" +"absolutiser" = "absolutizer" +"absolutisers" = "absolutizers" +"absolutises" = "absolutizes" +"absolutising" = "absolutizing" +"absolutizable" = "absolutizable" +"absolutization" = "absolutization" +"absolutizations" = "absolutizations" +"absolutize" = "absolutize" +"absolutized" = "absolutized" +"absolutizer" = "absolutizer" +"absolutizers" = "absolutizers" +"absolutizes" = "absolutizes" +"absolutizing" = "absolutizing" +"actualisable" = "actualizable" +"actualisation" = "actualization" +"actualisations" = "actualizations" +"actualise" = "actualize" +"actualised" = "actualized" +"actualiser" = "actualizer" +"actualisers" = "actualizers" +"actualises" = "actualizes" +"actualising" = "actualizing" +"actualizable" = "actualizable" +"actualization" = "actualization" +"actualizations" = "actualizations" +"actualize" = "actualize" +"actualized" = "actualized" +"actualizer" = "actualizer" +"actualizers" = "actualizers" +"actualizes" = "actualizes" +"actualizing" = "actualizing" +"alphabetisable" = "alphabetizable" +"alphabetisation" = "alphabetization" +"alphabetisations" = "alphabetizations" +"alphabetise" = "alphabetize" +"alphabetised" = "alphabetized" +"alphabetiser" = "alphabetizer" +"alphabetisers" = "alphabetizers" +"alphabetises" = "alphabetizes" +"alphabetising" = "alphabetizing" +"alphabetizable" = "alphabetizable" +"alphabetization" = "alphabetization" +"alphabetizations" = "alphabetizations" +"alphabetize" = "alphabetize" +"alphabetized" = "alphabetized" +"alphabetizer" = "alphabetizer" +"alphabetizers" = "alphabetizers" +"alphabetizes" = "alphabetizes" +"alphabetizing" = "alphabetizing" +"amortisable" = "amortizable" +"amortisation" = "amortization" +"amortisations" = "amortizations" +"amortise" = "amortize" +"amortised" = "amortized" +"amortiser" = "amortizer" +"amortisers" = "amortizers" +"amortises" = "amortizes" +"amortising" = "amortizing" +"amortizable" = "amortizable" +"amortization" = "amortization" +"amortizations" = "amortizations" +"amortize" = "amortize" +"amortized" = "amortized" +"amortizer" = "amortizer" +"amortizers" = "amortizers" +"amortizes" = "amortizes" +"amortizing" = "amortizing" +"anonymisable" = "anonymizable" +"anonymisation" = "anonymization" +"anonymisations" = "anonymizations" +"anonymise" = "anonymize" +"anonymised" = "anonymized" +"anonymiser" = "anonymizer" +"anonymisers" = "anonymizers" +"anonymises" = "anonymizes" +"anonymising" = "anonymizing" +"anonymizable" = "anonymizable" +"anonymization" = "anonymization" +"anonymizations" = "anonymizations" +"anonymize" = "anonymize" +"anonymized" = "anonymized" +"anonymizer" = "anonymizer" +"anonymizers" = "anonymizers" +"anonymizes" = "anonymizes" +"anonymizing" = "anonymizing" +"apologisable" = "apologizable" +"apologisation" = "apologization" +"apologisations" = "apologizations" +"apologise" = "apologize" +"apologised" = "apologized" +"apologiser" = "apologizer" +"apologisers" = "apologizers" +"apologises" = "apologizes" +"apologising" = "apologizing" +"apologizable" = "apologizable" +"apologization" = "apologization" +"apologizations" = "apologizations" +"apologize" = "apologize" +"apologized" = "apologized" +"apologizer" = "apologizer" +"apologizers" = "apologizers" +"apologizes" = "apologizes" +"apologizing" = "apologizing" +"atomisable" = "atomizable" +"atomisation" = "atomization" +"atomisations" = "atomizations" +"atomise" = "atomize" +"atomised" = "atomized" +"atomiser" = "atomizer" +"atomisers" = "atomizers" +"atomises" = "atomizes" +"atomising" = "atomizing" +"atomizable" = "atomizable" +"atomization" = "atomization" +"atomizations" = "atomizations" +"atomize" = "atomize" +"atomized" = "atomized" +"atomizer" = "atomizer" +"atomizers" = "atomizers" +"atomizes" = "atomizes" +"atomizing" = "atomizing" +"authorisable" = "authorizable" +"authorisation" = "authorization" +"authorisations" = "authorizations" +"authorise" = "authorize" +"authorised" = "authorized" +"authoriser" = "authorizer" +"authorisers" = "authorizers" +"authorises" = "authorizes" +"authorising" = "authorizing" +"authorizable" = "authorizable" +"authorization" = "authorization" +"authorizations" = "authorizations" +"authorize" = "authorize" +"authorized" = "authorized" +"authorizer" = "authorizer" +"authorizers" = "authorizers" +"authorizes" = "authorizes" +"authorizing" = "authorizing" +"canonicalisable" = "canonicalizable" +"canonicalisation" = "canonicalization" +"canonicalisations" = "canonicalizations" +"canonicalise" = "canonicalize" +"canonicalised" = "canonicalized" +"canonicaliser" = "canonicalizer" +"canonicalisers" = "canonicalizers" +"canonicalises" = "canonicalizes" +"canonicalising" = "canonicalizing" +"canonicalizable" = "canonicalizable" +"canonicalization" = "canonicalization" +"canonicalizations" = "canonicalizations" +"canonicalize" = "canonicalize" +"canonicalized" = "canonicalized" +"canonicalizer" = "canonicalizer" +"canonicalizers" = "canonicalizers" +"canonicalizes" = "canonicalizes" +"canonicalizing" = "canonicalizing" +"capitalisable" = "capitalizable" +"capitalisation" = "capitalization" +"capitalisations" = "capitalizations" +"capitalise" = "capitalize" +"capitalised" = "capitalized" +"capitaliser" = "capitalizer" +"capitalisers" = "capitalizers" +"capitalises" = "capitalizes" +"capitalising" = "capitalizing" +"capitalizable" = "capitalizable" +"capitalization" = "capitalization" +"capitalizations" = "capitalizations" +"capitalize" = "capitalize" +"capitalized" = "capitalized" +"capitalizer" = "capitalizer" +"capitalizers" = "capitalizers" +"capitalizes" = "capitalizes" +"capitalizing" = "capitalizing" +"categorisable" = "categorizable" +"categorisation" = "categorization" +"categorisations" = "categorizations" +"categorise" = "categorize" +"categorised" = "categorized" +"categoriser" = "categorizer" +"categorisers" = "categorizers" +"categorises" = "categorizes" +"categorising" = "categorizing" +"categorizable" = "categorizable" +"categorization" = "categorization" +"categorizations" = "categorizations" +"categorize" = "categorize" +"categorized" = "categorized" +"categorizer" = "categorizer" +"categorizers" = "categorizers" +"categorizes" = "categorizes" +"categorizing" = "categorizing" +"centralisable" = "centralizable" +"centralisation" = "centralization" +"centralisations" = "centralizations" +"centralise" = "centralize" +"centralised" = "centralized" +"centraliser" = "centralizer" +"centralisers" = "centralizers" +"centralises" = "centralizes" +"centralising" = "centralizing" +"centralizable" = "centralizable" +"centralization" = "centralization" +"centralizations" = "centralizations" +"centralize" = "centralize" +"centralized" = "centralized" +"centralizer" = "centralizer" +"centralizers" = "centralizers" +"centralizes" = "centralizes" +"centralizing" = "centralizing" +"characterisable" = "characterizable" +"characterisation" = "characterization" +"characterisations" = "characterizations" +"characterise" = "characterize" +"characterised" = "characterized" +"characteriser" = "characterizer" +"characterisers" = "characterizers" +"characterises" = "characterizes" +"characterising" = "characterizing" +"characterizable" = "characterizable" +"characterization" = "characterization" +"characterizations" = "characterizations" +"characterize" = "characterize" +"characterized" = "characterized" +"characterizer" = "characterizer" +"characterizers" = "characterizers" +"characterizes" = "characterizes" +"characterizing" = "characterizing" +"civilisable" = "civilizable" +"civilisation" = "civilization" +"civilisations" = "civilizations" +"civilise" = "civilize" +"civilised" = "civilized" +"civiliser" = "civilizer" +"civilisers" = "civilizers" +"civilises" = "civilizes" +"civilising" = "civilizing" +"civilizable" = "civilizable" +"civilization" = "civilization" +"civilizations" = "civilizations" +"civilize" = "civilize" +"civilized" = "civilized" +"civilizer" = "civilizer" +"civilizers" = "civilizers" +"civilizes" = "civilizes" +"civilizing" = "civilizing" +"colonisable" = "colonizable" +"colonisation" = "colonization" +"colonisations" = "colonizations" +"colonise" = "colonize" +"colonised" = "colonized" +"coloniser" = "colonizer" +"colonisers" = "colonizers" +"colonises" = "colonizes" +"colonising" = "colonizing" +"colonizable" = "colonizable" +"colonization" = "colonization" +"colonizations" = "colonizations" +"colonize" = "colonize" +"colonized" = "colonized" +"colonizer" = "colonizer" +"colonizers" = "colonizers" +"colonizes" = "colonizes" +"colonizing" = "colonizing" +"colourisable" = "colourizable" +"colourisation" = "colourization" +"colourisations" = "colourizations" +"colourise" = "colourize" +"colourised" = "colourized" +"colouriser" = "colourizer" +"colourisers" = "colourizers" +"colourises" = "colourizes" +"colourising" = "colourizing" +"colourizable" = "colourizable" +"colourization" = "colourization" +"colourizations" = "colourizations" +"colourize" = "colourize" +"colourized" = "colourized" +"colourizer" = "colourizer" +"colourizers" = "colourizers" +"colourizes" = "colourizes" +"colourizing" = "colourizing" +"commonisable" = "commonizable" +"commonisation" = "commonization" +"commonisations" = "commonizations" +"commonise" = "commonize" +"commonised" = "commonized" +"commoniser" = "commonizer" +"commonisers" = "commonizers" +"commonises" = "commonizes" +"commonising" = "commonizing" +"commonizable" = "commonizable" +"commonization" = "commonization" +"commonizations" = "commonizations" +"commonize" = "commonize" +"commonized" = "commonized" +"commonizer" = "commonizer" +"commonizers" = "commonizers" +"commonizes" = "commonizes" +"commonizing" = "commonizing" +"conceptualisable" = "conceptualizable" +"conceptualisation" = "conceptualization" +"conceptualisations" = "conceptualizations" +"conceptualise" = "conceptualize" +"conceptualised" = "conceptualized" +"conceptualiser" = "conceptualizer" +"conceptualisers" = "conceptualizers" +"conceptualises" = "conceptualizes" +"conceptualising" = "conceptualizing" +"conceptualizable" = "conceptualizable" +"conceptualization" = "conceptualization" +"conceptualizations" = "conceptualizations" +"conceptualize" = "conceptualize" +"conceptualized" = "conceptualized" +"conceptualizer" = "conceptualizer" +"conceptualizers" = "conceptualizers" +"conceptualizes" = "conceptualizes" +"conceptualizing" = "conceptualizing" +"concretisable" = "concretizable" +"concretisation" = "concretization" +"concretisations" = "concretizations" +"concretise" = "concretize" +"concretised" = "concretized" +"concretiser" = "concretizer" +"concretisers" = "concretizers" +"concretises" = "concretizes" +"concretising" = "concretizing" +"concretizable" = "concretizable" +"concretization" = "concretization" +"concretizations" = "concretizations" +"concretize" = "concretize" +"concretized" = "concretized" +"concretizer" = "concretizer" +"concretizers" = "concretizers" +"concretizes" = "concretizes" +"concretizing" = "concretizing" +"containerisable" = "containerizable" +"containerisation" = "containerization" +"containerisations" = "containerizations" +"containerise" = "containerize" +"containerised" = "containerized" +"containeriser" = "containerizer" +"containerisers" = "containerizers" +"containerises" = "containerizes" +"containerising" = "containerizing" +"containerizable" = "containerizable" +"containerization" = "containerization" +"containerizations" = "containerizations" +"containerize" = "containerize" +"containerized" = "containerized" +"containerizer" = "containerizer" +"containerizers" = "containerizers" +"containerizes" = "containerizes" +"containerizing" = "containerizing" +"contextualisable" = "contextualizable" +"contextualisation" = "contextualization" +"contextualisations" = "contextualizations" +"contextualise" = "contextualize" +"contextualised" = "contextualized" +"contextualiser" = "contextualizer" +"contextualisers" = "contextualizers" +"contextualises" = "contextualizes" +"contextualising" = "contextualizing" +"contextualizable" = "contextualizable" +"contextualization" = "contextualization" +"contextualizations" = "contextualizations" +"contextualize" = "contextualize" +"contextualized" = "contextualized" +"contextualizer" = "contextualizer" +"contextualizers" = "contextualizers" +"contextualizes" = "contextualizes" +"contextualizing" = "contextualizing" +"criticisable" = "criticizable" +"criticisation" = "criticization" +"criticisations" = "criticizations" +"criticise" = "criticize" +"criticised" = "criticized" +"criticiser" = "criticizer" +"criticisers" = "criticizers" +"criticises" = "criticizes" +"criticising" = "criticizing" +"criticizable" = "criticizable" +"criticization" = "criticization" +"criticizations" = "criticizations" +"criticize" = "criticize" +"criticized" = "criticized" +"criticizer" = "criticizer" +"criticizers" = "criticizers" +"criticizes" = "criticizes" +"criticizing" = "criticizing" +"crystallisable" = "crystallizable" +"crystallisation" = "crystallization" +"crystallisations" = "crystallizations" +"crystallise" = "crystallize" +"crystallised" = "crystallized" +"crystalliser" = "crystallizer" +"crystallisers" = "crystallizers" +"crystallises" = "crystallizes" +"crystallising" = "crystallizing" +"crystallizable" = "crystallizable" +"crystallization" = "crystallization" +"crystallizations" = "crystallizations" +"crystallize" = "crystallize" +"crystallized" = "crystallized" +"crystallizer" = "crystallizer" +"crystallizers" = "crystallizers" +"crystallizes" = "crystallizes" +"crystallizing" = "crystallizing" +"customisable" = "customizable" +"customisation" = "customization" +"customisations" = "customizations" +"customise" = "customize" +"customised" = "customized" +"customiser" = "customizer" +"customisers" = "customizers" +"customises" = "customizes" +"customising" = "customizing" +"customizable" = "customizable" +"customization" = "customization" +"customizations" = "customizations" +"customize" = "customize" +"customized" = "customized" +"customizer" = "customizer" +"customizers" = "customizers" +"customizes" = "customizes" +"customizing" = "customizing" +"daemonisable" = "daemonizable" +"daemonisation" = "daemonization" +"daemonisations" = "daemonizations" +"daemonise" = "daemonize" +"daemonised" = "daemonized" +"daemoniser" = "daemonizer" +"daemonisers" = "daemonizers" +"daemonises" = "daemonizes" +"daemonising" = "daemonizing" +"daemonizable" = "daemonizable" +"daemonization" = "daemonization" +"daemonizations" = "daemonizations" +"daemonize" = "daemonize" +"daemonized" = "daemonized" +"daemonizer" = "daemonizer" +"daemonizers" = "daemonizers" +"daemonizes" = "daemonizes" +"daemonizing" = "daemonizing" +"decentralisable" = "decentralizable" +"decentralisation" = "decentralization" +"decentralisations" = "decentralizations" +"decentralise" = "decentralize" +"decentralised" = "decentralized" +"decentraliser" = "decentralizer" +"decentralisers" = "decentralizers" +"decentralises" = "decentralizes" +"decentralising" = "decentralizing" +"decentralizable" = "decentralizable" +"decentralization" = "decentralization" +"decentralizations" = "decentralizations" +"decentralize" = "decentralize" +"decentralized" = "decentralized" +"decentralizer" = "decentralizer" +"decentralizers" = "decentralizers" +"decentralizes" = "decentralizes" +"decentralizing" = "decentralizing" +"denormalisable" = "denormalizable" +"denormalisation" = "denormalization" +"denormalisations" = "denormalizations" +"denormalise" = "denormalize" +"denormalised" = "denormalized" +"denormaliser" = "denormalizer" +"denormalisers" = "denormalizers" +"denormalises" = "denormalizes" +"denormalising" = "denormalizing" +"denormalizable" = "denormalizable" +"denormalization" = "denormalization" +"denormalizations" = "denormalizations" +"denormalize" = "denormalize" +"denormalized" = "denormalized" +"denormalizer" = "denormalizer" +"denormalizers" = "denormalizers" +"denormalizes" = "denormalizes" +"denormalizing" = "denormalizing" +"derandomisable" = "derandomizable" +"derandomisation" = "derandomization" +"derandomisations" = "derandomizations" +"derandomise" = "derandomize" +"derandomised" = "derandomized" +"derandomiser" = "derandomizer" +"derandomisers" = "derandomizers" +"derandomises" = "derandomizes" +"derandomising" = "derandomizing" +"derandomizable" = "derandomizable" +"derandomization" = "derandomization" +"derandomizations" = "derandomizations" +"derandomize" = "derandomize" +"derandomized" = "derandomized" +"derandomizer" = "derandomizer" +"derandomizers" = "derandomizers" +"derandomizes" = "derandomizes" +"derandomizing" = "derandomizing" +"deserialisable" = "deserializable" +"deserialisation" = "deserialization" +"deserialisations" = "deserializations" +"deserialise" = "deserialize" +"deserialised" = "deserialized" +"deserialiser" = "deserializer" +"deserialisers" = "deserializers" +"deserialises" = "deserializes" +"deserialising" = "deserializing" +"deserializable" = "deserializable" +"deserialization" = "deserialization" +"deserializations" = "deserializations" +"deserialize" = "deserialize" +"deserialized" = "deserialized" +"deserializer" = "deserializer" +"deserializers" = "deserializers" +"deserializes" = "deserializes" +"deserializing" = "deserializing" +"destabilisable" = "destabilizable" +"destabilisation" = "destabilization" +"destabilisations" = "destabilizations" +"destabilise" = "destabilize" +"destabilised" = "destabilized" +"destabiliser" = "destabilizer" +"destabilisers" = "destabilizers" +"destabilises" = "destabilizes" +"destabilising" = "destabilizing" +"destabilizable" = "destabilizable" +"destabilization" = "destabilization" +"destabilizations" = "destabilizations" +"destabilize" = "destabilize" +"destabilized" = "destabilized" +"destabilizer" = "destabilizer" +"destabilizers" = "destabilizers" +"destabilizes" = "destabilizes" +"destabilizing" = "destabilizing" +"desynchronisable" = "desynchronizable" +"desynchronisation" = "desynchronization" +"desynchronisations" = "desynchronizations" +"desynchronise" = "desynchronize" +"desynchronised" = "desynchronized" +"desynchroniser" = "desynchronizer" +"desynchronisers" = "desynchronizers" +"desynchronises" = "desynchronizes" +"desynchronising" = "desynchronizing" +"desynchronizable" = "desynchronizable" +"desynchronization" = "desynchronization" +"desynchronizations" = "desynchronizations" +"desynchronize" = "desynchronize" +"desynchronized" = "desynchronized" +"desynchronizer" = "desynchronizer" +"desynchronizers" = "desynchronizers" +"desynchronizes" = "desynchronizes" +"desynchronizing" = "desynchronizing" +"dockerisable" = "dockerizable" +"dockerisation" = "dockerization" +"dockerisations" = "dockerizations" +"dockerise" = "dockerize" +"dockerised" = "dockerized" +"dockeriser" = "dockerizer" +"dockerisers" = "dockerizers" +"dockerises" = "dockerizes" +"dockerising" = "dockerizing" +"dockerizable" = "dockerizable" +"dockerization" = "dockerization" +"dockerizations" = "dockerizations" +"dockerize" = "dockerize" +"dockerized" = "dockerized" +"dockerizer" = "dockerizer" +"dockerizers" = "dockerizers" +"dockerizes" = "dockerizes" +"dockerizing" = "dockerizing" +"dramatisable" = "dramatizable" +"dramatisation" = "dramatization" +"dramatisations" = "dramatizations" +"dramatise" = "dramatize" +"dramatised" = "dramatized" +"dramatiser" = "dramatizer" +"dramatisers" = "dramatizers" +"dramatises" = "dramatizes" +"dramatising" = "dramatizing" +"dramatizable" = "dramatizable" +"dramatization" = "dramatization" +"dramatizations" = "dramatizations" +"dramatize" = "dramatize" +"dramatized" = "dramatized" +"dramatizer" = "dramatizer" +"dramatizers" = "dramatizers" +"dramatizes" = "dramatizes" +"dramatizing" = "dramatizing" +"emphasisable" = "emphasizable" +"emphasisation" = "emphasization" +"emphasisations" = "emphasizations" +"emphasise" = "emphasize" +"emphasised" = "emphasized" +"emphasiser" = "emphasizer" +"emphasisers" = "emphasizers" +"emphasises" = "emphasizes" +"emphasising" = "emphasizing" +"emphasizable" = "emphasizable" +"emphasization" = "emphasization" +"emphasizations" = "emphasizations" +"emphasize" = "emphasize" +"emphasized" = "emphasized" +"emphasizer" = "emphasizer" +"emphasizers" = "emphasizers" +"emphasizes" = "emphasizes" +"emphasizing" = "emphasizing" +"energisable" = "energizable" +"energisation" = "energization" +"energisations" = "energizations" +"energise" = "energize" +"energised" = "energized" +"energiser" = "energizer" +"energisers" = "energizers" +"energises" = "energizes" +"energising" = "energizing" +"energizable" = "energizable" +"energization" = "energization" +"energizations" = "energizations" +"energize" = "energize" +"energized" = "energized" +"energizer" = "energizer" +"energizers" = "energizers" +"energizes" = "energizes" +"energizing" = "energizing" +"equalisable" = "equalizable" +"equalisation" = "equalization" +"equalisations" = "equalizations" +"equalise" = "equalize" +"equalised" = "equalized" +"equaliser" = "equalizer" +"equalisers" = "equalizers" +"equalises" = "equalizes" +"equalising" = "equalizing" +"equalizable" = "equalizable" +"equalization" = "equalization" +"equalizations" = "equalizations" +"equalize" = "equalize" +"equalized" = "equalized" +"equalizer" = "equalizer" +"equalizers" = "equalizers" +"equalizes" = "equalizes" +"equalizing" = "equalizing" +"externalisable" = "externalizable" +"externalisation" = "externalization" +"externalisations" = "externalizations" +"externalise" = "externalize" +"externalised" = "externalized" +"externaliser" = "externalizer" +"externalisers" = "externalizers" +"externalises" = "externalizes" +"externalising" = "externalizing" +"externalizable" = "externalizable" +"externalization" = "externalization" +"externalizations" = "externalizations" +"externalize" = "externalize" +"externalized" = "externalized" +"externalizer" = "externalizer" +"externalizers" = "externalizers" +"externalizes" = "externalizes" +"externalizing" = "externalizing" +"factorisable" = "factorizable" +"factorisation" = "factorization" +"factorisations" = "factorizations" +"factorise" = "factorize" +"factorised" = "factorized" +"factoriser" = "factorizer" +"factorisers" = "factorizers" +"factorises" = "factorizes" +"factorising" = "factorizing" +"factorizable" = "factorizable" +"factorization" = "factorization" +"factorizations" = "factorizations" +"factorize" = "factorize" +"factorized" = "factorized" +"factorizer" = "factorizer" +"factorizers" = "factorizers" +"factorizes" = "factorizes" +"factorizing" = "factorizing" +"familiarisable" = "familiarizable" +"familiarisation" = "familiarization" +"familiarisations" = "familiarizations" +"familiarise" = "familiarize" +"familiarised" = "familiarized" +"familiariser" = "familiarizer" +"familiarisers" = "familiarizers" +"familiarises" = "familiarizes" +"familiarising" = "familiarizing" +"familiarizable" = "familiarizable" +"familiarization" = "familiarization" +"familiarizations" = "familiarizations" +"familiarize" = "familiarize" +"familiarized" = "familiarized" +"familiarizer" = "familiarizer" +"familiarizers" = "familiarizers" +"familiarizes" = "familiarizes" +"familiarizing" = "familiarizing" +"finalisable" = "finalizable" +"finalisation" = "finalization" +"finalisations" = "finalizations" +"finalise" = "finalize" +"finalised" = "finalized" +"finaliser" = "finalizer" +"finalisers" = "finalizers" +"finalises" = "finalizes" +"finalising" = "finalizing" +"finalizable" = "finalizable" +"finalization" = "finalization" +"finalizations" = "finalizations" +"finalize" = "finalize" +"finalized" = "finalized" +"finalizer" = "finalizer" +"finalizers" = "finalizers" +"finalizes" = "finalizes" +"finalizing" = "finalizing" +"formalisable" = "formalizable" +"formalisation" = "formalization" +"formalisations" = "formalizations" +"formalise" = "formalize" +"formalised" = "formalized" +"formaliser" = "formalizer" +"formalisers" = "formalizers" +"formalises" = "formalizes" +"formalising" = "formalizing" +"formalizable" = "formalizable" +"formalization" = "formalization" +"formalizations" = "formalizations" +"formalize" = "formalize" +"formalized" = "formalized" +"formalizer" = "formalizer" +"formalizers" = "formalizers" +"formalizes" = "formalizes" +"formalizing" = "formalizing" +"fossilisable" = "fossilizable" +"fossilisation" = "fossilization" +"fossilisations" = "fossilizations" +"fossilise" = "fossilize" +"fossilised" = "fossilized" +"fossiliser" = "fossilizer" +"fossilisers" = "fossilizers" +"fossilises" = "fossilizes" +"fossilising" = "fossilizing" +"fossilizable" = "fossilizable" +"fossilization" = "fossilization" +"fossilizations" = "fossilizations" +"fossilize" = "fossilize" +"fossilized" = "fossilized" +"fossilizer" = "fossilizer" +"fossilizers" = "fossilizers" +"fossilizes" = "fossilizes" +"fossilizing" = "fossilizing" +"generalisable" = "generalizable" +"generalisation" = "generalization" +"generalisations" = "generalizations" +"generalise" = "generalize" +"generalised" = "generalized" +"generaliser" = "generalizer" +"generalisers" = "generalizers" +"generalises" = "generalizes" +"generalising" = "generalizing" +"generalizable" = "generalizable" +"generalization" = "generalization" +"generalizations" = "generalizations" +"generalize" = "generalize" +"generalized" = "generalized" +"generalizer" = "generalizer" +"generalizers" = "generalizers" +"generalizes" = "generalizes" +"generalizing" = "generalizing" +"globalisable" = "globalizable" +"globalisation" = "globalization" +"globalisations" = "globalizations" +"globalise" = "globalize" +"globalised" = "globalized" +"globaliser" = "globalizer" +"globalisers" = "globalizers" +"globalises" = "globalizes" +"globalising" = "globalizing" +"globalizable" = "globalizable" +"globalization" = "globalization" +"globalizations" = "globalizations" +"globalize" = "globalize" +"globalized" = "globalized" +"globalizer" = "globalizer" +"globalizers" = "globalizers" +"globalizes" = "globalizes" +"globalizing" = "globalizing" +"harmonisable" = "harmonizable" +"harmonisation" = "harmonization" +"harmonisations" = "harmonizations" +"harmonise" = "harmonize" +"harmonised" = "harmonized" +"harmoniser" = "harmonizer" +"harmonisers" = "harmonizers" +"harmonises" = "harmonizes" +"harmonising" = "harmonizing" +"harmonizable" = "harmonizable" +"harmonization" = "harmonization" +"harmonizations" = "harmonizations" +"harmonize" = "harmonize" +"harmonized" = "harmonized" +"harmonizer" = "harmonizer" +"harmonizers" = "harmonizers" +"harmonizes" = "harmonizes" +"harmonizing" = "harmonizing" +"homogenisable" = "homogenizable" +"homogenisation" = "homogenization" +"homogenisations" = "homogenizations" +"homogenise" = "homogenize" +"homogenised" = "homogenized" +"homogeniser" = "homogenizer" +"homogenisers" = "homogenizers" +"homogenises" = "homogenizes" +"homogenising" = "homogenizing" +"homogenizable" = "homogenizable" +"homogenization" = "homogenization" +"homogenizations" = "homogenizations" +"homogenize" = "homogenize" +"homogenized" = "homogenized" +"homogenizer" = "homogenizer" +"homogenizers" = "homogenizers" +"homogenizes" = "homogenizes" +"homogenizing" = "homogenizing" +"humanisable" = "humanizable" +"humanisation" = "humanization" +"humanisations" = "humanizations" +"humanise" = "humanize" +"humanised" = "humanized" +"humaniser" = "humanizer" +"humanisers" = "humanizers" +"humanises" = "humanizes" +"humanising" = "humanizing" +"humanizable" = "humanizable" +"humanization" = "humanization" +"humanizations" = "humanizations" +"humanize" = "humanize" +"humanized" = "humanized" +"humanizer" = "humanizer" +"humanizers" = "humanizers" +"humanizes" = "humanizes" +"humanizing" = "humanizing" +"hypothesisable" = "hypothesizable" +"hypothesisation" = "hypothesization" +"hypothesisations" = "hypothesizations" +"hypothesise" = "hypothesize" +"hypothesised" = "hypothesized" +"hypothesiser" = "hypothesizer" +"hypothesisers" = "hypothesizers" +"hypothesises" = "hypothesizes" +"hypothesising" = "hypothesizing" +"hypothesizable" = "hypothesizable" +"hypothesization" = "hypothesization" +"hypothesizations" = "hypothesizations" +"hypothesize" = "hypothesize" +"hypothesized" = "hypothesized" +"hypothesizer" = "hypothesizer" +"hypothesizers" = "hypothesizers" +"hypothesizes" = "hypothesizes" +"hypothesizing" = "hypothesizing" +"idealisable" = "idealizable" +"idealisation" = "idealization" +"idealisations" = "idealizations" +"idealise" = "idealize" +"idealised" = "idealized" +"idealiser" = "idealizer" +"idealisers" = "idealizers" +"idealises" = "idealizes" +"idealising" = "idealizing" +"idealizable" = "idealizable" +"idealization" = "idealization" +"idealizations" = "idealizations" +"idealize" = "idealize" +"idealized" = "idealized" +"idealizer" = "idealizer" +"idealizers" = "idealizers" +"idealizes" = "idealizes" +"idealizing" = "idealizing" +"industrialisable" = "industrializable" +"industrialisation" = "industrialization" +"industrialisations" = "industrializations" +"industrialise" = "industrialize" +"industrialised" = "industrialized" +"industrialiser" = "industrializer" +"industrialisers" = "industrializers" +"industrialises" = "industrializes" +"industrialising" = "industrializing" +"industrializable" = "industrializable" +"industrialization" = "industrialization" +"industrializations" = "industrializations" +"industrialize" = "industrialize" +"industrialized" = "industrialized" +"industrializer" = "industrializer" +"industrializers" = "industrializers" +"industrializes" = "industrializes" +"industrializing" = "industrializing" +"initialisable" = "initializable" +"initialisation" = "initialization" +"initialisations" = "initializations" +"initialise" = "initialize" +"initialised" = "initialized" +"initialiser" = "initializer" +"initialisers" = "initializers" +"initialises" = "initializes" +"initialising" = "initializing" +"initializable" = "initializable" +"initialization" = "initialization" +"initializations" = "initializations" +"initialize" = "initialize" +"initialized" = "initialized" +"initializer" = "initializer" +"initializers" = "initializers" +"initializes" = "initializes" +"initializing" = "initializing" +"institutionalisable" = "institutionalizable" +"institutionalisation" = "institutionalization" +"institutionalisations" = "institutionalizations" +"institutionalise" = "institutionalize" +"institutionalised" = "institutionalized" +"institutionaliser" = "institutionalizer" +"institutionalisers" = "institutionalizers" +"institutionalises" = "institutionalizes" +"institutionalising" = "institutionalizing" +"institutionalizable" = "institutionalizable" +"institutionalization" = "institutionalization" +"institutionalizations" = "institutionalizations" +"institutionalize" = "institutionalize" +"institutionalized" = "institutionalized" +"institutionalizer" = "institutionalizer" +"institutionalizers" = "institutionalizers" +"institutionalizes" = "institutionalizes" +"institutionalizing" = "institutionalizing" +"internalisable" = "internalizable" +"internalisation" = "internalization" +"internalisations" = "internalizations" +"internalise" = "internalize" +"internalised" = "internalized" +"internaliser" = "internalizer" +"internalisers" = "internalizers" +"internalises" = "internalizes" +"internalising" = "internalizing" +"internalizable" = "internalizable" +"internalization" = "internalization" +"internalizations" = "internalizations" +"internalize" = "internalize" +"internalized" = "internalized" +"internalizer" = "internalizer" +"internalizers" = "internalizers" +"internalizes" = "internalizes" +"internalizing" = "internalizing" +"internationalisable" = "internationalizable" +"internationalisation" = "internationalization" +"internationalisations" = "internationalizations" +"internationalise" = "internationalize" +"internationalised" = "internationalized" +"internationaliser" = "internationalizer" +"internationalisers" = "internationalizers" +"internationalises" = "internationalizes" +"internationalising" = "internationalizing" +"internationalizable" = "internationalizable" +"internationalization" = "internationalization" +"internationalizations" = "internationalizations" +"internationalize" = "internationalize" +"internationalized" = "internationalized" +"internationalizer" = "internationalizer" +"internationalizers" = "internationalizers" +"internationalizes" = "internationalizes" +"internationalizing" = "internationalizing" +"itemisable" = "itemizable" +"itemisation" = "itemization" +"itemisations" = "itemizations" +"itemise" = "itemize" +"itemised" = "itemized" +"itemiser" = "itemizer" +"itemisers" = "itemizers" +"itemises" = "itemizes" +"itemising" = "itemizing" +"itemizable" = "itemizable" +"itemization" = "itemization" +"itemizations" = "itemizations" +"itemize" = "itemize" +"itemized" = "itemized" +"itemizer" = "itemizer" +"itemizers" = "itemizers" +"itemizes" = "itemizes" +"itemizing" = "itemizing" +"jeopardisable" = "jeopardizable" +"jeopardisation" = "jeopardization" +"jeopardisations" = "jeopardizations" +"jeopardise" = "jeopardize" +"jeopardised" = "jeopardized" +"jeopardiser" = "jeopardizer" +"jeopardisers" = "jeopardizers" +"jeopardises" = "jeopardizes" +"jeopardising" = "jeopardizing" +"jeopardizable" = "jeopardizable" +"jeopardization" = "jeopardization" +"jeopardizations" = "jeopardizations" +"jeopardize" = "jeopardize" +"jeopardized" = "jeopardized" +"jeopardizer" = "jeopardizer" +"jeopardizers" = "jeopardizers" +"jeopardizes" = "jeopardizes" +"jeopardizing" = "jeopardizing" +"kernelisable" = "kernelizable" +"kernelisation" = "kernelization" +"kernelisations" = "kernelizations" +"kernelise" = "kernelize" +"kernelised" = "kernelized" +"kerneliser" = "kernelizer" +"kernelisers" = "kernelizers" +"kernelises" = "kernelizes" +"kernelising" = "kernelizing" +"kernelizable" = "kernelizable" +"kernelization" = "kernelization" +"kernelizations" = "kernelizations" +"kernelize" = "kernelize" +"kernelized" = "kernelized" +"kernelizer" = "kernelizer" +"kernelizers" = "kernelizers" +"kernelizes" = "kernelizes" +"kernelizing" = "kernelizing" +"legitimisable" = "legitimizable" +"legitimisation" = "legitimization" +"legitimisations" = "legitimizations" +"legitimise" = "legitimize" +"legitimised" = "legitimized" +"legitimiser" = "legitimizer" +"legitimisers" = "legitimizers" +"legitimises" = "legitimizes" +"legitimising" = "legitimizing" +"legitimizable" = "legitimizable" +"legitimization" = "legitimization" +"legitimizations" = "legitimizations" +"legitimize" = "legitimize" +"legitimized" = "legitimized" +"legitimizer" = "legitimizer" +"legitimizers" = "legitimizers" +"legitimizes" = "legitimizes" +"legitimizing" = "legitimizing" +"lemmatisable" = "lemmatizable" +"lemmatisation" = "lemmatization" +"lemmatisations" = "lemmatizations" +"lemmatise" = "lemmatize" +"lemmatised" = "lemmatized" +"lemmatiser" = "lemmatizer" +"lemmatisers" = "lemmatizers" +"lemmatises" = "lemmatizes" +"lemmatising" = "lemmatizing" +"lemmatizable" = "lemmatizable" +"lemmatization" = "lemmatization" +"lemmatizations" = "lemmatizations" +"lemmatize" = "lemmatize" +"lemmatized" = "lemmatized" +"lemmatizer" = "lemmatizer" +"lemmatizers" = "lemmatizers" +"lemmatizes" = "lemmatizes" +"lemmatizing" = "lemmatizing" +"linearisable" = "linearizable" +"linearisation" = "linearization" +"linearisations" = "linearizations" +"linearise" = "linearize" +"linearised" = "linearized" +"lineariser" = "linearizer" +"linearisers" = "linearizers" +"linearises" = "linearizes" +"linearising" = "linearizing" +"linearizable" = "linearizable" +"linearization" = "linearization" +"linearizations" = "linearizations" +"linearize" = "linearize" +"linearized" = "linearized" +"linearizer" = "linearizer" +"linearizers" = "linearizers" +"linearizes" = "linearizes" +"linearizing" = "linearizing" +"localisable" = "localizable" +"localisation" = "localization" +"localisations" = "localizations" +"localise" = "localize" +"localised" = "localized" +"localiser" = "localizer" +"localisers" = "localizers" +"localises" = "localizes" +"localising" = "localizing" +"localizable" = "localizable" +"localization" = "localization" +"localizations" = "localizations" +"localize" = "localize" +"localized" = "localized" +"localizer" = "localizer" +"localizers" = "localizers" +"localizes" = "localizes" +"localizing" = "localizing" +"materialisable" = "materializable" +"materialisation" = "materialization" +"materialisations" = "materializations" +"materialise" = "materialize" +"materialised" = "materialized" +"materialiser" = "materializer" +"materialisers" = "materializers" +"materialises" = "materializes" +"materialising" = "materializing" +"materializable" = "materializable" +"materialization" = "materialization" +"materializations" = "materializations" +"materialize" = "materialize" +"materialized" = "materialized" +"materializer" = "materializer" +"materializers" = "materializers" +"materializes" = "materializes" +"materializing" = "materializing" +"maximisable" = "maximizable" +"maximisation" = "maximization" +"maximisations" = "maximizations" +"maximise" = "maximize" +"maximised" = "maximized" +"maximiser" = "maximizer" +"maximisers" = "maximizers" +"maximises" = "maximizes" +"maximising" = "maximizing" +"maximizable" = "maximizable" +"maximization" = "maximization" +"maximizations" = "maximizations" +"maximize" = "maximize" +"maximized" = "maximized" +"maximizer" = "maximizer" +"maximizers" = "maximizers" +"maximizes" = "maximizes" +"maximizing" = "maximizing" +"mechanisable" = "mechanizable" +"mechanisation" = "mechanization" +"mechanisations" = "mechanizations" +"mechanise" = "mechanize" +"mechanised" = "mechanized" +"mechaniser" = "mechanizer" +"mechanisers" = "mechanizers" +"mechanises" = "mechanizes" +"mechanising" = "mechanizing" +"mechanizable" = "mechanizable" +"mechanization" = "mechanization" +"mechanizations" = "mechanizations" +"mechanize" = "mechanize" +"mechanized" = "mechanized" +"mechanizer" = "mechanizer" +"mechanizers" = "mechanizers" +"mechanizes" = "mechanizes" +"mechanizing" = "mechanizing" +"memoisable" = "memoizable" +"memoisation" = "memoization" +"memoisations" = "memoizations" +"memoise" = "memoize" +"memoised" = "memoized" +"memoiser" = "memoizer" +"memoisers" = "memoizers" +"memoises" = "memoizes" +"memoising" = "memoizing" +"memoizable" = "memoizable" +"memoization" = "memoization" +"memoizations" = "memoizations" +"memoize" = "memoize" +"memoized" = "memoized" +"memoizer" = "memoizer" +"memoizers" = "memoizers" +"memoizes" = "memoizes" +"memoizing" = "memoizing" +"memorisable" = "memorizable" +"memorisation" = "memorization" +"memorisations" = "memorizations" +"memorise" = "memorize" +"memorised" = "memorized" +"memoriser" = "memorizer" +"memorisers" = "memorizers" +"memorises" = "memorizes" +"memorising" = "memorizing" +"memorizable" = "memorizable" +"memorization" = "memorization" +"memorizations" = "memorizations" +"memorize" = "memorize" +"memorized" = "memorized" +"memorizer" = "memorizer" +"memorizers" = "memorizers" +"memorizes" = "memorizes" +"memorizing" = "memorizing" +"miniaturisable" = "miniaturizable" +"miniaturisation" = "miniaturization" +"miniaturisations" = "miniaturizations" +"miniaturise" = "miniaturize" +"miniaturised" = "miniaturized" +"miniaturiser" = "miniaturizer" +"miniaturisers" = "miniaturizers" +"miniaturises" = "miniaturizes" +"miniaturising" = "miniaturizing" +"miniaturizable" = "miniaturizable" +"miniaturization" = "miniaturization" +"miniaturizations" = "miniaturizations" +"miniaturize" = "miniaturize" +"miniaturized" = "miniaturized" +"miniaturizer" = "miniaturizer" +"miniaturizers" = "miniaturizers" +"miniaturizes" = "miniaturizes" +"miniaturizing" = "miniaturizing" +"minimisable" = "minimizable" +"minimisation" = "minimization" +"minimisations" = "minimizations" +"minimise" = "minimize" +"minimised" = "minimized" +"minimiser" = "minimizer" +"minimisers" = "minimizers" +"minimises" = "minimizes" +"minimising" = "minimizing" +"minimizable" = "minimizable" +"minimization" = "minimization" +"minimizations" = "minimizations" +"minimize" = "minimize" +"minimized" = "minimized" +"minimizer" = "minimizer" +"minimizers" = "minimizers" +"minimizes" = "minimizes" +"minimizing" = "minimizing" +"mobilisable" = "mobilizable" +"mobilisation" = "mobilization" +"mobilisations" = "mobilizations" +"mobilise" = "mobilize" +"mobilised" = "mobilized" +"mobiliser" = "mobilizer" +"mobilisers" = "mobilizers" +"mobilises" = "mobilizes" +"mobilising" = "mobilizing" +"mobilizable" = "mobilizable" +"mobilization" = "mobilization" +"mobilizations" = "mobilizations" +"mobilize" = "mobilize" +"mobilized" = "mobilized" +"mobilizer" = "mobilizer" +"mobilizers" = "mobilizers" +"mobilizes" = "mobilizes" +"mobilizing" = "mobilizing" +"modernisable" = "modernizable" +"modernisation" = "modernization" +"modernisations" = "modernizations" +"modernise" = "modernize" +"modernised" = "modernized" +"moderniser" = "modernizer" +"modernisers" = "modernizers" +"modernises" = "modernizes" +"modernising" = "modernizing" +"modernizable" = "modernizable" +"modernization" = "modernization" +"modernizations" = "modernizations" +"modernize" = "modernize" +"modernized" = "modernized" +"modernizer" = "modernizer" +"modernizers" = "modernizers" +"modernizes" = "modernizes" +"modernizing" = "modernizing" +"modularisable" = "modularizable" +"modularisation" = "modularization" +"modularisations" = "modularizations" +"modularise" = "modularize" +"modularised" = "modularized" +"modulariser" = "modularizer" +"modularisers" = "modularizers" +"modularises" = "modularizes" +"modularising" = "modularizing" +"modularizable" = "modularizable" +"modularization" = "modularization" +"modularizations" = "modularizations" +"modularize" = "modularize" +"modularized" = "modularized" +"modularizer" = "modularizer" +"modularizers" = "modularizers" +"modularizes" = "modularizes" +"modularizing" = "modularizing" +"monetisable" = "monetizable" +"monetisation" = "monetization" +"monetisations" = "monetizations" +"monetise" = "monetize" +"monetised" = "monetized" +"monetiser" = "monetizer" +"monetisers" = "monetizers" +"monetises" = "monetizes" +"monetising" = "monetizing" +"monetizable" = "monetizable" +"monetization" = "monetization" +"monetizations" = "monetizations" +"monetize" = "monetize" +"monetized" = "monetized" +"monetizer" = "monetizer" +"monetizers" = "monetizers" +"monetizes" = "monetizes" +"monetizing" = "monetizing" +"monomorphisable" = "monomorphizable" +"monomorphisation" = "monomorphization" +"monomorphisations" = "monomorphizations" +"monomorphise" = "monomorphize" +"monomorphised" = "monomorphized" +"monomorphiser" = "monomorphizer" +"monomorphisers" = "monomorphizers" +"monomorphises" = "monomorphizes" +"monomorphising" = "monomorphizing" +"monomorphizable" = "monomorphizable" +"monomorphization" = "monomorphization" +"monomorphizations" = "monomorphizations" +"monomorphize" = "monomorphize" +"monomorphized" = "monomorphized" +"monomorphizer" = "monomorphizer" +"monomorphizers" = "monomorphizers" +"monomorphizes" = "monomorphizes" +"monomorphizing" = "monomorphizing" +"monopolisable" = "monopolizable" +"monopolisation" = "monopolization" +"monopolisations" = "monopolizations" +"monopolise" = "monopolize" +"monopolised" = "monopolized" +"monopoliser" = "monopolizer" +"monopolisers" = "monopolizers" +"monopolises" = "monopolizes" +"monopolising" = "monopolizing" +"monopolizable" = "monopolizable" +"monopolization" = "monopolization" +"monopolizations" = "monopolizations" +"monopolize" = "monopolize" +"monopolized" = "monopolized" +"monopolizer" = "monopolizer" +"monopolizers" = "monopolizers" +"monopolizes" = "monopolizes" +"monopolizing" = "monopolizing" +"moralisable" = "moralizable" +"moralisation" = "moralization" +"moralisations" = "moralizations" +"moralise" = "moralize" +"moralised" = "moralized" +"moraliser" = "moralizer" +"moralisers" = "moralizers" +"moralises" = "moralizes" +"moralising" = "moralizing" +"moralizable" = "moralizable" +"moralization" = "moralization" +"moralizations" = "moralizations" +"moralize" = "moralize" +"moralized" = "moralized" +"moralizer" = "moralizer" +"moralizers" = "moralizers" +"moralizes" = "moralizes" +"moralizing" = "moralizing" +"neutralisable" = "neutralizable" +"neutralisation" = "neutralization" +"neutralisations" = "neutralizations" +"neutralise" = "neutralize" +"neutralised" = "neutralized" +"neutraliser" = "neutralizer" +"neutralisers" = "neutralizers" +"neutralises" = "neutralizes" +"neutralising" = "neutralizing" +"neutralizable" = "neutralizable" +"neutralization" = "neutralization" +"neutralizations" = "neutralizations" +"neutralize" = "neutralize" +"neutralized" = "neutralized" +"neutralizer" = "neutralizer" +"neutralizers" = "neutralizers" +"neutralizes" = "neutralizes" +"neutralizing" = "neutralizing" +"normalisable" = "normalizable" +"normalisation" = "normalization" +"normalisations" = "normalizations" +"normalise" = "normalize" +"normalised" = "normalized" +"normaliser" = "normalizer" +"normalisers" = "normalizers" +"normalises" = "normalizes" +"normalising" = "normalizing" +"normalizable" = "normalizable" +"normalization" = "normalization" +"normalizations" = "normalizations" +"normalize" = "normalize" +"normalized" = "normalized" +"normalizer" = "normalizer" +"normalizers" = "normalizers" +"normalizes" = "normalizes" +"normalizing" = "normalizing" +"notarisable" = "notarizable" +"notarisation" = "notarization" +"notarisations" = "notarizations" +"notarise" = "notarize" +"notarised" = "notarized" +"notariser" = "notarizer" +"notarisers" = "notarizers" +"notarises" = "notarizes" +"notarising" = "notarizing" +"notarizable" = "notarizable" +"notarization" = "notarization" +"notarizations" = "notarizations" +"notarize" = "notarize" +"notarized" = "notarized" +"notarizer" = "notarizer" +"notarizers" = "notarizers" +"notarizes" = "notarizes" +"notarizing" = "notarizing" +"operationalisable" = "operationalizable" +"operationalisation" = "operationalization" +"operationalisations" = "operationalizations" +"operationalise" = "operationalize" +"operationalised" = "operationalized" +"operationaliser" = "operationalizer" +"operationalisers" = "operationalizers" +"operationalises" = "operationalizes" +"operationalising" = "operationalizing" +"operationalizable" = "operationalizable" +"operationalization" = "operationalization" +"operationalizations" = "operationalizations" +"operationalize" = "operationalize" +"operationalized" = "operationalized" +"operationalizer" = "operationalizer" +"operationalizers" = "operationalizers" +"operationalizes" = "operationalizes" +"operationalizing" = "operationalizing" +"optimisable" = "optimizable" +"optimisation" = "optimization" +"optimisations" = "optimizations" +"optimise" = "optimize" +"optimised" = "optimized" +"optimiser" = "optimizer" +"optimisers" = "optimizers" +"optimises" = "optimizes" +"optimising" = "optimizing" +"optimizable" = "optimizable" +"optimization" = "optimization" +"optimizations" = "optimizations" +"optimize" = "optimize" +"optimized" = "optimized" +"optimizer" = "optimizer" +"optimizers" = "optimizers" +"optimizes" = "optimizes" +"optimizing" = "optimizing" +"ordinalisable" = "ordinalizable" +"ordinalisation" = "ordinalization" +"ordinalisations" = "ordinalizations" +"ordinalise" = "ordinalize" +"ordinalised" = "ordinalized" +"ordinaliser" = "ordinalizer" +"ordinalisers" = "ordinalizers" +"ordinalises" = "ordinalizes" +"ordinalising" = "ordinalizing" +"ordinalizable" = "ordinalizable" +"ordinalization" = "ordinalization" +"ordinalizations" = "ordinalizations" +"ordinalize" = "ordinalize" +"ordinalized" = "ordinalized" +"ordinalizer" = "ordinalizer" +"ordinalizers" = "ordinalizers" +"ordinalizes" = "ordinalizes" +"ordinalizing" = "ordinalizing" +"organisable" = "organizable" +"organisation" = "organization" +"organisations" = "organizations" +"organise" = "organize" +"organised" = "organized" +"organiser" = "organizer" +"organisers" = "organizers" +"organises" = "organizes" +"organising" = "organizing" +"organizable" = "organizable" +"organization" = "organization" +"organizations" = "organizations" +"organize" = "organize" +"organized" = "organized" +"organizer" = "organizer" +"organizers" = "organizers" +"organizes" = "organizes" +"organizing" = "organizing" +"oxendict" = "oxendict" +"palettisable" = "palettizable" +"palettisation" = "palettization" +"palettisations" = "palettizations" +"palettise" = "palettize" +"palettised" = "palettized" +"palettiser" = "palettizer" +"palettisers" = "palettizers" +"palettises" = "palettizes" +"palettising" = "palettizing" +"palettizable" = "palettizable" +"palettization" = "palettization" +"palettizations" = "palettizations" +"palettize" = "palettize" +"palettized" = "palettized" +"palettizer" = "palettizer" +"palettizers" = "palettizers" +"palettizes" = "palettizes" +"palettizing" = "palettizing" +"parallelisable" = "parallelizable" +"parallelisation" = "parallelization" +"parallelisations" = "parallelizations" +"parallelise" = "parallelize" +"parallelised" = "parallelized" +"paralleliser" = "parallelizer" +"parallelisers" = "parallelizers" +"parallelises" = "parallelizes" +"parallelising" = "parallelizing" +"parallelizable" = "parallelizable" +"parallelization" = "parallelization" +"parallelizations" = "parallelizations" +"parallelize" = "parallelize" +"parallelized" = "parallelized" +"parallelizer" = "parallelizer" +"parallelizers" = "parallelizers" +"parallelizes" = "parallelizes" +"parallelizing" = "parallelizing" +"parameterisable" = "parameterizable" +"parameterisation" = "parameterization" +"parameterisations" = "parameterizations" +"parameterise" = "parameterize" +"parameterised" = "parameterized" +"parameteriser" = "parameterizer" +"parameterisers" = "parameterizers" +"parameterises" = "parameterizes" +"parameterising" = "parameterizing" +"parameterizable" = "parameterizable" +"parameterization" = "parameterization" +"parameterizations" = "parameterizations" +"parameterize" = "parameterize" +"parameterized" = "parameterized" +"parameterizer" = "parameterizer" +"parameterizers" = "parameterizers" +"parameterizes" = "parameterizes" +"parameterizing" = "parameterizing" +"parametrisable" = "parametrizable" +"parametrisation" = "parametrization" +"parametrisations" = "parametrizations" +"parametrise" = "parametrize" +"parametrised" = "parametrized" +"parametriser" = "parametrizer" +"parametrisers" = "parametrizers" +"parametrises" = "parametrizes" +"parametrising" = "parametrizing" +"parametrizable" = "parametrizable" +"parametrization" = "parametrization" +"parametrizations" = "parametrizations" +"parametrize" = "parametrize" +"parametrized" = "parametrized" +"parametrizer" = "parametrizer" +"parametrizers" = "parametrizers" +"parametrizes" = "parametrizes" +"parametrizing" = "parametrizing" +"parenthesisable" = "parenthesizable" +"parenthesisation" = "parenthesization" +"parenthesisations" = "parenthesizations" +"parenthesise" = "parenthesize" +"parenthesised" = "parenthesized" +"parenthesiser" = "parenthesizer" +"parenthesisers" = "parenthesizers" +"parenthesises" = "parenthesizes" +"parenthesising" = "parenthesizing" +"parenthesizable" = "parenthesizable" +"parenthesization" = "parenthesization" +"parenthesizations" = "parenthesizations" +"parenthesize" = "parenthesize" +"parenthesized" = "parenthesized" +"parenthesizer" = "parenthesizer" +"parenthesizers" = "parenthesizers" +"parenthesizes" = "parenthesizes" +"parenthesizing" = "parenthesizing" +"penalisable" = "penalizable" +"penalisation" = "penalization" +"penalisations" = "penalizations" +"penalise" = "penalize" +"penalised" = "penalized" +"penaliser" = "penalizer" +"penalisers" = "penalizers" +"penalises" = "penalizes" +"penalising" = "penalizing" +"penalizable" = "penalizable" +"penalization" = "penalization" +"penalizations" = "penalizations" +"penalize" = "penalize" +"penalized" = "penalized" +"penalizer" = "penalizer" +"penalizers" = "penalizers" +"penalizes" = "penalizes" +"penalizing" = "penalizing" +"personalisable" = "personalizable" +"personalisation" = "personalization" +"personalisations" = "personalizations" +"personalise" = "personalize" +"personalised" = "personalized" +"personaliser" = "personalizer" +"personalisers" = "personalizers" +"personalises" = "personalizes" +"personalising" = "personalizing" +"personalizable" = "personalizable" +"personalization" = "personalization" +"personalizations" = "personalizations" +"personalize" = "personalize" +"personalized" = "personalized" +"personalizer" = "personalizer" +"personalizers" = "personalizers" +"personalizes" = "personalizes" +"personalizing" = "personalizing" +"pluralisable" = "pluralizable" +"pluralisation" = "pluralization" +"pluralisations" = "pluralizations" +"pluralise" = "pluralize" +"pluralised" = "pluralized" +"pluraliser" = "pluralizer" +"pluralisers" = "pluralizers" +"pluralises" = "pluralizes" +"pluralising" = "pluralizing" +"pluralizable" = "pluralizable" +"pluralization" = "pluralization" +"pluralizations" = "pluralizations" +"pluralize" = "pluralize" +"pluralized" = "pluralized" +"pluralizer" = "pluralizer" +"pluralizers" = "pluralizers" +"pluralizes" = "pluralizes" +"pluralizing" = "pluralizing" +"popularisable" = "popularizable" +"popularisation" = "popularization" +"popularisations" = "popularizations" +"popularise" = "popularize" +"popularised" = "popularized" +"populariser" = "popularizer" +"popularisers" = "popularizers" +"popularises" = "popularizes" +"popularising" = "popularizing" +"popularizable" = "popularizable" +"popularization" = "popularization" +"popularizations" = "popularizations" +"popularize" = "popularize" +"popularized" = "popularized" +"popularizer" = "popularizer" +"popularizers" = "popularizers" +"popularizes" = "popularizes" +"popularizing" = "popularizing" +"prioritisable" = "prioritizable" +"prioritisation" = "prioritization" +"prioritisations" = "prioritizations" +"prioritise" = "prioritize" +"prioritised" = "prioritized" +"prioritiser" = "prioritizer" +"prioritisers" = "prioritizers" +"prioritises" = "prioritizes" +"prioritising" = "prioritizing" +"prioritizable" = "prioritizable" +"prioritization" = "prioritization" +"prioritizations" = "prioritizations" +"prioritize" = "prioritize" +"prioritized" = "prioritized" +"prioritizer" = "prioritizer" +"prioritizers" = "prioritizers" +"prioritizes" = "prioritizes" +"prioritizing" = "prioritizing" +"privatisable" = "privatizable" +"privatisation" = "privatization" +"privatisations" = "privatizations" +"privatise" = "privatize" +"privatised" = "privatized" +"privatiser" = "privatizer" +"privatisers" = "privatizers" +"privatises" = "privatizes" +"privatising" = "privatizing" +"privatizable" = "privatizable" +"privatization" = "privatization" +"privatizations" = "privatizations" +"privatize" = "privatize" +"privatized" = "privatized" +"privatizer" = "privatizer" +"privatizers" = "privatizers" +"privatizes" = "privatizes" +"privatizing" = "privatizing" +"productisable" = "productizable" +"productisation" = "productization" +"productisations" = "productizations" +"productise" = "productize" +"productised" = "productized" +"productiser" = "productizer" +"productisers" = "productizers" +"productises" = "productizes" +"productising" = "productizing" +"productizable" = "productizable" +"productization" = "productization" +"productizations" = "productizations" +"productize" = "productize" +"productized" = "productized" +"productizer" = "productizer" +"productizers" = "productizers" +"productizes" = "productizes" +"productizing" = "productizing" +"publicisable" = "publicizable" +"publicisation" = "publicization" +"publicisations" = "publicizations" +"publicise" = "publicize" +"publicised" = "publicized" +"publiciser" = "publicizer" +"publicisers" = "publicizers" +"publicises" = "publicizes" +"publicising" = "publicizing" +"publicizable" = "publicizable" +"publicization" = "publicization" +"publicizations" = "publicizations" +"publicize" = "publicize" +"publicized" = "publicized" +"publicizer" = "publicizer" +"publicizers" = "publicizers" +"publicizes" = "publicizes" +"publicizing" = "publicizing" +"quantisable" = "quantizable" +"quantisation" = "quantization" +"quantisations" = "quantizations" +"quantise" = "quantize" +"quantised" = "quantized" +"quantiser" = "quantizer" +"quantisers" = "quantizers" +"quantises" = "quantizes" +"quantising" = "quantizing" +"quantizable" = "quantizable" +"quantization" = "quantization" +"quantizations" = "quantizations" +"quantize" = "quantize" +"quantized" = "quantized" +"quantizer" = "quantizer" +"quantizers" = "quantizers" +"quantizes" = "quantizes" +"quantizing" = "quantizing" +"randomisable" = "randomizable" +"randomisation" = "randomization" +"randomisations" = "randomizations" +"randomise" = "randomize" +"randomised" = "randomized" +"randomiser" = "randomizer" +"randomisers" = "randomizers" +"randomises" = "randomizes" +"randomising" = "randomizing" +"randomizable" = "randomizable" +"randomization" = "randomization" +"randomizations" = "randomizations" +"randomize" = "randomize" +"randomized" = "randomized" +"randomizer" = "randomizer" +"randomizers" = "randomizers" +"randomizes" = "randomizes" +"randomizing" = "randomizing" +"rasterisable" = "rasterizable" +"rasterisation" = "rasterization" +"rasterisations" = "rasterizations" +"rasterise" = "rasterize" +"rasterised" = "rasterized" +"rasteriser" = "rasterizer" +"rasterisers" = "rasterizers" +"rasterises" = "rasterizes" +"rasterising" = "rasterizing" +"rasterizable" = "rasterizable" +"rasterization" = "rasterization" +"rasterizations" = "rasterizations" +"rasterize" = "rasterize" +"rasterized" = "rasterized" +"rasterizer" = "rasterizer" +"rasterizers" = "rasterizers" +"rasterizes" = "rasterizes" +"rasterizing" = "rasterizing" +"rationalisable" = "rationalizable" +"rationalisation" = "rationalization" +"rationalisations" = "rationalizations" +"rationalise" = "rationalize" +"rationalised" = "rationalized" +"rationaliser" = "rationalizer" +"rationalisers" = "rationalizers" +"rationalises" = "rationalizes" +"rationalising" = "rationalizing" +"rationalizable" = "rationalizable" +"rationalization" = "rationalization" +"rationalizations" = "rationalizations" +"rationalize" = "rationalize" +"rationalized" = "rationalized" +"rationalizer" = "rationalizer" +"rationalizers" = "rationalizers" +"rationalizes" = "rationalizes" +"rationalizing" = "rationalizing" +"realisable" = "realizable" +"realisation" = "realization" +"realisations" = "realizations" +"realise" = "realize" +"realised" = "realized" +"realiser" = "realizer" +"realisers" = "realizers" +"realises" = "realizes" +"realising" = "realizing" +"realizable" = "realizable" +"realization" = "realization" +"realizations" = "realizations" +"realize" = "realize" +"realized" = "realized" +"realizer" = "realizer" +"realizers" = "realizers" +"realizes" = "realizes" +"realizing" = "realizing" +"recognisable" = "recognizable" +"recognisation" = "recognization" +"recognisations" = "recognizations" +"recognise" = "recognize" +"recognised" = "recognized" +"recogniser" = "recognizer" +"recognisers" = "recognizers" +"recognises" = "recognizes" +"recognising" = "recognizing" +"recognizable" = "recognizable" +"recognization" = "recognization" +"recognizations" = "recognizations" +"recognize" = "recognize" +"recognized" = "recognized" +"recognizer" = "recognizer" +"recognizers" = "recognizers" +"recognizes" = "recognizes" +"recognizing" = "recognizing" +"regularisable" = "regularizable" +"regularisation" = "regularization" +"regularisations" = "regularizations" +"regularise" = "regularize" +"regularised" = "regularized" +"regulariser" = "regularizer" +"regularisers" = "regularizers" +"regularises" = "regularizes" +"regularising" = "regularizing" +"regularizable" = "regularizable" +"regularization" = "regularization" +"regularizations" = "regularizations" +"regularize" = "regularize" +"regularized" = "regularized" +"regularizer" = "regularizer" +"regularizers" = "regularizers" +"regularizes" = "regularizes" +"regularizing" = "regularizing" +"reinitialisable" = "reinitializable" +"reinitialisation" = "reinitialization" +"reinitialisations" = "reinitializations" +"reinitialise" = "reinitialize" +"reinitialised" = "reinitialized" +"reinitialiser" = "reinitializer" +"reinitialisers" = "reinitializers" +"reinitialises" = "reinitializes" +"reinitialising" = "reinitializing" +"reinitializable" = "reinitializable" +"reinitialization" = "reinitialization" +"reinitializations" = "reinitializations" +"reinitialize" = "reinitialize" +"reinitialized" = "reinitialized" +"reinitializer" = "reinitializer" +"reinitializers" = "reinitializers" +"reinitializes" = "reinitializes" +"reinitializing" = "reinitializing" +"reorganisable" = "reorganizable" +"reorganisation" = "reorganization" +"reorganisations" = "reorganizations" +"reorganise" = "reorganize" +"reorganised" = "reorganized" +"reorganiser" = "reorganizer" +"reorganisers" = "reorganizers" +"reorganises" = "reorganizes" +"reorganising" = "reorganizing" +"reorganizable" = "reorganizable" +"reorganization" = "reorganization" +"reorganizations" = "reorganizations" +"reorganize" = "reorganize" +"reorganized" = "reorganized" +"reorganizer" = "reorganizer" +"reorganizers" = "reorganizers" +"reorganizes" = "reorganizes" +"reorganizing" = "reorganizing" +"reserialisable" = "reserializable" +"reserialisation" = "reserialization" +"reserialisations" = "reserializations" +"reserialise" = "reserialize" +"reserialised" = "reserialized" +"reserialiser" = "reserializer" +"reserialisers" = "reserializers" +"reserialises" = "reserializes" +"reserialising" = "reserializing" +"reserializable" = "reserializable" +"reserialization" = "reserialization" +"reserializations" = "reserializations" +"reserialize" = "reserialize" +"reserialized" = "reserialized" +"reserializer" = "reserializer" +"reserializers" = "reserializers" +"reserializes" = "reserializes" +"reserializing" = "reserializing" +"resynchronisable" = "resynchronizable" +"resynchronisation" = "resynchronization" +"resynchronisations" = "resynchronizations" +"resynchronise" = "resynchronize" +"resynchronised" = "resynchronized" +"resynchroniser" = "resynchronizer" +"resynchronisers" = "resynchronizers" +"resynchronises" = "resynchronizes" +"resynchronising" = "resynchronizing" +"resynchronizable" = "resynchronizable" +"resynchronization" = "resynchronization" +"resynchronizations" = "resynchronizations" +"resynchronize" = "resynchronize" +"resynchronized" = "resynchronized" +"resynchronizer" = "resynchronizer" +"resynchronizers" = "resynchronizers" +"resynchronizes" = "resynchronizes" +"resynchronizing" = "resynchronizing" +"retokenisable" = "retokenizable" +"retokenisation" = "retokenization" +"retokenisations" = "retokenizations" +"retokenise" = "retokenize" +"retokenised" = "retokenized" +"retokeniser" = "retokenizer" +"retokenisers" = "retokenizers" +"retokenises" = "retokenizes" +"retokenising" = "retokenizing" +"retokenizable" = "retokenizable" +"retokenization" = "retokenization" +"retokenizations" = "retokenizations" +"retokenize" = "retokenize" +"retokenized" = "retokenized" +"retokenizer" = "retokenizer" +"retokenizers" = "retokenizers" +"retokenizes" = "retokenizes" +"retokenizing" = "retokenizing" +"romanticisable" = "romanticizable" +"romanticisation" = "romanticization" +"romanticisations" = "romanticizations" +"romanticise" = "romanticize" +"romanticised" = "romanticized" +"romanticiser" = "romanticizer" +"romanticisers" = "romanticizers" +"romanticises" = "romanticizes" +"romanticising" = "romanticizing" +"romanticizable" = "romanticizable" +"romanticization" = "romanticization" +"romanticizations" = "romanticizations" +"romanticize" = "romanticize" +"romanticized" = "romanticized" +"romanticizer" = "romanticizer" +"romanticizers" = "romanticizers" +"romanticizes" = "romanticizes" +"romanticizing" = "romanticizing" +"sanitisable" = "sanitizable" +"sanitisation" = "sanitization" +"sanitisations" = "sanitizations" +"sanitise" = "sanitize" +"sanitised" = "sanitized" +"sanitiser" = "sanitizer" +"sanitisers" = "sanitizers" +"sanitises" = "sanitizes" +"sanitising" = "sanitizing" +"sanitizable" = "sanitizable" +"sanitization" = "sanitization" +"sanitizations" = "sanitizations" +"sanitize" = "sanitize" +"sanitized" = "sanitized" +"sanitizer" = "sanitizer" +"sanitizers" = "sanitizers" +"sanitizes" = "sanitizes" +"sanitizing" = "sanitizing" +"scrutinisable" = "scrutinizable" +"scrutinisation" = "scrutinization" +"scrutinisations" = "scrutinizations" +"scrutinise" = "scrutinize" +"scrutinised" = "scrutinized" +"scrutiniser" = "scrutinizer" +"scrutinisers" = "scrutinizers" +"scrutinises" = "scrutinizes" +"scrutinising" = "scrutinizing" +"scrutinizable" = "scrutinizable" +"scrutinization" = "scrutinization" +"scrutinizations" = "scrutinizations" +"scrutinize" = "scrutinize" +"scrutinized" = "scrutinized" +"scrutinizer" = "scrutinizer" +"scrutinizers" = "scrutinizers" +"scrutinizes" = "scrutinizes" +"scrutinizing" = "scrutinizing" +"serialisable" = "serializable" +"serialisation" = "serialization" +"serialisations" = "serializations" +"serialise" = "serialize" +"serialised" = "serialized" +"serialiser" = "serializer" +"serialisers" = "serializers" +"serialises" = "serializes" +"serialising" = "serializing" +"serializable" = "serializable" +"serialization" = "serialization" +"serializations" = "serializations" +"serialize" = "serialize" +"serialized" = "serialized" +"serializer" = "serializer" +"serializers" = "serializers" +"serializes" = "serializes" +"serializing" = "serializing" +"sexualisable" = "sexualizable" +"sexualisation" = "sexualization" +"sexualisations" = "sexualizations" +"sexualise" = "sexualize" +"sexualised" = "sexualized" +"sexualiser" = "sexualizer" +"sexualisers" = "sexualizers" +"sexualises" = "sexualizes" +"sexualising" = "sexualizing" +"sexualizable" = "sexualizable" +"sexualization" = "sexualization" +"sexualizations" = "sexualizations" +"sexualize" = "sexualize" +"sexualized" = "sexualized" +"sexualizer" = "sexualizer" +"sexualizers" = "sexualizers" +"sexualizes" = "sexualizes" +"sexualizing" = "sexualizing" +"singularisable" = "singularizable" +"singularisation" = "singularization" +"singularisations" = "singularizations" +"singularise" = "singularize" +"singularised" = "singularized" +"singulariser" = "singularizer" +"singularisers" = "singularizers" +"singularises" = "singularizes" +"singularising" = "singularizing" +"singularizable" = "singularizable" +"singularization" = "singularization" +"singularizations" = "singularizations" +"singularize" = "singularize" +"singularized" = "singularized" +"singularizer" = "singularizer" +"singularizers" = "singularizers" +"singularizes" = "singularizes" +"singularizing" = "singularizing" +"socialisable" = "socializable" +"socialisation" = "socialization" +"socialisations" = "socializations" +"socialise" = "socialize" +"socialised" = "socialized" +"socialiser" = "socializer" +"socialisers" = "socializers" +"socialises" = "socializes" +"socialising" = "socializing" +"socializable" = "socializable" +"socialization" = "socialization" +"socializations" = "socializations" +"socialize" = "socialize" +"socialized" = "socialized" +"socializer" = "socializer" +"socializers" = "socializers" +"socializes" = "socializes" +"socializing" = "socializing" +"specialisable" = "specializable" +"specialisation" = "specialization" +"specialisations" = "specializations" +"specialise" = "specialize" +"specialised" = "specialized" +"specialiser" = "specializer" +"specialisers" = "specializers" +"specialises" = "specializes" +"specialising" = "specializing" +"specializable" = "specializable" +"specialization" = "specialization" +"specializations" = "specializations" +"specialize" = "specialize" +"specialized" = "specialized" +"specializer" = "specializer" +"specializers" = "specializers" +"specializes" = "specializes" +"specializing" = "specializing" +"stabilisable" = "stabilizable" +"stabilisation" = "stabilization" +"stabilisations" = "stabilizations" +"stabilise" = "stabilize" +"stabilised" = "stabilized" +"stabiliser" = "stabilizer" +"stabilisers" = "stabilizers" +"stabilises" = "stabilizes" +"stabilising" = "stabilizing" +"stabilizable" = "stabilizable" +"stabilization" = "stabilization" +"stabilizations" = "stabilizations" +"stabilize" = "stabilize" +"stabilized" = "stabilized" +"stabilizer" = "stabilizer" +"stabilizers" = "stabilizers" +"stabilizes" = "stabilizes" +"stabilizing" = "stabilizing" +"standardisable" = "standardizable" +"standardisation" = "standardization" +"standardisations" = "standardizations" +"standardise" = "standardize" +"standardised" = "standardized" +"standardiser" = "standardizer" +"standardisers" = "standardizers" +"standardises" = "standardizes" +"standardising" = "standardizing" +"standardizable" = "standardizable" +"standardization" = "standardization" +"standardizations" = "standardizations" +"standardize" = "standardize" +"standardized" = "standardized" +"standardizer" = "standardizer" +"standardizers" = "standardizers" +"standardizes" = "standardizes" +"standardizing" = "standardizing" +"stylisable" = "stylizable" +"stylisation" = "stylization" +"stylisations" = "stylizations" +"stylise" = "stylize" +"stylised" = "stylized" +"styliser" = "stylizer" +"stylisers" = "stylizers" +"stylises" = "stylizes" +"stylising" = "stylizing" +"stylizable" = "stylizable" +"stylization" = "stylization" +"stylizations" = "stylizations" +"stylize" = "stylize" +"stylized" = "stylized" +"stylizer" = "stylizer" +"stylizers" = "stylizers" +"stylizes" = "stylizes" +"stylizing" = "stylizing" +"subsidisable" = "subsidizable" +"subsidisation" = "subsidization" +"subsidisations" = "subsidizations" +"subsidise" = "subsidize" +"subsidised" = "subsidized" +"subsidiser" = "subsidizer" +"subsidisers" = "subsidizers" +"subsidises" = "subsidizes" +"subsidising" = "subsidizing" +"subsidizable" = "subsidizable" +"subsidization" = "subsidization" +"subsidizations" = "subsidizations" +"subsidize" = "subsidize" +"subsidized" = "subsidized" +"subsidizer" = "subsidizer" +"subsidizers" = "subsidizers" +"subsidizes" = "subsidizes" +"subsidizing" = "subsidizing" +"summarisable" = "summarizable" +"summarisation" = "summarization" +"summarisations" = "summarizations" +"summarise" = "summarize" +"summarised" = "summarized" +"summariser" = "summarizer" +"summarisers" = "summarizers" +"summarises" = "summarizes" +"summarising" = "summarizing" +"summarizable" = "summarizable" +"summarization" = "summarization" +"summarizations" = "summarizations" +"summarize" = "summarize" +"summarized" = "summarized" +"summarizer" = "summarizer" +"summarizers" = "summarizers" +"summarizes" = "summarizes" +"summarizing" = "summarizing" +"symbolisable" = "symbolizable" +"symbolisation" = "symbolization" +"symbolisations" = "symbolizations" +"symbolise" = "symbolize" +"symbolised" = "symbolized" +"symboliser" = "symbolizer" +"symbolisers" = "symbolizers" +"symbolises" = "symbolizes" +"symbolising" = "symbolizing" +"symbolizable" = "symbolizable" +"symbolization" = "symbolization" +"symbolizations" = "symbolizations" +"symbolize" = "symbolize" +"symbolized" = "symbolized" +"symbolizer" = "symbolizer" +"symbolizers" = "symbolizers" +"symbolizes" = "symbolizes" +"symbolizing" = "symbolizing" +"synchronisable" = "synchronizable" +"synchronisation" = "synchronization" +"synchronisations" = "synchronizations" +"synchronise" = "synchronize" +"synchronised" = "synchronized" +"synchroniser" = "synchronizer" +"synchronisers" = "synchronizers" +"synchronises" = "synchronizes" +"synchronising" = "synchronizing" +"synchronizable" = "synchronizable" +"synchronization" = "synchronization" +"synchronizations" = "synchronizations" +"synchronize" = "synchronize" +"synchronized" = "synchronized" +"synchronizer" = "synchronizer" +"synchronizers" = "synchronizers" +"synchronizes" = "synchronizes" +"synchronizing" = "synchronizing" +"synthesisable" = "synthesizable" +"synthesisation" = "synthesization" +"synthesisations" = "synthesizations" +"synthesise" = "synthesize" +"synthesised" = "synthesized" +"synthesiser" = "synthesizer" +"synthesisers" = "synthesizers" +"synthesises" = "synthesizes" +"synthesising" = "synthesizing" +"synthesizable" = "synthesizable" +"synthesization" = "synthesization" +"synthesizations" = "synthesizations" +"synthesize" = "synthesize" +"synthesized" = "synthesized" +"synthesizer" = "synthesizer" +"synthesizers" = "synthesizers" +"synthesizes" = "synthesizes" +"synthesizing" = "synthesizing" +"systematisable" = "systematizable" +"systematisation" = "systematization" +"systematisations" = "systematizations" +"systematise" = "systematize" +"systematised" = "systematized" +"systematiser" = "systematizer" +"systematisers" = "systematizers" +"systematises" = "systematizes" +"systematising" = "systematizing" +"systematizable" = "systematizable" +"systematization" = "systematization" +"systematizations" = "systematizations" +"systematize" = "systematize" +"systematized" = "systematized" +"systematizer" = "systematizer" +"systematizers" = "systematizers" +"systematizes" = "systematizes" +"systematizing" = "systematizing" +"systemisable" = "systemizable" +"systemisation" = "systemization" +"systemisations" = "systemizations" +"systemise" = "systemize" +"systemised" = "systemized" +"systemiser" = "systemizer" +"systemisers" = "systemizers" +"systemises" = "systemizes" +"systemising" = "systemizing" +"systemizable" = "systemizable" +"systemization" = "systemization" +"systemizations" = "systemizations" +"systemize" = "systemize" +"systemized" = "systemized" +"systemizer" = "systemizer" +"systemizers" = "systemizers" +"systemizes" = "systemizes" +"systemizing" = "systemizing" +"templatisable" = "templatizable" +"templatisation" = "templatization" +"templatisations" = "templatizations" +"templatise" = "templatize" +"templatised" = "templatized" +"templatiser" = "templatizer" +"templatisers" = "templatizers" +"templatises" = "templatizes" +"templatising" = "templatizing" +"templatizable" = "templatizable" +"templatization" = "templatization" +"templatizations" = "templatizations" +"templatize" = "templatize" +"templatized" = "templatized" +"templatizer" = "templatizer" +"templatizers" = "templatizers" +"templatizes" = "templatizes" +"templatizing" = "templatizing" +"terminalisable" = "terminalizable" +"terminalisation" = "terminalization" +"terminalisations" = "terminalizations" +"terminalise" = "terminalize" +"terminalised" = "terminalized" +"terminaliser" = "terminalizer" +"terminalisers" = "terminalizers" +"terminalises" = "terminalizes" +"terminalising" = "terminalizing" +"terminalizable" = "terminalizable" +"terminalization" = "terminalization" +"terminalizations" = "terminalizations" +"terminalize" = "terminalize" +"terminalized" = "terminalized" +"terminalizer" = "terminalizer" +"terminalizers" = "terminalizers" +"terminalizes" = "terminalizes" +"terminalizing" = "terminalizing" +"theorisable" = "theorizable" +"theorisation" = "theorization" +"theorisations" = "theorizations" +"theorise" = "theorize" +"theorised" = "theorized" +"theoriser" = "theorizer" +"theorisers" = "theorizers" +"theorises" = "theorizes" +"theorising" = "theorizing" +"theorizable" = "theorizable" +"theorization" = "theorization" +"theorizations" = "theorizations" +"theorize" = "theorize" +"theorized" = "theorized" +"theorizer" = "theorizer" +"theorizers" = "theorizers" +"theorizes" = "theorizes" +"theorizing" = "theorizing" +"tokenisable" = "tokenizable" +"tokenisation" = "tokenization" +"tokenisations" = "tokenizations" +"tokenise" = "tokenize" +"tokenised" = "tokenized" +"tokeniser" = "tokenizer" +"tokenisers" = "tokenizers" +"tokenises" = "tokenizes" +"tokenising" = "tokenizing" +"tokenizable" = "tokenizable" +"tokenization" = "tokenization" +"tokenizations" = "tokenizations" +"tokenize" = "tokenize" +"tokenized" = "tokenized" +"tokenizer" = "tokenizer" +"tokenizers" = "tokenizers" +"tokenizes" = "tokenizes" +"tokenizing" = "tokenizing" +"trivialisable" = "trivializable" +"trivialisation" = "trivialization" +"trivialisations" = "trivializations" +"trivialise" = "trivialize" +"trivialised" = "trivialized" +"trivialiser" = "trivializer" +"trivialisers" = "trivializers" +"trivialises" = "trivializes" +"trivialising" = "trivializing" +"trivializable" = "trivializable" +"trivialization" = "trivialization" +"trivializations" = "trivializations" +"trivialize" = "trivialize" +"trivialized" = "trivialized" +"trivializer" = "trivializer" +"trivializers" = "trivializers" +"trivializes" = "trivializes" +"trivializing" = "trivializing" +"unauthorisable" = "unauthorizable" +"unauthorisation" = "unauthorization" +"unauthorisations" = "unauthorizations" +"unauthorise" = "unauthorize" +"unauthorised" = "unauthorized" +"unauthoriser" = "unauthorizer" +"unauthorisers" = "unauthorizers" +"unauthorises" = "unauthorizes" +"unauthorising" = "unauthorizing" +"unauthorizable" = "unauthorizable" +"unauthorization" = "unauthorization" +"unauthorizations" = "unauthorizations" +"unauthorize" = "unauthorize" +"unauthorized" = "unauthorized" +"unauthorizer" = "unauthorizer" +"unauthorizers" = "unauthorizers" +"unauthorizes" = "unauthorizes" +"unauthorizing" = "unauthorizing" +"uncategorisable" = "uncategorizable" +"uncategorisation" = "uncategorization" +"uncategorisations" = "uncategorizations" +"uncategorise" = "uncategorize" +"uncategorised" = "uncategorized" +"uncategoriser" = "uncategorizer" +"uncategorisers" = "uncategorizers" +"uncategorises" = "uncategorizes" +"uncategorising" = "uncategorizing" +"uncategorizable" = "uncategorizable" +"uncategorization" = "uncategorization" +"uncategorizations" = "uncategorizations" +"uncategorize" = "uncategorize" +"uncategorized" = "uncategorized" +"uncategorizer" = "uncategorizer" +"uncategorizers" = "uncategorizers" +"uncategorizes" = "uncategorizes" +"uncategorizing" = "uncategorizing" +"uninitialisable" = "uninitializable" +"uninitialisation" = "uninitialization" +"uninitialisations" = "uninitializations" +"uninitialise" = "uninitialize" +"uninitialised" = "uninitialized" +"uninitialiser" = "uninitializer" +"uninitialisers" = "uninitializers" +"uninitialises" = "uninitializes" +"uninitialising" = "uninitializing" +"uninitializable" = "uninitializable" +"uninitialization" = "uninitialization" +"uninitializations" = "uninitializations" +"uninitialize" = "uninitialize" +"uninitialized" = "uninitialized" +"uninitializer" = "uninitializer" +"uninitializers" = "uninitializers" +"uninitializes" = "uninitializes" +"uninitializing" = "uninitializing" +"unlocalisable" = "unlocalizable" +"unlocalisation" = "unlocalization" +"unlocalisations" = "unlocalizations" +"unlocalise" = "unlocalize" +"unlocalised" = "unlocalized" +"unlocaliser" = "unlocalizer" +"unlocalisers" = "unlocalizers" +"unlocalises" = "unlocalizes" +"unlocalising" = "unlocalizing" +"unlocalizable" = "unlocalizable" +"unlocalization" = "unlocalization" +"unlocalizations" = "unlocalizations" +"unlocalize" = "unlocalize" +"unlocalized" = "unlocalized" +"unlocalizer" = "unlocalizer" +"unlocalizers" = "unlocalizers" +"unlocalizes" = "unlocalizes" +"unlocalizing" = "unlocalizing" +"unoptimisable" = "unoptimizable" +"unoptimisation" = "unoptimization" +"unoptimisations" = "unoptimizations" +"unoptimise" = "unoptimize" +"unoptimised" = "unoptimized" +"unoptimiser" = "unoptimizer" +"unoptimisers" = "unoptimizers" +"unoptimises" = "unoptimizes" +"unoptimising" = "unoptimizing" +"unoptimizable" = "unoptimizable" +"unoptimization" = "unoptimization" +"unoptimizations" = "unoptimizations" +"unoptimize" = "unoptimize" +"unoptimized" = "unoptimized" +"unoptimizer" = "unoptimizer" +"unoptimizers" = "unoptimizers" +"unoptimizes" = "unoptimizes" +"unoptimizing" = "unoptimizing" +"unparameterisable" = "unparameterizable" +"unparameterisation" = "unparameterization" +"unparameterisations" = "unparameterizations" +"unparameterise" = "unparameterize" +"unparameterised" = "unparameterized" +"unparameteriser" = "unparameterizer" +"unparameterisers" = "unparameterizers" +"unparameterises" = "unparameterizes" +"unparameterising" = "unparameterizing" +"unparameterizable" = "unparameterizable" +"unparameterization" = "unparameterization" +"unparameterizations" = "unparameterizations" +"unparameterize" = "unparameterize" +"unparameterized" = "unparameterized" +"unparameterizer" = "unparameterizer" +"unparameterizers" = "unparameterizers" +"unparameterizes" = "unparameterizes" +"unparameterizing" = "unparameterizing" +"unrecognisable" = "unrecognizable" +"unrecognisation" = "unrecognization" +"unrecognisations" = "unrecognizations" +"unrecognise" = "unrecognize" +"unrecognised" = "unrecognized" +"unrecogniser" = "unrecognizer" +"unrecognisers" = "unrecognizers" +"unrecognises" = "unrecognizes" +"unrecognising" = "unrecognizing" +"unrecognizable" = "unrecognizable" +"unrecognization" = "unrecognization" +"unrecognizations" = "unrecognizations" +"unrecognize" = "unrecognize" +"unrecognized" = "unrecognized" +"unrecognizer" = "unrecognizer" +"unrecognizers" = "unrecognizers" +"unrecognizes" = "unrecognizes" +"unrecognizing" = "unrecognizing" +"unsynchronisable" = "unsynchronizable" +"unsynchronisation" = "unsynchronization" +"unsynchronisations" = "unsynchronizations" +"unsynchronise" = "unsynchronize" +"unsynchronised" = "unsynchronized" +"unsynchroniser" = "unsynchronizer" +"unsynchronisers" = "unsynchronizers" +"unsynchronises" = "unsynchronizes" +"unsynchronising" = "unsynchronizing" +"unsynchronizable" = "unsynchronizable" +"unsynchronization" = "unsynchronization" +"unsynchronizations" = "unsynchronizations" +"unsynchronize" = "unsynchronize" +"unsynchronized" = "unsynchronized" +"unsynchronizer" = "unsynchronizer" +"unsynchronizers" = "unsynchronizers" +"unsynchronizes" = "unsynchronizes" +"unsynchronizing" = "unsynchronizing" +"utilisable" = "utilizable" +"utilisation" = "utilization" +"utilisations" = "utilizations" +"utilise" = "utilize" +"utilised" = "utilized" +"utiliser" = "utilizer" +"utilisers" = "utilizers" +"utilises" = "utilizes" +"utilising" = "utilizing" +"utilizable" = "utilizable" +"utilization" = "utilization" +"utilizations" = "utilizations" +"utilize" = "utilize" +"utilized" = "utilized" +"utilizer" = "utilizer" +"utilizers" = "utilizers" +"utilizes" = "utilizes" +"utilizing" = "utilizing" +"vectorisable" = "vectorizable" +"vectorisation" = "vectorization" +"vectorisations" = "vectorizations" +"vectorise" = "vectorize" +"vectorised" = "vectorized" +"vectoriser" = "vectorizer" +"vectorisers" = "vectorizers" +"vectorises" = "vectorizes" +"vectorising" = "vectorizing" +"vectorizable" = "vectorizable" +"vectorization" = "vectorization" +"vectorizations" = "vectorizations" +"vectorize" = "vectorize" +"vectorized" = "vectorized" +"vectorizer" = "vectorizer" +"vectorizers" = "vectorizers" +"vectorizes" = "vectorizes" +"vectorizing" = "vectorizing" +"virtualisable" = "virtualizable" +"virtualisation" = "virtualization" +"virtualisations" = "virtualizations" +"virtualise" = "virtualize" +"virtualised" = "virtualized" +"virtualiser" = "virtualizer" +"virtualisers" = "virtualizers" +"virtualises" = "virtualizes" +"virtualising" = "virtualizing" +"virtualizable" = "virtualizable" +"virtualization" = "virtualization" +"virtualizations" = "virtualizations" +"virtualize" = "virtualize" +"virtualized" = "virtualized" +"virtualizer" = "virtualizer" +"virtualizers" = "virtualizers" +"virtualizes" = "virtualizes" +"virtualizing" = "virtualizing" +"visualisable" = "visualizable" +"visualisation" = "visualization" +"visualisations" = "visualizations" +"visualise" = "visualize" +"visualised" = "visualized" +"visualiser" = "visualizer" +"visualisers" = "visualizers" +"visualises" = "visualizes" +"visualising" = "visualizing" +"visualizable" = "visualizable" +"visualization" = "visualization" +"visualizations" = "visualizations" +"visualize" = "visualize" +"visualized" = "visualized" +"visualizer" = "visualizer" +"visualizers" = "visualizers" +"visualizes" = "visualizes" +"visualizing" = "visualizing" +"weaponisable" = "weaponizable" +"weaponisation" = "weaponization" +"weaponisations" = "weaponizations" +"weaponise" = "weaponize" +"weaponised" = "weaponized" +"weaponiser" = "weaponizer" +"weaponisers" = "weaponizers" +"weaponises" = "weaponizes" +"weaponising" = "weaponizing" +"weaponizable" = "weaponizable" +"weaponization" = "weaponization" +"weaponizations" = "weaponizations" +"weaponize" = "weaponize" +"weaponized" = "weaponized" +"weaponizer" = "weaponizer" +"weaponizers" = "weaponizers" +"weaponizes" = "weaponizes" +"weaponizing" = "weaponizing" +"yse" = "yse" +"zeroisable" = "zeroizable" +"zeroisation" = "zeroization" +"zeroisations" = "zeroizations" +"zeroise" = "zeroize" +"zeroised" = "zeroized" +"zeroiser" = "zeroizer" +"zeroisers" = "zeroizers" +"zeroises" = "zeroizes" +"zeroising" = "zeroizing" +"zeroizable" = "zeroizable" +"zeroization" = "zeroization" +"zeroizations" = "zeroizations" +"zeroize" = "zeroize" +"zeroized" = "zeroized" +"zeroizer" = "zeroizer" +"zeroizers" = "zeroizers" +"zeroizes" = "zeroizes" +"zeroizing" = "zeroizing"