From 47275d938bd3f7c76f389842488542d9aa3d59ac Mon Sep 17 00:00:00 2001 From: Yaroslav Date: Wed, 27 Apr 2022 15:04:56 +0400 Subject: [PATCH] Initial implementation (#1) * UK modulus checker implementation * Review * Review * Review * Review --- .github/CODEOWNERS | 1 + .github/dependabot.yml | 8 + .github/workflows/ci.yml | 66 + .gitignore | 3 + Makefile | 45 + requirements-dev.txt | 9 + setup.cfg | 31 + setup.py | 42 + tests/__init__.py | 0 tests/data/__init__.py | 0 tests/data/subs.txt | 21 + tests/data/weights.txt | 1116 +++++++++++++++++ tests/test_sort_code_substitution_table.py | 25 + tests/test_uk_modulus_checker.py | 78 ++ tests/test_weight_table.py | 31 + uk_modulus_check/__init__.py | 51 + uk_modulus_check/base_table.py | 7 + uk_modulus_check/py.typed | 1 + .../sort_code_substitution_table.py | 42 + uk_modulus_check/uk_modulus_checker.py | 264 ++++ uk_modulus_check/weight_table.py | 107 ++ 21 files changed, 1948 insertions(+) create mode 100644 .github/CODEOWNERS create mode 100644 .github/dependabot.yml create mode 100644 .github/workflows/ci.yml create mode 100644 Makefile create mode 100644 requirements-dev.txt create mode 100644 setup.cfg create mode 100644 setup.py create mode 100644 tests/__init__.py create mode 100644 tests/data/__init__.py create mode 100644 tests/data/subs.txt create mode 100644 tests/data/weights.txt create mode 100644 tests/test_sort_code_substitution_table.py create mode 100644 tests/test_uk_modulus_checker.py create mode 100644 tests/test_weight_table.py create mode 100644 uk_modulus_check/__init__.py create mode 100644 uk_modulus_check/base_table.py create mode 100644 uk_modulus_check/py.typed create mode 100644 uk_modulus_check/sort_code_substitution_table.py create mode 100644 uk_modulus_check/uk_modulus_checker.py create mode 100644 uk_modulus_check/weight_table.py diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 0000000..56f71a6 --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1 @@ +* @anna-money/banking-backend diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..2f8a8a1 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,8 @@ +version: 2 +updates: +- package-ecosystem: pip + directory: "/" + schedule: + interval: daily + time: "00:00" + open-pull-requests-limit: 10 diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..baf8ba4 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,66 @@ +name: CI + +on: + push: + branches: + - master + tags: [ 'v*' ] + pull_request: + branches: + - master + + +jobs: + test: + name: Test + runs-on: ubuntu-latest + timeout-minutes: 15 + + strategy: + matrix: + python-version: ["3.10"] + + steps: + - uses: actions/checkout@v2 + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v2 + with: + python-version: ${{ matrix.python-version }} + - name: Install dependencies + run: | + make deps + - name: Lint + run: | + make lint + - name: Tests + run: | + make test + + deploy: + name: Deploy + runs-on: ubuntu-latest + needs: test + # Run only on pushing a tag + if: github.event_name == 'push' && contains(github.ref, 'refs/tags/') + steps: + - name: Checkout + uses: actions/checkout@v2 + - name: Setup Python 3.10 + uses: actions/setup-python@v2 + with: + python-version: "3.10" + - name: Install dependencies + run: + python -m pip install -U pip wheel twine + - name: Make dists + run: + python setup.py sdist bdist_wheel + - name: Check dists + run: + twine check dist/* + - name: PyPI upload + env: + TWINE_USERNAME: __token__ + TWINE_PASSWORD: ${{ secrets.PYPI_TOKEN }} + run: | + twine upload dist/* diff --git a/.gitignore b/.gitignore index b6e4761..980ddd1 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,6 @@ +# ANNA +.idea + # Byte-compiled / optimized / DLL files __pycache__/ *.py[cod] diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..e88af47 --- /dev/null +++ b/Makefile @@ -0,0 +1,45 @@ +.EXPORT_ALL_VARIABLES: +DIRECTORY = uk_modulus_check + +all: deps lint test + +deps: + @python3 -m pip install --upgrade pip && pip3 install -r requirements-dev.txt + +lint: black isort flake8 mypy + +mypy: + mypy $(DIRECTORY) + mypy tests + +flake8: + flake8 $(DIRECTORY) + flake8 tests + flake8 setup.py + +black: +ifeq ($(MODE), ci) + black $(DIRECTORY) --check + black tests --check + black setup.py --check +else + black $(DIRECTORY) + black tests + black setup.py +endif + +isort: +ifeq ($(MODE), ci) + isort $(DIRECTORY) -c + isort tests -c +else + isort $(DIRECTORY) + isort tests + isort setup.py +endif + +test: + @python3 -m pytest -vv --rootdir tests . + +pyenv: + echo uk-modulus-check > .python-version && pyenv install -s 3.10.3 && pyenv virtualenv -f 3.10.3 uk-modulus-check diff --git a/requirements-dev.txt b/requirements-dev.txt new file mode 100644 index 0000000..d5bc5cf --- /dev/null +++ b/requirements-dev.txt @@ -0,0 +1,9 @@ +pytest==7.1.1 +pytest-runner==6.0.0 +isort==5.10.1 +flake8==4.0.1 +mypy==0.942 +black==22.3.0 +setuptools==62.1.0 +wheel==0.37.1 +twine==4.0.0 diff --git a/setup.cfg b/setup.cfg new file mode 100644 index 0000000..9c0aa23 --- /dev/null +++ b/setup.cfg @@ -0,0 +1,31 @@ +[flake8] +exclude = ,.git,__pycache__,old,build,dist,env/ # noqa +max-line-length = 120 +ignore = C901,C812,E203,E225 +extend-ignore = W503 +no-accept-encodings = True +enable-extensions=G + +[mypy] +python_version = 3.10 +ignore_missing_imports = True +disallow_incomplete_defs = True +no_implicit_optional = True +disallow_untyped_calls = True +warn_redundant_casts = True +warn_unused_ignores = True +disallow_untyped_defs = True +check_untyped_defs = True + +[isort] +combine_as_imports = true +default_section = THIRDPARTY +include_trailing_comma = true +use_parentheses = true +line_length = 120 +multi_line_output = 3 + + +[tool:pytest] +norecursedirs = .git .venv +python_files = tests.py test_*.py *_tests.py diff --git a/setup.py b/setup.py new file mode 100644 index 0000000..06333f4 --- /dev/null +++ b/setup.py @@ -0,0 +1,42 @@ +import re +from pathlib import Path + +from setuptools import setup + + +def read(*parts): + return Path(__file__).resolve().parent.joinpath(*parts).read_text().strip() + + +def read_version(): + regexp = re.compile(r"^__version__\W*=\W*\"([\d.abrc]+)\"") + for line in read("uk_modulus_check", "__init__.py").splitlines(): + match = regexp.match(line) + if match is not None: + return match.group(1) + else: + raise RuntimeError("Cannot find version in uk_modulus_check/__init__.py") + + +with open("README.md", "r") as fh: + long_description = fh.read() + + +setup( + name="uk-modulus-check", + version=read_version(), + description="A thing to check UK bank sort code and IBAN", + long_description=long_description, + long_description_content_type="text/markdown", + platforms=["macOS", "POSIX", "Windows"], + author="ANNA", + python_requires=">=3.10", + project_urls={}, + author_email="yury.pliner@gmail.com", + license="MIT", + packages=["uk_modulus_check"], + package_dir={"uk_modulus_check": "./uk_modulus_check"}, + package_data={"uk_modulus_check": ["py.typed"]}, + include_package_data=True, + exclude_package_data={"data": ["data/*.txt"]}, +) diff --git a/tests/__init__.py b/tests/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/data/__init__.py b/tests/data/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/data/subs.txt b/tests/data/subs.txt new file mode 100644 index 0000000..063a6e0 --- /dev/null +++ b/tests/data/subs.txt @@ -0,0 +1,21 @@ +938173 938017 +938289 938068 +938297 938076 +938600 938611 +938602 938343 +938604 938603 +938608 938408 +938609 938424 +938613 938017 +938616 938068 +938618 938657 +938620 938343 +938622 938130 +938628 938181 +938643 938246 +938647 938611 +938648 938246 +938649 938394 +938651 938335 +938653 938424 +938654 938621 \ No newline at end of file diff --git a/tests/data/weights.txt b/tests/data/weights.txt new file mode 100644 index 0000000..81df4e4 --- /dev/null +++ b/tests/data/weights.txt @@ -0,0 +1,1116 @@ +010004 016715 MOD11 0 0 0 0 0 0 8 7 6 5 4 3 2 1 +040003 040003 DBLAL 2 1 2 1 2 1 8 7 6 5 4 3 2 1 +040004 040004 DBLAL 0 0 0 0 0 0 8 7 6 5 4 3 2 1 +040005 040006 DBLAL 2 1 2 1 2 1 8 7 6 5 4 3 2 1 +040010 040014 MOD11 0 0 0 0 0 0 0 7 6 5 4 3 2 1 +040010 040014 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 1 +040015 040015 MOD11 0 0 0 0 0 0 0 7 6 5 4 3 2 1 +040020 040023 MOD11 0 2 0 0 9 1 2 8 4 3 7 5 6 1 +040024 040039 MOD11 0 0 0 0 0 0 0 7 6 5 4 3 2 1 +040024 040039 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 1 +040040 040059 MOD11 0 2 0 0 9 1 2 8 4 3 7 5 6 1 +040072 040073 MOD11 0 0 0 0 0 0 8 7 6 5 4 3 2 1 +040074 040075 MOD11 0 0 0 0 0 0 8 7 6 5 4 3 2 1 +040082 040082 MOD10 2 1 2 1 2 1 0 64 32 16 8 4 2 1 +040083 040085 MOD11 0 0 0 0 0 0 8 7 6 5 4 3 2 1 +040086 040086 MOD11 0 0 0 0 0 0 8 7 6 5 4 3 2 1 +040330 040334 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 1 +040330 040334 MOD11 0 0 0 0 0 0 0 7 6 5 4 3 2 1 +040340 040340 MOD11 0 0 0 0 0 0 8 7 6 5 4 3 2 1 +040390 040393 MOD11 0 0 0 0 0 0 8 7 6 5 4 3 2 1 +040400 041311 DBLAL 1 3 4 3 9 3 1 7 5 5 4 5 2 4 +041312 041312 MOD11 0 0 0 0 0 0 8 7 6 5 4 3 2 1 +041313 041316 DBLAL 1 3 4 3 9 3 1 7 5 5 4 5 2 4 +041317 041319 MOD11 0 0 0 0 0 0 8 7 6 5 4 3 2 1 +041320 041399 DBLAL 1 3 4 3 9 3 1 7 5 5 4 5 2 4 +041400 041449 MOD11 0 2 0 0 9 1 2 8 4 3 7 5 6 1 +041900 042099 MOD10 1 3 4 3 9 3 1 7 5 5 4 5 2 4 +042100 042899 MOD11 1 3 4 3 9 3 1 7 5 5 4 5 2 4 +042900 042909 MOD11 0 0 0 0 0 0 8 7 6 5 4 3 2 1 +044001 044001 MOD10 0 2 1 2 0 7 1 1 0 3 8 1 9 1 +050000 050020 MOD11 0 0 0 0 0 0 2 1 7 5 8 2 4 1 +050022 058999 MOD11 0 0 0 0 0 0 2 1 7 5 8 2 4 1 +070030 070030 MOD11 0 0 7 6 5 8 9 4 5 6 7 8 9 -1 +070040 070040 MOD11 0 0 7 6 5 8 9 4 5 6 7 8 9 -1 +070055 070055 MOD11 0 0 7 6 5 8 9 4 5 6 7 8 9 -1 +070066 070066 MOD11 0 0 7 6 5 8 9 4 5 6 7 8 9 -1 +070116 070116 MOD11 0 0 7 6 5 8 9 4 5 6 7 8 9 -1 12 +070116 070116 MOD10 0 3 2 4 5 8 9 4 5 6 7 8 9 -1 13 +070246 070246 MOD11 0 0 7 6 5 8 9 4 5 6 7 8 9 -1 +070436 070436 MOD11 0 0 7 6 5 8 9 4 5 6 7 8 9 -1 +070806 070806 MOD11 0 0 7 6 5 8 9 4 5 6 7 8 9 -1 +070976 070976 MOD11 0 0 7 6 5 8 9 4 5 6 7 8 9 -1 +071040 071040 MOD11 0 0 7 6 5 8 9 4 5 6 7 8 9 -1 +071096 071096 MOD11 0 0 7 6 5 8 9 4 5 6 7 8 9 -1 +071120 071120 MOD11 0 0 7 6 5 8 9 4 5 6 7 8 9 -1 +071226 071226 MOD11 0 0 7 6 5 8 9 4 5 6 7 8 9 -1 +071306 071306 MOD11 0 0 7 6 5 8 9 4 5 6 7 8 9 -1 +071310 071310 MOD11 0 0 7 6 5 8 9 4 5 6 7 8 9 -1 +071350 071350 MOD11 0 0 7 6 5 8 9 4 5 6 7 8 9 -1 +071490 071490 MOD11 0 0 7 6 5 8 9 4 5 6 7 8 9 -1 +071520 071520 MOD11 0 0 7 6 5 8 9 4 5 6 7 8 9 -1 +071660 071660 MOD11 0 0 7 6 5 8 9 4 5 6 7 8 9 -1 +071986 071986 MOD11 0 0 7 6 5 8 9 4 5 6 7 8 9 -1 +074456 074456 MOD11 0 0 7 6 5 8 9 4 5 6 7 8 9 -1 12 +074456 074456 MOD10 0 3 2 4 5 8 9 4 5 6 7 8 9 -1 13 +080211 080211 MOD10 0 0 0 0 0 0 7 1 3 7 1 3 7 1 +080228 080228 MOD10 0 0 0 0 0 0 7 1 3 7 1 3 7 1 +086001 086001 MOD10 0 0 0 0 0 0 7 1 3 7 1 3 7 1 +086020 086020 MOD10 0 0 0 0 0 0 7 1 3 7 1 3 7 1 +086086 086086 MOD11 0 0 0 0 0 8 9 4 5 6 7 8 9 -1 +086090 086090 MOD10 0 0 3 7 1 3 7 1 3 7 1 3 7 1 8 +086119 086119 MOD11 0 0 0 0 0 0 2 7 6 5 4 3 2 1 12 +086119 086119 MOD10 0 0 0 0 0 0 2 3 1 0 5 2 6 1 13 +089000 089999 MOD10 0 0 0 0 0 0 7 1 3 7 1 3 7 1 +090013 090013 MOD10 0 0 3 7 1 3 7 1 3 7 1 3 7 1 +090105 090105 MOD10 0 0 3 7 1 3 7 1 3 7 1 3 7 1 +090118 090118 MOD11 0 0 6 5 4 3 2 7 6 5 4 3 2 1 +090126 090129 MOD10 0 0 3 7 1 3 7 1 3 7 1 3 7 1 +090131 090136 MOD11 0 0 0 0 0 9 8 7 6 5 4 3 2 1 +090150 090156 MOD11 0 0 0 0 0 9 8 7 6 5 4 3 2 1 +090180 090185 MOD10 0 0 3 7 1 3 7 1 3 7 1 3 7 1 +090190 090196 MOD10 0 0 3 7 1 3 7 1 3 7 1 3 7 1 +090204 090204 MOD10 0 0 3 7 1 3 7 1 3 7 1 3 7 1 +090222 090222 MOD10 0 0 3 7 1 3 7 1 3 7 1 3 7 1 +090356 090356 MOD11 0 0 0 0 0 9 8 7 6 5 4 3 2 1 +090500 090599 MOD10 0 0 3 7 1 3 7 1 3 7 1 3 7 1 +090704 090704 MOD10 0 0 3 7 1 3 7 1 3 7 1 3 7 1 +090705 090705 MOD10 0 0 3 7 1 3 7 1 3 7 1 3 7 1 +090710 090710 MOD10 0 0 3 7 1 3 7 1 3 7 1 3 7 1 +090715 090715 MOD10 0 0 3 7 1 3 7 1 3 7 1 3 7 1 +090720 090726 MOD11 0 0 0 0 0 9 8 7 6 5 4 3 2 1 +090736 090739 MOD10 0 0 3 7 1 3 7 1 3 7 1 3 7 1 +090790 090790 MOD10 0 0 3 7 1 3 7 1 3 7 1 3 7 1 +091600 091600 MOD10 0 0 0 0 0 1 7 1 3 7 1 3 7 1 +091601 091601 MOD10 0 0 3 7 1 3 7 1 3 7 1 3 7 1 +091740 091743 MOD10 0 0 0 0 0 1 7 1 3 7 1 3 7 1 +091800 091809 MOD10 0 0 0 0 0 1 7 1 3 7 1 3 7 1 +091811 091865 MOD10 0 0 0 0 0 1 7 1 3 7 1 3 7 1 +100000 101099 MOD11 0 0 0 0 0 0 8 7 6 5 4 3 2 1 +101101 101498 MOD11 0 0 0 0 0 0 8 7 6 5 4 3 2 1 +101500 101999 MOD11 0 0 0 0 0 0 8 7 6 5 4 3 2 1 +102400 107999 MOD11 0 0 0 0 0 0 8 7 6 5 4 3 2 1 +108000 108079 MOD11 0 0 0 0 0 3 2 7 6 5 4 3 2 1 +108080 108099 MOD11 0 0 0 0 4 3 2 7 6 5 4 3 2 1 +108100 109999 MOD11 0 0 0 0 0 0 8 7 6 5 4 3 2 1 +110000 119280 DBLAL 0 0 2 1 2 1 2 1 2 1 2 1 2 1 1 +119282 119283 DBLAL 0 0 2 1 2 1 2 1 2 1 2 1 2 1 1 +119285 119999 DBLAL 0 0 2 1 2 1 2 1 2 1 2 1 2 1 1 +120000 120961 MOD11 0 0 1 8 2 6 3 7 9 5 8 4 2 1 +120963 122009 MOD11 0 0 1 8 2 6 3 7 9 5 8 4 2 1 +122011 122101 MOD11 0 0 1 8 2 6 3 7 9 5 8 4 2 1 +122103 122129 MOD11 0 0 1 8 2 6 3 7 9 5 8 4 2 1 +122131 122135 MOD11 0 0 1 8 2 6 3 7 9 5 8 4 2 1 +122213 122299 MOD11 0 0 1 8 2 6 3 7 9 5 8 4 2 1 +122400 122999 MOD11 0 0 1 8 2 6 3 7 9 5 8 4 2 1 +124000 124999 MOD11 0 0 1 8 2 6 3 7 9 5 8 4 2 1 +133000 133999 MOD11 0 0 0 0 0 10 7 8 4 6 3 5 2 1 +134012 134020 MOD11 0 0 0 7 5 9 8 4 6 3 5 2 0 0 4 +134121 134121 MOD11 0 0 0 1 0 0 8 4 6 3 5 2 0 0 4 +150000 158000 MOD11 4 3 0 0 0 0 2 7 6 5 4 3 2 1 +159800 159800 MOD11 0 0 0 0 0 0 7 6 5 4 3 2 1 0 +159900 159900 MOD11 0 0 0 0 0 0 7 6 5 4 3 2 1 0 +159910 159910 MOD11 0 0 0 0 0 0 7 6 5 4 3 2 1 0 +160000 161027 MOD11 0 0 6 5 4 3 2 7 6 5 4 3 2 1 +161029 161029 MOD11 0 0 0 0 0 0 2 7 6 5 4 3 2 1 +161030 161041 MOD11 0 0 6 5 4 3 2 7 6 5 4 3 2 1 +161050 161050 MOD11 0 0 6 5 4 3 2 7 6 5 4 3 2 1 +161055 161055 MOD11 0 0 6 5 4 3 2 7 6 5 4 3 2 1 +161060 161060 MOD11 0 0 6 5 4 3 2 7 6 5 4 3 2 1 +161065 161065 MOD11 0 0 6 5 4 3 2 7 6 5 4 3 2 1 +161070 161070 MOD11 0 0 6 5 4 3 2 7 6 5 4 3 2 1 +161075 161075 MOD11 0 0 6 5 4 3 2 7 6 5 4 3 2 1 +161080 161080 MOD11 0 0 6 5 4 3 2 7 6 5 4 3 2 1 +161085 161085 MOD11 0 0 6 5 4 3 2 7 6 5 4 3 2 1 +161090 161090 MOD11 0 0 6 5 4 3 2 7 6 5 4 3 2 1 +161100 162028 MOD11 0 0 6 5 4 3 2 7 6 5 4 3 2 1 +162030 164300 MOD11 0 0 6 5 4 3 2 7 6 5 4 3 2 1 +165901 166001 MOD11 0 0 6 5 4 3 2 7 6 5 4 3 2 1 +166050 167600 MOD11 0 0 6 5 4 3 2 7 6 5 4 3 2 1 +168600 168600 MOD11 0 0 0 0 0 0 2 7 6 5 4 3 2 1 +180002 180002 MOD11 0 0 0 0 0 0 8 7 6 5 4 3 2 1 14 +180005 180005 MOD11 0 0 0 0 0 0 8 7 6 5 4 3 2 1 14 +180009 180009 MOD11 0 0 0 0 0 0 8 7 6 5 4 3 2 1 14 +180036 180036 MOD11 0 0 0 0 0 0 8 7 6 5 4 3 2 1 14 +180038 180038 MOD11 0 0 0 0 0 0 8 7 6 5 4 3 2 1 14 +180091 180092 MOD11 0 0 0 0 0 0 8 7 6 5 4 3 2 1 14 +180104 180104 MOD11 0 0 0 0 0 0 8 7 6 5 4 3 2 1 14 +180109 180110 MOD11 0 0 0 0 0 0 8 7 6 5 4 3 2 1 14 +180156 180156 MOD11 0 0 0 0 0 0 8 7 6 5 4 3 2 1 14 +185001 185001 MOD11 0 0 0 0 0 0 8 7 6 5 4 3 2 1 14 +185003 185003 MOD11 0 0 0 0 0 0 0 7 6 5 4 3 2 1 +185004 185004 MOD11 0 0 0 0 0 0 2 7 6 5 4 3 2 1 +185005 185009 MOD11 0 0 0 0 0 0 0 7 6 5 4 3 2 1 +185011 185025 MOD11 0 0 0 0 0 0 0 7 6 5 4 3 2 1 +185027 185099 MOD11 0 0 0 0 0 0 0 7 6 5 4 3 2 1 +200000 200002 MOD11 0 0 0 0 0 0 0 7 6 5 4 3 2 1 6 +200000 200002 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 1 6 +200004 200004 MOD11 0 0 0 0 0 0 0 7 6 5 4 3 2 1 6 +200004 200004 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 1 6 +200026 200026 MOD11 0 0 0 0 0 0 0 7 6 5 4 3 2 1 6 +200026 200026 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 1 6 +200051 200077 MOD11 0 0 0 0 0 0 0 7 6 5 4 3 2 1 6 +200051 200077 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 1 6 +200079 200097 MOD11 0 0 0 0 0 0 0 7 6 5 4 3 2 1 6 +200079 200097 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 1 6 +200099 200156 MOD11 0 0 0 0 0 0 0 7 6 5 4 3 2 1 6 +200099 200156 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 1 6 +200158 200387 MOD11 0 0 0 0 0 0 0 7 6 5 4 3 2 1 6 +200158 200387 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 1 6 +200403 200405 MOD11 0 0 0 0 0 0 0 7 6 5 4 3 2 1 6 +200403 200405 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 1 6 +200407 200407 MOD11 0 0 0 0 0 0 0 7 6 5 4 3 2 1 6 +200407 200407 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 1 6 +200411 200412 MOD11 0 0 0 0 0 0 0 7 6 5 4 3 2 1 6 +200411 200412 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 1 6 +200414 200423 MOD11 0 0 0 0 0 0 0 7 6 5 4 3 2 1 6 +200414 200423 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 1 6 +200425 200899 MOD11 0 0 0 0 0 0 0 7 6 5 4 3 2 1 6 +200425 200899 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 1 6 +200901 201159 MOD11 0 0 0 0 0 0 0 7 6 5 4 3 2 1 6 +200901 201159 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 1 6 +201161 201177 MOD11 0 0 0 0 0 0 0 7 6 5 4 3 2 1 6 +201161 201177 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 1 6 +201179 201351 MOD11 0 0 0 0 0 0 0 7 6 5 4 3 2 1 6 +201179 201351 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 1 6 +201353 202698 MOD11 0 0 0 0 0 0 0 7 6 5 4 3 2 1 6 +201353 202698 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 1 6 +202700 203239 MOD11 0 0 0 0 0 0 0 7 6 5 4 3 2 1 6 +202700 203239 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 1 6 +203241 203255 MOD11 0 0 0 0 0 0 0 7 6 5 4 3 2 1 6 +203241 203255 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 1 6 +203259 203519 MOD11 0 0 0 0 0 0 0 7 6 5 4 3 2 1 6 +203259 203519 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 1 6 +203521 204476 MOD11 0 0 0 0 0 0 0 7 6 5 4 3 2 1 6 +203521 204476 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 1 6 +204478 205475 MOD11 0 0 0 0 0 0 0 7 6 5 4 3 2 1 6 +204478 205475 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 1 6 +205477 205954 MOD11 0 0 0 0 0 0 0 7 6 5 4 3 2 1 6 +205477 205954 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 1 6 +205956 206124 MOD11 0 0 0 0 0 0 0 7 6 5 4 3 2 1 6 +205956 206124 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 1 6 +206126 206157 MOD11 0 0 0 0 0 0 0 7 6 5 4 3 2 1 6 +206126 206157 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 1 6 +206159 206390 MOD11 0 0 0 0 0 0 0 7 6 5 4 3 2 1 6 +206159 206390 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 1 6 +206392 206799 MOD11 0 0 0 0 0 0 0 7 6 5 4 3 2 1 6 +206392 206799 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 1 6 +206802 206874 MOD11 0 0 0 0 0 0 0 7 6 5 4 3 2 1 6 +206802 206874 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 1 6 +206876 207170 MOD11 0 0 0 0 0 0 0 7 6 5 4 3 2 1 6 +206876 207170 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 1 6 +207173 208092 MOD11 0 0 0 0 0 0 0 7 6 5 4 3 2 1 6 +207173 208092 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 1 6 +208094 208721 MOD11 0 0 0 0 0 0 0 7 6 5 4 3 2 1 6 +208094 208721 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 1 6 +208723 209034 MOD11 0 0 0 0 0 0 0 7 6 5 4 3 2 1 6 +208723 209034 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 1 6 +209036 209128 MOD11 0 0 0 0 0 0 0 7 6 5 4 3 2 1 6 +209036 209128 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 1 6 +209130 209999 MOD11 0 0 0 0 0 0 0 7 6 5 4 3 2 1 6 +209130 209999 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 1 6 +230088 230088 MOD10 2 1 2 1 2 1 2 7 4 5 6 3 8 1 +230120 230120 MOD11 0 0 0 0 0 7 128 64 32 16 8 4 2 1 +230121 230121 MOD11 8 7 1 5 8 6 1 7 6 5 5 4 9 1 +230338 230338 MOD11 0 0 0 0 0 0 0 7 6 5 4 3 2 1 +230338 230338 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 1 +230363 230363 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 1 +230364 230364 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 1 +230365 230365 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 1 +230366 230366 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 1 +230367 230367 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 1 +230505 230505 MOD11 9 8 7 6 5 4 9 8 7 6 5 4 3 2 +230580 230580 MOD11 0 0 0 0 0 0 2 7 6 5 4 3 2 1 12 +230580 230580 MOD11 0 0 0 0 0 0 5 7 6 5 4 3 2 1 13 +230614 230614 MOD11 0 0 0 0 0 0 0 7 6 5 4 3 2 1 +230614 230614 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 1 +230709 230709 MOD11 0 0 0 0 0 0 0 7 6 5 4 3 2 1 +230709 230709 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 1 +230872 230872 MOD11 0 0 0 0 0 0 0 7 6 5 4 3 2 1 +230872 230872 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 1 +230933 230933 MOD11 0 0 0 0 0 0 0 7 6 5 4 3 2 1 +230933 230933 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 1 +231018 231018 MOD11 0 0 0 0 0 0 0 7 6 5 4 3 2 1 +231018 231018 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 1 +231213 231213 MOD11 0 0 0 0 0 0 0 7 6 5 4 3 2 1 +231213 231213 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 1 +231228 231228 MOD11 0 0 0 0 0 0 0 7 6 5 4 3 2 1 +231228 231228 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 1 +231354 231354 MOD11 0 0 0 0 0 0 0 7 6 5 4 3 2 1 +231354 231354 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 1 +231469 231469 MOD11 0 0 0 0 0 0 0 7 6 5 4 3 2 1 +231469 231469 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 1 +231470 231470 MOD11 0 0 20 18 1 14 0 0 0 0 0 0 0 0 +231536 231536 MOD11 0 0 0 0 0 0 0 7 6 5 4 3 2 1 +231536 231536 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 1 +231558 231558 MOD11 0 0 0 0 0 0 0 7 6 5 4 3 2 1 +231558 231558 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 1 +231618 231618 MOD11 0 0 0 0 0 0 0 7 6 5 4 3 2 1 +231618 231618 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 1 +231679 231679 MOD11 0 0 0 0 0 0 0 7 6 5 4 3 2 1 +231679 231679 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 1 +231843 231843 MOD11 0 0 0 0 0 0 0 7 6 5 4 3 2 1 +231843 231843 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 1 +231985 231985 MOD11 0 0 0 0 0 0 0 7 6 5 4 3 2 1 +231985 231985 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 1 +232130 232130 MOD11 0 0 0 0 0 0 0 7 6 5 4 3 2 1 +232130 232130 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 1 +232279 232279 MOD11 0 0 0 0 0 0 0 7 6 5 4 3 2 1 +232279 232279 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 1 +232283 232283 MOD11 0 0 0 0 0 0 0 7 6 5 4 3 2 1 +232283 232283 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 1 +232290 232290 MOD11 0 0 0 0 0 0 0 7 6 5 4 3 2 1 +232445 232445 MOD11 0 0 0 0 0 0 0 7 6 5 4 3 2 1 +232445 232445 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 1 +232507 232507 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 1 +232571 232571 MOD11 0 0 0 0 0 0 0 7 6 5 4 3 2 1 +232571 232571 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 1 +232636 232636 MOD11 0 0 0 0 0 0 0 7 6 5 4 3 2 1 +232636 232636 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 1 +232704 232704 MOD11 0 0 0 0 0 0 0 7 6 5 4 3 2 1 +232704 232704 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 1 +232725 232725 MOD11 0 0 0 0 0 0 0 7 6 5 4 3 2 1 +232725 232725 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 1 +232813 232813 MOD11 0 0 0 0 0 0 0 7 6 5 4 3 2 1 +232813 232813 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 1 +232939 232939 MOD11 0 0 0 0 0 0 0 7 6 5 4 3 2 1 +232939 232939 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 1 +233080 233080 MOD11 0 0 0 0 0 0 0 7 6 5 4 3 2 1 +233080 233080 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 1 +233135 233135 MOD11 0 0 0 0 0 0 0 7 6 5 4 3 2 1 +233135 233135 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 1 +233142 233142 MOD10 2 1 2 1 2 1 30 36 24 20 16 12 8 4 +233171 233171 MOD11 0 0 0 0 0 0 0 7 6 5 4 3 2 1 +233171 233171 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 1 +233188 233188 MOD11 0 0 0 0 0 0 0 7 6 5 4 3 2 1 +233188 233188 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 1 +233231 233231 MOD11 0 0 0 0 0 0 0 7 6 5 4 3 2 1 +233231 233231 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 1 +233344 233344 MOD11 0 0 0 0 0 0 0 7 6 5 4 3 2 1 +233344 233344 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 1 +233438 233438 MOD11 0 0 0 0 0 0 0 7 6 5 4 3 2 1 +233438 233438 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 1 +233456 233456 MOD10 2 1 2 1 2 1 0 64 32 16 8 4 2 1 +233483 233483 MOD11 0 0 0 0 0 0 2 7 6 5 4 3 2 1 +233556 233556 MOD11 0 0 0 0 0 0 0 7 6 5 4 3 2 1 +233556 233556 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 1 +233658 233658 MOD11 0 0 0 0 0 0 0 7 6 5 4 3 2 1 +233658 233658 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 1 +233693 233693 MOD11 0 0 0 0 0 0 0 7 6 5 4 3 2 1 +233693 233693 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 1 +233752 233752 MOD11 0 0 0 0 0 0 0 7 6 5 4 3 2 1 +233752 233752 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 1 +234081 234081 MOD11 0 0 0 0 0 0 0 7 6 5 4 3 2 1 +234081 234081 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 1 +234193 234193 MOD11 0 0 0 0 0 0 0 7 6 5 4 3 2 1 +234193 234193 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 1 +234252 234252 MOD11 0 0 0 0 0 0 0 7 6 5 4 3 2 1 +234252 234252 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 1 +234321 234321 MOD11 0 0 0 0 0 0 0 7 6 5 4 3 2 1 +234321 234321 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 1 +234377 234377 MOD11 0 0 0 0 0 0 0 7 6 5 4 3 2 1 +234377 234377 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 1 +234570 234570 MOD11 0 0 0 0 0 0 0 7 6 5 4 3 2 1 +234570 234570 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 1 +234666 234666 MOD11 0 0 0 0 0 0 0 7 6 5 4 3 2 1 +234666 234666 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 1 +234779 234779 MOD11 0 0 0 0 0 0 0 7 6 5 4 3 2 1 +234779 234779 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 1 +234828 234828 MOD11 0 0 0 0 0 0 0 7 6 5 4 3 2 1 +234828 234828 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 1 +234985 234985 MOD11 0 0 0 0 0 0 0 7 6 5 4 3 2 1 +234985 234985 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 1 +235054 235054 MOD11 0 0 0 0 0 0 0 7 6 5 4 3 2 1 +235054 235054 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 1 +235164 235164 MOD11 0 0 0 0 0 0 0 7 6 5 4 3 2 1 +235164 235164 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 1 +235262 235262 MOD11 0 0 0 0 0 0 0 7 6 5 4 3 2 1 +235262 235262 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 1 +235323 235323 MOD11 0 0 0 0 0 0 0 7 6 5 4 3 2 1 +235323 235323 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 1 +235451 235451 MOD11 0 0 0 0 0 0 2 7 6 5 4 3 2 1 +235459 235459 MOD11 0 0 0 0 0 0 0 7 6 5 4 3 2 1 +235459 235459 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 1 +235519 235519 MOD11 0 0 0 0 0 0 0 7 6 5 4 3 2 1 +235519 235519 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 1 +235676 235676 MOD11 0 0 0 0 0 0 0 7 6 5 4 3 2 1 +235676 235676 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 1 +235711 235711 MOD11 0 0 0 0 0 0 0 7 6 5 4 3 2 1 +235711 235711 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 1 +235756 235756 MOD11 0 0 0 0 0 0 0 7 6 5 4 3 2 1 +235756 235756 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 1 +235889 235889 MOD10 2 1 2 1 2 1 0 64 32 16 8 4 2 1 +235945 235945 MOD11 0 0 0 0 0 0 0 7 6 5 4 3 2 1 +235945 235945 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 1 +236006 236006 MOD11 0 0 0 0 0 0 0 7 6 5 4 3 2 1 +236006 236006 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 1 +236119 236119 MOD11 0 0 0 0 0 0 0 7 6 5 4 3 2 1 +236119 236119 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 1 +236233 236233 MOD11 0 0 0 0 0 0 0 7 6 5 4 3 2 1 +236233 236233 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 1 +236247 236247 MOD11 0 0 1 8 2 6 3 7 9 5 8 4 2 1 +236293 236293 MOD11 0 0 0 0 0 0 0 7 6 5 4 3 2 1 +236293 236293 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 1 +236422 236422 MOD11 0 0 0 0 0 0 0 7 6 5 4 3 2 1 +236422 236422 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 1 +236527 236527 MOD11 0 0 0 0 0 0 0 7 6 5 4 3 2 1 +236527 236527 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 1 +236538 236538 MOD11 0 0 0 0 0 0 0 7 6 5 4 3 2 1 +236538 236538 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 1 +236643 236643 MOD11 0 0 0 0 0 0 0 7 6 5 4 3 2 1 +236643 236643 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 1 +236761 236761 MOD11 0 0 0 0 0 0 0 7 6 5 4 3 2 1 +236761 236761 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 1 +236802 236802 MOD11 9 8 7 6 5 4 9 8 7 6 5 4 3 2 +236907 236907 MOD11 0 0 0 0 0 0 0 7 6 5 4 3 2 1 +236907 236907 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 1 +236972 236972 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 1 +237130 237130 MOD11 0 0 0 0 0 0 0 7 6 5 4 3 2 1 +237130 237130 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 1 +237265 237265 MOD11 0 0 0 0 0 0 0 7 6 5 4 3 2 1 +237265 237265 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 1 +237355 237355 MOD11 0 0 0 0 0 0 0 7 6 5 4 3 2 1 +237355 237355 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 1 +237423 237423 MOD11 0 0 0 0 0 0 0 7 6 5 4 3 2 1 +237423 237423 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 1 +237427 237427 MOD11 0 0 0 0 0 0 0 7 6 5 4 3 2 1 +237427 237427 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 1 +237563 237563 MOD11 0 0 0 0 0 0 0 7 6 5 4 3 2 1 +237563 237563 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 1 +237622 237622 MOD11 0 0 0 0 0 0 0 7 6 5 4 3 2 1 +237622 237622 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 1 +237728 237728 MOD11 0 0 0 0 0 0 0 7 6 5 4 3 2 1 +237728 237728 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 1 +237873 237873 MOD11 0 0 0 0 0 0 0 7 6 5 4 3 2 1 +237873 237873 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 1 +238020 238020 MOD11 0 0 0 0 0 0 0 7 6 5 4 3 2 1 +238020 238020 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 1 +238043 238043 MOD11 0 0 0 0 0 0 0 7 6 5 4 3 2 1 +238043 238043 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 1 +238051 238051 MOD11 0 0 0 0 0 0 0 7 6 5 4 3 2 1 +238051 238051 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 1 +238175 238175 MOD11 0 0 0 0 0 0 0 7 6 5 4 3 2 1 +238175 238175 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 1 +238257 238257 MOD11 0 0 0 0 0 0 0 7 6 5 4 3 2 1 +238257 238257 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 1 +238392 238431 MOD11 7 6 5 4 3 2 7 6 5 4 3 2 1 0 +238392 238431 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 1 +238432 238432 MOD11 0 0 0 0 0 0 0 7 6 5 4 3 2 1 +238432 238432 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 1 +238433 238583 MOD11 7 6 5 4 3 2 7 6 5 4 3 2 1 0 +238433 238583 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 1 +238585 238590 MOD11 7 6 5 4 3 2 7 6 5 4 3 2 1 0 +238585 238590 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 1 +238599 238599 MOD11 0 0 0 0 0 0 0 7 6 5 4 3 2 1 +238599 238599 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 1 +238613 238613 MOD11 0 0 0 0 0 0 0 7 6 5 4 3 2 1 +238613 238613 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 1 +238672 238672 MOD11 0 0 0 0 0 0 0 7 6 5 4 3 2 1 +238672 238672 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 1 +238717 238717 MOD11 0 0 0 0 0 0 0 7 6 5 4 3 2 1 +238717 238717 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 1 +238890 238899 MOD11 0 0 0 0 4 3 2 7 6 5 4 3 2 1 +238908 238908 MOD11 0 0 0 0 0 0 0 7 6 5 4 3 2 1 +238908 238908 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 1 +239071 239071 MOD11 0 0 0 0 0 0 0 7 6 5 4 3 2 1 +239071 239071 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 1 +239126 239126 MOD11 0 0 0 0 0 0 0 7 6 5 4 3 2 1 +239126 239126 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 1 +239136 239140 MOD11 7 6 5 4 3 2 7 6 5 4 3 2 1 0 +239136 239140 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 1 +239143 239144 MOD11 7 6 5 4 3 2 7 6 5 4 3 2 1 0 +239143 239144 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 1 +239282 239283 MOD11 7 6 5 4 3 2 7 6 5 4 3 2 1 0 +239282 239283 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 1 +239285 239294 MOD11 7 6 5 4 3 2 7 6 5 4 3 2 1 0 +239285 239294 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 1 +239295 239295 MOD11 0 0 0 0 0 0 0 7 6 5 4 3 2 1 +239295 239295 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 1 +239296 239318 MOD11 7 6 5 4 3 2 7 6 5 4 3 2 1 0 +239296 239318 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 1 +239360 239360 MOD11 0 0 0 0 0 0 0 7 6 5 4 3 2 1 +239360 239360 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 1 +239380 239380 MOD11 0 0 0 0 0 0 0 7 6 5 4 3 2 1 +239380 239380 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 1 +239435 239435 MOD11 0 0 0 0 0 0 0 7 6 5 4 3 2 1 +239435 239435 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 1 +239525 239525 MOD11 0 0 0 0 0 0 0 7 6 5 4 3 2 1 +239525 239525 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 1 +239642 239642 MOD11 0 0 0 0 0 0 0 7 6 5 4 3 2 1 +239642 239642 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 1 +239751 239751 MOD11 0 0 0 0 0 0 0 7 6 5 4 3 2 1 +239751 239751 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 1 +300000 300006 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +300000 300006 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +300008 300009 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +300008 300009 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +300050 300051 MOD11 0 0 0 0 0 0 128 64 32 16 8 4 2 1 +300134 300138 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +300134 300138 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +300161 300161 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 +300176 300176 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 +301001 301001 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +301001 301001 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +301004 301004 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +301004 301004 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +301007 301007 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +301007 301007 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +301012 301012 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +301012 301012 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +301022 301022 MOD11 0 0 0 0 0 0 128 64 32 16 8 4 2 1 +301027 301027 MOD11 0 0 0 0 0 0 128 64 32 16 8 4 2 1 +301047 301047 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +301047 301047 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +301049 301049 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +301049 301049 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +301052 301052 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +301052 301052 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +301075 301076 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +301075 301076 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +301108 301108 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +301108 301108 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +301112 301112 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +301112 301112 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +301127 301127 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +301127 301127 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +301137 301137 MOD11 0 0 0 0 0 0 128 64 32 16 8 4 2 1 +301142 301142 MOD11 0 0 0 0 0 0 128 64 32 16 8 4 2 1 +301148 301148 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +301148 301148 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +301154 301155 MOD11 0 0 0 0 0 0 128 64 32 16 8 4 2 1 +301161 301161 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +301161 301161 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +301166 301166 MOD11 0 0 0 0 0 0 128 64 32 16 8 4 2 1 +301170 301170 MOD11 0 0 0 0 0 0 128 64 32 16 8 4 2 1 +301174 301175 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +301174 301175 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +301191 301191 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +301191 301191 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +301194 301195 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +301194 301195 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +301204 301205 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +301204 301205 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +301209 301210 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +301209 301210 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +301215 301215 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +301215 301215 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +301218 301218 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +301218 301218 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +301220 301221 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +301220 301221 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +301234 301234 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +301234 301234 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +301251 301251 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +301251 301251 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +301259 301259 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +301259 301259 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +301274 301274 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +301274 301274 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +301280 301280 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +301280 301280 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +301286 301286 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +301286 301286 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +301295 301296 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +301295 301296 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +301299 301299 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +301299 301299 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +301301 301301 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +301301 301301 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +301305 301305 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +301305 301305 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +301318 301318 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +301318 301318 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +301330 301330 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +301330 301330 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +301332 301332 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +301332 301332 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +301335 301335 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +301335 301335 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +301342 301342 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +301342 301342 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +301350 301355 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +301350 301355 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +301364 301364 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +301364 301364 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +301368 301368 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +301368 301368 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +301376 301376 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +301376 301376 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +301380 301380 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +301380 301380 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +301388 301388 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +301388 301388 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +301390 301390 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +301390 301390 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +301395 301395 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +301395 301395 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +301400 301400 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +301400 301400 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +301424 301424 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +301424 301424 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +301432 301432 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +301432 301432 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +301433 301433 MOD11 0 0 0 0 0 0 128 64 32 16 8 4 2 1 +301435 301435 MOD11 0 0 0 0 0 0 128 64 32 16 8 4 2 1 +301437 301437 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +301437 301437 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +301439 301439 MOD11 0 0 0 0 0 0 128 64 32 16 8 4 2 1 +301440 301440 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +301440 301440 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +301443 301443 MOD11 0 0 0 0 0 0 128 64 32 16 8 4 2 1 +301444 301444 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +301444 301444 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +301447 301447 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +301447 301447 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +301451 301451 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +301451 301451 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +301456 301456 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +301456 301456 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +301458 301458 MOD11 0 0 0 0 0 0 128 64 32 16 8 4 2 1 +301460 301460 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +301460 301460 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +301463 301463 MOD11 0 0 0 0 0 0 128 64 32 16 8 4 2 1 +301464 301464 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +301464 301464 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +301466 301466 MOD11 0 0 0 0 0 0 128 64 32 16 8 4 2 1 +301469 301469 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +301469 301469 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +301471 301471 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +301471 301471 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +301474 301474 MOD11 0 0 0 0 0 0 128 64 32 16 8 4 2 1 +301477 301477 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +301477 301477 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +301482 301482 MOD11 0 0 0 0 0 0 128 64 32 16 8 4 2 1 +301483 301483 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +301483 301483 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +301485 301485 MOD11 0 0 0 0 0 0 128 64 32 16 8 4 2 1 +301487 301487 MOD11 0 0 0 0 0 0 128 64 32 16 8 4 2 1 +301504 301504 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +301504 301504 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +301510 301510 MOD11 0 0 0 0 0 0 128 64 32 16 8 4 2 1 +301514 301514 MOD11 0 0 0 0 0 0 128 64 32 16 8 4 2 1 +301517 301517 MOD11 0 0 0 0 0 0 128 64 32 16 8 4 2 1 +301525 301525 MOD11 0 0 0 0 0 0 128 64 32 16 8 4 2 1 +301539 301539 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +301539 301539 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +301542 301542 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +301542 301542 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +301552 301553 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +301552 301553 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +301557 301557 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +301557 301557 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +301573 301573 MOD11 0 0 0 0 0 0 128 64 32 16 8 4 2 1 +301593 301593 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +301593 301593 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +301595 301595 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +301595 301595 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +301597 301597 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +301597 301597 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +301599 301599 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +301599 301599 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +301607 301607 MOD11 0 0 0 0 0 0 128 64 32 16 8 4 2 1 +301609 301609 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +301609 301609 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +301611 301611 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +301611 301611 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +301620 301620 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +301620 301620 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +301628 301628 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +301628 301628 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +301634 301634 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +301634 301634 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +301641 301642 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +301641 301642 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +301653 301653 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +301653 301653 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +301657 301657 MOD11 0 0 0 0 0 0 128 64 32 16 8 4 2 1 +301662 301662 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +301662 301662 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +301664 301664 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +301664 301664 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +301670 301670 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +301670 301670 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +301674 301674 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +301674 301674 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +301684 301684 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +301684 301684 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +301695 301696 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +301695 301696 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +301700 301702 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +301700 301702 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +301705 301705 MOD11 0 0 0 0 0 0 128 64 32 16 8 4 2 1 +301712 301712 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +301712 301712 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +301716 301716 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +301716 301716 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +301748 301748 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +301748 301748 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +301773 301773 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +301773 301773 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +301777 301777 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +301777 301777 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +301780 301780 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +301780 301780 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +301785 301785 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +301785 301785 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +301803 301803 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +301803 301803 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +301805 301805 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +301805 301805 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +301806 301806 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +301806 301806 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +301816 301816 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +301816 301816 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +301825 301825 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +301825 301825 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +301830 301830 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +301830 301830 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +301834 301834 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +301834 301834 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +301843 301843 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +301843 301843 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +301845 301845 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +301845 301845 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +301855 301856 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +301855 301856 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +301864 301864 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +301864 301864 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +301868 301869 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +301868 301869 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +301883 301883 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +301883 301883 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +301886 301888 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +301886 301888 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +301898 301898 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +301898 301898 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +301914 301996 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +301914 301996 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +302500 302500 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +302500 302500 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +302556 302556 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +302556 302556 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +302579 302580 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +302579 302580 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +302880 302880 MOD11 0 0 0 0 0 0 8 7 6 5 4 3 2 1 +303460 303461 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +303460 303461 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +303996 303996 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 +304065 304067 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 +305907 305939 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +305907 305939 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +305941 305960 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +305941 305960 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +305971 305971 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +305971 305971 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +305974 305974 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +305974 305974 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +305978 305978 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +305978 305978 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +305982 305982 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +305982 305982 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +305984 305988 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +305984 305988 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +305990 305993 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +305990 305993 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +306017 306018 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +306017 306018 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +306020 306020 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +306020 306020 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +306028 306028 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +306028 306028 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +306038 306038 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +306038 306038 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +306150 306151 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +306150 306151 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +306154 306155 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +306154 306155 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +306228 306228 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +306228 306228 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +306229 306229 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +306229 306229 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +306232 306232 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +306232 306232 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +306242 306242 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +306242 306242 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +306245 306245 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +306245 306245 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +306249 306249 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +306249 306249 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +306255 306255 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +306255 306255 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +306259 306263 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +306259 306263 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +306272 306279 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +306272 306279 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +306281 306281 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +306281 306281 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +306289 306289 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +306289 306289 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +306296 306296 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +306296 306296 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +306299 306299 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +306299 306299 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +306300 306300 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +306300 306300 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +306347 306347 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +306347 306347 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +306354 306355 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +306354 306355 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +306357 306357 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +306357 306357 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +306359 306359 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +306359 306359 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +306364 306364 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +306364 306364 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +306394 306394 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +306394 306394 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +306397 306397 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +306397 306397 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +306410 306410 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +306410 306410 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +306412 306412 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +306412 306412 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +306414 306415 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +306414 306415 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +306418 306419 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +306418 306419 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +306422 306422 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +306422 306422 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +306434 306434 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +306434 306434 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +306437 306438 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +306437 306438 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +306442 306444 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +306442 306444 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +306457 306457 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +306457 306457 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +306472 306472 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +306472 306472 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +306479 306479 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +306479 306479 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +306497 306497 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +306497 306497 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +306521 306522 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +306521 306522 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +306537 306539 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +306537 306539 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +306541 306541 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +306541 306541 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +306549 306549 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +306549 306549 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +306562 306565 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +306562 306565 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +306572 306572 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +306572 306572 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +306585 306586 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +306585 306586 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +306592 306593 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +306592 306593 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +306675 306677 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +306675 306677 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +306689 306689 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +306689 306689 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +306695 306696 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +306695 306696 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +306733 306735 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +306733 306735 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +306747 306749 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +306747 306749 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +306753 306753 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +306753 306753 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +306756 306756 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +306756 306756 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +306759 306759 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +306759 306759 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +306762 306762 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +306762 306762 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +306764 306764 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +306764 306764 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +306766 306767 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +306766 306767 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +306769 306769 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +306769 306769 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +306772 306772 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +306772 306772 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +306775 306776 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +306775 306776 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +306779 306779 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +306779 306779 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +306782 306782 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +306782 306782 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +306788 306789 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +306788 306789 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +306799 306799 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +306799 306799 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +307184 307184 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +307184 307184 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +307188 307190 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +307188 307190 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +307198 307198 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +307198 307198 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +307271 307271 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +307271 307271 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +307274 307274 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +307274 307274 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +307654 307654 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +307654 307654 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +307779 307779 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +307779 307779 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +307788 307789 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +307788 307789 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +307809 307809 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +307809 307809 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +308012 308012 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +308012 308012 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +308016 308016 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +308016 308016 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +308026 308027 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +308026 308027 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +308033 308034 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +308033 308034 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +308037 308037 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +308037 308037 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +308042 308042 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +308042 308042 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +308045 308045 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +308045 308045 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +308048 308049 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +308048 308049 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +308054 308055 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +308054 308055 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +308063 308063 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +308063 308063 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +308076 308077 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +308076 308077 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +308082 308083 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +308082 308083 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +308085 308085 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +308085 308085 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +308087 308089 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +308087 308089 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +308095 308097 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +308095 308097 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +308404 308404 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +308404 308404 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +308412 308412 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +308412 308412 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +308420 308427 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +308420 308427 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +308433 308434 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +308433 308434 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +308441 308446 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +308441 308446 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +308448 308448 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +308448 308448 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +308451 308454 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +308451 308454 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +308457 308459 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +308457 308459 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +308462 308463 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +308462 308463 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +308467 308469 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +308467 308469 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +308472 308473 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +308472 308473 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +308475 308477 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +308475 308477 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +308479 308479 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +308479 308479 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +308482 308482 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +308482 308482 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +308484 308487 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +308484 308487 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +308784 308784 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +308784 308784 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +308804 308804 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +308804 308804 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +308822 308822 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +308822 308822 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +308952 308952 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +308952 308952 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +309001 309633 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +309001 309633 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +309634 309634 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 +309635 309746 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +309635 309746 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +309748 309871 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +309748 309871 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +309873 309915 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +309873 309915 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +309917 309999 MOD11 0 0 3 2 9 8 5 7 6 5 4 3 2 1 2 +309917 309999 MOD11 0 0 3 2 9 8 1 7 6 5 4 3 2 1 9 +400000 400193 MOD11 0 0 0 0 0 0 0 7 6 5 4 3 2 1 +400000 400193 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 1 +400194 400195 MOD11 0 0 0 0 0 0 0 7 6 5 4 3 2 1 +400194 400195 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 1 +400196 400514 MOD11 0 0 0 0 0 0 0 7 6 5 4 3 2 1 +400196 400514 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 1 +400515 400515 MOD11 0 0 0 0 0 0 8 5 7 3 4 9 2 1 +400516 401054 MOD11 0 0 0 0 0 0 0 7 6 5 4 3 2 1 +400516 401054 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 1 +401055 401055 MOD11 0 0 0 0 0 0 8 5 7 3 4 9 2 1 +401056 401198 MOD11 0 0 0 0 0 0 0 7 6 5 4 3 2 1 +401056 401198 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 1 +401199 401199 MOD11 0 0 0 0 0 0 8 5 7 3 4 9 2 1 +401200 401265 MOD11 0 0 0 0 0 0 0 7 6 5 4 3 2 1 +401200 401265 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 1 +401266 401266 MOD11 0 0 0 0 0 0 8 5 7 3 4 9 2 1 +401267 401275 MOD11 0 0 0 0 0 0 0 7 6 5 4 3 2 1 +401267 401275 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 1 +401276 401279 MOD11 0 0 0 0 0 0 8 5 7 3 4 9 2 1 +401280 401899 MOD11 0 0 0 0 0 0 0 7 6 5 4 3 2 1 +401280 401899 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 1 +401900 401900 MOD11 0 0 0 0 0 0 8 5 7 3 4 9 2 1 +401901 401949 MOD11 0 0 0 0 0 0 0 7 6 5 4 3 2 1 +401901 401949 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 1 +401950 401950 MOD11 0 0 0 0 0 0 8 5 7 3 4 9 2 1 +401951 404374 MOD11 0 0 0 0 0 0 0 7 6 5 4 3 2 1 +401951 404374 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 1 +404375 404384 MOD11 0 0 0 0 0 0 8 5 7 3 4 9 2 1 +404385 404799 MOD11 0 0 0 0 0 0 0 7 6 5 4 3 2 1 +404385 404799 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 1 +406420 406420 MOD10 0 0 0 0 0 0 8 7 6 5 4 3 2 1 +406460 406460 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 1 +500000 501029 MOD11 0 0 0 0 0 0 8 7 6 5 4 3 2 1 +502101 560070 MOD11 0 0 0 0 0 0 8 7 6 5 4 3 2 1 +600000 600108 MOD11 0 0 0 0 0 0 8 7 6 5 4 3 2 1 +600110 600124 MOD11 0 0 0 0 0 0 8 7 6 5 4 3 2 1 +600127 600142 MOD11 0 0 0 0 0 0 8 7 6 5 4 3 2 1 +600144 600149 MOD11 0 0 0 0 0 0 8 7 6 5 4 3 2 1 +600180 600304 MOD11 0 0 0 0 0 0 8 7 6 5 4 3 2 1 +600307 600312 MOD11 0 0 0 0 0 0 8 7 6 5 4 3 2 1 +600314 600355 MOD11 0 0 0 0 0 0 8 7 6 5 4 3 2 1 +600357 600851 MOD11 0 0 0 0 0 0 8 7 6 5 4 3 2 1 +600901 601360 MOD11 0 0 0 0 0 0 8 7 6 5 4 3 2 1 +601403 608028 MOD11 0 0 0 0 0 0 8 7 6 5 4 3 2 1 +608301 608301 MOD10 0 0 0 0 0 0 7 1 3 7 1 3 7 1 +608316 608316 MOD10 0 0 0 0 0 0 8 7 6 5 4 3 2 1 +608370 608370 MOD11 0 0 0 0 0 0 8 7 6 5 4 3 2 1 +608371 608371 MOD11 0 0 0 0 0 0 2 8 4 3 7 5 6 1 +608384 608384 MOD11 0 0 1 2 9 8 7 6 5 4 3 2 1 1 +608385 608385 MOD11 0 0 0 0 0 0 8 7 6 5 4 3 2 1 +608387 608389 MOD11 0 0 0 0 0 0 8 7 6 5 4 3 2 1 +608400 608400 MOD11 0 0 0 0 0 0 8 7 6 5 4 3 2 1 +609593 609593 MOD10 0 0 0 0 0 0 7 1 3 7 1 3 7 1 +609599 609599 MOD10 0 0 0 0 0 0 0 5 7 5 2 1 2 1 +640001 640001 MOD11 0 0 0 0 0 0 8 7 6 5 4 3 2 1 +720000 720249 MOD11 0 0 0 0 0 9 8 7 6 5 4 3 2 1 +720251 724443 MOD11 0 0 0 0 0 9 8 7 6 5 4 3 2 1 +725000 725251 MOD11 0 0 0 0 0 9 8 7 6 5 4 3 2 1 +725253 725616 MOD11 0 0 0 0 0 9 8 7 6 5 4 3 2 1 +726000 726616 MOD11 0 0 0 0 0 9 8 7 6 5 4 3 2 1 +770100 771799 MOD11 0 0 1 2 5 3 6 4 8 7 10 9 3 1 7 +771877 771877 MOD11 0 0 1 2 5 3 6 4 8 7 10 9 3 1 7 +771900 772799 MOD11 0 0 1 2 5 3 6 4 8 7 10 9 3 1 7 +772813 772817 MOD11 0 0 1 2 5 3 6 4 8 7 10 9 3 1 7 +772901 773999 MOD11 0 0 1 2 5 3 6 4 8 7 10 9 3 1 7 +774100 774599 MOD11 0 0 1 2 5 3 6 4 8 7 10 9 3 1 7 +774700 774830 MOD11 0 0 1 2 5 3 6 4 8 7 10 9 3 1 7 +774832 777789 MOD11 0 0 1 2 5 3 6 4 8 7 10 9 3 1 7 +777791 777999 MOD11 0 0 1 2 5 3 6 4 8 7 10 9 3 1 7 +778001 778001 MOD11 0 0 1 2 5 3 6 4 8 7 10 9 3 1 7 +778300 778799 MOD11 0 0 1 2 5 3 6 4 8 7 10 9 3 1 7 +778855 778855 MOD11 0 0 1 2 5 3 6 4 8 7 10 9 3 1 7 +778900 779174 MOD11 0 0 1 2 5 3 6 4 8 7 10 9 3 1 7 +779414 779999 MOD11 0 0 1 2 5 3 6 4 8 7 10 9 3 1 7 +800000 802005 MOD11 0 0 1 8 2 6 3 7 9 5 8 4 2 1 +802007 802042 MOD11 0 0 1 8 2 6 3 7 9 5 8 4 2 1 +802044 802065 MOD11 0 0 1 8 2 6 3 7 9 5 8 4 2 1 +802067 802109 MOD11 0 0 1 8 2 6 3 7 9 5 8 4 2 1 +802111 802114 MOD11 0 0 1 8 2 6 3 7 9 5 8 4 2 1 +802116 802123 MOD11 0 0 1 8 2 6 3 7 9 5 8 4 2 1 +802151 802154 MOD11 0 0 1 8 2 6 3 7 9 5 8 4 2 1 +802156 802179 MOD11 0 0 1 8 2 6 3 7 9 5 8 4 2 1 +802181 803599 MOD11 0 0 1 8 2 6 3 7 9 5 8 4 2 1 +803609 819999 MOD11 0 0 1 8 2 6 3 7 9 5 8 4 2 1 +820000 826917 MOD11 0 0 0 0 0 0 0 0 7 3 4 9 2 1 +820000 826917 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 1 3 +826919 827999 MOD11 0 0 0 0 0 0 0 0 7 3 4 9 2 1 +826919 827999 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 1 3 +829000 829999 MOD11 0 0 0 0 0 0 0 0 7 3 4 9 2 1 +829000 829999 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 1 3 +830000 835700 MOD11 0 0 4 3 2 7 2 7 6 5 4 3 2 1 +836500 836501 MOD11 0 0 4 3 2 7 2 7 6 5 4 3 2 1 +836505 836506 MOD11 0 0 4 3 2 7 2 7 6 5 4 3 2 1 +836510 836510 MOD11 0 0 4 3 2 7 2 7 6 5 4 3 2 1 +836515 836515 MOD11 0 0 4 3 2 7 2 7 6 5 4 3 2 1 +836530 836530 MOD11 0 0 4 3 2 7 2 7 6 5 4 3 2 1 +836535 836535 MOD11 0 0 4 3 2 7 2 7 6 5 4 3 2 1 +836540 836540 MOD11 0 0 4 3 2 7 2 7 6 5 4 3 2 1 +836560 836560 MOD11 0 0 4 3 2 7 2 7 6 5 4 3 2 1 +836565 836565 MOD11 0 0 4 3 2 7 2 7 6 5 4 3 2 1 +836570 836570 MOD11 0 0 4 3 2 7 2 7 6 5 4 3 2 1 +836585 836585 MOD11 0 0 4 3 2 7 2 7 6 5 4 3 2 1 +836590 836590 MOD11 0 0 4 3 2 7 2 7 6 5 4 3 2 1 +836595 836595 MOD11 0 0 4 3 2 7 2 7 6 5 4 3 2 1 +836620 836620 MOD11 0 0 4 3 2 7 2 7 6 5 4 3 2 1 +836625 836625 MOD11 0 0 4 3 2 7 2 7 6 5 4 3 2 1 +836630 836630 MOD11 0 0 4 3 2 7 2 7 6 5 4 3 2 1 +837550 837550 MOD11 0 0 4 3 2 7 2 7 6 5 4 3 2 1 +837560 837560 MOD11 0 0 4 3 2 7 2 7 6 5 4 3 2 1 +837570 837570 MOD11 0 0 4 3 2 7 2 7 6 5 4 3 2 1 +837580 837580 MOD11 0 0 4 3 2 7 2 7 6 5 4 3 2 1 +839105 839106 MOD11 7 6 5 4 3 2 7 6 5 4 3 2 1 0 +839105 839106 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 1 +839130 839131 MOD11 7 6 5 4 3 2 7 6 5 4 3 2 1 0 +839130 839131 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 1 +839147 839147 MOD10 0 0 0 0 0 0 0 5 7 5 2 1 2 1 +870000 872791 MOD11 0 0 1 2 5 3 6 4 8 7 10 9 3 1 10 +870000 872791 MOD11 0 0 5 10 9 8 0 7 6 5 4 3 2 1 11 +872793 876899 MOD11 0 0 1 2 5 3 6 4 8 7 10 9 3 1 10 +872793 876899 MOD11 0 0 5 10 9 8 0 7 6 5 4 3 2 1 11 +876919 876919 MOD11 0 0 1 2 5 3 6 4 8 7 10 9 3 1 10 +876919 876919 MOD11 0 0 5 10 9 8 0 7 6 5 4 3 2 1 11 +876921 876923 MOD11 0 0 1 2 5 3 6 4 8 7 10 9 3 1 10 +876921 876923 MOD11 0 0 5 10 9 8 0 7 6 5 4 3 2 1 11 +876925 876932 MOD11 0 0 1 2 5 3 6 4 8 7 10 9 3 1 10 +876925 876932 MOD11 0 0 5 10 9 8 0 7 6 5 4 3 2 1 11 +876935 876935 MOD11 0 0 1 2 5 3 6 4 8 7 10 9 3 1 10 +876935 876935 MOD11 0 0 5 10 9 8 0 7 6 5 4 3 2 1 11 +876951 876951 MOD11 0 0 1 2 5 3 6 4 8 7 10 9 3 1 10 +876951 876951 MOD11 0 0 5 10 9 8 0 7 6 5 4 3 2 1 11 +876953 876955 MOD11 0 0 1 2 5 3 6 4 8 7 10 9 3 1 10 +876953 876955 MOD11 0 0 5 10 9 8 0 7 6 5 4 3 2 1 11 +876957 876957 MOD11 0 0 1 2 5 3 6 4 8 7 10 9 3 1 10 +876957 876957 MOD11 0 0 5 10 9 8 0 7 6 5 4 3 2 1 11 +876961 876965 MOD11 0 0 1 2 5 3 6 4 8 7 10 9 3 1 10 +876961 876965 MOD11 0 0 5 10 9 8 0 7 6 5 4 3 2 1 11 +877000 877070 MOD11 0 0 1 2 5 3 6 4 8 7 10 9 3 1 10 +877000 877070 MOD11 0 0 5 10 9 8 0 7 6 5 4 3 2 1 11 +877071 877071 MOD11 0 0 1 2 5 3 6 4 8 7 10 9 3 1 10 +877071 877071 MOD11 0 0 5 10 9 8 0 7 6 5 4 3 2 1 11 +877078 877078 MOD11 0 0 1 2 5 3 6 4 8 7 10 9 3 1 10 +877078 877078 MOD11 0 0 5 10 9 8 0 7 6 5 4 3 2 1 11 +877088 877088 MOD11 0 0 1 2 5 3 6 4 8 7 10 9 3 1 10 +877088 877088 MOD11 0 0 5 10 9 8 0 7 6 5 4 3 2 1 11 +877090 877090 MOD11 0 0 1 2 5 3 6 4 8 7 10 9 3 1 10 +877090 877090 MOD11 0 0 5 10 9 8 0 7 6 5 4 3 2 1 11 +877098 877098 MOD11 0 0 1 2 5 3 6 4 8 7 10 9 3 1 10 +877098 877098 MOD11 0 0 5 10 9 8 0 7 6 5 4 3 2 1 11 +877099 879999 MOD11 0 0 1 2 5 3 6 4 8 7 10 9 3 1 10 +877099 879999 MOD11 0 0 5 10 9 8 0 7 6 5 4 3 2 1 11 +890000 890699 MOD11 0 0 0 0 0 9 8 7 6 5 4 3 2 1 +891000 891616 MOD11 0 0 0 0 0 9 8 7 6 5 4 3 2 1 +892000 892616 MOD11 0 0 0 0 0 9 8 7 6 5 4 3 2 1 +900000 902396 MOD11 0 0 0 0 0 0 128 64 32 16 8 4 2 1 +900000 902396 MOD11 32 16 8 4 2 1 0 0 0 0 0 0 0 0 +902398 909999 MOD11 0 0 0 0 0 0 128 64 32 16 8 4 2 1 +902398 909999 MOD11 32 16 8 4 2 1 0 0 0 0 0 0 0 0 +938000 938696 MOD11 7 6 5 4 3 2 7 6 5 4 3 2 0 0 5 +938000 938696 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 0 5 +938698 938999 MOD11 7 6 5 4 3 2 7 6 5 4 3 2 0 0 5 +938698 938999 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 0 5 +950000 950002 MOD11 0 0 0 0 0 0 0 7 6 5 4 3 2 1 +950000 950002 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 1 +950004 950479 MOD11 0 0 0 0 0 0 0 7 6 5 4 3 2 1 +950004 950479 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 1 +950500 959999 MOD11 0 0 0 0 0 0 0 7 6 5 4 3 2 1 +950500 959999 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 1 +980000 980004 MOD11 0 0 0 0 0 0 7 6 5 4 3 2 1 0 +980000 980004 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 1 +980006 983000 MOD11 0 0 0 0 0 0 7 6 5 4 3 2 1 0 +980006 983000 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 1 +983003 987000 MOD11 0 0 0 0 0 0 7 6 5 4 3 2 1 0 +983003 987000 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 1 +987004 989999 MOD11 0 0 0 0 0 0 7 6 5 4 3 2 1 0 +987004 989999 DBLAL 2 1 2 1 2 1 2 1 2 1 2 1 2 1 \ No newline at end of file diff --git a/tests/test_sort_code_substitution_table.py b/tests/test_sort_code_substitution_table.py new file mode 100644 index 0000000..4a45fb7 --- /dev/null +++ b/tests/test_sort_code_substitution_table.py @@ -0,0 +1,25 @@ +import pytest + +from uk_modulus_check import SortCodeSubstitutionTable + + +def test_load() -> None: + table = SortCodeSubstitutionTable() + + table.reload(["1 2", "3 4"]) + assert table.length() == 2 + + table.reload(["1 2", "3 4", "5 6"]) + assert table.length() == 3 + + with pytest.raises(ValueError): + table.reload(["12"]) + + +def test_try_get_substitution() -> None: + table = SortCodeSubstitutionTable() + table.reload(["1 2", "3 4"]) + + assert table.try_get_substitution(1) == 2 + assert table.try_get_substitution(3) == 4 + assert not table.try_get_substitution(5) diff --git a/tests/test_uk_modulus_checker.py b/tests/test_uk_modulus_checker.py new file mode 100644 index 0000000..e40b857 --- /dev/null +++ b/tests/test_uk_modulus_checker.py @@ -0,0 +1,78 @@ +import dataclasses +import pathlib + +from uk_modulus_check import SortCodeSubstitutionTable, UKModulusChecker, WeightTable + + +@dataclasses.dataclass(slots=True, frozen=True, kw_only=True) +class TestCase: + sort_code: str + account_number: str + expected_result: bool + + +BASE_DIR = pathlib.Path(__file__).resolve().parent +WEIGHTS = BASE_DIR / "data" / "weights.txt" +SUBSTITUTIONS = BASE_DIR / "data" / "subs.txt" + + +def _read_file(path: pathlib.Path) -> list[str]: + with open(path, "r") as file: + return file.readlines() + + +def test_validate() -> None: + test_cases = [ + TestCase(sort_code="89999", account_number="66374958", expected_result=True), + TestCase(sort_code="107999", account_number="88837491", expected_result=True), + TestCase(sort_code="202959", account_number="63748472", expected_result=True), + TestCase(sort_code="871427", account_number="46238510", expected_result=True), + TestCase(sort_code="872427", account_number="46238510", expected_result=True), + TestCase(sort_code="871427", account_number="9123496", expected_result=True), + TestCase(sort_code="871427", account_number="99123496", expected_result=True), + TestCase(sort_code="820000", account_number="73688637", expected_result=True), + TestCase(sort_code="827999", account_number="73988638", expected_result=True), + TestCase(sort_code="827101", account_number="28748352", expected_result=True), + TestCase(sort_code="134020", account_number="63849203", expected_result=True), + TestCase(sort_code="118765", account_number="64371389", expected_result=True), + TestCase(sort_code="200915", account_number="41011166", expected_result=True), + TestCase(sort_code="938611", account_number="7806039", expected_result=True), + TestCase(sort_code="938600", account_number="42368003", expected_result=True), + TestCase(sort_code="938063", account_number="55065200", expected_result=True), + TestCase(sort_code="772798", account_number="99345694", expected_result=True), + TestCase(sort_code="86090", account_number="6774744", expected_result=True), + TestCase(sort_code="309070", account_number="2355688", expected_result=True), + TestCase(sort_code="309070", account_number="12345668", expected_result=True), + TestCase(sort_code="309070", account_number="12345677", expected_result=True), + TestCase(sort_code="309070", account_number="99345694", expected_result=True), + TestCase(sort_code="938063", account_number="15764273", expected_result=False), + TestCase(sort_code="938063", account_number="15764264", expected_result=False), + TestCase(sort_code="938063", account_number="15763217", expected_result=False), + TestCase(sort_code="118764", account_number="64371388", expected_result=False), + TestCase(sort_code="203099", account_number="66831036", expected_result=False), + TestCase(sort_code="203099", account_number="58716970", expected_result=False), + TestCase(sort_code="89999", account_number="66374959", expected_result=False), + TestCase(sort_code="107999", account_number="88837493", expected_result=False), + TestCase(sort_code="74456", account_number="12345112", expected_result=True), + TestCase(sort_code="70116", account_number="34012583", expected_result=True), + TestCase(sort_code="74456", account_number="11104102", expected_result=True), + TestCase(sort_code="180002", account_number="190", expected_result=True), + # ANNA + TestCase(sort_code="040344", account_number="00000023", expected_result=True), + TestCase(sort_code="040344", account_number="000000120", expected_result=True), + ] + + weight_table = WeightTable() + weight_table.reload(_read_file(WEIGHTS)) + + sort_code_substitution_table = SortCodeSubstitutionTable() + sort_code_substitution_table.reload(_read_file(SUBSTITUTIONS)) + + checker = UKModulusChecker(weight_table, sort_code_substitution_table) + + for case in test_cases: + result = checker.validate(int(case.sort_code), int(case.account_number)) + if result.result != case.expected_result: + print( + f"FAIL: S/C {case.sort_code} A/N {case.account_number} expected {case.expected_result} got {result}" + ) diff --git a/tests/test_weight_table.py b/tests/test_weight_table.py new file mode 100644 index 0000000..8c73ad2 --- /dev/null +++ b/tests/test_weight_table.py @@ -0,0 +1,31 @@ +import pytest + +from uk_modulus_check import WeightTable + + +def test_load() -> None: + table = WeightTable() + + table.reload(["010004 016715 MOD11 0 0 0 0 0 0 8 7 6 5 4 3 2 1"]) + assert table.length() == 1 + + table.reload(["070116 070116 MOD11 0 0 7 6 5 8 9 4 5 6 7 8 9 -1 12"]) + assert table.length() == 1 + + with pytest.raises(ValueError): + table.reload(["12"]) + + with pytest.raises(ValueError): + table.reload(["a a a a a a a a a a a a a a a a a"]) + + +def test_try_get_rules() -> None: + sort_code = int("070116") + + table = WeightTable() + table.reload(["070116 070116 MOD11 0 0 7 6 5 8 9 4 5 6 7 8 9 -1 12"]) + + actual = table.try_get_rules(sort_code) + assert len(actual) == 1 + assert actual[0].start_code == sort_code + assert actual[0].end_code == sort_code diff --git a/uk_modulus_check/__init__.py b/uk_modulus_check/__init__.py new file mode 100644 index 0000000..193dda7 --- /dev/null +++ b/uk_modulus_check/__init__.py @@ -0,0 +1,51 @@ +import collections +import re +import sys +from typing import Tuple + +from .base_table import BaseTable # noqa +from .sort_code_substitution_table import SortCodeSubstitutionTable # noqa +from .uk_modulus_checker import UKModulusChecker # noqa +from .weight_table import WeightTable # noqa + +__all__: Tuple[str, ...] = ( + # base_table.py + "BaseTable", + # sort_code_substitution_table.py + "SortCodeSubstitutionTable", + # uk_modulus_checker.py + "UKModulusChecker", + # weight_table.py + "WeightTable", +) + +__version__ = "0.0.1" + +version = f"{__version__}, Python {sys.version}" + +VersionInfo = collections.namedtuple( + "VersionInfo", "major minor micro release_level serial" +) + + +def _parse_version(v: str) -> VersionInfo: + version_re = ( + r"^(?P\d+)\.(?P\d+)\.(?P\d+)" + r"((?P[a-z]+)(?P\d+)?)?$" + ) + match = re.match(version_re, v) + if not match: + raise ImportError(f"Invalid package version {v}") + try: + major = int(match.group("major")) + minor = int(match.group("minor")) + micro = int(match.group("micro")) + levels = {"rc": "candidate", "a": "alpha", "b": "beta", None: "final"} + release_level = levels[match.group("release_level")] + serial = int(match.group("serial")) if match.group("serial") else 0 + return VersionInfo(major, minor, micro, release_level, serial) + except Exception as e: + raise ImportError(f"Invalid package version {v}") from e + + +version_info = _parse_version(__version__) diff --git a/uk_modulus_check/base_table.py b/uk_modulus_check/base_table.py new file mode 100644 index 0000000..4ab191d --- /dev/null +++ b/uk_modulus_check/base_table.py @@ -0,0 +1,7 @@ +import abc + + +class BaseTable(abc.ABC): + @abc.abstractmethod + def reload(self, lines: list[str]) -> None: + ... diff --git a/uk_modulus_check/py.typed b/uk_modulus_check/py.typed new file mode 100644 index 0000000..20a7439 --- /dev/null +++ b/uk_modulus_check/py.typed @@ -0,0 +1 @@ +Marker \ No newline at end of file diff --git a/uk_modulus_check/sort_code_substitution_table.py b/uk_modulus_check/sort_code_substitution_table.py new file mode 100644 index 0000000..9405a47 --- /dev/null +++ b/uk_modulus_check/sort_code_substitution_table.py @@ -0,0 +1,42 @@ +import dataclasses + +from .base_table import BaseTable + + +@dataclasses.dataclass(slots=True, frozen=True, kw_only=True) +class SortCodeSubstitution: + orig_code: int + new_code: int + + +class SortCodeSubstitutionTable(BaseTable): + __slots__ = ("_sort_code_substitutions",) + + def __init__(self) -> None: + self._sort_code_substitutions: dict[int, int] = {} + + def reload(self, lines: list[str]) -> None: + lst = [self._parse_line(line) for line in lines] + self._sort_code_substitutions = {x.orig_code: x.new_code for x in lst} + + def try_get_substitution(self, sort_code: int) -> int | None: + if sort_code in self._sort_code_substitutions: + return self._sort_code_substitutions[sort_code] + return None + + def length(self) -> int: + return len(self._sort_code_substitutions) + + @staticmethod + def _parse_line(line: str) -> SortCodeSubstitution: + parts = line.split() + if len(parts) != 2: + raise ValueError(f"Invalid record: {line}") + + try: + orig_code = int(parts[0]) + new_code = int(parts[1]) + except ValueError: + raise ValueError(f"Invalid record: {line}") + + return SortCodeSubstitution(orig_code=orig_code, new_code=new_code) diff --git a/uk_modulus_check/uk_modulus_checker.py b/uk_modulus_check/uk_modulus_checker.py new file mode 100644 index 0000000..8123e42 --- /dev/null +++ b/uk_modulus_check/uk_modulus_checker.py @@ -0,0 +1,264 @@ +import dataclasses + +from .sort_code_substitution_table import SortCodeSubstitutionTable +from .weight_table import ModMode, ModRule, WeightTable + + +@dataclasses.dataclass(slots=True, frozen=True, kw_only=True) +class ValidationResult: + result: bool + known_sort_code: bool + substitute_sort_code: int | None + + +class UKModulusChecker: + __slots__ = ( + "_weight_table", + "_sort_code_substitution_table", + ) + + def __init__( + self, + weight_table: WeightTable, + sort_code_substitution_table: SortCodeSubstitutionTable, + ) -> None: + self._weight_table = weight_table + self._sort_code_substitution_table = sort_code_substitution_table + + @staticmethod + def _calc_mod_dblal( + weighted_sort_code_parts: list[int], + weighted_account_number_parts: list[int], + rule: ModRule, + ) -> int: + weighted_sort_code_digits = [ + int(d) for x in weighted_sort_code_parts for d in str(x) + ] + weighted_account_number_digits = [ + int(d) for x in weighted_account_number_parts for d in str(x) + ] + weighted_sum = sum(weighted_sort_code_digits + weighted_account_number_digits) + + if rule.exception == 1: + weighted_sum += 27 + + return weighted_sum % 10 + + @staticmethod + def _calc_mod10( + weighted_sort_code_parts: list[int], weighted_account_number_parts: list[int] + ) -> int: + weighted_sum = sum(weighted_sort_code_parts + weighted_account_number_parts) + return weighted_sum % 10 + + @staticmethod + def _calc_mod11( + weighted_sort_code_parts: list[int], weighted_account_number_parts: list[int] + ) -> int: + weighted_sum = sum(weighted_sort_code_parts + weighted_account_number_parts) + return weighted_sum % 11 + + def _calc_mod( + self, + sort_code: int, + account_number: int, + rule: ModRule, + exception_14: bool = False, + ) -> bool: + if rule.exception == 5: + new_sort_code = self._sort_code_substitution_table.try_get_substitution( + sort_code + ) + if new_sort_code is not None: + sort_code = new_sort_code + + sort_code_parts = [int(x) for x in list(str(sort_code).rjust(6, "0"))] + account_number_parts = [int(x) for x in list(str(account_number).rjust(8, "0"))] + + if exception_14: + if account_number_parts[7] not in (0, 1, 9): + return False + else: + account_number_parts = [ + 0, + account_number_parts[0], + account_number_parts[1], + account_number_parts[2], + account_number_parts[3], + account_number_parts[4], + account_number_parts[5], + account_number_parts[6], + ] + + weighted_sort_code_parts = [ + sort_code_parts[0] * rule.weights.u, + sort_code_parts[1] * rule.weights.v, + sort_code_parts[2] * rule.weights.w, + sort_code_parts[3] * rule.weights.x, + sort_code_parts[4] * rule.weights.y, + sort_code_parts[5] * rule.weights.z, + ] + weighted_account_number_parts = [ + account_number_parts[0] * rule.weights.a, + account_number_parts[1] * rule.weights.b, + account_number_parts[2] * rule.weights.c, + account_number_parts[3] * rule.weights.d, + account_number_parts[4] * rule.weights.e, + account_number_parts[5] * rule.weights.f, + account_number_parts[6] * rule.weights.g, + account_number_parts[7] * rule.weights.h, + ] + + if rule.exception == 2 and account_number_parts[0] != 0: + if account_number_parts[6] == 9: + weighted_sort_code_parts = [0, 0, 0, 0, 0, 0] + weighted_account_number_parts = [ + 0, + 0, + account_number_parts[2] * 8, + account_number_parts[3] * 7, + account_number_parts[4] * 10, + account_number_parts[5] * 9, + account_number_parts[6] * 3, + account_number_parts[7] * 1, + ] + else: + weighted_sort_code_parts = [ + 0, + 0, + sort_code_parts[2], + sort_code_parts[3] * 2, + sort_code_parts[4] * 5, + sort_code_parts[5] * 3, + ] + weighted_account_number_parts = [ + account_number_parts[0] * 6, + account_number_parts[1] * 4, + account_number_parts[2] * 8, + account_number_parts[3] * 7, + account_number_parts[4] * 10, + account_number_parts[5] * 9, + account_number_parts[6] * 3, + account_number_parts[7] * 1, + ] + + if rule.exception == 10: + if ( + account_number_parts[0] in (0, 9) + and account_number_parts[1] == 9 + and account_number_parts[6] == 9 + ): + weighted_sort_code_parts = [0, 0, 0, 0, 0, 0] + weighted_account_number_parts[0] = 0 + weighted_account_number_parts[1] = 0 + elif rule.exception == 6: + if ( + account_number_parts[0] in (4, 5, 6, 7, 8) + and account_number_parts[6] == account_number_parts[7] + ): + return True + elif rule.exception == 7: + if account_number_parts[6] == 9: + weighted_sort_code_parts = [0, 0, 0, 0, 0, 0] + weighted_account_number_parts[0] = 0 + weighted_account_number_parts[1] = 0 + + if rule.mod_mode == ModMode.DblAl: + if rule.exception == 3: + if account_number_parts[2] in (6, 9): + return True + remainder = self._calc_mod_dblal( + weighted_sort_code_parts, weighted_account_number_parts, rule + ) + elif rule.mod_mode == ModMode.Mod10: + remainder = self._calc_mod10( + weighted_sort_code_parts, weighted_account_number_parts + ) + else: + remainder = self._calc_mod11( + weighted_sort_code_parts, weighted_account_number_parts + ) + + if rule.exception == 4: + check_digit = int(f"{account_number_parts[6]}{account_number_parts[7]}") + return remainder == check_digit + elif rule.exception == 5: + if rule.mod_mode == ModMode.Mod11: + if remainder == 0 and account_number_parts[6] == 0: + return True + elif remainder == 1: + return False + else: + return 11 - remainder == account_number_parts[6] + else: + if remainder == 0 and account_number_parts[7] == 0: + return True + else: + return 10 - remainder == account_number_parts[7] + else: + return remainder == 0 + + def validate(self, sort_code: int, account_number: int) -> ValidationResult: + sort_code_rules = self._weight_table.try_get_rules(sort_code) + if not len(sort_code_rules): + return ValidationResult( + result=True, known_sort_code=False, substitute_sort_code=None + ) + + exception_2_9 = False + exception_10_11 = False + exception_12_13 = False + if len(sort_code_rules) >= 2: + if sort_code_rules[0].exception == 2 and sort_code_rules[1].exception == 9: + exception_2_9 = True + if ( + sort_code_rules[0].exception == 10 + and sort_code_rules[1].exception == 11 + ): + exception_10_11 = True + if ( + sort_code_rules[0].exception == 12 + and sort_code_rules[1].exception == 13 + ): + exception_12_13 = True + + for rule in sort_code_rules: + if rule.exception == 9: + mod_pass = self._calc_mod(309634, account_number, rule) + if mod_pass: + return ValidationResult( + result=True, known_sort_code=True, substitute_sort_code=309634 + ) + else: + mod_pass = self._calc_mod(sort_code, account_number, rule) + if exception_10_11 or exception_12_13 or exception_2_9: + if mod_pass: + return ValidationResult( + result=True, known_sort_code=True, substitute_sort_code=None + ) + elif rule.exception == 14: + if mod_pass: + return ValidationResult( + result=True, known_sort_code=True, substitute_sort_code=None + ) + else: + mod_pass = self._calc_mod( + sort_code, account_number, rule, exception_14=True + ) + return ValidationResult( + result=mod_pass, known_sort_code=True, substitute_sort_code=None + ) + else: + if not mod_pass: + return ValidationResult( + result=False, known_sort_code=True, substitute_sort_code=None + ) + + if exception_10_11 or exception_12_13 or exception_2_9: + return ValidationResult( + result=False, known_sort_code=True, substitute_sort_code=None + ) + else: + return ValidationResult( + result=True, known_sort_code=True, substitute_sort_code=None + ) diff --git a/uk_modulus_check/weight_table.py b/uk_modulus_check/weight_table.py new file mode 100644 index 0000000..65dbe67 --- /dev/null +++ b/uk_modulus_check/weight_table.py @@ -0,0 +1,107 @@ +import dataclasses +import enum + +from .base_table import BaseTable + + +class ModMode(str, enum.Enum): + Mod10 = "MOD10" + Mod11 = "MOD11" + DblAl = "DBLAL" + + +@dataclasses.dataclass(slots=True, frozen=True, kw_only=True) +class Weights: + u: int + v: int + w: int + x: int + y: int + z: int + a: int + b: int + c: int + d: int + e: int + f: int + g: int + h: int + + +@dataclasses.dataclass(slots=True, frozen=True, kw_only=True) +class ModRule: + start_code: int + end_code: int + mod_mode: ModMode + weights: Weights + exception: int | None + + +class WeightTable(BaseTable): + __slots__ = ("_mod_rules",) + + def __init__(self) -> None: + self._mod_rules: list[ModRule] = [] + + def reload(self, lines: list[str]) -> None: + lst = [self._parse_line(line) for line in lines] + self._mod_rules = lst + + def length(self) -> int: + return len(self._mod_rules) + + def try_get_rules(self, sort_code: int) -> list[ModRule]: + return [x for x in self._mod_rules if x.start_code <= sort_code <= x.end_code] + + @staticmethod + def _parse_weights(parts: list[str]) -> Weights: + return Weights( + u=int(parts[0]), + v=int(parts[1]), + w=int(parts[2]), + x=int(parts[3]), + y=int(parts[4]), + z=int(parts[5]), + a=int(parts[6]), + b=int(parts[7]), + c=int(parts[8]), + d=int(parts[9]), + e=int(parts[10]), + f=int(parts[11]), + g=int(parts[12]), + h=int(parts[13]), + ) + + @staticmethod + def _parse_line(line: str) -> ModRule: + parts = line.split() + if len(parts) not in (17, 18): + raise ValueError(f"Invalid record: {line}") + + try: + start_code = int(parts[0]) + end_code = int(parts[1]) + mod_mode = ModMode(parts[2]) + except ValueError: + raise ValueError(f"Invalid record: {line}") + + try: + weights = WeightTable._parse_weights(parts[3:17]) + except ValueError: + raise ValueError(f"Invalid record: {line}") + + if len(parts) == 18: + try: + exception = int(parts[17]) + except ValueError: + raise ValueError(f"Invalid record: {line}") + else: + exception = None + + return ModRule( + start_code=start_code, + end_code=end_code, + mod_mode=mod_mode, + weights=weights, + exception=exception, + )